permissions for sidebar

This commit is contained in:
Amirhossein Mahmoodi
2024-07-10 11:21:32 +03:30
parent ad36728411
commit 6b78309e37
6 changed files with 124 additions and 86 deletions

View File

@@ -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 (
<Box sx={{ display: "flex", flexDirection: "column", my: 1 }}>

View File

@@ -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);

View File

@@ -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;
}, []);
}

View File

@@ -7,6 +7,7 @@ export const pageMenu = [
type: "page",
route: "/dashboard",
icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
permissions: ["all"]
},
{
id: "userManagement",
@@ -14,6 +15,7 @@ export const pageMenu = [
type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management",
icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
permissions: ["all"]
},
],
},
@@ -294,6 +322,7 @@ export const pageMenu = [
type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp",
icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
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: <Security sx={{ width: "inherit", height: "inherit" }} />,
permissions: ["all"]
},
],
},
// {
// id: "hello",
// type: "menu",
// route: "/hello",
// icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />,
// selected: false,
// Subitems: [
// {
// id: "amin",
// route: "/s",
// icon: <SpaceDashboard sx={{ width: 'inherit', height: 'inherit' }} />,
// firstName: "amin",
// lastName: "ali",
// Subitems: [
// {
// id: "shahrokh", shahrokh: "shahrokh", type: "page", selected: false, route: "/dashbssoard", icon: <Assessment sx={{ width: 'inherit', height: 'inherit' }} />
// },
// {
// id: "shasdasdsahrokh", shahrokh: "shahroasdasdkh", type: "page", selected: false, route: "/dashboardsd", icon: <AirlineSeatReclineNormal sx={{ width: 'inherit', height: 'inherit' }} />
// }
// ],
// hasSubitems: true,
// showSubitems: false,
// type: "menu",
// selected: false,
// },
// {
// id: "amir",
// route: "/dashboarsad",
// icon: <Repartition sx={{ width: 'inherit', height: 'inherit' }} />,
// firstName: "amir",
// lastName: "akbar",
// hasSubitems: false,
// showSubitems: false,
// selected: false,
// type: "page",
// },
// ],
// hasSubitems: true,
// showSubitems: false
// },
];

View File

@@ -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";

View File

@@ -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 });
}