feat(frontend): Phase 2/3 hardening release
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
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
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";
|
||||
@@ -8,146 +10,166 @@ import ProtectedRoute from "@/components/ProtectedRoute";
|
||||
import StudentLayout from "@/components/StudentLayout";
|
||||
import TeacherLayout from "@/components/TeacherLayout";
|
||||
import AdminLmsLayout from "@/components/AdminLmsLayout";
|
||||
import Login from "@/pages/Login";
|
||||
import Register from "@/pages/Register";
|
||||
import EmailVerification from "@/pages/EmailVerification";
|
||||
import OnboardingWizard from "@/pages/OnboardingWizard";
|
||||
import ForgotPassword from "@/pages/ForgotPassword";
|
||||
import ResetPassword from "@/pages/ResetPassword";
|
||||
import ScoreVerification from "@/pages/ScoreVerification";
|
||||
// Original platform pages
|
||||
import AdminDashboard from "@/pages/AdminDashboard";
|
||||
import UsersPage from "@/pages/UsersPage";
|
||||
import EntitiesPage from "@/pages/EntitiesPage";
|
||||
import AssignmentsPage from "@/pages/AssignmentsPage";
|
||||
import ExamsListPage from "@/pages/ExamsListPage";
|
||||
import ExamStructuresPage from "@/pages/ExamStructuresPage";
|
||||
import RubricsPage from "@/pages/RubricsPage";
|
||||
import GenerationPage from "@/pages/GenerationPage";
|
||||
import ApprovalWorkflowsPage from "@/pages/ApprovalWorkflowsPage";
|
||||
import ClassroomsPage from "@/pages/ClassroomsPage";
|
||||
import StudentPerformancePage from "@/pages/StudentPerformancePage";
|
||||
import StatsCorporatePage from "@/pages/StatsCorporatePage";
|
||||
import RecordPage from "@/pages/RecordPage";
|
||||
import VocabularyPage from "@/pages/VocabularyPage";
|
||||
import GrammarPage from "@/pages/GrammarPage";
|
||||
import PaymentRecordPage from "@/pages/PaymentRecordPage";
|
||||
import TicketsPage from "@/pages/TicketsPage";
|
||||
import SettingsPage from "@/pages/SettingsPage";
|
||||
import ProfilePage from "@/pages/ProfilePage";
|
||||
import ExamPage from "@/pages/ExamPage";
|
||||
// Student pages
|
||||
import StudentDashboard from "@/pages/student/StudentDashboard";
|
||||
import StudentCourses from "@/pages/student/StudentCourses";
|
||||
import StudentCourseDetail from "@/pages/student/StudentCourseDetail";
|
||||
import StudentAssignments from "@/pages/student/StudentAssignments";
|
||||
import StudentGrades from "@/pages/student/StudentGrades";
|
||||
import StudentAttendance from "@/pages/student/StudentAttendance";
|
||||
import StudentTimetable from "@/pages/student/StudentTimetable";
|
||||
import StudentProfile from "@/pages/student/StudentProfile";
|
||||
// Adaptive learning pages
|
||||
import SubjectSelection from "@/pages/student/SubjectSelection";
|
||||
import DiagnosticTest from "@/pages/student/DiagnosticTest";
|
||||
import ProficiencyProfile from "@/pages/student/ProficiencyProfile";
|
||||
import LearningPlanPage from "@/pages/student/LearningPlan";
|
||||
import TopicLearning from "@/pages/student/TopicLearning";
|
||||
// Teacher pages
|
||||
import TeacherDashboard from "@/pages/teacher/TeacherDashboard";
|
||||
import TeacherCourses from "@/pages/teacher/TeacherCourses";
|
||||
import CourseBuilder from "@/pages/teacher/CourseBuilder";
|
||||
import TeacherAssignments from "@/pages/teacher/TeacherAssignments";
|
||||
import TeacherAssignmentDetail from "@/pages/teacher/TeacherAssignmentDetail";
|
||||
import TeacherAttendance from "@/pages/teacher/TeacherAttendance";
|
||||
import TeacherStudents from "@/pages/teacher/TeacherStudents";
|
||||
import TeacherTimetable from "@/pages/teacher/TeacherTimetable";
|
||||
import TeacherProfile from "@/pages/teacher/TeacherProfile";
|
||||
import TeacherLibrary from "@/pages/teacher/TeacherLibrary";
|
||||
import AdaptiveSettings from "@/pages/teacher/AdaptiveSettings";
|
||||
// Admin LMS pages
|
||||
import AdminLmsDashboard from "@/pages/admin/AdminLmsDashboard";
|
||||
import AdminCourses from "@/pages/admin/AdminCourses";
|
||||
import AdminStudents from "@/pages/admin/AdminStudents";
|
||||
import AdminTeachers from "@/pages/admin/AdminTeachers";
|
||||
import AdminBatches from "@/pages/admin/AdminBatches";
|
||||
import AdminBatchDetail from "@/pages/admin/AdminBatchDetail";
|
||||
import AdminTimetable from "@/pages/admin/AdminTimetable";
|
||||
import AdminReports from "@/pages/admin/AdminReports";
|
||||
import AdminSettings from "@/pages/admin/AdminSettings";
|
||||
import AdminProfileLms from "@/pages/admin/AdminProfile";
|
||||
import TaxonomyManager from "@/pages/admin/TaxonomyManager";
|
||||
import ResourceManager from "@/pages/admin/ResourceManager";
|
||||
import AcademicYearManager from "@/pages/admin/AcademicYearManager";
|
||||
import DepartmentManager from "@/pages/admin/DepartmentManager";
|
||||
import AdmissionList from "@/pages/admin/AdmissionList";
|
||||
import AdmissionDetail from "@/pages/admin/AdmissionDetail";
|
||||
import AdmissionRegisterPage from "@/pages/admin/AdmissionRegisterPage";
|
||||
import InstitutionalExamSessions from "@/pages/admin/InstitutionalExamSessions";
|
||||
import MarksheetManager from "@/pages/admin/MarksheetManager";
|
||||
import AdminStudentLeave from "@/pages/admin/AdminStudentLeave";
|
||||
import AdminFees from "@/pages/admin/AdminFees";
|
||||
import AdminLessons from "@/pages/admin/AdminLessons";
|
||||
import AdminGradebook from "@/pages/admin/AdminGradebook";
|
||||
import AdminStudentProgress from "@/pages/admin/AdminStudentProgress";
|
||||
import AdminLibrary from "@/pages/admin/AdminLibrary";
|
||||
import AdminActivities from "@/pages/admin/AdminActivities";
|
||||
import AdminFacilities from "@/pages/admin/AdminFacilities";
|
||||
import AdmissionApplication from "@/pages/AdmissionApplication";
|
||||
import SubjectRegistrationPage from "@/pages/student/SubjectRegistrationPage";
|
||||
// Courseware pages
|
||||
import CourseChapters from "@/pages/teacher/CourseChapters";
|
||||
import ChapterDetail from "@/pages/teacher/ChapterDetail";
|
||||
import AiWorkbench from "@/pages/teacher/AiWorkbench";
|
||||
import TeacherDiscussionBoard from "@/pages/teacher/TeacherDiscussionBoard";
|
||||
import TeacherAnnouncements from "@/pages/teacher/TeacherAnnouncements";
|
||||
import StudentChapterView from "@/pages/student/StudentChapterView";
|
||||
import StudentDiscussionBoard from "@/pages/student/StudentDiscussionBoard";
|
||||
import StudentAnnouncements from "@/pages/student/StudentAnnouncements";
|
||||
import StudentMessages from "@/pages/student/StudentMessages";
|
||||
import StudentJourney from "@/pages/student/StudentJourney";
|
||||
import AiEnglishCourse from "@/pages/student/AiEnglishCourse";
|
||||
import AiIeltsCourse from "@/pages/student/AiIeltsCourse";
|
||||
import ExamSession from "@/pages/student/ExamSession";
|
||||
import ExamStatus from "@/pages/student/ExamStatus";
|
||||
import ExamResults from "@/pages/student/ExamResults";
|
||||
import GapAnalysis from "@/pages/student/GapAnalysis";
|
||||
import CourseDelivery from "@/pages/student/CourseDelivery";
|
||||
import GradingQueue from "@/pages/admin/GradingQueue";
|
||||
import CourseConfig from "@/pages/admin/CourseConfig";
|
||||
import ModuleBuilder from "@/pages/admin/ModuleBuilder";
|
||||
import CourseProgress from "@/pages/teacher/CourseProgress";
|
||||
import PlacementBriefing from "@/pages/student/PlacementBriefing";
|
||||
import PlacementTest from "@/pages/student/PlacementTest";
|
||||
import PlacementResults from "@/pages/student/PlacementResults";
|
||||
import PlacementAccess from "@/pages/student/PlacementAccess";
|
||||
import FaqManager from "@/pages/admin/FaqManager";
|
||||
import NotificationRules from "@/pages/admin/NotificationRules";
|
||||
import ApprovalWorkflowConfig from "@/pages/admin/ApprovalWorkflowConfig";
|
||||
import RolesPermissions from "@/pages/admin/RolesPermissions";
|
||||
import AuthorityMatrix from "@/pages/admin/AuthorityMatrix";
|
||||
import UserRoles from "@/pages/admin/UserRoles";
|
||||
import BulkStudentUpload from "@/pages/admin/BulkStudentUpload";
|
||||
import CredentialDashboard from "@/pages/admin/CredentialDashboard";
|
||||
import AiEnglishQuality from "@/pages/admin/AiEnglishQuality";
|
||||
import AiEnglishTaxonomy from "@/pages/admin/AiEnglishTaxonomy";
|
||||
import AiIeltsValidation from "@/pages/admin/AiIeltsValidation";
|
||||
import AdaptiveDashboard from "@/pages/admin/AdaptiveDashboard";
|
||||
import AdaptiveStudentDetail from "@/pages/admin/AdaptiveStudentDetail";
|
||||
import LevelMappingConfig from "@/pages/admin/LevelMappingConfig";
|
||||
import WhiteLabelBranding from "@/pages/admin/WhiteLabelBranding";
|
||||
import ScoreApprovalQueue from "@/pages/admin/ScoreApprovalQueue";
|
||||
import ExamTemplateSelection from "@/pages/admin/ExamTemplateSelection";
|
||||
import IeltsExamCreate from "@/pages/admin/IeltsExamCreate";
|
||||
import IeltsSkillConfig from "@/pages/admin/IeltsSkillConfig";
|
||||
import IeltsContentPool from "@/pages/admin/IeltsContentPool";
|
||||
import IeltsExamValidation from "@/pages/admin/IeltsExamValidation";
|
||||
import CustomExamCreate from "@/pages/admin/CustomExamCreate";
|
||||
import OfficialExamAccess from "@/pages/OfficialExamAccess";
|
||||
import FaqPage from "@/pages/FaqPage";
|
||||
import NotFound from "@/pages/NotFound";
|
||||
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 (
|
||||
@@ -158,14 +180,30 @@ function StudentSubscriptionPlaceholder() {
|
||||
);
|
||||
}
|
||||
|
||||
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 />} />
|
||||
@@ -200,6 +238,7 @@ const App = () => (
|
||||
<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 />} />
|
||||
@@ -241,6 +280,7 @@ const App = () => (
|
||||
<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>
|
||||
@@ -263,6 +303,7 @@ const App = () => (
|
||||
<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 />} />
|
||||
@@ -285,13 +326,16 @@ const App = () => (
|
||||
<Route path="/admin/payment-record" element={<PaymentRecordPage />} />
|
||||
<Route path="/admin/tickets" element={<TicketsPage />} />
|
||||
<Route path="/admin/settings-platform" element={<SettingsPage />} />
|
||||
<Route path="/admin/exam" element={<ExamPage />} />
|
||||
<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 */}
|
||||
@@ -340,10 +384,12 @@ const App = () => (
|
||||
<Route path="/dashboard/admin" element={<Navigate to="/admin/platform" replace />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</AuthProvider>
|
||||
</BrowserRouter>
|
||||
</TooltipProvider>
|
||||
</QueryClientProvider>
|
||||
</ThemeProvider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user