import { create } from 'zustand'; import { deliveriesApi } from '../api'; import { useToastStore } from './toastStore'; import type { Delivery, DeliveryStatus } from '../types'; interface DeliveryState { // Data deliveries: Delivery[]; deliveryCounts: Record; // Loading states isLoading: boolean; isLoadingCounts: boolean; error: string | null; // Actions fetchDeliveriesByDate: (date: string) => Promise; fetchDeliveryCounts: () => Promise; addDelivery: (delivery: Omit) => Promise; updateDelivery: (id: string, updates: Omit) => Promise; deleteDelivery: (id: string) => Promise; toggleStatus: (id: string, currentStatus: DeliveryStatus) => Promise; getDeliveriesByDate: (date: string) => Delivery[]; getDeliveriesByDateRange: (startDate: string, endDate: string) => Delivery[]; getDeliveryCountsByDate: () => Record; clearError: () => void; } export const useDeliveryStore = create()((set, get) => ({ // Initial state deliveries: [], deliveryCounts: {}, isLoading: false, isLoadingCounts: false, error: null, // Fetch deliveries for a specific date fetchDeliveriesByDate: async (date: string) => { set({ isLoading: true, error: null }); try { const deliveries = await deliveriesApi.getByDate(date); set({ deliveries, isLoading: false }); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to fetch deliveries'; set({ error: message, isLoading: false, }); useToastStore.getState().addToast(message, 'error'); } }, // Fetch delivery counts for calendar fetchDeliveryCounts: async () => { set({ isLoadingCounts: true, error: null }); try { const counts = await deliveriesApi.getCounts(); set({ deliveryCounts: counts, isLoadingCounts: false }); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to fetch counts'; set({ error: message, isLoadingCounts: false, }); useToastStore.getState().addToast(message, 'error'); } }, // Add new delivery addDelivery: async (delivery) => { set({ isLoading: true, error: null }); try { await deliveriesApi.create(delivery); // Refresh deliveries for that date await get().fetchDeliveriesByDate(delivery.date); // Refresh counts await get().fetchDeliveryCounts(); set({ isLoading: false }); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to create delivery'; set({ error: message, isLoading: false, }); useToastStore.getState().addToast(message, 'error'); throw err; } }, // Update delivery updateDelivery: async (id, updates) => { set({ isLoading: true, error: null }); try { await deliveriesApi.update(id, updates); // Refresh deliveries for that date await get().fetchDeliveriesByDate(updates.date); // Refresh counts (in case date changed) await get().fetchDeliveryCounts(); set({ isLoading: false }); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to update delivery'; set({ error: message, isLoading: false, }); useToastStore.getState().addToast(message, 'error'); throw err; } }, // Delete delivery deleteDelivery: async (id) => { set({ isLoading: true, error: null }); try { await deliveriesApi.delete(id); // Remove from local state set((state) => ({ deliveries: state.deliveries.filter((d) => d.id !== id), isLoading: false, })); // Refresh counts await get().fetchDeliveryCounts(); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to delete delivery'; set({ error: message, isLoading: false, }); useToastStore.getState().addToast(message, 'error'); throw err; } }, // Toggle delivery status toggleStatus: async (id, currentStatus) => { set({ isLoading: true, error: null }); try { const newStatus = currentStatus === 'new' ? 'delivered' : 'new'; await deliveriesApi.updateStatus(id, newStatus); // Update local state set((state) => ({ deliveries: state.deliveries.map((d) => d.id === id ? { ...d, status: newStatus, updatedAt: Date.now() } : d ), isLoading: false, })); } catch (err) { const message = err instanceof Error ? err.message : 'Failed to update status'; set({ error: message, isLoading: false, }); useToastStore.getState().addToast(message, 'error'); throw err; } }, // Getters (local filtering) getDeliveriesByDate: (date) => { return get().deliveries.filter((d) => d.date === date); }, getDeliveriesByDateRange: (startDate, endDate) => { return get().deliveries.filter((d) => { const date = d.date; return date >= startDate && date <= endDate; }); }, getDeliveryCountsByDate: () => { return get().deliveryCounts; }, clearError: () => set({ error: null }), }));