import React from "react"; import { assignDriverToOrderGroup, fetchOrderGroupById, fetchOrderGroups, saveShipmentData, updateDeliveryStatus, updateOrderGroupDeliveryChoice } from "../services/supabase/orderGroupRepository"; import { buildOrderGroupBuckets, filterOrderGroups, groupOrderGroupsByDate, ORDER_GROUP_DISPLAY_STATUS_OPTIONS, getOrderGroupDisplayStatusValue, } from "../services/orderGroupViews"; import { getErrorMessage } from "../utils/deliveryUtils"; export const useOrderGroups = ({ enabled = true, details = false, groupId = null } = {}) => { const [orderGroups, setOrderGroups] = React.useState(() => []); const FILTERS_STORAGE_KEY = "supersam_order_filters"; const [filters, setFilters] = React.useState(() => { try { const saved = localStorage.getItem(FILTERS_STORAGE_KEY); if (saved) return JSON.parse(saved); } catch (e) {} return { query: "", displayStatus: "all", deliveryType: "" }; }); // Persist filters to localStorage on every change React.useEffect(() => { try { localStorage.setItem(FILTERS_STORAGE_KEY, JSON.stringify(filters)); } catch (e) {} }, [filters]); const [selectedOrderGroupId, setSelectedOrderGroupId] = React.useState(null); const [isLoading, setIsLoading] = React.useState(enabled); const [loadError, setLoadError] = React.useState(""); const [isSavingDeliveryChoice, setIsSavingDeliveryChoice] = React.useState(false); const [isSavingDriverAssignment, setIsSavingDriverAssignment] = React.useState(false); const [isSavingStatusChange, setIsSavingStatusChange] = React.useState(false); const loadLiveData = React.useCallback(async (showLoading = true) => { if (showLoading) { setIsLoading(true); } setLoadError(""); if (!enabled) { setOrderGroups([]); setIsLoading(false); return; } // Single-group mode: load only the requested group (avoids pulling all // 430 groups with their full source_orders JSON — 2.6MB — for a detail view). if (groupId) { const singleResult = await fetchOrderGroupById(groupId); if (!singleResult) { return; } if (singleResult.error) { setLoadError(singleResult.error?.message || "Не удалось загрузить группу доставки"); setOrderGroups([]); setIsLoading(false); return; } setOrderGroups(singleResult.data ? [singleResult.data] : []); setIsLoading(false); return; } const groupsResult = await fetchOrderGroups({ details }); if (!groupsResult) { return; } if (groupsResult.error) { setLoadError(groupsResult.error?.message || "Не удалось загрузить группы доставки"); setOrderGroups([]); setIsLoading(false); return; } setOrderGroups(groupsResult.data || []); setIsLoading(false); }, [enabled, details, groupId]); // Initial load React.useEffect(() => { let cancelled = false; const doLoad = async () => { setIsLoading(true); await loadLiveData(true); if (cancelled) return; }; if (enabled) doLoad(); else { setOrderGroups([]); setIsLoading(false); } return () => { cancelled = true; }; }, [loadLiveData, enabled]); // Refetch on window focus to keep data fresh across tabs/pages React.useEffect(() => { if (!enabled) return undefined; const handleFocus = () => { loadLiveData(false); // silent refetch, no loading spinner }; window.addEventListener("focus", handleFocus); return () => window.removeEventListener("focus", handleFocus); }, [loadLiveData, enabled]); React.useEffect(() => { if (!orderGroups.length) { setSelectedOrderGroupId(null); return; } if (!selectedOrderGroupId || !orderGroups.some((group) => group.id === selectedOrderGroupId)) { setSelectedOrderGroupId(orderGroups[0].id); } }, [orderGroups, selectedOrderGroupId]); const statusCounts = React.useMemo(() => { const counts = {}; orderGroups.forEach((group) => { const status = getOrderGroupDisplayStatusValue(group); counts[status] = (counts[status] || 0) + 1; }); return counts; }, [orderGroups]); const statusOptions = React.useMemo(() => ORDER_GROUP_DISPLAY_STATUS_OPTIONS.map((opt) => ({ ...opt, count: opt.value === "all" ? orderGroups.length : (statusCounts[opt.value] || 0), })), [statusCounts, orderGroups] ); const filteredOrderGroups = React.useMemo( () => filterOrderGroups(orderGroups, filters), [filters, orderGroups], ); const visibleOrderGroups = filteredOrderGroups; const selectedOrderGroup = visibleOrderGroups.find((group) => group.id === selectedOrderGroupId) || orderGroups.find((group) => group.id === selectedOrderGroupId) || visibleOrderGroups[0] || null; const orderGroupsByDate = React.useMemo(() => groupOrderGroupsByDate(orderGroups), [orderGroups]); const deliveryGroupBuckets = React.useMemo(() => buildOrderGroupBuckets(orderGroups), [orderGroups]); const saveManualDeliveryChoice = React.useCallback(async ({ orderGroupId, deliveryDate, deliveryTime, deliveryType, deliveryAddress, pickupDate, pickupTimeSlot, }) => { setIsSavingDeliveryChoice(true); try { /* Demo mode removed */ const result = await updateOrderGroupDeliveryChoice({ orderGroupId, deliveryDate, deliveryTime, deliveryType, deliveryAddress, pickupDate, pickupTimeSlot, }); if (result.error) { return { success: false, error: getErrorMessage(result.error, "Не удалось сохранить согласование доставки"), }; } setOrderGroups((currentGroups) => currentGroups.map((group) => (group.id === orderGroupId ? result.data : group)), ); return { success: true, data: result.data }; } catch (error) { return { success: false, error: getErrorMessage(error, "Не удалось сохранить согласование доставки"), }; } finally { setIsSavingDeliveryChoice(false); } }, []); const assignDriver = React.useCallback(async ({ orderGroupId, driverId }) => { setIsSavingDriverAssignment(true); try { const result = await assignDriverToOrderGroup({ orderGroupId, driverId }); if (result.error) { return { success: false, error: getErrorMessage(result.error, "Не удалось назначить водителя"), }; } setOrderGroups((currentGroups) => currentGroups.map((group) => (group.id === orderGroupId ? result.data : group)), ); return { success: true, data: result.data }; } catch (error) { return { success: false, error: getErrorMessage(error, "Не удалось назначить водителя"), }; } finally { setIsSavingDriverAssignment(false); } }, []); const changeDeliveryStatus = React.useCallback(async ({ orderGroupId, status, details, shipmentData }) => { setIsSavingStatusChange(true); try { const result = await updateDeliveryStatus({ orderGroupId, status, details, shipmentData }); if (result.error) { return { success: false, error: getErrorMessage(result.error, "Не удалось обновить статус"), }; } setOrderGroups((currentGroups) => currentGroups.map((group) => (group.id === orderGroupId ? result.data : group)), ); return { success: true, data: result.data }; } catch (error) { return { success: false, error: getErrorMessage(error, "Не удалось обновить статус"), }; } finally { setIsSavingStatusChange(false); } }, []); const onSaveShipmentData = React.useCallback(async ({ orderGroupId, shipmentData }) => { try { const result = await saveShipmentData({ orderGroupId, shipmentData }); if (result.error) { return { success: false, error: getErrorMessage(result.error, "Не удалось сохранить данные отгрузки"), }; } setOrderGroups((currentGroups) => currentGroups.map((group) => (group.id === orderGroupId ? result.data : group)), ); return { success: true, data: result.data }; } catch (error) { return { success: false, error: getErrorMessage(error, "Не удалось сохранить данные отгрузки"), }; } }, []); return { orderGroups, allOrderGroups: orderGroups, filteredOrderGroups, visibleOrderGroups, selectedOrderGroup, selectedOrderGroupId, setSelectedOrderGroupId, filters, setFilters, statusOptions, orderGroupsByDate, deliveryGroupBuckets, saveManualDeliveryChoice, assignDriver, changeDeliveryStatus, saveShipmentData: onSaveShipmentData, isSavingDeliveryChoice, isSavingDriverAssignment, isSavingStatusChange, isLoading, loadError, refetch: loadLiveData, }; };