Files
dashboard-noc-desa-darmasaba/src/components/sidebar.tsx
2026-03-25 00:09:38 +08:00

186 lines
4.9 KiB
TypeScript

import {
Badge,
Box,
Collapse,
Group,
Image,
Input,
NavLink as MantineNavLink,
Stack,
Text,
useMantineColorScheme,
} from "@mantine/core";
import { useLocation, useNavigate } from "@tanstack/react-router";
import { ChevronDown, ChevronUp, Search } from "lucide-react";
import { useState } from "react";
interface SidebarProps {
className?: string;
}
export function Sidebar({ className }: SidebarProps) {
const location = useLocation();
const navigate = useNavigate();
const { colorScheme } = useMantineColorScheme();
const dark = colorScheme === "dark";
const isActiveBg = colorScheme === "dark" ? "#182949" : "#E6F0FF";
const isActiveBorder = colorScheme === "dark" ? "#00398D" : "#1F41AE";
// State for settings submenu collapse
const [settingsOpen, setSettingsOpen] = useState(
location.pathname.startsWith("/pengaturan"),
);
// Define menu items with their paths
const menuItems = [
{ name: "Beranda", path: "/" },
{ name: "Kinerja Divisi", path: "/kinerja-divisi" },
{ name: "Pengaduan & Layanan Publik", path: "/pengaduan-layanan-publik" },
{ name: "Jenna Analytic", path: "/jenna-analytic" },
{ name: "Demografi & Kependudukan", path: "/demografi-pekerjaan" },
{ name: "Keuangan & Anggaran", path: "/keuangan-anggaran" },
{ name: "Bumdes & UMKM Desa", path: "/bumdes" },
{ name: "Sosial", path: "/sosial" },
{ name: "Keamanan", path: "/keamanan" },
{ name: "Bantuan", path: "/bantuan" },
];
// Settings submenu items
const settingsItems = [
{ name: "Umum", path: "/pengaturan/umum" },
{ name: "Notifikasi", path: "/pengaturan/notifikasi" },
{ name: "Keamanan", path: "/pengaturan/keamanan" },
{ name: "Akses & Tim", path: "/pengaturan/akses-dan-tim" },
];
// Check if any settings submenu is active
const isSettingsActive = settingsItems.some(
(item) => location.pathname === item.path,
);
return (
<Box className={className}>
{/* Logo */}
<Image src={dark ? "/white.png" : "/light-mode.png"} alt="Logo" />
{/* Search */}
<Box p="md">
<Input
placeholder="cari apa saja"
leftSection={<Search size={16} />}
styles={{
input: {
"&::placeholder": {
color: dark ? "#F1F5F9" : "#263852ff",
},
},
}}
/>
</Box>
{/* Menu Items */}
<Stack gap={0} px="xs" style={{ overflowY: "auto" }}>
{menuItems.map((item, index) => {
const isActive = location.pathname === item.path;
return (
<MantineNavLink
key={index}
onClick={() => navigate({ to: item.path })}
label={item.name}
active={isActive}
variant="subtle"
color="blue"
style={{
background: isActive ? isActiveBg : "transparent",
fontWeight: isActive ? "bold" : "normal",
borderLeft: isActive
? `4px solid ${isActiveBorder}`
: "4px solid transparent",
borderRadius: "8px",
transition: "all 200ms ease",
margin: "2px 0",
}}
styles={{
body: {
"&:hover": {
background: "#F1F5F9",
},
},
}}
/>
);
})}
{/* Settings with submenu */}
<Box>
<MantineNavLink
onClick={() => setSettingsOpen(!settingsOpen)}
rightSection={
settingsOpen ? <ChevronUp size={16} /> : <ChevronDown size={16} />
}
label="Pengaturan"
active={isSettingsActive}
variant="subtle"
color="blue"
style={{
background: isSettingsActive ? isActiveBg : "transparent",
fontWeight: isSettingsActive ? "bold" : "normal",
borderLeft: isSettingsActive
? `4px solid ${isActiveBorder}`
: "4px solid transparent",
borderRadius: "8px",
transition: "all 200ms ease",
margin: "2px 0",
}}
styles={{
body: {
"&:hover": {
background: "#F1F5F9",
},
},
}}
/>
<Collapse in={settingsOpen}>
<Stack
gap={0}
ml="lg"
style={{ overflowY: "auto", maxHeight: "200px" }}
>
{settingsItems.map((item, index) => {
const isActive = location.pathname === item.path;
return (
<MantineNavLink
key={index}
onClick={() => navigate({ to: item.path })}
label={item.name}
active={isActive}
variant="subtle"
color="blue"
style={{
background: isActive ? isActiveBg : "transparent",
fontWeight: isActive ? "bold" : "normal",
borderLeft: isActive
? `4px solid ${isActiveBorder}`
: "4px solid transparent",
borderRadius: "8px",
transition: "all 200ms ease",
margin: "2px 0",
}}
styles={{
body: {
"&:hover": {
background: "#F1F5F9",
},
},
}}
/>
);
})}
</Stack>
</Collapse>
</Box>
</Stack>
</Box>
);
}