feat: refactor navigation structure in AppSidebar to use permissions for dynamic item rendering
This commit is contained in:
parent
6834d47e2b
commit
4350f7d9ea
@ -64,164 +64,216 @@ const STAFF_ROLES = ['developer', 'staff-admin', 'staff-keuangan', 'kaprodi'];
|
|||||||
function buildNavMain({
|
function buildNavMain({
|
||||||
isMahasiswa,
|
isMahasiswa,
|
||||||
isDosen,
|
isDosen,
|
||||||
canViewLogs,
|
permissions,
|
||||||
canViewRoles,
|
|
||||||
}: {
|
}: {
|
||||||
isMahasiswa: boolean;
|
isMahasiswa: boolean;
|
||||||
isDosen: boolean;
|
isDosen: boolean;
|
||||||
canViewLogs: boolean;
|
permissions: string[];
|
||||||
canViewRoles: boolean;
|
|
||||||
}): (NavGroup | NavItem)[] {
|
}): (NavGroup | NavItem)[] {
|
||||||
return [
|
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[] = [
|
||||||
|
...(isMahasiswa || can('view-letter-requests')
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
name: 'Surat Permohonan',
|
||||||
|
url: isMahasiswa
|
||||||
|
? studentLetterRequestsRoute.url()
|
||||||
|
: letterRequestsRoute.url(),
|
||||||
|
icon: Mail,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
...(isDosen || can('view-academic-advising-logs')
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
name: 'Bimbingan Akademik',
|
||||||
|
url: isDosen
|
||||||
|
? lecturerAcademicAdvisingLogsRoute.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',
|
name: 'Dasbor',
|
||||||
url: '#',
|
url: '#',
|
||||||
icon: IconGridDots,
|
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,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
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(
|
function buildNavSecondary(
|
||||||
@ -249,13 +301,11 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
|||||||
const isStaff = roleNames.some((role) => STAFF_ROLES.includes(role));
|
const isStaff = roleNames.some((role) => STAFF_ROLES.includes(role));
|
||||||
const isMahasiswa = !isStaff && roleNames.includes('mahasiswa');
|
const isMahasiswa = !isStaff && roleNames.includes('mahasiswa');
|
||||||
const isDosen = !isStaff && roleNames.includes('dosen');
|
const isDosen = !isStaff && roleNames.includes('dosen');
|
||||||
const canViewLogs = (auth?.permissions ?? []).includes('view-logs');
|
const permissions = auth?.permissions ?? [];
|
||||||
const canViewRoles = (auth?.permissions ?? []).includes('view-roles');
|
|
||||||
const navMain = buildNavMain({
|
const navMain = buildNavMain({
|
||||||
isMahasiswa,
|
isMahasiswa,
|
||||||
isDosen,
|
isDosen,
|
||||||
canViewLogs,
|
permissions,
|
||||||
canViewRoles,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user