selected nested sidebar
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
import {Collapse, ListItem, ListItemButton, ListItemText} from "@mui/material";
|
||||
import SidebarSubitem from "@/core/components/SidebarSubitem";
|
||||
import {useState} from "react";
|
||||
|
||||
const SidebarListItem = ({menuItem, dispatch}) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
return(
|
||||
<>
|
||||
<ListItem>
|
||||
<ListItemText primary={menuItem.id}></ListItemText>
|
||||
<ListItemButton onClick={() => {
|
||||
dispatch({type: "COLLAPSE_MENU", id: menuItem.id})
|
||||
setOpen(!open)
|
||||
}}>click</ListItemButton>
|
||||
</ListItem>
|
||||
<Collapse in={menuItem.showSubitems}>
|
||||
{
|
||||
menuItem.hasSubitems ? (menuItem.Subitems.map((subitem,index)=>{
|
||||
return(
|
||||
<SidebarSubitem dispatch={dispatch} key={index} subitem={subitem} open={open}/>
|
||||
)
|
||||
})) : null
|
||||
}
|
||||
</Collapse>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default SidebarListItem
|
||||
46
src/core/components/SidebarListItems.jsx
Normal file
46
src/core/components/SidebarListItems.jsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import {Collapse, ListItem, ListItemButton, ListItemIcon, ListItemText} from "@mui/material";
|
||||
import { ExpandLess, ExpandMore } from '@mui/icons-material';
|
||||
import WifiIcon from '@mui/icons-material/Wifi';
|
||||
import SidebarSubitems from "@/core/components/SidebarSubitems";
|
||||
|
||||
const SidebarListItems = ({menuItem, dispatch}) => {
|
||||
return(
|
||||
<>
|
||||
<ListItem disablePadding sx={{p : 0}}>
|
||||
<ListItemButton sx={{
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.2)',
|
||||
},
|
||||
}} selected={menuItem.selected} onClick={() => {
|
||||
dispatch({type: "COLLAPSE_MENU", id: menuItem.id})
|
||||
}}>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: 0,
|
||||
justifyContent: "center",
|
||||
color: "primary.main",
|
||||
width: 40,
|
||||
height: 24,
|
||||
pr: 2,
|
||||
}}
|
||||
>
|
||||
{menuItem.icon}
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={menuItem.id} />
|
||||
{menuItem.hasSubitems ? (menuItem.showSubitems ? <ExpandLess /> : <ExpandMore />) : null }
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
<Collapse in={menuItem.showSubitems} timeout="auto" mountOnEnter={true} unmountOnExit={true}>
|
||||
{
|
||||
menuItem.hasSubitems ? (menuItem.Subitems.map((subitem,index)=>{
|
||||
return(
|
||||
<SidebarSubitems dispatch={dispatch} key={index} subitem={subitem}/>
|
||||
)
|
||||
})) : null
|
||||
}
|
||||
</Collapse>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default SidebarListItems
|
||||
201
src/core/components/SidebarMenu.jsx
Normal file
201
src/core/components/SidebarMenu.jsx
Normal file
@@ -0,0 +1,201 @@
|
||||
"use client"
|
||||
import {List} from "@mui/material";
|
||||
import SidebarListItems from "@/core/components/SidebarListItems";
|
||||
import {useEffect, useReducer, useState} from "react";
|
||||
import {usePathname} from 'next/navigation'
|
||||
import SecurityIcon from '@mui/icons-material/Security';
|
||||
import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard";
|
||||
import AssessmentIcon from '@mui/icons-material/Assessment';
|
||||
import AirlineSeatReclineNormalIcon from "@mui/icons-material/AirlineSeatReclineNormal";
|
||||
import RepartitionIcon from '@mui/icons-material/Repartition';
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: "hello",
|
||||
type: "menu",
|
||||
route: "/hello",
|
||||
icon: <SecurityIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
selected: false,
|
||||
Subitems: [
|
||||
{
|
||||
id: "amin",
|
||||
route: "/s",
|
||||
icon: <SpaceDashboardIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
firstName: "amin",
|
||||
lastName: "ali",
|
||||
Subitems: [
|
||||
{
|
||||
id: "shahrokh", shahrokh: "shahrokh", type: "page", selected: false, route: "/dashbssoard", icon: <AssessmentIcon sx={{width: 'inherit', height: 'inherit'}}/>
|
||||
},
|
||||
{
|
||||
id: "shasdasdsahrokh", shahrokh: "shahroasdasdkh", type: "page", selected: false, route: "/dashboardsd", icon: <AirlineSeatReclineNormalIcon sx={{width: 'inherit', height: 'inherit'}}/>
|
||||
}
|
||||
],
|
||||
hasSubitems: true,
|
||||
showSubitems: false,
|
||||
type: "menu",
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
id: "amir",
|
||||
route: "/dashboarsad",
|
||||
icon: <RepartitionIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
firstName: "amir",
|
||||
lastName: "akbar",
|
||||
hasSubitems: false,
|
||||
showSubitems: false,
|
||||
selected: false,
|
||||
type: "page",
|
||||
},
|
||||
],
|
||||
hasSubitems: true,
|
||||
showSubitems: false
|
||||
},
|
||||
{
|
||||
id: "hi",
|
||||
type: "menu",
|
||||
icon: <SecurityIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
route: "/hi",
|
||||
selected: false,
|
||||
Subitems: [
|
||||
{
|
||||
id: "ali",
|
||||
route: "/dashboardss",
|
||||
firstName: "ali",
|
||||
lastName: "ali",
|
||||
icon: <SecurityIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
hasSubitems: false,
|
||||
showSubitems: false,
|
||||
type: "page",
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
id: "akbar",
|
||||
route: "/akbar",
|
||||
firstName: "akbar",
|
||||
icon: <SecurityIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
lastName: "akbar",
|
||||
hasSubitems: false,
|
||||
showSubitems: false,
|
||||
type: "page",
|
||||
selected: false,
|
||||
},
|
||||
],
|
||||
hasSubitems: true,
|
||||
showSubitems: false
|
||||
},
|
||||
{
|
||||
id: "hoo",
|
||||
type: "page",
|
||||
route: "/dashboard",
|
||||
icon: <SecurityIcon sx={{width: 'inherit', height: 'inherit'}}/>,
|
||||
selected: false,
|
||||
hasSubitems: false,
|
||||
showSubitems: false
|
||||
}
|
||||
]
|
||||
|
||||
function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case "COLLAPSE_MENU":
|
||||
return state.map((item) => action.id == item.id ? {
|
||||
...item, showSubitems: !item.showSubitems
|
||||
} : item)
|
||||
case "COLLAPSE_SUB_ITEMS" :
|
||||
return state.map((item) => {
|
||||
return item.hasSubitems ? {
|
||||
...item, Subitems: item.Subitems.map((subitem) => action.id === subitem.id ? {
|
||||
...subitem, showSubitems: !subitem.showSubitems
|
||||
} : subitem)
|
||||
} : item
|
||||
})
|
||||
case "COLLAPSE_SUB_SECOND_ITEMS" :
|
||||
return state.map((item) => {
|
||||
return item.hasSubitems ? {
|
||||
...item, Subitems: item.Subitems.map((subitem) => {
|
||||
return subitem.hasSubitems ? {
|
||||
...subitem,
|
||||
Subitems: subitem.Subitems.map((secondSubitem) => action.id === secondSubitem.id ? {
|
||||
...secondSubitem, showSubitems: !secondSubitem.showSubitems
|
||||
} : secondSubitem)
|
||||
} : subitem
|
||||
})
|
||||
} : item
|
||||
})
|
||||
case "SELECTED":
|
||||
return state.map((item) => {
|
||||
return item.type === "page" ? {
|
||||
...item, selected: action.route === item.route,showSubitems: item.route === action.route
|
||||
} : item.Subitems && Array.isArray(item.Subitems) ? {
|
||||
...item, Subitems: item.Subitems.map((subitem) => {
|
||||
return subitem.type === "page" ? {
|
||||
...subitem, selected: action.route === subitem.route,showSubitems: subitem.route === action.route
|
||||
} : subitem.Subitems && Array.isArray(subitem.Subitems) ? {
|
||||
...subitem, Subitems: subitem.Subitems.map((secondSubItem) => ({
|
||||
...secondSubItem, selected: secondSubItem.route === action.route
|
||||
})),showSubitems: subitem.Subitems.some((secondSubItem) => secondSubItem.route === action.route),
|
||||
} : subitem
|
||||
}),showSubitems: item.Subitems.some((subitem) => subitem.showSubitems),
|
||||
} : item
|
||||
});
|
||||
// case "SELECTED":
|
||||
// return state.map((item) => {
|
||||
// return item.type === "page" ? {
|
||||
// ...item,
|
||||
// selected: action.route === item.route
|
||||
// } : item.Subitems && Array.isArray(item.Subitems) ? {
|
||||
// ...item,
|
||||
// Subitems: item.Subitems.map((subitem) => {
|
||||
// const updatedSubitem = subitem.type === "page" ? {
|
||||
// ...subitem,
|
||||
// selected: action.route === subitem.route
|
||||
// } : subitem.Subitems && Array.isArray(subitem.Subitems) ? {
|
||||
// ...subitem,
|
||||
// Subitems: subitem.Subitems.map((secondSubItem) => ({
|
||||
// ...secondSubItem,
|
||||
// selected: secondSubItem.route === action.route
|
||||
// })),
|
||||
// showSubitems: subitem.Subitems.some((secondSubItem) => secondSubItem.route === action.route),
|
||||
// } : subitem;
|
||||
//
|
||||
// console.log("Updated subitem:", updatedSubitem); // Log the updated subitem
|
||||
// return updatedSubitem;
|
||||
// }),
|
||||
// showSubitems: item.Subitems.some((subitem) => subitem.showSubitems),
|
||||
// } : item
|
||||
// });
|
||||
|
||||
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
const SidebarMenu = () => {
|
||||
const [menuItems, dispatch] = useReducer(reducer, data);
|
||||
const pathname = usePathname()
|
||||
const [selectedKey, setSelectedKey] = useState(null);
|
||||
useEffect(() => {
|
||||
dispatch({type: "SELECTED", route: pathname});
|
||||
setSelectedKey(pathname);
|
||||
}, [pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
selectedKey && document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({
|
||||
behavior: "smooth", block: "center"
|
||||
});
|
||||
}, [selectedKey]);
|
||||
|
||||
return (
|
||||
<List disablePadding>
|
||||
{
|
||||
menuItems.map((menuItem) => {
|
||||
return (
|
||||
<SidebarListItems dispatch={dispatch} key={menuItem.id} menuItem={menuItem}/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</List>
|
||||
)
|
||||
}
|
||||
export default SidebarMenu
|
||||
@@ -1,33 +0,0 @@
|
||||
import {Collapse, List, ListItem, ListItemButton, ListItemText} from "@mui/material";
|
||||
import {useState} from "react";
|
||||
|
||||
const SidebarSubitem = ({subitem, dispatch}) => {
|
||||
const [subOpen, setSubOpen] = useState(false)
|
||||
return(
|
||||
<>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText primary={subitem.firstName} />
|
||||
{subitem.hasSubitems ? (<ListItemButton onClick={() => {
|
||||
dispatch({type: "Subitem1", id: subitem.id})
|
||||
setSubOpen(!subOpen)
|
||||
}}>click</ListItemButton>) : null}
|
||||
</ListItem>
|
||||
</List>
|
||||
{
|
||||
subitem.hasSubitems ? (subitem.Subitems.map((subSubitem,index) => {
|
||||
return(
|
||||
<Collapse key={index} in={subitem.showSubitems}>
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText primary={subSubitem.shahrokh} />
|
||||
</ListItem>
|
||||
</List>
|
||||
</Collapse>
|
||||
)
|
||||
})) : null
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default SidebarSubitem
|
||||
74
src/core/components/SidebarSubitems.jsx
Normal file
74
src/core/components/SidebarSubitems.jsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import {Collapse, List, ListItem, ListItemButton, ListItemIcon, ListItemText} from "@mui/material";
|
||||
import {ExpandLess, ExpandMore} from "@mui/icons-material";
|
||||
|
||||
const SidebarSubitems = ({subitem, dispatch}) => {
|
||||
return (
|
||||
<>
|
||||
<List disablePadding>
|
||||
<ListItem disablePadding>
|
||||
<ListItemButton sx={{
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
},
|
||||
}} selected={subitem.selected} onClick={() => {
|
||||
dispatch({type: "COLLAPSE_SUB_ITEMS", id: subitem.id})
|
||||
}}>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: 0,
|
||||
justifyContent: "center",
|
||||
color: "primary.main",
|
||||
width: 40,
|
||||
height: 24,
|
||||
pr: 2,
|
||||
}}
|
||||
>
|
||||
{subitem.icon}
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={subitem.firstName}/>
|
||||
{subitem.hasSubitems ? (subitem.showSubitems ? <ExpandLess/> : <ExpandMore/>) : null
|
||||
}
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</List>
|
||||
{
|
||||
subitem.hasSubitems ? (subitem.Subitems.map((subSubitem, index) => {
|
||||
return (
|
||||
<Collapse key={index} in={subitem.showSubitems} timeout="auto" mountOnEnter={true} unmountOnExit={true}>
|
||||
<List disablePadding>
|
||||
<ListItem disablePadding>
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
dispatch({type: "COLLAPSE_SUB_SECOND_ITEMS", id: subSubitem.id})
|
||||
}}
|
||||
selected={subSubitem.selected}
|
||||
sx={{
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.05)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: 0,
|
||||
justifyContent: "center",
|
||||
color: "primary.main",
|
||||
width: 40,
|
||||
height: 24,
|
||||
pr: 2,
|
||||
}}
|
||||
>
|
||||
{subSubitem.icon}
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={subSubitem.shahrokh}/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Collapse>
|
||||
)
|
||||
})) : null
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default SidebarSubitems
|
||||
@@ -1,56 +0,0 @@
|
||||
"use client"
|
||||
import {List} from "@mui/material";
|
||||
import SidebarListItem from "@/core/components/SidebarListItem";
|
||||
import {useReducer} from "react";
|
||||
const data = [
|
||||
{
|
||||
id : "hello",
|
||||
Subitems : [
|
||||
{id : "amin",firstName : "amin", lastName:"ali",Subitems : [{id : "shahrokh",shahrokh : "shahrokh"}], hasSubitems : true, showSubitems : false},
|
||||
{id : "amir",firstName : "amir", lastName:"akbar", hasSubitems : false, showSubitems : false},
|
||||
],
|
||||
hasSubitems : true,
|
||||
showSubitems : false
|
||||
},
|
||||
{
|
||||
id : "hi",
|
||||
Subitems : [
|
||||
{id : "ali",firstName : "ali", lastName:"ali", hasSubitems : false, showSubitems : false},
|
||||
{id : "akbar",firstName : "akbar", lastName:"akbar", hasSubitems : false, showSubitems : false},
|
||||
],
|
||||
hasSubitems : true,
|
||||
showSubitems : false
|
||||
}
|
||||
]
|
||||
function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case "COLLAPSE_MENU":
|
||||
return state.map((item) => action.id == item.id ? {
|
||||
...item, showSubitems: !item.showSubitems
|
||||
} : item)
|
||||
case "Subitem1" :
|
||||
return state.map((item) => {
|
||||
return item.hasSubitems ? {...item, Subitems: item.Subitems.map((subitem) => action.id === subitem.id ? {
|
||||
...subitem, showSubitems: !subitem.showSubitems
|
||||
} : subitem)} : item
|
||||
})
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
const SidebarTest = () => {
|
||||
const [itemMenu, dispatch] = useReducer(reducer, data);
|
||||
return(
|
||||
<List sx={{maxWidth : 500}}>
|
||||
{
|
||||
itemMenu.map((menuItem) => {
|
||||
return(
|
||||
<SidebarListItem dispatch={dispatch} key={menuItem.id} menuItem={menuItem} />
|
||||
)
|
||||
})
|
||||
}
|
||||
</List>
|
||||
)
|
||||
}
|
||||
export default SidebarTest
|
||||
Reference in New Issue
Block a user