diff --git a/index.html b/index.html index be61163..15fb1d9 100644 --- a/index.html +++ b/index.html @@ -1,78 +1,84 @@ - - - - - - NOTESTACK - - - - -
- - - - - -
- -
- -
- - -
-
- - -
- Labels: -
- - - - -
-
- -
-
-
- - - - -
- -
- - - - + + + + + + NOTESTACK + + + + +
+ + + + + +
+ +
+ +
+ + +
+
+ +
+ + + +
+
+ +
+ Labels: +
+ + + + +
+
+ +
+
+
+ + + + +
+ +
+ + + + diff --git a/script.js b/script.js index 28ad504..206fe3e 100644 --- a/script.js +++ b/script.js @@ -1,473 +1,503 @@ -const noteInput = document.getElementById("noteInput"); -const addNoteBtn = document.getElementById("addNoteBtn"); -const notesGrid = document.getElementById("notesGrid"); -const searchInput = document.getElementById("searchInput"); -const trashGrid = document.getElementById("trashGrid"); -const darkModeBtn = document.getElementById("darkModeBtn"); -const labelCheckboxes = document.querySelectorAll(".label-checkbox"); -let trash = JSON.parse(localStorage.getItem("ultimateTrash")) || []; -let notes = JSON.parse(localStorage.getItem("ultimateNotes")) || []; -let currentFilter = "all"; // Track current category filter -function showEmptyState(container, message) { - container.innerHTML = ` -
-
📝
-

No notes yet

-

${message}

- -
- `; - - const btn = document.getElementById("emptyAddBtn"); - if (btn) { - btn.addEventListener("click", () => { - noteInput.focus(); - }); - } -} -function getSelectedLabels() { - const selected = []; - labelCheckboxes.forEach(checkbox => { - if (checkbox.checked) { - selected.push(checkbox.value); - } - }); - return selected; -} -function filterNotesByCategory(category) { - currentFilter = category; - - if (category === "all") { - renderNotes(searchInput.value); - } else { - const filtered = notes.filter(note => - note.labels && note.labels.includes(category) - ); - - // Create a temporary filtered display - notesGrid.innerHTML = ""; - - if (filtered.length === 0) { - showEmptyState( - notesGrid, - `No ${category} notes found. Start by adding your first note!` -); - return; - } - - filtered.forEach((note, index) => { - const originalIndex = notes.findIndex(n => n.id === note.id); - - const card = document.createElement("div"); - card.className = "note-card"; - - if (note.labels && note.labels.length > 0) { - card.setAttribute('data-labels', note.labels.join(' ')); - - const labelsDiv = document.createElement("div"); - labelsDiv.className = "note-labels"; - - note.labels.forEach(label => { - const labelSpan = document.createElement("span"); - labelSpan.className = `note-label ${label.toLowerCase()}`; - labelSpan.textContent = label; - labelsDiv.appendChild(labelSpan); - }); - - card.appendChild(labelsDiv); - } - - const content = document.createElement("p"); - content.textContent = note.text; - - const actions = document.createElement("div"); - actions.className = "card-actions"; - - const editBtn = document.createElement("button"); - editBtn.textContent = "Edit"; - editBtn.className = "edit-btn"; - editBtn.onclick = () => editNote(originalIndex); - - const deleteBtn = document.createElement("button"); - deleteBtn.textContent = "Delete"; - deleteBtn.className = "delete-btn"; - deleteBtn.onclick = () => deleteNote(originalIndex); - - actions.appendChild(editBtn); - actions.appendChild(deleteBtn); - - card.appendChild(content); - card.appendChild(actions); - - notesGrid.appendChild(card); - }); - } - - // Update active state in sidebar - document.querySelectorAll('.sidebar li').forEach(li => { - li.classList.remove('active'); - }); - document.getElementById(`nav${category}`).classList.add('active'); -} -function saveNotes() { - localStorage.setItem("notestackNotes", JSON.stringify(notes)); -} -// Migrate old notes to new format -notes = notes.map(note => { - if (typeof note === 'string') { - return { - id: Date.now() + Math.random(), - text: note, - labels: [] - }; - } - return note; -}); -saveNotes(); - -function saveTrash() { - localStorage.setItem("ultimateTrash", JSON.stringify(trash)); -} - -function renderNotes(filter = "") { - // If we're in a category view, don't override with search - if (currentFilter !== "all") { - filterNotesByCategory(currentFilter); - return; - } - - notesGrid.innerHTML = ""; - - let filteredNotes = notes; - if (filter.startsWith('#')) { - const labelFilter = filter.substring(1).toLowerCase(); - filteredNotes = notes.filter(note => - note.labels && note.labels.some(label => label.toLowerCase().includes(labelFilter)) - ); - } else { - filteredNotes = notes.filter(note => - note.text.toLowerCase().includes(filter.toLowerCase()) - ); - } - - if (filteredNotes.length === 0 && filter.trim() !== "") { - showEmptyState( - notesGrid, - `No notes found matching "${filter}". Try a different search or add a new note.` -); - return; - } - - filteredNotes.forEach((note, index) => { - const originalIndex = notes.findIndex(n => n.text === note.text && n.id === note.id); - - const card = document.createElement("div"); - card.className = "note-card"; - - if (note.labels && note.labels.length > 0) { - card.setAttribute('data-labels', note.labels.join(' ')); - - const labelsDiv = document.createElement("div"); - labelsDiv.className = "note-labels"; - - note.labels.forEach(label => { - const labelSpan = document.createElement("span"); - labelSpan.className = `note-label ${label.toLowerCase()}`; - labelSpan.textContent = label; - labelsDiv.appendChild(labelSpan); - }); - - card.appendChild(labelsDiv); - } - - const content = document.createElement("p"); - content.textContent = note.text; - - const actions = document.createElement("div"); - actions.className = "card-actions"; - - const editBtn = document.createElement("button"); - editBtn.textContent = "Edit"; - editBtn.className = "edit-btn"; - editBtn.onclick = () => editNote(originalIndex); - - const deleteBtn = document.createElement("button"); - deleteBtn.textContent = "Delete"; - deleteBtn.className = "delete-btn"; - deleteBtn.onclick = () => deleteNote(originalIndex); - - actions.appendChild(editBtn); - actions.appendChild(deleteBtn); - - card.appendChild(content); - card.appendChild(actions); - - notesGrid.appendChild(card); - }); -} -function addNote() { - const text = noteInput.value.trim(); - if (!text) return; - - const selectedLabels = getSelectedLabels(); - - notes.push({ - id: Date.now(), - text: text, - labels: selectedLabels - }); - - noteInput.value = ""; - labelCheckboxes.forEach(cb => cb.checked = false); - - saveNotes(); - renderNotes(searchInput.value); -} - -function deleteNote(index) { - // Store the entire note object, not just the text - trash.push(notes[index]); - notes.splice(index, 1); - saveNotes(); - saveTrash(); - - // Re-render based on current view - if (currentFilter !== "all") { - filterNotesByCategory(currentFilter); - } else { - renderNotes(searchInput.value); - } -} - -function editNote(index) { - const updated = prompt("Edit note:", notes[index].text); - if (updated !== null && updated.trim() !== "") { - notes[index].text = updated.trim(); - saveNotes(); - renderNotes(searchInput.value); - } -} - -addNoteBtn.addEventListener("click", addNote); -searchInput.addEventListener("input", () => { - if (currentFilter !== "all") { - // If in category view, search within that category - const filtered = notes.filter(note => - note.labels && note.labels.includes(currentFilter) && - note.text.toLowerCase().includes(searchInput.value.toLowerCase()) - ); - - notesGrid.innerHTML = ""; - - if (filtered.length === 0) { - notesGrid.innerHTML = `

