Как сделать чтобы когда navbar сворачивается/разворачивается отображение другого компонента корректным?
Нужно сделать отображение другого компонента, например формы заполнения корректным. Ибо navbar может перекрывать его и т.п. Это надо как-то передавать состояние navbar или как?
Еще проблема, когда открывается navbar то элементы (categories) смещаются чуть ниже...
Код компонента navbar:
import React, { useState, useEffect } from "react";
import {
CssBaseline,
Drawer,
List,
ListItemButton,
ListItemIcon,
ListItemText,
Typography,
Box,
Collapse,
Divider,
Button,
} from "@mui/material";
import ShareIcon from '@mui/icons-material/Share';
import CalendarMonthIcon from '@mui/icons-material/CalendarMonth';
import QueryStatsIcon from '@mui/icons-material/QueryStats';
import {
ExpandLess,
ExpandMore,
Liquor as LiquorIcon,
LibraryBooks as LibraryBooksIcon,
Settings as SettingsIcon,
Logout as LogoutIcon,
} from "@mui/icons-material";
import { createTheme, ThemeProvider } from "@mui/material/styles";
const Navbar = () => {
const [isExpanded, setIsExpanded] = useState(false);
const [openCategories, setOpenCategories] = useState({});
const [activeTab, setActiveTab] = useState("");
const drawerWidthCollapsed = 80;
const drawerWidthExpanded = 300;
const darkTheme = createTheme({
palette: {
mode: "dark",
primary: {
main: "#313131",
},
secondary: {
main: "#f990d8",
},
},
typography: {
fontFamily: "JetBrains Sans, Helvetica, Arial, sans-serif",
},
});
const categories = [
{
title: "Администрирование",
items: [
{ text: "Аналитика", icon: <QueryStatsIcon /> },
{ text: "Расписание", icon: <CalendarMonthIcon /> },
{
text: "Отчётность",
icon: <LibraryBooksIcon />,
subItems: ["Текущая смена", "Бар"],
},
],
},
{
title: "Управление",
items: [
{
text: "Бар",
icon: <LiquorIcon />,
subItems: ["Лимиты", "Склад"],
},
{
text: "Интеграции",
icon: <ShareIcon />,
subItems: ["Telegram", "Колесо фортуны"],
},
{
text: "Настройки",
icon: <SettingsIcon />,
subItems: ["Сотрудники", "Расписание"],
},
],
},
];
const toggleCategory = (index) => {
setOpenCategories((prevState) => ({
...prevState,
[index]: !prevState[index],
}));
};
const handleTabClick = (tabName) => {
setActiveTab(tabName);
};
useEffect(() => {
if (!isExpanded) {
setOpenCategories({});
}
}, [isExpanded]);
const handleLogout = () => {
console.log("Logout clicked");
};
return (
<ThemeProvider theme={darkTheme}>
<CssBaseline />
<Drawer
variant="permanent"
anchor="left"
onMouseEnter={() => setIsExpanded(true)}
onMouseLeave={() => setIsExpanded(false)}
sx={{
width: isExpanded ? drawerWidthExpanded : drawerWidthCollapsed,
transition: "width 0.3s ease",
[`& .MuiDrawer-paper`]: {
width: isExpanded ? drawerWidthExpanded : drawerWidthCollapsed,
boxSizing: "border-box",
backgroundColor: darkTheme.palette.background.default,
color: darkTheme.palette.text.primary,
overflowX: "hidden",
transition: "width 0.3s ease",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
height: "100vh",
},
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
minHeight: "80px", // Минимальная высота для блока с логотипом
padding: "16px",
marginBottom: "20px",
}}
>
<Typography
variant="h4"
noWrap
sx={{
fontWeight: 600,
letterSpacing: "1px",
fontSize: "24px",
display: "flex",
alignItems: "center",
gap: isExpanded ? "8px" : "0px",
transition: "gap 0.3s ease",
}}
>
<span
style={{
background: "linear-gradient(to right, #30cfd0, #90caf9)",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
fontSize: isExpanded ? "42px" : "32px",
transition: "font-size 0.3s ease",
}}
>
{isExpanded ? "Serve" : "S"}
</span>
{isExpanded && (
<span
style={{
background: "linear-gradient(to right, #f76c6c, #fcb69f)",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
fontSize: "24px",
position: "relative",
top: "-10px",
}}
>
{`{Report}`}
</span>
)}
</Typography>
</Box>
<List sx={{ padding: "24px", flexGrow: 1, overflowY: "auto" }}>
{categories.map((category, catIndex) => (
<div key={catIndex}>
{isExpanded && (
<Typography
variant="h6"
sx={{
fontSize: "12px",
padding: "8px 16px",
fontWeight: "350",
color: darkTheme.palette.text.secondary,
marginBottom: "2px",
}}
>
{category.title}
</Typography>
)}
<Divider sx={{ marginBottom: "8px" }} />
{category.items.map((item, index) => (
<div key={index}>
<ListItemButton
onClick={() => {
handleTabClick(item.text);
if (item.subItems) {
toggleCategory(`${catIndex}-${index}`);
}
}}
sx={{
marginBottom: "12px",
borderRadius: "12px",
justifyContent: isExpanded ? "flex-start" : "center",
padding: isExpanded ? "8px 12px" : "8px",
backgroundColor: activeTab === item.text ? "#2c2c2c" : "transparent",
"&:hover": {
backgroundColor: darkTheme.palette.primary.main,
color: "#fff",
},
}}
>
<ListItemIcon
sx={{
color: "inherit",
minWidth: isExpanded ? "30px" : "unset",
display: "flex",
justifyContent: "center",
}}
>
{item.icon}
</ListItemIcon>
<Box
sx={{
overflow: "hidden",
height: isExpanded ? "auto" : "0px",
display: isExpanded ? "block" : "none",
opacity: isExpanded ? 1 : 0,
transition: "opacity 0.3s ease, height 0.3s ease",
}}
>
<ListItemText primary={item.text} />
</Box>
{item.subItems &&
isExpanded &&
(openCategories[`${catIndex}-${index}`] ? (
<ExpandLess />
) : (
<ExpandMore />
))}
</ListItemButton>
{item.subItems && (
<Collapse
in={openCategories[`${catIndex}-${index}`]}
timeout="auto"
unmountOnExit
sx={{
"& .MuiListItemButton-root": {
opacity: openCategories[`${catIndex}-${index}`] ? 1 : 0,
transform: openCategories[`${catIndex}-${index}`] ? "translateY(0)" : "translateY(-10px)",
transition: "opacity 0.3s ease, transform 0.3s ease",
},
}}
>
<List component="div" disablePadding>
{item.subItems.map((subItem, subIndex) => (
<ListItemButton
key={subIndex}
sx={{
pl: 4,
borderRadius: "8px",
margin: "4px 8px",
"&:hover": {
backgroundColor: "#2c2c2c",
},
}}
>
<ListItemText primary={subItem} />
</ListItemButton>
))}
</List>
</Collapse>
)}
</div>
))}
</div>
))}
</List>
<Box
sx={{
position: "absolute",
bottom: 0,
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
padding: "16px",
}}
>
<Button
variant="text"
color="secondary"
startIcon={isExpanded ? <LogoutIcon /> : null}
onClick={handleLogout}
sx={{
color: "#ff4f4f",
justifyContent: isExpanded ? "flex-start" : "center",
width: isExpanded ? "100%" : "auto",
padding: isExpanded ? "8px 12px" : "8px",
"&:hover": {
backgroundColor: "rgba(255,116,116,0.15)",
},
transition: "all 0.3s ease",
}}
>
{isExpanded ? "Выйти" : <LogoutIcon />}
</Button>
</Box>
</Drawer>
</ThemeProvider>
);
};
export default Navbar;