Files
budget2.0/src/ui/App.tsx
T
Lucas WintherandClaude Opus 5 c069ed3a94 feat(pwa): add service worker, manifest, and subpath-aware build
The precache list is generated from Bun.build's outputs, so hashed asset
names cannot drift. A waiting worker prompts to reload rather than
pinning the user to a stale build.

Two fixes beyond the brief: naming.entry changed from "[dir]/[name].[ext]"
to "[name].[ext]" because [dir] resolved to "src", putting index.html at
dist/src/index.html instead of the dist root; and external:
["*.webmanifest", "*.svg"] was added because Bun's HTML bundler otherwise
tries to resolve <link> hrefs as module imports, which fails outright for
the not-yet-generated manifest.webmanifest and would hash icon.svg,
breaking the fixed paths the manifest and service worker depend on.

happy-dom is registered per-file in src/ui/registerSw.test.ts only, not
as a global test preload, so src/domain/smoke.test.ts still guards the
domain layer's DOM-free invariant.

PNG icons (192px/512px) are not included — binary image generation isn't
available here; a human needs to add them for full Chrome installability.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 21:22:58 +02:00

55 lines
2.0 KiB
TypeScript

import { BrowserRouter, Navigate, Route, Routes, NavLink } from "react-router";
import { ROUTER_BASENAME } from "./basePath.ts";
import { currentMonth } from "../store/index.ts";
import { MonthRoute } from "./routes/MonthRoute.tsx";
import { YearRoute } from "./routes/YearRoute.tsx";
import { PostMonthRoute } from "./routes/PostMonthRoute.tsx";
import { PostYearRoute } from "./routes/PostYearRoute.tsx";
import { SummaryRoute } from "./routes/SummaryRoute.tsx";
import { SettingsRoute } from "./routes/SettingsRoute.tsx";
import { UpdatePrompt } from "./components/UpdatePrompt.tsx";
export function AppRoutes() {
const year = currentMonth.slice(0, 4);
return (
<div className="min-h-screen bg-background text-foreground">
<nav className="flex gap-4 border-b px-6 py-3 text-sm">
<NavLink to={`/month/${currentMonth}`} className="hover:underline">
Month
</NavLink>
<NavLink to={`/year/${year}`} className="hover:underline">
Year
</NavLink>
<NavLink to="/summary" className="hover:underline">
Summary
</NavLink>
<NavLink to="/settings" className="ml-auto hover:underline">
Settings
</NavLink>
</nav>
<main className="p-6">
<Routes>
<Route path="/month/:monthId" element={<MonthRoute />} />
<Route path="/year/:year" element={<YearRoute />} />
<Route path="/post/:postId/month/:monthId" element={<PostMonthRoute />} />
<Route path="/post/:postId/year/:year" element={<PostYearRoute />} />
<Route path="/summary" element={<SummaryRoute />} />
<Route path="/settings" element={<SettingsRoute />} />
<Route path="*" element={<Navigate to={`/month/${currentMonth}`} replace />} />
</Routes>
</main>
<UpdatePrompt />
</div>
);
}
export function App() {
return (
<BrowserRouter basename={ROUTER_BASENAME}>
<AppRoutes />
</BrowserRouter>
);
}
export default App;