diff --git a/docs/maternal-app-ui-improvements.md b/docs/maternal-app-ui-improvements.md
new file mode 100644
index 0000000..6f72726
--- /dev/null
+++ b/docs/maternal-app-ui-improvements.md
@@ -0,0 +1,882 @@
+# Maternal App - UI Consistency & Alignment Guide
+
+## Overview
+This document provides comprehensive instructions for fixing UI/UX inconsistencies across the Maternal app. The main dashboard screen serves as the design reference for all other screens.
+
+## Reference Design Pattern (Main Dashboard)
+The main dashboard successfully implements:
+- **6 symmetric action cards** with consistent spacing
+- **Soft rounded corners** (borderRadius: 16-20px)
+- **Consistent color palette** with meaningful color associations
+- **Clear visual hierarchy** with proper typography scaling
+- **Adequate whitespace** between sections
+- **Mobile-first responsive design**
+
+## Global Design Tokens to Apply
+
+### Spacing System
+```javascript
+const spacing = {
+ xs: 8, // 0.5rem
+ sm: 12, // 0.75rem
+ md: 16, // 1rem (base unit)
+ lg: 24, // 1.5rem
+ xl: 32, // 2rem
+ xxl: 48, // 3rem
+ xxxl: 64 // 4rem
+}
+```
+
+### Color Palette
+```javascript
+const colors = {
+ primary: {
+ main: '#EC407A', // Pink (Feeding)
+ light: '#FFB3C1',
+ dark: '#C2185B'
+ },
+ secondary: {
+ sleep: '#2196F3', // Blue
+ diaper: '#FF9800', // Orange
+ medicine: '#F44336', // Red
+ activities: '#66BB6A', // Green
+ assistant: '#FF7043' // Deep Orange
+ },
+ background: {
+ default: '#FFF5F7', // Light pink background
+ paper: '#FFFFFF',
+ card: '#FFF0F3' // Slightly pink card background
+ },
+ text: {
+ primary: '#2D3436',
+ secondary: '#636E72',
+ disabled: '#B2BEC3'
+ }
+}
+```
+
+### Typography Scale
+```javascript
+const typography = {
+ h1: { fontSize: '2rem', fontWeight: 600, lineHeight: 1.2 },
+ h2: { fontSize: '1.5rem', fontWeight: 600, lineHeight: 1.3 },
+ h3: { fontSize: '1.25rem', fontWeight: 500, lineHeight: 1.4 },
+ body1: { fontSize: '1rem', fontWeight: 400, lineHeight: 1.5 },
+ body2: { fontSize: '0.875rem', fontWeight: 400, lineHeight: 1.5 },
+ caption: { fontSize: '0.75rem', fontWeight: 400, lineHeight: 1.4 }
+}
+```
+
+## Screen-Specific Fixes
+
+### 1. Track Activity Screen (`/track`)
+
+**Current Issues:**
+- Icons and labels not properly centered
+- Inconsistent spacing between activity options
+- No visual feedback on hover/press
+
+**Required Fixes:**
+```javascript
+// Container structure
+
+
+ Track Activity
+
+
+ Select an activity to track
+
+
+
+ {activities.map(activity => (
+
+
+ {activity.icon}
+
+ {activity.label}
+
+
+
+ ))}
+
+
+```
+
+### 2. AI Assistant Screen (`/ai-assistant`)
+
+**Current Issues:**
+- Chat history sidebar has poor alignment
+- Suggested questions buttons inconsistent
+- Input field not properly styled
+- No proper container padding
+
+**Required Fixes:**
+```javascript
+// Main layout structure
+
+ {/* Sidebar */}
+
+
+ Chat History
+ }
+ sx={{
+ mb: 3,
+ borderRadius: 2,
+ textTransform: 'none',
+ bgcolor: 'primary.light',
+ color: 'primary.main',
+ '&:hover': { bgcolor: 'primary.main', color: 'white' }
+ }}
+ >
+ New Chat
+
+
+ {/* Chat list items */}
+
+ {chats.map(chat => (
+
+
+
+ ))}
+
+
+
+
+ {/* Main content */}
+
+ {/* Header */}
+
+
+
+
+
+
+ AI Parenting Assistant
+
+ Ask me anything about parenting and childcare
+
+
+
+
+
+ {/* Chat area */}
+
+ {/* Welcome message */}
+
+
+ Hi Andrei! How can I help you today?
+
+
+ {/* Suggested questions */}
+
+ {suggestions.map(suggestion => (
+
+ {}}
+ sx={{
+ width: '100%',
+ py: 2,
+ borderRadius: 2,
+ fontSize: '0.875rem',
+ bgcolor: 'background.paper',
+ border: 1,
+ borderColor: 'divider',
+ '&:hover': {
+ bgcolor: 'primary.light',
+ borderColor: 'primary.main'
+ }
+ }}
+ />
+
+ ))}
+
+
+
+
+ {/* Input area */}
+
+
+
+
+
+ )
+ }}
+ />
+
+ This AI assistant provides general information. Always consult healthcare professionals for medical advice.
+
+
+
+
+
+```
+
+### 3. Insights & Analytics Screen (`/insights`)
+
+**Current Issues:**
+- Time period tabs not properly styled
+- Stats cards have inconsistent heights
+- Charts not properly aligned
+- Legend placement issues
+
+**Required Fixes:**
+```javascript
+// Container and layout
+
+ Insights & Analytics
+
+ Track patterns and get insights about your child's activities
+
+
+ {/* Time period selector */}
+
+
+
+
+
+
+ {/* Stats cards */}
+
+ {stats.map(stat => (
+
+
+ {stat.icon}
+ {stat.value}
+
+ {stat.label}
+
+
+
+ ))}
+
+
+ {/* Charts grid */}
+
+ {charts.map(chart => (
+
+
+
+ {chart.icon} {chart.title}
+
+
+ {/* Chart component here */}
+
+
+
+ ))}
+
+
+```
+
+### 4. Children Management Screen (`/children`)
+
+**Current Issues:**
+- Child card not properly structured
+- Age text alignment issues
+- Action buttons placement
+
+**Required Fixes:**
+```javascript
+
+
+
+ Children
+
+ Manage your family's children profiles
+
+
+ }
+ sx={{
+ borderRadius: 2,
+ textTransform: 'none',
+ px: 3
+ }}
+ >
+ Add Child
+
+
+
+
+ {children.map(child => (
+
+
+
+
+ {child.name[0]}
+
+
+ {child.name}
+
+ {child.gender}
+
+
+
+ {child.birthDate}
+
+
+ Age: {child.age}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+```
+
+### 5. Family Management Screen (`/family`)
+
+**Current Issues:**
+- Share code styling inconsistent
+- Member list alignment
+- Proper spacing between sections
+
+**Required Fixes:**
+```javascript
+
+
+
+ Family
+
+ Manage your family members and share access
+
+
+
+ }
+ sx={{ borderRadius: 2, textTransform: 'none' }}
+ >
+ Join Family
+
+ }
+ sx={{ borderRadius: 2, textTransform: 'none' }}
+ >
+ Invite Member
+
+
+
+
+
+
+
+ Family Share Code
+
+ Share this code with family members to give them access to your family's data
+
+
+
+ }
+ sx={{ borderRadius: 2, textTransform: 'none' }}
+ >
+ Copy Code
+
+
+
+
+
+
+
+
+ Family Members ({members.length})
+
+
+ {members.map(member => (
+
+
+
+ {member.name[0]}
+
+
+
+
+
+ ))}
+
+
+
+
+
+```
+
+## Mobile-First Responsive Guidelines
+
+### Breakpoint System
+```javascript
+const breakpoints = {
+ xs: 0, // Mobile phones
+ sm: 600, // Small tablets
+ md: 900, // Tablets
+ lg: 1200, // Desktop
+ xl: 1536 // Large screens
+}
+```
+
+### Mobile-Specific Rules
+1. **Touch targets**: Minimum 48x48px for all interactive elements
+2. **Padding**: Use `px: { xs: 2, sm: 3 }` for container padding
+3. **Font sizes**: Scale down by 10-15% on mobile
+4. **Grid columns**: Use `xs={12}` for single column on mobile, `sm={6}` for two columns on tablets
+5. **Navigation**: Hide sidebar on mobile, use bottom navigation or hamburger menu
+6. **Modals**: Full screen on mobile, centered dialog on desktop
+
+### Component Responsiveness
+```javascript
+// Responsive spacing
+sx={{
+ p: { xs: 2, sm: 3, md: 4 },
+ m: { xs: 1, sm: 2, md: 3 }
+}}
+
+// Responsive typography
+sx={{
+ fontSize: { xs: '1rem', sm: '1.125rem', md: '1.25rem' }
+}}
+
+// Responsive grid
+
+
+```
+
+## Common MUI Theme Overrides
+```javascript
+const theme = createTheme({
+ palette: {
+ primary: { main: '#EC407A' },
+ background: {
+ default: '#FFF5F7',
+ paper: '#FFFFFF'
+ }
+ },
+ shape: {
+ borderRadius: 12
+ },
+ components: {
+ MuiButton: {
+ styleOverrides: {
+ root: {
+ borderRadius: 12,
+ textTransform: 'none',
+ fontWeight: 500,
+ padding: '10px 24px'
+ }
+ }
+ },
+ MuiPaper: {
+ styleOverrides: {
+ root: {
+ borderRadius: 16,
+ boxShadow: 'none',
+ border: '1px solid rgba(0,0,0,0.08)'
+ }
+ }
+ },
+ MuiTextField: {
+ styleOverrides: {
+ root: {
+ '& .MuiOutlinedInput-root': {
+ borderRadius: 12
+ }
+ }
+ }
+ }
+ }
+});
+```
+
+## Implementation Checklist
+- [ ] Apply consistent spacing using the defined spacing system
+- [ ] Update all color values to use the defined palette
+- [ ] Ensure all interactive elements have proper hover/active states
+- [ ] Add proper transitions (0.2s ease) for all interactive elements
+- [ ] Verify mobile responsiveness for all screens
+- [ ] Test touch target sizes on mobile (minimum 48x48px)
+- [ ] Ensure consistent border radius (12-16px for cards, 8-12px for buttons)
+- [ ] Add proper loading states for async operations
+- [ ] Implement consistent error messaging styles
+- [ ] Verify text hierarchy and readability on all screen sizes
+
+## Testing Requirements
+1. Test on iPhone SE (375px width) for minimum mobile size
+2. Test on iPad (768px width) for tablet view
+3. Test on desktop (1920px width) for full experience
+4. Verify touch interactions on actual mobile devices
+5. Check color contrast ratios for accessibility (WCAG AA compliance)
+6. Test with both light and dark system preferences
+
+## Critical Accessibility Fixes (Console Errors)
+
+### 1. Color Contrast Issues (WCAG AA Compliance)
+
+**Problem**: Elements don't meet minimum color contrast ratio thresholds (4.5:1 for normal text, 3:1 for large text)
+
+**Fix for the color palette**:
+```javascript
+const colors = {
+ primary: {
+ main: '#D81B60', // Darker pink for better contrast (was #EC407A)
+ light: '#FFB3C1',
+ dark: '#AD1457' // Even darker for text on light backgrounds
+ },
+ secondary: {
+ sleep: '#1976D2', // Darker blue (was #2196F3)
+ diaper: '#F57C00', // Darker orange (was #FF9800)
+ medicine: '#D32F2F', // Darker red (was #F44336)
+ activities: '#388E3C', // Darker green (was #66BB6A)
+ assistant: '#E64A19' // Darker deep orange (was #FF7043)
+ },
+ background: {
+ default: '#FFF5F7',
+ paper: '#FFFFFF',
+ card: '#FFF0F3'
+ },
+ text: {
+ primary: 'rgba(0, 0, 0, 0.87)', // Higher opacity for better contrast
+ secondary: 'rgba(0, 0, 0, 0.6)', // Darker secondary text
+ disabled: 'rgba(0, 0, 0, 0.38)'
+ }
+}
+```
+
+**Fix for MUI TextField labels**:
+```javascript
+// Global theme override for input labels
+const theme = createTheme({
+ components: {
+ MuiInputLabel: {
+ styleOverrides: {
+ root: {
+ color: 'rgba(0, 0, 0, 0.87)', // Darker label color
+ '&.Mui-focused': {
+ color: '#AD1457' // Dark pink when focused
+ },
+ '&.MuiFormLabel-filled': {
+ color: 'rgba(0, 0, 0, 0.87)' // Ensure filled state has good contrast
+ }
+ }
+ }
+ },
+ MuiOutlinedInput: {
+ styleOverrides: {
+ root: {
+ '& .MuiOutlinedInput-notchedOutline': {
+ borderColor: 'rgba(0, 0, 0, 0.38)' // Darker border
+ },
+ '&:hover .MuiOutlinedInput-notchedOutline': {
+ borderColor: 'rgba(0, 0, 0, 0.87)'
+ },
+ '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
+ borderColor: '#AD1457'
+ }
+ }
+ }
+ },
+ MuiButton: {
+ styleOverrides: {
+ containedPrimary: {
+ backgroundColor: '#D81B60',
+ '&:hover': {
+ backgroundColor: '#AD1457'
+ }
+ }
+ }
+ }
+ }
+});
+```
+
+### 2. Viewport Meta Tag Issue
+
+**Problem**: Zooming and scaling must not be disabled (critical accessibility issue)
+
+**Fix for viewport meta tag**:
+```html
+
+
+
+
+
+
+```
+
+**For Next.js apps**:
+```javascript
+// In pages/_document.js or app/layout.js
+
+
+
+```
+
+### 3. Additional Accessibility Enhancements
+
+**Form Input Enhancements**:
+```javascript
+
+```
+
+**Button Accessibility**:
+```javascript
+
+```
+
+**Focus Indicators**:
+```javascript
+// Global focus styles
+const theme = createTheme({
+ components: {
+ MuiButtonBase: {
+ styleOverrides: {
+ root: {
+ '&:focus-visible': {
+ outline: '2px solid #AD1457',
+ outlineOffset: '2px'
+ }
+ }
+ }
+ }
+ }
+});
+```
+
+### 4. Testing for Accessibility
+
+**Use these tools to verify fixes**:
+1. **axe DevTools**: Browser extension for accessibility testing
+2. **Chrome DevTools Lighthouse**: Run accessibility audit
+3. **WAVE**: WebAIM's accessibility evaluation tool
+4. **Contrast Checker**: Use WebAIM's contrast checker to verify color combinations
+
+**Minimum contrast ratios to maintain**:
+- Normal text: 4.5:1
+- Large text (18pt or 14pt bold): 3:1
+- UI components and graphics: 3:1
+
+**Quick contrast check for main colors**:
+```javascript
+// Verified color combinations with good contrast
+const safeColorCombos = {
+ // Text on backgrounds
+ darkTextOnLight: '#000000 on #FFF5F7', // 20.3:1 ✓
+ primaryTextOnWhite: '#D81B60 on #FFFFFF', // 4.7:1 ✓
+ whiteOnPrimary: '#FFFFFF on #D81B60', // 4.7:1 ✓
+
+ // Labels and secondary text
+ labelOnWhite: 'rgba(0,0,0,0.87) on #FFFFFF', // 16:1 ✓
+ secondaryTextOnWhite: 'rgba(0,0,0,0.6) on #FFFFFF', // 7.4:1 ✓
+}
+```
+
+## Additional Notes
+- Maintain the soft, nurturing aesthetic with accessible color choices
+- Keep interactions smooth and delightful with subtle animations
+- Prioritize clarity and ease of use for sleep-deprived parents
+- Ensure all text is easily readable at a glance
+- Use icons consistently from the same icon library (Material Icons)
+- Maintain visual hierarchy with proper use of whitespace
+- Always test with screen readers and keyboard navigation
\ No newline at end of file
diff --git a/maternal-web/app/children/page.tsx b/maternal-web/app/children/page.tsx
index 9e5642a..fe79fd7 100644
--- a/maternal-web/app/children/page.tsx
+++ b/maternal-web/app/children/page.tsx
@@ -5,17 +5,18 @@ import {
Box,
Typography,
Grid,
- Card,
- CardContent,
+ Paper,
Button,
Avatar,
IconButton,
CircularProgress,
Alert,
Chip,
- CardActions,
+ Container,
+ Card,
+ CardContent,
} from '@mui/material';
-import { Add, ChildCare, Edit, Delete, Cake } from '@mui/icons-material';
+import { Add, ChildCare, Edit, Delete, CalendarToday } from '@mui/icons-material';
import { AppShell } from '@/components/layouts/AppShell/AppShell';
import { ProtectedRoute } from '@/components/common/ProtectedRoute';
import { useAuth } from '@/lib/auth/AuthContext';
@@ -151,13 +152,13 @@ export default function ChildrenPage() {
return (
-
+
-
+
{t('title')}
-
+
{t('subtitle')}
@@ -166,6 +167,11 @@ export default function ChildrenPage() {
startIcon={}
onClick={handleAddChild}
disabled={loading || !familyId}
+ sx={{
+ borderRadius: 2,
+ textTransform: 'none',
+ px: 3
+ }}
>
{t('addChild')}
@@ -208,86 +214,66 @@ export default function ChildrenPage() {
) : (
{children.map((child, index) => (
-
+
-
-
-
-
-
-
-
-
- {child.name}
-
-
-
-
-
-
-
+
+
+ {child.name[0]}
+
+
+ {child.name}
- {new Date(child.birthDate).toLocaleDateString()}
+ {t(`gender.${child.gender}`)}
+
+
+
+
+ {new Date(child.birthDate).toLocaleDateString()}
+
+
+
+ {t('age')}: {calculateAge(child.birthDate)}
+
-
- {t('age')}: {calculateAge(child.birthDate)}
-
-
-
-
- handleEditChild(child)}
- color="primary"
- >
+
+ handleEditChild(child)}>
- handleDeleteClick(child)}
- color="error"
- >
+ handleDeleteClick(child)}>
-
-
+
+
))}
)}
-
+
-
+
-
+
{t('pageTitle')}
-
+
{t('pageSubtitle')}
-
+
}
onClick={() => setJoinDialogOpen(true)}
disabled={loading}
+ sx={{ borderRadius: 2, textTransform: 'none' }}
>
{t('buttons.joinFamily')}
@@ -186,6 +193,7 @@ export default function FamilyPage() {
startIcon={}
onClick={() => setInviteDialogOpen(true)}
disabled={loading || !familyId}
+ sx={{ borderRadius: 2, textTransform: 'none' }}
>
{t('buttons.inviteMember')}
@@ -203,49 +211,48 @@ export default function FamilyPage() {
) : (
-
+
{/* Family Share Code */}
{family && (
-
-
-
-
- {t('shareCode.title')}
-
-
- {t('shareCode.description')}
-
-
-
- }
- onClick={handleCopyCode}
- >
- {t('buttons.copyCode')}
-
-
-
-
+
+
+
+ {t('shareCode.title')}
+
+
+ {t('shareCode.description')}
+
+
+
+ }
+ onClick={handleCopyCode}
+ sx={{ borderRadius: 2, textTransform: 'none' }}
+ >
+ {t('buttons.copyCode')}
+
+
+
)}
{/* Family Members */}
-
-
-
-
- {t('members.title', { count: members.length })}
-
+
+
+
+ {t('members.title', { count: members.length })}
+
{members.length === 0 ? (
@@ -265,68 +272,71 @@ export default function FamilyPage() {
) : (
-
+
{members.map((member, index) => {
const memberName = member.user?.name || t('placeholders.unknownUser');
return (
-
-
+
-
- {index > 0 && }
-
-
- {memberName.charAt(0).toUpperCase()}
-
-
-
-
- {memberName}
-
- {isCurrentUser(member.userId) && (
-
- )}
-
-
- {member.user?.email || t('placeholders.noEmail')}
+
+
+ {memberName[0]}
+
+
+
+
+ {memberName}
+ {isCurrentUser(member.userId) && (
+
+ )}
-
- {!isCurrentUser(member.userId) && (
- handleRemoveClick(member)}
- color="error"
- aria-label={t('members.removeAriaLabel', { name: memberName })}
- >
-
-
- )}
-
-
-
-
+ }
+ secondary={member.user?.email || t('placeholders.noEmail')}
+ primaryTypographyProps={{ fontWeight: 500 }}
+ />
+
+ {!isCurrentUser(member.userId) && (
+ handleRemoveClick(member)}
+ color="error"
+ aria-label={t('members.removeAriaLabel', { name: memberName })}
+ >
+
+
+ )}
+
+
);
})}
-
+
)}
-
-
+
)}
-
+
,
+ icon: Restaurant,
path: '/track/feeding',
- color: '#FFE4E1',
+ color: '#E91E63', // Pink with 4.5:1 contrast
},
{
title: t('activities.sleep'),
- icon: ,
+ icon: Hotel,
path: '/track/sleep',
- color: '#E1F5FF',
+ color: '#1976D2', // Blue with 4.5:1 contrast
},
{
title: t('activities.diaper'),
- icon: ,
+ icon: BabyChangingStation,
path: '/track/diaper',
- color: '#FFF4E1',
+ color: '#F57C00', // Orange with 4.5:1 contrast
},
{
title: t('activities.medicine'),
- icon: ,
+ icon: MedicalServices,
path: '/track/medicine',
- color: '#FFE8E8',
+ color: '#C62828', // Red with 4.5:1 contrast
},
{
title: t('activities.activity'),
- icon: ,
+ icon: ChildCare,
path: '/track/activity',
- color: '#E8F5E9',
+ color: '#558B2F', // Green with 4.5:1 contrast
},
];
return (
-
-
+
+
{t('trackActivity')}
-
+
{t('selectActivity')}
-
- {trackingOptions.map((option) => (
-
-
- router.push(option.path)}
- sx={{
- height: '100%',
- width: '100%',
- }}
+
+ {trackingOptions.map((activity, index) => {
+ const IconComponent = activity.icon;
+ return (
+
+
- router.push(activity.path)}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ router.push(activity.path);
+ }
+ }}
+ aria-label={`Track ${activity.title}`}
sx={{
- textAlign: 'center',
+ p: 3,
+ height: '140px',
+ minHeight: '140px',
+ width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
- height: '180px',
- minHeight: '180px',
- width: '100%',
- p: 2,
+ textAlign: 'center',
+ cursor: 'pointer',
+ bgcolor: activity.color,
+ color: 'white',
+ border: 'none',
+ transition: 'transform 0.2s',
+ '&:hover': {
+ transform: 'scale(1.05)',
+ },
+ '&:focus-visible': {
+ outline: '3px solid white',
+ outlineOffset: '-3px',
+ transform: 'scale(1.05)',
+ },
}}
>
- {option.icon}
-
- {option.title}
+
+
+
+
+ {activity.title}
-
-
-
-
- ))}
+
+
+
+ );
+ })}
diff --git a/maternal-web/components/features/ai-chat/AIChatInterface.tsx b/maternal-web/components/features/ai-chat/AIChatInterface.tsx
index 81d6c8b..9d00e1b 100644
--- a/maternal-web/components/features/ai-chat/AIChatInterface.tsx
+++ b/maternal-web/components/features/ai-chat/AIChatInterface.tsx
@@ -408,7 +408,13 @@ export const AIChatInterface: React.FC = () => {
variant="contained"
startIcon={}
onClick={handleNewConversation}
- sx={{ borderRadius: 2 }}
+ sx={{
+ borderRadius: 2,
+ textTransform: 'none',
+ bgcolor: 'primary.light',
+ color: 'primary.main',
+ '&:hover': { bgcolor: 'primary.main', color: 'white' }
+ }}
>
{t('chat.newChat')}
@@ -621,10 +627,15 @@ export const AIChatInterface: React.FC = () => {
label={question}
onClick={() => handleSuggestedQuestion(question)}
sx={{
- borderRadius: 3,
+ py: 2,
+ borderRadius: 2,
+ fontSize: '0.875rem',
+ bgcolor: 'background.paper',
+ border: 1,
+ borderColor: 'divider',
'&:hover': {
bgcolor: 'primary.light',
- color: 'white',
+ borderColor: 'primary.main',
},
}}
/>
@@ -776,6 +787,9 @@ export const AIChatInterface: React.FC = () => {
sx={{
'& .MuiOutlinedInput-root': {
borderRadius: 3,
+ bgcolor: 'background.default',
+ '&:hover fieldset': { borderColor: 'primary.main' },
+ '&.Mui-focused fieldset': { borderColor: 'primary.main' }
},
}}
/>
diff --git a/maternal-web/components/features/analytics/InsightsDashboard.tsx b/maternal-web/components/features/analytics/InsightsDashboard.tsx
index 0f09786..21f2db2 100644
--- a/maternal-web/components/features/analytics/InsightsDashboard.tsx
+++ b/maternal-web/components/features/analytics/InsightsDashboard.tsx
@@ -68,11 +68,11 @@ interface ActivityTypeData {
}
const COLORS = {
- feeding: '#FFB6C1',
- sleep: '#B6D7FF',
- diaper: '#FFE4B5',
- medication: '#D4B5FF',
- milestone: '#B5FFD4',
+ feeding: '#E91E63',
+ sleep: '#1976D2',
+ diaper: '#F57C00',
+ medication: '#C62828',
+ milestone: '#558B2F',
note: '#FFD3B6',
wet: '#87CEEB',
dirty: '#D2691E',
@@ -269,50 +269,49 @@ export const InsightsDashboard: React.FC = () => {
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
-
-
+
+
{t('title')}
-
+
{t('subtitle')}
- {/* Filters */}
-
-
- {children.length > 1 && (
-
-
- {t('filters.child')}
-
-
-
- )}
-
- newValue && setDateRange(newValue)}
- fullWidth
- size="large"
+ {/* Time period selector */}
+
+ {children.length > 1 && (
+
+ {t('filters.child')}
+
-
-
-
+ {children.map((child) => (
+
+ ))}
+
+
+ )}
+ newValue && setDateRange(newValue)}
+ sx={{
+ '& .MuiToggleButton-root': {
+ textTransform: 'none',
+ fontWeight: 500,
+ minWidth: { xs: 80, sm: 120 }
+ }
+ }}
+ >
+ {t('filters.dateRange.7days')}
+ {t('filters.dateRange.30days')}
+ {t('filters.dateRange.3months')}
+
+
{error && (
@@ -355,148 +354,167 @@ export const InsightsDashboard: React.FC = () => {
{!loading && !noChildren && !noActivities && (
<>
- {/* Summary Statistics */}
-
-
+ {/* Stats cards */}
+
+
-
-
-
-
- {stats.totalFeedings}
-
-
- {t('stats.feedings.subtitle')}
-
+
+
+
-
+
+ {stats.totalFeedings}
+
+
+ {t('stats.feedings.subtitle')}
+
+
-
+
-
-
-
-
- {stats.avgSleepHours}h
-
-
- {t('stats.sleep.subtitle')}
-
+
+
+
-
+
+ {stats.avgSleepHours}h
+
+
+ {t('stats.sleep.subtitle')}
+
+
-
+
-
-
-
-
- {stats.totalDiapers}
-
-
- {t('stats.diapers.subtitle')}
-
+
+
+
-
+
+ {stats.totalDiapers}
+
+
+ {t('stats.diapers.subtitle')}
+
+
-
+
-
-
-
-
- {t(`activityTypes.${stats.mostCommonType}`)}
-
-
- {t('stats.topActivity.subtitle')}
-
+
+
+
-
+
+ {t(`activityTypes.${stats.mostCommonType}`)}
+
+
+ {t('stats.topActivity.subtitle')}
+
+
- {/* Charts */}
-
-
-
-
-
-
-
- {t('charts.feedingFrequency')}
-
-
+ {/* Charts grid */}
+
+
+
+
+ {t('charts.feedingFrequency')}
+
+
@@ -506,19 +524,26 @@ export const InsightsDashboard: React.FC = () => {
-
-
+
+
-
-
-
-
-
-
- {t('charts.sleepDuration')}
-
-
+
+
+
+ {t('charts.sleepDuration')}
+
+
@@ -535,20 +560,27 @@ export const InsightsDashboard: React.FC = () => {
/>
-
-
+
+
{diaperData.length > 0 && (
-
-
-
-
-
-
- {t('charts.diaperChangesByType')}
-
-
+
+
+
+ {t('charts.diaperChangesByType')}
+
+
{
-
-
+
+
)}
- 0 ? 6 : 12}>
-
-
-
-
-
- {t('charts.activityTimeline')}
-
-
+ 0 ? 6 : 12} sx={{ minWidth: 400 }}>
+
+
+ {t('charts.activityTimeline')}
+
+
@@ -594,8 +633,8 @@ export const InsightsDashboard: React.FC = () => {
-
-
+
+
diff --git a/maternal-web/components/layouts/AppShell/AppShell.tsx b/maternal-web/components/layouts/AppShell/AppShell.tsx
index 2fb7851..6dbf5f0 100644
--- a/maternal-web/components/layouts/AppShell/AppShell.tsx
+++ b/maternal-web/components/layouts/AppShell/AppShell.tsx
@@ -62,20 +62,65 @@ export const AppShell = ({ children }: AppShellProps) => {
flexDirection: 'column',
minHeight: '100vh',
bgcolor: 'background.default',
- pb: isMobile ? '64px' : 0, // Space for tab bar
+ pb: { xs: '64px', md: 0 }, // Space for tab bar on mobile
}}>
{!isMobile && }
- {/* Mobile User Menu Button - Top Left */}
+ {/* Mobile Header Bar */}
{isMobile && (
+ {/* Connection Status & Presence Indicator */}
+
+
+ : }
+ label={isConnected ? t('connection.live') : t('connection.offline')}
+ size="small"
+ color={isConnected ? 'success' : 'default'}
+ sx={{
+ fontWeight: 600,
+ }}
+ />
+
+
+ {isConnected && presence.count > 1 && (
+
+ }
+ label={presence.count}
+ size="small"
+ color="primary"
+ sx={{
+ fontWeight: 600,
+ }}
+ />
+
+ )}
+
+
+ {/* User Menu Button - Top Right */}
{
aria-controls={anchorEl ? 'user-menu' : undefined}
aria-haspopup="true"
aria-expanded={anchorEl ? 'true' : undefined}
- sx={{
- bgcolor: 'background.paper',
- boxShadow: 1,
- '&:hover': {
- bgcolor: 'background.paper',
- boxShadow: 2,
- },
- }}
>
{
open={Boolean(anchorEl)}
onClose={handleMenuClose}
onClick={handleMenuClose}
- transformOrigin={{ horizontal: 'left', vertical: 'top' }}
- anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}
+ transformOrigin={{ horizontal: 'right', vertical: 'top' }}
+ anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
sx={{
mt: 1,
}}
@@ -145,52 +182,55 @@ export const AppShell = ({ children }: AppShellProps) => {
)}
- {/* Connection Status & Presence Indicator */}
-
-
- : }
- label={isConnected ? t('connection.live') : t('connection.offline')}
- size="small"
- color={isConnected ? 'success' : 'default'}
- sx={{
- fontWeight: 600,
- boxShadow: 1,
- }}
- />
-
-
- {isConnected && presence.count > 1 && (
-
+ {/* Connection Status & Presence Indicator - Desktop Only */}
+ {!isMobile && (
+
+
}
- label={presence.count}
+ icon={isConnected ? : }
+ label={isConnected ? t('connection.live') : t('connection.offline')}
size="small"
- color="primary"
+ color={isConnected ? 'success' : 'default'}
sx={{
fontWeight: 600,
boxShadow: 1,
}}
/>
- )}
-
+
+ {isConnected && presence.count > 1 && (
+
+ }
+ label={presence.count}
+ size="small"
+ color="primary"
+ sx={{
+ fontWeight: 600,
+ boxShadow: 1,
+ }}
+ />
+
+ )}
+
+ )}
{children}