feat: task 1.7 routing skeleton
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.
This commit is contained in:
+14
-33
@@ -1,38 +1,19 @@
|
||||
import { useAuthStore } from '@/auth';
|
||||
import { LoginPage } from '@/ui/pages/login';
|
||||
import { RouterProvider, createRouter } from '@tanstack/react-router';
|
||||
import { routeTree } from './routeTree.gen';
|
||||
import { queryClient } from '@/lib/query-client';
|
||||
|
||||
function App() {
|
||||
const status = useAuthStore((s) => s.status);
|
||||
const user = useAuthStore((s) => (s.status === 'authenticated' ? s.user : null));
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
context: { queryClient },
|
||||
defaultPreload: 'intent',
|
||||
});
|
||||
|
||||
// While the boot probe is in flight, render a minimal placeholder rather
|
||||
// than flashing the login page for users who already have a session.
|
||||
if (status === 'unknown' || status === 'authenticating') {
|
||||
return (
|
||||
<div className="min-h-screen grid place-items-center bg-muted text-sm text-muted-foreground">
|
||||
Signing you in…
|
||||
</div>
|
||||
);
|
||||
declare module '@tanstack/react-router' {
|
||||
interface Register {
|
||||
router: typeof router;
|
||||
}
|
||||
|
||||
if (status === 'anonymous') {
|
||||
return <LoginPage />;
|
||||
}
|
||||
|
||||
// Phase 1.7 replaces this branch with the TanStack Router shell.
|
||||
return (
|
||||
<div className="min-h-screen grid place-items-center bg-muted">
|
||||
<div className="space-y-4 text-center">
|
||||
<h1 className="text-3xl font-semibold">TRM</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Phase 1 scaffold. Routing + protected pages land in 1.7.
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Signed in as <code className="font-mono">{user?.email ?? user?.id}</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default function App() {
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user