- No ${currentFilter} notes found matching "${searchInput.value}" -

`; - return; - } - - filtered.forEach((note, index) => { - const originalIndex = notes.findIndex(n => n.id === note.id); - - const card = document.createElement("div"); - card.className = "note-card"; - - if (note.labels && note.labels.length > 0) { - card.setAttribute('data-labels', note.labels.join(' ')); - - const labelsDiv = document.createElement("div"); - labelsDiv.className = "note-labels"; - - note.labels.forEach(label => { - const labelSpan = document.createElement("span"); - labelSpan.className = `note-label ${label.toLowerCase()}`; - labelSpan.textContent = label; - labelsDiv.appendChild(labelSpan); - }); - - card.appendChild(labelsDiv); - } - - const content = document.createElement("p"); - content.textContent = note.text; - - const actions = document.createElement("div"); - actions.className = "card-actions"; - - const editBtn = document.createElement("button"); - editBtn.textContent = "Edit"; - editBtn.className = "edit-btn"; - editBtn.onclick = () => editNote(originalIndex); - - const deleteBtn = document.createElement("button"); - deleteBtn.textContent = "Delete"; - deleteBtn.className = "delete-btn"; - deleteBtn.onclick = () => deleteNote(originalIndex); - - actions.appendChild(editBtn); - actions.appendChild(deleteBtn); - - card.appendChild(content); - card.appendChild(actions); - - notesGrid.appendChild(card); - }); - } else { - renderNotes(searchInput.value); - } -}); -function restoreNote(index) { - notes.push(trash[index]); - trash.splice(index, 1); - saveNotes(); - saveTrash(); - - // If we're in trash view, stay in trash view - if (document.getElementById("trashView").style.display === "block") { - renderTrash(); - } else { - // Otherwise update notes view based on current filter - if (currentFilter !== "all") { - filterNotesByCategory(currentFilter); - } else { - renderNotes(searchInput.value); - } - } -} -function permanentlyDelete(index) { - if (!confirm("Permanently delete this note? This cannot be undone.")) return; - trash.splice(index, 1); - saveTrash(); - renderTrash(); -} - -function renderTrash() { - if (!trashGrid) return; - trashGrid.innerHTML = ""; - - if (trash.length === 0) { - trashGrid.innerHTML = `

Trash is empty

