- Increase logo size (48x48 desktop, 56x56 mobile) for better visibility - Add logo as favicon - Add logo to mobile header - Move user menu to navigation bars (sidebar on desktop, bottom bar on mobile) - Fix desktop chat layout - container structure prevents voice controls cutoff - Fix mobile bottom bar - use icon-only ActionIcons instead of truncated text buttons - Hide Create Node/New Conversation buttons on mobile to save header space - Make fixed header and voice controls work properly with containers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
96 lines
2.5 KiB
TypeScript
96 lines
2.5 KiB
TypeScript
'use client';
|
|
|
|
/**
|
|
* Mobile Bottom Bar Navigation
|
|
*
|
|
* Fixed bottom navigation for mobile devices (< 768px).
|
|
* Shows three buttons: Convo, Edit, Galaxy
|
|
* Highlights the active mode based on app state machine.
|
|
*/
|
|
|
|
import { Group, Button, Paper, ActionIcon, Box } from '@mantine/core';
|
|
import { IconMessageCircle, IconEdit, IconUniverse, IconUser } from '@tabler/icons-react';
|
|
import { useSelector } from '@xstate/react';
|
|
import { useAppMachine } from '@/hooks/useAppMachine';
|
|
import { UserMenu } from '@/components/UserMenu';
|
|
|
|
export function MobileBottomBar() {
|
|
const actor = useAppMachine();
|
|
const state = useSelector(actor, (state) => state);
|
|
const send = actor.send;
|
|
|
|
const handleNavigation = (target: 'convo' | 'edit' | 'galaxy') => {
|
|
console.log('[Mobile Nav] Navigating to:', target);
|
|
|
|
if (target === 'convo') {
|
|
send({ type: 'NAVIGATE_TO_CONVO' });
|
|
} else if (target === 'edit') {
|
|
send({ type: 'NAVIGATE_TO_EDIT' });
|
|
} else if (target === 'galaxy') {
|
|
send({ type: 'NAVIGATE_TO_GALAXY' });
|
|
}
|
|
};
|
|
|
|
const isConvo = state.matches('convo');
|
|
const isEdit = state.matches('edit');
|
|
const isGalaxy = state.matches('galaxy');
|
|
|
|
console.log('[Mobile Nav] Current state:', state.value, {
|
|
isConvo,
|
|
isEdit,
|
|
isGalaxy,
|
|
});
|
|
|
|
return (
|
|
<Paper
|
|
withBorder
|
|
p="md"
|
|
radius={0}
|
|
style={{
|
|
position: 'fixed',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
zIndex: 100,
|
|
borderTop: '1px solid #dee2e6',
|
|
}}
|
|
>
|
|
<Group justify="space-around" grow>
|
|
<ActionIcon
|
|
variant={isConvo ? 'filled' : 'subtle'}
|
|
color={isConvo ? 'blue' : 'gray'}
|
|
onClick={() => handleNavigation('convo')}
|
|
size={48}
|
|
radius="md"
|
|
>
|
|
<IconMessageCircle size={24} />
|
|
</ActionIcon>
|
|
|
|
<ActionIcon
|
|
variant={isEdit ? 'filled' : 'subtle'}
|
|
color={isEdit ? 'blue' : 'gray'}
|
|
onClick={() => handleNavigation('edit')}
|
|
size={48}
|
|
radius="md"
|
|
>
|
|
<IconEdit size={24} />
|
|
</ActionIcon>
|
|
|
|
<ActionIcon
|
|
variant={isGalaxy ? 'filled' : 'subtle'}
|
|
color={isGalaxy ? 'blue' : 'gray'}
|
|
onClick={() => handleNavigation('galaxy')}
|
|
size={48}
|
|
radius="md"
|
|
>
|
|
<IconUniverse size={24} />
|
|
</ActionIcon>
|
|
|
|
<Box style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
|
<UserMenu />
|
|
</Box>
|
|
</Group>
|
|
</Paper>
|
|
);
|
|
}
|