Files
maternal-app/maternal-web/components/layouts/TabBar/TabBar.tsx
Andrei b0ac2f71df
Some checks failed
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
feat: Add advanced analytics UI components in frontend
- Add comprehensive API client methods for all advanced analytics endpoints
- Create CircadianRhythmCard component for sleep pattern visualization
- Create AnomalyAlertsPanel for anomaly detection and alerts
- Create GrowthPercentileChart with WHO/CDC percentiles
- Create CorrelationInsights for activity correlations
- Create TrendAnalysisChart with predictions
- Add advanced analytics page with all new components
- Add UI component library (shadcn/ui) setup
- Add navigation link to advanced analytics from insights page

All advanced analytics features are now accessible from the frontend UI.
2025-10-06 11:46:05 +00:00

121 lines
3.8 KiB
TypeScript

'use client';
import { usePathname, useRouter } from 'next/navigation';
import { useState } from 'react';
import { BottomNavigation, BottomNavigationAction, Paper, Fab, Box, IconButton } from '@mui/material';
import {
Home,
Timeline,
Insights,
Chat,
Mic,
} from '@mui/icons-material';
import { useTranslation } from '@/hooks/useTranslation';
export const TabBar = () => {
const { t } = useTranslation('common');
const router = useRouter();
const pathname = usePathname();
const [voiceOpen, setVoiceOpen] = useState(false);
const tabs = [
{ label: t('navigation.home'), icon: <Home />, value: '/' },
{ label: t('navigation.track'), icon: <Timeline />, value: '/track' },
{ label: '', icon: null, value: 'voice' }, // Placeholder for center button
{ label: t('navigation.insights'), icon: <Insights />, value: pathname.startsWith('/analytics') ? pathname : '/insights' },
{ label: t('navigation.aiChat'), icon: <Chat />, value: '/ai-assistant' },
];
return (
<>
<Paper
component="nav"
aria-label="Primary navigation"
sx={{
position: 'fixed',
bottom: { xs: 0, md: 20 },
left: { xs: 0, md: '50%' },
right: { xs: 0, md: 'auto' },
transform: { xs: 'none', md: 'translateX(-50%)' },
width: { xs: '100%', md: '30%' },
zIndex: 1000,
borderRadius: { xs: 0, md: 2 },
}}
elevation={3}
>
<BottomNavigation
value={pathname}
onChange={(event, newValue) => {
if (newValue !== 'voice') {
router.push(newValue);
}
}}
showLabels
sx={{
height: 64,
borderRadius: { xs: 0, md: 2 },
'& .MuiBottomNavigationAction-root': {
minWidth: 60,
'&.Mui-selected': {
color: 'primary.main',
},
},
}}
>
{tabs.map((tab) => {
if (tab.value === 'voice') {
// Center voice button - using BottomNavigationAction as wrapper to avoid prop warnings
return (
<BottomNavigationAction
key="voice-placeholder"
label=""
value="voice"
showLabel={false}
onClick={(e) => {
e.stopPropagation();
const voiceButton = document.querySelector('[aria-label="voice input"]') as HTMLButtonElement;
if (voiceButton) {
voiceButton.click();
}
}}
icon={(
<Box
aria-label="voice command"
sx={{
bgcolor: '#FF69B4',
color: 'white',
width: 48,
height: 48,
'&:hover': {
bgcolor: '#FF1493',
},
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
}}
>
<Mic />
</Box>
)}
sx={{ minWidth: 80 }}
/>
);
}
return (
<BottomNavigationAction
key={tab.value}
label={tab.label}
icon={tab.icon}
value={tab.value}
/>
);
})}
</BottomNavigation>
</Paper>
{/* Voice Command Floating Button is now centralized in layout.tsx - removed duplicate */}
</>
);
};