42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
import { Outlet, useRouterState } from "@tanstack/react-router";
|
|
import { ThemeProvider } from "next-themes";
|
|
import { useEffect, useState } from "react";
|
|
import { pageTitle } from "~/components/console/nav.ts";
|
|
import { GlassTooltip } from "~/components/glass-tooltip.tsx";
|
|
import { Toaster } from "~/components/ui/sonner.tsx";
|
|
import "@fontsource-variable/inter-tight";
|
|
import "@fontsource-variable/space-grotesk";
|
|
import "./app.css";
|
|
|
|
export default function App() {
|
|
const pathname = useRouterState({ select: (state) => state.location.pathname });
|
|
const [queryClient] = useState(
|
|
() =>
|
|
new QueryClient({
|
|
defaultOptions: { queries: { staleTime: 30_000, refetchOnWindowFocus: false } },
|
|
}),
|
|
);
|
|
useEffect(() => {
|
|
const title = pathname === "/login" ? "登录" : pageTitle(pathname);
|
|
document.title = title ? `${title} · UHD 媒体自动化控制台` : "UHD 媒体自动化控制台";
|
|
}, [pathname]);
|
|
// SPA 首屏主题由 index.html 初始化;next-themes 的服务端引导脚本在客户端保持惰性。
|
|
return (
|
|
<ThemeProvider
|
|
attribute="class"
|
|
defaultTheme="dark"
|
|
themes={["light", "dark"]}
|
|
enableSystem={false}
|
|
storageKey="umt-theme"
|
|
scriptProps={{ type: "text/plain" }}
|
|
>
|
|
<QueryClientProvider client={queryClient}>
|
|
<Outlet />
|
|
<Toaster position="top-center" duration={1500} expand gap={8} />
|
|
<GlassTooltip />
|
|
</QueryClientProvider>
|
|
</ThemeProvider>
|
|
);
|
|
}
|