feat: Unify navigation with consistent header and centered bottom menu
- Removed duplicate MobileNav AppBar from desktop view - Added unified header bar across all screen sizes (mobile + desktop) - Positioned connection status on left, user menu on right in header - Centered bottom navigation menu on desktop (30% width with 20px margin) - Hidden floating voice button on desktop (using center button instead) - Updated voice command button to pink color (#FF69B4) matching design - Added rounded corners to desktop bottom navigation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -62,12 +62,9 @@ export const AppShell = ({ children }: AppShellProps) => {
|
||||
flexDirection: 'column',
|
||||
minHeight: '100vh',
|
||||
bgcolor: 'background.default',
|
||||
pb: { xs: '64px', md: 0 }, // Space for tab bar on mobile
|
||||
pb: '64px', // Space for tab bar on both mobile and desktop
|
||||
}}>
|
||||
{!isMobile && <MobileNav />}
|
||||
|
||||
{/* Mobile Header Bar */}
|
||||
{isMobile && (
|
||||
{/* Header Bar - Both Mobile and Desktop */}
|
||||
<Box
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
@@ -180,49 +177,6 @@ export const AppShell = ({ children }: AppShellProps) => {
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Connection Status & Presence Indicator - Desktop Only */}
|
||||
{!isMobile && (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
top: 16,
|
||||
right: 16,
|
||||
zIndex: 1200,
|
||||
display: 'flex',
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<Tooltip title={isConnected ? t('connection.syncActive') : t('connection.syncDisconnected')}>
|
||||
<Chip
|
||||
icon={isConnected ? <Wifi /> : <WifiOff />}
|
||||
label={isConnected ? t('connection.live') : t('connection.offline')}
|
||||
size="small"
|
||||
color={isConnected ? 'success' : 'default'}
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
boxShadow: 1,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
||||
{isConnected && presence.count > 1 && (
|
||||
<Tooltip title={t('connection.familyMembersOnline', { count: presence.count })}>
|
||||
<Chip
|
||||
icon={<People />}
|
||||
label={presence.count}
|
||||
size="small"
|
||||
color="primary"
|
||||
sx={{
|
||||
fontWeight: 600,
|
||||
boxShadow: 1,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Container
|
||||
maxWidth={isTablet ? 'md' : 'lg'}
|
||||
@@ -230,13 +184,13 @@ export const AppShell = ({ children }: AppShellProps) => {
|
||||
flex: 1,
|
||||
px: { xs: 2, md: 3 },
|
||||
py: 3,
|
||||
pt: { xs: '64px', md: 3 }, // Add top padding for header bar on mobile
|
||||
pt: '64px', // Add top padding for header bar on both mobile and desktop
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
|
||||
{isMobile && <TabBar />}
|
||||
<TabBar />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { BottomNavigation, BottomNavigationAction, Paper, Fab, Box } from '@mui/material';
|
||||
import { BottomNavigation, BottomNavigationAction, Paper, Fab, Box, IconButton } from '@mui/material';
|
||||
import {
|
||||
Home,
|
||||
Timeline,
|
||||
@@ -33,10 +33,13 @@ export const TabBar = () => {
|
||||
aria-label="Primary navigation"
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
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}
|
||||
>
|
||||
@@ -50,6 +53,7 @@ export const TabBar = () => {
|
||||
showLabels
|
||||
sx={{
|
||||
height: 64,
|
||||
borderRadius: { xs: 0, md: 2 },
|
||||
'& .MuiBottomNavigationAction-root': {
|
||||
minWidth: 60,
|
||||
'&.Mui-selected': {
|
||||
@@ -60,7 +64,7 @@ export const TabBar = () => {
|
||||
>
|
||||
{tabs.map((tab) => {
|
||||
if (tab.value === 'voice') {
|
||||
// Center voice button placeholder
|
||||
// Center voice button
|
||||
return (
|
||||
<Box
|
||||
key="voice-placeholder"
|
||||
@@ -70,7 +74,28 @@ export const TabBar = () => {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<IconButton
|
||||
aria-label="voice command"
|
||||
onClick={() => {
|
||||
const voiceButton = document.querySelector('[aria-label="voice input"]') as HTMLButtonElement;
|
||||
if (voiceButton) {
|
||||
voiceButton.click();
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
bgcolor: '#FF69B4',
|
||||
color: 'white',
|
||||
width: 48,
|
||||
height: 48,
|
||||
'&:hover': {
|
||||
bgcolor: '#FF1493',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Mic />
|
||||
</IconButton>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
@@ -85,7 +110,7 @@ export const TabBar = () => {
|
||||
</BottomNavigation>
|
||||
</Paper>
|
||||
|
||||
{/* Voice Command Floating Button - Centered */}
|
||||
{/* Voice Command Floating Button - Mobile Only */}
|
||||
<Fab
|
||||
color="secondary"
|
||||
aria-label="voice command"
|
||||
@@ -97,6 +122,7 @@ export const TabBar = () => {
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
display: { xs: 'flex', md: 'none' },
|
||||
position: 'fixed',
|
||||
bottom: 40,
|
||||
left: '50%',
|
||||
@@ -104,9 +130,9 @@ export const TabBar = () => {
|
||||
zIndex: 1100,
|
||||
width: 56,
|
||||
height: 56,
|
||||
bgcolor: 'secondary.main',
|
||||
bgcolor: '#FF69B4',
|
||||
'&:hover': {
|
||||
bgcolor: 'secondary.dark',
|
||||
bgcolor: '#FF1493',
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -323,7 +323,7 @@ export function VoiceFloatingButton() {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Floating button positioned in bottom-right - Hidden on mobile since we have TabBar center button */}
|
||||
{/* Floating button positioned in bottom-right - Hidden on desktop since we have TabBar center button */}
|
||||
<Tooltip title="Voice Command (Beta)" placement="left">
|
||||
<Fab
|
||||
color="primary"
|
||||
@@ -335,7 +335,7 @@ export function VoiceFloatingButton() {
|
||||
bottom: 24,
|
||||
right: 24,
|
||||
zIndex: 1000,
|
||||
display: { xs: 'none', md: 'flex' }, // Hide on mobile (xs) and small screens, show on medium+
|
||||
display: 'none', // Hidden - using TabBar center button instead
|
||||
}}
|
||||
>
|
||||
<MicIcon />
|
||||
|
||||
Reference in New Issue
Block a user