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 lecturerAcademicAdvisingLogsRoute } from '@/routes/lecturer/academic-advising-logs'; import { index as studentCourseRegistrationsRoute } from '@/routes/student/course-registrations'; import { index as studentLetterRequestsRoute } from '@/routes/student/letter-requests'; import type { Auth } from '@/types/auth'; const STAFF_ROLES = ['developer', 'staff-admin', 'staff-keuangan', 'kaprodi']; function buildNavMain({ isMahasiswa, isDosen, canViewLogs, canViewRoles, }: { isMahasiswa: boolean; isDosen: boolean; canViewLogs: boolean; canViewRoles: boolean; }): (NavGroup | NavItem)[] { return [ { name: 'Dasbor', url: '#', icon: IconGridDots, }, { label: 'Pengguna', items: [ { name: 'Administrator', url: administratorsRoute.url(), icon: User, }, { name: 'Dosen', url: lecturersRoute.url(), icon: Users, }, { name: 'Mahasiswa', url: studentsRoute.url(), icon: GraduationCap, }, ], }, { label: 'Master', items: [ { name: 'Periode Akademik', url: academicTerm.url(), icon: Calendar, }, { name: 'Jurusan', url: departmentsRoute.url(), icon: Building2, }, { name: 'Mata Kuliah', url: coursesRoute.url(), icon: BookOpen, }, ], }, { label: 'Kelola', items: [ { name: 'Registrasi KRS', url: isMahasiswa ? studentCourseRegistrationsRoute.url() : courseRegistrationsRoute.url(), icon: FileCheck2, }, { name: 'Kelas Mata Kuliah', url: courseClassesRoute.url(), icon: School, }, { name: 'Pengumuman', url: announcementsRoute.url(), icon: Megaphone, }, ], }, { label: 'Kelas', items: [ { name: 'Materi', url: materialsRoute.url(), icon: FileText, }, { name: 'Tugas', url: assignmentsRoute.url(), icon: ClipboardList, }, { name: 'Jadwal', url: schedulesRoute.url(), icon: CalendarClock, }, { name: 'Kehadiran', url: attendancesRoute.url(), icon: ClipboardCheck, }, ], }, { label: 'Keuangan', items: [ { name: 'Tagihan', url: tuitionInvoicesRoute.url(), icon: Receipt, }, ], }, { label: 'Layanan', items: [ { name: 'Surat Permohonan', url: isMahasiswa ? studentLetterRequestsRoute.url() : letterRequestsRoute.url(), icon: Mail, }, { name: 'Bimbingan Akademik', url: isDosen ? lecturerAcademicAdvisingLogsRoute.url() : academicAdvisingLogsRoute.url(), icon: MessageCircle, }, ], }, ...(canViewLogs || canViewRoles ? [ { label: 'Pengembang', items: [ ...(canViewLogs ? [ { name: 'Logs', url: logsRoute.url(), icon: ScrollText, }, ] : []), ...(canViewRoles ? [ { name: 'Role & Permission', url: rolePermissionsRoute.url(), icon: ShieldCheck, }, ] : []), ], }, ] : []), ]; } 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 isDosen = !isStaff && roleNames.includes('dosen'); const canViewLogs = (auth?.permissions ?? []).includes('view-logs'); const canViewRoles = (auth?.permissions ?? []).includes('view-roles'); const navMain = buildNavMain({ isMahasiswa, isDosen, canViewLogs, canViewRoles, }); return ( {name} ); }