Frontend UI¶
The frontend lives under frontend/ and is built with React 18, TypeScript, Vite, Tailwind-esque utility classes, and Radix-inspired primitives. Production builds are emitted by Vite and served via nginx:alpine in Docker.
Project Structure¶
src/App.tsx– single-page experience orchestrating backup selection, unlock flow, manifest browser, and artifact tabs.src/lib/api.ts– thin wrapper aroundfetchthat injects API/session tokens and exposes typed helper methods.src/lib/types.ts– shared types mirroring backend schemas, plus view models for artifact renderers.src/components/*(future) – when the UI grows, extract panels into components here.
State Machine¶
- Session Setup – user enters the API token (default
dev-token), stored in component state and reused for every request. - Backup Selection –
useEffectcallsapi.listBackups()(GET/backups). The manifest tree stays disabled until a backup is unlocked. - Unlocking –
api.unlockBackup()posts the passphrase; on success it returnssession_token+ TTL which the frontend saves to issueX-Backup-Sessionheaders. - Manifest Browsing – the manifest view paginates through
/backups/{id}/files, allows domain/path filters, and lazy-loads more rows. - Artifact Tabs – additional tabs (Photos, Messages, WhatsApp, etc.) fire artifact-specific API calls once their data exists in Postgres.
All requests respect the API base URL provided through import.meta.env.VITE_API_BASE_URL (set to http://backend:8080 inside Docker). During local development Vite proxies to http://localhost:8080.
Styling and Layout¶
- The root layout uses a fixed-width sidebar for backups and a flexible content area for manifest/artifacts.
- Animations and transitions are handled via CSS modules + utility classes included in
src/App.tsx. - Nginx injects cache headers so the SPA can be safely served behind reverse proxies.
Browser Compatibility¶
The UI targets modern Chromium, Firefox, and Safari releases. It relies on Fetch API, async/await, and CSS grid/flexbox, so no legacy polyfills are included by default.
Extensibility Tips¶
- Represent new artifact types in
src/lib/types.ts, then add view tabs inApp.tsx. - If the API surface expands, keep
src/lib/api.tsas the central spot for fetch wrappers so headers stay consistent. - For large feature work, consider migrating to React Router and splitting the manifest + artifact states into context providers.