feat: Add real data to families page and fix MUI Grid warnings
Some checks failed
ParentFlow CI/CD Pipeline / Build Docker Images (map[context:maternal-app/maternal-app-backend dockerfile:Dockerfile.production name:backend]) (push) Has been cancelled
ParentFlow CI/CD Pipeline / Build Docker Images (map[context:maternal-web dockerfile:Dockerfile.production name:frontend]) (push) Has been cancelled
ParentFlow CI/CD Pipeline / Deploy to Development (push) Has been cancelled
ParentFlow CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled
ParentFlow CI/CD Pipeline / Backend Tests (push) Has been cancelled
ParentFlow CI/CD Pipeline / Frontend Tests (push) Has been cancelled
ParentFlow CI/CD Pipeline / Security Scanning (push) Has been cancelled

Backend changes:
- Created FamiliesModule with controller and service
- Added /admin/families endpoint to list all families with members and children
- Added /admin/families/:id endpoint to get family details
- Added DELETE /admin/families/:id endpoint for family deletion
- Query families, family_members, children, and activities tables
- Calculate activity counts and last activity timestamps

Frontend changes:
- Removed all mock data from families page
- Connected to real /admin/families API endpoint
- Replaced deprecated MUI Grid v1 with CSS Grid layout
- Removed Grid import (no longer used)
- Fixed all Grid deprecation warnings (item, xs, sm, md props)
- Display real family data: members, children, activity counts
- Maintain responsive layout with CSS Grid breakpoints
This commit is contained in:
Andrei
2025-10-08 08:34:24 +00:00
parent 28a781517c
commit 0f56c68a1b
5 changed files with 309 additions and 234 deletions

View File

