// Per-role sidebar sections, kept as plain builder functions so any layout // can request the union of sections for every role a user holds — additive // multi-role access without each layout hardcoding its own single-role list. // Only roles with a registered builder participate in the merge; a role // without one (e.g. admin) contributes nothing and keeps its own standalone // menu untouched. export const buildStudentMenuItems = (route) => [ { title: 'داشبورد', icon: 'monitor', to: { name: 'student-dashboard' }, active: route.name === 'student-dashboard', dedupeKey: 'dashboard', }, { title: 'آموزش', icon: 'graduation-cap', to: { name: 'student-terms' }, active: [ 'student-terms', 'student-term-details', 'student-lesson-details', 'student-session-details', 'student-exam', 'student-courses', 'student-course-details', ].includes(route.name), dedupeKey: 'education', }, { title: 'خدمات', icon: 'folder-simple-star', to: { name: 'student-services' }, active: route.name === 'student-services', }, { title: 'مشاوره', icon: 'chat-teardrop-text', to: { name: 'student-consultants' }, active: route.name === 'student-consultants', }, { title: 'گواهینامه', icon: 'certificate', to: { name: 'student-certificates' }, active: route.name === 'student-certificates', }, { title: 'ویرایش پروفایل', icon: 'user-circle-check', to: { name: 'student-profile' }, active: route.name === 'student-profile', }, { title: 'تیکت', icon: 'envelope-open', to: { name: 'student-tickets' }, active: route.name === 'student-tickets', dedupeKey: 'ticket', }, ] export const buildMissionaryMenuItems = (route) => [ { title: 'پیشخوان', icon: 'menu', to: { name: 'missionary-dashboard' }, active: route.name === 'missionary-dashboard', dedupeKey: 'dashboard', }, { title: 'سامانه اعزام', icon: 'user-sound', to: { name: 'missionary-requests' }, active: route.name === 'missionary-requests', }, { title: 'آموزش من', icon: 'graduation-cap', to: { name: 'missionary-education' }, active: route.name?.startsWith('missionary-education'), dedupeKey: 'education', }, { title: 'تیکت', icon: 'envelope-open', to: { name: 'missionary-tickets' }, active: route.name === 'missionary-tickets', dedupeKey: 'ticket', }, ] export const buildCounselorMenuItems = (route) => [ { title: 'پیشخوان', icon: 'menu', to: { name: 'counselor-dashboard' }, active: route.name === 'counselor-dashboard', dedupeKey: 'dashboard', }, { title: 'مشاوره', icon: 'chat', to: { name: 'counselor-consultations' }, active: route.name === 'counselor-consultations', dedupeKey: 'consultation', }, ] const MENU_BUILDERS = { student: buildStudentMenuItems, missionary: buildMissionaryMenuItems, counselor: buildCounselorMenuItems, } /** * Union of every panel section unlocked by `roles`, in role order (roles * come back from the API ordered by role id, so a user's base role's * sections lead and each additional role's sections are appended after). * Items sharing a dedupeKey across roles are merged — only the first * occurrence is kept (the primary role's version wins). */ export const buildMergedMenuItems = (roles, route) => { const seenRoles = new Set() const seenKeys = new Set() const items = [] for (const roleName of roles ?? []) { const builder = MENU_BUILDERS[roleName] if (!builder || seenRoles.has(roleName)) continue seenRoles.add(roleName) for (const item of builder(route)) { if (item.dedupeKey && seenKeys.has(item.dedupeKey)) continue if (item.dedupeKey) seenKeys.add(item.dedupeKey) items.push(item) } } return items }