import { useState, useCallback, useRef } from 'react'; import axios from 'axios'; interface UseQuantityAdjustmentResult { quantity: number; isLoading: boolean; error: string | null; adjustQuantity: (newQuantity: number) => Promise; resetError: () => void; } export function useQuantityAdjustment( itemId: string, initialQuantity: number ): UseQuantityAdjustmentResult { const [quantity, setQuantity] = useState(initialQuantity); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const debounceTimerRef = useRef(null); const adjustQuantity = useCallback( async (newQuantity: number) => { // Validate quantity if (typeof newQuantity !== 'number' || newQuantity < 0 || !Number.isInteger(newQuantity)) { setError('Quantity must be a non-negative integer'); return; } // Clear any pending debounce timer if (debounceTimerRef.current) { clearTimeout(debounceTimerRef.current); } // Optimistic update const previousQuantity = quantity; setQuantity(newQuantity); setError(null); setIsLoading(true); try { // Debounce: wait 100ms before sending to API await new Promise(resolve => { debounceTimerRef.current = setTimeout(resolve, 100); }); // Make API call const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8906'; const response = await axios.patch(`${backendUrl}/items/${itemId}`, { quantity: newQuantity, }); // Confirm the update with response data if (response.data && typeof response.data.quantity === 'number') { setQuantity(response.data.quantity); } } catch (err) { // Revert optimistic update on error setQuantity(previousQuantity); const errorMessage = err instanceof Error ? err.message : axios.isAxiosError(err) ? err.response?.data?.detail || 'Failed to update quantity' : 'Failed to update quantity'; setError(errorMessage); throw err; } finally { setIsLoading(false); } }, [itemId, quantity] ); const resetError = useCallback(() => { setError(null); }, []); return { quantity, isLoading, error, adjustQuantity, resetError, }; }