feat: implement settings menu with umum, notifikasi, keamanan, and akses & tim sections

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
2026-02-13 12:05:57 +08:00
parent ab2afbb27f
commit 81c138a961
12 changed files with 527 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
import { useNavigate, useLocation } from "@tanstack/react-router";
import { Search } from "lucide-react";
import { Search, ChevronDown, ChevronUp } from "lucide-react";
import {
Stack,
Group,
@@ -9,7 +9,9 @@ import {
NavLink as MantineNavLink,
Box,
useMantineColorScheme,
Collapse,
} from "@mantine/core";
import { useState } from "react";
interface SidebarProps {
className?: string;
@@ -21,6 +23,11 @@ export function Sidebar({ className }: SidebarProps) {
const { colorScheme } = useMantineColorScheme();
const isActiveBg = colorScheme === 'dark' ? "#182949" : "#E6F0FF";
const isActiveBorder = colorScheme === 'dark' ? "#00398D" : "#1F41AE";
// State for settings submenu collapse
const [settingsOpen, setSettingsOpen] = useState(
location.pathname.startsWith('/dashboard/pengaturan')
);
// Define menu items with their paths
const menuItems = [
@@ -34,9 +41,21 @@ export function Sidebar({ className }: SidebarProps) {
{ name: "Sosial", path: "/dashboard/sosial" },
{ name: "Keamanan", path: "/dashboard/keamanan" },
{ name: "Bantuan", path: "/dashboard/bantuan" },
{ name: "Pengaturan", path: "/dashboard/pengaturan" },
];
// Settings submenu items
const settingsItems = [
{ name: "Umum", path: "/dashboard/pengaturan/umum" },
{ name: "Notifikasi", path: "/dashboard/pengaturan/notifikasi" },
{ name: "Keamanan", path: "/dashboard/pengaturan/keamanan" },
{ name: "Akses & Tim", path: "/dashboard/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 */}
@@ -78,7 +97,7 @@ export function Sidebar({ className }: SidebarProps) {
</Box>
{/* Menu Items */}
<Stack gap={0} px="xs" flex={1} style={{ overflowY: "auto" }}>
<Stack gap={0} px="xs" style={{ overflowY: "auto" }}>
{menuItems.map((item, index) => {
const isActive = location.pathname === item.path;
return (
@@ -107,6 +126,65 @@ export function Sidebar({ className }: SidebarProps) {
/>
);
})}
{/* 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>
);