Files
WhiteNightsAdminPanel/src/app/router/index.tsx
2026-04-24 13:17:27 +03:00

413 lines
9.3 KiB
TypeScript

import {
CreateSightPage,
DevicesPage,
EditSightPage,
LoginPage,
MainPage,
SightListPage,
MapPage,
MediaListPage,
MediaPreviewPage,
MediaEditPage,
CountryListPage,
CityListPage,
RouteListPage,
UserListPage,
SnapshotListPage,
CarrierListPage,
StationListPage,
ArticleListPage,
SnapshotCreatePage,
CountryCreatePage,
CityCreatePage,
CarrierCreatePage,
VehicleCreatePage,
VehicleEditPage,
CountryEditPage,
CityEditPage,
UserCreatePage,
UserEditPage,
CarrierEditPage,
StationCreatePage,
StationPreviewPage,
StationEditPage,
RouteCreatePage,
RoutePreview,
DemoPage,
RouteEditPage,
ArticlePreviewPage,
CountryAddPage,
} from "@pages";
import {
authStore,
createSightStore,
editSightStore,
languageStore,
ROUTE_REQUIRED_RESOURCES,
} from "@shared";
import { Layout } from "@widgets";
import { runInAction } from "mobx";
import React, { useEffect } from "react";
import {
createBrowserRouter,
RouterProvider,
Navigate,
Outlet,
useLocation,
useMatches,
} from "react-router-dom";
const PublicRoute = ({ children }: { children: React.ReactNode }) => {
const { isAuthenticated } = authStore;
const need_auth = import.meta.env.VITE_NEED_AUTH == "true";
if (isAuthenticated || !need_auth) {
return <Navigate to="/map" replace />;
}
return <>{children}</>;
};
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const { isAuthenticated } = authStore;
const need_auth = import.meta.env.VITE_NEED_AUTH == "true";
const location = useLocation();
const matches = useMatches();
if (!isAuthenticated && need_auth) {
return <Navigate to="/login" replace />;
}
if (location.pathname === "/" && authStore.canRead("map")) {
return <Navigate to="/map" replace />;
}
const lastMatch = matches[matches.length - 1] as
| { handle?: { permissions?: string[] } }
| undefined;
const requiredPermissions = lastMatch?.handle?.permissions ?? [];
if (
requiredPermissions.length > 0 &&
!requiredPermissions.every((permission) => authStore.canAccess(permission))
) {
return <Navigate to="/" replace />;
}
return <>{children}</>;
};
const ClearStoresWrapper: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const location = useLocation();
useEffect(() => {
editSightStore.clearSightInfo();
createSightStore.clearCreateSight();
runInAction(() => {
editSightStore.hasLoadedCommon = false;
});
if (
location.pathname.includes("create") ||
location.pathname.includes("edit") ||
location.pathname.includes("add")
) {
languageStore.setLanguage("ru");
}
}, [location]);
return <>{children}</>;
};
const router = createBrowserRouter([
{
path: "/login",
element: (
<PublicRoute>
<LoginPage />
</PublicRoute>
),
},
{
path: "route-preview/:id",
element: <RoutePreview />,
},
{
path: "demo/:id",
element: <DemoPage />,
},
{
path: "/",
element: (
<ProtectedRoute>
<Layout>
<ClearStoresWrapper>
<Outlet />
</ClearStoresWrapper>
</Layout>
</ProtectedRoute>
),
children: [
{
index: true,
element: <MainPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/"],
},
},
{
path: "sight",
element: <SightListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/sight"],
},
},
{
path: "sight/create",
element: <CreateSightPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/sight/create"],
},
},
{
path: "sight/:id/edit",
element: <EditSightPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/sight/:id/edit"],
},
},
{
path: "devices",
element: <DevicesPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/devices"],
},
},
{
path: "map",
element: <MapPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/map"],
},
},
{
path: "media",
element: <MediaListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/media"],
},
},
{
path: "media/:id",
element: <MediaPreviewPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/media/:id"],
},
},
{
path: "media/:id/edit",
element: <MediaEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/media/:id/edit"],
},
},
{
path: "country",
element: <CountryListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/country"],
},
},
{
path: "country/create",
element: <CountryCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/country/create"],
},
},
{
path: "country/add",
element: <CountryAddPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/country/add"],
},
},
{
path: "country/:id/edit",
element: <CountryEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/country/:id/edit"],
},
},
{
path: "city",
element: <CityListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/city"],
},
},
{
path: "city/create",
element: <CityCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/city/create"],
},
},
{
path: "city/:id/edit",
element: <CityEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/city/:id/edit"],
},
},
{
path: "route",
element: <RouteListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/route"],
},
},
{
path: "route/create",
element: <RouteCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/route/create"],
},
},
{
path: "route/:id/edit",
element: <RouteEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/route/:id/edit"],
},
},
{
path: "user",
element: <UserListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/user"],
},
},
{
path: "user/create",
element: <UserCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/user/create"],
},
},
{
path: "user/:id/edit",
element: <UserEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/user/:id/edit"],
},
},
{
path: "snapshot",
element: <SnapshotListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/snapshot"],
},
},
{
path: "snapshot/create",
element: <SnapshotCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/snapshot/create"],
},
},
{
path: "carrier",
element: <CarrierListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/carrier"],
},
},
{
path: "carrier/create",
element: <CarrierCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/carrier/create"],
},
},
{
path: "carrier/:id/edit",
element: <CarrierEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/carrier/:id/edit"],
},
},
{
path: "station",
element: <StationListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/station"],
},
},
{
path: "station/create",
element: <StationCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/station/create"],
},
},
{
path: "station/:id",
element: <StationPreviewPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/station/:id"],
},
},
{
path: "station/:id/edit",
element: <StationEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/station/:id/edit"],
},
},
{
path: "vehicle/create",
element: <VehicleCreatePage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/vehicle/create"],
},
},
{
path: "vehicle/:id/edit",
element: <VehicleEditPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/vehicle/:id/edit"],
},
},
{
path: "article",
element: <ArticleListPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/article"],
},
},
{
path: "article/:id",
element: <ArticlePreviewPage />,
handle: {
permissions: ROUTE_REQUIRED_RESOURCES["/article/:id"],
},
},
],
},
]);
export const Router = () => {
return <RouterProvider router={router} />;
};