Fix sidebar bug

main
Deardo Satria 2 days ago
parent 54dfbd2691
commit 1ab0c2e321

@ -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<NavItem, { items: unknown }>;
export function AppSidebar({ footer }: { footer: React.ReactNode }) {
const pathname = usePathname();
@ -36,11 +39,49 @@ export function AppSidebar({ footer }: { footer: React.ReactNode }) {
<SidebarMenu className="gap-0.5">
{navItems.map((item) =>
"items" in item ? (
<Collapsible
key={item.title}
defaultOpen={item.items.some((sub) =>
pathname.startsWith(sub.href),
<NavGroup key={item.title} item={item} pathname={pathname} />
) : (
<SidebarMenuItem key={item.href}>
<SidebarMenuButton
render={<Link href={item.href} />}
isActive={pathname === item.href}
>
<item.icon />
<span>{item.title}</span>
</SidebarMenuButton>
</SidebarMenuItem>
),
)}
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>{footer}</SidebarFooter>
</Sidebar>
);
}
// 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 (
<Collapsible
open={open}
onOpenChange={setOpen}
render={<SidebarMenuItem />}
>
<CollapsibleTrigger render={<SidebarMenuButton />}>
@ -63,22 +104,5 @@ export function AppSidebar({ footer }: { footer: React.ReactNode }) {
</SidebarMenuSub>
</CollapsibleContent>
</Collapsible>
) : (
<SidebarMenuItem key={item.href}>
<SidebarMenuButton
render={<Link href={item.href} />}
isActive={pathname === item.href}
>
<item.icon />
<span>{item.title}</span>
</SidebarMenuButton>
</SidebarMenuItem>
),
)}
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>{footer}</SidebarFooter>
</Sidebar>
);
}

@ -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 (
<div className="grid min-h-svh place-items-center bg-background px-6 text-foreground">
<div className="w-full max-w-sm text-center">
<p className="font-mono text-xs tracking-[0.3em] text-muted-foreground uppercase">
Cleo Minimarket
</p>
<h1 className="mt-4 text-7xl font-semibold tracking-tighter tabular-nums">
404
</h1>
<p className="mt-3 text-lg font-medium">Halaman tidak ditemukan</p>
<p className="mt-2 text-sm text-muted-foreground">
Alamat yang dibuka tidak ada atau sudah dipindah.
</p>
<div className="mt-8 border-t border-dashed pt-6">
<Button
className="inline-flex h-10 items-center rounded-md bg-primary px-5 text-sm font-medium text-primary-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring"
onClick={() => {
router.back();
}}
>
Kembali
</Button>
</div>
</div>
</div>
);
}
Loading…
Cancel
Save