delivery slot ui
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import { useState, useMemo } from 'react';
|
||||
import {
|
||||
WINDOW_FILTERS,
|
||||
matchesWindow,
|
||||
windowHasPassed,
|
||||
windowHours,
|
||||
windowLabel,
|
||||
type WindowFilterKey,
|
||||
} from '../deliveryWindow';
|
||||
import { WindowFilterSelect } from '../WindowFilterSelect';
|
||||
import { useDateScope } from '@/components/shell/DateScope';
|
||||
import { CheckboxInput } from '@astryxdesign/core/CheckboxInput';
|
||||
import { Card } from '@astryxdesign/core/Card';
|
||||
@@ -203,14 +203,17 @@ export function SalesPage() {
|
||||
matchesStatus(status, orderStage(row, stages).status) &&
|
||||
matchesWindow(windowFilter, row),
|
||||
),
|
||||
[allOrders, status, stages],
|
||||
// windowFilter belongs here. Left out, this memo never recomputed when the
|
||||
// dropdown changed, so the control moved and the table did not — a filter
|
||||
// that silently does nothing.
|
||||
[allOrders, status, stages, windowFilter],
|
||||
);
|
||||
const deliveryRows = useMemo(
|
||||
() =>
|
||||
allDeliveries.filter(
|
||||
(row) => matchesStatus(status, row.orderstatus) && matchesWindow(windowFilter, row),
|
||||
),
|
||||
[allDeliveries, status],
|
||||
[allDeliveries, status, windowFilter],
|
||||
);
|
||||
|
||||
const billRows = useMemo(() => {
|
||||
@@ -387,12 +390,20 @@ export function SalesPage() {
|
||||
/* Tabs left, search right, on ONE row — see `isTabsInline`. */
|
||||
isTabsInline
|
||||
actions={
|
||||
<SearchInput
|
||||
label="Search sales"
|
||||
value={keyword}
|
||||
onChange={setKeyword}
|
||||
placeholder={SEARCH_HINT[tab]}
|
||||
/>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
|
||||
{/* Not on the counter tab. Imported till bills are not deliveries
|
||||
and can never carry a window, so the control would be one that
|
||||
does nothing on a third of this page. */}
|
||||
{tab === 'counter' ? null : (
|
||||
<WindowFilterSelect value={windowFilter} onChange={setWindowFilter} />
|
||||
)}
|
||||
<SearchInput
|
||||
label="Search sales"
|
||||
value={keyword}
|
||||
onChange={setKeyword}
|
||||
placeholder={SEARCH_HINT[tab]}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
tabs={
|
||||
/* THREE views, not four.
|
||||
@@ -477,10 +488,6 @@ export function SalesPage() {
|
||||
counts={tabCounts}
|
||||
onStatus={setStatus}
|
||||
/>
|
||||
{/* Beside the status tabs, not inside them. Both filters apply at
|
||||
once, because "evening orders still pending" is the question
|
||||
somebody actually has. */}
|
||||
<WindowFilter value={windowFilter} onChange={setWindowFilter} />
|
||||
{/* Above the table, not below it and not in a drawer.
|
||||
Assigning is something you do WHILE reading the day's orders —
|
||||
glancing between the drop addresses and who is free — so the
|
||||
@@ -1528,39 +1535,3 @@ function WindowCell({ row }: { row: OrderRow | DeliveryRow }) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Which window to show.
|
||||
*
|
||||
* "No window" earns its place: it is how an operator finds orders placed
|
||||
* without choosing one, which is most of them while this rolls out, and is the
|
||||
* population worth watching to see the feature being used at all.
|
||||
*/
|
||||
function WindowFilter({
|
||||
value,
|
||||
onChange,
|
||||
}: {
|
||||
value: WindowFilterKey;
|
||||
onChange: (next: WindowFilterKey) => void;
|
||||
}) {
|
||||
return (
|
||||
<select
|
||||
value={value}
|
||||
onChange={(event) => onChange(event.target.value as WindowFilterKey)}
|
||||
aria-label="Filter by delivery window"
|
||||
style={{
|
||||
padding: '6px 10px',
|
||||
fontSize: 12.5,
|
||||
border: '1px solid var(--color-line, #d7dce5)',
|
||||
borderRadius: 7,
|
||||
background: 'var(--color-surface, #fff)',
|
||||
color: 'var(--color-ink-1)',
|
||||
}}
|
||||
>
|
||||
{WINDOW_FILTERS.map((option) => (
|
||||
<option key={option.key} value={option.key}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user