updates on the bookings page and updated ai and more thngs
This commit is contained in:
@@ -16,6 +16,8 @@ import { useZone } from '@/lib/ZoneContext';
|
||||
import { BATCHES, batchRangeLabel, getRowBatchId } from '@/lib/batchBucket';
|
||||
import { formatDoormileTimestamp, parseDoormileTimestamp } from '@/lib/doormileTimestamp';
|
||||
import { currency, exportRows, km as formatKm, matchesQuery, orDash, useDebouncedValue } from '@/lib/doormileFormat';
|
||||
import { pickupSourceTypeLabel } from '@/lib/orderFlow';
|
||||
import { summariseRouting } from '@/lib/routingSummary';
|
||||
|
||||
/**
|
||||
* Deliveries — orders that have moved past merely being created.
|
||||
@@ -640,6 +642,59 @@ export default function Deliveries() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* How this booking was routed, and on what.
|
||||
*
|
||||
* Backend decides the route; this only reports the decision and the inputs it
|
||||
* was made from, so support can answer "why does the rider's screen say hand
|
||||
* over at a base instead of deliver?" without reconstructing a pincode rule by
|
||||
* hand.
|
||||
*
|
||||
* Before pickup the decision has not been taken — `decided` is false and what is
|
||||
* shown is a projection from the captured from/to, labelled as such. A number
|
||||
* presented as a decision when it is only a forecast is worse than no number.
|
||||
*
|
||||
* Wording note: the wire says hub, operators and riders say base. The
|
||||
* translation happens here, at the edge, and never travels back up.
|
||||
*/
|
||||
function RoutingSummary({ routing }) {
|
||||
const s = summariseRouting(routing);
|
||||
if (!s) return null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="mb-2 text-overline uppercase text-ink-4">Routing</p>
|
||||
<Surface variant="subtle" padding="sm" radius="lg">
|
||||
<Stack space="xs">
|
||||
<p className="text-body-sm text-ink-1">{s.reason}</p>
|
||||
<p className="text-caption text-ink-3">{s.route}</p>
|
||||
|
||||
<dl className="grid grid-cols-2 gap-3 pt-1">
|
||||
{[
|
||||
['Collected from', pickupSourceTypeLabel(routing.pickup_source_type)],
|
||||
['Parcel state', s.consignmentState],
|
||||
['Next step', s.nextAction],
|
||||
['Base', s.base || '—'],
|
||||
].map(([label, value]) => (
|
||||
<div key={label}>
|
||||
<dt className="text-caption uppercase tracking-wide text-ink-3">{label}</dt>
|
||||
<dd className="text-body-sm text-ink-1">{value}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
{s.baseAddress ? <p className="text-caption text-ink-3">{s.baseAddress}</p> : null}
|
||||
{s.inwardedAt ? (
|
||||
<p className="text-caption text-ink-3">
|
||||
Received at the base {formatDoormileTimestamp(s.inwardedAt)}
|
||||
</p>
|
||||
) : null}
|
||||
</Stack>
|
||||
</Surface>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* What is actually in the parcel.
|
||||
*
|
||||
@@ -687,14 +742,40 @@ function OrderDetailDrawer({ row, onClose }) {
|
||||
|
||||
<div>
|
||||
<p className="mb-2 text-overline uppercase text-ink-4">Pickup</p>
|
||||
<p className="text-body-sm text-ink-2">{orDash(row?.pickupaddress)}</p>
|
||||
<p className="text-body-sm text-ink-2">
|
||||
{orDash(booking?.routing?.from_address || row?.pickupaddress)}
|
||||
</p>
|
||||
{booking?.routing ? (
|
||||
<p className="text-caption text-ink-3">
|
||||
{[
|
||||
pickupSourceTypeLabel(booking.routing.pickup_source_type),
|
||||
booking.routing.pickup_source_name,
|
||||
booking.routing.from_pincode
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' · ')}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="mb-2 text-overline uppercase text-ink-4">Drop</p>
|
||||
<p className="text-body-sm text-ink-2">{orDash(row?.deliveryaddress)}</p>
|
||||
<p className="text-body-sm text-ink-2">
|
||||
{orDash(booking?.routing?.to_address || row?.deliveryaddress)}
|
||||
</p>
|
||||
{booking?.routing?.destination_pincode ? (
|
||||
<p className="text-caption text-ink-3">{booking.routing.destination_pincode}</p>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Why this parcel is going where it is going.
|
||||
A rider rings asking why his screen says hand over at a base
|
||||
instead of deliver to the customer; without this, answering meant
|
||||
reconstructing the routing rule from two pincodes by hand. The
|
||||
backend decides the route and reports it here with the inputs it
|
||||
used, so the answer is a lookup. */}
|
||||
{booking?.routing ? <RoutingSummary routing={booking.routing} /> : null}
|
||||
|
||||
<div>
|
||||
<p className="mb-2 text-overline uppercase text-ink-4">
|
||||
Parcels {parcels.length ? `· ${parcels.length}` : ''}
|
||||
|
||||
Reference in New Issue
Block a user