Skip to content

Commit 39d0b64

Browse files
committed
feat: enhance navigation with collapsible Ability Manuals section and toggle functionality
1 parent 9ce4eb3 commit 39d0b64

1 file changed

Lines changed: 69 additions & 15 deletions

File tree

src/App.tsx

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AppShell, Group, Title, UnstyledButton, rem, useMantineColorScheme } from '@mantine/core';
1+
import { AppShell, Group, Title, UnstyledButton, Text, rem, Box, Collapse, ActionIcon } from '@mantine/core';
22
import { Outlet, Link, useLocation } from 'react-router-dom';
33
import { ThemeCustomizer } from './components/ThemeCustomizer';
44
import { ColorSchemeToggle } from './components/ColorSchemeToggle';
@@ -7,12 +7,18 @@ import { useTheme } from './context/ThemeContext';
77
import { useStyles } from './hooks/useStyles';
88
import { Prefetcher } from './components/Prefetcher';
99
import { useState } from 'react';
10+
import { useDisclosure } from '@mantine/hooks';
11+
import { IconChevronRight, IconChevronDown, IconBook, IconMenu2 } from '@tabler/icons-react';
12+
import { useAbilityManuals } from './hooks/useAbilityManuals';
1013

1114
export default function App() {
1215
const location = useLocation();
1316
const { colors } = useTheme();
1417
const { isDark } = useStyles(); // Use the isDark from useStyles which gets it from Mantine
1518
const [themeSettingsOpened, setThemeSettingsOpened] = useState(false);
19+
const [navbarCollapsed, { toggle: toggleNavbar }] = useDisclosure(false);
20+
const [manualsExpanded, { toggle: toggleManuals }] = useDisclosure(false);
21+
const { AbilityManuals } = useAbilityManuals();
1622

1723
// Generate inline styles based on theme settings
1824
const getComponentStyles = () => ({
@@ -49,16 +55,29 @@ export default function App() {
4955
}
5056
return isDark ? 'gray.3' : 'dark.6';
5157
};
52-
5358
return (
5459
<AppShell
5560
header={{ height: 60 }}
56-
navbar={{ width: 300, breakpoint: 'sm' }}
61+
navbar={{
62+
width: 300,
63+
breakpoint: 'sm',
64+
collapsed: { desktop: navbarCollapsed, mobile: true }
65+
}}
5766
padding="md"
5867
>
5968
<AppShell.Header p="md" style={styles.header}>
6069
<Group h="100%" px="md" justify="space-between">
61-
<Title order={1} size="h3" c="white">SAGA Abilities Manager</Title>
70+
<Group>
71+
<ActionIcon
72+
variant="subtle"
73+
color={isDark ? 'gray.0' : 'dark.0'}
74+
onClick={toggleNavbar}
75+
aria-label="Toggle navigation"
76+
>
77+
<IconMenu2 size={24} />
78+
</ActionIcon>
79+
<Title order={1} size="h3" c="white">SAGA Abilities Manager</Title>
80+
</Group>
6281
<ColorSchemeToggle />
6382
</Group>
6483
</AppShell.Header>
@@ -80,18 +99,53 @@ export default function App() {
8099
Abilities Library
81100
</UnstyledButton>
82101

83-
<UnstyledButton
84-
component={Link}
85-
to="/AbilityManuals"
86-
fw={location.pathname.includes('/AbilityManuals') ? 'bold' : 'normal'}
87-
c={getNavLinkColor(location.pathname.includes('/AbilityManuals'))}
88-
display="block"
89-
style={styles.navButton}
90-
>
91-
My Ability Manuals
92-
</UnstyledButton>
102+
<Box mb={rem(10)}>
103+
<Group justify="space-between" style={{ ...styles.navButton, cursor: 'pointer' }} onClick={toggleManuals}>
104+
<UnstyledButton
105+
component={Link}
106+
to="/AbilityManuals"
107+
fw={location.pathname.includes('/AbilityManuals') ? 'bold' : 'normal'}
108+
c={getNavLinkColor(location.pathname.includes('/AbilityManuals'))}
109+
style={{ flex: 1 }}
110+
>
111+
My Ability Manuals
112+
</UnstyledButton>
113+
{manualsExpanded ?
114+
<IconChevronDown size={16} color={isDark ? 'var(--mantine-color-gray-5)' : 'var(--mantine-color-dark-3)'} /> :
115+
<IconChevronRight size={16} color={isDark ? 'var(--mantine-color-gray-5)' : 'var(--mantine-color-dark-3)'} />
116+
}
117+
</Group>
118+
119+
<Collapse in={manualsExpanded}>
120+
<Box pl={20} pt={5}>
121+
{AbilityManuals.length === 0 ? (
122+
<Text size="sm" c={isDark ? 'gray.5' : 'gray.6'} fs="italic">No ability manuals</Text>
123+
) : (
124+
AbilityManuals.map((manual) => (
125+
<UnstyledButton
126+
key={manual.id}
127+
component={Link}
128+
to={`/AbilityManuals/${manual.id}`}
129+
fw={location.pathname === `/AbilityManuals/${manual.id}` ? 'bold' : 'normal'}
130+
c={getNavLinkColor(location.pathname === `/AbilityManuals/${manual.id}`)}
131+
mb={rem(5)}
132+
display="block"
133+
style={{ ...styles.navButton, fontSize: `${(colors.fontScale * 0.85)}rem` }}
134+
>
135+
<Group gap={5}>
136+
<IconBook size={14} />
137+
<Text truncate>{manual.name}</Text>
138+
</Group>
139+
</UnstyledButton>
140+
))
141+
)}
142+
</Box>
143+
</Collapse>
144+
</Box>
93145
</AppShell.Section>
94-
</AppShell.Navbar> <AppShell.Main style={styles.main}>
146+
</AppShell.Navbar>
147+
148+
<AppShell.Main style={styles.main}>
95149
{/* Invisible component that prefetches critical resources */}
96150
<Prefetcher />
97151
<Outlet />

0 commit comments

Comments
 (0)