switch frontend to real API instead of mocks
This commit is contained in:
@@ -1,83 +1,164 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import type { Delivery } from '../types';
|
||||
import { deliveriesApi } from '../api';
|
||||
import type { Delivery, DeliveryStatus } from '../types';
|
||||
|
||||
interface DeliveryState {
|
||||
// Data
|
||||
deliveries: Delivery[];
|
||||
addDelivery: (delivery: Omit<Delivery, 'id' | 'createdAt' | 'updatedAt'>) => void;
|
||||
updateDelivery: (id: string, updates: Partial<Delivery>) => void;
|
||||
deleteDelivery: (id: string) => void;
|
||||
toggleStatus: (id: string) => void;
|
||||
deliveryCounts: Record<string, number>;
|
||||
|
||||
// Loading states
|
||||
isLoading: boolean;
|
||||
isLoadingCounts: boolean;
|
||||
error: string | null;
|
||||
|
||||
// Actions
|
||||
fetchDeliveriesByDate: (date: string) => Promise<void>;
|
||||
fetchDeliveryCounts: () => Promise<void>;
|
||||
addDelivery: (delivery: Omit<Delivery, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
|
||||
updateDelivery: (id: string, updates: Omit<Delivery, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
|
||||
deleteDelivery: (id: string) => Promise<void>;
|
||||
toggleStatus: (id: string, currentStatus: DeliveryStatus) => Promise<void>;
|
||||
getDeliveriesByDate: (date: string) => Delivery[];
|
||||
getDeliveriesByDateRange: (startDate: string, endDate: string) => Delivery[];
|
||||
getDeliveryCountsByDate: () => Record<string, number>;
|
||||
clearError: () => void;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'delivery-tracker-data';
|
||||
export const useDeliveryStore = create<DeliveryState>()((set, get) => ({
|
||||
// Initial state
|
||||
deliveries: [],
|
||||
deliveryCounts: {},
|
||||
isLoading: false,
|
||||
isLoadingCounts: false,
|
||||
error: null,
|
||||
|
||||
export const useDeliveryStore = create<DeliveryState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
deliveries: [],
|
||||
|
||||
addDelivery: (delivery) => {
|
||||
const now = Date.now();
|
||||
const newDelivery: Delivery = {
|
||||
...delivery,
|
||||
id: crypto.randomUUID(),
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
set((state) => ({
|
||||
deliveries: [...state.deliveries, newDelivery],
|
||||
}));
|
||||
},
|
||||
|
||||
updateDelivery: (id, updates) => {
|
||||
set((state) => ({
|
||||
deliveries: state.deliveries.map((d) =>
|
||||
d.id === id ? { ...d, ...updates, updatedAt: Date.now() } : d
|
||||
),
|
||||
}));
|
||||
},
|
||||
|
||||
deleteDelivery: (id) => {
|
||||
set((state) => ({
|
||||
deliveries: state.deliveries.filter((d) => d.id !== id),
|
||||
}));
|
||||
},
|
||||
|
||||
toggleStatus: (id) => {
|
||||
set((state) => ({
|
||||
deliveries: state.deliveries.map((d) =>
|
||||
d.id === id
|
||||
? { ...d, status: d.status === 'new' ? 'delivered' : 'new', updatedAt: Date.now() }
|
||||
: d
|
||||
),
|
||||
}));
|
||||
},
|
||||
|
||||
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: () => {
|
||||
const counts: Record<string, number> = {};
|
||||
get().deliveries.forEach((d) => {
|
||||
counts[d.date] = (counts[d.date] || 0) + 1;
|
||||
});
|
||||
return counts;
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: STORAGE_KEY,
|
||||
// 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) {
|
||||
set({
|
||||
error: err instanceof Error ? err.message : 'Failed to fetch deliveries',
|
||||
isLoading: false,
|
||||
});
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
// 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) {
|
||||
set({
|
||||
error: err instanceof Error ? err.message : 'Failed to fetch counts',
|
||||
isLoadingCounts: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 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) {
|
||||
set({
|
||||
error: err instanceof Error ? err.message : 'Failed to create delivery',
|
||||
isLoading: false,
|
||||
});
|
||||
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) {
|
||||
set({
|
||||
error: err instanceof Error ? err.message : 'Failed to update delivery',
|
||||
isLoading: false,
|
||||
});
|
||||
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) {
|
||||
set({
|
||||
error: err instanceof Error ? err.message : 'Failed to delete delivery',
|
||||
isLoading: false,
|
||||
});
|
||||
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) {
|
||||
set({
|
||||
error: err instanceof Error ? err.message : 'Failed to update status',
|
||||
isLoading: false,
|
||||
});
|
||||
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 }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user