Files
UHD_Media_Tool/apps/web/app/router.tsx
T

135 lines
4.5 KiB
TypeScript

import { createRootRoute, createRoute, createRouter, lazyRouteComponent, redirect } from "@tanstack/react-router";
import type { ComponentType } from "react";
import { EmptyState } from "./components/console/empty-state.tsx";
import { Button } from "./components/ui/button.tsx";
import { parseUrlSearch, stringifyUrlSearch } from "./lib/router-compat.tsx";
import App from "./root.tsx";
type PageModule = { default: ComponentType; clientLoader?: (args: { request: Request }) => Promise<unknown> | unknown };
const modules = import.meta.glob<PageModule>("./routes/**/*.tsx");
async function loadPage(modulePath: string, href: string) {
const module = await modules[`./routes/${modulePath}.tsx`]?.();
if (!module) throw new Error(`路由模块不存在: ${modulePath}`);
const result = await module.clientLoader?.({ request: new Request(new URL(href, window.location.origin)) });
if (result instanceof Response && result.status >= 300 && result.status < 400) {
const target = new URL(result.headers.get("Location") ?? "/console", window.location.origin);
throw redirect({
to: target.pathname,
search: parseUrlSearch(target.search),
hash: target.hash.slice(1),
replace: true,
} as never);
}
}
const rootRoute = createRootRoute({
component: App,
notFoundComponent: lazyRouteComponent(() => modules["./routes/not-found.tsx"]!()),
errorComponent: () => (
<main className="grid min-h-screen place-items-center bg-background px-4">
<EmptyState
title="页面加载失败"
description="刷新页面后重试。"
action={<Button onClick={() => window.location.reload()}>刷新页面</Button>}
/>
</main>
),
});
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/",
beforeLoad: () => {
throw redirect({ to: "/console" } as never);
},
});
const loginRoute = createRoute({
getParentRoute: () => rootRoute,
path: "login",
component: lazyRouteComponent(() => modules["./routes/login.tsx"]!()),
});
const consoleRoute = createRoute({
getParentRoute: () => rootRoute,
path: "console",
component: lazyRouteComponent(() => modules["./routes/console/layout.tsx"]!()),
});
function page(path: string, modulePath: string) {
return createRoute({
getParentRoute: () => consoleRoute,
path,
component: lazyRouteComponent(() => modules[`./routes/console/${modulePath}.tsx`]!()),
beforeLoad: ({ location }) => loadPage(`console/${modulePath}`, location.href),
});
}
const agentRoute = createRoute({
getParentRoute: () => consoleRoute,
path: "agent",
component: lazyRouteComponent(() => modules["./routes/console/agent.tsx"]!()),
});
const agentIndexRoute = createRoute({
getParentRoute: () => agentRoute,
path: "/",
component: lazyRouteComponent(() => modules["./routes/console/agent._index.tsx"]!()),
});
const agentRunRoute = createRoute({
getParentRoute: () => agentRoute,
path: "$runId",
component: lazyRouteComponent(() => modules["./routes/console/agent.$runId.tsx"]!()),
});
const routeTree = rootRoute.addChildren([
indexRoute,
loginRoute,
consoleRoute.addChildren([
page("/", "home"),
page("inbox", "inbox"),
page("library", "library"),
page("library/$id", "library.$id"),
page("media/tmdb/$type/$id", "media.tmdb.$type.$id"),
page("identity", "identity"),
page("organize", "organize"),
page("organize/$id", "organize.$id"),
page("files", "files"),
page("files/trash", "files.trash"),
page("discover", "discover"),
page("subscriptions", "subscriptions"),
page("subscriptions/$id", "subscriptions.$id"),
page("preferences", "preferences"),
page("sites", "sites"),
page("sites/$siteId", "sites.$siteId"),
page("sources", "sources"),
page("rules", "rules"),
page("downloads", "downloads"),
page("downloads/plans", "downloads.plans"),
page("downloads/plans/$id", "downloads.plans"),
page("downloads/$id", "downloads.$id"),
page("tasks", "tasks"),
page("tasks/$id", "tasks.$id"),
agentRoute.addChildren([agentIndexRoute, agentRunRoute]),
page("engine", "engine"),
page("engine/$runId", "engine.$runId"),
page("audit", "audit"),
page("logs", "logs"),
page("settings", "settings"),
page("schedules", "schedules"),
page("search", "search"),
page("status", "status"),
]),
]);
export const router = createRouter({
routeTree,
parseSearch: parseUrlSearch,
stringifySearch: stringifyUrlSearch,
scrollRestoration: true,
defaultPreload: false,
});
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}