fix: show saved client delivery choice

This commit is contained in:
Codex 2026-04-16 17:41:46 +03:00
parent 31388f267d
commit de0cf49490
4 changed files with 56 additions and 10 deletions

View File

@ -50,6 +50,7 @@ const splitOrderItem = (item) => {
export const DeliveryChoiceFlow = ({
invitation = {},
selectedSlot = null,
isChoiceSaved = false,
onConfirmChoice = () => {},
onRequestNewLink = () => {},
}) => {
@ -61,13 +62,16 @@ export const DeliveryChoiceFlow = ({
.map(splitOrderItem)
.filter(Boolean);
const slotSummary = selectedSlot ? formatDeliverySlotLabel(selectedSlot) : "";
const isLocked = isChoiceSaved || !isActive;
const selectionCard = (
<div className="space-y-3 rounded-[22px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-4">
<p className="text-sm uppercase tracking-[0.18em] text-[var(--color-text-muted)]">Выбранный слот</p>
<p className="text-sm uppercase tracking-[0.18em] text-[var(--color-text-muted)]">
{isChoiceSaved ? "Сохранённый выбор" : "Выбранный слот"}
</p>
{slotSummary ? (
<p className="text-sm leading-6">
<span className="font-medium">Выбрано:</span> {slotSummary}
<span className="font-medium">{isChoiceSaved ? "Сохранено:" : "Выбрано:"}</span> {slotSummary}
</p>
) : (
<p className="text-sm leading-6 text-[var(--color-text-muted)]">
@ -119,17 +123,21 @@ export const DeliveryChoiceFlow = ({
{selectionCard}
<div className="flex flex-col gap-3 sm:flex-row">
<Button
className="w-full sm:w-auto"
disabled={!slotSummary}
onClick={() => onConfirmChoice(selectedSlot)}
>
Сохранить
</Button>
{!isLocked ? (
<Button
className="w-full sm:w-auto"
disabled={!slotSummary}
onClick={() => onConfirmChoice(selectedSlot)}
>
Сохранить
</Button>
) : null}
<Button variant="secondary" className="w-full sm:w-auto" onClick={onRequestNewLink}>
Запросить новую ссылку
</Button>
</div>
{isChoiceSaved ? <DeliveryStateNotice state="agreed" /> : null}
</Panel>
);
};

View File

@ -46,6 +46,30 @@ describe("DeliveryChoiceFlow", () => {
expect(markup).toContain("disabled");
});
it("renders a saved selection in read-only mode", () => {
const markup = renderToStaticMarkup(
<DeliveryChoiceFlow
invitation={{
state: "agreed",
orderNumber: "CD-240031",
customerName: "Мария Волкова",
}}
selectedSlot={{
date: "2026-04-14",
time: "До обеда",
}}
isChoiceSaved
onConfirmChoice={() => {}}
onRequestNewLink={() => {}}
/>,
);
expect(markup).toContain("Сохранённый выбор");
expect(markup).toContain("14.04.2026");
expect(markup).toContain("До обеда");
expect(markup).not.toContain("Сохранить");
});
it("renders order items with quantities when they are provided", () => {
const markup = renderToStaticMarkup(
<DeliveryChoiceFlow

View File

@ -22,6 +22,10 @@ const STATE_COPY = {
title: "Доставка уже согласована",
description: "Выбор времени доставки уже сохранён в системе.",
},
confirmed: {
title: "Доставка уже согласована",
description: "Выбор времени доставки уже сохранён в системе.",
},
default: {
title: "Требуется ручная обработка",
description: "Сейчас по этому заказу недоступно самостоятельное согласование доставки.",

View File

@ -85,6 +85,7 @@ export const ClientDeliveryPage = () => {
const [actionMessage, setActionMessage] = React.useState("");
const [selectedSlotId, setSelectedSlotId] = React.useState(null);
const [selectedSlot, setSelectedSlot] = React.useState(null);
const [choiceSaved, setChoiceSaved] = React.useState(false);
React.useEffect(() => {
let cancelled = false;
@ -98,6 +99,10 @@ export const ClientDeliveryPage = () => {
setLoading(true);
setError("");
setActionMessage("");
setSelectedSlotId(null);
setSelectedSlot(null);
setChoiceSaved(false);
try {
const loadedInvitation = await fetchDeliveryInvitation(token);
@ -137,6 +142,7 @@ export const ClientDeliveryPage = () => {
);
const effectiveSelectedSlot = selectedSlot || invitationSelectedSlot;
const isChoiceSaved = choiceSaved || (!isActiveState && Boolean(invitationSelectedSlot));
const handleSaveChoice = React.useCallback(
async () => {
@ -150,6 +156,7 @@ export const ClientDeliveryPage = () => {
}
setActionMessage("Сохраняем выбор...");
setChoiceSaved(false);
setError("");
try {
@ -161,6 +168,7 @@ export const ClientDeliveryPage = () => {
const loadedInvitation = await fetchDeliveryInvitation(token);
setInvitation(loadedInvitation);
setSelectedSlot(buildSelectedSlotFromInvitation(loadedInvitation, groupSlotsFromInvitation(loadedInvitation)) || effectiveSelectedSlot);
setChoiceSaved(true);
setActionMessage("Выбор сохранен, спасибо.");
} catch (confirmError) {
setActionMessage("");
@ -174,6 +182,7 @@ export const ClientDeliveryPage = () => {
(slot) => {
setSelectedSlotId(slot.id);
setSelectedSlot(slot);
setChoiceSaved(false);
setActionMessage(
`Выбрано: ${slot.date ? `${formatDeliveryDate(slot.date)} / ${slot.time}` : slot.time}`,
);
@ -227,7 +236,7 @@ export const ClientDeliveryPage = () => {
</p>
</Panel>
{isActiveState && slots.length ? (
{isActiveState && !isChoiceSaved && slots.length ? (
<DeliverySlotsPicker
slots={slots}
onSelectSlot={handleSlotSelect}
@ -239,6 +248,7 @@ export const ClientDeliveryPage = () => {
<DeliveryChoiceFlow
invitation={invitation}
selectedSlot={effectiveSelectedSlot}
isChoiceSaved={isChoiceSaved}
onConfirmChoice={handleSaveChoice}
onRequestNewLink={handleRequestNewLink}
/>