diff --git a/src/components/StockActivityChart.tsx b/src/components/StockActivityChart.tsx
index 0896436..fa4a4f6 100644
--- a/src/components/StockActivityChart.tsx
+++ b/src/components/StockActivityChart.tsx
@@ -1,17 +1,18 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
-
-const data = [
- { name: 'Jan', stockIn: 400, stockOut: 240 },
- { name: 'Feb', stockIn: 300, stockOut: 139 },
- { name: 'Mar', stockIn: 200, stockOut: 980 },
- { name: 'Apr', stockIn: 278, stockOut: 390 },
- { name: 'May', stockIn: 189, stockOut: 480 },
- { name: 'Jun', stockIn: 239, stockOut: 380 },
- { name: 'Jul', stockIn: 349, stockOut: 430 },
-];
+import { useDashboardData } from '@/hooks/useDashboardData';
const StockActivityChart = () => {
+ const { monthlyActivityData, loading, error } = useDashboardData();
+
+ if (loading) {
+ return Loading chart data...;
+ }
+
+ if (error) {
+ return Error loading chart: {error};
+ }
+
return (
@@ -19,7 +20,7 @@ const StockActivityChart = () => {
-
+
diff --git a/src/components/StockChart.tsx b/src/components/StockChart.tsx
index 4d92d25..c313af8 100644
--- a/src/components/StockChart.tsx
+++ b/src/components/StockChart.tsx
@@ -1,17 +1,18 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
-
-const data = [
- { name: 'Jan', stockIn: 4000, stockOut: 2400 },
- { name: 'Feb', stockIn: 3000, stockOut: 1398 },
- { name: 'Mar', stockIn: 2000, stockOut: 9800 },
- { name: 'Apr', stockIn: 2780, stockOut: 3908 },
- { name: 'May', stockIn: 1890, stockOut: 4800 },
- { name: 'Jun', stockIn: 2390, stockOut: 3800 },
- { name: 'Jul', stockIn: 3490, stockOut: 4300 },
-];
+import { useDashboardData } from '@/hooks/useDashboardData';
const StockChart = () => {
+ const { monthlyActivityData, loading, error } = useDashboardData();
+
+ if (loading) {
+ return Loading chart data...;
+ }
+
+ if (error) {
+ return Error loading chart: {error};
+ }
+
return (
@@ -19,7 +20,7 @@ const StockChart = () => {
-
+
diff --git a/src/hooks/useDashboardData.ts b/src/hooks/useDashboardData.ts
index 4bc9088..ac031f0 100644
--- a/src/hooks/useDashboardData.ts
+++ b/src/hooks/useDashboardData.ts
@@ -1,6 +1,6 @@
import { useState, useEffect, useCallback } from "react";
import pb from "@/lib/pocketbase";
-import { subDays } from "date-fns";
+import { subDays, format, startOfMonth, eachMonthOfInterval } from "date-fns";
interface DashboardStats {
totalStockValue: string;
@@ -9,6 +9,12 @@ interface DashboardStats {
lowStockAlerts: string;
}
+interface MonthlyActivity {
+ name: string; // Month name, e.g., 'Jan'
+ stockIn: number;
+ stockOut: number;
+}
+
export function useDashboardData() {
const [stats, setStats] = useState({
totalStockValue: "R0.00",
@@ -16,6 +22,7 @@ export function useDashboardData() {
stockOutLast30Days: "0",
lowStockAlerts: "0",
});
+ const [monthlyActivityData, setMonthlyActivityData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
@@ -42,12 +49,12 @@ export function useDashboardData() {
// Fetch book out records for the last 30 days
const thirtyDaysAgo = subDays(new Date(), 30).toISOString();
- const bookOutRecords = await pb.collection('book_out_records').getFullList({
+ const bookOutRecordsLast30Days = await pb.collection('book_out_records').getFullList({
filter: `date_booked_out >= "${thirtyDaysAgo}"`,
});
let calculatedStockOutLast30Days = 0;
- bookOutRecords.forEach((record: any) => {
+ bookOutRecordsLast30Days.forEach((record: any) => {
calculatedStockOutLast30Days += record.quantity;
});
@@ -60,6 +67,63 @@ export function useDashboardData() {
stockOutLast30Days: calculatedStockOutLast30Days.toString(),
lowStockAlerts: calculatedLowStockAlerts.toString(),
});
+
+ // --- Monthly Activity Data for Charts ---
+ const now = new Date();
+ const twelveMonthsAgo = subDays(now, 365); // Roughly 12 months ago
+ const monthsInterval = eachMonthOfInterval({
+ start: startOfMonth(twelveMonthsAgo),
+ end: startOfMonth(now),
+ });
+
+ const monthlyDataMap = new Map();
+
+ monthsInterval.forEach(month => {
+ const monthKey = format(month, 'MMM'); // e.g., 'Jan', 'Feb'
+ monthlyDataMap.set(monthKey, { stockIn: 0, stockOut: 0 });
+ });
+
+ // Process stock items for 'stockIn' (based on creation date)
+ stockRecords.forEach((item: any) => {
+ const createdDate = new Date(item.created);
+ if (createdDate >= twelveMonthsAgo) {
+ const monthKey = format(createdDate, 'MMM');
+ if (monthlyDataMap.has(monthKey)) {
+ const current = monthlyDataMap.get(monthKey)!;
+ current.stockIn += item.quantity;
+ monthlyDataMap.set(monthKey, current);
+ }
+ }
+ });
+
+ // Process all book out records for 'stockOut'
+ const allBookOutRecords = await pb.collection('book_out_records').getFullList({
+ sort: '-created',
+ });
+
+ allBookOutRecords.forEach((record: any) => {
+ const bookedOutDate = new Date(record.date_booked_out);
+ if (bookedOutDate >= twelveMonthsAgo) {
+ const monthKey = format(bookedOutDate, 'MMM');
+ if (monthlyDataMap.has(monthKey)) {
+ const current = monthlyDataMap.get(monthKey)!;
+ current.stockOut += record.quantity;
+ monthlyDataMap.set(monthKey, current);
+ }
+ }
+ });
+
+ // Convert map to array, maintaining chronological order
+ const sortedMonthlyData: MonthlyActivity[] = monthsInterval.map(month => {
+ const monthKey = format(month, 'MMM');
+ return {
+ name: monthKey,
+ ...monthlyDataMap.get(monthKey),
+ };
+ });
+
+ setMonthlyActivityData(sortedMonthlyData);
+
} catch (err) {
console.error("Failed to fetch dashboard data:", err);
setError("Failed to load dashboard data.");
@@ -69,6 +133,7 @@ export function useDashboardData() {
stockOutLast30Days: "0",
lowStockAlerts: "0",
});
+ setMonthlyActivityData([]);
} finally {
setLoading(false);
}
@@ -78,5 +143,5 @@ export function useDashboardData() {
fetchDashboardStats();
}, [fetchDashboardStats]);
- return { stats, loading, error, refresh: fetchDashboardStats };
+ return { stats, monthlyActivityData, loading, error, refresh: fetchDashboardStats };
}
\ No newline at end of file