# DriverVault — Web App Maintenance tracker for your cars: a **Vue 3 + Vite + Tailwind CSS v4** SPA served by a small **Go backend-for-frontend (BFF)**. The BFF serves the built SPA and reverse-proxies `/api/*` to the API Server, so the browser is always same-origin and all data access still flows through the API Server (never PocketBase directly). ``` Browser ─► Web App BFF (:8090) ──/api/*──► API Server (:8080) ─► PocketBase └── serves embedded Vue SPA ``` ## Layout ``` server/ Go BFF: embeds web/dist, proxies /api -> API_BASE main.go Run-WebApp.ps1 build frontend, then serve .env.example dist/ built SPA (generated; embedded at compile time) web/ Vue 3 + Vite + Tailwind v4 source src/ main.js app bootstrap router.js /login, / (dashboard), /charging, /cars/:id, /settings, /admin api.js the only place that calls the API Server (base URL resolution) auth.js token/profile state, isAdmin prefs.js theme/locale/date/font preferences -> i18n/ en / pl / da translation files + loader lib/format.js date/km formatting + next-service status badges lib/attachment.js upload / fetch / open a record's attached file style.css Tailwind v4 entry (+ dark custom-variant) App.vue layout shell + nav (Charging + Admin links when relevant) components/ Modal, AttachmentField, CarFormModal, ServiceFormModal, TechnicalCheckFormModal, MaintenanceFormModal, FuelFormModal, DocumentFormModal, ReminderFormModal, PartFormModal, ShareModal, Logo views/ Login, Dashboard, CarDetail, Charging, Settings, AdminUsers ``` ## Requirements - Node 18+ and Go 1.26+ - A running **API Server** (see `../API Server`) ## Develop Two terminals: ```powershell # terminal 1 — API Server (see ../API Server/README.md) cd "../API Server"; .\bin\api-server.exe # terminal 2 — Vite dev server with hot reload (proxies /api -> :8080) cd web; npm install; npm run dev # http://localhost:5173 ``` The dev server proxies `/api/*` to the API Server (default `http://localhost:8080`, override with `VITE_API_TARGET`), so the client uses same-origin relative URLs and avoids CORS. It also listens on all interfaces (`host: true`) so it's reachable on the LAN (e.g. `http://10.2.1.101:5173`). At runtime, users can override the API base URL from the login screen's **Server settings** (persisted in `localStorage` as `cc_server_url`); resolution order is that override → `VITE_API_BASE` → `/api`. ## Build & run (production-style) ```powershell ./server/Run-WebApp.ps1 # builds frontend, then serves on :8090 # or manually: cd web; npm run build # outputs to ../server/dist cd ../server; go run . # http://localhost:8090 ``` Config (`server/.env`, copy from `.env.example`): | Variable | Purpose | Default | |---|---|---| | `WEB_ADDR` | Listen address | `:8090` | | `API_BASE` | API Server base URL | `http://localhost:8080` | ## Features - **Dashboard** — one card per car: last service, odometer, next-due date/km, and a status badge (OK / due soon ≤30d / overdue) from the Excel formulas. Add a car; shared cars are labelled and gated by your access level. - **Car detail** — all car spec fields (engine / transmission / differential oil, brake fluid, coolant, VIN, fuel type, …) plus tabbed histories, each with an optional file attachment and add/edit/delete gated by your access level: - **Service history** — date, km, computed next date/km, and changed-parts flags. - **Technical checks** — roadworthiness inspections; result, cost, station and the certificate's valid-until, which drives the next-due date. - **Maintenance** — workshop visits and repairs (type/status, workshop, parts, labour + parts cost, invoice, warranty-until). - **Fuel** — refills with a summary panel (average / best / worst consumption, cost per km, price per litre), measured between full tanks. - **Documents** — insurance, registration, road tax, … with a renewal badge. - **Parts** — the per-car parts catalog. - **Reminders** — date/odometer, one-off or recurring; server-derived ones are read-only. Also **share** the car with other users (read/write, owner only); edit/delete controls are hidden for read-only shares. - **Charging** — the EV charging screen for connected Anker Solix chargers: live status and, in own/proxy control mode, start/stop and charge-limit controls driven by the API Server's OCPP Central System. - **Settings** — split into tabs: account (name / email verification / password), appearance (theme light/dark/system, locale, date format, currency, font size), profile (avatar, bio), **integrations** (Toyota, Anker Solix), data **export/import**, and the account-deletion state machine. - **Admin** — `/admin` user management (list / create / role / reset password / delete), gated by the admin role via a router guard + nav link. - **Theming** — light/dark/system app-wide (Tailwind v4 class strategy); `prefs.js` toggles `.dark` on `` and applies the saved theme/locale/date/font. ## Auth & access Login proxies to the API Server, which relays PocketBase's own token — there is no JWT the server mints and no server-side session list. The token is stored client-side and sent as `Authorization` on every call. `auth.js` exposes `isAdmin` and the current profile; the router guards `public` / `admin` routes. Cars are per-user (owned + shared), and the UI mirrors the server's read / write / owner access levels.