monitor-im-flur
Project Structure (abridged)
src/
api/ # External data fetchers
components/ # UI building blocks (Cards, Timetable, Weather, Terminal, etc.)
store/ # Zustand stores encapsulating fetch + state
types/ # Type definitions for external data
pipeline/
create-git-hash-html.sh # Injects current commit hash into dist
Dockerfile # Nginx static hosting
docker-compose.yml # Example runtime service definition
Environment Configuration
Create a .env (or .env.local) for Vite with the following (only what you need):
VITE_FLATTASTIC_API_KEY=your_flatastic_api_key
# (Planned) VITE_HOME_ASSISTANT_TOKEN=your_long_lived_token # NOTE: currently hardcoded – see Security section
Vite automatically exposes variables prefixed with VITE_ to the client bundle. Do NOT place secrets without that prefix – but remember: anything in the client bundle is public. For sensitive data consider a tiny proxy backend instead of calling APIs directly from the browser.
Security Notice
src/api/homeAssistant.ts currently contains a hard‑coded long‑lived Home Assistant token. This should be refactored before any public deployment:
- Remove the literal token from the repository.
- Load it via environment variable during build (
import.meta.env.VITE_HOME_ASSISTANT_TOKEN) OR - Prefer a minimal server proxy so the token never ships to the browser.
Development
Install dependencies (Bun is inferred from bun.lock, but npm/pnpm/yarn also work).
bun install
Run the dev server (HTTPS support possible with vite-plugin-mkcert if certificates are trusted):
bun run dev
Open: http://localhost:5173
Lint & Format
bun run lint
Optionally run Biome (if desired):
npx biome check --apply .
Build
bun run build
Outputs production bundle to dist/.
Docker Image
Build locally:
docker build -t monitor-im-flur:local .
Run:
docker run --rm -p 9123:80 monitor-im-flur:local
Or use compose (uses published image):
docker compose up -d
Visit: http://localhost:9123
Data Sources
- KVV Departures: Public endpoint (JSON) for stop IDs 7000044 / 7000045.
- Weather: Open‑Meteo forecast API (lat 49.0094, lon 8.4044, Europe/Berlin TZ).
- Flatastic: Auth via
x-api-key(user provided). - Home Assistant: Long‑lived bearer token (refactor recommended).
Adding a New Card
- Create a directory under
src/components/<NewCard>/withNewCard.tsx& optionalstyle.module.css. - Wrap content with existing
Cardcomponent (icon+nameprops). - Register inside
Dashboard.tsxwhere layout lives (usingCardColumn/CardRow).
State Management Notes
All data fetching is encapsulated inside zustand store fetch methods invoked on an interval within the respective components. Consider centralizing polling or using React Query if complexity grows.