diff --git a/src/components/MapTest.jsx b/src/components/MapTest.jsx new file mode 100644 index 0000000..8ccea0a --- /dev/null +++ b/src/components/MapTest.jsx @@ -0,0 +1,41 @@ +"use client" +import {Typography} from "@mui/material"; + +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 + } +] +const MapTest = () => { + const Amin = data.map((item) => { + return item.hasSubitems ? {...item, Subitems: item.Subitems.map((subitem) => true ? { + ...subitem, showSubitems: !item.showSubitems + } : subitem)} : item + }) + + + console.log(Amin) + + + return ( + <> + hello + + ) +} +export default MapTest \ No newline at end of file diff --git a/src/components/layouts/dashboard/headerWithSidebar/index.jsx b/src/components/layouts/dashboard/headerWithSidebar/index.jsx index 7591951..eeb88a3 100644 --- a/src/components/layouts/dashboard/headerWithSidebar/index.jsx +++ b/src/components/layouts/dashboard/headerWithSidebar/index.jsx @@ -4,6 +4,7 @@ import {Box, Drawer, IconButton, Paper, styled, Toolbar, Typography} from "@mui/ import MuiAppBar from '@mui/material/AppBar'; import MenuIcon from '@mui/icons-material/Menu'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import SidebarMenu from "@/core/components/SidebarMenu"; const drawerWidth = 260; @@ -82,6 +83,7 @@ const HeaderWithSidebar = ({children}) => { +
diff --git a/src/core/components/SidebarListItems.jsx b/src/core/components/SidebarListItems.jsx new file mode 100644 index 0000000..9ffcac2 --- /dev/null +++ b/src/core/components/SidebarListItems.jsx @@ -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( + <> + + { + dispatch({type: "COLLAPSE_MENU", id: menuItem.id}) + }}> + + {menuItem.icon} + + + {menuItem.hasSubitems ? (menuItem.showSubitems ? : ) : null } + + + + { + menuItem.hasSubitems ? (menuItem.Subitems.map((subitem,index)=>{ + return( + + ) + })) : null + } + + + + ) +} +export default SidebarListItems \ No newline at end of file diff --git a/src/core/components/SidebarMenu.jsx b/src/core/components/SidebarMenu.jsx new file mode 100644 index 0000000..f7589c3 --- /dev/null +++ b/src/core/components/SidebarMenu.jsx @@ -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: , + selected: false, + Subitems: [ + { + id: "amin", + route: "/s", + icon: , + firstName: "amin", + lastName: "ali", + Subitems: [ + { + id: "shahrokh", shahrokh: "shahrokh", type: "page", selected: false, route: "/dashbssoard", icon: + }, + { + id: "shasdasdsahrokh", shahrokh: "shahroasdasdkh", type: "page", selected: false, route: "/dashboardsd", icon: + } + ], + hasSubitems: true, + showSubitems: false, + type: "menu", + selected: false, + }, + { + id: "amir", + route: "/dashboarsad", + icon: , + firstName: "amir", + lastName: "akbar", + hasSubitems: false, + showSubitems: false, + selected: false, + type: "page", + }, + ], + hasSubitems: true, + showSubitems: false + }, + { + id: "hi", + type: "menu", + icon: , + route: "/hi", + selected: false, + Subitems: [ + { + id: "ali", + route: "/dashboardss", + firstName: "ali", + lastName: "ali", + icon: , + hasSubitems: false, + showSubitems: false, + type: "page", + selected: false, + }, + { + id: "akbar", + route: "/akbar", + firstName: "akbar", + icon: , + lastName: "akbar", + hasSubitems: false, + showSubitems: false, + type: "page", + selected: false, + }, + ], + hasSubitems: true, + showSubitems: false + }, + { + id: "hoo", + type: "page", + route: "/dashboard", + icon: , + 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 ( + + { + menuItems.map((menuItem) => { + return ( + + ) + }) + } + + ) +} +export default SidebarMenu \ No newline at end of file diff --git a/src/core/components/SidebarSubitems.jsx b/src/core/components/SidebarSubitems.jsx new file mode 100644 index 0000000..275befb --- /dev/null +++ b/src/core/components/SidebarSubitems.jsx @@ -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 ( + <> + + + { + dispatch({type: "COLLAPSE_SUB_ITEMS", id: subitem.id}) + }}> + + {subitem.icon} + + + {subitem.hasSubitems ? (subitem.showSubitems ? : ) : null + } + + + + { + subitem.hasSubitems ? (subitem.Subitems.map((subSubitem, index) => { + return ( + + + + { + dispatch({type: "COLLAPSE_SUB_SECOND_ITEMS", id: subSubitem.id}) + }} + selected={subSubitem.selected} + sx={{ + '&.Mui-selected': { + backgroundColor: 'rgba(0, 0, 0, 0.05)', + }, + }} + > + + {subSubitem.icon} + + + + + + + ) + })) : null + } + + ) +} +export default SidebarSubitems \ No newline at end of file