`; - return; - } - - trash.forEach((note, index) => { - const card = document.createElement("div"); - card.className = "note-card"; - - // Handle both old string format and new object format - const noteText = typeof note === 'string' ? note : note.text; - const noteLabels = typeof note === 'object' && note.labels ? note.labels : []; - - // Show labels if they exist - if (noteLabels.length > 0) { - const labelsDiv = document.createElement("div"); - labelsDiv.className = "note-labels"; - - noteLabels.forEach(label => { - const labelSpan = document.createElement("span"); - labelSpan.className = `note-label ${label.toLowerCase()}`; - labelSpan.textContent = label; - labelsDiv.appendChild(labelSpan); - }); - - card.appendChild(labelsDiv); - } - - const content = document.createElement("p"); - content.textContent = noteText; - - const actions = document.createElement("div"); - actions.className = "card-actions"; - - const restoreBtn = document.createElement("button"); - restoreBtn.textContent = "Restore"; - restoreBtn.className = "edit-btn"; - restoreBtn.onclick = () => restoreNote(index); - - const permDeleteBtn = document.createElement("button"); - permDeleteBtn.textContent = "Delete Forever"; - permDeleteBtn.className = "delete-btn"; - permDeleteBtn.onclick = () => permanentlyDelete(index); - - actions.appendChild(restoreBtn); - actions.appendChild(permDeleteBtn); - card.appendChild(content); - card.appendChild(actions); - trashGrid.appendChild(card); - }); -} - - -if (localStorage.getItem("theme") === "dark") { - document.body.classList.add("dark-mode"); - darkModeBtn.textContent = "☀️ Light Mode"; - } - -darkModeBtn.addEventListener("click", () => { - document.body.classList.toggle("dark-mode"); - const isDark = document.body.classList.contains("dark-mode"); - localStorage.setItem("theme", isDark ? "dark" : "light"); - darkModeBtn.textContent = isDark ? "☀️ Light Mode" : "🌙 Dark Mode"; -}); -renderNotes(); -renderTrash(); - -// Sidebar navigation -document.getElementById("navNotes").addEventListener("click", () => { - document.getElementById("notesView").style.display = "block"; - document.getElementById("trashView").style.display = "none"; - document.getElementById("navNotes").classList.add("active"); - document.getElementById("navTrash").classList.remove("active"); -}); - -document.getElementById("navTrash").addEventListener("click", () => { - document.getElementById("notesView").style.display = "none"; - document.getElementById("trashView").style.display = "block"; - document.getElementById("navTrash").classList.add("active"); - document.getElementById("navNotes").classList.remove("active"); - renderTrash(); -}); -// Category filter event listeners -document.getElementById("navImportant").addEventListener("click", () => { - document.getElementById("notesView").style.display = "block"; - document.getElementById("trashView").style.display = "none"; - filterNotesByCategory("Important"); -}); - -document.getElementById("navWork").addEventListener("click", () => { - document.getElementById("notesView").style.display = "block"; - document.getElementById("trashView").style.display = "none"; - filterNotesByCategory("Work"); -}); - -document.getElementById("navPersonal").addEventListener("click", () => { - document.getElementById("notesView").style.display = "block"; - document.getElementById("trashView").style.display = "none"; - filterNotesByCategory("Personal"); -}); - -document.getElementById("navIdeas").addEventListener("click", () => { - document.getElementById("notesView").style.display = "block"; - document.getElementById("trashView").style.display = "none"; - filterNotesByCategory("Ideas"); -}); - -// Update existing All Notes navigation -document.getElementById("navNotes").addEventListener("click", () => { - document.getElementById("notesView").style.display = "block"; - document.getElementById("trashView").style.display = "none"; - filterNotesByCategory("all"); -}); - -// Update Trash navigation -document.getElementById("navTrash").addEventListener("click", () => { - document.getElementById("notesView").style.display = "none"; - document.getElementById("trashView").style.display = "block"; - document.getElementById("navTrash").classList.add("active"); - document.getElementById("navNotes").classList.remove("active"); - document.getElementById("navImportant").classList.remove("active"); - document.getElementById("navWork").classList.remove("active"); - document.getElementById("navPersonal").classList.remove("active"); - document.getElementById("navIdeas").classList.remove("active"); - renderTrash(); +const noteInput = document.getElementById("noteInput"); +const addNoteBtn = document.getElementById("addNoteBtn"); +const notesGrid = document.getElementById("notesGrid"); +const searchInput = document.getElementById("searchInput"); +const trashGrid = document.getElementById("trashGrid"); +const darkModeBtn = document.getElementById("darkModeBtn"); +const labelCheckboxes = document.querySelectorAll(".label-checkbox"); + +// Formatting Toolbar Elements +const boldBtn = document.getElementById("boldBtn"); +const italicBtn = document.getElementById("italicBtn"); +const ulBtn = document.getElementById("ulBtn"); + +let trash = JSON.parse(localStorage.getItem("ultimateTrash")) || []; +let notes = JSON.parse(localStorage.getItem("ultimateNotes")) || []; +let currentFilter = "all"; // Track current category filter +function showEmptyState(container, message) { + container.innerHTML = ` +
+
📝
+

No notes yet

+

${message}

