diff --git a/src/hooks/useDashboardData.ts b/src/hooks/useDashboardData.ts index 4f4ab5c..3c7b4e8 100644 --- a/src/hooks/useDashboardData.ts +++ b/src/hooks/useDashboardData.ts @@ -7,7 +7,7 @@ interface DashboardStats { totalItemsInStock: string; stockOutLast30Days: string; lowStockAlerts: string; - totalCustomers: string; + totalCustomers: string; // Added totalCustomers property } interface MonthlyActivity { @@ -22,7 +22,7 @@ export function useDashboardData() { totalItemsInStock: "0", stockOutLast30Days: "0", lowStockAlerts: "0", - totalCustomers: "0", + totalCustomers: "0", // Initialize totalCustomers }); const [monthlyActivityData, setMonthlyActivityData] = useState([]); const [loading, setLoading] = useState(true); @@ -38,7 +38,6 @@ export function useDashboardData() { await pb.admins.authWithPassword('david@wfsales.co.za', '1234567890'); console.log('Re-authenticated as admin successfully.'); } catch (authError: any) { - // Check if the error is due to abortion if (authError.name === 'AbortError') { console.log('Authentication request aborted.'); return; @@ -53,7 +52,7 @@ export function useDashboardData() { // Fetch all stock items const stockRecords = await pb.collection('stock_items').getFullList({ sort: '-created', - signal: abortSignal, // Pass the abort signal + signal: abortSignal, }); let calculatedTotalStockValue = 0; @@ -63,7 +62,7 @@ export function useDashboardData() { stockRecords.forEach((item: any) => { calculatedTotalStockValue += (item.quantity * item.cost_price); calculatedTotalItemsInStock += item.quantity; - if (item.quantity < 10) { // Define low stock threshold as < 10 + if (item.quantity < 10) { calculatedLowStockAlerts++; } }); @@ -72,7 +71,7 @@ export function useDashboardData() { const thirtyDaysAgo = subDays(new Date(), 30).toISOString(); const bookOutRecordsLast30Days = await pb.collection('book_out_records').getFullList({ filter: `date_booked_out >= "${thirtyDaysAgo}"`, - signal: abortSignal, // Pass the abort signal + signal: abortSignal, }); let calculatedStockOutLast30Days = 0; @@ -81,7 +80,10 @@ export function useDashboardData() { }); // Fetch total customers - const totalCustomers = await pb.collection('customers').getTotal(); + const totalCustomersRecord = await pb.collection('customers').getFirstListItem('', { + signal: abortSignal, + }); + const totalCustomers = totalCustomersRecord.total; setStats({ totalStockValue: new Intl.NumberFormat("en-ZA", { @@ -96,8 +98,8 @@ export function useDashboardData() { // --- Monthly Activity Data for Charts --- const now = new Date(); - const currentYearStart = startOfYear(now); // Start of the current year - const currentMonthEnd = startOfMonth(now); // Start of the current month (for interval end) + const currentYearStart = startOfYear(now); + const currentMonthEnd = startOfMonth(now); const monthsInterval = eachMonthOfInterval({ start: currentYearStart, @@ -107,14 +109,14 @@ export function useDashboardData() { const monthlyDataMap = new Map(); monthsInterval.forEach(month => { - const monthKey = format(month, 'MMM'); // e.g., 'Jan', 'Feb' + const monthKey = format(month, 'MMM'); monthlyDataMap.set(monthKey, { stockIn: 0, stockOut: 0 }); }); - // Process stock items for 'stockIn' (based on creation date) + // Process stock items for 'stockIn' stockRecords.forEach((item: any) => { const createdDate = new Date(item.created); - if (createdDate >= currentYearStart) { // Filter by current year start + if (createdDate >= currentYearStart) { const monthKey = format(createdDate, 'MMM'); if (monthlyDataMap.has(monthKey)) { const current = monthlyDataMap.get(monthKey)!; @@ -124,15 +126,15 @@ export function useDashboardData() { } }); - // Process all book out records for 'stockOut' - const allBookOutRecords = await pb.collection('book_out_records').getFullList({ + // Fetch all book out records for 'stockOut' + const allBookOutRecords = await pb.collection('book_out_records').getFullList({ // Declared allBookOutRecords here sort: '-created', - signal: abortSignal, // Pass the abort signal + signal: abortSignal, }); allBookOutRecords.forEach((record: any) => { const bookedOutDate = new Date(record.date_booked_out); - if (bookedOutDate >= currentYearStart) { // Filter by current year start + if (bookedOutDate >= currentYearStart) { const monthKey = format(bookedOutDate, 'MMM'); if (monthlyDataMap.has(monthKey)) { const current = monthlyDataMap.get(monthKey)!; @@ -142,7 +144,6 @@ export function useDashboardData() { } }); - // Convert map to array, maintaining chronological order const sortedMonthlyData: MonthlyActivity[] = monthsInterval.map(month => { const monthKey = format(month, 'MMM'); return { @@ -153,22 +154,7 @@ export function useDashboardData() { setMonthlyActivityData(sortedMonthlyData); - // Fetch total customers - const totalCustomersValue = await pb.collection('customers').getTotal(); - - setStats({ - totalStockValue: new Intl.NumberFormat("en-ZA", { - style: "currency", - currency: "ZAR", - }).format(calculatedTotalStockValue), - totalItemsInStock: calculatedTotalItemsInStock.toString(), - stockOutLast30Days: calculatedStockOutLast30Days.toString(), - lowStockAlerts: calculatedLowStockAlerts.toString(), - totalCustomers: totalCustomersValue.toString(), - }); - } catch (err: any) { - // Check if the error is due to abortion, if so, ignore it if (err.name === 'AbortError') { console.log('Dashboard data fetch aborted.'); return; @@ -186,16 +172,16 @@ export function useDashboardData() { } finally { setLoading(false); } - }, []); // Empty dependency array for useCallback to ensure fetchDashboardData is stable + }, []); useEffect(() => { const abortController = new AbortController(); fetchDashboardData(abortController.signal); return () => { - abortController.abort(); // Abort any pending requests on unmount or re-run + abortController.abort(); }; - }, [fetchDashboardData]); // Now fetchDashboardData is stable, so this won't cause a loop + }, [fetchDashboardData]); return { stats, monthlyActivityData, loading, error, refresh: fetchDashboardData }; } \ No newline at end of file