94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
import { Check, Plus, Sun, Moon } from "lucide-react"
|
|
|
|
import { Sidebar, SidebarContent, SidebarHeader, SidebarFooter } from "@/components/ui/sidebar"
|
|
import { Button } from "@/components/ui/button"
|
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
|
import { Input } from "@/components/ui/input"
|
|
|
|
import ListItem from "./ListItem"
|
|
|
|
import { useNote } from "../contexts/ActiveNoteContext"
|
|
import { useNotesStore } from "../contexts/NotesStore"
|
|
import { useTheme } from "../contexts/ThemeContext"
|
|
import { ChangeEvent, ReactNode, useState } from "react"
|
|
|
|
function AppSidebar() {
|
|
const { notes, createNote } = useNotesStore()
|
|
const { setCurrentNoteId } = useNote()
|
|
const { theme, toggleTheme } = useTheme()
|
|
const [ filter, setFilter ] = useState("")
|
|
|
|
const buildNoteListItems = () => {
|
|
const out: ReactNode[] = []
|
|
notes.forEach((note, key, _) => {
|
|
if (filter && !note.title.toLowerCase().includes(filter.toLowerCase())) return;
|
|
out.push(
|
|
<ListItem
|
|
key={key}
|
|
id={note.id}
|
|
label={note.title}
|
|
onSelect={() => setCurrentNoteId(note.id)}
|
|
/>
|
|
)
|
|
})
|
|
return out;
|
|
}
|
|
|
|
return (
|
|
<Sidebar>
|
|
|
|
<SidebarHeader className="justify-between px-4 py-3 border-b-1 gap-3.5">
|
|
<div className="flex items-center justify-between">
|
|
<span className="font-medium">Notes</span>
|
|
<Button variant="ghost" size="sm" onClick={toggleTheme} className="text-muted-foreground">
|
|
{theme === "dark" ? <Sun /> : <Moon />}
|
|
</Button>
|
|
</div>
|
|
<Input
|
|
placeholder="Search Notes"
|
|
className="shadow-none bg-background"
|
|
onChange={(e) => setFilter(e.target.value)}
|
|
/>
|
|
</SidebarHeader>
|
|
|
|
<SidebarContent>
|
|
<ScrollArea className="h-full px-2 py-2">
|
|
<div className="space-y-1 py-2">
|
|
{buildNoteListItems()}
|
|
</div>
|
|
|
|
<Button
|
|
variant="secondary"
|
|
className="w-full justify-start gap-2 mb-2"
|
|
onClick={createNote}
|
|
>
|
|
<Plus />
|
|
New Note
|
|
</Button>
|
|
</ScrollArea>
|
|
</SidebarContent>
|
|
|
|
<SidebarFooter className="p-2 border-t-1">
|
|
<div className="flex items-center gap-3 rounded-md px-2 py-1.5">
|
|
<div className="flex flex-col leading-tight gap-2">
|
|
<span className="text-xs text-muted-foreground">
|
|
{notes.length} note{notes.length !== 1 && "s"}
|
|
</span>
|
|
<div className="flex flex-row gap-2">
|
|
<div className="flex h-4 w-4 items-center justify-center rounded-full bg-foreground">
|
|
<Check className="h-2 w-2 text-background" />
|
|
</div>
|
|
<span className="text-sm font-medium text-foreground">
|
|
Notes synced
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</SidebarFooter>
|
|
|
|
</Sidebar>
|
|
)
|
|
}
|
|
|
|
export default AppSidebar
|