feat(markers): department-colour square + arrow for vehicles active within 24h

High-level fleet-activity read: parked vehicles (reported within 24h) now take
their cost-centre colour as a SQUARE (same 32px as the circle) with the heading
arrow, instead of a flat grey circle. Moving-now stays a coloured circle; only
offline (>24h silent) stays grey. Verified per-state: active=circle, parked=
square+arrow, offline=grey circle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kianiadee 2026-06-06 10:18:25 +03:00
parent 2237757369
commit 74f1ef268f
2 changed files with 19 additions and 7 deletions

View file

@ -3,9 +3,13 @@
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 with a heading arrow, the
plate tail below, and a hover popup (status, driver, reverse-geocoded address,
heading, odometer, last fix, source). Markers **scale with the zoom level**.
- 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)
- **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.

View file

@ -202,7 +202,10 @@
filter: drop-shadow(0 0 1px rgba(0,0,0,.65));
}
.veh-pin .idle-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(255,255,255,.92); }
.veh-marker.parked .veh-pin { box-shadow: 0 2px 5px rgba(0,0,0,.4); opacity: .85; }
/* Parked = reported within 24h ("moved within 24h"): department-coloured
SQUARE (same 32px) with the heading arrow, so high-level viewers can scan
recent fleet activity by department. Moving-now stays a circle. */
.veh-marker.parked .veh-pin { border-radius: 6px; opacity: .95; }
.veh-marker.offline .veh-pin { opacity: .5; border-color: rgba(255,255,255,.4); }
.veh-plate {
position: absolute; top: 33px; left: 50%; transform: translateX(-50%);
@ -517,8 +520,10 @@ function renderLive() {
function upsertLiveMarker(p, coords, feature) {
const state = vehicleState(p);
const color = state === 'active' ? colorForCostCentre(p.cost_centre)
: state === 'offline' ? OFFLINE_COLOR : PARKED_COLOR;
// Active (moving now) and parked (reported within 24h = "moved within 24h")
// both take the department/cost-centre colour so stakeholders read fleet
// activity at a glance. Only offline (>24h silent) stays grey.
const color = state === 'offline' ? OFFLINE_COLOR : colorForCostCentre(p.cost_centre);
const speed = Number(p.speed || 0);
const dir = Number(p.direction || 0);
let m = liveMarkers.get(p.imei);
@ -547,8 +552,11 @@ function upsertLiveMarker(p, coords, feature) {
el.classList.add(state);
const pin = el.querySelector('.veh-pin');
pin.style.setProperty('--c', color);
// Direction arrow for vehicles moving now AND for parked vehicles (last
// heading) — the square + arrow says "active in the last 24h, now stopped".
// Idling (engine on, speed 0) and offline keep the neutral dot.
const glyph = el.querySelector('.glyph');
if (state === 'active' && speed > 0) {
if ((state === 'active' && speed > 0) || state === 'parked') {
glyph.className = 'glyph veh-arrow';
glyph.style.setProperty('--dir', dir + 'deg');
} else {