2025-11-25 10:50:27 +01:00

138 lines
3.7 KiB
TypeScript

import React from "react";
import {
Button,
Menu,
MenuItem,
ListItemText,
ListItemIcon,
Divider,
} from "@mui/material";
import { useSelector } from "react-redux";
import { useRouter } from "next/navigation";
import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import { selectNavigationSidebar } from "@/app/redux/metadata/selectors";
import { SidebarLink } from "@/app/redux/metadata/metadataSlice";
import { resolveIcon } from "@/app/utils/iconMap";
import "./DropDown.scss";
interface Props {
onChange?: (path: string) => void;
}
export default function SidebarDropdown({ onChange }: Props) {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const [openMenus, setOpenMenus] = React.useState<Record<string, boolean>>({});
const sidebar = useSelector(selectNavigationSidebar);
const router = useRouter();
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
setOpenMenus({});
};
const toggleMenu = (title: string) => {
setOpenMenus(prev => ({ ...prev, [title]: !prev[title] }));
};
const handleNavigation = (path: string) => {
router.push(path);
onChange?.(path);
handleClose();
};
const renderMenuItem = (
link: SidebarLink,
level: number = 0
): React.ReactNode => {
const Icon = link.icon ? resolveIcon(link.icon as string) : undefined;
const hasChildren = link.children && link.children.length > 0;
const isOpen = openMenus[link.title];
const indent = level * 24;
if (hasChildren) {
return (
<React.Fragment key={link.title || link.path}>
<MenuItem
onClick={() => toggleMenu(link.title)}
sx={{
pl: `${8 + indent}px`,
}}
>
{Icon && (
<ListItemIcon sx={{ minWidth: 36 }}>
<Icon fontSize="small" />
</ListItemIcon>
)}
<ListItemText primary={link.title} />
{isOpen ? (
<KeyboardArrowDownIcon fontSize="small" />
) : (
<KeyboardArrowRightIcon fontSize="small" />
)}
</MenuItem>
{isOpen &&
link.children?.map(child => renderMenuItem(child, level + 1))}
</React.Fragment>
);
}
return (
<MenuItem
key={link.path}
onClick={() => handleNavigation(link.path)}
sx={{
pl: `${8 + indent}px`,
}}
>
{Icon && (
<ListItemIcon sx={{ minWidth: 36 }}>
<Icon fontSize="small" />
</ListItemIcon>
)}
<ListItemText primary={link.title} />
</MenuItem>
);
};
return (
<div>
<Button
variant="outlined"
onClick={handleClick}
sx={{ minWidth: 200, justifyContent: "space-between" }}
>
Navigate To
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
</Button>
<Menu
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "sidebar-dropdown-button",
}}
PaperProps={{
style: {
maxHeight: 400,
width: "250px",
},
}}
>
<MenuItem disabled>
<ListItemText primary="Select a page" />
</MenuItem>
<Divider />
<div className="sidebar-dropdown__container">
{sidebar?.map(link => renderMenuItem(link))}
</div>
</Menu>
</div>
);
}