diff --git a/src/helpers/permissions.ts b/src/helpers/permissions.ts
index f44a283..9e5d30c 100644
--- a/src/helpers/permissions.ts
+++ b/src/helpers/permissions.ts
@@ -1,3 +1,29 @@
+export enum PermissionGroupEnum {
+ SERVICES = "services",
+ CUSTOMERS = "customers",
+ USERS = "users",
+ FINANCIAL = "financial",
+ CONTENT = "content",
+ SUPPORT = "support",
+ OTHER = "other",
+ PRODUCTS = "products",
+ REPRESENTATIVES = "representatives",
+ TASK_MANAGER = "task_manager",
+}
+
+export const PERMISSION_GROUP_ORDER: PermissionGroupEnum[] = [
+ PermissionGroupEnum.SERVICES,
+ PermissionGroupEnum.CUSTOMERS,
+ PermissionGroupEnum.USERS,
+ PermissionGroupEnum.FINANCIAL,
+ PermissionGroupEnum.CONTENT,
+ PermissionGroupEnum.SUPPORT,
+ PermissionGroupEnum.OTHER,
+ PermissionGroupEnum.PRODUCTS,
+ PermissionGroupEnum.REPRESENTATIVES,
+ PermissionGroupEnum.TASK_MANAGER,
+];
+
export enum PermissionEnum {
SERVICES_CREATE = "services_create",
SERVICES_READ = "services_read",
diff --git a/src/langs/fa.json b/src/langs/fa.json
index 9c11fac..e3f8897 100644
--- a/src/langs/fa.json
+++ b/src/langs/fa.json
@@ -727,6 +727,18 @@
"submit_role": "ثبت نقش",
"title_role": "عنوان نقش",
"permissions": "دسترسی ها",
+ "permission_groups": {
+ "services": "سرویسها",
+ "customers": "مشتریان",
+ "users": "کاربران",
+ "financial": "مالی",
+ "content": "محتوا",
+ "support": "پشتیبانی",
+ "other": "سایر",
+ "products": "محصولات",
+ "representatives": "نمایندگان",
+ "task_manager": "مدیریت وظایف"
+ },
"status_role": "وضعیت نقش",
"error_count_permission": "حداقل به دسترسی رو باید انتخاب کنید",
"is_admin": "آیا ادمین است؟",
diff --git a/src/pages/users/RoleCreate.tsx b/src/pages/users/RoleCreate.tsx
index 2fd7491..73d0441 100644
--- a/src/pages/users/RoleCreate.tsx
+++ b/src/pages/users/RoleCreate.tsx
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import Button from '../../components/Button'
import { TickCircle } from 'iconsax-react'
import Input from '../../components/Input'
-import CheckBoxComponent from '../../components/CheckBoxComponent'
+import RolePermissionsSelector from './components/RolePermissionsSelector'
import { useCreateRole, useGetPermissions } from './hooks/useUserData'
import PageLoading from '../../components/PageLoading'
import { useFormik } from 'formik'
@@ -98,24 +98,11 @@ const RoleCreate: FC = () => {
{t('user.permissions')}
-
- {
- getPermissions.data?.data?.permissions?.map((item: { id: string, name: string }) => {
- return (
-
-
handleAdd(item.id)}
- />
- {item.name}
-
- )
- })
- }
-
-
-
-
+
diff --git a/src/pages/users/RoleUpdate.tsx b/src/pages/users/RoleUpdate.tsx
index c8414ec..522b859 100644
--- a/src/pages/users/RoleUpdate.tsx
+++ b/src/pages/users/RoleUpdate.tsx
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import Button from '../../components/Button'
import { TickCircle } from 'iconsax-react'
import Input from '../../components/Input'
-import CheckBoxComponent from '../../components/CheckBoxComponent'
+import RolePermissionsSelector from './components/RolePermissionsSelector'
import { useGetPermissions, useGetRoleDetail, useUpdateRole } from './hooks/useUserData'
import PageLoading from '../../components/PageLoading'
import { useFormik } from 'formik'
@@ -112,24 +112,11 @@ const RoleUpdate: FC = () => {
{t('user.permissions')}
-
- {
- getPermissions.data?.data?.permissions?.map((item: { id: string, name: string }) => {
- return (
-
-
handleAdd(item.id)}
- />
- {item.name}
-
- )
- })
- }
-
-
-
-
+
diff --git a/src/pages/users/components/RolePermissionsSelector.tsx b/src/pages/users/components/RolePermissionsSelector.tsx
new file mode 100644
index 0000000..ebfc4de
--- /dev/null
+++ b/src/pages/users/components/RolePermissionsSelector.tsx
@@ -0,0 +1,85 @@
+import { FC, useEffect, useMemo, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import CheckBoxComponent from '../../../components/CheckBoxComponent'
+import { PERMISSION_GROUP_ORDER } from '../../../helpers/permissions'
+import { PermissionType } from '../types/UserTypes'
+
+type Props = {
+ permissions: PermissionType[]
+ selectedIds: string[]
+ onToggle: (id: string) => void
+}
+
+const RolePermissionsSelector: FC = ({ permissions, selectedIds, onToggle }) => {
+ const { t } = useTranslation('global')
+ const [activeGroup, setActiveGroup] = useState('')
+
+ const groupedPermissions = useMemo(() => {
+ const groups = new Map()
+
+ PERMISSION_GROUP_ORDER.forEach((group) => {
+ groups.set(group, [])
+ })
+
+ permissions.forEach((permission) => {
+ const groupItems = groups.get(permission.group)
+ if (groupItems) {
+ groupItems.push(permission)
+ }
+ })
+
+ return PERMISSION_GROUP_ORDER
+ .map((group) => ({
+ group,
+ items: groups.get(group) ?? [],
+ }))
+ .filter(({ items }) => items.length > 0)
+ }, [permissions])
+
+ useEffect(() => {
+ if (groupedPermissions.length === 0) {
+ setActiveGroup('')
+ return
+ }
+
+ if (!groupedPermissions.some(({ group }) => group === activeGroup)) {
+ setActiveGroup(groupedPermissions[0].group)
+ }
+ }, [activeGroup, groupedPermissions])
+
+ const activeGroupPermissions = groupedPermissions.find(({ group }) => group === activeGroup)?.items ?? []
+
+ return (
+
+
+ {groupedPermissions.map(({ group }) => (
+
+ ))}
+
+
+
+ {activeGroupPermissions.map((item) => (
+
+
onToggle(item.id)}
+ />
+ {item.title}
+
+ ))}
+
+
+ )
+}
+
+export default RolePermissionsSelector
diff --git a/src/pages/users/types/UserTypes.ts b/src/pages/users/types/UserTypes.ts
index 9582ea7..56a0f60 100644
--- a/src/pages/users/types/UserTypes.ts
+++ b/src/pages/users/types/UserTypes.ts
@@ -1,3 +1,12 @@
+import { PermissionGroupEnum } from "../../../helpers/permissions";
+
+export type PermissionType = {
+ id: string;
+ name: string;
+ title: string;
+ group: PermissionGroupEnum;
+};
+
export type CreateRoleType = {
name: string;
permissions: string[];
@@ -15,6 +24,8 @@ export type RoleItemType = {
export type RolePermissionType = {
id: string;
name: string;
+ title?: string;
+ group?: PermissionGroupEnum;
};
export type RoleDetailType = {