67 lines
2.8 KiB
TypeScript
67 lines
2.8 KiB
TypeScript
import { Activity, BarChart3, BookOpen, Car, ClipboardList, GitPullRequest, Settings, Users, type LucideIcon } from 'lucide-react';
|
|
|
|
export type AppRoute = 'dashboard' | 'curriculum' | 'groups' | 'platforms' | 'students' | 'submissions' | 'analytics' | 'settings' | 'profile';
|
|
|
|
export type NavItem = {
|
|
id: AppRoute;
|
|
label: string;
|
|
icon: LucideIcon;
|
|
// children?: string[];
|
|
};
|
|
|
|
export const defaultRoute: AppRoute = 'dashboard';
|
|
|
|
export const routePaths: Record<AppRoute, string> = {
|
|
dashboard: '/dashboard',
|
|
curriculum: '/curriculum',
|
|
groups: '/groups',
|
|
platforms: '/platforms',
|
|
students: '/students',
|
|
submissions: '/submissions',
|
|
analytics: '/analytics',
|
|
settings: '/settings',
|
|
profile: '/profile'
|
|
};
|
|
|
|
export const navItems: NavItem[] = [
|
|
{ id: 'dashboard', label: '대시보드', icon: Activity },
|
|
{ id: 'curriculum', label: '커리큘럼 관리', icon: ClipboardList },
|
|
{ id: 'groups', label: '그룹 관리', icon: Users },
|
|
{ id: 'platforms', label: '플랫폼 관리', icon: Car },
|
|
{ id: 'students', label: '수강생 현황', icon: BookOpen },
|
|
{ id: 'submissions', label: '제출 현황', icon: GitPullRequest },
|
|
{ id: 'analytics', label: '통계 분석', icon: BarChart3 },
|
|
{ id: 'settings', label: '설정', icon: Settings }
|
|
];
|
|
|
|
// 2depth menu candidates. Keep this until the left menu structure is finalized.
|
|
// export const navItemChildren: Record<Exclude<AppRoute, 'profile'>, string[]> = {
|
|
// dashboard: ['운영 요약', '오늘 할 일', '빠른 설정'],
|
|
// groups: ['그룹 목록', '플랫폼 배정', '실습 주차'],
|
|
// platforms: ['실시간 상태', '긴급 정지 로그', '장비 설정'],
|
|
// students: ['수강생 목록', '접속 현황', '과제 제출'],
|
|
// analytics: ['진도 분석', '플랫폼 사용률', '질문 추이'],
|
|
// settings: ['권한 정책', '알림 설정', '서비스 연결']
|
|
// };
|
|
|
|
const appRoutes: AppRoute[] = [...navItems.map((item) => item.id), 'profile'];
|
|
const publicBasePath = import.meta.env.BASE_URL.replace(/\/+$/, '');
|
|
|
|
const stripPublicBasePath = (pathname: string): string => {
|
|
if (!publicBasePath || publicBasePath === '/') return pathname;
|
|
if (pathname === publicBasePath) return '/';
|
|
if (pathname.startsWith(`${publicBasePath}/`)) return pathname.slice(publicBasePath.length) || '/';
|
|
return pathname;
|
|
};
|
|
|
|
export const isAppRoute = (value: string): value is AppRoute => appRoutes.includes(value as AppRoute);
|
|
|
|
export const getRoutePath = (route: AppRoute) => routePaths[route];
|
|
|
|
export const getRouteFromPathname = (pathname: string): AppRoute | null => {
|
|
const routePathname = stripPublicBasePath(pathname);
|
|
const normalizedPath = routePathname === '/' ? routePaths[defaultRoute] : routePathname.replace(/\/+$/, '');
|
|
const entry = Object.entries(routePaths).find(([, path]) => path === normalizedPath);
|
|
return entry ? (entry[0] as AppRoute) : null;
|
|
};
|