diff --git a/apps/web/public/app.js b/apps/web/public/app.js
index c988421..6e4893d 100644
--- a/apps/web/public/app.js
+++ b/apps/web/public/app.js
@@ -926,8 +926,8 @@ function updateLeafletMarker(location) {
const icon = L.divIcon({
className: `leaflet-truck-marker truck-marker ${status.key} ${vehicleType.className} ${selectedClass}`,
html: createTruckMarkerHtml(location, vehicleType, markerHeading),
- iconSize: [86, 68],
- iconAnchor: [43, 64],
+ iconSize: [104, 68],
+ iconAnchor: [52, 64],
popupAnchor: [0, -50]
});
@@ -969,7 +969,7 @@ function createTruckMarkerElement(location, status, heading) {
function createTruckMarkerHtml(location, vehicleType = getVehicleType(location), heading = getLocationHeading(location)) {
const label = location.vehicleNo ? location.vehicleNo.slice(-4) : location.driverId.slice(0, 4);
const rotation = normalizeMarkerRotation(heading);
- const markerCode = getVehicleMarkerCode(vehicleType.className);
+ const vehiclePictogram = createVehiclePictogramSvg(vehicleType.className);
return `
- ${escapeHtml(markerCode)}
+ ${vehiclePictogram}
+ ${vehiclePictogram}
${escapeHtml(label)}
${escapeHtml(vehicleType.shortLabel)}
`;
}
-function getVehicleMarkerCode(typeClass) {
- const markerCodes = {
- "type-cargo": "CT",
- "type-trailer": "TR",
- "type-container": "CN",
- "type-box": "BX",
- "type-van": "V",
- "type-cold": "RF",
- "type-wing": "WB"
- };
- return markerCodes[typeClass] || "CT";
+function createVehiclePictogramSvg(typeClass) {
+ if (typeClass === "type-trailer") {
+ return `
+
+ `;
+ }
+
+ if (typeClass === "type-container") {
+ return `
+
+ `;
+ }
+
+ if (typeClass === "type-box") {
+ return `
+
+ `;
+ }
+
+ if (typeClass === "type-van") {
+ return `
+
+ `;
+ }
+
+ if (typeClass === "type-cold") {
+ return `
+
+ `;
+ }
+
+ if (typeClass === "type-wing") {
+ return `
+
+ `;
+ }
+
+ return `
+
+ `;
}
function resolveMarkerHeading(location, fromPosition, targetPosition) {
diff --git a/apps/web/public/styles.css b/apps/web/public/styles.css
index c135ebb..27a8611 100644
--- a/apps/web/public/styles.css
+++ b/apps/web/public/styles.css
@@ -1058,8 +1058,8 @@ button:hover {
position: relative;
display: grid;
place-items: center;
- width: 86px;
- min-width: 86px;
+ width: 104px;
+ min-width: 104px;
height: 68px;
min-height: 68px;
border: 0;
@@ -1176,32 +1176,11 @@ button:hover {
filter: drop-shadow(0 0 0 rgba(31, 111, 235, 0.22));
}
-.truck-marker__type-code {
- position: absolute;
- top: 19px;
- left: 50%;
- z-index: 3;
- display: grid;
- place-items: center;
- width: 25px;
- height: 17px;
- border: 1px solid rgba(255, 255, 255, 0.72);
- border-radius: 5px;
- background: rgba(15, 23, 42, 0.2);
- color: #ffffff;
- font-size: 9px;
- font-weight: 950;
- line-height: 1;
- letter-spacing: 0;
- transform: translateX(-50%);
- pointer-events: none;
-}
-
.truck-marker__status {
position: absolute;
top: 33px;
left: calc(50% + 16px);
- z-index: 4;
+ z-index: 5;
width: 10px;
height: 10px;
border: 2px solid #ffffff;
@@ -1211,6 +1190,47 @@ button:hover {
pointer-events: none;
}
+.truck-marker__body-icon {
+ position: absolute;
+ top: 15px;
+ left: 50%;
+ z-index: 4;
+ display: grid;
+ place-items: center;
+ width: 52px;
+ height: 27px;
+ border: 1px solid rgba(15, 23, 42, 0.1);
+ border-radius: 8px;
+ background:
+ linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 250, 252, 0.92));
+ box-shadow:
+ 0 6px 14px rgba(15, 23, 42, 0.2),
+ inset 0 1px 0 rgba(255, 255, 255, 0.95);
+ transform: translateX(-50%);
+ pointer-events: none;
+}
+
+.truck-marker__body-icon .truck-marker__vehicle-icon {
+ width: 47px;
+ height: 25px;
+ filter: drop-shadow(0 1px 1px rgba(15, 23, 42, 0.24));
+}
+
+.truck-marker__body-icon .truck-marker__vehicle-icon .icon-load,
+.truck-marker__body-icon .truck-marker__vehicle-icon .icon-cab,
+.truck-marker__body-icon .truck-marker__vehicle-icon .icon-wing {
+ stroke-width: 1.55;
+}
+
+.truck-marker__body-icon .truck-marker__vehicle-icon .icon-line,
+.truck-marker__body-icon .truck-marker__vehicle-icon .icon-snow {
+ stroke-width: 1.45;
+}
+
+.truck-marker__body-icon .truck-marker__vehicle-icon .icon-wheel {
+ stroke-width: 1.2;
+}
+
.truck-marker__identity {
position: absolute;
left: 50%;
@@ -1218,10 +1238,10 @@ button:hover {
z-index: 3;
display: inline-flex;
align-items: center;
- gap: 4px;
- max-width: 84px;
- min-height: 20px;
- padding: 2px 7px;
+ gap: 5px;
+ max-width: 102px;
+ min-height: 23px;
+ padding: 2px 7px 2px 4px;
border: 1px solid rgba(15, 23, 42, 0.12);
border-radius: 7px;
background: rgba(255, 255, 255, 0.96);
@@ -1234,6 +1254,61 @@ button:hover {
white-space: nowrap;
}
+.truck-marker__label-icon {
+ display: grid;
+ flex: 0 0 28px;
+ place-items: center;
+ width: 28px;
+ height: 17px;
+ border: 1px solid rgba(15, 23, 42, 0.08);
+ border-radius: 5px;
+ background: var(--marker-chip);
+ overflow: hidden;
+}
+
+.truck-marker__vehicle-icon {
+ display: block;
+ width: 26px;
+ height: 15px;
+ overflow: visible;
+}
+
+.truck-marker__vehicle-icon .icon-load,
+.truck-marker__vehicle-icon .icon-cab,
+.truck-marker__vehicle-icon .icon-wing {
+ fill: var(--marker-fill);
+ stroke: #ffffff;
+ stroke-linejoin: round;
+ stroke-width: 1.35;
+}
+
+.truck-marker__vehicle-icon .icon-cab {
+ fill: var(--marker-dark);
+}
+
+.truck-marker__vehicle-icon .icon-window {
+ fill: rgba(255, 255, 255, 0.75);
+}
+
+.truck-marker__vehicle-icon .icon-wheel {
+ fill: #111827;
+ stroke: #ffffff;
+ stroke-width: 1.1;
+}
+
+.truck-marker__vehicle-icon .icon-line,
+.truck-marker__vehicle-icon .icon-snow {
+ fill: none;
+ stroke: rgba(255, 255, 255, 0.86);
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ stroke-width: 1.3;
+}
+
+.truck-marker__vehicle-icon .icon-snow {
+ stroke: #ffffff;
+}
+
.truck-marker__plate {
display: inline-block;
min-width: 0;