A
Anonymous

Main Layout for React Applications with Material-UI

This is code for my list const MainLayout = ({ data, children }) => { const theme = useTheme(); const [open, setOpen] = useState(false); const [selectedMenu, setSelectedMenu] = useState(null); const [openSubmenu, setOpenSubmenu] = useState(null); const [anchorEl, setAnchorEl] = useState(null); const {empleado, user} = useLogin() const { isLogged } = useLogin(state => state); const logout = useLogin(state => state.logout); const handleDrawerOpen = () => { setOpen(true); }; const handleDrawerClose = () => { setOpen(false); }; const handleMenuSelect = (menuId) => { if (menuId === openSubmenu) { setOpenSubmenu(null); } else { setOpenSubmenu(menuId); } setSelectedMenu(menuId); }; const handleMenuClick = (event) => { setAnchorEl(event.currentTarget); }; const handleMenuClose = () => { setAnchorEl(null); }; const handleLogout = () => { // Implementa la lógica de logout aquí logout(); handleMenuClose(); }; const handleThemeChange = () => { // Implementa la lógica para cambiar el tema aquí handleMenuClose(); }; const filteredMenuItems = (menuItems) => { if (!user || !user.roles) return []; // Si no hay usuario o roles, no se muestra nada const userRoles = user.roles.map(item=>item.name); return menuItems.filter(item => { // Filtrar los elementos principales const hasRole = item.roles ? item.roles.some(role => userRoles.includes(role)) : true; if (item.children) { // Filtrar los submenús} item.children = item.children.filter(child => child.roles.some(role => userRoles.includes(role)) ); } return hasRole && (!item.children || item.children.length > 0); }); }; return ( <Box sx={{ display: 'flex' }}> <CssBaseline /> <AppBar position="fixed" open={open} style={{backgroundColor: '#c60000'}}> <Toolbar> <IconButton color="inherit" aria-label="open drawer" onClick={handleDrawerOpen} edge="start" sx={{ marginRight: 5, ...(open && { display: 'none' }), }} > <MenuIcon /> </IconButton> <Typography variant="subtitle1" noWrap component="div"> Grupo Sur Forms </Typography> <IconButton color="inherit" aria-label="menu" aria-controls="menu-appbar" aria-haspopup="true" onClick={handleMenuClick} sx={{ marginLeft: 'auto', }} > {iconComponents['PersonIcon']} </IconButton> <Menu id="menu-appbar" anchorEl={anchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={Boolean(anchorEl)} onClose={handleMenuClose} > <MenuItem>{empleado?.full_name}</MenuItem> <MenuItem onClick={handleLogout}>Logout</MenuItem> <MenuItem onClick={handleThemeChange}>Cambiar tema</MenuItem> </Menu> </Toolbar> </AppBar> <Drawer variant="permanent" open={open}> <DrawerHeader> <IconButton onClick={handleDrawerClose}> {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />} </IconButton> </DrawerHeader> <Divider /> <List> {data && filteredMenuItems(data.user).map((item) => ( <React.Fragment key={item.id}> {item.children ? ( <React.Fragment> <ListItem button onClick={() => handleMenuSelect(item.id)} selected={selectedMenu === item.id} > <ListItemIcon>{iconComponents[item.icon]}</ListItemIcon> <ListItemText primary={item.title} /> </ListItem> <Collapse in={selectedMenu === item.id} timeout="auto" unmountOnExit> <List component="div" disablePadding> {item.children.map((child) => ( <ListItem key={child.id} button sx={{ pl: 4 }} onClick={() => handleMenuSelect(child.id)} selected={selectedMenu === child.id} component={Link} // Usamos Link de react-router-dom to={child.path} // Usamos "to" en lugar de "href" > <ListItemIcon>{iconComponents[child.icon]}</ListItemIcon> <ListItemText primary={child.title} /> </ListItem> ))} </List> </Collapse> </React.Fragment> ) : ( <ListItem button onClick={() => handleMenuSelect(item.id)} selected={selectedMenu === item.id} component={Link} // Usamos Link de react-router-dom to={item.path} // Usamos "to" en lugar de "href" > <ListItemIcon>{iconComponents[item.icon]}</ListItemIcon> <ListItemText primary={item.title} /> </ListItem> )} </React.Fragment> ) )} </List> </Drawer> <Box component="main" sx={{ flexGrow: 1, p: 10 }}> {children} </Box> </Box>

Prompt
Component Preview

About

Discover the React MainLayout component built with Material-UI, featuring a responsive sidebar, user menu, and role-based navigation for your web app.

Share

Last updated 1 month ago