2026-06-05 18:56:01 +00:00
|
|
|
# FleetNow
|
|
|
|
|
|
|
|
|
|
A single-file map console that **merges live vehicle positions and historical
|
|
|
|
|
trips** into one view for the Fireside Communications / Tracksolid fleet.
|
|
|
|
|
|
2026-06-06 07:18:25 +00:00
|
|
|
- Land on the **live fleet** — markers carry the **department (cost-centre) colour**,
|
|
|
|
|
a heading arrow, the plate tail, and a hover popup (status, driver, reverse-geocoded
|
|
|
|
|
address, heading, odometer, last fix, source). Markers **scale with the zoom level**.
|
|
|
|
|
Shape encodes recency so stakeholders read activity at a glance:
|
|
|
|
|
- **● circle** — moving right now
|
|
|
|
|
- **■ square** — active within the last 24h, now stopped (with last-heading arrow)
|
|
|
|
|
- **grey ●** — offline (no fix in 24h)
|
2026-06-06 07:09:52 +00:00
|
|
|
- **Filters** (bottom-right card) apply to the live map *instantly*:
|
|
|
|
|
- **Number plate** — multi-select, sorted A→Z; picking a vehicle auto-fills its
|
|
|
|
|
cost centre + city.
|
|
|
|
|
- **Cost centre** and **Assigned city** — narrow the live fleet (and the KPI bar
|
|
|
|
|
recomputes to match).
|
|
|
|
|
- **Time** (Today / 1 week / 1 month / Custom) — applies to **trips**, not live.
|
|
|
|
|
- Drill into history: click a vehicle's dot → **Show trips**, or set
|
|
|
|
|
plate / cost centre / city + period and hit **Show trips** for a fleet-wide pull.
|
|
|
|
|
The map switches to **seq-coloured trip routes** with start/end markers and a
|
|
|
|
|
click-to-animate replay; the **● Live** pill returns to the live snapshot.
|
2026-06-05 18:56:01 +00:00
|
|
|
|
|
|
|
|
Live: <https://fleetnow.rahamafresh.com>
|
|
|
|
|
|
|
|
|
|
## Architecture
|
|
|
|
|
|
|
|
|
|
The whole app is **one self-contained `index.html`** (inline CSS + JS; MapLibre
|
|
|
|
|
GL JS loaded from a CDN). It has no build step and no local assets. It reads from
|
|
|
|
|
the existing dashboard read-API — it does **not** talk to the database directly.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
index.html → the entire SPA
|
|
|
|
|
Dockerfile → bakes index.html into an nginx:alpine image (port 80)
|
|
|
|
|
nginx.conf → static serve + /healthz + no-cache on index.html
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Backend it depends on
|
|
|
|
|
|
|
|
|
|
`const API_BASE = 'https://fleetapi.rahamafresh.com';` (top of the `<script>` in
|
|
|
|
|
`index.html`). That service (`dashboard_api_rev.py` in the `tracksolid` repo)
|
|
|
|
|
exposes:
|
|
|
|
|
|
|
|
|
|
| Endpoint | Use |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `GET /webhook/live-positions` | live snapshot `{summary, geojson}` |
|
|
|
|
|
| `GET /webhook/live-positions/track?vehicle_number=&hours=` | 1 h trail |
|
|
|
|
|
| `GET /webhook/fleet-dashboard` | filter options (plates, cost centres) |
|
|
|
|
|
| `POST /webhook/fleet-dashboard` | trips for a selection `{summary, geojson}` |
|
|
|
|
|
|
|
|
|
|
**CORS:** the API must allow the `https://fleetnow.rahamafresh.com` origin
|
|
|
|
|
(`DASHBOARD_CORS_ORIGINS`). It is in the code default; make sure the deployed
|
|
|
|
|
`dashboard_api` container's env includes it, then restart that container.
|
|
|
|
|
|
|
|
|
|
## Deploy (Coolify, git-based)
|
|
|
|
|
|
|
|
|
|
1. In Coolify, create a new **Application** from this git repo
|
|
|
|
|
(`https://repo.rahamafresh.com/kianiadee/fleetnow.git`), branch `main`,
|
|
|
|
|
build pack **Dockerfile**.
|
|
|
|
|
2. Set the **port** to `80`.
|
|
|
|
|
3. Add the domain **`fleetnow.rahamafresh.com`** (HTTPS / Let's Encrypt). Coolify
|
|
|
|
|
wires Traefik on the `coolify` network automatically.
|
|
|
|
|
4. Point DNS `fleetnow.rahamafresh.com` → the VPS (`31.97.44.246`) if not already.
|
|
|
|
|
5. Deploy. Every push to `main` redeploys; `index.html` is served `no-cache` so
|
|
|
|
|
changes appear immediately.
|
|
|
|
|
|
|
|
|
|
## Local preview
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
docker build -t fleetnow . && docker run --rm -p 8080:80 fleetnow
|
|
|
|
|
# open http://localhost:8080
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> Loading from `localhost` will be CORS-blocked by the live API unless that
|
|
|
|
|
> origin is allow-listed. For pure UI work, run a same-origin proxy that forwards
|
|
|
|
|
> `/webhook/*` to `fleetapi.rahamafresh.com`.
|