| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import { useEffect, useCallback } from 'react';
- import { Routes, Route, Navigate, useNavigate } from 'react-router-dom';
- import { useAuth } from '@picobaas/client/react';
- import Layout from './components/Layout';
- import HomePage from './pages/HomePage';
- import LoginPage from './pages/LoginPage';
- import RegisterPage from './pages/RegisterPage';
- import ForgotPasswordPage from './pages/ForgotPasswordPage';
- import ResetPasswordPage from './pages/ResetPasswordPage';
- import VerifyEmailPage from './pages/VerifyEmailPage';
- import DashboardPage from './pages/DashboardPage';
- import ImageDetailPage from './pages/ImageDetailPage';
- import SharedImagePage from './pages/SharedImagePage';
- import ImageAnalyticsPage from './pages/ImageAnalyticsPage';
- // Hook to handle session expiry - auto logout when session expires
- function useSessionExpiry() {
- const { logout, isAuthenticated } = useAuth();
- const navigate = useNavigate();
- const handleSessionExpired = useCallback(async (event: Event) => {
- const customEvent = event as CustomEvent<{ reason: string }>;
- console.warn('Session expired:', customEvent.detail?.reason);
- // Only handle if user was authenticated
- if (isAuthenticated) {
- await logout();
- navigate('/login', {
- replace: true,
- state: { message: 'Your session has expired. Please log in again.' }
- });
- }
- }, [logout, navigate, isAuthenticated]);
- useEffect(() => {
- window.addEventListener('baas:session-expired', handleSessionExpired);
- return () => {
- window.removeEventListener('baas:session-expired', handleSessionExpired);
- };
- }, [handleSessionExpired]);
- }
- // Protected route wrapper
- function ProtectedRoute({ children }: { children: React.ReactNode }) {
- const { isAuthenticated, isLoading } = useAuth();
- if (isLoading) {
- return (
- <div className="min-h-screen flex items-center justify-center">
- <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600"></div>
- </div>
- );
- }
- if (!isAuthenticated) {
- return <Navigate to="/login" replace />;
- }
- return <>{children}</>;
- }
- function App() {
- // Auto-logout when session expires
- useSessionExpiry();
- return (
- <Routes>
- {/* Public routes */}
- <Route path="/" element={<Layout />}>
- <Route index element={<HomePage />} />
- <Route path="login" element={<LoginPage />} />
- <Route path="register" element={<RegisterPage />} />
- <Route path="forgot-password" element={<ForgotPasswordPage />} />
- <Route path="reset-password" element={<ResetPasswordPage />} />
- <Route path="verify-email" element={<VerifyEmailPage />} />
- {/* Protected routes */}
- <Route
- path="dashboard"
- element={
- <ProtectedRoute>
- <DashboardPage />
- </ProtectedRoute>
- }
- />
- <Route
- path="image/:imageId"
- element={
- <ProtectedRoute>
- <ImageDetailPage />
- </ProtectedRoute>
- }
- />
- <Route
- path="analytics/:shortCode"
- element={
- <ProtectedRoute>
- <ImageAnalyticsPage />
- </ProtectedRoute>
- }
- />
- </Route>
- {/* Shared image view (no layout) */}
- <Route path="s/:shareId" element={<SharedImagePage />} />
- {/* Catch all */}
- <Route path="*" element={<Navigate to="/" replace />} />
- </Routes>
- );
- }
- export default App;
|