updates on the deliveries page added the steps in the tabular format and updated the comparison map
This commit is contained in:
@@ -923,6 +923,7 @@ const Deliveries = () => {
|
||||
<TableCell sx={{ position: 'sticky !important', backgroundColor: theme.palette.secondary.light, whiteSpace: 'nowrap', border: 'none' }}> Kms</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important', backgroundColor: theme.palette.secondary.light, whiteSpace: 'nowrap', border: 'none' }}>Amount </TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important', backgroundColor: theme.palette.secondary.light, whiteSpace: 'nowrap', border: 'none' }}>Notes </TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important', backgroundColor: theme.palette.secondary.light, whiteSpace: 'nowrap', border: 'none' }}>Steps</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important', backgroundColor: theme.palette.secondary.light, whiteSpace: 'nowrap', border: 'none' }}>Qty</TableCell>
|
||||
<TableCell sx={{ position: 'sticky !important', backgroundColor: theme.palette.secondary.light, whiteSpace: 'nowrap', border: 'none' }}>COD </TableCell>
|
||||
{tabstatus !== 'Cancelled' && tabstatus !== 'Delivered' && (
|
||||
@@ -944,7 +945,7 @@ const Deliveries = () => {
|
||||
<TableBody>
|
||||
{rows.length == 0 && !loading1 && (
|
||||
<>
|
||||
<TableCell colSpan={13}>
|
||||
<TableCell colSpan={14}>
|
||||
{/* <Stack width={'100%'} direction={'row'} justifyContent={'center'}> */}
|
||||
<Empty description={`No ${tabstatus} Orders`} styles={{ description: { color: theme.palette.error.main } }} />
|
||||
</TableCell>
|
||||
@@ -1125,10 +1126,27 @@ const Deliveries = () => {
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
{/* {qty} */}
|
||||
{/* notes */}
|
||||
<TableCell>
|
||||
<Typography>{row.notes}</Typography>
|
||||
</TableCell>
|
||||
{/* step */}
|
||||
<TableCell align="center">
|
||||
{row.step ? (
|
||||
<Chip
|
||||
label={row.step}
|
||||
size="small"
|
||||
color="primary"
|
||||
variant="light"
|
||||
sx={{ fontWeight: 700, minWidth: 28 }}
|
||||
/>
|
||||
) : (
|
||||
<Typography variant="subtitle2" color="text.disabled">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
{/* qty */}
|
||||
<TableCell>
|
||||
{row.Quantity ? (
|
||||
<Typography variant="subtitle1" color={'error'} sx={{ whiteSpace: 'nowrap' }}>
|
||||
|
||||
@@ -13,7 +13,11 @@ import {
|
||||
MdFormatListBulleted,
|
||||
MdTimer,
|
||||
MdWarning,
|
||||
MdClose
|
||||
MdClose,
|
||||
MdSpeed,
|
||||
MdStar,
|
||||
MdFlag,
|
||||
MdHourglassBottom
|
||||
} from 'react-icons/md';
|
||||
import {
|
||||
stepColor,
|
||||
@@ -513,48 +517,126 @@ function CompareDataPanel({
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Timing KPIs */}
|
||||
{/* Timing — clock-style timeline. First/last delivery render as
|
||||
digital clock faces flanking a duration centerpiece. Tiny
|
||||
"Started" / "Finished" captions give the row a narrative.
|
||||
Below: avg-per-stop with a dotted stops-row visualization,
|
||||
and avg speed with a 0-60 gauge bar. */}
|
||||
{(firstDelivery || lastDelivery) && (
|
||||
<section className="cdp-section">
|
||||
<section className="cdp-section cdp-timing-section">
|
||||
<div className="cdp-section-head">
|
||||
<span className="cdp-section-icon"><MdTimer /></span>
|
||||
<span className="cdp-section-title">Timing KPIs</span>
|
||||
<span className="cdp-section-title">Timing</span>
|
||||
{activeMin > 0 && (
|
||||
<span className="cdp-timing-active-tag">
|
||||
<span className="cdp-timing-active-pulse" />
|
||||
Day window
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="cdp-kpi-row">
|
||||
<div className="cdp-kpi">
|
||||
<div className="cdp-kpi-label">First delivery</div>
|
||||
<div className="cdp-kpi-value">
|
||||
{firstDelivery ? firstDelivery.format('hh:mm A') : '—'}
|
||||
<div className="cdp-timing-clock">
|
||||
<div className="cdp-clock-card is-start">
|
||||
<div className="cdp-clock-label">
|
||||
<MdFlag /> First delivery
|
||||
</div>
|
||||
<div className="cdp-clock-face">
|
||||
<span className="cdp-clock-time">
|
||||
{firstDelivery ? firstDelivery.format('hh:mm') : '—'}
|
||||
</span>
|
||||
<span className="cdp-clock-period">
|
||||
{firstDelivery ? firstDelivery.format('A') : ''}
|
||||
</span>
|
||||
</div>
|
||||
<div className="cdp-clock-caption">Started</div>
|
||||
</div>
|
||||
<div className="cdp-clock-track" aria-hidden="true">
|
||||
<span className="cdp-clock-track-line" />
|
||||
<span className="cdp-clock-track-dot is-start" />
|
||||
<span className="cdp-clock-track-dot is-end" />
|
||||
<div className="cdp-clock-duration">
|
||||
<span className="cdp-clock-duration-icon">
|
||||
<MdHourglassBottom />
|
||||
</span>
|
||||
<span className="cdp-clock-duration-val">
|
||||
{activeMin > 0
|
||||
? activeMin >= 60
|
||||
? `${Math.floor(activeMin / 60)}h ${activeMin % 60}m`
|
||||
: `${activeMin}m`
|
||||
: '—'}
|
||||
</span>
|
||||
<span className="cdp-clock-duration-sub">active</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="cdp-kpi">
|
||||
<div className="cdp-kpi-label">Last delivery</div>
|
||||
<div className="cdp-kpi-value">
|
||||
{lastDelivery ? lastDelivery.format('hh:mm A') : '—'}
|
||||
<div className="cdp-clock-card is-end">
|
||||
<div className="cdp-clock-label">
|
||||
<MdCheckCircle /> Last delivery
|
||||
</div>
|
||||
<div className="cdp-clock-face">
|
||||
<span className="cdp-clock-time">
|
||||
{lastDelivery ? lastDelivery.format('hh:mm') : '—'}
|
||||
</span>
|
||||
<span className="cdp-clock-period">
|
||||
{lastDelivery ? lastDelivery.format('A') : ''}
|
||||
</span>
|
||||
</div>
|
||||
<div className="cdp-clock-caption">Finished</div>
|
||||
</div>
|
||||
<div className="cdp-kpi">
|
||||
<div className="cdp-kpi-label">Active time</div>
|
||||
<div className="cdp-kpi-value">
|
||||
{activeMin > 0
|
||||
? activeMin >= 60
|
||||
? `${Math.floor(activeMin / 60)}h ${activeMin % 60}m`
|
||||
: `${activeMin}m`
|
||||
: '—'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="cdp-kpi">
|
||||
<div className="cdp-kpi-label">Avg / stop</div>
|
||||
<div className="cdp-kpi-value">
|
||||
{avgPerStop > 0 ? `${avgPerStop}m` : '—'}
|
||||
</div>
|
||||
<div className="cdp-timing-stats">
|
||||
<div className="cdp-timing-stat">
|
||||
<div className="cdp-timing-stat-head">
|
||||
<div className="cdp-timing-stat-icon">
|
||||
<MdAccessTime />
|
||||
</div>
|
||||
<div className="cdp-timing-stat-body">
|
||||
<div className="cdp-timing-stat-value">
|
||||
{avgPerStop > 0 ? `${avgPerStop}` : '—'}
|
||||
{avgPerStop > 0 && (
|
||||
<span className="cdp-timing-stat-unit">min</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="cdp-timing-stat-label">Avg / stop</div>
|
||||
</div>
|
||||
</div>
|
||||
{compareDeltas.length > 0 && (
|
||||
<div className="cdp-timing-stat-viz cdp-stops-dots" aria-hidden="true">
|
||||
{Array.from({ length: Math.min(compareDeltas.length, 12) }).map((_, i) => (
|
||||
<span key={`dot-${i}`} className="cdp-stop-dot" />
|
||||
))}
|
||||
<span className="cdp-timing-stat-viz-label">
|
||||
{compareDeltas.length} stop{compareDeltas.length === 1 ? '' : 's'}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{avgSpeed != null && (
|
||||
<div className="cdp-kpi">
|
||||
<div className="cdp-kpi-label">Avg speed</div>
|
||||
<div className="cdp-kpi-value">
|
||||
{avgSpeed}
|
||||
<span className="cdp-kpi-unit">km/h</span>
|
||||
<div className="cdp-timing-stat">
|
||||
<div className="cdp-timing-stat-head">
|
||||
<div className="cdp-timing-stat-icon">
|
||||
<MdSpeed />
|
||||
</div>
|
||||
<div className="cdp-timing-stat-body">
|
||||
<div className="cdp-timing-stat-value">
|
||||
{avgSpeed}
|
||||
<span className="cdp-timing-stat-unit">km/h</span>
|
||||
</div>
|
||||
<div className="cdp-timing-stat-label">Avg speed</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="cdp-timing-stat-viz cdp-speed-gauge" aria-hidden="true">
|
||||
<div className="cdp-speed-gauge-track">
|
||||
<div
|
||||
className="cdp-speed-gauge-fill"
|
||||
style={{
|
||||
width: `${Math.min(100, (parseFloat(avgSpeed) / 60) * 100)}%`
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="cdp-speed-gauge-scale">
|
||||
<span>0</span>
|
||||
<span>30</span>
|
||||
<span>60 km/h</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -562,11 +644,14 @@ function CompareDataPanel({
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Highlights — best/worst step quick-pick. */}
|
||||
{/* Highlights — best/worst step quick-pick. Full-width cards stacked
|
||||
vertically: a colored rail on the left side encodes good/bad,
|
||||
the customer name is the headline, the step number sits as a
|
||||
right-aligned chip, and the metric line uses bold pills. */}
|
||||
{(bestStep || worstStep) && (
|
||||
<section className="cdp-section">
|
||||
<div className="cdp-section-head">
|
||||
<span className="cdp-section-icon"><MdTrendingUp /></span>
|
||||
<span className="cdp-section-icon"><MdStar /></span>
|
||||
<span className="cdp-section-title">Highlights</span>
|
||||
</div>
|
||||
<div className="cdp-highlights">
|
||||
@@ -577,23 +662,35 @@ function CompareDataPanel({
|
||||
role="button"
|
||||
title="Focus this step"
|
||||
>
|
||||
<span
|
||||
className="cdp-highlight-num"
|
||||
style={{ background: stepColor(bestStep.sequenceStep - 1) }}
|
||||
>
|
||||
{bestStep.sequenceStep}
|
||||
</span>
|
||||
<div className="cdp-highlight-body">
|
||||
<div className="cdp-highlight-label">
|
||||
<MdCheckCircle /> Fastest stop
|
||||
<span className="cdp-highlight-rail" aria-hidden="true" />
|
||||
<div className="cdp-highlight-content">
|
||||
<div className="cdp-highlight-top">
|
||||
<span className="cdp-highlight-label">
|
||||
<span className="cdp-highlight-chip">
|
||||
<MdCheckCircle />
|
||||
</span>
|
||||
Fastest stop
|
||||
</span>
|
||||
<span
|
||||
className="cdp-highlight-step-chip"
|
||||
style={{
|
||||
background: stepColor(bestStep.sequenceStep - 1)
|
||||
}}
|
||||
>
|
||||
Step {bestStep.sequenceStep}
|
||||
</span>
|
||||
</div>
|
||||
<div className="cdp-highlight-title">
|
||||
{bestStep.deliverycustomer || `Step ${bestStep.sequenceStep}`}
|
||||
</div>
|
||||
<div className="cdp-highlight-meta">
|
||||
{bestStep.timeDeltaMin != null
|
||||
? `${bestStep.timeDeltaMin > 0 ? '+' : ''}${bestStep.timeDeltaMin} min vs plan`
|
||||
: 'on schedule'}
|
||||
<span className="cdp-highlight-pill is-good">
|
||||
{bestStep.timeDeltaMin != null
|
||||
? bestStep.timeDeltaMin === 0
|
||||
? 'On schedule'
|
||||
: `${bestStep.timeDeltaMin > 0 ? '+' : ''}${bestStep.timeDeltaMin} min vs plan`
|
||||
: 'On schedule'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -605,26 +702,39 @@ function CompareDataPanel({
|
||||
role="button"
|
||||
title="Focus this step"
|
||||
>
|
||||
<span
|
||||
className="cdp-highlight-num"
|
||||
style={{ background: stepColor(worstStep.sequenceStep - 1) }}
|
||||
>
|
||||
{worstStep.sequenceStep}
|
||||
</span>
|
||||
<div className="cdp-highlight-body">
|
||||
<div className="cdp-highlight-label">
|
||||
<MdWarning /> Biggest deviation
|
||||
<span className="cdp-highlight-rail" aria-hidden="true" />
|
||||
<div className="cdp-highlight-content">
|
||||
<div className="cdp-highlight-top">
|
||||
<span className="cdp-highlight-label">
|
||||
<span className="cdp-highlight-chip">
|
||||
<MdWarning />
|
||||
</span>
|
||||
Biggest deviation
|
||||
</span>
|
||||
<span
|
||||
className="cdp-highlight-step-chip"
|
||||
style={{
|
||||
background: stepColor(worstStep.sequenceStep - 1)
|
||||
}}
|
||||
>
|
||||
Step {worstStep.sequenceStep}
|
||||
</span>
|
||||
</div>
|
||||
<div className="cdp-highlight-title">
|
||||
{worstStep.deliverycustomer || `Step ${worstStep.sequenceStep}`}
|
||||
</div>
|
||||
<div className="cdp-highlight-meta">
|
||||
{worstStep.kmDeltaPct != null
|
||||
? `${worstStep.kmDeltaPct > 0 ? '+' : ''}${worstStep.kmDeltaPct.toFixed(0)}% route`
|
||||
: ''}
|
||||
{worstStep.timeDeltaMin != null && worstStep.timeDeltaMin > 0
|
||||
? ` · +${worstStep.timeDeltaMin}m late`
|
||||
: ''}
|
||||
{worstStep.kmDeltaPct != null && (
|
||||
<span className="cdp-highlight-pill is-bad">
|
||||
{worstStep.kmDeltaPct > 0 ? '+' : ''}
|
||||
{worstStep.kmDeltaPct.toFixed(0)}% route
|
||||
</span>
|
||||
)}
|
||||
{worstStep.timeDeltaMin != null && worstStep.timeDeltaMin > 0 && (
|
||||
<span className="cdp-highlight-pill is-bad">
|
||||
+{worstStep.timeDeltaMin}m late
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user