'use client' import colors from "@/con/colors"; import { authStore } from "@/store/authStore"; import { ActionIcon, AppShell, AppShellHeader, AppShellMain, AppShellNavbar, Burger, Center, Flex, Group, Image, Loader, NavLink, ScrollArea, Text, Tooltip, rem } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { IconChevronLeft, IconChevronRight, IconLogout2 } from "@tabler/icons-react"; import _ from "lodash"; import Link from "next/link"; import { useRouter, useSelectedLayoutSegments } from "next/navigation"; import { useEffect, useState } from "react"; import { getNavbar } from "./(dashboard)/user&role/_com/dynamicNavbar"; export default function Layout({ children }: { children: React.ReactNode }) { const [opened, { toggle, close }] = useDisclosure(); // ✅ Tambahkan 'close' const [loading, setLoading] = useState(true); const [isLoggingOut, setIsLoggingOut] = useState(false); const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true); const router = useRouter(); const segments = useSelectedLayoutSegments().map((s) => _.lowerCase(s)); useEffect(() => { const fetchUser = async () => { try { const res = await fetch('/api/auth/me', { credentials: 'include' }); const data = await res.json(); if (data.user) { if (!data.user.isActive) { authStore.setUser(null); router.replace('/waiting-room'); return; } const menuRes = await fetch(`/api/admin/user-menu-access?userId=${data.user.id}`, { credentials: 'include' }); const menuData = await menuRes.json(); const menuIds = menuData.success && Array.isArray(menuData.menuIds) ? [...menuData.menuIds] : null; authStore.setUser({ id: data.user.id, name: data.user.name, roleId: Number(data.user.roleId), menuIds, isActive: data.user.isActive }); const currentPath = window.location.pathname; if (currentPath === '/admin') { const expectedPath = getRedirectPath(Number(data.user.roleId)); console.log('🔄 Redirecting from /admin to:', expectedPath); router.replace(expectedPath); } } else { authStore.setUser(null); router.replace('/login'); } } catch (error) { console.error('Gagal memuat data pengguna:', error); authStore.setUser(null); router.replace('/login'); } finally { setLoading(false); } }; fetchUser(); }, [router]); const getRedirectPath = (roleId: number): string => { switch (roleId) { case 0: case 1: case 2: return '/admin/landing-page/profil/program-inovasi'; case 3: return '/admin/kesehatan/posyandu'; case 4: return '/admin/pendidikan/info-sekolah/jenjang-pendidikan'; default: return '/admin'; } }; if (loading) { return (
); } const currentNav = authStore.user ? getNavbar({ roleId: authStore.user.roleId, menuIds: authStore.user.menuIds }) : []; const handleLogout = async () => { try { setIsLoggingOut(true); const response = await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }); const result = await response.json(); if (result.success) { authStore.setUser(null); localStorage.removeItem('auth_nomor'); localStorage.removeItem('auth_kodeId'); localStorage.removeItem('auth_username'); window.location.href = '/login'; } else { console.error('Logout failed:', result.message); authStore.setUser(null); window.location.href = '/login'; } } catch (error) { console.error('Error during logout:', error); authStore.setUser(null); window.location.href = '/login'; } finally { setIsLoggingOut(false); } }; // ✅ Handler untuk menutup mobile menu saat navigasi const handleNavClick = (path: string) => { router.push(path); close(); // Tutup mobile menu }; return ( Logo Darmasaba Admin Darmasaba {!desktopOpened && ( )} router.push("/darmasaba")} color={colors["blue-button"]} radius="xl" size="lg" variant="gradient" gradient={{ from: colors["blue-button"], to: "#228be6" }}> Logo Darmasaba {currentNav.map((v, k) => { const isParentActive = segments.includes(_.lowerCase(v.name)); return ( {v.name}} style={{ borderRadius: rem(10), marginBottom: rem(4), transition: "background 150ms ease" }} styles={{ root: { '&:hover': { backgroundColor: 'rgba(25, 113, 194, 0.05)' } } }} variant="light" active={isParentActive} > {v.children.map((child, key) => { const isChildActive = segments.includes(_.lowerCase(child.name)); return ( { e.preventDefault(); handleNavClick(child.path); }} href={child.path} c={isChildActive ? colors["blue-button"] : "gray"} label={{child.name}} styles={{ root: { borderRadius: rem(8), marginBottom: rem(2), transition: 'background 150ms ease', padding: '6px 12px', '&:hover': { backgroundColor: isChildActive ? 'rgba(25, 113, 194, 0.15)' : 'rgba(25, 113, 194, 0.05)' }, ...(isChildActive && { backgroundColor: 'rgba(25, 113, 194, 0.1)' }) } }} active={isChildActive} component={Link} /> ); })} ); })} {children} ); }