@@ -25,7 +25,6 @@ import {
DialogActions,
Avatar,
AvatarGroup,
Grid,
List,
ListItem,
ListItemAvatar,
@@ -90,142 +89,10 @@ export default function FamiliesPage() {
try {
setLoading(true);
const response = await apiClient.get('/admin/families');
setFamilies(response.data);
setFamilies(response.data || []);
} catch (error) {
console.error('Failed to fetch families:', error);
// Using mock data for development
setFamilies([
{
id: '1',
name: 'The Doe Family',
createdAt: '2024-01-15T10:00:00Z',
memberCount: 2,
childrenCount: 2,
activityCount: 542,
lastActivityAt: '2024-10-06T08:30:00Z',
members: [
{
id: '1',
name: 'John Doe',
email: 'john.doe@example.com',
role: 'parent',
joinedAt: '2024-01-15T10:00:00Z',
},
{
id: '2',
name: 'Jane Doe',
email: 'jane.doe@example.com',
role: 'parent',
joinedAt: '2024-01-15T10:30:00Z',
},
],
children: [
{
id: '1',
name: 'Emma Doe',
birthDate: '2022-03-15',
gender: 'female',
displayColor: '#FFB5A0',
},
{
id: '2',
name: 'Liam Doe',
birthDate: '2020-08-22',
gender: 'male',
displayColor: '#81C784',
},
],
},
{
id: '2',
name: 'The Smith Family',
createdAt: '2024-02-20T14:30:00Z',
memberCount: 2,
childrenCount: 1,
activityCount: 287,
lastActivityAt: '2024-10-05T18:45:00Z',
members: [
{
id: '3',
name: 'Jane Smith',
email: 'jane.smith@example.com',
role: 'parent',
joinedAt: '2024-02-20T14:30:00Z',
},
{
id: '4',
name: 'Bob Smith',
email: 'bob.smith@example.com',
role: 'parent',
joinedAt: '2024-02-20T15:00:00Z',
},
],
children: [
{
id: '3',
name: 'Olivia Smith',
birthDate: '2023-01-10',
gender: 'female',
displayColor: '#FFD4CC',
},
],
},
{
id: '3',
name: 'The Johnson Family',
createdAt: '2024-03-10T09:15:00Z',
memberCount: 3,
childrenCount: 3,
activityCount: 892,
lastActivityAt: '2024-09-30T12:00:00Z',
members: [
{
id: '5',
name: 'Bob Johnson',
email: 'bob.johnson@example.com',
role: 'parent',
joinedAt: '2024-03-10T09:15:00Z',
},
{
id: '6',
name: 'Alice Johnson',
email: 'alice.johnson@example.com',
role: 'parent',
joinedAt: '2024-03-10T09:30:00Z',
},
{
id: '7',
name: 'Mary (Grandma)',
email: 'mary.johnson@example.com',
role: 'caregiver',
joinedAt: '2024-03-15T10:00:00Z',
},
],
children: [
{
id: '4',
name: 'Noah Johnson',
birthDate: '2021-05-20',
gender: 'male',
displayColor: '#64B5F6',
},
{
id: '5',
name: 'Sophia Johnson',
birthDate: '2019-11-08',
gender: 'female',
displayColor: '#BA68C8',
},
{
id: '6',
name: 'Ethan Johnson',
birthDate: '2023-07-15',
gender: 'male',
displayColor: '#FFB74D',
},
],
},
]);
setFamilies([]);
} finally {
setLoading(false);
}
@@ -288,56 +155,48 @@ export default function FamiliesPage() {
</Box>
{/* Stats Cards */}
<Grid container spacing={3} sx={{ mb: 4 }}>
<Grid item xs={12} sm={6} md={3}>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Families
</Typography>
<Typography variant="h3" sx={{ color: 'primary.main' }}>
{families.length}
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Members
</Typography>
<Typography variant="h3" sx={{ color: 'success.main' }}>
{families.reduce((sum, f) => sum + f.memberCount, 0)}
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Children
</Typography>
<Typography variant="h3" sx={{ color: 'info.main' }}>
{families.reduce((sum, f) => sum + f.childrenCount, 0)}
</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Activities
</Typography>
<Typography variant="h3" sx={{ color: 'secondary.main' }}>
{families.reduce((sum, f) => sum + f.activityCount, 0)}
</Typography>
</CardContent>
</Card>
</Grid>
</Grid>
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: 3, mb: 4 }}>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Families
</Typography>
<Typography variant="h3" sx={{ color: 'primary.main' }}>
{families.length}
</Typography>
</CardContent>
</Card>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Members
</Typography>
<Typography variant="h3" sx={{ color: 'success.main' }}>
{families.reduce((sum, f) => sum + f.memberCount, 0)}
</Typography>
</CardContent>
</Card>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Children
</Typography>
<Typography variant="h3" sx={{ color: 'info.main' }}>
{families.reduce((sum, f) => sum + f.childrenCount, 0)}
</Typography>
</CardContent>
</Card>
<Card>
<CardContent>
<Typography color="text.secondary" gutterBottom>
Total Activities
</Typography>
<Typography variant="h3" sx={{ color: 'secondary.main' }}>
{families.reduce((sum, f) => sum + f.activityCount, 0)}
</Typography>
</CardContent>
</Card>
</Box>
{/* Search Bar */}
<Box sx={{ mb: 3 }}>
@@ -464,52 +323,49 @@ export default function FamiliesPage() {
<DialogContent>
{selectedFamily && (
<Box sx={{ pt: 2 }}>
<Grid container spacing={3}>
{/* Family Info */}
<Grid item xs={12}>
<Typography variant="h6" gutterBottom>
Family Information
</Typography>
<Grid container spacing={2}>
<Grid item xs={6}>
<Typography variant="subtitle2" color="text.secondary">
Family ID
</Typography>
<Typography variant="body1">{selectedFamily.id}</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="subtitle2" color="text.secondary">
Created
</Typography>
<Typography variant="body1">
{formatDate(selectedFamily.createdAt)}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="subtitle2" color="text.secondary">
Total Activities
</Typography>
<Typography variant="body1">
{selectedFamily.activityCount}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="subtitle2" color="text.secondary">
Last Activity
</Typography>
<Typography variant="body1">
{formatDate(selectedFamily.lastActivityAt)}
</Typography>
</Grid>
</Grid>
</Grid>
<Box sx={{ mb: 3 }}>
<Typography variant="h6" gutterBottom>
Family Information
</Typography>
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 2 }}>
<Box>
<Typography variant="subtitle2" color="text.secondary">
Family ID
</Typography>
<Typography variant="body1">{selectedFamily.id}</Typography>
</Box>
<Box>
<Typography variant="subtitle2" color="text.secondary">
Created
</Typography>
<Typography variant="body1">
{formatDate(selectedFamily.createdAt)}
</Typography>
</Box>
<Box>
<Typography variant="subtitle2" color="text.secondary">
Total Activities
</Typography>
<Typography variant="body1">
{selectedFamily.activityCount}
</Typography>
</Box>
<Box>
<Typography variant="subtitle2" color="text.secondary">
Last Activity
</Typography>
<Typography variant="body1">
{formatDate(selectedFamily.lastActivityAt)}
</Typography>
</Box>
</Box>
</Box>
<Grid item xs={12}>
<Divider />
</Grid>
<Divider sx={{ mb: 3 }} />
<Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' }, gap: 3 }}>
{/* Members */}
<Grid item xs={12} md={6}>
<Box>
<Typography variant="h6" gutterBottom>
Members ({selectedFamily.memberCount})
</Typography>
@@ -539,10 +395,10 @@ export default function FamiliesPage() {
</ListItem>
))}
</List>
</Grid>
</Box>
{/* Children */}
<Grid item xs={12} md={6}>
<Box>
<Typography variant="h6" gutterBottom>
Children ({selectedFamily.childrenCount})
</Typography>
@@ -569,8 +425,8 @@ export default function FamiliesPage() {
</ListItem>
))}
</List>
</Grid>
</Grid>
</Box>
</Box>
</Box>
)}
</DialogContent>