From 07b1247e9a8425f790a325913fd901abd47ea5d6 Mon Sep 17 00:00:00 2001
From: Veronaet <191837011+Veronaet@users.noreply.github.com>
Date: Tue, 10 Jun 2025 05:01:42 -0700
Subject: [PATCH 1/4] Create manifest.json
---
submissions/Homework Tracker/manifest.json | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 submissions/Homework Tracker/manifest.json
diff --git a/submissions/Homework Tracker/manifest.json b/submissions/Homework Tracker/manifest.json
new file mode 100644
index 00000000..62496658
--- /dev/null
+++ b/submissions/Homework Tracker/manifest.json
@@ -0,0 +1,25 @@
+{
+ "manifest_version": 3,
+ "name": "Homework Tracker",
+ "version": "1.0",
+ "description": "Track your homework assignments and never miss a deadline",
+ "permissions": [
+ "storage"
+ ],
+ "action": {
+ "default_popup": "popup.html",
+ "default_title": "Homework Tracker",
+ "default_icon": {
+ "16": "icon16.png",
+ "32": "icon32.png",
+ "48": "icon48.png",
+ "128": "icon128.png"
+ }
+ },
+ "icons": {
+ "16": "icon16.png",
+ "32": "icon32.png",
+ "48": "icon48.png",
+ "128": "icon128.png"
+ }
+}
From 094c4140f0021cdb059d3f47fea33a6c02c82b5d Mon Sep 17 00:00:00 2001
From: Veronaet <191837011+Veronaet@users.noreply.github.com>
Date: Tue, 10 Jun 2025 05:03:43 -0700
Subject: [PATCH 2/4] Create popup.html
---
submissions/Homework Tracker/popup.html | 39 +++++++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 submissions/Homework Tracker/popup.html
diff --git a/submissions/Homework Tracker/popup.html b/submissions/Homework Tracker/popup.html
new file mode 100644
index 00000000..55456a07
--- /dev/null
+++ b/submissions/Homework Tracker/popup.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+ Homework Tracker
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
No assignments yet. Add one above!
+
+
+
+
+
+
+
From 38da1868264d315b8944df6d4e2370e888c812b9 Mon Sep 17 00:00:00 2001
From: Veronaet <191837011+Veronaet@users.noreply.github.com>
Date: Tue, 10 Jun 2025 05:06:21 -0700
Subject: [PATCH 3/4] Create styles.css
---
submissions/Homework Tracker/styles.css | 275 ++++++++++++++++++++++++
1 file changed, 275 insertions(+)
create mode 100644 submissions/Homework Tracker/styles.css
diff --git a/submissions/Homework Tracker/styles.css b/submissions/Homework Tracker/styles.css
new file mode 100644
index 00000000..b092a813
--- /dev/null
+++ b/submissions/Homework Tracker/styles.css
@@ -0,0 +1,275 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ width: 400px;
+ min-height: 500px;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: #333;
+}
+
+.container {
+ background: white;
+ margin: 0;
+ min-height: 500px;
+ display: flex;
+ flex-direction: column;
+}
+
+header {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ padding: 20px;
+ text-align: center;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+}
+
+header h1 {
+ font-size: 20px;
+ font-weight: 600;
+}
+
+.add-form {
+ padding: 20px;
+ background: #f8f9fa;
+ border-bottom: 1px solid #e9ecef;
+}
+
+.add-form input,
+.add-form textarea,
+.add-form button {
+ width: 100%;
+ margin-bottom: 10px;
+ padding: 12px;
+ border: 1px solid #ddd;
+ border-radius: 8px;
+ font-size: 14px;
+ font-family: inherit;
+}
+
+.add-form input:focus,
+.add-form textarea:focus {
+ outline: none;
+ border-color: #667eea;
+ box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
+}
+
+.add-form textarea {
+ resize: vertical;
+ min-height: 60px;
+ max-height: 100px;
+}
+
+#addBtn {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ border: none;
+ font-weight: 600;
+ cursor: pointer;
+ transition: transform 0.2s, box-shadow 0.2s;
+}
+
+#addBtn:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+}
+
+#addBtn:active {
+ transform: translateY(0);
+}
+
+.filters {
+ display: flex;
+ padding: 0 20px;
+ background: white;
+ border-bottom: 1px solid #e9ecef;
+}
+
+.filter-btn {
+ flex: 1;
+ padding: 12px;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 500;
+ color: #666;
+ transition: all 0.2s;
+ border-bottom: 2px solid transparent;
+}
+
+.filter-btn:hover {
+ color: #667eea;
+ background: rgba(102, 126, 234, 0.05);
+}
+
+.filter-btn.active {
+ color: #667eea;
+ border-bottom-color: #667eea;
+ background: rgba(102, 126, 234, 0.1);
+}
+
+.assignments-container {
+ flex: 1;
+ padding: 20px;
+ overflow-y: auto;
+}
+
+.assignment-item {
+ background: white;
+ border: 1px solid #e9ecef;
+ border-radius: 12px;
+ padding: 16px;
+ margin-bottom: 12px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.05);
+ transition: all 0.2s;
+ position: relative;
+}
+
+.assignment-item:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 16px rgba(0,0,0,0.1);
+}
+
+.assignment-item.completed {
+ opacity: 0.7;
+ background: #f8f9fa;
+}
+
+.assignment-item.completed .assignment-title {
+ text-decoration: line-through;
+ color: #666;
+}
+
+.assignment-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 8px;
+}
+
+.assignment-title {
+ font-weight: 600;
+ font-size: 16px;
+ color: #333;
+ margin: 0;
+ flex: 1;
+}
+
+.assignment-actions {
+ display: flex;
+ gap: 5px;
+}
+
+.action-btn {
+ background: none;
+ border: none;
+ font-size: 16px;
+ cursor: pointer;
+ padding: 4px;
+ border-radius: 4px;
+ transition: background 0.2s;
+}
+
+.action-btn:hover {
+ background: rgba(0,0,0,0.1);
+}
+
+.complete-btn {
+ color: #28a745;
+}
+
+.delete-btn {
+ color: #dc3545;
+}
+
+.assignment-meta {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+}
+
+.assignment-subject {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ padding: 4px 8px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+}
+
+.assignment-date {
+ font-size: 12px;
+ color: #666;
+ font-weight: 500;
+}
+
+.assignment-date.overdue {
+ color: #dc3545;
+ font-weight: 600;
+}
+
+.assignment-date.due-soon {
+ color: #ffc107;
+ font-weight: 600;
+}
+
+.assignment-description {
+ font-size: 14px;
+ color: #666;
+ line-height: 1.4;
+ margin-top: 8px;
+ padding-top: 8px;
+ border-top: 1px solid #f0f0f0;
+}
+
+.empty-state {
+ text-align: center;
+ color: #666;
+ font-style: italic;
+ padding: 40px 20px;
+}
+
+.empty-state p {
+ font-size: 16px;
+}
+
+/* Scrollbar styling */
+.assignments-container::-webkit-scrollbar {
+ width: 6px;
+}
+
+.assignments-container::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 3px;
+}
+
+.assignments-container::-webkit-scrollbar-thumb {
+ background: #ccc;
+ border-radius: 3px;
+}
+
+.assignments-container::-webkit-scrollbar-thumb:hover {
+ background: #999;
+}
+
+/* Animation for new items */
+@keyframes slideIn {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.assignment-item.new {
+ animation: slideIn 0.3s ease-out;
+}
From ed321ff359b5736a5b26324cc4dbd8076e3d36a1 Mon Sep 17 00:00:00 2001
From: Veronaet <191837011+Veronaet@users.noreply.github.com>
Date: Tue, 10 Jun 2025 05:07:37 -0700
Subject: [PATCH 4/4] Create popup.js
---
submissions/Homework Tracker/popup.js | 299 ++++++++++++++++++++++++++
1 file changed, 299 insertions(+)
create mode 100644 submissions/Homework Tracker/popup.js
diff --git a/submissions/Homework Tracker/popup.js b/submissions/Homework Tracker/popup.js
new file mode 100644
index 00000000..38eb11d1
--- /dev/null
+++ b/submissions/Homework Tracker/popup.js
@@ -0,0 +1,299 @@
+// Homework Tracker Chrome Extension - Main JavaScript
+
+class HomeworkTracker {
+ constructor() {
+ this.assignments = [];
+ this.currentFilter = 'all';
+ this.init();
+ }
+
+ async init() {
+ await this.loadAssignments();
+ this.setupEventListeners();
+ this.renderAssignments();
+ this.setTodayAsDefault();
+ }
+
+ setupEventListeners() {
+ // Add assignment button
+ document.getElementById('addBtn').addEventListener('click', () => this.addAssignment());
+
+ // Enter key in input fields
+ ['assignmentTitle', 'assignmentSubject'].forEach(id => {
+ document.getElementById(id).addEventListener('keypress', (e) => {
+ if (e.key === 'Enter') this.addAssignment();
+ });
+ });
+
+ // Filter buttons
+ document.querySelectorAll('.filter-btn').forEach(btn => {
+ btn.addEventListener('click', (e) => this.setFilter(e.target.dataset.filter));
+ });
+ }
+
+ setTodayAsDefault() {
+ const today = new Date().toISOString().split('T')[0];
+ document.getElementById('assignmentDate').value = today;
+ }
+
+ async loadAssignments() {
+ try {
+ const result = await chrome.storage.local.get(['assignments']);
+ this.assignments = result.assignments || [];
+ } catch (error) {
+ console.error('Error loading assignments:', error);
+ this.assignments = [];
+ }
+ }
+
+ async saveAssignments() {
+ try {
+ await chrome.storage.local.set({ assignments: this.assignments });
+ } catch (error) {
+ console.error('Error saving assignments:', error);
+ }
+ }
+
+ generateId() {
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
+ }
+
+ async addAssignment() {
+ const title = document.getElementById('assignmentTitle').value.trim();
+ const subject = document.getElementById('assignmentSubject').value.trim();
+ const date = document.getElementById('assignmentDate').value;
+ const description = document.getElementById('assignmentDescription').value.trim();
+
+ if (!title || !subject || !date) {
+ this.showError('Please fill in title, subject, and due date');
+ return;
+ }
+
+ const assignment = {
+ id: this.generateId(),
+ title,
+ subject,
+ date,
+ description,
+ completed: false,
+ createdAt: new Date().toISOString()
+ };
+
+ this.assignments.push(assignment);
+ await this.saveAssignments();
+
+ // Clear form
+ document.getElementById('assignmentTitle').value = '';
+ document.getElementById('assignmentSubject').value = '';
+ document.getElementById('assignmentDescription').value = '';
+ this.setTodayAsDefault();
+
+ this.renderAssignments();
+ this.showSuccess('Assignment added successfully!');
+ }
+
+ async toggleComplete(id) {
+ const assignment = this.assignments.find(a => a.id === id);
+ if (assignment) {
+ assignment.completed = !assignment.completed;
+ await this.saveAssignments();
+ this.renderAssignments();
+ }
+ }
+
+ async deleteAssignment(id) {
+ if (confirm('Are you sure you want to delete this assignment?')) {
+ this.assignments = this.assignments.filter(a => a.id !== id);
+ await this.saveAssignments();
+ this.renderAssignments();
+ this.showSuccess('Assignment deleted');
+ }
+ }
+
+ setFilter(filter) {
+ this.currentFilter = filter;
+
+ // Update active filter button
+ document.querySelectorAll('.filter-btn').forEach(btn => {
+ btn.classList.toggle('active', btn.dataset.filter === filter);
+ });
+
+ this.renderAssignments();
+ }
+
+ getFilteredAssignments() {
+ let filtered = [...this.assignments];
+
+ // Apply filter
+ switch (this.currentFilter) {
+ case 'pending':
+ filtered = filtered.filter(a => !a.completed);
+ break;
+ case 'completed':
+ filtered = filtered.filter(a => a.completed);
+ break;
+ }
+
+ // Sort by due date (earliest first)
+ filtered.sort((a, b) => {
+ if (a.completed && !b.completed) return 1;
+ if (!a.completed && b.completed) return -1;
+ return new Date(a.date) - new Date(b.date);
+ });
+
+ return filtered;
+ }
+
+ formatDate(dateString) {
+ const date = new Date(dateString);
+ const today = new Date();
+ const tomorrow = new Date(today);
+ tomorrow.setDate(tomorrow.getDate() + 1);
+
+ // Reset time for comparison
+ today.setHours(0, 0, 0, 0);
+ tomorrow.setHours(0, 0, 0, 0);
+ date.setHours(0, 0, 0, 0);
+
+ if (date.getTime() === today.getTime()) {
+ return 'Today';
+ } else if (date.getTime() === tomorrow.getTime()) {
+ return 'Tomorrow';
+ } else {
+ return date.toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: date.getFullYear() !== today.getFullYear() ? 'numeric' : undefined
+ });
+ }
+ }
+
+ getDateStatus(dateString) {
+ const date = new Date(dateString);
+ const today = new Date();
+ const tomorrow = new Date(today);
+ tomorrow.setDate(tomorrow.getDate() + 1);
+
+ // Reset time for comparison
+ today.setHours(0, 0, 0, 0);
+ tomorrow.setHours(0, 0, 0, 0);
+ date.setHours(0, 0, 0, 0);
+
+ if (date < today) {
+ return 'overdue';
+ } else if (date.getTime() === today.getTime() || date.getTime() === tomorrow.getTime()) {
+ return 'due-soon';
+ }
+ return '';
+ }
+
+ renderAssignments() {
+ const container = document.getElementById('assignmentsList');
+ const emptyState = document.getElementById('emptyState');
+ const filtered = this.getFilteredAssignments();
+
+ if (filtered.length === 0) {
+ container.innerHTML = '';
+ emptyState.style.display = 'block';
+ return;
+ }
+
+ emptyState.style.display = 'none';
+
+ container.innerHTML = filtered.map(assignment => {
+ const dateStatus = this.getDateStatus(assignment.date);
+ const formattedDate = this.formatDate(assignment.date);
+
+ return `
+
+
+
+ ${this.escapeHtml(assignment.subject)}
+ ${formattedDate}
+
+ ${assignment.description ? `
${this.escapeHtml(assignment.description)}
` : ''}
+
+ `;
+ }).join('');
+ }
+
+ escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
+ showSuccess(message) {
+ this.showNotification(message, 'success');
+ }
+
+ showError(message) {
+ this.showNotification(message, 'error');
+ }
+
+ showNotification(message, type) {
+ // Remove existing notifications
+ const existing = document.querySelector('.notification');
+ if (existing) existing.remove();
+
+ const notification = document.createElement('div');
+ notification.className = `notification ${type}`;
+ notification.textContent = message;
+
+ // Add styles
+ Object.assign(notification.style, {
+ position: 'fixed',
+ top: '20px',
+ left: '50%',
+ transform: 'translateX(-50%)',
+ background: type === 'success' ? '#28a745' : '#dc3545',
+ color: 'white',
+ padding: '10px 20px',
+ borderRadius: '8px',
+ fontSize: '14px',
+ fontWeight: '500',
+ zIndex: '1000',
+ boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
+ animation: 'slideDown 0.3s ease-out'
+ });
+
+ // Add animation keyframes
+ if (!document.querySelector('#notification-styles')) {
+ const style = document.createElement('style');
+ style.id = 'notification-styles';
+ style.textContent = `
+ @keyframes slideDown {
+ from { opacity: 0; transform: translateX(-50%) translateY(-20px); }
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
+ }
+ `;
+ document.head.appendChild(style);
+ }
+
+ document.body.appendChild(notification);
+
+ // Auto remove after 3 seconds
+ setTimeout(() => {
+ if (notification.parentNode) {
+ notification.style.animation = 'slideDown 0.3s ease-out reverse';
+ setTimeout(() => notification.remove(), 300);
+ }
+ }, 3000);
+ }
+}
+
+// Initialize the tracker when the popup loads
+let tracker;
+document.addEventListener('DOMContentLoaded', () => {
+ tracker = new HomeworkTracker();
+});