diff --git a/src/config/Paths.tsx b/src/config/Paths.tsx index 8db4132..c88ec1c 100644 --- a/src/config/Paths.tsx +++ b/src/config/Paths.tsx @@ -32,9 +32,9 @@ export const Paths = { update: '/admin/update/', }, role: { - list: '/admin/role', - create: '/admin/role/create', - update: '/admin/role/update/', + list: '/role', + create: '/role/create', + update: '/role/update/', }, formBuilder: { list: '/form-builder/list/', diff --git a/src/pages/admin/hooks/useAdminData.ts b/src/pages/admin/hooks/useAdminData.ts index e450705..f82e2ec 100644 --- a/src/pages/admin/hooks/useAdminData.ts +++ b/src/pages/admin/hooks/useAdminData.ts @@ -52,3 +52,10 @@ export const useDeleteAdmin = () => { }, }); }; + +export const useGetAdminMe = () => { + return useQuery({ + queryKey: ["adminMe"], + queryFn: api.getAdminMe, + }); +}; diff --git a/src/pages/admin/service/AdminService.ts b/src/pages/admin/service/AdminService.ts index 863e71b..28e7df0 100644 --- a/src/pages/admin/service/AdminService.ts +++ b/src/pages/admin/service/AdminService.ts @@ -4,6 +4,7 @@ import type { CreateAdminType, RolesResponseType, AdminDetailResponseType, + AdminMeResponseType, } from "../types/Types"; export const getAdmins = async (page: number, limit: number = 10) => { @@ -46,3 +47,8 @@ export const deleteAdmin = async (adminId: string) => { const { data } = await axios.delete(`/admin/admins/${adminId}`); return data; }; + +export const getAdminMe = async () => { + const { data } = await axios.get("/admin/admins/me"); + return data; +}; diff --git a/src/pages/admin/types/Types.ts b/src/pages/admin/types/Types.ts index 15c8239..0d70893 100644 --- a/src/pages/admin/types/Types.ts +++ b/src/pages/admin/types/Types.ts @@ -48,3 +48,9 @@ export type RoleItemType = { export type RolesResponseType = BaseResponse; export type AdminDetailResponseType = BaseResponse; + +/** Admin "me" response: admin with full role including permissions */ +export type AdminMeDataType = Omit & { + role: RoleItemType; +}; +export type AdminMeResponseType = BaseResponse; diff --git a/src/shared/Sidebar.tsx b/src/shared/Sidebar.tsx index 5bb6b6e..667161d 100644 --- a/src/shared/Sidebar.tsx +++ b/src/shared/Sidebar.tsx @@ -26,6 +26,7 @@ import { t } from '../locale'; import Button from '@/components/Button'; const SideBar: FC = () => { + const { openSidebar, setOpenSidebar } = useSharedStore(); const location = useLocation(); @@ -64,6 +65,7 @@ const SideBar: FC = () => { title={t('sidebar.mainPage')} isActive={isActive('/home')} link={Paths.home} + activeName='dashboard' /> { title={'محصولات'} isActive={isActive('product')} link={Paths.product.list} + activeName='manage_products' /> { title={'درخواست ها'} isActive={isActive('requests')} link={Paths.requests.list} + activeName='view_requests' /> { title={'پیش فاکتور'} isActive={isActive('/invoice')} link={Paths.perfomaInvoice.list} + activeName='view_invoices' /> { title={'سفارشات'} isActive={isActive('order')} link={Paths.order.list} + activeName={['view_orders', 'view_assigned_orders']} /> @@ -101,6 +107,7 @@ const SideBar: FC = () => { title={'مشتریان'} isActive={isActive('users')} link={Paths.users.list} + activeName='view_users' /> { title={'چاپ'} isActive={isActive('print')} link={Paths.print.list} + activeName='view_print' /> { title={'ادمین'} isActive={isActive('admin')} link={Paths.admin.list} + activeName='manage_admins' /> { title={'نقش‌ها'} isActive={isActive('role')} link={Paths.role.list} + activeName='manage_roles' /> @@ -134,6 +144,7 @@ const SideBar: FC = () => { title={t('sidebar.tickets')} isActive={isActive('/tickets')} link={Paths.tickets.list} + activeName='manage_tickets' /> { title={t('sidebar.announcement')} isActive={isActive('/announcement')} link={Paths.announcement.list} + activeName='manage_announcements' /> { title={t('sidebar.criticisms')} isActive={isActive('/criticisms')} link={Paths.criticisms.list} + activeName='manage_criticisms' /> { title={t('sidebar.learning')} isActive={isActive('/learning')} link={Paths.learning.list} + activeName='manage_learnings' /> @@ -176,6 +190,7 @@ const SideBar: FC = () => { title={t('sidebar.logout')} isActive={isActive('logout')} link={`#`} + activeName='' isLogout /> diff --git a/src/shared/SidebarItem.tsx b/src/shared/SidebarItem.tsx index b91ffbb..f685c68 100644 --- a/src/shared/SidebarItem.tsx +++ b/src/shared/SidebarItem.tsx @@ -5,6 +5,8 @@ import { Paths } from '../config/Paths' // import { useLogout } from '../pages/auth/hooks/useAuthData' import { removeToken } from '../config/func' import { removeRefreshToken } from '../config/func' +import { useGetAdminMe } from '@/pages/admin/hooks/useAdminData' +import type { PermissionItemType } from '@/pages/admin/types/Types' type Props = { icon: ReactNode, @@ -12,11 +14,14 @@ type Props = { isActive: boolean, link: string, isLogout?: boolean, - isWithoutLine?: boolean + isWithoutLine?: boolean, + activeName?: string | string[] } const SideBarItem: FC = (props: Props) => { + const { data:adminPermissions } = useGetAdminMe(); + // const logout = useLogout() const handleLogout = async () => { @@ -25,21 +30,31 @@ const SideBarItem: FC = (props: Props) => { removeRefreshToken() window.location.href = Paths.auth.login } + const permissions: PermissionItemType[] = adminPermissions?.data?.role?.permissions ?? [] + const hasPermission = + props.activeName === '' || + (Array.isArray(props.activeName) + ? permissions.some((p) => (props.activeName as string[]).includes(p.name)) + : !!props.activeName && permissions.some((p) => p.name === props.activeName)) + if (hasPermission) { - return ( - -
- {props.icon} -
- {props.title} + return ( + +
+ {props.icon} +
+ {props.title} +
-
- - ) + + ) + } + + return null } export default SideBarItem \ No newline at end of file