diff --git a/css/styles.css b/css/styles.css index 83339e5..101666e 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1593,3 +1593,69 @@ html, body { .wish-item-url:hover { text-decoration: underline; } + +/* ======================== + Notes + ======================== */ +.notes-container { + max-width: 800px; + margin: 0 auto; +} + +.notes-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; +} + +.notes-list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 1rem; +} + +.note-item { + background: #fff; + border: 1px solid var(--border-color, #e0e0e0); + border-radius: 8px; + padding: 1rem; + cursor: pointer; + transition: box-shadow 0.2s; + display: flex; + flex-direction: column; + gap: 0.4rem; + min-height: 100px; +} + +.note-item:hover { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.note-item-title { + font-weight: 600; + font-size: 1rem; + word-break: break-word; +} + +.note-item-preview { + font-size: 0.875rem; + color: #555; + flex: 1; + overflow: hidden; + word-break: break-word; + white-space: pre-wrap; +} + +.note-item-date { + font-size: 0.75rem; + color: #999; + margin-top: auto; +} + +#noteContent { + width: 100%; + resize: vertical; + font-family: inherit; + font-size: 0.95rem; +} diff --git a/index.html b/index.html index 134e84d..181a891 100644 --- a/index.html +++ b/index.html @@ -66,6 +66,7 @@

πŸ“‹ Task Manager

+ @@ -663,6 +664,45 @@

Add Wish List Item

+ +
+
+
+

Notes

+ +
+ +
+

No notes yet. Add one to get started!

+
+
+ + + +
+
diff --git a/js/app.d.ts.map b/js/app.d.ts.map index 5a9ff03..036a619 100644 --- a/js/app.d.ts.map +++ b/js/app.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/js/app.js b/js/app.js index 9966f85..df92cb7 100644 --- a/js/app.js +++ b/js/app.js @@ -11,6 +11,7 @@ class TaskManager { this.currentEditingFinanceType = null; this.currentEditingRewardId = null; this.currentEditingWishItemId = null; + this.currentEditingNoteId = null; this.dragSrcWishId = null; this.selectedDate = new Date(); this.tasksExpanded = false; @@ -112,6 +113,11 @@ class TaskManager { document.getElementById('wishItemForm').addEventListener('submit', (e) => this.saveWishItem(e)); document.getElementById('cancelWishItemBtn').addEventListener('click', () => this.closeWishItemModal()); document.getElementById('deleteWishItemBtn').addEventListener('click', () => this.deleteWishItem()); + // Notes section + document.getElementById('addNoteBtn').addEventListener('click', () => this.openNoteModal()); + document.getElementById('noteForm').addEventListener('submit', (e) => this.saveNote(e)); + document.getElementById('cancelNoteBtn').addEventListener('click', () => this.closeNoteModal()); + document.getElementById('deleteNoteBtn').addEventListener('click', () => this.deleteNote()); // Modal close buttons document.querySelectorAll('.close-btn').forEach(btn => { btn.addEventListener('click', (e) => { @@ -223,6 +229,9 @@ class TaskManager { else if (tabName === 'wishlist') { this.renderWishList(); } + else if (tabName === 'notes') { + this.renderNotes(); + } else if (tabName === 'settings') { this.renderSettings(); } @@ -1754,6 +1763,82 @@ class TaskManager { } } // ======================== + // Notes + // ======================== + renderNotes() { + const notes = storage.getNotes(); + const container = document.getElementById('notesList'); + if (notes.length === 0) { + container.innerHTML = '

No notes yet. Add one to get started!

'; + return; + } + container.innerHTML = notes.map(note => this.renderNoteItem(note)).join(''); + container.querySelectorAll('.note-item').forEach(el => { + el.addEventListener('click', () => { + this.openNoteModal(el.dataset.noteId); + }); + }); + } + renderNoteItem(note) { + const rawPreview = note.content.length > 120 + ? note.content.substring(0, 120) + '…' + : note.content; + const title = this.escapeHtml(note.title || 'Untitled'); + const preview = rawPreview ? this.escapeHtml(rawPreview) : 'No content'; + const date = new Date(note.updatedDate ?? note.createdDate).toLocaleDateString(); + return ` +
+
${title}
+
${preview}
+
${date}
+
+ `; + } + openNoteModal(noteId = null) { + this.currentEditingNoteId = noteId; + const modal = document.getElementById('noteModal'); + const form = document.getElementById('noteForm'); + const deleteBtn = document.getElementById('deleteNoteBtn'); + form.reset(); + deleteBtn.style.display = 'none'; + document.getElementById('noteModalTitle').textContent = noteId ? 'Edit Note' : 'Add Note'; + if (noteId) { + const note = storage.getNotes().find(n => n.id === noteId); + if (note) { + document.getElementById('noteTitle').value = note.title; + document.getElementById('noteContent').value = note.content; + deleteBtn.style.display = 'block'; + } + } + modal.classList.add('active'); + } + closeNoteModal() { + document.getElementById('noteModal').classList.remove('active'); + this.currentEditingNoteId = null; + } + saveNote(e) { + e.preventDefault(); + const title = document.getElementById('noteTitle').value.trim(); + const content = document.getElementById('noteContent').value.trim(); + if (this.currentEditingNoteId) { + storage.updateNote(this.currentEditingNoteId, { title, content }); + } + else { + storage.addNote({ title, content }); + } + this.closeNoteModal(); + this.renderNotes(); + } + deleteNote() { + if (this.currentEditingNoteId) { + if (confirm('Are you sure you want to delete this note?')) { + storage.deleteNote(this.currentEditingNoteId); + this.closeNoteModal(); + this.renderNotes(); + } + } + } + // ======================== // Settings // ======================== renderSettings() { diff --git a/js/storage.d.ts.map b/js/storage.d.ts.map index a77791f..3f46582 100644 --- a/js/storage.d.ts.map +++ b/js/storage.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,eAAe,UAAU,CAAC;AAChC,QAAA,MAAM,WAAW,oBAAoB,CAAC;AAOtC,MAAM,WAAW,IAAI;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,KAAK;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,IAAI;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,eAAe,CAAC;CACpC;AAED,MAAM,WAAW,QAAQ;IACrB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,OAAO;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,cAAc,EAAE,QAAQ,EAAE,CAAC;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,QAAQ,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,KAAK,EAAE,IAAI,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACvB;AAED,qBAAa,cAAc;;IAKvB,iBAAiB,IAAI,IAAI;IAOzB,iBAAiB,IAAI,IAAI;IAqCzB,OAAO,IAAI,OAAO;IAKlB,OAAO,CAAC,cAAc;IAKtB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAM7B,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAiBlC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS;IAUpE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMhC,QAAQ,IAAI,IAAI,EAAE;IAMlB,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO;IAa9C,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS;IAUhF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAatC,WAAW,IAAI,OAAO,EAAE;IAMxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK;IAkBtC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS;IAWxE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMlC,SAAS,IAAI,KAAK,EAAE;IAKpB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,IAAI;IAqBlE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM;IAqCnF,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAM/C,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAMnD,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAMtE,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW;IActD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,SAAS;IAUxF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMtC,WAAW,IAAI,WAAW,EAAE;IAK5B,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW;IActD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,SAAS;IAUxF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMtC,UAAU,IAAI,WAAW,EAAE;IAM3B,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW;IAiBpD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,SAAS;IAatF,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASpC,UAAU,IAAI,WAAW,EAAE;IAM3B,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;IAmB1C,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS;IAc5E,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASpC,UAAU,IAAI,MAAM,EAAE;IAKtB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IA4ChD,kBAAkB,IAAI,QAAQ,EAAE;IAMhC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAe9C,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,SAAS;IAWhF,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IASpC,YAAY,IAAI,QAAQ,EAAE;IAM1B,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAW5C,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAclC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS;IAYpE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAOhC,QAAQ,IAAI,IAAI,EAAE;IASlB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAW/C,WAAW,IAAI,IAAI;IAQnB,iBAAiB,CAAC,SAAS,GAAE,OAAc,GAAG,IAAI;IAoBlD,YAAY,IAAI,SAAS;IAMzB,UAAU,IAAI,MAAM;IAIpB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAO9B,UAAU,IAAI,MAAM;IAKpB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAevC,YAAY,IAAI,OAAO;IAYvB,aAAa,IAAI,MAAM,EAAE;IAgBzB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAa1C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAyBzD,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAyB7C,WAAW,IAAI,QAAQ;IAYvB,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;CAUpD;AAGD,QAAA,MAAM,OAAO,gBAAuB,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAEjD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAS3D"} \ No newline at end of file diff --git a/js/storage.js b/js/storage.js index 49cd856..65bd7bb 100644 --- a/js/storage.js +++ b/js/storage.js @@ -44,7 +44,8 @@ export class StorageManager { settings: { tasksPerLevel: 30 }, - wishList: [] + wishList: [], + notes: [] }; localStorage.setItem(STORAGE_KEY, JSON.stringify(initialData)); } @@ -477,6 +478,46 @@ export class StorageManager { }); this.saveData(data); } + // Note Management + addNote(note) { + const data = this.getData(); + if (!data.notes) + data.notes = []; + const newNote = { + id: this.generateId(), + title: note.title || '', + content: note.content || '', + createdDate: new Date().toISOString(), + }; + data.notes.push(newNote); + this.saveData(data); + return newNote; + } + updateNote(noteId, updates) { + const data = this.getData(); + if (!data.notes) + data.notes = []; + const note = data.notes.find(n => n.id === noteId); + if (note) { + Object.assign(note, updates); + note.updatedDate = new Date().toISOString(); + this.saveData(data); + } + return note; + } + deleteNote(noteId) { + const data = this.getData(); + if (!data.notes) + data.notes = []; + data.notes = data.notes.filter(n => n.id !== noteId); + this.saveData(data); + } + getNotes() { + const data = this.getData(); + if (!data.notes) + return []; + return data.notes.slice().sort((a, b) => new Date(b.updatedDate ?? b.createdDate).getTime() - new Date(a.updatedDate ?? a.createdDate).getTime()); + } // Points Management addPoints(amount, source) { const data = this.getData(); diff --git a/src/app.ts b/src/app.ts index ad5d0ea..a6772f4 100644 --- a/src/app.ts +++ b/src/app.ts @@ -2,7 +2,7 @@ // Main Application Logic // ======================== -import { StorageManager, storage, STORAGE_VERSION, Task, Habit, FinanceItem, WishItem, getDaysUntilDueText } from './storage.js'; +import { StorageManager, storage, STORAGE_VERSION, Task, Habit, FinanceItem, WishItem, Note, getDaysUntilDueText } from './storage.js'; interface Activity { type: string; @@ -23,6 +23,7 @@ class TaskManager { currentEditingFinanceType: string | null = null; currentEditingRewardId: string | null = null; currentEditingWishItemId: string | null = null; + currentEditingNoteId: string | null = null; dragSrcWishId: string | null = null; selectedDate: Date = new Date(); tasksExpanded: boolean = false; @@ -137,6 +138,12 @@ class TaskManager { document.getElementById('cancelWishItemBtn')!.addEventListener('click', () => this.closeWishItemModal()); document.getElementById('deleteWishItemBtn')!.addEventListener('click', () => this.deleteWishItem()); + // Notes section + document.getElementById('addNoteBtn')!.addEventListener('click', () => this.openNoteModal()); + document.getElementById('noteForm')!.addEventListener('submit', (e) => this.saveNote(e)); + document.getElementById('cancelNoteBtn')!.addEventListener('click', () => this.closeNoteModal()); + document.getElementById('deleteNoteBtn')!.addEventListener('click', () => this.deleteNote()); + // Modal close buttons document.querySelectorAll('.close-btn').forEach(btn => { btn.addEventListener('click', (e) => { @@ -251,6 +258,8 @@ class TaskManager { this.renderShop(); } else if (tabName === 'wishlist') { this.renderWishList(); + } else if (tabName === 'notes') { + this.renderNotes(); } else if (tabName === 'settings') { this.renderSettings(); } @@ -1974,6 +1983,97 @@ class TaskManager { } } + // ======================== + // Notes + // ======================== + renderNotes(): void { + const notes = storage.getNotes(); + const container = document.getElementById('notesList')!; + + if (notes.length === 0) { + container.innerHTML = '

No notes yet. Add one to get started!

'; + return; + } + + container.innerHTML = notes.map(note => this.renderNoteItem(note)).join(''); + + container.querySelectorAll('.note-item').forEach(el => { + el.addEventListener('click', () => { + this.openNoteModal(el.dataset.noteId!); + }); + }); + } + + renderNoteItem(note: Note): string { + const rawPreview = note.content.length > 120 + ? note.content.substring(0, 120) + '…' + : note.content; + const title = this.escapeHtml(note.title || 'Untitled'); + const preview = rawPreview ? this.escapeHtml(rawPreview) : 'No content'; + const date = new Date(note.updatedDate ?? note.createdDate).toLocaleDateString(); + return ` +
+
${title}
+
${preview}
+
${date}
+
+ `; + } + + openNoteModal(noteId: string | null = null): void { + this.currentEditingNoteId = noteId; + const modal = document.getElementById('noteModal')!; + const form = document.getElementById('noteForm') as HTMLFormElement; + const deleteBtn = document.getElementById('deleteNoteBtn') as HTMLElement; + + form.reset(); + deleteBtn.style.display = 'none'; + + document.getElementById('noteModalTitle')!.textContent = noteId ? 'Edit Note' : 'Add Note'; + + if (noteId) { + const note = storage.getNotes().find(n => n.id === noteId); + if (note) { + (document.getElementById('noteTitle') as HTMLInputElement).value = note.title; + (document.getElementById('noteContent') as HTMLTextAreaElement).value = note.content; + deleteBtn.style.display = 'block'; + } + } + + modal.classList.add('active'); + } + + closeNoteModal(): void { + document.getElementById('noteModal')!.classList.remove('active'); + this.currentEditingNoteId = null; + } + + saveNote(e: Event): void { + e.preventDefault(); + + const title = (document.getElementById('noteTitle') as HTMLInputElement).value.trim(); + const content = (document.getElementById('noteContent') as HTMLTextAreaElement).value.trim(); + + if (this.currentEditingNoteId) { + storage.updateNote(this.currentEditingNoteId, { title, content }); + } else { + storage.addNote({ title, content }); + } + + this.closeNoteModal(); + this.renderNotes(); + } + + deleteNote(): void { + if (this.currentEditingNoteId) { + if (confirm('Are you sure you want to delete this note?')) { + storage.deleteNote(this.currentEditingNoteId); + this.closeNoteModal(); + this.renderNotes(); + } + } + } + // ======================== // Settings // ======================== diff --git a/src/storage.ts b/src/storage.ts index e0d95cb..f145287 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -96,6 +96,14 @@ export interface WishItem { createdDate: string; } +export interface Note { + id: string; + title: string; + content: string; + createdDate: string; + updatedDate?: string; +} + export interface PointsBreakdown { tasks: number; projects: number; @@ -133,6 +141,7 @@ export interface AppData { userStats: UserStats; settings: Settings; wishList: WishItem[]; + notes: Note[]; } export interface PurchaseResult { @@ -183,7 +192,8 @@ export class StorageManager { settings: { tasksPerLevel: 30 }, - wishList: [] + wishList: [], + notes: [] }; localStorage.setItem(STORAGE_KEY, JSON.stringify(initialData)); @@ -666,6 +676,48 @@ export class StorageManager { this.saveData(data); } + // Note Management + addNote(note: Partial): Note { + const data = this.getData(); + if (!data.notes) data.notes = []; + const newNote: Note = { + id: this.generateId(), + title: note.title || '', + content: note.content || '', + createdDate: new Date().toISOString(), + }; + data.notes.push(newNote); + this.saveData(data); + return newNote; + } + + updateNote(noteId: string, updates: Partial): Note | undefined { + const data = this.getData(); + if (!data.notes) data.notes = []; + const note = data.notes.find(n => n.id === noteId); + if (note) { + Object.assign(note, updates); + note.updatedDate = new Date().toISOString(); + this.saveData(data); + } + return note; + } + + deleteNote(noteId: string): void { + const data = this.getData(); + if (!data.notes) data.notes = []; + data.notes = data.notes.filter(n => n.id !== noteId); + this.saveData(data); + } + + getNotes(): Note[] { + const data = this.getData(); + if (!data.notes) return []; + return data.notes.slice().sort((a, b) => + new Date(b.updatedDate ?? b.createdDate).getTime() - new Date(a.updatedDate ?? a.createdDate).getTime() + ); + } + // Points Management addPoints(amount: number, source: string): void { const data = this.getData(); diff --git a/tests/storage.test.ts b/tests/storage.test.ts index e5a8925..8594700 100644 --- a/tests/storage.test.ts +++ b/tests/storage.test.ts @@ -623,6 +623,57 @@ describe('StorageManager', () => { expect(storage.getTasks().length).toBe(0); }); }); + + // ======================== + // Note Management + // ======================== + describe('note management', () => { + it('should add a note', () => { + const note = storage.addNote({ title: 'Shopping list', content: 'Milk, eggs' }); + expect(note.id).toBeDefined(); + expect(note.title).toBe('Shopping list'); + expect(note.content).toBe('Milk, eggs'); + expect(note.createdDate).toBeDefined(); + }); + + it('should set default values for note fields', () => { + const note = storage.addNote({}); + expect(note.title).toBe(''); + expect(note.content).toBe(''); + }); + + it('should get all notes sorted by most recently updated', () => { + const a = storage.addNote({ title: 'Note A', content: 'A' }); + const b = storage.addNote({ title: 'Note B', content: 'B' }); + storage.updateNote(a.id, { content: 'A updated' }); + const notes = storage.getNotes(); + expect(notes[0].id).toBe(a.id); + expect(notes[1].id).toBe(b.id); + }); + + it('should update a note and set updatedDate', () => { + const note = storage.addNote({ title: 'Old', content: 'Old content' }); + const updated = storage.updateNote(note.id, { title: 'New', content: 'New content' }); + expect(updated?.title).toBe('New'); + expect(updated?.content).toBe('New content'); + expect(updated?.updatedDate).toBeDefined(); + }); + + it('should return undefined when updating non-existent note', () => { + const result = storage.updateNote('nonexistent', { title: 'Test' }); + expect(result).toBeUndefined(); + }); + + it('should delete a note', () => { + const note = storage.addNote({ title: 'To delete', content: '' }); + storage.deleteNote(note.id); + expect(storage.getNotes().length).toBe(0); + }); + + it('should return empty array when no notes exist', () => { + expect(storage.getNotes()).toEqual([]); + }); + }); }); // ========================