supersam/src/hooks/useOrderGroups.js

224 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react";
import { assignDriverToOrderGroup, fetchOrderGroups, updateDeliveryStatus, updateOrderGroupDeliveryChoice } from "../services/supabase/orderGroupRepository";
import {
buildOrderGroupBuckets,
filterOrderGroups,
groupOrderGroupsByDate,
ORDER_GROUP_DISPLAY_STATUS_OPTIONS,
getOrderGroupDisplayStatusValue,
} from "../services/orderGroupViews";
const getErrorMessage = (error, fallbackMessage) => {
if (!error) {
return fallbackMessage;
}
if (error instanceof Error) {
return error.message || fallbackMessage;
}
if (typeof error === "string") {
return error || fallbackMessage;
}
return error?.message || fallbackMessage;
};
export const useOrderGroups = () => {
const [orderGroups, setOrderGroups] = React.useState(() => []);
const [filters, setFilters] = React.useState({
query: "",
displayStatus: "all",
});
const [selectedOrderGroupId, setSelectedOrderGroupId] = React.useState(null);
const [isLoading, setIsLoading] = React.useState(true);
const [loadError, setLoadError] = React.useState("");
const [isSavingDeliveryChoice, setIsSavingDeliveryChoice] = React.useState(false);
React.useEffect(() => {
let cancelled = false;
const loadLiveData = async () => {
/* Demo mode removed — always use Supabase */
setIsLoading(true);
setLoadError("");
const groupsResult = await fetchOrderGroups();
if (cancelled) {
return;
}
if (groupsResult.error) {
setLoadError(groupsResult.error?.message || "Не удалось загрузить группы доставки");
setOrderGroups([]);
setIsLoading(false);
return;
}
setOrderGroups(groupsResult.data || []);
setIsLoading(false);
};
loadLiveData();
return () => {
cancelled = true;
};
}, []);
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,
}) => {
setIsSavingDeliveryChoice(true);
try {
/* Demo mode removed */
const result = await updateOrderGroupDeliveryChoice({
orderGroupId,
deliveryDate,
deliveryTime,
});
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 }) => {
setIsSavingDeliveryChoice(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 {
setIsSavingDeliveryChoice(false);
}
}, []);
const changeDeliveryStatus = React.useCallback(async ({ orderGroupId, status, details }) => {
setIsSavingDeliveryChoice(true);
try {
const result = await updateDeliveryStatus({ orderGroupId, status, details });
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);
}
}, []);
return {
orderGroups,
allOrderGroups: orderGroups,
filteredOrderGroups,
visibleOrderGroups,
selectedOrderGroup,
selectedOrderGroupId,
setSelectedOrderGroupId,
filters,
setFilters,
statusOptions,
orderGroupsByDate,
deliveryGroupBuckets,
saveManualDeliveryChoice,
assignDriver,
changeDeliveryStatus,
isSavingDeliveryChoice,
isLoading,
loadError,
};
};