Roadmap P0
- Ship /logo.svg fallback and rewire asset references (superseded later by
the project-manager PNG in a separate commit).
Roadmap P1
- Response envelope alignment ({items,total,page,size}) across services
and query hooks.
- Approval/ticket UX updates tied to the new backend rollback semantics.
Roadmap P2
- React.lazy + Vite manualChunks to split vendor-radix/charts/icons/forms
from the main bundle and cut initial JS.
- Fix the 181 tsc errors (PaginationParams class + per-service generics).
- Auto-refresh flow for JWT refresh tokens wired into api-client.ts.
Roadmap P3
- i18n: i18next + language detector, en/ar locales, RTL auto-switch,
LanguageToggle component in RoleLayout and AdminLmsLayout.
- GDPR: PrivacyCenter page for data export and right-to-erasure, backed
by gdpr.service.ts; logout via AuthContext after erasure.
- Human-in-the-loop exam review UI: admin ExamReviewQueue + ExamReviewDetail
pages, useExamReview hooks, exam-review.service.ts.
- AI quality loop: AIPromptEditor (versioning + render preview),
AIFeedbackButtons for students, AIFeedbackTriage admin page, dedicated
services, hooks, and types.
- Dark mode: ThemeProvider + ThemeToggle + chart color tokens.
- Accessibility: DialogDescription on every DialogContent; alert-dialog
and sheet updates.
- Retire dead pages: ExamPage marketing, Index, ProfilePage import.
- Playwright e2e scaffolding: playwright.config.ts + e2e/login.spec.ts
smoke tests, npm scripts test:e2e / test:e2e:install.
Made-with: Cursor
397 lines
26 KiB
TypeScript
397 lines
26 KiB
TypeScript
import { lazy, Suspense } from "react";
|
|
import { ThemeProvider } from "next-themes";
|
|
import { Toaster } from "@/components/ui/toaster";
|
|
import { Toaster as Sonner } from "@/components/ui/sonner";
|
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
import { BrowserRouter, Routes, Route, Navigate, useNavigate } from "react-router-dom";
|
|
import { AuthProvider } from "@/contexts/AuthContext";
|
|
import ProtectedRoute from "@/components/ProtectedRoute";
|
|
import StudentLayout from "@/components/StudentLayout";
|
|
import TeacherLayout from "@/components/TeacherLayout";
|
|
import AdminLmsLayout from "@/components/AdminLmsLayout";
|
|
import { queryClient } from "@/lib/query-client";
|
|
import { Button } from "@/components/ui/button";
|
|
import { ErrorBoundary } from "@/components/ErrorBoundary";
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Lazy-loaded route pages
|
|
// -----------------------------------------------------------------------------
|
|
// Keeping the initial bundle small matters on slow networks / modest hardware
|
|
// (many teachers/students open the app from school Wi-Fi). Each page below is
|
|
// split into its own chunk and only fetched when the user hits the matching
|
|
// route. The shell (layouts, providers, router) is still eagerly imported so
|
|
// the first paint stays snappy.
|
|
|
|
// Auth
|
|
const Login = lazy(() => import("@/pages/Login"));
|
|
const Register = lazy(() => import("@/pages/Register"));
|
|
const EmailVerification = lazy(() => import("@/pages/EmailVerification"));
|
|
const OnboardingWizard = lazy(() => import("@/pages/OnboardingWizard"));
|
|
const ForgotPassword = lazy(() => import("@/pages/ForgotPassword"));
|
|
const ResetPassword = lazy(() => import("@/pages/ResetPassword"));
|
|
const ScoreVerification = lazy(() => import("@/pages/ScoreVerification"));
|
|
|
|
// Original platform pages
|
|
const AdminDashboard = lazy(() => import("@/pages/AdminDashboard"));
|
|
const UsersPage = lazy(() => import("@/pages/UsersPage"));
|
|
const EntitiesPage = lazy(() => import("@/pages/EntitiesPage"));
|
|
const AssignmentsPage = lazy(() => import("@/pages/AssignmentsPage"));
|
|
const ExamsListPage = lazy(() => import("@/pages/ExamsListPage"));
|
|
const ExamStructuresPage = lazy(() => import("@/pages/ExamStructuresPage"));
|
|
const RubricsPage = lazy(() => import("@/pages/RubricsPage"));
|
|
const GenerationPage = lazy(() => import("@/pages/GenerationPage"));
|
|
const ApprovalWorkflowsPage = lazy(() => import("@/pages/ApprovalWorkflowsPage"));
|
|
const ClassroomsPage = lazy(() => import("@/pages/ClassroomsPage"));
|
|
const StudentPerformancePage = lazy(() => import("@/pages/StudentPerformancePage"));
|
|
const StatsCorporatePage = lazy(() => import("@/pages/StatsCorporatePage"));
|
|
const RecordPage = lazy(() => import("@/pages/RecordPage"));
|
|
const VocabularyPage = lazy(() => import("@/pages/VocabularyPage"));
|
|
const GrammarPage = lazy(() => import("@/pages/GrammarPage"));
|
|
const PaymentRecordPage = lazy(() => import("@/pages/PaymentRecordPage"));
|
|
const TicketsPage = lazy(() => import("@/pages/TicketsPage"));
|
|
const SettingsPage = lazy(() => import("@/pages/SettingsPage"));
|
|
|
|
// Student pages
|
|
const StudentDashboard = lazy(() => import("@/pages/student/StudentDashboard"));
|
|
const StudentCourses = lazy(() => import("@/pages/student/StudentCourses"));
|
|
const StudentCourseDetail = lazy(() => import("@/pages/student/StudentCourseDetail"));
|
|
const StudentAssignments = lazy(() => import("@/pages/student/StudentAssignments"));
|
|
const StudentGrades = lazy(() => import("@/pages/student/StudentGrades"));
|
|
const StudentAttendance = lazy(() => import("@/pages/student/StudentAttendance"));
|
|
const StudentTimetable = lazy(() => import("@/pages/student/StudentTimetable"));
|
|
const StudentProfile = lazy(() => import("@/pages/student/StudentProfile"));
|
|
|
|
// Adaptive learning pages
|
|
const SubjectSelection = lazy(() => import("@/pages/student/SubjectSelection"));
|
|
const DiagnosticTest = lazy(() => import("@/pages/student/DiagnosticTest"));
|
|
const ProficiencyProfile = lazy(() => import("@/pages/student/ProficiencyProfile"));
|
|
const LearningPlanPage = lazy(() => import("@/pages/student/LearningPlan"));
|
|
const TopicLearning = lazy(() => import("@/pages/student/TopicLearning"));
|
|
|
|
// Teacher pages
|
|
const TeacherDashboard = lazy(() => import("@/pages/teacher/TeacherDashboard"));
|
|
const TeacherCourses = lazy(() => import("@/pages/teacher/TeacherCourses"));
|
|
const CourseBuilder = lazy(() => import("@/pages/teacher/CourseBuilder"));
|
|
const TeacherAssignments = lazy(() => import("@/pages/teacher/TeacherAssignments"));
|
|
const TeacherAssignmentDetail = lazy(() => import("@/pages/teacher/TeacherAssignmentDetail"));
|
|
const TeacherAttendance = lazy(() => import("@/pages/teacher/TeacherAttendance"));
|
|
const TeacherStudents = lazy(() => import("@/pages/teacher/TeacherStudents"));
|
|
const TeacherTimetable = lazy(() => import("@/pages/teacher/TeacherTimetable"));
|
|
const TeacherProfile = lazy(() => import("@/pages/teacher/TeacherProfile"));
|
|
const TeacherLibrary = lazy(() => import("@/pages/teacher/TeacherLibrary"));
|
|
const AdaptiveSettings = lazy(() => import("@/pages/teacher/AdaptiveSettings"));
|
|
|
|
// Admin LMS pages
|
|
const AdminLmsDashboard = lazy(() => import("@/pages/admin/AdminLmsDashboard"));
|
|
const AdminCourses = lazy(() => import("@/pages/admin/AdminCourses"));
|
|
const AdminStudents = lazy(() => import("@/pages/admin/AdminStudents"));
|
|
const AdminTeachers = lazy(() => import("@/pages/admin/AdminTeachers"));
|
|
const AdminBatches = lazy(() => import("@/pages/admin/AdminBatches"));
|
|
const AdminBatchDetail = lazy(() => import("@/pages/admin/AdminBatchDetail"));
|
|
const AdminTimetable = lazy(() => import("@/pages/admin/AdminTimetable"));
|
|
const AdminReports = lazy(() => import("@/pages/admin/AdminReports"));
|
|
const AdminSettings = lazy(() => import("@/pages/admin/AdminSettings"));
|
|
const AdminProfileLms = lazy(() => import("@/pages/admin/AdminProfile"));
|
|
const TaxonomyManager = lazy(() => import("@/pages/admin/TaxonomyManager"));
|
|
const ResourceManager = lazy(() => import("@/pages/admin/ResourceManager"));
|
|
const AcademicYearManager = lazy(() => import("@/pages/admin/AcademicYearManager"));
|
|
const DepartmentManager = lazy(() => import("@/pages/admin/DepartmentManager"));
|
|
const AdmissionList = lazy(() => import("@/pages/admin/AdmissionList"));
|
|
const AdmissionDetail = lazy(() => import("@/pages/admin/AdmissionDetail"));
|
|
const AdmissionRegisterPage = lazy(() => import("@/pages/admin/AdmissionRegisterPage"));
|
|
const InstitutionalExamSessions = lazy(() => import("@/pages/admin/InstitutionalExamSessions"));
|
|
const MarksheetManager = lazy(() => import("@/pages/admin/MarksheetManager"));
|
|
const AdminStudentLeave = lazy(() => import("@/pages/admin/AdminStudentLeave"));
|
|
const AdminFees = lazy(() => import("@/pages/admin/AdminFees"));
|
|
const AdminLessons = lazy(() => import("@/pages/admin/AdminLessons"));
|
|
const AdminGradebook = lazy(() => import("@/pages/admin/AdminGradebook"));
|
|
const AdminStudentProgress = lazy(() => import("@/pages/admin/AdminStudentProgress"));
|
|
const AdminLibrary = lazy(() => import("@/pages/admin/AdminLibrary"));
|
|
const AdminActivities = lazy(() => import("@/pages/admin/AdminActivities"));
|
|
const AdminFacilities = lazy(() => import("@/pages/admin/AdminFacilities"));
|
|
const AdmissionApplication = lazy(() => import("@/pages/AdmissionApplication"));
|
|
const SubjectRegistrationPage = lazy(() => import("@/pages/student/SubjectRegistrationPage"));
|
|
|
|
// Courseware pages
|
|
const CourseChapters = lazy(() => import("@/pages/teacher/CourseChapters"));
|
|
const ChapterDetail = lazy(() => import("@/pages/teacher/ChapterDetail"));
|
|
const AiWorkbench = lazy(() => import("@/pages/teacher/AiWorkbench"));
|
|
const TeacherDiscussionBoard = lazy(() => import("@/pages/teacher/TeacherDiscussionBoard"));
|
|
const TeacherAnnouncements = lazy(() => import("@/pages/teacher/TeacherAnnouncements"));
|
|
const StudentChapterView = lazy(() => import("@/pages/student/StudentChapterView"));
|
|
const StudentDiscussionBoard = lazy(() => import("@/pages/student/StudentDiscussionBoard"));
|
|
const StudentAnnouncements = lazy(() => import("@/pages/student/StudentAnnouncements"));
|
|
const StudentMessages = lazy(() => import("@/pages/student/StudentMessages"));
|
|
const StudentJourney = lazy(() => import("@/pages/student/StudentJourney"));
|
|
const AiEnglishCourse = lazy(() => import("@/pages/student/AiEnglishCourse"));
|
|
const AiIeltsCourse = lazy(() => import("@/pages/student/AiIeltsCourse"));
|
|
const ExamSession = lazy(() => import("@/pages/student/ExamSession"));
|
|
const ExamStatus = lazy(() => import("@/pages/student/ExamStatus"));
|
|
const ExamResults = lazy(() => import("@/pages/student/ExamResults"));
|
|
const GapAnalysis = lazy(() => import("@/pages/student/GapAnalysis"));
|
|
const CourseDelivery = lazy(() => import("@/pages/student/CourseDelivery"));
|
|
const GradingQueue = lazy(() => import("@/pages/admin/GradingQueue"));
|
|
const CourseConfig = lazy(() => import("@/pages/admin/CourseConfig"));
|
|
const ModuleBuilder = lazy(() => import("@/pages/admin/ModuleBuilder"));
|
|
const CourseProgress = lazy(() => import("@/pages/teacher/CourseProgress"));
|
|
const PlacementBriefing = lazy(() => import("@/pages/student/PlacementBriefing"));
|
|
const PlacementTest = lazy(() => import("@/pages/student/PlacementTest"));
|
|
const PlacementResults = lazy(() => import("@/pages/student/PlacementResults"));
|
|
const PlacementAccess = lazy(() => import("@/pages/student/PlacementAccess"));
|
|
const FaqManager = lazy(() => import("@/pages/admin/FaqManager"));
|
|
const NotificationRules = lazy(() => import("@/pages/admin/NotificationRules"));
|
|
const ApprovalWorkflowConfig = lazy(() => import("@/pages/admin/ApprovalWorkflowConfig"));
|
|
const RolesPermissions = lazy(() => import("@/pages/admin/RolesPermissions"));
|
|
const AuthorityMatrix = lazy(() => import("@/pages/admin/AuthorityMatrix"));
|
|
const UserRoles = lazy(() => import("@/pages/admin/UserRoles"));
|
|
const BulkStudentUpload = lazy(() => import("@/pages/admin/BulkStudentUpload"));
|
|
const CredentialDashboard = lazy(() => import("@/pages/admin/CredentialDashboard"));
|
|
const AiEnglishQuality = lazy(() => import("@/pages/admin/AiEnglishQuality"));
|
|
const AiEnglishTaxonomy = lazy(() => import("@/pages/admin/AiEnglishTaxonomy"));
|
|
const AiIeltsValidation = lazy(() => import("@/pages/admin/AiIeltsValidation"));
|
|
const AdaptiveDashboard = lazy(() => import("@/pages/admin/AdaptiveDashboard"));
|
|
const AdaptiveStudentDetail = lazy(() => import("@/pages/admin/AdaptiveStudentDetail"));
|
|
const LevelMappingConfig = lazy(() => import("@/pages/admin/LevelMappingConfig"));
|
|
const WhiteLabelBranding = lazy(() => import("@/pages/admin/WhiteLabelBranding"));
|
|
const ScoreApprovalQueue = lazy(() => import("@/pages/admin/ScoreApprovalQueue"));
|
|
const ExamTemplateSelection = lazy(() => import("@/pages/admin/ExamTemplateSelection"));
|
|
const IeltsExamCreate = lazy(() => import("@/pages/admin/IeltsExamCreate"));
|
|
const IeltsSkillConfig = lazy(() => import("@/pages/admin/IeltsSkillConfig"));
|
|
const IeltsContentPool = lazy(() => import("@/pages/admin/IeltsContentPool"));
|
|
const IeltsExamValidation = lazy(() => import("@/pages/admin/IeltsExamValidation"));
|
|
const CustomExamCreate = lazy(() => import("@/pages/admin/CustomExamCreate"));
|
|
const ExamReviewQueue = lazy(() => import("@/pages/admin/ExamReviewQueue"));
|
|
const ExamReviewDetail = lazy(() => import("@/pages/admin/ExamReviewDetail"));
|
|
const AIPromptEditor = lazy(() => import("@/pages/admin/AIPromptEditor"));
|
|
const AIFeedbackTriage = lazy(() => import("@/pages/admin/AIFeedbackTriage"));
|
|
const PrivacyCenter = lazy(() => import("@/pages/PrivacyCenter"));
|
|
const OfficialExamAccess = lazy(() => import("@/pages/OfficialExamAccess"));
|
|
const FaqPage = lazy(() => import("@/pages/FaqPage"));
|
|
const NotFound = lazy(() => import("@/pages/NotFound"));
|
|
|
|
function StudentSubscriptionPlaceholder() {
|
|
const navigate = useNavigate();
|
|
return (
|
|
<div className="min-h-screen flex flex-col items-center justify-center gap-4 p-8">
|
|
<p className="text-muted-foreground text-center max-w-sm">Subscription checkout will be available here.</p>
|
|
<Button onClick={() => navigate("/student/dashboard")}>Back to dashboard</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function RouteFallback() {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center">
|
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const App = () => (
|
|
<ErrorBoundary>
|
|
<ThemeProvider
|
|
attribute="class"
|
|
defaultTheme="system"
|
|
enableSystem
|
|
storageKey="encoach-theme"
|
|
disableTransitionOnChange
|
|
>
|
|
<QueryClientProvider client={queryClient}>
|
|
<TooltipProvider>
|
|
<Toaster />
|
|
<Sonner />
|
|
<BrowserRouter>
|
|
<AuthProvider>
|
|
<Suspense fallback={<RouteFallback />}>
|
|
<Routes>
|
|
{/* Auth routes */}
|
|
<Route path="/login" element={<Login />} />
|
|
<Route path="/register" element={<Register />} />
|
|
<Route path="/verify-email" element={<EmailVerification />} />
|
|
<Route path="/forgot-password" element={<ForgotPassword />} />
|
|
<Route path="/reset-password" element={<ResetPassword />} />
|
|
<Route path="/verify/:verificationHash" element={<ScoreVerification />} />
|
|
{/* Public pages */}
|
|
<Route path="/apply" element={<AdmissionApplication />} />
|
|
<Route path="/exam/access/:token" element={<OfficialExamAccess />} />
|
|
<Route path="/exam/official/:code" element={<OfficialExamAccess />} />
|
|
<Route path="/exam/login/:examId" element={<OfficialExamAccess />} />
|
|
<Route path="/faq" element={<FaqPage />} />
|
|
|
|
<Route element={<ProtectedRoute />}>
|
|
<Route path="/onboarding" element={<OnboardingWizard />} />
|
|
</Route>
|
|
|
|
{/* Student routes */}
|
|
<Route element={<ProtectedRoute allowedRoles={["student"]} />}>
|
|
<Route path="/student/exam/:examId/session" element={<ExamSession />} />
|
|
<Route path="/student/exam/:examId/status" element={<ExamStatus />} />
|
|
<Route path="/student/placement/test" element={<PlacementTest />} />
|
|
<Route path="/student/subscription" element={<StudentSubscriptionPlaceholder />} />
|
|
<Route element={<StudentLayout />}>
|
|
<Route path="/student/dashboard" element={<StudentDashboard />} />
|
|
<Route path="/student/courses" element={<StudentCourses />} />
|
|
<Route path="/student/courses/:id" element={<StudentCourseDetail />} />
|
|
<Route path="/student/assignments" element={<StudentAssignments />} />
|
|
<Route path="/student/grades" element={<StudentGrades />} />
|
|
<Route path="/student/attendance" element={<StudentAttendance />} />
|
|
<Route path="/student/timetable" element={<StudentTimetable />} />
|
|
<Route path="/student/profile" element={<StudentProfile />} />
|
|
<Route path="/student/privacy" element={<PrivacyCenter />} />
|
|
<Route path="/student/subjects" element={<SubjectSelection />} />
|
|
<Route path="/student/diagnostic/:subjectId" element={<DiagnosticTest />} />
|
|
<Route path="/student/proficiency/:subjectId" element={<ProficiencyProfile />} />
|
|
<Route path="/student/plan/:subjectId" element={<LearningPlanPage />} />
|
|
<Route path="/student/topic/:topicId" element={<TopicLearning />} />
|
|
<Route path="/student/subject-registration" element={<SubjectRegistrationPage />} />
|
|
<Route path="/student/courses/:id/chapters/:chapterId" element={<StudentChapterView />} />
|
|
<Route path="/student/discussions" element={<StudentDiscussionBoard />} />
|
|
<Route path="/student/announcements" element={<StudentAnnouncements />} />
|
|
<Route path="/student/messages" element={<StudentMessages />} />
|
|
<Route path="/student/journey" element={<StudentJourney />} />
|
|
<Route path="/student/placement" element={<PlacementBriefing />} />
|
|
<Route path="/student/placement/results" element={<PlacementResults />} />
|
|
<Route path="/student/placement/access" element={<PlacementAccess />} />
|
|
<Route path="/student/exam/:examId/results" element={<ExamResults />} />
|
|
<Route path="/student/course/generate" element={<GapAnalysis />} />
|
|
<Route path="/student/course/ai-english/:courseId" element={<AiEnglishCourse />} />
|
|
<Route path="/student/course/ai-ielts/:courseId" element={<AiIeltsCourse />} />
|
|
<Route path="/student/course/:courseId" element={<CourseDelivery />} />
|
|
</Route>
|
|
</Route>
|
|
|
|
{/* Teacher routes */}
|
|
<Route element={<ProtectedRoute allowedRoles={["teacher", "admin", "developer"]} />}>
|
|
<Route element={<TeacherLayout />}>
|
|
<Route path="/teacher/dashboard" element={<TeacherDashboard />} />
|
|
<Route path="/teacher/courses" element={<TeacherCourses />} />
|
|
<Route path="/teacher/library" element={<TeacherLibrary />} />
|
|
<Route path="/teacher/courses/new" element={<CourseBuilder />} />
|
|
<Route path="/teacher/courses/:id/edit" element={<CourseBuilder />} />
|
|
<Route path="/teacher/assignments" element={<TeacherAssignments />} />
|
|
<Route path="/teacher/assignments/:id" element={<TeacherAssignmentDetail />} />
|
|
<Route path="/teacher/attendance" element={<TeacherAttendance />} />
|
|
<Route path="/teacher/students" element={<TeacherStudents />} />
|
|
<Route path="/teacher/timetable" element={<TeacherTimetable />} />
|
|
<Route path="/teacher/courses/:courseId/chapters" element={<CourseChapters />} />
|
|
<Route path="/teacher/courses/:courseId/chapters/:chapterId" element={<ChapterDetail />} />
|
|
<Route path="/teacher/courses/:courseId/workbench" element={<AiWorkbench />} />
|
|
<Route path="/teacher/discussions" element={<TeacherDiscussionBoard />} />
|
|
<Route path="/teacher/announcements" element={<TeacherAnnouncements />} />
|
|
<Route path="/teacher/profile" element={<TeacherProfile />} />
|
|
<Route path="/teacher/privacy" element={<PrivacyCenter />} />
|
|
<Route path="/teacher/course/:courseId/progress" element={<CourseProgress />} />
|
|
<Route path="/teacher/adaptive/settings" element={<AdaptiveSettings />} />
|
|
</Route>
|
|
</Route>
|
|
|
|
{/* Admin routes — unified: original platform + LMS + AI */}
|
|
<Route element={<ProtectedRoute allowedRoles={["admin", "corporate", "mastercorporate", "agent", "developer"]} />}>
|
|
<Route element={<AdminLmsLayout />}>
|
|
{/* LMS Dashboard */}
|
|
<Route path="/admin/dashboard" element={<AdminLmsDashboard />} />
|
|
{/* Original platform dashboard */}
|
|
<Route path="/admin/platform" element={<AdminDashboard />} />
|
|
{/* LMS pages */}
|
|
<Route path="/admin/courses" element={<AdminCourses />} />
|
|
<Route path="/admin/students" element={<AdminStudents />} />
|
|
<Route path="/admin/teachers" element={<AdminTeachers />} />
|
|
<Route path="/admin/batches" element={<AdminBatches />} />
|
|
<Route path="/admin/batches/:id" element={<AdminBatchDetail />} />
|
|
<Route path="/admin/timetable" element={<AdminTimetable />} />
|
|
<Route path="/admin/reports" element={<AdminReports />} />
|
|
<Route path="/admin/settings" element={<AdminSettings />} />
|
|
<Route path="/admin/profile" element={<AdminProfileLms />} />
|
|
<Route path="/admin/privacy" element={<PrivacyCenter />} />
|
|
{/* Original academic pages */}
|
|
<Route path="/admin/assignments" element={<AssignmentsPage />} />
|
|
<Route path="/admin/examsList" element={<ExamsListPage />} />
|
|
<Route path="/admin/exam-structures" element={<ExamStructuresPage />} />
|
|
<Route path="/admin/rubrics" element={<RubricsPage />} />
|
|
<Route path="/admin/generation" element={<GenerationPage />} />
|
|
<Route path="/admin/approval-workflows" element={<ApprovalWorkflowsPage />} />
|
|
{/* Original management pages */}
|
|
<Route path="/admin/users" element={<UsersPage />} />
|
|
<Route path="/admin/entities" element={<EntitiesPage />} />
|
|
<Route path="/admin/classrooms" element={<ClassroomsPage />} />
|
|
{/* Original report pages */}
|
|
<Route path="/admin/student-performance" element={<StudentPerformancePage />} />
|
|
<Route path="/admin/stats-corporate" element={<StatsCorporatePage />} />
|
|
<Route path="/admin/record" element={<RecordPage />} />
|
|
{/* Training */}
|
|
<Route path="/admin/training/vocabulary" element={<VocabularyPage />} />
|
|
<Route path="/admin/training/grammar" element={<GrammarPage />} />
|
|
{/* Support */}
|
|
<Route path="/admin/payment-record" element={<PaymentRecordPage />} />
|
|
<Route path="/admin/tickets" element={<TicketsPage />} />
|
|
<Route path="/admin/settings-platform" element={<SettingsPage />} />
|
|
<Route path="/admin/exam/create" element={<ExamTemplateSelection />} />
|
|
<Route path="/admin/exam/ielts/create" element={<IeltsExamCreate />} />
|
|
<Route path="/admin/exam/ielts/:examId/skills" element={<IeltsSkillConfig />} />
|
|
<Route path="/admin/exam/ielts/:examId/content" element={<IeltsContentPool />} />
|
|
<Route path="/admin/exam/ielts/:examId/validate" element={<IeltsExamValidation />} />
|
|
<Route path="/admin/exam/custom/create" element={<CustomExamCreate />} />
|
|
<Route path="/admin/exam/review-queue" element={<ExamReviewQueue />} />
|
|
<Route path="/admin/exam/review/:examId" element={<ExamReviewDetail />} />
|
|
<Route path="/admin/ai/prompts" element={<AIPromptEditor />} />
|
|
<Route path="/admin/ai/feedback" element={<AIFeedbackTriage />} />
|
|
<Route path="/admin/taxonomy" element={<TaxonomyManager />} />
|
|
<Route path="/admin/resources" element={<ResourceManager />} />
|
|
{/* Institutional LMS pages */}
|
|
<Route path="/admin/academic-years" element={<AcademicYearManager />} />
|
|
<Route path="/admin/departments" element={<DepartmentManager />} />
|
|
<Route path="/admin/admissions" element={<AdmissionList />} />
|
|
<Route path="/admin/admissions/:id" element={<AdmissionDetail />} />
|
|
<Route path="/admin/admission-register" element={<AdmissionRegisterPage />} />
|
|
<Route path="/admin/exam-sessions" element={<InstitutionalExamSessions />} />
|
|
<Route path="/admin/marksheets" element={<MarksheetManager />} />
|
|
{/* OpenEduCat module pages */}
|
|
<Route path="/admin/student-leave" element={<AdminStudentLeave />} />
|
|
<Route path="/admin/fees" element={<AdminFees />} />
|
|
<Route path="/admin/lessons" element={<AdminLessons />} />
|
|
<Route path="/admin/gradebook" element={<AdminGradebook />} />
|
|
<Route path="/admin/student-progress" element={<AdminStudentProgress />} />
|
|
<Route path="/admin/library" element={<AdminLibrary />} />
|
|
<Route path="/admin/activities" element={<AdminActivities />} />
|
|
<Route path="/admin/facilities" element={<AdminFacilities />} />
|
|
<Route path="/admin/faq" element={<FaqManager />} />
|
|
<Route path="/admin/notification-rules" element={<NotificationRules />} />
|
|
<Route path="/admin/approval-config" element={<ApprovalWorkflowConfig />} />
|
|
<Route path="/admin/roles-permissions" element={<RolesPermissions />} />
|
|
<Route path="/admin/authority-matrix" element={<AuthorityMatrix />} />
|
|
<Route path="/admin/user-roles" element={<UserRoles />} />
|
|
<Route path="/admin/exam/:examId/grading" element={<GradingQueue />} />
|
|
<Route path="/admin/course/configure/:courseId" element={<CourseConfig />} />
|
|
<Route path="/admin/course/:courseId/modules" element={<ModuleBuilder />} />
|
|
<Route path="/admin/entity/students/upload" element={<BulkStudentUpload />} />
|
|
<Route path="/admin/entity/students/credentials" element={<CredentialDashboard />} />
|
|
<Route path="/admin/entity/:entityId/level-mapping" element={<LevelMappingConfig />} />
|
|
<Route path="/admin/entity/:entityId/branding" element={<WhiteLabelBranding />} />
|
|
<Route path="/admin/ai-course/english/:courseId/quality" element={<AiEnglishQuality />} />
|
|
<Route path="/admin/ai-course/english/taxonomy" element={<AiEnglishTaxonomy />} />
|
|
<Route path="/admin/ai-course/ielts/:courseId/validation" element={<AiIeltsValidation />} />
|
|
<Route path="/admin/adaptive/dashboard" element={<AdaptiveDashboard />} />
|
|
<Route path="/admin/adaptive/student/:studentId" element={<AdaptiveStudentDetail />} />
|
|
<Route path="/admin/scores/pending" element={<ScoreApprovalQueue />} />
|
|
</Route>
|
|
</Route>
|
|
|
|
{/* Redirects */}
|
|
<Route path="/" element={<Navigate to="/login" replace />} />
|
|
<Route path="/admin" element={<Navigate to="/admin/dashboard" replace />} />
|
|
{/* Legacy route redirects */}
|
|
<Route path="/dashboard/admin" element={<Navigate to="/admin/platform" replace />} />
|
|
<Route path="*" element={<NotFound />} />
|
|
</Routes>
|
|
</Suspense>
|
|
</AuthProvider>
|
|
</BrowserRouter>
|
|
</TooltipProvider>
|
|
</QueryClientProvider>
|
|
</ThemeProvider>
|
|
</ErrorBoundary>
|
|
);
|
|
|
|
export default App;
|