+ +
+ `; + + const btn = document.getElementById("emptyAddBtn"); + if (btn) { + btn.addEventListener("click", () => { + noteInput.focus(); + }); + } +} +function getSelectedLabels() { + const selected = []; + labelCheckboxes.forEach(checkbox => { + if (checkbox.checked) { + selected.push(checkbox.value); + } + }); + return selected; +} +function filterNotesByCategory(category) { + currentFilter = category; + + if (category === "all") { + renderNotes(searchInput.value); + } else { + const filtered = notes.filter(note => + note.labels && note.labels.includes(category) + ); + + // Create a temporary filtered display + notesGrid.innerHTML = ""; + + if (filtered.length === 0) { + showEmptyState( + notesGrid, + `No ${category} notes found. Start by adding your first note!` +); + return; + } + + filtered.forEach((note, index) => { + const originalIndex = notes.findIndex(n => n.id === note.id); + + const card = document.createElement("div"); + card.className = "note-card"; + + if (note.labels && note.labels.length > 0) { + card.setAttribute('data-labels', note.labels.join(' ')); + + const labelsDiv = document.createElement("div"); + labelsDiv.className = "note-labels"; + + note.labels.forEach(label => { + const labelSpan = document.createElement("span"); + labelSpan.className = `note-label ${label.toLowerCase()}`; + labelSpan.textContent = label; + labelsDiv.appendChild(labelSpan); + }); + + card.appendChild(labelsDiv); + } + + const content = document.createElement("div"); // Use div to hold HTML + content.className = "note-text"; + content.innerHTML = note.text; // Render HTML directly + + const actions = document.createElement("div"); + actions.className = "card-actions"; + + const editBtn = document.createElement("button"); + editBtn.textContent = "Edit"; + editBtn.className = "edit-btn"; + editBtn.onclick = () => editNote(originalIndex); + + const deleteBtn = document.createElement("button"); + deleteBtn.textContent = "Delete"; + deleteBtn.className = "delete-btn"; + deleteBtn.onclick = () => deleteNote(originalIndex); + + actions.appendChild(editBtn); + actions.appendChild(deleteBtn); + + card.appendChild(content); + card.appendChild(actions); + + notesGrid.appendChild(card); + }); + } + + // Update active state in sidebar + document.querySelectorAll('.sidebar li').forEach(li => { + li.classList.remove('active'); + }); + document.getElementById(`nav${category}`).classList.add('active'); +} +function saveNotes() { + localStorage.setItem("notestackNotes", JSON.stringify(notes)); +} +// Migrate old notes to new format +notes = notes.map(note => { + if (typeof note === 'string') { + return { + id: Date.now() + Math.random(), + text: note, + labels: [] + }; + } + return note; +}); +saveNotes(); + +function saveTrash() { + localStorage.setItem("ultimateTrash", JSON.stringify(trash)); +} + +function renderNotes(filter = "") { + // If we're in a category view, don't override with search + if (currentFilter !== "all") { + filterNotesByCategory(currentFilter); + return; + } + + notesGrid.innerHTML = ""; + + let filteredNotes = notes; + if (filter.startsWith('#')) { + const labelFilter = filter.substring(1).toLowerCase(); + filteredNotes = notes.filter(note => + note.labels && note.labels.some(label => label.toLowerCase().includes(labelFilter)) + ); + } else { + filteredNotes = notes.filter(note => + note.text.toLowerCase().includes(filter.toLowerCase()) + ); + } + + if (filteredNotes.length === 0 && filter.trim() !== "") { + showEmptyState( + notesGrid, + `No notes found matching "${filter}". Try a different search or add a new note.` +); + return; + } + + filteredNotes.forEach((note, index) => { + const originalIndex = notes.findIndex(n => n.text === note.text && n.id === note.id); + + const card = document.createElement("div"); + card.className = "note-card"; + + if (note.labels && note.labels.length > 0) { + card.setAttribute('data-labels', note.labels.join(' ')); + + const labelsDiv = document.createElement("div"); + labelsDiv.className = "note-labels"; + + note.labels.forEach(label => { + const labelSpan = document.createElement("span"); + labelSpan.className = `note-label ${label.toLowerCase()}`; + labelSpan.textContent = label; + labelsDiv.appendChild(labelSpan); + }); + + card.appendChild(labelsDiv); + } + + const content = document.createElement("div"); // Use div to hold HTML + content.className = "note-text"; + content.innerHTML = note.text; // Render HTML directly + + const actions = document.createElement("div"); + actions.className = "card-actions"; + + const editBtn = document.createElement("button"); + editBtn.textContent = "Edit"; + editBtn.className = "edit-btn"; + editBtn.onclick = () => editNote(originalIndex); + + const deleteBtn = document.createElement("button"); + deleteBtn.textContent = "Delete"; + deleteBtn.className = "delete-btn"; + deleteBtn.onclick = () => deleteNote(originalIndex); + + actions.appendChild(editBtn); + actions.appendChild(deleteBtn); + + card.appendChild(content); + card.appendChild(actions); + + notesGrid.appendChild(card); + }); +} +function addNote() { + // Read from the contenteditable div + const textHTML = noteInput.innerHTML.trim(); + const textPlain = noteInput.innerText.trim(); + if (!textPlain) return; // Prevent empty notes + + const selectedLabels = getSelectedLabels(); + + notes.push({ + id: Date.now(), + text: textHTML, // Save the HTML content + labels: selectedLabels + }); + + noteInput.innerHTML = ""; // Clear contenteditable + labelCheckboxes.forEach(cb => cb.checked = false); + + saveNotes(); + renderNotes(searchInput.value); +} + +function deleteNote(index) { + // Store the entire note object, not just the text + trash.push(notes[index]); + notes.splice(index, 1); + saveNotes(); + saveTrash(); + + // Re-render based on current view + if (currentFilter !== "all") { + filterNotesByCategory(currentFilter); + } else { + renderNotes(searchInput.value); + } +} + +function editNote(index) { + const updated = prompt("Edit note:", notes[index].text); + if (updated !== null && updated.trim() !== "") { + notes[index].text = updated.trim(); + saveNotes(); + renderNotes(searchInput.value); + } +} + +addNoteBtn.addEventListener("click", addNote); + +// --- Formatting Logic --- +function formatText(command) { + document.execCommand(command, false, null); + noteInput.focus(); +} + +if (boldBtn) boldBtn.addEventListener("click", () => formatText("bold")); +if (italicBtn) italicBtn.addEventListener("click", () => formatText("italic")); +if (ulBtn) ulBtn.addEventListener("click", () => formatText("insertUnorderedList")); + +// Ensure contenteditable div handles paragraphs cleanly on enter +noteInput.addEventListener("keydown", (e) => { + if (e.key === "Enter" && !e.shiftKey) { + // Just let it do default div/br insertion for simple rich text + } +}); + +searchInput.addEventListener("input", () => { + if (currentFilter !== "all") { + // If in category view, search within that category + const filtered = notes.filter(note => + note.labels && note.labels.includes(currentFilter) && + note.text.toLowerCase().includes(searchInput.value.toLowerCase()) + ); + + notesGrid.innerHTML = ""; + + if (filtered.length === 0) { + notesGrid.innerHTML = `

