import { computed, type Ref } from 'vue' import { useRoute } from 'vue-router' import { Visibility, routes, type LayoutRoute } from '@/plugins/routesLayout' import { ROLE_ADMIN, hasRole, type CurrentUser } from '@/services/authSession' function normalizeRoutePath(path: string) { if (!path || path === '/') { return '/' } return path.endsWith('/') ? path.slice(0, -1) : path } function isWithinRoutePath(currentPath: string, targetPath: string) { const normalizedCurrent = normalizeRoutePath(currentPath) const normalizedTarget = normalizeRoutePath(targetPath) if (normalizedTarget === '/') { return normalizedCurrent === '/' } return ( normalizedCurrent === normalizedTarget || normalizedCurrent.startsWith(`${normalizedTarget}/`) ) } function resolveVisibilityRoutes(path: string, visibilityRoute?: string | string[]) { if (Array.isArray(visibilityRoute)) { return visibilityRoute.map((entry) => entry.trim()).filter((entry) => entry.length > 0) } const normalized = visibilityRoute?.trim() if (normalized && normalized.length > 0) { return [normalized] } return [path] } function isVisible(item: LayoutRoute, currentPath: string, user: CurrentUser | null) { switch (item.visible) { case Visibility.Public: return true case Visibility.Authenticated: return user !== null case Visibility.Unauthenticated: return user === null case Visibility.Authorized: if (!user) { return false } if (!item.requiredRoles || item.requiredRoles.length === 0) { return true } return item.requiredRoles.every((role) => hasRole(user, role)) case Visibility.Route: return resolveVisibilityRoutes(item.path, item.visibilityRoute).some((target) => isWithinRoutePath(currentPath, target), ) default: return false } } function isAdminRoute(item: LayoutRoute) { return ( item.visible === Visibility.Authorized && Array.isArray(item.requiredRoles) && item.requiredRoles.some((role) => role.trim().toLowerCase() === ROLE_ADMIN) ) } export function useSidebarRoutes(currentUser: Ref) { const route = useRoute() const sidebarRoutes = computed(() => routes.filter((item) => isVisible(item, route.path, currentUser.value)), ) const adminSidebarRoutes = computed(() => sidebarRoutes.value.filter(isAdminRoute)) const primarySidebarRoutes = computed(() => sidebarRoutes.value.filter((item) => !isAdminRoute(item)), ) const footerRoutes = computed(() => routes.filter((item) => item.visible === Visibility.Footer), ) return { sidebarRoutes, adminSidebarRoutes, primarySidebarRoutes, footerRoutes, } }