fix: show saved client delivery choice
This commit is contained in:
parent
31388f267d
commit
de0cf49490
|
|
@ -50,6 +50,7 @@ const splitOrderItem = (item) => {
|
||||||
export const DeliveryChoiceFlow = ({
|
export const DeliveryChoiceFlow = ({
|
||||||
invitation = {},
|
invitation = {},
|
||||||
selectedSlot = null,
|
selectedSlot = null,
|
||||||
|
isChoiceSaved = false,
|
||||||
onConfirmChoice = () => {},
|
onConfirmChoice = () => {},
|
||||||
onRequestNewLink = () => {},
|
onRequestNewLink = () => {},
|
||||||
}) => {
|
}) => {
|
||||||
|
|
@ -61,13 +62,16 @@ export const DeliveryChoiceFlow = ({
|
||||||
.map(splitOrderItem)
|
.map(splitOrderItem)
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
const slotSummary = selectedSlot ? formatDeliverySlotLabel(selectedSlot) : "";
|
const slotSummary = selectedSlot ? formatDeliverySlotLabel(selectedSlot) : "";
|
||||||
|
const isLocked = isChoiceSaved || !isActive;
|
||||||
|
|
||||||
const selectionCard = (
|
const selectionCard = (
|
||||||
<div className="space-y-3 rounded-[22px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-4">
|
<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 ? (
|
{slotSummary ? (
|
||||||
<p className="text-sm leading-6">
|
<p className="text-sm leading-6">
|
||||||
<span className="font-medium">Выбрано:</span> {slotSummary}
|
<span className="font-medium">{isChoiceSaved ? "Сохранено:" : "Выбрано:"}</span> {slotSummary}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm leading-6 text-[var(--color-text-muted)]">
|
<p className="text-sm leading-6 text-[var(--color-text-muted)]">
|
||||||
|
|
@ -119,6 +123,7 @@ export const DeliveryChoiceFlow = ({
|
||||||
{selectionCard}
|
{selectionCard}
|
||||||
|
|
||||||
<div className="flex flex-col gap-3 sm:flex-row">
|
<div className="flex flex-col gap-3 sm:flex-row">
|
||||||
|
{!isLocked ? (
|
||||||
<Button
|
<Button
|
||||||
className="w-full sm:w-auto"
|
className="w-full sm:w-auto"
|
||||||
disabled={!slotSummary}
|
disabled={!slotSummary}
|
||||||
|
|
@ -126,10 +131,13 @@ export const DeliveryChoiceFlow = ({
|
||||||
>
|
>
|
||||||
Сохранить
|
Сохранить
|
||||||
</Button>
|
</Button>
|
||||||
|
) : null}
|
||||||
<Button variant="secondary" className="w-full sm:w-auto" onClick={onRequestNewLink}>
|
<Button variant="secondary" className="w-full sm:w-auto" onClick={onRequestNewLink}>
|
||||||
Запросить новую ссылку
|
Запросить новую ссылку
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isChoiceSaved ? <DeliveryStateNotice state="agreed" /> : null}
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,30 @@ describe("DeliveryChoiceFlow", () => {
|
||||||
expect(markup).toContain("disabled");
|
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", () => {
|
it("renders order items with quantities when they are provided", () => {
|
||||||
const markup = renderToStaticMarkup(
|
const markup = renderToStaticMarkup(
|
||||||
<DeliveryChoiceFlow
|
<DeliveryChoiceFlow
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ const STATE_COPY = {
|
||||||
title: "Доставка уже согласована",
|
title: "Доставка уже согласована",
|
||||||
description: "Выбор времени доставки уже сохранён в системе.",
|
description: "Выбор времени доставки уже сохранён в системе.",
|
||||||
},
|
},
|
||||||
|
confirmed: {
|
||||||
|
title: "Доставка уже согласована",
|
||||||
|
description: "Выбор времени доставки уже сохранён в системе.",
|
||||||
|
},
|
||||||
default: {
|
default: {
|
||||||
title: "Требуется ручная обработка",
|
title: "Требуется ручная обработка",
|
||||||
description: "Сейчас по этому заказу недоступно самостоятельное согласование доставки.",
|
description: "Сейчас по этому заказу недоступно самостоятельное согласование доставки.",
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ export const ClientDeliveryPage = () => {
|
||||||
const [actionMessage, setActionMessage] = React.useState("");
|
const [actionMessage, setActionMessage] = React.useState("");
|
||||||
const [selectedSlotId, setSelectedSlotId] = React.useState(null);
|
const [selectedSlotId, setSelectedSlotId] = React.useState(null);
|
||||||
const [selectedSlot, setSelectedSlot] = React.useState(null);
|
const [selectedSlot, setSelectedSlot] = React.useState(null);
|
||||||
|
const [choiceSaved, setChoiceSaved] = React.useState(false);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
|
@ -98,6 +99,10 @@ export const ClientDeliveryPage = () => {
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError("");
|
setError("");
|
||||||
|
setActionMessage("");
|
||||||
|
setSelectedSlotId(null);
|
||||||
|
setSelectedSlot(null);
|
||||||
|
setChoiceSaved(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const loadedInvitation = await fetchDeliveryInvitation(token);
|
const loadedInvitation = await fetchDeliveryInvitation(token);
|
||||||
|
|
@ -137,6 +142,7 @@ export const ClientDeliveryPage = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const effectiveSelectedSlot = selectedSlot || invitationSelectedSlot;
|
const effectiveSelectedSlot = selectedSlot || invitationSelectedSlot;
|
||||||
|
const isChoiceSaved = choiceSaved || (!isActiveState && Boolean(invitationSelectedSlot));
|
||||||
|
|
||||||
const handleSaveChoice = React.useCallback(
|
const handleSaveChoice = React.useCallback(
|
||||||
async () => {
|
async () => {
|
||||||
|
|
@ -150,6 +156,7 @@ export const ClientDeliveryPage = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
setActionMessage("Сохраняем выбор...");
|
setActionMessage("Сохраняем выбор...");
|
||||||
|
setChoiceSaved(false);
|
||||||
setError("");
|
setError("");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -161,6 +168,7 @@ export const ClientDeliveryPage = () => {
|
||||||
const loadedInvitation = await fetchDeliveryInvitation(token);
|
const loadedInvitation = await fetchDeliveryInvitation(token);
|
||||||
setInvitation(loadedInvitation);
|
setInvitation(loadedInvitation);
|
||||||
setSelectedSlot(buildSelectedSlotFromInvitation(loadedInvitation, groupSlotsFromInvitation(loadedInvitation)) || effectiveSelectedSlot);
|
setSelectedSlot(buildSelectedSlotFromInvitation(loadedInvitation, groupSlotsFromInvitation(loadedInvitation)) || effectiveSelectedSlot);
|
||||||
|
setChoiceSaved(true);
|
||||||
setActionMessage("Выбор сохранен, спасибо.");
|
setActionMessage("Выбор сохранен, спасибо.");
|
||||||
} catch (confirmError) {
|
} catch (confirmError) {
|
||||||
setActionMessage("");
|
setActionMessage("");
|
||||||
|
|
@ -174,6 +182,7 @@ export const ClientDeliveryPage = () => {
|
||||||
(slot) => {
|
(slot) => {
|
||||||
setSelectedSlotId(slot.id);
|
setSelectedSlotId(slot.id);
|
||||||
setSelectedSlot(slot);
|
setSelectedSlot(slot);
|
||||||
|
setChoiceSaved(false);
|
||||||
setActionMessage(
|
setActionMessage(
|
||||||
`Выбрано: ${slot.date ? `${formatDeliveryDate(slot.date)} / ${slot.time}` : slot.time}`,
|
`Выбрано: ${slot.date ? `${formatDeliveryDate(slot.date)} / ${slot.time}` : slot.time}`,
|
||||||
);
|
);
|
||||||
|
|
@ -227,7 +236,7 @@ export const ClientDeliveryPage = () => {
|
||||||
</p>
|
</p>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
{isActiveState && slots.length ? (
|
{isActiveState && !isChoiceSaved && slots.length ? (
|
||||||
<DeliverySlotsPicker
|
<DeliverySlotsPicker
|
||||||
slots={slots}
|
slots={slots}
|
||||||
onSelectSlot={handleSlotSelect}
|
onSelectSlot={handleSlotSelect}
|
||||||
|
|
@ -239,6 +248,7 @@ export const ClientDeliveryPage = () => {
|
||||||
<DeliveryChoiceFlow
|
<DeliveryChoiceFlow
|
||||||
invitation={invitation}
|
invitation={invitation}
|
||||||
selectedSlot={effectiveSelectedSlot}
|
selectedSlot={effectiveSelectedSlot}
|
||||||
|
isChoiceSaved={isChoiceSaved}
|
||||||
onConfirmChoice={handleSaveChoice}
|
onConfirmChoice={handleSaveChoice}
|
||||||
onRequestNewLink={handleRequestNewLink}
|
onRequestNewLink={handleRequestNewLink}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue