import { usePage } from '@inertiajs/react'; import type { Icon } from '@tabler/icons-react'; import { IconGridDots, IconHelp, IconMessageDots } from '@tabler/icons-react'; import { BookOpen, Building2, Calendar, CalendarClock, ClipboardCheck, ClipboardList, FileCheck2, FileText, GraduationCap, Mail, Megaphone, MessageCircle, Receipt, School, ScrollText, ShieldCheck, User, Users, } from 'lucide-react'; import * as React from 'react'; import AppLogoIcon from '@/components/app-logo-icon'; import type { NavGroup, NavItem } from '@/components/nav-main'; import { NavMain } from '@/components/nav-main'; import { NavSecondary } from '@/components/nav-secondary'; import { Sidebar, SidebarContent, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, } from '@/components/ui/sidebar'; import { index as assignmentsRoute } from '@/routes/admin/academic-classes/assignments'; import { index as attendancesRoute } from '@/routes/admin/academic-classes/attendances'; import { index as materialsRoute } from '@/routes/admin/academic-classes/materials'; import { index as schedulesRoute } from '@/routes/admin/academic-classes/schedules'; import { index as logsRoute } from '@/routes/admin/developer/logs'; import { index as rolePermissionsRoute } from '@/routes/admin/developer/roles'; import { index as feedbackRoute } from '@/routes/admin/feedback'; import { index as tuitionInvoicesRoute } from '@/routes/admin/finances/tuition-invoices'; import { index as announcementsRoute } from '@/routes/admin/manage/announcements'; import { index as courseClassesRoute } from '@/routes/admin/manage/course-classes'; import { index as courseRegistrationsRoute } from '@/routes/admin/manage/course-registrations'; import { index as academicTerm } from '@/routes/admin/master/academic-terms'; import { index as coursesRoute } from '@/routes/admin/master/courses'; import { index as departmentsRoute } from '@/routes/admin/master/departments'; import { index as academicAdvisingLogsRoute } from '@/routes/admin/services/academic-advising-logs'; import { index as letterRequestsRoute } from '@/routes/admin/services/letter-requests'; import { index as administratorsRoute } from '@/routes/admin/users/administrators'; import { index as lecturersRoute } from '@/routes/admin/users/lecturers'; import { index as studentsRoute } from '@/routes/admin/users/students'; import { index as studentCourseRegistrationsRoute } from '@/routes/student/course-registrations'; import type { Auth } from '@/types/auth'; const STAFF_ROLES = ['developer', 'staff-admin', 'staff-keuangan', 'kaprodi']; function buildNavMain({ isMahasiswa, permissions, }: { isMahasiswa: boolean; permissions: string[]; }): (NavGroup | NavItem)[] { const can = (permission: string) => permissions.includes(permission); const penggunaItems: NavItem[] = [ ...(can('view-administrators') ? [ { name: 'Administrator', url: administratorsRoute.url(), icon: User, }, ] : []), ...(can('view-lecturers') ? [{ name: 'Dosen', url: lecturersRoute.url(), icon: Users }] : []), ...(can('view-students') ? [ { name: 'Mahasiswa', url: studentsRoute.url(), icon: GraduationCap, }, ] : []), ]; const masterItems: NavItem[] = [ ...(can('view-academic-terms') ? [ { name: 'Periode Akademik', url: academicTerm.url(), icon: Calendar, }, ] : []), ...(can('view-departments') ? [ { name: 'Jurusan', url: departmentsRoute.url(), icon: Building2, }, ] : []), ...(can('view-courses') ? [{ name: 'Mata Kuliah', url: coursesRoute.url(), icon: BookOpen }] : []), ]; const kelolaItems: NavItem[] = [ ...(isMahasiswa || can('view-course-registrations') ? [ { name: 'Registrasi KRS', url: isMahasiswa ? studentCourseRegistrationsRoute.url() : courseRegistrationsRoute.url(), icon: FileCheck2, }, ] : []), ...(can('view-course-classes') ? [ { name: 'Kelas Mata Kuliah', url: courseClassesRoute.url(), icon: School, }, ] : []), ...(can('view-announcements') ? [ { name: 'Pengumuman', url: announcementsRoute.url(), icon: Megaphone, }, ] : []), ]; const kelasItems: NavItem[] = [ ...(can('view-materials') ? [{ name: 'Materi', url: materialsRoute.url(), icon: FileText }] : []), ...(can('view-assignments') ? [ { name: 'Tugas', url: assignmentsRoute.url(), icon: ClipboardList, }, ] : []), ...(can('view-schedules') ? [ { name: 'Jadwal', url: schedulesRoute.url(), icon: CalendarClock, }, ] : []), ...(can('view-attendances') ? [ { name: 'Kehadiran', url: attendancesRoute.url(), icon: ClipboardCheck, }, ] : []), ]; const keuanganItems: NavItem[] = [ ...(can('view-tuition-invoices') ? [ { name: 'Tagihan', url: tuitionInvoicesRoute.url(), icon: Receipt, }, ] : []), ]; const layananItems: NavItem[] = [ ...(can('view-letter-requests') ? [ { name: 'Surat Permohonan', url: letterRequestsRoute.url(), icon: Mail, }, ] : []), ...(can('view-academic-advising-logs') ? [ { name: 'Bimbingan Akademik', url: academicAdvisingLogsRoute.url(), icon: MessageCircle, }, ] : []), ]; const pengembangItems: NavItem[] = [ ...(can('view-logs') ? [{ name: 'Logs', url: logsRoute.url(), icon: ScrollText }] : []), ...(can('view-roles') ? [ { name: 'Role & Permission', url: rolePermissionsRoute.url(), icon: ShieldCheck, }, ] : []), ]; const groups: (NavGroup | NavItem)[] = [ { name: 'Dasbor', url: '#', icon: IconGridDots, }, ]; if (penggunaItems.length > 0) { groups.push({ label: 'Pengguna', items: penggunaItems }); } if (masterItems.length > 0) { groups.push({ label: 'Master', items: masterItems }); } if (kelolaItems.length > 0) { groups.push({ label: 'Kelola', items: kelolaItems }); } if (kelasItems.length > 0) { groups.push({ label: 'Kelas', items: kelasItems }); } if (keuanganItems.length > 0) { groups.push({ label: 'Keuangan', items: keuanganItems }); } if (layananItems.length > 0) { groups.push({ label: 'Layanan', items: layananItems }); } if (pengembangItems.length > 0) { groups.push({ label: 'Pengembang', items: pengembangItems }); } return groups; } function buildNavSecondary( pendingFeedbackCount: number, ): { title: string; url: string; icon: Icon; badge?: number }[] { return [ { title: 'Kritik dan Saran', url: feedbackRoute.url(), icon: IconMessageDots, badge: pendingFeedbackCount, }, { title: 'Bantuan', url: '#', icon: IconHelp, }, ]; } export function AppSidebar({ ...props }: React.ComponentProps) { const { name, auth, pendingFeedbackCount } = usePage<{ auth: Auth }>() .props; const roleNames = auth?.user?.roles?.map((role) => role.name) ?? []; const isStaff = roleNames.some((role) => STAFF_ROLES.includes(role)); const isMahasiswa = !isStaff && roleNames.includes('mahasiswa'); const permissions = auth?.permissions ?? []; const navMain = buildNavMain({ isMahasiswa, permissions, }); return ( {name} ); }