diff --git a/src/App.tsx b/src/App.tsx index 7db0964..7d24fdf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,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 9ef4bbc..1590678 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -14,7 +14,7 @@ import { AlertDialogTitle, AlertDialogTrigger, } from '@/components/ui/alert-dialog'; - +import { useLocation } from 'react-router-dom'; interface NoteCardProps { note: Note; isActive: boolean; @@ -24,6 +24,8 @@ interface NoteCardProps { } export function NoteCard({ note, isActive, onClick, onDelete, onDuplicate }: NoteCardProps) { + const path = useLocation()?.pathname; + const deletePage = path === '/recycle-bin'; const preview = note.content.slice(0, 100) || 'No content'; return ( @@ -83,7 +85,10 @@ export function NoteCard({ note, isActive, onClick, onDelete, onDuplicate }: Not Delete Note - Are you sure you want to delete this note? This action cannot be undone. + { + 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 53ae287..e257185 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 - Are you sure you want to delete this note? This action cannot be undone. + { + 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 f2c188b..fecd2a5 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[]; @@ -26,62 +27,69 @@ export function NotesSidebar({ onDelete, }: NotesSidebarProps) { const [searchQuery, setSearchQuery] = useState(''); + const path = useLocation()?.pathname; + const deletePage = path === '/recycle-bin'; + 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 === deletePage) ); return (
-

Notes

+

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

- - - + doc.save(`${activeNote.title || 'note'}.pdf`); + }} + size="icon" + variant="outline" + className="hover:bg-secondary" + title="Export as PDF" + > + + + + + )}
@@ -98,7 +106,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) => ( @@ -114,6 +122,31 @@ export function NotesSidebar({ )}
+
+ {!deletePage ? ( + + + + ) : ( + + + + )} +
); } diff --git a/src/hooks/useNotes.ts b/src/hooks/useNotes.ts index e6dfa38..4b78a42 100644 --- a/src/hooks/useNotes.ts +++ b/src/hooks/useNotes.ts @@ -85,6 +85,14 @@ 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 + ) + ); + } + const duplicateNote = (id: string) => { const newId = crypto.randomUUID(); @@ -123,6 +131,7 @@ export function useNotes() { createNote, updateNote, deleteNote, + softDeleteNote, duplicateNote, }; } diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 154d12c..9edf44d 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -5,9 +5,8 @@ import { NoteEditor } from "@/components/NoteEditor"; import { FileText, ArrowLeft } from "lucide-react"; import { toast } from "sonner"; -const Index = () => { - const { notes, createNote, updateNote, deleteNote, duplicateNote } = - useNotes(); +const Index = ({deletePage = false}: {deletePage?: boolean}) => { + const { notes, createNote, updateNote, deleteNote, duplicateNote, softDeleteNote } = useNotes(); const [activeNoteId, setActiveNoteId] = useState(null); const [isMobile, setIsMobile] = useState(false); @@ -18,6 +17,10 @@ const Index = () => { return () => window.removeEventListener("resize", checkMobile); }, []); + useEffect(() => { + setActiveNoteId(null); + }, [deletePage]); + const handleCreateNote = () => { const newId = createNote(); setActiveNoteId(newId); @@ -29,6 +32,12 @@ const Index = () => { setActiveNoteId(notes.length > 1 ? notes[0].id : null); } }; + const handleSoftDeleteNote = (id: string) => { + softDeleteNote(id); + if (activeNoteId === id) { + setActiveNoteId(null); + } + }; const handleDuplicateNote = useCallback( (id: string) => { @@ -144,7 +153,7 @@ const Index = () => { onSelectNote={setActiveNoteId} onCreateNote={handleCreateNote} onDuplicateNote={handleDuplicateNote} - onDelete={handleDeleteNote} + onDelete={ deletePage ? handleDeleteNote : handleSoftDeleteNote} />
{/* Keyboard Shortcuts Helper */} @@ -193,7 +202,7 @@ const Index = () => {
) : ( @@ -222,7 +231,7 @@ const Index = () => {
) : ( @@ -232,7 +241,7 @@ const Index = () => { onSelectNote={setActiveNoteId} onCreateNote={handleCreateNote} onDuplicateNote={handleDuplicateNote} - onDelete={handleDeleteNote} + onDelete={ deletePage ? handleDeleteNote : 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 => {