diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 7d89691..21776ae 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -15,6 +15,7 @@ "between": "میان", "online_message": "شما به اینترنت وصل هستید", "offline_message": "اتصال شما به اینترنت قطع شده است", + "routing_to": "در حال انتقال به صفحه", "socket_is_connect_message": "شما به سوکت وصل هستید", "socket_is_not_connect_message": "اتصال شما به سوکت قطع شده است", "header": { @@ -264,10 +265,10 @@ }, "CallAction": { "call_history_of": "عملیات های مربوط به تماس", - "categories" : "موضوع ها", - "subcategories" : "زیر موضوع ها", - "description" : "توضیحات تماس (اختیاری)", - "text_field_label" : "توضیحات", - "text_field_palacholder" : "لطفا توضیحات خود را وارد نمایید" + "categories": "موضوع ها", + "subcategories": "زیر موضوع ها", + "description": "توضیحات تماس (اختیاری)", + "text_field_label": "توضیحات", + "text_field_palacholder": "لطفا توضیحات خود را وارد نمایید" } } diff --git a/src/components/layouts/Dashboard/Content/index.jsx b/src/components/layouts/Dashboard/Content/index.jsx new file mode 100644 index 0000000..e3f39db --- /dev/null +++ b/src/components/layouts/Dashboard/Content/index.jsx @@ -0,0 +1,65 @@ +import LoadingHardPage from "@/core/components/LoadingHardPage"; +import RolePermissionMiddleware from "@/middlewares/RolePermission"; +import BreadCrumbs from "@/components/layouts/Dashboard/Breadcrumbs"; +import FullPageLayout from "@/layouts/FullPageLayout"; +import {useEffect, useMemo, useState} from "react"; +import sidebarMenu from "@/core/data/sidebarMenu"; +import {useRouter} from "next/router"; +import {useTranslations} from "next-intl"; + +const Content = (props) => { + const t = useTranslations() + const router = useRouter() + const [routing, setRouting] = useState(false) + const [routingItem, setRoutingItem] = useState({}) + const pageList = useMemo(() => { + const list = [] + for (const menu of sidebarMenu) { + for (const item of menu) { + if (item.type === 'menu') { + for (const subItem of item.subItem) { + list.push(subItem) + } + } else { + list.push(item) + } + } + } + + return list + }, []) + + useEffect(() => { + const handlerStartRoute = (url) => { + setRoutingItem(pageList.find(page => page.route === url)) + setRouting(true) + } + const handlerCompleteRoute = () => { + setRouting(false) + } + + router.events.on('routeChangeStart', handlerStartRoute) + router.events.on('routeChangeComplete', handlerCompleteRoute) + + return () => { + router.events.off('routeChangeStart', handlerStartRoute) + router.events.off('routeChangeComplete', handlerCompleteRoute) + } + }, [router]); + + return ( + + + + + {props.children} + + + + ) +} + +export default Content \ No newline at end of file diff --git a/src/components/layouts/Dashboard/Sidebar/SidebarList.jsx b/src/components/layouts/Dashboard/Sidebar/SidebarList.jsx index 265da6c..3a2eb44 100644 --- a/src/components/layouts/Dashboard/Sidebar/SidebarList.jsx +++ b/src/components/layouts/Dashboard/Sidebar/SidebarList.jsx @@ -1,5 +1,5 @@ import {Divider, List} from "@mui/material"; -import {Fragment, useEffect, useReducer, useRef, useState} from "react"; +import {Fragment, useEffect, useReducer, useState} from "react"; import SidebarListItem from "./SidebarListItem"; import sidebarMenu from "@/core/data/sidebarMenu"; import {useRouter} from "next/router"; @@ -10,20 +10,41 @@ function reducer(state, action) { case "COLLAPSE_MENU": return state.map((itemsArr) => itemsArr.map((item) => - action.key === item.key ? { ...item, showSubItem: !item.showSubItem } : item + action.key === item.key ? {...item, showSubItem: !item.showSubItem} : item ) ); case "SELECTED": return state.map((itemsArr) => itemsArr.map((item) => { return item.type === "page" - ? { ...item, selected: action.route === item.route } + ? {...item, selected: action.route === item.route, routing: false} : item.subItem && Array.isArray(item.subItem) ? { ...item, subItem: item.subItem.map((subitem) => ({ ...subitem, selected: subitem.route === action.route, + routing: false + })), + showSubItem: item.subItem.some( + (subitem) => subitem.selected + ), + } + : item; + }) + ); + case "SELECTING": + return state.map((itemsArr) => + itemsArr.map((item) => { + return item.type === "page" + ? {...item, selected: action.route === item.route, routing: action.route === item.route} + : item.subItem && Array.isArray(item.subItem) + ? { + ...item, + subItem: item.subItem.map((subitem) => ({ + ...subitem, + selected: subitem.route === action.route, + routing: subitem.route === action.route })), showSubItem: item.subItem.some( (subitem) => subitem.selected @@ -46,7 +67,16 @@ export default function SidebarList({handleDrawerToggle}) { useEffect(() => { dispatch({type: "SELECTED", route: router.pathname}); setSelectedKey(router.pathname); - }, [router.pathname]); + const handlerStartRoute = (url) => { + dispatch({type: "SELECTING", route: url}); + } + + router.events.on('routeChangeStart', handlerStartRoute) + + return () => { + router.events.off('routeChangeStart', handlerStartRoute) + } + }, [router]); useEffect(() => { @@ -57,7 +87,7 @@ export default function SidebarList({handleDrawerToggle}) { }, [selectedKey]); return ( - + {itemMenu.map((itemArr, index) => ( {itemArr.map((item) => diff --git a/src/components/layouts/Dashboard/Sidebar/SidebarListItem.jsx b/src/components/layouts/Dashboard/Sidebar/SidebarListItem.jsx index e9657a9..81fd444 100644 --- a/src/components/layouts/Dashboard/Sidebar/SidebarListItem.jsx +++ b/src/components/layouts/Dashboard/Sidebar/SidebarListItem.jsx @@ -1,7 +1,16 @@ import {NextLinkComposed} from "@/core/components/LinkRouting"; import ExpandLess from "@mui/icons-material/ExpandLess"; import ExpandMore from "@mui/icons-material/ExpandMore"; -import {Badge, IconButton, ListItem, ListItemButton, ListItemIcon, ListItemText, Typography,} from "@mui/material"; +import { + Badge, + CircularProgress, + IconButton, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, +} from "@mui/material"; import {useTranslations} from "next-intl"; import {Fragment} from "react"; import SidebarListSubItem from "./SidebarListSubItem"; @@ -9,7 +18,7 @@ import useNotification from "@/lib/app/hooks/useNotification"; const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => { const t = useTranslations(); - const { notification_count } = useNotification(); + const {notification_count} = useNotification(); const hasSubItems = item.type === "menu" && item.subItem && item.subItem.length > 0; const renderBadge = () => { return !hasSubItems ? ( @@ -40,7 +49,7 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => { })} onClick={() => { if (hasSubItems) { - dispatch({ type: "COLLAPSE_MENU", key: item.key }); + dispatch({type: "COLLAPSE_MENU", key: item.key}); } }} sx={{ @@ -53,10 +62,13 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => { minWidth: 0, justifyContent: "center", color: "primary.main", + width: 40, + height: 24, pr: 2, }} > - {item.icon} + {item.routing ? + : item.icon} { } /> - {hasSubItems && (item.showSubItem ? : )} + {hasSubItems && (item.showSubItem ? : )} {item.subItem && ( diff --git a/src/components/layouts/Dashboard/Sidebar/SidebarListSubItem.jsx b/src/components/layouts/Dashboard/Sidebar/SidebarListSubItem.jsx index d663d2c..3ef8731 100644 --- a/src/components/layouts/Dashboard/Sidebar/SidebarListSubItem.jsx +++ b/src/components/layouts/Dashboard/Sidebar/SidebarListSubItem.jsx @@ -1,6 +1,7 @@ import {NextLinkComposed} from "@/core/components/LinkRouting"; import { Badge, + CircularProgress, Collapse, IconButton, List, @@ -13,7 +14,7 @@ import { import {useTranslations} from "next-intl"; import useNotification from "@/lib/app/hooks/useNotification"; -const SidebarListSubItem = ({item, handleDrawerToggle }) => { +const SidebarListSubItem = ({item, handleDrawerToggle}) => { const t = useTranslations(); const {notification_count} = useNotification(); const renderBadge = (subitem) => ( @@ -50,10 +51,13 @@ const SidebarListSubItem = ({item, handleDrawerToggle }) => { sx={{ minWidth: 0, justifyContent: "center", + width: 40, + height: 24, pr: 2, }} > - {subitem.icon} + {subitem.routing ? + : subitem.icon} { + const theme = useTheme(); + const isUpSm = useMediaQuery((theme.breakpoints.up('sm'))) + return ( - - - - - - + {isUpSm ? ( + + + + ) : ( + + + + )} ); }; diff --git a/src/components/layouts/Dashboard/index.jsx b/src/components/layouts/Dashboard/index.jsx index de3b229..8201e54 100644 --- a/src/components/layouts/Dashboard/index.jsx +++ b/src/components/layouts/Dashboard/index.jsx @@ -1,10 +1,9 @@ import FullPageLayout from "@/layouts/FullPageLayout"; import {Toolbar} from "@mui/material"; import {useState} from "react"; -import RolePermissionMiddleware from "@/middlewares/RolePermission"; import Header from "@/components/layouts/Dashboard/Header"; import Sidebar from "@/components/layouts/Dashboard/Sidebar"; -import BreadCrumbs from "@/components/layouts/Dashboard/Breadcrumbs"; +import Content from "@/components/layouts/Dashboard/Content"; const drawerWidth = 240; @@ -34,12 +33,7 @@ const Dashboard = (props) => { sx={{flexGrow: 1, width: {sm: `calc(100% - ${drawerWidth}px)`}}} > - - - - {props.children} - - + ) diff --git a/src/core/components/LoadingHardPage.jsx b/src/core/components/LoadingHardPage.jsx index 5d00cd0..3001c6c 100644 --- a/src/core/components/LoadingHardPage.jsx +++ b/src/core/components/LoadingHardPage.jsx @@ -1,5 +1,5 @@ import SvgLoading from "@/core/components/svgs/SvgLoading"; -import {Backdrop, Box} from "@mui/material"; +import {Backdrop, Box, Stack, Typography} from "@mui/material"; import {styled} from "@mui/material/styles"; const LoadingImage = styled(Box)({ @@ -10,7 +10,7 @@ const LoadingImage = styled(Box)({ }, "50%": { // opacity: 1, - transform: "scale(2)", + transform: "scale(0.5)", }, "100%": { // opacity: 0, @@ -20,20 +20,29 @@ const LoadingImage = styled(Box)({ animation: "load 2s infinite", }); -const LoadingHardPage = ({children, loading}) => { +const LoadingHardPage = ({children, loading, sx = {}, icon = null, width = 200, height = 200, label = ''}) => { return ( <> theme.zIndex.modal + 1}} + sx={{bgcolor: "#fff", zIndex: (theme) => theme.zIndex.modal + 1, ...sx}} open={loading} > - - - + + + {icon ? ( + + {icon} + + ) : ( + + )} + + {label} + {children} diff --git a/src/core/data/sidebarMenu.jsx b/src/core/data/sidebarMenu.jsx index 5c14462..1fcc48c 100644 --- a/src/core/data/sidebarMenu.jsx +++ b/src/core/data/sidebarMenu.jsx @@ -8,7 +8,7 @@ const sidebarMenu = [ key: "sidebar.dashboard", type: "page", route: "/dashboard", - icon: , + icon: , selected: false, permission: "all", }, @@ -17,16 +17,16 @@ const sidebarMenu = [ type: "page", name: "expert_management", route: "/dashboard/expert-management", - icon: , + icon: , selected: false, permission: "all", }, { key: "sidebar.role-management", - name : "role_management", + name: "role_management", type: "page", route: "/dashboard/role-management", - icon: , + icon: , selected: false, permission: "manage_roles", }, diff --git a/src/layouts/index.jsx b/src/layouts/index.jsx index a620a0e..ce7a9c9 100644 --- a/src/layouts/index.jsx +++ b/src/layouts/index.jsx @@ -2,7 +2,7 @@ import DashboardLayout from "@/layouts/DashboardLayout"; import {Fragment} from "react"; const layoutList = { - DashboardLayout + DashboardLayout, } const Layout = ({layout, children}) => {