import React, { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider } from './context/AuthContext';
import { useAuth } from './context/useAuth';
import { ErrorBoundary } from './components/ErrorBoundary';
import { LoginPage } from './pages/LoginPage';
/*
* Every page except the login screen is loaded on demand.
*
* Imported eagerly, the whole app landed in one ~790kB bundle, and every
* visitor downloaded all of it before they could reach the login form.
* Splitting per route means each page's code arrives when it is first opened.
* (The charting library that dominated that bundle went away with the
* analytics pages, but the split is still worth keeping.)
*
* LoginPage stays eager: it is the first thing an unauthenticated visitor
* sees, so deferring it would only add a round trip before the form appears.
*/
const HomePage = lazy(() => import('./pages/HomePage').then((m) => ({ default: m.HomePage })));
const AdminPage = lazy(() => import('./pages/AdminPage').then((m) => ({ default: m.AdminPage })));
function PageFallback({ label }) {
return (
{label}
);
}
function ProtectedRoute({ children, allowedRoles }) {
const { user, role, restoring } = useAuth();
// A token restored from sessionStorage is still being checked against
// /api/auth/me. Redirecting to /login now would bounce a valid session out
// on every refresh; rendering now would flash a dashboard about to be torn
// down if the token turns out to be expired.
if (restoring) {
return ;
}
if (!user) {
return ;
}
const effectiveRole = role || (user.role === 'store' ? 'user' : user.role);
if (allowedRoles && !allowedRoles.includes(effectiveRole)) {
// Every remaining route is admin-only, so there is nowhere else in the app
// to send a non-admin. This can still be reached by a token minted before
// the `user` account was disabled - those stay valid for their 12h TTL -
// so it has to terminate somewhere public rather than redirect in a loop.
return ;
}
return children;
}
export default function App() {
return (
{/* Covers the network fetch for a lazily-loaded page chunk. */}
}>
{/* Public Login Route */}
} />
{/* Catalog Route - RESTRICTED TO ADMIN ONLY */}
}
/>
{/* Admin Panel Route - RESTRICTED TO ADMIN ONLY */}
}
/>
{/* Catch-all redirect */}
} />
);
}