permission menu
This commit is contained in:
@@ -32,9 +32,9 @@ export const Paths = {
|
|||||||
update: '/admin/update/',
|
update: '/admin/update/',
|
||||||
},
|
},
|
||||||
role: {
|
role: {
|
||||||
list: '/admin/role',
|
list: '/role',
|
||||||
create: '/admin/role/create',
|
create: '/role/create',
|
||||||
update: '/admin/role/update/',
|
update: '/role/update/',
|
||||||
},
|
},
|
||||||
formBuilder: {
|
formBuilder: {
|
||||||
list: '/form-builder/list/',
|
list: '/form-builder/list/',
|
||||||
|
|||||||
@@ -52,3 +52,10 @@ export const useDeleteAdmin = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGetAdminMe = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["adminMe"],
|
||||||
|
queryFn: api.getAdminMe,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type {
|
|||||||
CreateAdminType,
|
CreateAdminType,
|
||||||
RolesResponseType,
|
RolesResponseType,
|
||||||
AdminDetailResponseType,
|
AdminDetailResponseType,
|
||||||
|
AdminMeResponseType,
|
||||||
} from "../types/Types";
|
} from "../types/Types";
|
||||||
|
|
||||||
export const getAdmins = async (page: number, limit: number = 10) => {
|
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}`);
|
const { data } = await axios.delete(`/admin/admins/${adminId}`);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getAdminMe = async () => {
|
||||||
|
const { data } = await axios.get<AdminMeResponseType>("/admin/admins/me");
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
@@ -48,3 +48,9 @@ export type RoleItemType = {
|
|||||||
|
|
||||||
export type RolesResponseType = BaseResponse<RoleItemType[]>;
|
export type RolesResponseType = BaseResponse<RoleItemType[]>;
|
||||||
export type AdminDetailResponseType = BaseResponse<AdminItemType>;
|
export type AdminDetailResponseType = BaseResponse<AdminItemType>;
|
||||||
|
|
||||||
|
/** Admin "me" response: admin with full role including permissions */
|
||||||
|
export type AdminMeDataType = Omit<AdminItemType, "role"> & {
|
||||||
|
role: RoleItemType;
|
||||||
|
};
|
||||||
|
export type AdminMeResponseType = BaseResponse<AdminMeDataType>;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { t } from '../locale';
|
|||||||
import Button from '@/components/Button';
|
import Button from '@/components/Button';
|
||||||
|
|
||||||
const SideBar: FC = () => {
|
const SideBar: FC = () => {
|
||||||
|
|
||||||
const { openSidebar, setOpenSidebar } = useSharedStore();
|
const { openSidebar, setOpenSidebar } = useSharedStore();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.mainPage')}
|
title={t('sidebar.mainPage')}
|
||||||
isActive={isActive('/home')}
|
isActive={isActive('/home')}
|
||||||
link={Paths.home}
|
link={Paths.home}
|
||||||
|
activeName='dashboard'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -71,6 +73,7 @@ const SideBar: FC = () => {
|
|||||||
title={'محصولات'}
|
title={'محصولات'}
|
||||||
isActive={isActive('product')}
|
isActive={isActive('product')}
|
||||||
link={Paths.product.list}
|
link={Paths.product.list}
|
||||||
|
activeName='manage_products'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -78,6 +81,7 @@ const SideBar: FC = () => {
|
|||||||
title={'درخواست ها'}
|
title={'درخواست ها'}
|
||||||
isActive={isActive('requests')}
|
isActive={isActive('requests')}
|
||||||
link={Paths.requests.list}
|
link={Paths.requests.list}
|
||||||
|
activeName='view_requests'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -85,6 +89,7 @@ const SideBar: FC = () => {
|
|||||||
title={'پیش فاکتور'}
|
title={'پیش فاکتور'}
|
||||||
isActive={isActive('/invoice')}
|
isActive={isActive('/invoice')}
|
||||||
link={Paths.perfomaInvoice.list}
|
link={Paths.perfomaInvoice.list}
|
||||||
|
activeName='view_invoices'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -92,6 +97,7 @@ const SideBar: FC = () => {
|
|||||||
title={'سفارشات'}
|
title={'سفارشات'}
|
||||||
isActive={isActive('order')}
|
isActive={isActive('order')}
|
||||||
link={Paths.order.list}
|
link={Paths.order.list}
|
||||||
|
activeName={['view_orders', 'view_assigned_orders']}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
@@ -101,6 +107,7 @@ const SideBar: FC = () => {
|
|||||||
title={'مشتریان'}
|
title={'مشتریان'}
|
||||||
isActive={isActive('users')}
|
isActive={isActive('users')}
|
||||||
link={Paths.users.list}
|
link={Paths.users.list}
|
||||||
|
activeName='view_users'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -108,6 +115,7 @@ const SideBar: FC = () => {
|
|||||||
title={'چاپ'}
|
title={'چاپ'}
|
||||||
isActive={isActive('print')}
|
isActive={isActive('print')}
|
||||||
link={Paths.print.list}
|
link={Paths.print.list}
|
||||||
|
activeName='view_print'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -115,6 +123,7 @@ const SideBar: FC = () => {
|
|||||||
title={'ادمین'}
|
title={'ادمین'}
|
||||||
isActive={isActive('admin')}
|
isActive={isActive('admin')}
|
||||||
link={Paths.admin.list}
|
link={Paths.admin.list}
|
||||||
|
activeName='manage_admins'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -122,6 +131,7 @@ const SideBar: FC = () => {
|
|||||||
title={'نقشها'}
|
title={'نقشها'}
|
||||||
isActive={isActive('role')}
|
isActive={isActive('role')}
|
||||||
link={Paths.role.list}
|
link={Paths.role.list}
|
||||||
|
activeName='manage_roles'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -134,6 +144,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.tickets')}
|
title={t('sidebar.tickets')}
|
||||||
isActive={isActive('/tickets')}
|
isActive={isActive('/tickets')}
|
||||||
link={Paths.tickets.list}
|
link={Paths.tickets.list}
|
||||||
|
activeName='manage_tickets'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -141,6 +152,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.announcement')}
|
title={t('sidebar.announcement')}
|
||||||
isActive={isActive('/announcement')}
|
isActive={isActive('/announcement')}
|
||||||
link={Paths.announcement.list}
|
link={Paths.announcement.list}
|
||||||
|
activeName='manage_announcements'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -148,6 +160,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.criticisms')}
|
title={t('sidebar.criticisms')}
|
||||||
isActive={isActive('/criticisms')}
|
isActive={isActive('/criticisms')}
|
||||||
link={Paths.criticisms.list}
|
link={Paths.criticisms.list}
|
||||||
|
activeName='manage_criticisms'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
@@ -155,6 +168,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.learning')}
|
title={t('sidebar.learning')}
|
||||||
isActive={isActive('/learning')}
|
isActive={isActive('/learning')}
|
||||||
link={Paths.learning.list}
|
link={Paths.learning.list}
|
||||||
|
activeName='manage_learnings'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -176,6 +190,7 @@ const SideBar: FC = () => {
|
|||||||
title={t('sidebar.logout')}
|
title={t('sidebar.logout')}
|
||||||
isActive={isActive('logout')}
|
isActive={isActive('logout')}
|
||||||
link={`#`}
|
link={`#`}
|
||||||
|
activeName=''
|
||||||
isLogout
|
isLogout
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+28
-13
@@ -5,6 +5,8 @@ import { Paths } from '../config/Paths'
|
|||||||
// import { useLogout } from '../pages/auth/hooks/useAuthData'
|
// import { useLogout } from '../pages/auth/hooks/useAuthData'
|
||||||
import { removeToken } from '../config/func'
|
import { removeToken } from '../config/func'
|
||||||
import { removeRefreshToken } 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 = {
|
type Props = {
|
||||||
icon: ReactNode,
|
icon: ReactNode,
|
||||||
@@ -12,11 +14,14 @@ type Props = {
|
|||||||
isActive: boolean,
|
isActive: boolean,
|
||||||
link: string,
|
link: string,
|
||||||
isLogout?: boolean,
|
isLogout?: boolean,
|
||||||
isWithoutLine?: boolean
|
isWithoutLine?: boolean,
|
||||||
|
activeName?: string | string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const SideBarItem: FC<Props> = (props: Props) => {
|
const SideBarItem: FC<Props> = (props: Props) => {
|
||||||
|
|
||||||
|
const { data:adminPermissions } = useGetAdminMe();
|
||||||
|
|
||||||
// const logout = useLogout()
|
// const logout = useLogout()
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
@@ -25,21 +30,31 @@ const SideBarItem: FC<Props> = (props: Props) => {
|
|||||||
removeRefreshToken()
|
removeRefreshToken()
|
||||||
window.location.href = Paths.auth.login
|
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 (
|
return (
|
||||||
<Link onClick={props.isLogout ? handleLogout : undefined} to={props.link} className={clx(
|
<Link onClick={props.isLogout ? handleLogout : undefined} to={props.link} className={clx(
|
||||||
'h-12 rounded-2xl flex gap-2 text-[#4F5260] px-4 text-[13px] items-center',
|
'h-12 rounded-2xl flex gap-2 text-[#4F5260] px-4 text-[13px] items-center',
|
||||||
props.isActive && 'bg-[#F5F7FC]',
|
props.isActive && 'bg-[#F5F7FC]',
|
||||||
)}>
|
)}>
|
||||||
<div className='flex gap-3 items-center'>
|
<div className='flex gap-3 items-center'>
|
||||||
{props.icon}
|
{props.icon}
|
||||||
<div className={`text-[#4F5260]`}>
|
<div className={`text-[#4F5260]`}>
|
||||||
{props.title}
|
{props.title}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SideBarItem
|
export default SideBarItem
|
||||||
Reference in New Issue
Block a user