updates on the deliveries page added the steps in the tabular format and updated the comparison map

This commit is contained in:
2026-05-25 12:22:42 +05:30
parent 13309c1d24
commit e87d5908ea
4 changed files with 1316 additions and 764 deletions

View File

@@ -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' }}>

View File

@@ -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