From 8d8517644e1ffdc149aad028f6eaf912303419f7 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Fri, 3 Oct 2025 17:09:57 +0530 Subject: [PATCH 01/12] soft delete functionality implemented --- src/components/NoteCard.tsx | 4 ++-- src/components/NoteEditor.tsx | 2 +- src/components/NotesSidebar.tsx | 7 +++++-- src/hooks/useNotes.ts | 9 +++++++++ src/pages/Index.tsx | 16 ++++++++++++---- src/types/note.ts | 1 + 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index 4d0f377..8bdcb2d 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -14,7 +14,6 @@ import { AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'; - interface NoteCardProps { note: Note; isActive: boolean; @@ -23,6 +22,7 @@ interface NoteCardProps { } export function NoteCard({ note, isActive, onClick, onDelete }: NoteCardProps) { + const preview = note.content.slice(0, 100) || 'No content'; return ( @@ -66,7 +66,7 @@ export function NoteCard({ note, isActive, onClick, onDelete }: NoteCardProps) { Delete Note - Are you sure you want to delete this note? This action cannot be undone. + This note will be moved to the recycle bin and can be restored later. Are you sure you want to continue? diff --git a/src/components/NoteEditor.tsx b/src/components/NoteEditor.tsx index 03d94a5..321d201 100644 --- a/src/components/NoteEditor.tsx +++ b/src/components/NoteEditor.tsx @@ -60,7 +60,7 @@ export function NoteEditor({ note, onUpdate, onDelete }: NoteEditorProps) { Delete Note - Are you sure you want to delete this note? This action cannot be undone. + This note will be moved to the recycle bin and can be restored later. Are you sure you want to continue? diff --git a/src/components/NotesSidebar.tsx b/src/components/NotesSidebar.tsx index 55d8f7d..5661145 100644 --- a/src/components/NotesSidebar.tsx +++ b/src/components/NotesSidebar.tsx @@ -13,6 +13,7 @@ interface NotesSidebarProps { activeNoteId: string | null; onSelectNote: (id: string) => void; onCreateNote: () => void; + onDelete: (id: string) => void; } export function NotesSidebar({ @@ -20,13 +21,14 @@ export function NotesSidebar({ activeNoteId, onSelectNote, onCreateNote, + onDelete, }: NotesSidebarProps) { const [searchQuery, setSearchQuery] = useState(''); const filteredNotes = notes.filter( (note) => - note.title.toLowerCase().includes(searchQuery.toLowerCase()) || - note.content.toLowerCase().includes(searchQuery.toLowerCase()) + (note.title.toLowerCase().includes(searchQuery.toLowerCase()) || + note.content.toLowerCase().includes(searchQuery.toLowerCase())) && !note.deleted ); return ( @@ -102,6 +104,7 @@ export function NotesSidebar({ note={note} isActive={note.id === activeNoteId} onClick={() => onSelectNote(note.id)} + onDelete={onDelete} /> )) )} diff --git a/src/hooks/useNotes.ts b/src/hooks/useNotes.ts index 5825a75..a3ba8f3 100644 --- a/src/hooks/useNotes.ts +++ b/src/hooks/useNotes.ts @@ -55,10 +55,19 @@ export function useNotes() { setNotes((prev) => prev.filter((note) => note.id !== id)); }; + const softDeleteNote = (id: string) => { + setNotes((prev) => + prev.map((note) => + note.id === id ? { ...note, deleted: true } : note + ) + ); + }; + return { notes, createNote, updateNote, deleteNote, + softDeleteNote }; } diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 52c51a0..5567fab 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -5,7 +5,7 @@ import { NoteEditor } from '@/components/NoteEditor'; import { FileText, ArrowLeft } from 'lucide-react'; const Index = () => { - const { notes, createNote, updateNote, deleteNote } = useNotes(); + const { notes, createNote, updateNote, deleteNote, softDeleteNote } = useNotes(); const [activeNoteId, setActiveNoteId] = useState(null); const [isMobile, setIsMobile] = useState(false); @@ -27,8 +27,14 @@ const Index = () => { setActiveNoteId(notes.length > 1 ? notes[0].id : null); } }; + const handleSoftDeleteNote = (id: string) => { + softDeleteNote(id); + if (activeNoteId === id) { + setActiveNoteId(null); + } + }; - const activeNote = notes.find((note) => note.id === activeNoteId); + const activeNote = notes.find((note) => note.id === activeNoteId && !note.deleted); return (
@@ -40,6 +46,7 @@ const Index = () => { activeNoteId={activeNoteId} onSelectNote={setActiveNoteId} onCreateNote={handleCreateNote} + onDelete={handleSoftDeleteNote} />
{activeNote ? ( @@ -47,7 +54,7 @@ const Index = () => {
) : ( @@ -75,7 +82,7 @@ const Index = () => { ) : ( @@ -84,6 +91,7 @@ const Index = () => { activeNoteId={activeNoteId} onSelectNote={setActiveNoteId} onCreateNote={handleCreateNote} + onDelete={handleSoftDeleteNote} /> )} diff --git a/src/types/note.ts b/src/types/note.ts index 7efe349..387ac92 100644 --- a/src/types/note.ts +++ b/src/types/note.ts @@ -4,6 +4,7 @@ export interface Note { content: string; createdAt: Date; updatedAt: Date; + deleted?: boolean; } // Utility function to format timestamps export const formatTimestamp = (date: Date, locale: string = 'en-US'): string => { From fef453e7ae6e4d61cc37bc91685f1c29bd9be890 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Fri, 3 Oct 2025 19:41:02 +0530 Subject: [PATCH 02/12] recycle bin page created --- src/App.tsx | 1 + src/components/NoteCard.tsx | 8 ++- src/components/NoteEditor.tsx | 8 ++- src/components/NotesSidebar.tsx | 113 +++++++++++++++++++++----------- src/pages/Index.tsx | 16 +++-- 5 files changed, 99 insertions(+), 47 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 18daf2e..9cdc3d3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,6 +16,7 @@ const App = () => ( } /> + } /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} } /> diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index 8bdcb2d..f63f054 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -14,6 +14,7 @@ import { AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'; +import { useLocation } from 'react-router-dom'; interface NoteCardProps { note: Note; isActive: boolean; @@ -22,6 +23,8 @@ interface NoteCardProps { } export function NoteCard({ note, isActive, onClick, onDelete }: NoteCardProps) { + const path = useLocation()?.pathname + const deletePage = path === '/recycle-bin' const preview = note.content.slice(0, 100) || 'No content'; @@ -66,7 +69,10 @@ export function NoteCard({ note, isActive, onClick, onDelete }: NoteCardProps) { Delete Note - This note will be moved to the recycle bin and can be restored later. Are you sure you want to continue? + { + deletePage ? "This note will be permanently deleted and cannot be recovered. Are you sure you want to continue?" : + "This note will be moved to the recycle bin and can be restored later. Are you sure you want to continue?" + } diff --git a/src/components/NoteEditor.tsx b/src/components/NoteEditor.tsx index 321d201..7d54288 100644 --- a/src/components/NoteEditor.tsx +++ b/src/components/NoteEditor.tsx @@ -15,6 +15,7 @@ import { AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'; +import { useLocation } from 'react-router-dom'; interface NoteEditorProps { note: Note; @@ -25,6 +26,8 @@ interface NoteEditorProps { export function NoteEditor({ note, onUpdate, onDelete }: NoteEditorProps) { const [title, setTitle] = useState(note.title); const [content, setContent] = useState(note.content); + const path = useLocation()?.pathname + const deletePage = path === '/recycle-bin' useEffect(() => { setTitle(note.title); @@ -60,7 +63,10 @@ export function NoteEditor({ note, onUpdate, onDelete }: NoteEditorProps) { Delete Note - This note will be moved to the recycle bin and can be restored later. Are you sure you want to continue? + { + deletePage ? "This note will be permanently deleted and cannot be recovered. Are you sure you want to continue?" : + "This note will be moved to the recycle bin and can be restored later. Are you sure you want to continue?" + } diff --git a/src/components/NotesSidebar.tsx b/src/components/NotesSidebar.tsx index 5661145..b7d2bc0 100644 --- a/src/components/NotesSidebar.tsx +++ b/src/components/NotesSidebar.tsx @@ -2,11 +2,12 @@ import { Note } from '@/types/note'; import { NoteCard } from './NoteCard'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; -import { PlusCircle, Search, FileDown } from 'lucide-react'; +import { PlusCircle, Search, FileDown, Trash2, Home } from 'lucide-react'; import jsPDF from 'jspdf'; import { useState } from 'react'; import { ScrollArea } from '@/components/ui/scroll-area'; import { ThemeToggle } from "@/components/theme/themeToggle"; +import { Link, useLocation } from 'react-router-dom'; interface NotesSidebarProps { notes: Note[]; @@ -24,61 +25,70 @@ export function NotesSidebar({ onDelete, }: NotesSidebarProps) { const [searchQuery, setSearchQuery] = useState(''); + const path = useLocation()?.pathname + const deletePage = path === '/recycle-bin' + + console.log(notes) + console.log(activeNoteId) const filteredNotes = notes.filter( (note) => (note.title.toLowerCase().includes(searchQuery.toLowerCase()) || - note.content.toLowerCase().includes(searchQuery.toLowerCase())) && !note.deleted + note.content.toLowerCase().includes(searchQuery.toLowerCase())) && (!!note?.deleted === deletePage) ); return (
-

Notes

+

{ deletePage ? "Recycle Bin" : "Notes"}

- - - + doc.save(`${activeNote.title || 'note'}.pdf`); + }} + size="icon" + variant="outline" + className="hover:bg-secondary" + > + + + + + )}
@@ -95,7 +105,7 @@ export function NotesSidebar({
{filteredNotes.length === 0 ? (
- {searchQuery ? 'No notes found' : 'No notes yet. Create one!'} + {(searchQuery ? 'No notes found' : (deletePage ? 'Recycle Bin is empty' : 'No notes yet. Create one!'))}
) : ( filteredNotes.map((note) => ( @@ -110,6 +120,31 @@ export function NotesSidebar({ )}
+
+ {!deletePage ? ( + + + + ) : ( + + + + )} +
); } diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 5567fab..6026931 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -4,7 +4,7 @@ import { NotesSidebar } from '@/components/NotesSidebar'; import { NoteEditor } from '@/components/NoteEditor'; import { FileText, ArrowLeft } from 'lucide-react'; -const Index = () => { +const Index = ({deletePage = false}: {deletePage?: boolean}) => { const { notes, createNote, updateNote, deleteNote, softDeleteNote } = useNotes(); const [activeNoteId, setActiveNoteId] = useState(null); const [isMobile, setIsMobile] = useState(false); @@ -16,6 +16,10 @@ const Index = () => { return () => window.removeEventListener("resize", checkMobile); }, []); + useEffect(() => { + setActiveNoteId(null); + }, [deletePage]) + const handleCreateNote = () => { const newId = createNote(); setActiveNoteId(newId); @@ -34,7 +38,7 @@ const Index = () => { } }; - const activeNote = notes.find((note) => note.id === activeNoteId && !note.deleted); + const activeNote = notes.find((note) => note.id === activeNoteId); return (
@@ -46,7 +50,7 @@ const Index = () => { activeNoteId={activeNoteId} onSelectNote={setActiveNoteId} onCreateNote={handleCreateNote} - onDelete={handleSoftDeleteNote} + onDelete={ deletePage ? handleDeleteNote : handleSoftDeleteNote} />
{activeNote ? ( @@ -54,7 +58,7 @@ const Index = () => {
) : ( @@ -82,7 +86,7 @@ const Index = () => {
) : ( @@ -91,7 +95,7 @@ const Index = () => { activeNoteId={activeNoteId} onSelectNote={setActiveNoteId} onCreateNote={handleCreateNote} - onDelete={handleSoftDeleteNote} + onDelete={ deletePage ? handleDeleteNote : handleSoftDeleteNote} /> )} From 694eca5f817256c5f649b47164f47e27ab1a8847 Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Sun, 5 Oct 2025 17:12:14 +0530 Subject: [PATCH 03/12] Update src/components/NotesSidebar.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/NotesSidebar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/NotesSidebar.tsx b/src/components/NotesSidebar.tsx index b7d2bc0..3dbfbbb 100644 --- a/src/components/NotesSidebar.tsx +++ b/src/components/NotesSidebar.tsx @@ -114,7 +114,7 @@ export function NotesSidebar({ note={note} isActive={note.id === activeNoteId} onClick={() => onSelectNote(note.id)} - onDelete={onDelete} + onDelete={() => onDelete(note.id)} /> )) )} From 05f6db3e50d6c03b185294772bd43ae76ebf0615 Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Sun, 5 Oct 2025 17:12:27 +0530 Subject: [PATCH 04/12] Update src/components/NotesSidebar.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/NotesSidebar.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/NotesSidebar.tsx b/src/components/NotesSidebar.tsx index 3dbfbbb..43a3e26 100644 --- a/src/components/NotesSidebar.tsx +++ b/src/components/NotesSidebar.tsx @@ -28,8 +28,6 @@ export function NotesSidebar({ const path = useLocation()?.pathname const deletePage = path === '/recycle-bin' - console.log(notes) - console.log(activeNoteId) const filteredNotes = notes.filter( (note) => From a0b58e80f6152ea94e348bddfa5dd21cdc0ae29f Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:44:32 +0530 Subject: [PATCH 05/12] Update src/pages/Index.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/pages/Index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 473f21d..895ab4b 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -6,8 +6,6 @@ import { FileText, ArrowLeft } from "lucide-react"; import { toast } from "sonner"; const Index = ({deletePage = false}: {deletePage?: boolean}) => { - const { notes, createNote, updateNote, deleteNote, softDeleteNote } = useNotes(); -const Index = () => { const { notes, createNote, updateNote, deleteNote, duplicateNote, softDeleteNote } = useNotes(); const [activeNoteId, setActiveNoteId] = useState(null); const [isMobile, setIsMobile] = useState(false); From fa0185201f6811fd5a05db3024b5328c10d0402a Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:44:40 +0530 Subject: [PATCH 06/12] Update src/hooks/useNotes.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/hooks/useNotes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useNotes.ts b/src/hooks/useNotes.ts index 373314e..4b78a42 100644 --- a/src/hooks/useNotes.ts +++ b/src/hooks/useNotes.ts @@ -131,7 +131,7 @@ export function useNotes() { createNote, updateNote, deleteNote, - softDeleteNote + softDeleteNote, duplicateNote, }; } From 8560449474a385e486ec7b76ab67457f3b75cd4f Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:44:48 +0530 Subject: [PATCH 07/12] Update src/components/NoteCard.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/NoteCard.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index 268fc59..9e50ea9 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -23,8 +23,6 @@ interface NoteCardProps { onDuplicate?: (id: string) => void; } -export function NoteCard({ note, isActive, onClick, onDelete }: NoteCardProps) { - export function NoteCard({ note, isActive, onClick, onDelete, onDuplicate }: NoteCardProps) { const path = useLocation()?.pathname const deletePage = path === '/recycle-bin' From 965996e9559a280d1c5fda638b79c36b97536bc7 Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:47:07 +0530 Subject: [PATCH 08/12] Update NotesSidebar.tsx --- src/components/NotesSidebar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/NotesSidebar.tsx b/src/components/NotesSidebar.tsx index d87b555..18b58b1 100644 --- a/src/components/NotesSidebar.tsx +++ b/src/components/NotesSidebar.tsx @@ -81,6 +81,7 @@ export function NotesSidebar({ size="icon" variant="outline" className="hover:bg-secondary" + title="Export as PDF" > From f6db01ce233aac5968dd9ace205086c59ff28f42 Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:51:24 +0530 Subject: [PATCH 09/12] Update src/pages/Index.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/pages/Index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 895ab4b..9edf44d 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -19,7 +19,7 @@ const Index = ({deletePage = false}: {deletePage?: boolean}) => { useEffect(() => { setActiveNoteId(null); - }, [deletePage]) + }, [deletePage]); const handleCreateNote = () => { const newId = createNote(); From c5271c033b02e52cf5d238e7cfb39e9634ee9d6c Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:51:41 +0530 Subject: [PATCH 10/12] Update src/components/NotesSidebar.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/NotesSidebar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/NotesSidebar.tsx b/src/components/NotesSidebar.tsx index 18b58b1..fecd2a5 100644 --- a/src/components/NotesSidebar.tsx +++ b/src/components/NotesSidebar.tsx @@ -27,8 +27,8 @@ export function NotesSidebar({ onDelete, }: NotesSidebarProps) { const [searchQuery, setSearchQuery] = useState(''); - const path = useLocation()?.pathname - const deletePage = path === '/recycle-bin' + const path = useLocation()?.pathname; + const deletePage = path === '/recycle-bin'; const filteredNotes = notes.filter( From 043f0cb992c4bfab88c06bb396c3e189439f4f3e Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:51:52 +0530 Subject: [PATCH 11/12] Update src/components/NoteCard.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/NoteCard.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index 9e50ea9..e9e2cc7 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -24,8 +24,8 @@ interface NoteCardProps { } export function NoteCard({ note, isActive, onClick, onDelete, onDuplicate }: NoteCardProps) { - const path = useLocation()?.pathname - const deletePage = path === '/recycle-bin' + const path = useLocation()?.pathname; + const deletePage = path === '/recycle-bin'; const preview = note.content.slice(0, 100) || 'No content'; return ( From bd4f7961f0becde3b5ce5013b066d3a8e3a63ef0 Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Mon, 6 Oct 2025 17:52:02 +0530 Subject: [PATCH 12/12] Update src/components/NoteCard.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/NoteCard.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index e9e2cc7..1590678 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -67,7 +67,8 @@ export function NoteCard({ note, isActive, onClick, onDelete, onDuplicate }: Not title="Duplicate note" > - )} + + )}