152 lines
4.1 KiB
JavaScript
152 lines
4.1 KiB
JavaScript
import React from "react";
|
|
import { Navigate, createBrowserRouter, useParams } from "react-router-dom";
|
|
import App from "./App";
|
|
import { useAuth } from "./context/AuthContext";
|
|
|
|
/**
|
|
* Code-splitting: client-facing pages (opened from SMS links on mobile) load a
|
|
* small chunk instead of the full 932KB bundle that includes the staff
|
|
* dashboard, admin panels, etc. This fixes 30-40s loads on slow mobile
|
|
* connections (customers in Crimea opening delivery links).
|
|
*
|
|
* Staff pages are also lazy so the login page stays light.
|
|
*/
|
|
const ClientDeliveryPage = React.lazy(() =>
|
|
import("./pages/ClientDeliveryPage").then((m) => ({ default: m.ClientDeliveryPage }))
|
|
);
|
|
const ClientTestPage = React.lazy(() =>
|
|
import("./pages/ClientTestPage").then((m) => ({ default: m.ClientTestPage }))
|
|
);
|
|
const ClientTestConsentPage = React.lazy(() =>
|
|
import("./pages/ClientTestConsentPage").then((m) => ({ default: m.ClientTestConsentPage }))
|
|
);
|
|
const DashboardPage = React.lazy(() =>
|
|
import("./pages/DashboardPage").then((m) => ({ default: m.DashboardPage }))
|
|
);
|
|
const GroupDetailPage = React.lazy(() =>
|
|
import("./pages/GroupDetailPage").then((m) => ({ default: m.GroupDetailPage }))
|
|
);
|
|
const LoginPage = React.lazy(() =>
|
|
import("./pages/LoginPage").then((m) => ({ default: m.LoginPage }))
|
|
);
|
|
const NotFoundPage = React.lazy(() =>
|
|
import("./pages/NotFoundPage").then((m) => ({ default: m.NotFoundPage }))
|
|
);
|
|
const ForbiddenPage = React.lazy(() =>
|
|
import("./pages/ForbiddenPage").then((m) => ({ default: m.ForbiddenPage }))
|
|
);
|
|
const SettingsPage = React.lazy(() =>
|
|
import("./pages/SettingsPage").then((m) => ({ default: m.SettingsPage }))
|
|
);
|
|
|
|
const PageLoader = () => (
|
|
<div
|
|
style={{
|
|
minHeight: "100vh",
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
color: "var(--color-text-muted, #888)",
|
|
fontFamily: "system-ui, sans-serif",
|
|
}}
|
|
>
|
|
Загрузка…
|
|
</div>
|
|
);
|
|
|
|
const withSuspense = (node) => <React.Suspense fallback={<PageLoader />}>{node}</React.Suspense>;
|
|
|
|
/**
|
|
* Protects routes that require authentication.
|
|
* Redirects to /login with return URL if no user and session is loaded.
|
|
* Shows nothing while session is being restored (avoids flash-of-login).
|
|
*/
|
|
const RequireAuth = ({ children }) => {
|
|
const { user, isSessionLoading } = useAuth();
|
|
|
|
if (isSessionLoading) {
|
|
return null;
|
|
}
|
|
|
|
if (!user) {
|
|
const redirect = encodeURIComponent(window.location.pathname + window.location.search);
|
|
return <Navigate to={`/login?redirect=${redirect}`} replace />;
|
|
}
|
|
|
|
return children;
|
|
};
|
|
|
|
export const router = createBrowserRouter([
|
|
{
|
|
path: "/",
|
|
element: <App />,
|
|
children: [
|
|
{
|
|
index: true,
|
|
element: <Navigate to="/client" replace />,
|
|
},
|
|
{
|
|
path: "login",
|
|
element: withSuspense(<LoginPage />),
|
|
},
|
|
{
|
|
path: "client",
|
|
element: withSuspense(<ClientDeliveryPage />),
|
|
},
|
|
{
|
|
path: "client/:token",
|
|
element: withSuspense(<ClientDeliveryPage />),
|
|
},
|
|
{
|
|
path: "client/test",
|
|
element: withSuspense(<ClientTestPage />),
|
|
},
|
|
{
|
|
path: "client/test-consent",
|
|
element: withSuspense(<ClientTestConsentPage />),
|
|
},
|
|
{
|
|
path: "delivery/:token",
|
|
element: <LegacyDeliveryRedirect />,
|
|
},
|
|
{
|
|
path: "forbidden",
|
|
element: withSuspense(<ForbiddenPage />),
|
|
},
|
|
{
|
|
path: "dashboard",
|
|
element: withSuspense(
|
|
<RequireAuth>
|
|
<DashboardPage />
|
|
</RequireAuth>
|
|
),
|
|
},
|
|
{
|
|
path: "dashboard/group/:groupId",
|
|
element: withSuspense(
|
|
<RequireAuth>
|
|
<GroupDetailPage />
|
|
</RequireAuth>
|
|
),
|
|
},
|
|
{
|
|
path: "settings",
|
|
element: withSuspense(
|
|
<RequireAuth>
|
|
<SettingsPage />
|
|
</RequireAuth>
|
|
),
|
|
},
|
|
{
|
|
path: "*",
|
|
element: withSuspense(<NotFoundPage />),
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
function LegacyDeliveryRedirect() {
|
|
const { token } = useParams();
|
|
return <Navigate to={`/client/${encodeURIComponent(token || "")}`} replace />;
|
|
}
|