fix: order numbers clickable+copy, expandable sub-accounts, preserve delivery address on pickup switch, opaque calendar, tab-aware date label
This commit is contained in:
parent
005d4467bc
commit
fb5728ba43
|
|
@ -76,6 +76,34 @@ const DELIVERY_TIME_ALIASES = {
|
|||
"После обеда": "Вторая половина дня",
|
||||
};
|
||||
|
||||
const CollapsibleChips = ({ label, items }) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
if (!Array.isArray(items) || items.length === 0) return null;
|
||||
return (
|
||||
<span className="inline">
|
||||
<button
|
||||
type="button"
|
||||
className="ml-1 cursor-pointer rounded-full bg-[var(--color-surface)] px-2 py-0.5 text-xs font-medium text-[var(--color-text-muted)] transition hover:bg-[var(--color-accent-soft)] hover:text-[var(--color-accent)]"
|
||||
onClick={() => setOpen(!open)}
|
||||
>
|
||||
{label} {open ? "▲" : "▼"}
|
||||
</button>
|
||||
{open && (
|
||||
<span className="ml-1 inline-flex flex-wrap gap-1">
|
||||
{items.map((item, idx) => (
|
||||
<span
|
||||
key={idx}
|
||||
className="cursor-pointer rounded-full bg-[var(--color-surface)] px-2 py-0.5 text-xs text-[var(--color-text-muted)] transition hover:bg-[var(--color-accent-soft)] hover:text-[var(--color-accent)]"
|
||||
title="Нажмите, чтобы скопировать"
|
||||
onClick={() => { navigator.clipboard?.writeText(item); }}
|
||||
>{item}</span>
|
||||
))}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const renderList = (values) => {
|
||||
if (!Array.isArray(values) || !values.length) {
|
||||
return <p className="text-sm text-[var(--color-text-muted)]">Нет данных</p>;
|
||||
|
|
@ -574,7 +602,7 @@ export const OrderDetailPanel = ({
|
|||
const [deliveryType, setDeliveryType] = React.useState(order?.deliveryType || "delivery");
|
||||
const [pickupDate, setPickupDate] = React.useState(order?.pickupDate || "");
|
||||
const [pickupTimeSlot, setPickupTimeSlot] = React.useState(DELIVERY_TIME_OPTIONS[0]);
|
||||
const [deliveryAddress, setDeliveryAddress] = React.useState(order?.deliveryAddress || order?.customerAddress || "");
|
||||
const [deliveryAddress, setDeliveryAddress] = React.useState(order?.originalDeliveryAddress || order?.deliveryAddress || order?.customerAddress || "");
|
||||
const [confirmAction, setConfirmAction] = React.useState(null);
|
||||
const minSelectableDateKey = React.useMemo(() => getNextSelectableDateKey(), []);
|
||||
const [currentMonth, setCurrentMonth] = React.useState(() => {
|
||||
|
|
@ -613,6 +641,7 @@ export const OrderDetailPanel = ({
|
|||
setDeliveryType(order?.deliveryType || "delivery");
|
||||
setPickupDate(order?.pickupDate || "");
|
||||
setPickupTimeSlot(normalizeDeliveryTimeChoice(order?.pickupTimeSlot || order?.deliveryTime || order?.deliveryHalfDay));
|
||||
setDeliveryAddress(order?.originalDeliveryAddress || order?.deliveryAddress || order?.customerAddress || "");
|
||||
setFormMessage("");
|
||||
}, [order?.id, order?.deliveryDate, order?.deliveryHalfDay, order?.deliveryTime, order?.deliveryType, order?.pickupDate, order?.pickupTimeSlot]);
|
||||
|
||||
|
|
@ -655,7 +684,7 @@ export const OrderDetailPanel = ({
|
|||
deliveryDate: deliveryType === "pickup" ? pickupDate : deliveryDate,
|
||||
deliveryTime: deliveryType === "pickup" ? pickupTimeSlot : deliveryTime,
|
||||
deliveryType,
|
||||
...(deliveryType === "pickup" ? { pickupDate, pickupTimeSlot, deliveryAddress: "" } : {}),
|
||||
...(deliveryType === "pickup" ? { pickupDate, pickupTimeSlot } : {}),
|
||||
...(deliveryType === "delivery" ? { deliveryAddress: deliveryAddress.trim() } : {}),
|
||||
});
|
||||
|
||||
|
|
@ -800,9 +829,19 @@ export const OrderDetailPanel = ({
|
|||
if (mainNumbers.length > 0) {
|
||||
return (
|
||||
<span>
|
||||
<span className="font-bold">{mainNumbers.join(", ")}</span>
|
||||
{mainNumbers.map((num, idx) => (
|
||||
<span
|
||||
key={idx}
|
||||
className="mr-1 cursor-pointer rounded-full bg-[var(--color-accent-soft)] px-2.5 py-0.5 text-sm font-bold text-[var(--color-accent)] transition hover:opacity-80 active:opacity-60"
|
||||
title="Нажмите, чтобы скопировать"
|
||||
onClick={() => { navigator.clipboard?.writeText(num); }}
|
||||
>{num}</span>
|
||||
))}
|
||||
{extraNumbers.length > 0 && (
|
||||
<span className="text-[var(--color-text-muted)]"> +{extraNumbers.length} сч.</span>
|
||||
<CollapsibleChips
|
||||
label={`+${extraNumbers.length} сч.`}
|
||||
items={extraNumbers}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
|
|
@ -921,7 +960,7 @@ export const OrderDetailPanel = ({
|
|||
disabled={isSavingDeliveryChoice}
|
||||
className="text-sm"
|
||||
>
|
||||
Изменить {(order.deliveryType === "pickup" || order.deliveryStatus === "pickup" || order.delivery_status === "pickup") ? "дату самовывоза" : "дату доставки"}
|
||||
Изменить дату {deliveryType === "pickup" ? "самовывоза" : "доставки"}
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
|
|
@ -939,7 +978,7 @@ export const OrderDetailPanel = ({
|
|||
<span aria-hidden="true" className="text-[var(--color-text-muted)]">▾</span>
|
||||
</button>
|
||||
{isCalendarOpen ? (
|
||||
<div className="rounded-[20px] border border-[var(--color-border)] bg-[var(--color-surface)] p-3 shadow-soft absolute left-0 top-full z-50 mt-2 w-[300px]">
|
||||
<div className="rounded-[20px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-3 shadow-lg absolute left-0 top-full z-50 mt-2 w-[300px]">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
|
||||
|
|
@ -1070,7 +1109,7 @@ export const OrderDetailPanel = ({
|
|||
<span aria-hidden="true" className="text-[var(--color-text-muted)]">▾</span>
|
||||
</button>
|
||||
{isCalendarOpen ? (
|
||||
<div className="rounded-[20px] border border-[var(--color-border)] bg-[var(--color-surface)] p-3 shadow-soft absolute left-0 top-full z-50 mt-2 w-[300px]">
|
||||
<div className="rounded-[20px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-3 shadow-lg absolute left-0 top-full z-50 mt-2 w-[300px]">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--color-text-muted)]">Календарь самовывоза</p>
|
||||
|
|
|
|||
|
|
@ -123,7 +123,9 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
|
|||
? "pickup"
|
||||
: (row.delivery_type || "delivery");
|
||||
|
||||
// Clear placeholder pickup address
|
||||
// Preserve original address for pre-filling delivery form (don't clear for pickup)
|
||||
const originalDeliveryAddress = deliveryAddress;
|
||||
// For display: show nothing for pickup placeholder addresses
|
||||
const resolvedDeliveryAddress = (effectiveDeliveryType === "pickup" && (deliveryAddress.toUpperCase() === "САМОВЫВОЗ" || !deliveryAddress))
|
||||
? ""
|
||||
: deliveryAddress;
|
||||
|
|
@ -170,6 +172,7 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => {
|
|||
customerPhoneNormalized: parsedKey.phone || normalizePhone(customerPhone),
|
||||
customerDate,
|
||||
deliveryAddress: resolvedDeliveryAddress,
|
||||
originalDeliveryAddress,
|
||||
customerAddress,
|
||||
city,
|
||||
assignedDriverId: row.assigned_driver_id || null,
|
||||
|
|
@ -277,7 +280,6 @@ export const updateOrderGroupDeliveryChoice = async ({
|
|||
if (deliveryType === "pickup") {
|
||||
updatePayload.pickup_date = pickupDate || null;
|
||||
updatePayload.pickup_time_slot = pickupTimeSlot || null;
|
||||
updatePayload.delivery_address = "";
|
||||
} else {
|
||||
updatePayload.pickup_date = null;
|
||||
updatePayload.pickup_time_slot = null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue