mirror of
https://github.com/R0m1k3/Reviflow.git
synced 2026-10-15 19:28:40 +02:00
168 lines
5.1 KiB
TypeScript
168 lines
5.1 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
|
import { useAuth } from './stores/useAuth';
|
|
import { LoginPage } from './features/auth/LoginPage';
|
|
import { RegisterPage } from './features/auth/RegisterPage';
|
|
import { SettingsPage } from './features/settings/SettingsPage';
|
|
import { NewRevisionPage } from './features/ingest/NewRevisionPage';
|
|
import { AnalyzePage } from './features/ingest/AnalyzePage';
|
|
import { ReviewPage } from './features/ingest/ReviewPage';
|
|
import { QuizPage } from './features/quiz/QuizPage';
|
|
import { RevisionViewPage } from './features/quiz/RevisionViewPage';
|
|
import DashboardPage from './pages/DashboardPage';
|
|
import { ParentalGate } from './features/auth/ParentalGate';
|
|
import { ProfileSelectionPage } from './features/auth/ProfileSelectionPage';
|
|
import { ParentHubPage } from './pages/ParentHubPage';
|
|
import { HistoryPage } from './features/quiz/HistoryPage';
|
|
import { useThemeEffect } from './stores/useTheme';
|
|
|
|
|
|
function ProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
const { isAuthenticated, isLoading, checkAuth } = useAuth();
|
|
|
|
useEffect(() => {
|
|
checkAuth();
|
|
}, []);
|
|
|
|
if (isLoading) return (
|
|
<div className="flex justify-center items-center h-screen bg-[#FDFCF8]">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600"></div>
|
|
</div>
|
|
);
|
|
|
|
if (!isAuthenticated) return <Navigate to="/login" />;
|
|
return <>{children}</>;
|
|
}
|
|
|
|
function MainRedirect() {
|
|
const { user, activeLearner } = useAuth();
|
|
|
|
// 1. If parent and no learner selected -> Parent Hub
|
|
if (user?.role === 'parent' && !activeLearner) {
|
|
return <Navigate to="/parent-hub" replace />;
|
|
}
|
|
|
|
// 2. If learner (auto-active) or parent with selection -> Dashboard
|
|
return <Navigate to="/dashboard" replace />;
|
|
}
|
|
|
|
function LearnerProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
const { isAuthenticated, activeLearner, isLoading } = useAuth();
|
|
|
|
if (isLoading) return null; // Or spinner
|
|
if (!isAuthenticated) return <Navigate to="/login" />;
|
|
if (!activeLearner) return <Navigate to="/select-profile" />;
|
|
|
|
return <>{children}</>;
|
|
}
|
|
|
|
function ParentalProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
const { isParentalModeActive } = useAuth();
|
|
const [showGate, setShowGate] = React.useState(!isParentalModeActive);
|
|
|
|
if (isParentalModeActive) return <>{children}</>;
|
|
|
|
if (showGate) {
|
|
return (
|
|
<ParentalGate
|
|
onSuccess={() => setShowGate(false)}
|
|
onCancel={() => window.history.back()}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return <>{children}</>;
|
|
}
|
|
|
|
function App() {
|
|
useThemeEffect();
|
|
|
|
return (
|
|
<BrowserRouter>
|
|
<Routes>
|
|
<Route path="/login" element={<LoginPage />} />
|
|
<Route path="/register" element={<RegisterPage />} />
|
|
<Route path="/select-profile" element={
|
|
<ProtectedRoute>
|
|
<ProfileSelectionPage />
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/dashboard" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<DashboardPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/settings" element={
|
|
<ProtectedRoute>
|
|
<ParentalProtectedRoute>
|
|
<SettingsPage />
|
|
</ParentalProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/new" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<NewRevisionPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/analyze" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<AnalyzePage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/review" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<ReviewPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/quiz" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<QuizPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/revision/:id" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<RevisionViewPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/play/:revisionId" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<QuizPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/parent-hub" element={
|
|
<ProtectedRoute>
|
|
<ParentalProtectedRoute>
|
|
<ParentHubPage />
|
|
</ParentalProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/history" element={
|
|
<ProtectedRoute>
|
|
<LearnerProtectedRoute>
|
|
<HistoryPage />
|
|
</LearnerProtectedRoute>
|
|
</ProtectedRoute>
|
|
} />
|
|
<Route path="/" element={<MainRedirect />} />
|
|
|
|
</Routes>
|
|
</BrowserRouter>
|
|
);
|
|
}
|
|
|
|
export default App;
|