dc4e73f73a
TanStack Router file-based routes: - vite.config.ts: TanStackRouterVite plugin (target: react, autoCodeSplitting: true) before the React plugin. - .gitignore: src/routeTree.gen.ts (auto-generated). - src/lib/query-client.ts: module-level QueryClient singleton. - src/routes/__root.tsx: root route, QueryClientProvider, Suspense- wrapped router + query devtools (dev-only via import.meta.env.DEV). - src/routes/login.tsx: public route. validateSearch schema accepts optional redirect. LoginRoute wraps <LoginPage> with onAuthenticated navigating to redirect ?? '/'. - src/routes/_authed/route.tsx: pathless protected layout. beforeLoad redirects to /login on 'anonymous'; falls through on 'unknown' / 'authenticating' so hard reload doesn't flash the login page. - src/routes/_authed/index.tsx: placeholder home with sign-out button. Cross-tab logout effect bounces to /login on store transition. - src/App.tsx: replaced — now creates the router and renders <RouterProvider />. The interim status-branching logic from 1.6 is gone (the route tree handles it). - eslint.config.js: override for src/routes/** disabling react-refresh/only-export-components — TanStack Router's file-based pattern intentionally co-exports Route alongside components. Code-splitting working: login chunk 37KB, home + auth 17KB, card primitive 31KB, all loaded lazily; main bundle 353KB. Deviations: 1. No top-level useRequireAuth hook — per-page useEffect on store transitions is just as effective and only used in one place. 2. ESLint override for src/routes/** matches the existing pattern for src/ui/primitives/**. 3. Login page's auto-navigate effect from 1.6 is removed — the route wrapper owns navigation via onAuthenticated.
27 lines
652 B
TypeScript
27 lines
652 B
TypeScript
import { createFileRoute, useNavigate } from '@tanstack/react-router';
|
|
import { z } from 'zod';
|
|
import { LoginPage } from '@/ui/pages/login';
|
|
|
|
const LoginSearchSchema = z.object({
|
|
/** Where to bounce the user once login succeeds. Defaults to `/`. */
|
|
redirect: z.string().optional(),
|
|
});
|
|
|
|
export const Route = createFileRoute('/login')({
|
|
component: LoginRoute,
|
|
validateSearch: LoginSearchSchema,
|
|
});
|
|
|
|
function LoginRoute() {
|
|
const { redirect } = Route.useSearch();
|
|
const navigate = useNavigate();
|
|
|
|
return (
|
|
<LoginPage
|
|
onAuthenticated={() => {
|
|
void navigate({ to: redirect ?? '/', replace: true });
|
|
}}
|
|
/>
|
|
);
|
|
}
|