article and relayout

This commit is contained in:
seb
2026-07-19 19:39:07 +02:00
parent f012f27bf9
commit af9e072427
12 changed files with 878 additions and 209 deletions

View File

@@ -2,12 +2,27 @@ import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
import { NavLink } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
import { artikelQueryPath } from '../pages/artikel/artikelQuery';
const SUB_NAV_WIDTH = 80;
function isSubNavActive(pathname, basePath, segment, knownSegments) {
if (!segment) {
if (pathname === basePath || pathname === `${basePath}/`) return true;
// /artikel/:sku detail — highlight overview, not kategorien/lager
const rest = pathname.slice(basePath.length).replace(/^\//, '');
return Boolean(rest) && !rest.includes('/') && !knownSegments.has(rest);
}
const subPath = `${basePath}/${segment}`;
return pathname === subPath || pathname === `${subPath}/`;
}
export default function PageLayout({ title, subNav, basePath, children }) {
const hasSubNav = subNav?.length > 0;
const navigate = useNavigate();
const { pathname } = useLocation();
const knownSegments = new Set((subNav ?? []).map((item) => item.segment).filter(Boolean));
return (
<Box sx={{ display: 'flex', gap: 2, minHeight: 0 }}>
@@ -25,31 +40,33 @@ export default function PageLayout({ title, subNav, basePath, children }) {
>
{hasSubNav &&
subNav.map(({ segment, label, icon: Icon }) => {
const to = segment ? `${basePath}/${segment}` : basePath;
const active = isSubNavActive(pathname, basePath, segment, knownSegments);
return (
<Tooltip key={segment || 'index'} title={label} placement="right">
<IconButton
component={NavLink}
to={to}
end={!segment}
type="button"
aria-label={label}
aria-current={active ? 'page' : undefined}
disableRipple
onMouseDown={(e) => e.preventDefault()}
onClick={() => {
if (!segment && basePath === '/artikel') {
navigate(artikelQueryPath());
return;
}
navigate(segment ? `${basePath}/${segment}` : basePath);
}}
sx={(theme) => ({
width: 80,
height: 80,
borderRadius: '50%',
color: theme.palette.text.secondary,
color: active ? theme.palette.primary.main : theme.palette.text.secondary,
bgcolor: 'transparent',
'&:hover': {
bgcolor: theme.palette.action.hover,
color: theme.palette.primary.main,
},
'&.active': {
bgcolor: 'transparent',
color: theme.palette.primary.main,
},
})}
>
<Icon sx={{ fontSize: 40 }} />