+ No ${currentFilter} notes found matching "${searchInput.value}" +

`; + return; + } + + filtered.forEach((note, index) => { + const originalIndex = notes.findIndex(n => n.id === note.id); + + const card = document.createElement("div"); + card.className = "note-card"; + + if (note.labels && note.labels.length > 0) { + card.setAttribute('data-labels', note.labels.join(' ')); + + const labelsDiv = document.createElement("div"); + labelsDiv.className = "note-labels"; + + note.labels.forEach(label => { + const labelSpan = document.createElement("span"); + labelSpan.className = `note-label ${label.toLowerCase()}`; + labelSpan.textContent = label; + labelsDiv.appendChild(labelSpan); + }); + + card.appendChild(labelsDiv); + } + + const content = document.createElement("div"); // Use div to hold HTML + content.className = "note-text"; + content.innerHTML = note.text; // Render HTML directly + + const actions = document.createElement("div"); + actions.className = "card-actions"; + + const editBtn = document.createElement("button"); + editBtn.textContent = "Edit"; + editBtn.className = "edit-btn"; + editBtn.onclick = () => editNote(originalIndex); + + const deleteBtn = document.createElement("button"); + deleteBtn.textContent = "Delete"; + deleteBtn.className = "delete-btn"; + deleteBtn.onclick = () => deleteNote(originalIndex); + + actions.appendChild(editBtn); + actions.appendChild(deleteBtn); + + card.appendChild(content); + card.appendChild(actions); + + notesGrid.appendChild(card); + }); + } else { + renderNotes(searchInput.value); + } +}); +function restoreNote(index) { + notes.push(trash[index]); + trash.splice(index, 1); + saveNotes(); + saveTrash(); + + // If we're in trash view, stay in trash view + if (document.getElementById("trashView").style.display === "block") { + renderTrash(); + } else { + // Otherwise update notes view based on current filter + if (currentFilter !== "all") { + filterNotesByCategory(currentFilter); + } else { + renderNotes(searchInput.value); + } + } +} +function permanentlyDelete(index) { + if (!confirm("Permanently delete this note? This cannot be undone.")) return; + trash.splice(index, 1); + saveTrash(); + renderTrash(); +} + +function renderTrash() { + if (!trashGrid) return; + trashGrid.innerHTML = ""; + + if (trash.length === 0) { + trashGrid.innerHTML = `

Trash is empty

