diff --git a/app/(dashboard)/_components/app-sidebar.tsx b/app/(dashboard)/_components/app-sidebar.tsx index 0ad818a..cc2ad9a 100644 --- a/app/(dashboard)/_components/app-sidebar.tsx +++ b/app/(dashboard)/_components/app-sidebar.tsx @@ -1,5 +1,6 @@ "use client"; +import { useState } from "react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { ChevronRightIcon } from "lucide-react"; @@ -21,7 +22,9 @@ import { SidebarMenuSubButton, SidebarMenuSubItem, } from "@/components/ui/sidebar"; -import { navItems } from "./nav-items"; +import { navItems, type NavItem } from "./nav-items"; + +type NavGroupItem = Extract; export function AppSidebar({ footer }: { footer: React.ReactNode }) { const pathname = usePathname(); @@ -36,33 +39,7 @@ export function AppSidebar({ footer }: { footer: React.ReactNode }) { {navItems.map((item) => "items" in item ? ( - - pathname.startsWith(sub.href), - )} - render={} - > - }> - - {item.title} - - - - - {item.items.map((sub) => ( - - } - isActive={pathname.startsWith(sub.href)} - > - {sub.title} - - - ))} - - - + ) : ( ); } + +// Controlled karena sidebar tetap ter-mount antar navigasi; defaultOpen yang berubah memicu warning Base UI. +function NavGroup({ + item, + pathname, +}: { + item: NavGroupItem; + pathname: string; +}) { + const isActive = item.items.some((sub) => pathname.startsWith(sub.href)); + const [open, setOpen] = useState(isActive); + const [prevActive, setPrevActive] = useState(isActive); + + // Buka otomatis saat navigasi masuk ke grup ini, tanpa menutup grup yang dibuka manual. + if (isActive !== prevActive) { + setPrevActive(isActive); + if (isActive) setOpen(true); + } + + return ( + } + > + }> + + {item.title} + + + + + {item.items.map((sub) => ( + + } + isActive={pathname.startsWith(sub.href)} + > + {sub.title} + + + ))} + + + + ); +} diff --git a/app/not-found.tsx b/app/not-found.tsx new file mode 100644 index 0000000..ce5167b --- /dev/null +++ b/app/not-found.tsx @@ -0,0 +1,34 @@ +"use client"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; + +export default function NotFoundPage() { + const router = useRouter(); + return ( +
+
+

+ Cleo Minimarket +

+

+ 404 +

+

Halaman tidak ditemukan

+

+ Alamat yang dibuka tidak ada atau sudah dipindah. +

+
+ +
+
+
+ ); +}