This commit is contained in:
seb
2026-10-14 23:24:45 +02:00
parent eb4654dfbf
commit e2a2d02cb4
8 changed files with 170 additions and 71 deletions

View File

@@ -66,19 +66,37 @@ class AppSidebar extends PureComponent {
<Box
component="nav"
sx={(theme) => ({
width: SIDEBAR_WIDTH,
width: { xs: '100%', lg: SIDEBAR_WIDTH },
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
flexDirection: { xs: 'row', lg: 'column' },
alignItems: { xs: 'center', lg: 'stretch' },
backgroundColor: theme.nav.backgroundColor || NAV_SURFACE,
background: theme.nav.background,
position: 'sticky',
top: 0,
zIndex: theme.zIndex.appBar || 1100,
alignSelf: 'flex-start',
height: 'var(--df-vh, 100vh)',
height: { xs: 52, sm: 56, lg: 'var(--df-vh, 100vh)' },
px: { xs: 1, sm: 1.5, lg: 0 },
boxSizing: 'border-box',
boxShadow: { xs: '0 2px 8px rgba(0,0,0,0.18)', lg: 'none' },
})}
>
<List disablePadding sx={{ flexGrow: 1 }}>
<List
disablePadding
sx={{
flexGrow: 1,
display: 'flex',
flexDirection: { xs: 'row', lg: 'column' },
alignItems: 'center',
height: { xs: '100%', lg: 'auto' },
overflowX: { xs: 'auto', lg: 'visible' },
scrollbarWidth: 'none',
'&::-webkit-scrollbar': { display: 'none' },
gap: { xs: 0.5, sm: 1, lg: 0 },
}}
>
{NAV_ITEMS.map(({ path, label, help, icon: Icon }) => {
const active = path === activeNav;
@@ -110,12 +128,21 @@ class AppSidebar extends PureComponent {
}
}}
sx={(theme) => ({
borderRadius: 0,
px: 1.5,
py: 1.25,
borderLeft: '3px solid transparent',
borderRadius: { xs: 1, lg: 0 },
width: { xs: 'auto', lg: '100%' },
height: { xs: '100%', lg: 'auto' },
px: { xs: 1.25, sm: 1.5 },
py: { xs: 0.75, sm: 1, lg: 1.25 },
borderLeft: { xs: 'none', lg: '3px solid transparent' },
borderBottom: { xs: '3px solid transparent', lg: 'none' },
color: theme.nav.item,
'& .MuiListItemIcon-root': { color: 'inherit' },
whiteSpace: 'nowrap',
flexShrink: 0,
'& .MuiListItemIcon-root': {
color: 'inherit',
minWidth: { xs: 'auto', lg: 36 },
mr: { xs: 0.75, lg: 0 },
},
'&:hover': {
bgcolor: theme.nav.itemHover,
color: theme.nav.itemHoverText,
@@ -124,7 +151,8 @@ class AppSidebar extends PureComponent {
bgcolor: theme.nav.itemActive,
color: theme.nav.itemActiveText,
fontWeight: 600,
borderLeftColor: theme.nav.itemActiveAccent,
borderLeftColor: { xs: 'transparent', lg: theme.nav.itemActiveAccent },
borderBottomColor: { xs: theme.nav.itemActiveAccent, lg: 'transparent' },
'&:hover': {
bgcolor: theme.nav.itemActive,
color: theme.nav.itemActiveText,
@@ -132,18 +160,28 @@ class AppSidebar extends PureComponent {
},
})}
>
<ListItemIcon sx={{ minWidth: 36 }}>
<ListItemIcon>
<HelpBadge title={label} help={help} placement="right">
<Icon />
</HelpBadge>
</ListItemIcon>
<ListItemText primary={label} />
<ListItemText
primary={label}
primaryTypographyProps={{
fontSize: { xs: '0.8rem', sm: '0.875rem' },
fontWeight: active ? 600 : 500,
noWrap: true,
}}
sx={{ m: 0 }}
/>
</ListItemButton>
);
})}
</List>
<UserMenu />
<Box sx={{ ml: { xs: 'auto', lg: 0 }, flexShrink: 0, display: 'flex', alignItems: 'center' }}>
<UserMenu />
</Box>
</Box>
);
}
@@ -187,10 +225,11 @@ class AppSubNav extends PureComponent {
return (
<Box
sx={{
width: SUB_NAV_WIDTH,
width: { xs: 0, lg: SUB_NAV_WIDTH },
display: { xs: 'none', lg: 'block' },
flexShrink: 0,
ml: 3,
mr: 2,
ml: { xs: 0, lg: 3 },
mr: { xs: 0, lg: 2 },
}}
/>
);
@@ -201,19 +240,23 @@ class AppSubNav extends PureComponent {
component="nav"
aria-label="Unternavigation"
sx={{
width: SUB_NAV_WIDTH,
width: { xs: 60, sm: 72, md: SUB_NAV_WIDTH },
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 1.5,
position: 'sticky',
top: 0,
top: { xs: 52, sm: 56, lg: 0 },
alignSelf: 'flex-start',
height: 'var(--df-vh, 100vh)',
py: 4,
ml: 3,
mr: 2,
height: {
xs: 'calc(var(--df-vh, 100vh) - 52px)',
sm: 'calc(var(--df-vh, 100vh) - 56px)',
lg: 'var(--df-vh, 100vh)',
},
py: { xs: 2, lg: 4 },
ml: { xs: 1, sm: 2, lg: 3 },
mr: { xs: 1, sm: 1.5, lg: 2 },
}}
>
{subNav.map(({ segment, label, title, help, icon: Icon }) => {
@@ -247,7 +290,7 @@ class AppSubNav extends PureComponent {
navigate(segment ? `${activeNav}/${segment}` : activeNav);
}}
sx={(theme) => ({
width: SUB_NAV_WIDTH,
width: { xs: 60, sm: 72, md: SUB_NAV_WIDTH },
py: 1,
px: 0.5,
borderRadius: 2,
@@ -271,14 +314,14 @@ class AppSubNav extends PureComponent {
})}
>
<HelpBadge title={title || label} help={help} placement="right">
<Icon sx={{ fontSize: 32 }} />
<Icon sx={{ fontSize: { xs: 24, sm: 28, md: 32 } }} />
</HelpBadge>
{label ? (
<Typography
variant="caption"
noWrap
sx={{
fontSize: '0.68rem',
fontSize: { xs: '0.62rem', sm: '0.68rem' },
fontWeight: 500,
lineHeight: 1.2,
textAlign: 'center',
@@ -303,26 +346,43 @@ export default function AppShell() {
const activeSub = activeNav ? resolveActiveSub(pathname, activeNav) : null;
return (
<Box sx={{ display: 'flex', minHeight: 'var(--df-vh, 100vh)', bgcolor: 'background.default' }}>
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column', lg: 'row' },
minHeight: 'var(--df-vh, 100vh)',
bgcolor: 'background.default',
}}
>
<AppSidebar activeNav={activeNav} navigate={navigate} />
<AppSubNav
activeNav={activeNav}
activeSub={activeSub}
navigate={navigate}
/>
<Box
component="main"
sx={(theme) => ({
flexGrow: 1,
sx={{
display: 'flex',
flexDirection: 'column',
py: 4,
pr: 3,
bgcolor: theme.nav.mainBackground,
flexDirection: 'row',
flexGrow: 1,
minWidth: 0,
})}
}}
>
<Outlet />
<AppSubNav
activeNav={activeNav}
activeSub={activeSub}
navigate={navigate}
/>
<Box
component="main"
sx={(theme) => ({
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
py: { xs: 2, md: 3, lg: 4 },
pr: { xs: 1.5, sm: 2, lg: 3 },
pl: { xs: 1.5, sm: 2, lg: 0 },
bgcolor: theme.nav.mainBackground,
minWidth: 0,
})}
>
<Outlet />
</Box>
</Box>
<ChatFab />
<ChatDrawer />