diff --git a/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx b/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx index d715192..b4da7f5 100644 --- a/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx +++ b/src/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker.jsx @@ -7,9 +7,6 @@ import ClearIcon from "@mui/icons-material/Clear"; import moment from "jalali-moment"; function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error }) { - // console.log("error", error); - // - // console.log("helperText", helperText) return ( diff --git a/src/core/components/SidebarMenu.jsx b/src/core/components/SidebarMenu.jsx index 0ad01dc..326dd11 100644 --- a/src/core/components/SidebarMenu.jsx +++ b/src/core/components/SidebarMenu.jsx @@ -1,80 +1,86 @@ "use client"; import SidebarListItems from "@/core/components/SidebarListItems"; +import { usePermissions } from "@/lib/hooks/usePermissions"; import { List } from "@mui/material"; import { usePathname } from "next/navigation"; import { useEffect, useReducer, useState } from "react"; +import { filterMenuItems } from "../utils/filterMenuItems"; import { pageMenu } from "../utils/pageMenu"; function reducer(state, action) { switch (action.type) { + case "UPDATE_MENU": + const _permissions = action.permissions || [] + const filteredPageMenu = filterMenuItems(pageMenu, ['all', ..._permissions]) + return filteredPageMenu case "COLLAPSE_MENU": return state.map((item) => action.id == item.id ? { - ...item, - showSubitems: !item.showSubitems, - } + ...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, + 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, + 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, + 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, + selected: action.route === subitem.route, + showSubitems: subitem.route === action.route, + } : subitem.Subitems && Array.isArray(subitem.Subitems) - ? { + ? { ...subitem, Subitems: subitem.Subitems.map((secondSubItem) => ({ ...secondSubItem, @@ -84,11 +90,11 @@ function reducer(state, action) { (secondSubItem) => secondSubItem.route === action.route ), } - : subitem; + : subitem; }), showSubitems: item.Subitems.some((subitem) => subitem.showSubitems), } - : item; + : item; }); default: @@ -97,9 +103,15 @@ function reducer(state, action) { } const SidebarMenu = () => { + const { data: userPermissions } = usePermissions() const [menuItems, dispatch] = useReducer(reducer, pageMenu); const pathname = usePathname(); const [selectedKey, setSelectedKey] = useState(null); + + useEffect(() => { + dispatch({ type: 'UPDATE_MENU', permissions: userPermissions }); + }, [userPermissions]) + useEffect(() => { dispatch({ type: "SELECTED", route: pathname }); setSelectedKey(pathname); diff --git a/src/core/utils/filterMenuItems.js b/src/core/utils/filterMenuItems.js new file mode 100644 index 0000000..7bceeb5 --- /dev/null +++ b/src/core/utils/filterMenuItems.js @@ -0,0 +1,17 @@ +export function filterMenuItems(items, _permissions = []) { + return items.reduce((acc, item) => { + if (item.permissions) { + if (item.permissions.some(permission => _permissions.includes(permission))) { + acc.push(item); + } + } else if (item.hasSubitems) { + const filteredSubItems = filterMenuItems(item.Subitems, _permissions); + if (filteredSubItems.length > 0) { + acc.push({ ...item, Subitems: filteredSubItems }); + } + } else { + acc.push(item); + } + return acc; + }, []); +} \ No newline at end of file diff --git a/src/core/utils/pageMenu.js b/src/core/utils/pageMenu.js index 6145ffd..9750e63 100644 --- a/src/core/utils/pageMenu.js +++ b/src/core/utils/pageMenu.js @@ -7,6 +7,7 @@ export const pageMenu = [ type: "page", route: "/dashboard", icon: , + permissions: ["all"] }, { id: "userManagement", @@ -14,6 +15,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", icon: , + permissions: ['full-user-management', 'limited-user-management'] }, { id: "projectsManagment", @@ -28,6 +30,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", icon: , + permissions: ['show-contract', 'show-contract-province'], }, { id: "projectsManagmentList", @@ -35,6 +38,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", icon: , + permissions: ["all"] }, { id: "projectsManagmentProposal", @@ -42,6 +46,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", icon: , + permissions: ['show-proposal', 'show-proposal-province'] }, { id: "projectsManagmentLawmaker", @@ -49,6 +54,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", icon: , + permissions: ['show-lawmaker', 'show-lawmaker-province'] }, { id: "projectsManagmentMap", @@ -56,6 +62,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", icon: , + permissions: ["all"] }, ], }, @@ -78,6 +85,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/supervisor/cartable", + permissions: ['show-road-item-supervise-cartable', 'show-road-item-supervise-cartable-province'] }, ], }, @@ -93,12 +101,14 @@ export const pageMenu = [ label: "ثبت فعالیت", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create", + permissions: ['create-road-item'] }, { id: "roadItemManagmentOparationCartable", label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/cartable", + permissions: ['create-road-item'] }, ], }, @@ -108,6 +118,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", icon: , + permissions: ['show-road-item-supervise-cartable', 'show-road-item-supervise-cartable-province', 'create-road-item'] }, { id: "roadItemManagmentReport", @@ -115,6 +126,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", icon: , + permissions: ['show-road-item-supervise-cartable', 'show-road-item-supervise-cartable-province', 'create-road-item'] }, ], }, @@ -137,6 +149,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/road_patrols/supervisor/cartable", + permissions: ['show-road-patrol-supervise-cartable', 'show-road-patrol-supervise-cartable-province'] }, ], }, @@ -152,12 +165,14 @@ export const pageMenu = [ label: "ثبت اقدام", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create", + permissions: ['add-road-patrol'] }, { id: "roadPatrolManagmentOparationCartable", label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable", + permissions: ['add-road-patrol'] }, ], }, @@ -167,6 +182,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", icon: , + permissions: ['add-road-patrol', 'show-road-patrol-supervise-cartable', 'show-road-patrol-supervise-cartable-province'] }, { id: "roadPatrolManagmentReport", @@ -174,6 +190,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", icon: , + permissions: ['add-road-patrol', 'show-road-patrol-supervise-cartable', 'show-road-patrol-supervise-cartable-province'] }, ], }, @@ -196,12 +213,14 @@ export const pageMenu = [ label: "ثبت فعالیت", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/safety_and_privacy/operator/first_step", + permissions: ['add-safety-and-privacy'] }, { id: "safetyAndPrivacyManagmentOparationCartable", label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable", + permissions: ['show-safety-and-privacy-operator-cartable', 'show-safety-and-privacy-operator-cartable-province', 'show-safety-and-privacy-operator-cartable-edarate-shahri'] }, ], }, @@ -211,6 +230,8 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", icon: , + permissions: ['show-safety-and-privacy-operator-cartable', 'show-safety-and-privacy-operator-cartable-province', + 'show-safety-and-privacy-operator-cartable-edarate-shahri', 'add-safety-and-privacy'] }, { id: "safetyAndPrivacyManagmentReport", @@ -218,6 +239,8 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", icon: , + permissions: ['show-safety-and-privacy-operator-cartable', 'show-safety-and-privacy-operator-cartable-province', + 'show-safety-and-privacy-operator-cartable-edarate-shahri', 'add-safety-and-privacy'] }, ], }, @@ -240,6 +263,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/supervisor/cartable", + permissions: ['supervise-fast-react', 'supervise-fast-react-province'] }, ], }, @@ -249,6 +273,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", icon: , + permissions: ['show-fast-react', 'show-fast-react-province', 'show-fast-react-edarate-shahri'] }, { id: "roadObservationsManagmentOparation", @@ -262,6 +287,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/operator/cartable", + permissions: ['show-fast-react', 'show-fast-react-province', 'show-fast-react-edarate-shahri'] }, ], }, @@ -271,6 +297,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", icon: , + permissions: ["all"] }, { id: "roadObservationsManagmentReport", @@ -278,6 +305,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", icon: , + permissions: ["all"] }, ], }, @@ -294,6 +322,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", icon: , + permissions: ['show-camp', 'show-camp-province'] }, { id: "winterCampManagmentFirstRing", @@ -301,6 +330,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", icon: , + permissions: ['show-camp', 'show-camp-province'] }, { id: "winterCampManagmentReport", @@ -308,6 +338,7 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", icon: , + permissions: ['show-camp', 'show-camp-province'] }, ], }, @@ -330,6 +361,7 @@ export const pageMenu = [ label: "کارتابل", type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt", + permissions: ["all"] }, ], }, @@ -339,48 +371,8 @@ export const pageMenu = [ type: "page", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", icon: , + permissions: ["all"] }, ], }, - // { - // 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 - // }, ]; diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index 8fae96f..81ac016 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -2,3 +2,5 @@ const api = process.env.NEXT_PUBLIC_API_URL; export const GET_USER_ROUTE = api + "/webapi/user/get-permission"; export const GET_LOGIN_ROUTE = api + "/login_dev"; + +export const GET_PERMISSIONS_ROUTE = api + "/webapi/user/get-permission"; \ No newline at end of file diff --git a/src/lib/hooks/usePermissions.js b/src/lib/hooks/usePermissions.js new file mode 100644 index 0000000..4f54b41 --- /dev/null +++ b/src/lib/hooks/usePermissions.js @@ -0,0 +1,18 @@ +import { GET_PERMISSIONS_ROUTE } from "@/core/utils/routes"; +import useSWR from "swr"; +import useRequest from "./useRequest"; + +export const usePermissions = () => { + const request = useRequest() + + const fetcher = async (url) => { + try { + const response = await request(url) + return response.data.data + } catch (error) { + throw new Error(); + } + }; + + return useSWR(GET_PERMISSIONS_ROUTE, fetcher, { keepPreviousData: true }); +} \ No newline at end of file