marketing/src/hooks/useCartPolling.ts

92 lines
3.1 KiB
TypeScript
Raw Normal View History

2026-08-24 10:07:16 +00:00
import {Dispatch, SetStateAction, useEffect, useRef} from 'react';
import { getCartUpdates } from '../api/promoApi';
import { normalizeProductImage } from '../utils/product';
import type { Product } from '../types/cart';
interface UseCartPollingParams {
enabled: boolean;
onProductsChange: Dispatch<SetStateAction<Product[]>>;
onComplete: () => void;
onLoadingChange: (isLoading: boolean) => void;
setDisplayText: Dispatch<SetStateAction<string>>;
}
export function useCartPolling({
enabled,
onProductsChange,
onComplete,
onLoadingChange,
setDisplayText,
}: UseCartPollingParams) {
const timeoutRef = useRef<number | null>(null);
useEffect(() => {
if (!enabled) return;
let cancelled = false;
async function tick() {
try {
onLoadingChange(true);
const update = await getCartUpdates();
if (cancelled) return;
if (update.status === 'complete') {
onLoadingChange(false);
onComplete();
return;
}
if (update.status === 'waiting') {
setDisplayText('Брок бегает по супермаркету...')
return;
}
if (update.status === 'clear') {
const nextProducts = update.payload?.chunk?.map(product => normalizeProductImage(product)) ?? [];
onProductsChange(nextProducts);
}
if (update.status === 'data') {
const chunk = update.payload?.chunk?.map(product => normalizeProductImage(product)) ?? [];
onProductsChange(current => {
const next = [...current];
chunk.forEach(product => {
const index = next.findIndex(item => item.name === product.name);
if (index === -1) {
next.push(product);
} else {
next[index] = {
...next[index],
n: next[index].n + product.n,
};
}
});
return next;
});
setDisplayText('Брок закинул пару товаров...')
}
timeoutRef.current = window.setTimeout(tick, 3000);
} catch (error) {
setDisplayText('Ищем Брока...')
timeoutRef.current = window.setTimeout(tick, 3000);
}
}
tick();
return () => {
cancelled = true;
if (timeoutRef.current) {
window.clearTimeout(timeoutRef.current);
}
};
}, [enabled, onComplete, onLoadingChange, onProductsChange]);
}