supersam/src/components/client/DeliverySlotsPicker.jsx

95 lines
3.1 KiB
JavaScript

import React from "react";
import { Button } from "../UI/Button";
import { Panel } from "../UI/Panel";
import { formatDeliverySlotGroupLabel } from "./deliveryDateFormatting";
const groupSlotsByDate = (slots) => {
const groups = new Map();
const getSlotPriority = (slot) => {
const time = String(slot?.time || "").toLowerCase();
if (time.includes("первая") || time.includes("до обеда")) {
return 0;
}
if (time.includes("вторая") || time.includes("после обеда")) {
return 1;
}
return 2;
};
for (const slot of slots) {
if (!groups.has(slot.date)) {
groups.set(slot.date, []);
}
groups.get(slot.date).push(slot);
}
return Array.from(groups.entries())
.map(([date, dateSlots]) => [
date,
[...dateSlots].sort((left, right) => getSlotPriority(left) - getSlotPriority(right)),
])
.sort(([a], [b]) => a.localeCompare(b));
};
export { formatDeliverySlotGroupLabel } from "./deliveryDateFormatting";
export const DeliverySlotsPicker = ({
slots,
onSelectSlot,
selectedSlotId,
referenceDate = new Date(),
}) => {
if (!slots || !slots.length) {
return (
<Panel className="p-5 sm:p-6">
<p className="text-sm text-[var(--color-text-muted)]">Нет доступных слотов для выбора. Логист назначит слот позже.</p>
</Panel>
);
}
const grouped = groupSlotsByDate(slots);
return (
<div className="space-y-4">
{grouped.map(([date, dateSlots]) => (
<details key={date} className="group rounded-[28px] border border-[var(--color-border)] bg-[var(--color-surface)] shadow-soft backdrop-blur" open>
<summary className="cursor-pointer list-none p-5 sm:p-6">
<div className="flex items-center justify-between gap-3">
<div className="space-y-1">
<p className="text-sm uppercase tracking-[0.18em] text-[var(--color-text-muted)]">Доставка на день</p>
<h4 className="font-medium">{formatDeliverySlotGroupLabel(date, referenceDate)}</h4>
</div>
<span className="text-sm text-[var(--color-text-muted)] group-open:hidden">Раскрыть</span>
<span className="hidden text-sm text-[var(--color-text-muted)] group-open:inline">Свернуть</span>
</div>
</summary>
<div className="px-5 pb-5 sm:px-6 sm:pb-6">
<div className="grid gap-3 sm:grid-cols-2">
{dateSlots.map((slot) => {
const isSelected = selectedSlotId === slot.id;
return (
<Button
key={slot.id}
variant={isSelected ? "primary" : "secondary"}
aria-pressed={isSelected}
onClick={() => onSelectSlot(slot)}
>
{slot.time}
{isSelected ? " — Выбрано" : ""}
</Button>
);
})}
</div>
</div>
</details>
))}
</div>
);
};