commit 3d420fa82e667b199a5c99ea3a08a33dff82314b Author: kianiadee Date: Fri Jun 5 21:56:01 2026 +0300 feat: FleetNow merged live+trips map SPA (nginx/Coolify) Single-file MapLibre SPA merging live vehicle positions and historical trips into one console. Reads the existing dashboard read-API (fleetapi.rahamafresh.com); served as a static nginx image for Coolify. Co-Authored-By: Claude Opus 4.8 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0f2f39d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.git +.gitignore +README.md +*.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18b2cef --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +*.log +node_modules/ +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c29cdf5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +# FleetNow — static single-file SPA served by nginx. +# Coolify auto-detects this Dockerfile; set the app's port to 80 and attach +# the domain (fleetnow.rahamafresh.com) in the Coolify UI — Traefik + LE are +# wired automatically from there. +FROM nginx:1.27-alpine + +# Drop the stock default site, add ours. +RUN rm -f /etc/nginx/conf.d/default.conf +COPY nginx.conf /etc/nginx/conf.d/fleetnow.conf + +# The whole app is one self-contained file (inline CSS/JS; MapLibre from a CDN). +COPY index.html /usr/share/nginx/html/index.html + +EXPOSE 80 + +# Coolify reads this; also handy for `docker ps` health. +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget -qO- http://localhost/healthz >/dev/null 2>&1 || exit 1 diff --git a/README.md b/README.md new file mode 100644 index 0000000..b9875fb --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# FleetNow + +A single-file map console that **merges live vehicle positions and historical +trips** into one view for the Fireside Communications / Tracksolid fleet. + +- Land on the **live fleet** (cost-centre-coloured pins, heading arrows, hover + popups with reverse-geocoded address). +- Pick a vehicle (click its dot → **Show trips**, or the plate dropdown) or apply + **cost centre + time period** → 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. + +Live: + +## 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 ` + + + +
+
+
FLEETNOW
+
+
+ +
Last batch
+
EAT
+
+ +
+
Loading live fleet…
+ + +
+ +

Trips

+
+
No trips.
+
+
+ + +
+

Filters

+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+
+ + + + diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..e22fc5d --- /dev/null +++ b/nginx.conf @@ -0,0 +1,32 @@ +server { + listen 80; + listen [::]:80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Lightweight health endpoint (Docker/Coolify probe + Traefik). + location = /healthz { + access_log off; + add_header Content-Type text/plain; + return 200 'ok'; + } + + # Single-page app: always fall back to index.html. + location / { + try_files $uri $uri/ /index.html; + } + + # index.html must never be cached, so a redeploy is picked up immediately. + location = /index.html { + add_header Cache-Control "no-store, no-cache, must-revalidate"; + add_header X-Content-Type-Options "nosniff"; + add_header Referrer-Policy "no-referrer-when-downgrade"; + } + + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css application/javascript application/json image/svg+xml; +}