From 450c18e58f00cb7e7ad26f7f5db4b302ba614690 Mon Sep 17 00:00:00 2001 From: jason Date: Sun, 8 Mar 2026 22:53:19 -0500 Subject: [PATCH] Add Dashboard page --- client/src/pages/Dashboard.jsx | 113 +++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 client/src/pages/Dashboard.jsx diff --git a/client/src/pages/Dashboard.jsx b/client/src/pages/Dashboard.jsx new file mode 100644 index 0000000..b2476fa --- /dev/null +++ b/client/src/pages/Dashboard.jsx @@ -0,0 +1,113 @@ +import { useEffect, useState } from 'react' +import { Link } from 'react-router-dom' +import { Dog, Activity, Heart, AlertCircle } from 'lucide-react' +import axios from 'axios' + +function Dashboard() { + const [stats, setStats] = useState({ + totalDogs: 0, + males: 0, + females: 0, + totalLitters: 0, + activeHeatCycles: 0 + }) + const [recentDogs, setRecentDogs] = useState([]) + const [loading, setLoading] = useState(true) + + useEffect(() => { + fetchDashboardData() + }, []) + + const fetchDashboardData = async () => { + try { + const [dogsRes, littersRes, heatCyclesRes] = await Promise.all([ + axios.get('/api/dogs'), + axios.get('/api/litters'), + axios.get('/api/breeding/heat-cycles/active') + ]) + + const dogs = dogsRes.data + setStats({ + totalDogs: dogs.length, + males: dogs.filter(d => d.sex === 'male').length, + females: dogs.filter(d => d.sex === 'female').length, + totalLitters: littersRes.data.length, + activeHeatCycles: heatCyclesRes.data.length + }) + + setRecentDogs(dogs.slice(0, 6)) + setLoading(false) + } catch (error) { + console.error('Error fetching dashboard data:', error) + setLoading(false) + } + } + + if (loading) { + return
Loading dashboard...
+ } + + return ( +
+

Dashboard

+ +
+
+ +

{stats.totalDogs}

+

Total Dogs

+

+ {stats.males} Males • {stats.females} Females +

+
+ +
+ +

{stats.totalLitters}

+

Total Litters

+
+ +
+ +

{stats.activeHeatCycles}

+

Active Heat Cycles

+
+
+ +
+

Recent Dogs

+ View All +
+ + {recentDogs.length === 0 ? ( +
+ +

No dogs registered yet

+

Start by adding your first dog to the system

+ Add Dog +
+ ) : ( +
+ {recentDogs.map(dog => ( + +
+ {dog.photo_urls && dog.photo_urls.length > 0 ? ( + {dog.name} + ) : ( + + )} +
+

{dog.name}

+

{dog.breed} • {dog.sex}

+ {dog.registration_number && ( +

{dog.registration_number}

+ )} + + ))} +
+ )} +
+ ) +} + +export default Dashboard \ No newline at end of file