- Vertically centre the cluster/status/window filters against the metric tiles
in the INC overview row.
- Overlay only ISP cost-centre vehicles (the teams handling INC); other cost
centres are filtered out. Layer count + labels updated to "ISP vehicles".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fold the filter controls into the INC overview card, right-aligned next to the
metric tiles, and remove the standalone filter bar — better visual balance
(fills the previously empty right side of the overview row).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Remove the redundant header KPI strip on the Tickets tab (metrics live in the
INC overview card); header stays empty there.
- Enlarge the map (62vh, min 520px) and size the grid cards to their content
(#tk-main align-items:start) so there's no stretched empty space under the
Closures / By-status cards.
- Split the single 26-row "By cluster" list into "Clusters — Nairobi" and
"Clusters — Mombasa / Voi", classified by cluster name (coast keyword set);
bottom row is now four compact span3 cards.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Render INC tickets as canvas-drawn teardrop map pins via MapLibre symbol layers
(scales to thousands of closed features, unlike DOM markers):
- Open pins coloured by SLA state; larger than the old circles for hierarchy.
- Closed pins use a single muted slate colour irrespective of status (the only
distinction that matters once closed), slightly smaller + under the open layer.
- Legend/popup closed swatch aligned to the new closed colour.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Late async loaders (notably the boot-time logistics loadAll) called their KPI
renderer unconditionally, overwriting the shared header strip after the user had
switched to another tab. Guard renderKpis / renderFuelKpis / renderIncKpis so each
only updates the header when its own tab is active.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Overhaul the Tickets tab into the documented INC operations dashboard,
backed by the new GET /webhook/inc-dashboard endpoint (reporting.fn_inc_dashboard):
- Filterbar (cluster / status / window: today|week|month|custom)
- Metric strip: open now, closed in window, open/closed SLA breakdown,
avg MTTR, closures/day + freshness
- Live map: open INC coloured by SLA state, dimmed closed overlay,
FleetNow vehicle markers, layer toggles + SLA legend
- By-status / by-cluster tables + daily closures chart
- Data load decoupled from the basemap so the dashboard renders even if
WebGL/map init is slow or fails
Removes the old combined INC/CRQ map and the /webhook/tickets call (CRQ deferred).
Adds docs/tickets-inc-{overhaul-plan,implementation-guide}.{md,html}.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New tab backed by dashboard_api /analytics/fuel-fills(+/recent): KPI strip
(litres, KES spend, fills, KES/L, vehicles), spend+litres daily trend, per-vehicle
table (incl. km/L), by-department breakdown, recent fills. Shares the filter state
plus new department/fuel-type dropdowns; lazy-loads on first open. Recent-fills
time renders the Africa/Nairobi wall-clock value directly (no double tz shift).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- #view-tickets is now a MapLibre map: live vehicle DOM markers (ported from
FleetNow) + INC (red) / CRQ (blue) ticket circle layers from /webhook/tickets
- Layers toggle with counts; open/all status filter; lazy-init + map.resize()
- Header KPI strip shows INC/CRQ open + vehicles/moving on the Tickets tab
- Logistics analytics tab unchanged
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Wrap the existing analytics dashboard as the Logistics tab
- Add a scaffolded Tickets tab (per-tab KPIs, recent-tickets + by-status
cards, informative empty state)
- Shared header KPI strip swaps per tab; tickets load lazily on first open
- Ticket data source left as a dashboard_api integration point — no S3
credentials embedded in the static SPA
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs/webhook-auto-deploy.html — step-by-step for push->webhook->Coolify->Traefik
auto-deploy: Coolify Gitea webhook URL/secret, the Forgejo webhook, verifying
deliveries, the staging/prod model, and a troubleshooting table (Auto Deploy
under Advanced, port 80, branch, domain typo, secret). Not served (Dockerfile
copies only src/); repo reference doc.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto-deploy verified (push->Forgejo webhook->Coolify->Traefik). Reverting the
test meta marker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Harmless <meta> marker to confirm a push to staging triggers a Coolify
redeploy. Safe to revert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Caddy `templates` only processes text/html + text/plain by default, so the
text/javascript env.js was served with {{env "API_BASE"}} unevaluated (a literal
that's also a JS parse error). Name the JS MIME types in the templates directive
so the API_BASE injection works — required for prod to point at the prod API
(staging worked only via the index.html fallback).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>