# Conflicts: # src/AppRoutes.tsx # src/pages/exam/index.ts # src/services/exam/examRepository.ts # src/types/exam.types.ts
211 lines
7.6 KiB
TypeScript
211 lines
7.6 KiB
TypeScript
import React from 'react';
|
|
import { Routes, Route, useLocation, Outlet, Navigate } from 'react-router-dom';
|
|
import { useAuth } from './contexts/AuthContext';
|
|
import { useUser } from './contexts/UserContext';
|
|
import Layout from './pages/Layout';
|
|
import LoginPage from './pages/auth/loginPage';
|
|
import SignupPage from './pages/auth/signupPage';
|
|
import SinglePlayerPage from './pages/tldraw/singlePlayerPage';
|
|
import MultiplayerUser from './pages/tldraw/multiplayerUser';
|
|
import { ExamDashboardPage, ExamMarkingPage, ExamResultsPage, ExamTemplateSetupPage, MarkSchemePage } from './pages/exam';
|
|
import { ErrorBoundary } from './components/ErrorBoundary';
|
|
import CalendarPage from './pages/user/calendarPage';
|
|
import SettingsPage from './pages/user/settingsPage';
|
|
import TLDrawCanvas from './pages/tldraw/TLDrawCanvas';
|
|
import AdminDashboard from './pages/auth/adminPage';
|
|
import PlatformAdminPage from './pages/auth/PlatformAdminPage';
|
|
import TLDrawDevPage from './pages/tldraw/devPlayerPage';
|
|
import DevPage from './pages/tldraw/devPage';
|
|
import TeacherPlanner from './pages/react-flow/teacherPlanner';
|
|
import MorphicPage from './pages/morphicPage';
|
|
import NotFound from './pages/user/NotFound';
|
|
import NotFoundPublic from './pages/NotFoundPublic';
|
|
import ShareHandler from './pages/tldraw/ShareHandler';
|
|
import SearxngPage from './pages/searxngPage';
|
|
import SimpleUploadTest from './pages/dev/SimpleUploadTest';
|
|
import { logger } from './debugConfig';
|
|
import { CircularProgress } from '@mui/material';
|
|
import { CCDocumentIntelligence } from './pages/tldraw/CCDocumentIntelligence/CCDocumentIntelligence';
|
|
import DashboardPage from './pages/user/dashboardPage';
|
|
|
|
// Timetable Module Pages
|
|
import {
|
|
TimetablePage,
|
|
TimetableListPage,
|
|
ClassesPage,
|
|
LessonPage,
|
|
TaughtLessonsPage,
|
|
MyClassesPage,
|
|
EnrollmentRequestsPage,
|
|
StaffManagerPage,
|
|
StudentManagerPage,
|
|
SchoolSettingsPage,
|
|
ClassDetailPage,
|
|
StudentLessonsPage,
|
|
LessonPlansPage,
|
|
LessonPlanDetailPage,
|
|
} from './pages/timetable';
|
|
|
|
const FullContextRoutes: React.FC = () => {
|
|
const { isInitialized: isUserInitialized } = useUser();
|
|
|
|
if (!isUserInitialized) {
|
|
return (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
height: '100%',
|
|
width: '100%'
|
|
}}
|
|
>
|
|
<CircularProgress />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return <Outlet />;
|
|
};
|
|
|
|
const RequireAuth: React.FC = () => {
|
|
const { user, isAuthResolving } = useAuth();
|
|
|
|
if (isAuthResolving) {
|
|
return (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
height: '100vh'
|
|
}}
|
|
>
|
|
<CircularProgress />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!user) {
|
|
return <Navigate to="/login" replace />;
|
|
}
|
|
|
|
return <Outlet />;
|
|
};
|
|
|
|
const AppRoutes: React.FC = () => {
|
|
const { user, user_role, loading: isAuthLoading } = useAuth();
|
|
const location = useLocation();
|
|
const platformAdminRoles = ['super_admin', 'cc_admin', 'cc_developer'];
|
|
const isPlatformAdmin = !!user && platformAdminRoles.includes(user_role ?? '');
|
|
|
|
// Debug log for routing
|
|
logger.debug('routing', '🔄 Rendering routes', {
|
|
hasUser: !!user,
|
|
userId: user?.id,
|
|
userEmail: user?.email,
|
|
currentPath: location.pathname,
|
|
authStatus: {
|
|
isLoading: isAuthLoading,
|
|
},
|
|
});
|
|
|
|
// Show loading state while initializing
|
|
if (isAuthLoading) {
|
|
return (
|
|
<Layout>
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
height: '100vh',
|
|
}}
|
|
>
|
|
<CircularProgress />
|
|
</div>
|
|
</Layout>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Layout>
|
|
<Routes>
|
|
{/* Public routes */}
|
|
<Route
|
|
path="/"
|
|
element={user ? <DashboardPage /> : <TLDrawCanvas />}
|
|
/>
|
|
<Route path="/login" element={<LoginPage />} />
|
|
<Route path="/signup" element={<SignupPage />} />
|
|
<Route path="/share" element={<ShareHandler />} />
|
|
|
|
{/* Lightweight authenticated routes */}
|
|
<Route
|
|
path="/dashboard"
|
|
element={user ? <DashboardPage /> : <Navigate to="/login" replace />}
|
|
/>
|
|
|
|
{/* Super Admin only routes */}
|
|
<Route
|
|
path="/admin"
|
|
element={
|
|
!user ? (
|
|
<Navigate to="/login" replace state={{ from: location }} />
|
|
) : isPlatformAdmin ? (
|
|
<PlatformAdminPage />
|
|
) : (
|
|
<Navigate to="/dashboard" replace />
|
|
)
|
|
}
|
|
/>
|
|
|
|
{/* Authentication only routes - only render if all contexts are initialized */}
|
|
<Route element={<RequireAuth />}>
|
|
<Route element={<FullContextRoutes />}>
|
|
{/* Timetable Module Routes */}
|
|
<Route path="/timetable" element={<TimetableListPage />} />
|
|
<Route path="/timetable/:timetableId" element={<TimetablePage />} />
|
|
<Route path="/classes" element={<ClassesPage />} />
|
|
<Route path="/my-classes" element={<MyClassesPage />} />
|
|
<Route path="/classes/:classId" element={<ClassDetailPage />} />
|
|
<Route path="/timetable/classes/:classId" element={<ClassDetailPage />} />
|
|
<Route path="/student-lessons" element={<StudentLessonsPage />} />
|
|
<Route path="/lesson-plans" element={<LessonPlansPage />} />
|
|
<Route path="/lesson-plans/:planId" element={<LessonPlanDetailPage />} />
|
|
<Route path="/enrollment-requests" element={<EnrollmentRequestsPage />} />
|
|
<Route path="/lessons/:lessonId" element={<LessonPage />} />
|
|
<Route path="/my-lessons" element={<TaughtLessonsPage />} />
|
|
<Route path="/staff-manager" element={<StaffManagerPage />} />
|
|
<Route path="/student-manager" element={<StudentManagerPage />} />
|
|
<Route path="/school-settings" element={<SchoolSettingsPage />} />
|
|
|
|
{/* Existing Routes */}
|
|
<Route path="/search" element={<SearxngPage />} />
|
|
<Route path="/teacher-planner" element={<TeacherPlanner />} />
|
|
<Route path="/exam-marker" element={<ErrorBoundary><ExamDashboardPage /></ErrorBoundary>} />
|
|
<Route path="/exam-marker/:templateId/setup" element={<ErrorBoundary><ExamTemplateSetupPage /></ErrorBoundary>} />
|
|
<Route path="/exam-marker/:templateId/marks" element={<ErrorBoundary><MarkSchemePage /></ErrorBoundary>} />
|
|
<Route path="/exam-marker/:batchId/mark" element={<ErrorBoundary><ExamMarkingPage /></ErrorBoundary>} />
|
|
<Route path="/exam-marker/:batchId/results" element={<ErrorBoundary><ExamResultsPage /></ErrorBoundary>} />
|
|
<Route path="/doc-intelligence/:fileId" element={<CCDocumentIntelligence />} />
|
|
<Route path="/morphic" element={<MorphicPage />} />
|
|
<Route path="/tldraw-dev" element={<TLDrawDevPage />} />
|
|
<Route path="/dev" element={<DevPage />} />
|
|
<Route path="/dev/upload-test" element={<SimpleUploadTest />} />
|
|
<Route path="/single-player" element={<SinglePlayerPage />} />
|
|
<Route path="/multiplayer" element={<MultiplayerUser />} />
|
|
<Route path="/calendar" element={<CalendarPage />} />
|
|
<Route path="/settings" element={<SettingsPage />} />
|
|
</Route>
|
|
</Route>
|
|
|
|
{/* Fallback route - authenticated users go to dashboard, unauthenticated see public 404 */}
|
|
<Route path="*" element={user ? <Navigate to="/dashboard" replace /> : <NotFoundPublic />} />
|
|
</Routes>
|
|
</Layout>
|
|
);
|
|
};
|
|
|
|
export default AppRoutes;
|