import React from "react"; import { Button } from "../UI/Button"; import { Panel } from "../UI/Panel"; const WEEK_DAYS = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]; const startOfMonth = (date) => new Date(date.getFullYear(), date.getMonth(), 1); const endOfMonth = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0); const addMonths = (date, amount) => new Date(date.getFullYear(), date.getMonth() + amount, 1); const formatDayKey = (date) => date.toISOString().slice(0, 10); const labelMonth = (date) => date.toLocaleDateString("ru-RU", { month: "long", year: "numeric" }); const resolveOrderDay = (order) => order.deliverySlots[0]?.date || order.scheduledDelivery.slice(0, 10); const buildCalendarDays = (currentMonth) => { const firstDay = startOfMonth(currentMonth); const lastDay = endOfMonth(currentMonth); const firstWeekDay = (firstDay.getDay() + 6) % 7; const totalDays = lastDay.getDate(); const cells = []; for (let index = 0; index < firstWeekDay; index += 1) { cells.push(null); } for (let day = 1; day <= totalDays; day += 1) { cells.push(new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day)); } while (cells.length % 7 !== 0) { cells.push(null); } return cells; }; export const OrdersCalendarView = ({ orders, onOpenOrder }) => { const initialMonth = React.useMemo(() => { if (!orders.length) { return startOfMonth(new Date()); } const firstOrderDate = new Date(`${resolveOrderDay(orders[0])}T00:00:00`); return startOfMonth(firstOrderDate); }, [orders]); const [currentMonth, setCurrentMonth] = React.useState(initialMonth); React.useEffect(() => { setCurrentMonth(initialMonth); }, [initialMonth]); const calendarDays = React.useMemo(() => buildCalendarDays(currentMonth), [currentMonth]); const ordersByDay = React.useMemo( () => orders.reduce((accumulator, order) => { const key = resolveOrderDay(order); accumulator[key] = accumulator[key] || []; accumulator[key].push(order); return accumulator; }, {}), [orders], ); const agendaDays = React.useMemo( () => Object.entries(ordersByDay) .sort(([left], [right]) => new Date(left) - new Date(right)) .map(([key, dayOrders]) => ({ key, dayOrders })), [ordersByDay], ); return (

Календарь доставок

Месячный вид по датам доставки. Клик по заказу открывает карточку.

{labelMonth(currentMonth)}
Заказы по дням
{agendaDays.map(({ key, dayOrders }) => (
{new Date(`${key}T00:00:00`).toLocaleDateString("ru-RU", { day: "numeric", month: "long", })}
{dayOrders.length}
{dayOrders.map((order) => ( ))}
))}
{WEEK_DAYS.map((day) => (
{day}
))}
{calendarDays.map((day, index) => { if (!day) { return (
); } const key = formatDayKey(day); const dayOrders = ordersByDay[key] || []; return (
{day.getDate()}
{dayOrders.length || ""}
{dayOrders.slice(0, 2).map((order) => ( ))} {dayOrders.length > 2 ? (
Ещё {dayOrders.length - 2}
) : null}
); })}
); };