`; + return; + } + + trash.forEach((note, index) => { + const card = document.createElement("div"); + card.className = "note-card"; + + // Handle both old string format and new object format + const noteText = typeof note === 'string' ? note : note.text; + const noteLabels = typeof note === 'object' && note.labels ? note.labels : []; + + // Show labels if they exist + if (noteLabels.length > 0) { + const labelsDiv = document.createElement("div"); + labelsDiv.className = "note-labels"; + + noteLabels.forEach(label => { + const labelSpan = document.createElement("span"); + labelSpan.className = `note-label ${label.toLowerCase()}`; + labelSpan.textContent = label; + labelsDiv.appendChild(labelSpan); + }); + + card.appendChild(labelsDiv); + } + + const content = document.createElement("div"); // Use div to hold HTML + content.className = "note-text"; + content.innerHTML = noteText; // Render HTML directly + + const actions = document.createElement("div"); + actions.className = "card-actions"; + + const restoreBtn = document.createElement("button"); + restoreBtn.textContent = "Restore"; + restoreBtn.className = "edit-btn"; + restoreBtn.onclick = () => restoreNote(index); + + const permDeleteBtn = document.createElement("button"); + permDeleteBtn.textContent = "Delete Forever"; + permDeleteBtn.className = "delete-btn"; + permDeleteBtn.onclick = () => permanentlyDelete(index); + + actions.appendChild(restoreBtn); + actions.appendChild(permDeleteBtn); + card.appendChild(content); + card.appendChild(actions); + trashGrid.appendChild(card); + }); +} + + +if (localStorage.getItem("theme") === "dark") { + document.body.classList.add("dark-mode"); + darkModeBtn.textContent = "☀️ Light Mode"; + } + +darkModeBtn.addEventListener("click", () => { + document.body.classList.toggle("dark-mode"); + const isDark = document.body.classList.contains("dark-mode"); + localStorage.setItem("theme", isDark ? "dark" : "light"); + darkModeBtn.textContent = isDark ? "☀️ Light Mode" : "🌙 Dark Mode"; +}); +renderNotes(); +renderTrash(); + +// Sidebar navigation +document.getElementById("navNotes").addEventListener("click", () => { + document.getElementById("notesView").style.display = "block"; + document.getElementById("trashView").style.display = "none"; + document.getElementById("navNotes").classList.add("active"); + document.getElementById("navTrash").classList.remove("active"); +}); + +document.getElementById("navTrash").addEventListener("click", () => { + document.getElementById("notesView").style.display = "none"; + document.getElementById("trashView").style.display = "block"; + document.getElementById("navTrash").classList.add("active"); + document.getElementById("navNotes").classList.remove("active"); + renderTrash(); +}); +// Category filter event listeners +document.getElementById("navImportant").addEventListener("click", () => { + document.getElementById("notesView").style.display = "block"; + document.getElementById("trashView").style.display = "none"; + filterNotesByCategory("Important"); +}); + +document.getElementById("navWork").addEventListener("click", () => { + document.getElementById("notesView").style.display = "block"; + document.getElementById("trashView").style.display = "none"; + filterNotesByCategory("Work"); +}); + +document.getElementById("navPersonal").addEventListener("click", () => { + document.getElementById("notesView").style.display = "block"; + document.getElementById("trashView").style.display = "none"; + filterNotesByCategory("Personal"); +}); + +document.getElementById("navIdeas").addEventListener("click", () => { + document.getElementById("notesView").style.display = "block"; + document.getElementById("trashView").style.display = "none"; + filterNotesByCategory("Ideas"); +}); + +// Update existing All Notes navigation +document.getElementById("navNotes").addEventListener("click", () => { + document.getElementById("notesView").style.display = "block"; + document.getElementById("trashView").style.display = "none"; + filterNotesByCategory("all"); +}); + +// Update Trash navigation +document.getElementById("navTrash").addEventListener("click", () => { + document.getElementById("notesView").style.display = "none"; + document.getElementById("trashView").style.display = "block"; + document.getElementById("navTrash").classList.add("active"); + document.getElementById("navNotes").classList.remove("active"); + document.getElementById("navImportant").classList.remove("active"); + document.getElementById("navWork").classList.remove("active"); + document.getElementById("navPersonal").classList.remove("active"); + document.getElementById("navIdeas").classList.remove("active"); + renderTrash(); }); \ No newline at end of file diff --git a/style.css b/style.css index 0392735..49c6daf 100644 --- a/style.css +++ b/style.css @@ -1,395 +1,497 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; - font-family: 'Segoe UI', sans-serif; -} - -body { - background: #f1f3f4; -} - -.app { - display: flex; - height: 100vh; -} - -.sidebar { - width: 230px; - background: white; - padding: 20px; - border-right: 1px solid #ddd; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.sidebar h2 { - margin-bottom: 30px; -} - -.sidebar ul { - list-style: none; -} - -.sidebar li { - padding: 10px; - border-radius: 8px; - margin-bottom: 10px; - cursor: pointer; - transition: 0.2s; -} - -.sidebar li.active, -.sidebar li:hover { - background: #e8f0fe; -} - -#darkModeBtn { - padding: 8px; - border: none; - border-radius: 6px; - cursor: pointer; -} - -.main { - flex: 1; - padding: 20px 40px; - overflow-y: auto; -} - -.topbar { - margin-bottom: 20px; -} - -.topbar input { - width: 100%; - padding: 12px; - border-radius: 8px; - border: 1px solid #ccc; -} - -.create-note { - background: white; - padding: 15px; - border-radius: 12px; - box-shadow: 0 4px 12px rgba(0,0,0,0.08); - margin-bottom: 30px; -} - -.create-note textarea { - width: 100%; - border: none; - resize: none; - outline: none; - font-size: 16px; - min-height: 60px; -} - -#addNoteBtn { - margin-top: 10px; - padding: 8px 14px; - border: none; - border-radius: 6px; - background: #1a73e8; - color: white; - cursor: pointer; -} - -.notes-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); - gap: 20px; -} - -.note-card { - background: #fff; - padding: 15px; - border-radius: 12px; - box-shadow: 0 4px 10px rgba(0,0,0,0.08); - transition: 0.2s; -} - -.note-card:hover { - transform: translateY(-5px); -} - -.note-card p { - white-space: pre-wrap; -} - -.card-actions { - margin-top: 10px; - display: flex; - justify-content: flex-end; - gap: 8px; -} - -.card-actions button { - padding: 5px 8px; - border: none; - border-radius: 6px; - cursor: pointer; - font-size: 12px; -} - -.edit-btn { - background: #34a853; - color: white; -} - -.delete-btn { - background: #ea4335; - color: white; -} -/* REPLACE your existing dark mode styles at the bottom with these */ - -.dark-mode { - background-color: #121212; - color: #e8eaed; -} - -/* 1. Sidebar contrast + active state alignment */ -.dark-mode .sidebar { - background-color: #1e1e1e; - border-right: 1px solid #333; - color: #e8eaed; -} - -.dark-mode .sidebar h2 { - color: #ffffff; -} - -.dark-mode .sidebar li { - color: #c4c7cc; -} - -.dark-mode .sidebar li.active { - background: #2d3748; - color: #ffffff; - font-weight: 600; - border-left: 3px solid #1a73e8; -} - -.dark-mode .sidebar li:hover { - background: #2a2a2a; - color: #ffffff; -} - -/* 2. Main content depth and separation */ -.dark-mode .main { - background-color: #181818; -} - -.dark-mode .topbar input { - background-color: #2a2a2a; - color: #e8eaed; - border: 1px solid #444; - border-radius: 8px; -} - -.dark-mode .topbar input::placeholder { - color: #9aa0a6; -} - -/* 3. Create note card visual depth */ -.dark-mode .create-note { - background-color: #1e1e1e; - border: 1px solid #333; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); -} - -.dark-mode .create-note textarea { - background-color: #1e1e1e; - color: #e8eaed; - border: none; -} - -.dark-mode .create-note textarea::placeholder { - color: #9aa0a6; -} - -/* 4. Note cards with hierarchy and separation */ -.dark-mode .note-card { - background-color: #242424; - border: 1px solid #333; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); - color: #e8eaed; -} - -.dark-mode .note-card:hover { - background-color: #2a2a2a; - border-color: #555; -} - -/* Dark mode button */ -.dark-mode #darkModeBtn { - background-color: #2d3748; - color: #e8eaed; - border: 1px solid #444; -} - -/* Keep action buttons their original colors */ -.dark-mode .edit-btn { - background: #34a853; - color: white; -} - -.dark-mode .delete-btn { - background: #ea4335; - color: white; -} -/* Label Selector Styles */ -.label-selector { - margin: 10px 0; - padding: 10px; - border-top: 1px solid #eee; - border-bottom: 1px solid #eee; -} - -.label-title { - font-size: 14px; - color: #666; - display: block; - margin-bottom: 8px; -} - -.label-options { - display: flex; - flex-wrap: wrap; - gap: 15px; -} - -.label-option { - display: flex; - align-items: center; - gap: 5px; - cursor: pointer; - font-size: 14px; -} - -.label-checkbox { - cursor: pointer; -} - -.label-dot { - width: 12px; - height: 12px; - border-radius: 50%; - display: inline-block; -} - -.label-dot.important { background-color: #f28b82; } -.label-dot.work { background-color: #fbbc04; } -.label-dot.personal { background-color: #4285f4; } -.label-dot.ideas { background-color: #81c995; } - -.note-card { - border-left: 4px solid transparent; -} - -.note-card[data-labels*="Important"] { border-left-color: #f28b82; } -.note-card[data-labels*="Work"] { border-left-color: #fbbc04; } -.note-card[data-labels*="Personal"] { border-left-color: #4285f4; } -.note-card[data-labels*="Ideas"] { border-left-color: #81c995; } - -.note-labels { - display: flex; - flex-wrap: wrap; - gap: 8px; - margin-bottom: 10px; -} - -.note-label { - font-size: 11px; - padding: 4px 8px; - border-radius: 12px; - color: white; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.note-label.important { background-color: #f28b82; } -.note-label.work { background-color: #fbbc04; color: #333; } -.note-label.personal { background-color: #4285f4; } -.note-label.ideas { background-color: #81c995; color: #333; } - -.dark-mode .label-selector { - border-top-color: #333; - border-bottom-color: #333; -} - -.dark-mode .label-title { - color: #9aa0a6; -} - -.dark-mode .label-option { - color: #e8eaed; -} -/* Category indicators in sidebar */ -.sidebar li i { - margin-right: 8px; - font-style: normal; -} - -.sidebar li[class*="important"] { border-left: 3px solid transparent; } -.sidebar li[class*="important"].active { border-left-color: #f28b82; } - -.sidebar li[class*="work"].active { border-left-color: #fbbc04; } -.sidebar li[class*="personal"].active { border-left-color: #4285f4; } -.sidebar li[class*="ideas"].active { border-left-color: #81c995; } -/* ================= EMPTY STATE ================= */ - -.empty-state { - text-align: center; - padding: 40px 20px; - background: white; - border-radius: 12px; - box-shadow: 0 4px 12px rgba(0,0,0,0.08); - margin-top: 20px; -} - -.empty-icon { - font-size: 40px; - margin-bottom: 10px; -} - -.empty-state h3 { - margin: 10px 0; - color: #333; -} - -.empty-state p { - color: #777; - margin-bottom: 15px; -} - -.empty-state button { - padding: 8px 16px; - border: none; - border-radius: 6px; - background: #1a73e8; - color: white; - cursor: pointer; - transition: 0.2s ease; -} - -.empty-state button:hover { - background: #1558b0; - transform: translateY(-2px); -} - -/* Dark mode support */ -.dark-mode .empty-state { - background: #1e1e1e; - border: 1px solid #333; -} - -.dark-mode .empty-state h3 { - color: #e8eaed; -} - -.dark-mode .empty-state p { - color: #9aa0a6; +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Segoe UI', sans-serif; +} + +body { + background: #f1f3f4; +} + +.app { + display: flex; + height: 100vh; +} + +.sidebar { + width: 230px; + background: white; + padding: 20px; + border-right: 1px solid #ddd; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.sidebar h2 { + margin-bottom: 30px; +} + +.sidebar ul { + list-style: none; +} + +.sidebar li { + padding: 10px; + border-radius: 8px; + margin-bottom: 10px; + cursor: pointer; + transition: 0.2s; +} + +.sidebar li.active, +.sidebar li:hover { + background: #e8f0fe; +} + +#darkModeBtn { + padding: 8px; + border: none; + border-radius: 6px; + cursor: pointer; +} + +.main { + flex: 1; + padding: 20px 40px; + overflow-y: auto; +} + +.topbar { + margin-bottom: 20px; +} + +.topbar input { + width: 100%; + padding: 12px; + border-radius: 8px; + border: 1px solid #ccc; +} + +.create-note { + background: white; + padding: 15px; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + margin-bottom: 30px; +} + +.create-note [contenteditable] { + width: 100%; + border: none; + outline: none; + font-size: 16px; + min-height: 60px; + padding: 10px 0; +} + +.create-note [contenteditable]:empty::before { + content: attr(data-placeholder); + color: #777; + pointer-events: none; + display: block; +} + +.format-toolbar { + display: flex; + gap: 8px; + margin-bottom: 10px; + padding-bottom: 10px; + border-bottom: 1px solid #eee; +} + +.format-btn { + background: transparent; + border: none; + padding: 6px 10px; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + color: #333; + transition: 0.2s; +} + +.format-btn:hover { + background: #f1f3f4; +} + +.format-btn i { + font-family: serif; + font-style: italic; +} + +.format-btn b { + font-weight: bold; +} + +#addNoteBtn { + margin-top: 10px; + padding: 8px 14px; + border: none; + border-radius: 6px; + background: #1a73e8; + color: white; + cursor: pointer; +} + +.notes-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 20px; +} + +.note-card { + background: #fff; + padding: 15px; + border-radius: 12px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08); + transition: 0.2s; +} + +.note-card:hover { + transform: translateY(-5px); +} + +.note-card p { + white-space: pre-wrap; +} + +.card-actions { + margin-top: 10px; + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.card-actions button { + padding: 5px 8px; + border: none; + border-radius: 6px; + cursor: pointer; + font-size: 12px; +} + +.edit-btn { + background: #34a853; + color: white; +} + +.delete-btn { + background: #ea4335; + color: white; +} + +/* REPLACE your existing dark mode styles at the bottom with these */ + +.dark-mode { + background-color: #121212; + color: #e8eaed; +} + +/* 1. Sidebar contrast + active state alignment */ +.dark-mode .sidebar { + background-color: #1e1e1e; + border-right: 1px solid #333; + color: #e8eaed; +} + +.dark-mode .sidebar h2 { + color: #ffffff; +} + +.dark-mode .sidebar li { + color: #c4c7cc; +} + +.dark-mode .sidebar li.active { + background: #2d3748; + color: #ffffff; + font-weight: 600; + border-left: 3px solid #1a73e8; +} + +.dark-mode .sidebar li:hover { + background: #2a2a2a; + color: #ffffff; +} + +/* 2. Main content depth and separation */ +.dark-mode .main { + background-color: #181818; +} + +.dark-mode .topbar input { + background-color: #2a2a2a; + color: #e8eaed; + border: 1px solid #444; + border-radius: 8px; +} + +.dark-mode .topbar input::placeholder { + color: #9aa0a6; +} + +/* 3. Create note card visual depth */ +.dark-mode .create-note { + background-color: #1e1e1e; + border: 1px solid #333; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +.dark-mode .create-note [contenteditable] { + background-color: #1e1e1e; + color: #e8eaed; +} + +.dark-mode .create-note [contenteditable]:empty::before { + color: #9aa0a6; +} + +.dark-mode .format-toolbar { + border-bottom-color: #333; +} + +.dark-mode .format-btn { + color: #e8eaed; +} + +.dark-mode .format-btn:hover { + background: #333; +} + +/* 4. Note cards with hierarchy and separation */ +.dark-mode .note-card { + background-color: #242424; + border: 1px solid #333; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + color: #e8eaed; +} + +.dark-mode .note-card:hover { + background-color: #2a2a2a; + border-color: #555; +} + +/* Dark mode button */ +.dark-mode #darkModeBtn { + background-color: #2d3748; + color: #e8eaed; + border: 1px solid #444; +} + +/* Keep action buttons their original colors */ +.dark-mode .edit-btn { + background: #34a853; + color: white; +} + +.dark-mode .delete-btn { + background: #ea4335; + color: white; +} + +/* Label Selector Styles */ +.label-selector { + margin: 10px 0; + padding: 10px; + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; +} + +.label-title { + font-size: 14px; + color: #666; + display: block; + margin-bottom: 8px; +} + +.label-options { + display: flex; + flex-wrap: wrap; + gap: 15px; +} + +.label-option { + display: flex; + align-items: center; + gap: 5px; + cursor: pointer; + font-size: 14px; +} + +.label-checkbox { + cursor: pointer; +} + +.label-dot { + width: 12px; + height: 12px; + border-radius: 50%; + display: inline-block; +} + +.label-dot.important { + background-color: #f28b82; +} + +.label-dot.work { + background-color: #fbbc04; +} + +.label-dot.personal { + background-color: #4285f4; +} + +.label-dot.ideas { + background-color: #81c995; +} + +.note-card { + border-left: 4px solid transparent; +} + +.note-card[data-labels*="Important"] { + border-left-color: #f28b82; +} + +.note-card[data-labels*="Work"] { + border-left-color: #fbbc04; +} + +.note-card[data-labels*="Personal"] { + border-left-color: #4285f4; +} + +.note-card[data-labels*="Ideas"] { + border-left-color: #81c995; +} + +.note-labels { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 10px; +} + +.note-label { + font-size: 11px; + padding: 4px 8px; + border-radius: 12px; + color: white; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.note-label.important { + background-color: #f28b82; +} + +.note-label.work { + background-color: #fbbc04; + color: #333; +} + +.note-label.personal { + background-color: #4285f4; +} + +.note-label.ideas { + background-color: #81c995; + color: #333; +} + +.dark-mode .label-selector { + border-top-color: #333; + border-bottom-color: #333; +} + +.dark-mode .label-title { + color: #9aa0a6; +} + +.dark-mode .label-option { + color: #e8eaed; +} + +/* Category indicators in sidebar */ +.sidebar li i { + margin-right: 8px; + font-style: normal; +} + +.sidebar li[class*="important"] { + border-left: 3px solid transparent; +} + +.sidebar li[class*="important"].active { + border-left-color: #f28b82; +} + +.sidebar li[class*="work"].active { + border-left-color: #fbbc04; +} + +.sidebar li[class*="personal"].active { + border-left-color: #4285f4; +} + +.sidebar li[class*="ideas"].active { + border-left-color: #81c995; +} + +/* ================= EMPTY STATE ================= */ + +.empty-state { + text-align: center; + padding: 40px 20px; + background: white; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + margin-top: 20px; +} + +.empty-icon { + font-size: 40px; + margin-bottom: 10px; +} + +.empty-state h3 { + margin: 10px 0; + color: #333; +} + +.empty-state p { + color: #777; + margin-bottom: 15px; +} + +.empty-state button { + padding: 8px 16px; + border: none; + border-radius: 6px; + background: #1a73e8; + color: white; + cursor: pointer; + transition: 0.2s ease; +} + +.empty-state button:hover { + background: #1558b0; + transform: translateY(-2px); +} + +/* Dark mode support */ +.dark-mode .empty-state { + background: #1e1e1e; + border: 1px solid #333; +} + +.dark-mode .empty-state h3 { + color: #e8eaed; +} + +.dark-mode .empty-state p { + color: #9aa0a6; } \ No newline at end of file