@@ -56,6 +56,7 @@ export const Paths = {
|
|||||||
print: '/service/print',
|
print: '/service/print',
|
||||||
},
|
},
|
||||||
home: '/home',
|
home: '/home',
|
||||||
|
profile: '/profile',
|
||||||
myOrders: '/my-orders',
|
myOrders: '/my-orders',
|
||||||
perfomaInvoice: {
|
perfomaInvoice: {
|
||||||
list: '/invoice/list',
|
list: '/invoice/list',
|
||||||
|
|||||||
@@ -1,23 +1,38 @@
|
|||||||
import { useState, type FC } from "react";
|
import { useState, type FC } from "react";
|
||||||
import { useGetAdmins, useDeleteAdmin } from "./hooks/useAdminData";
|
import { useGetAdmins, useDeleteAdmin, useGetAdminMe } from "./hooks/useAdminData";
|
||||||
import Table from "@/components/Table";
|
import Table from "@/components/Table";
|
||||||
import PresignedImage from "@/components/PresignedImage";
|
import PresignedImage from "@/components/PresignedImage";
|
||||||
import moment from "moment-jalaali";
|
import moment from "moment-jalaali";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Paths } from "@/config/Paths";
|
import { Paths } from "@/config/Paths";
|
||||||
import Button from "@/components/Button";
|
import Button from "@/components/Button";
|
||||||
import { AddSquare, Eye } from "iconsax-react";
|
import { AddSquare, Eye, ShieldSecurity } from "iconsax-react";
|
||||||
import TrashWithConfrim from "@/components/TrashWithConfrim";
|
import TrashWithConfrim from "@/components/TrashWithConfrim";
|
||||||
|
|
||||||
const AdminList: FC = () => {
|
const AdminList: FC = () => {
|
||||||
const [page, setPage] = useState<number>(1);
|
const [page, setPage] = useState<number>(1);
|
||||||
const { data } = useGetAdmins(page);
|
const { data } = useGetAdmins(page);
|
||||||
const deleteAdminMutation = useDeleteAdmin();
|
const deleteAdminMutation = useDeleteAdmin();
|
||||||
|
const { data: adminMe } = useGetAdminMe();
|
||||||
|
const canManageRoles = adminMe?.data?.role?.permissions?.some(
|
||||||
|
(p) => p.name === "manage_roles",
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<h1 className="text-lg font-light">مدیران</h1>
|
<h1 className="text-lg font-light">مدیران</h1>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
{canManageRoles && (
|
||||||
|
<Link to={Paths.role.list}>
|
||||||
|
<Button className="w-fit px-6 bg-[#F5F7FC]">
|
||||||
|
<div className="flex gap-1.5">
|
||||||
|
<ShieldSecurity size={18} color="black" />
|
||||||
|
<div className="text-[13px] font-light text-black">نقشها</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
<Link to={Paths.admin.create}>
|
<Link to={Paths.admin.create}>
|
||||||
<Button className="w-fit px-6">
|
<Button className="w-fit px-6">
|
||||||
<div className="flex gap-1.5">
|
<div className="flex gap-1.5">
|
||||||
@@ -27,6 +42,7 @@ const AdminList: FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
columns={[
|
columns={[
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as api from "../service/AdminService";
|
import * as api from "../service/AdminService";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import type { CreateAdminType } from "../types/Types";
|
import type { CreateAdminType, UpdateAdminMeType } from "../types/Types";
|
||||||
|
|
||||||
export const useGetAdmins = (page: number = 1, limit: number = 10) => {
|
export const useGetAdmins = (page: number = 1, limit: number = 10) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
@@ -59,3 +59,14 @@ export const useGetAdminMe = () => {
|
|||||||
queryFn: api.getAdminMe,
|
queryFn: api.getAdminMe,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useUpdateAdminMe = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (params: UpdateAdminMeType) => api.updateAdminMe(params),
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["adminMe"] });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type {
|
|||||||
RolesResponseType,
|
RolesResponseType,
|
||||||
AdminDetailResponseType,
|
AdminDetailResponseType,
|
||||||
AdminMeResponseType,
|
AdminMeResponseType,
|
||||||
|
UpdateAdminMeType,
|
||||||
} from "../types/Types";
|
} from "../types/Types";
|
||||||
|
|
||||||
export const getAdmins = async (page: number, limit: number = 10) => {
|
export const getAdmins = async (page: number, limit: number = 10) => {
|
||||||
@@ -52,3 +53,8 @@ export const getAdminMe = async () => {
|
|||||||
const { data } = await axios.get<AdminMeResponseType>("/admin/admins/me");
|
const { data } = await axios.get<AdminMeResponseType>("/admin/admins/me");
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateAdminMe = async (params: UpdateAdminMeType) => {
|
||||||
|
const { data } = await axios.patch<AdminMeResponseType>("/admin/admins/me", params);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
@@ -65,4 +65,11 @@ export interface AdminMeDataType {
|
|||||||
avatarUrl?: string | null;
|
avatarUrl?: string | null;
|
||||||
role: RoleItemType;
|
role: RoleItemType;
|
||||||
}
|
}
|
||||||
|
export type UpdateAdminMeType = {
|
||||||
|
phone: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
avatarUrl?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type AdminMeResponseType = BaseResponse<AdminMeDataType>;
|
export type AdminMeResponseType = BaseResponse<AdminMeDataType>;
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
import { useFormik } from 'formik';
|
||||||
|
import { type FC, useState } from 'react';
|
||||||
|
import * as Yup from 'yup';
|
||||||
|
import Button from '@/components/Button';
|
||||||
|
import { Edit } from 'iconsax-react';
|
||||||
|
import Input from '@/components/Input';
|
||||||
|
import UploadBox from '@/components/UploadBox';
|
||||||
|
import PresignedImage from '@/components/PresignedImage';
|
||||||
|
import { useGetAdminMe, useUpdateAdminMe } from '@/pages/admin/hooks/useAdminData';
|
||||||
|
import { useSingleUpload } from '@/pages/uploader/hooks/useUploader';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import { extractErrorMessage } from '@/config/func';
|
||||||
|
import type { UpdateAdminMeType } from '@/pages/admin/types/Types';
|
||||||
|
|
||||||
|
const Profile: FC = () => {
|
||||||
|
const { data: adminData, isLoading } = useGetAdminMe();
|
||||||
|
const { mutate: update, isPending: isUpdating } = useUpdateAdminMe();
|
||||||
|
const { mutate: upload, isPending: isUploading } = useSingleUpload();
|
||||||
|
const [file, setFile] = useState<File>();
|
||||||
|
|
||||||
|
const admin = adminData?.data;
|
||||||
|
|
||||||
|
const handleSave = (values: UpdateAdminMeType) => {
|
||||||
|
update(values, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success('پروفایل با موفقیت ویرایش شد');
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(extractErrorMessage(error));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const formik = useFormik<UpdateAdminMeType>({
|
||||||
|
enableReinitialize: true,
|
||||||
|
initialValues: {
|
||||||
|
firstName: admin?.firstName ?? '',
|
||||||
|
lastName: admin?.lastName ?? '',
|
||||||
|
phone: admin?.phone ? `0${admin.phone}` : '',
|
||||||
|
avatarUrl: admin?.avatarUrl ?? undefined,
|
||||||
|
},
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
firstName: Yup.string()
|
||||||
|
.required('نام اجباری می باشد')
|
||||||
|
.min(2, 'نام باید حداقل 2 کاراکتر باشد'),
|
||||||
|
lastName: Yup.string()
|
||||||
|
.required('نام خانوادگی اجباری می باشد')
|
||||||
|
.min(2, 'نام خانوادگی باید حداقل 2 کاراکتر باشد'),
|
||||||
|
phone: Yup.string()
|
||||||
|
.required('شماره موبایل اجباری می باشد')
|
||||||
|
.matches(/^09[0-9]{9}$/, 'شماره موبایل معتبر نمی باشد'),
|
||||||
|
}),
|
||||||
|
onSubmit: (values) => {
|
||||||
|
if (file) {
|
||||||
|
upload(file, {
|
||||||
|
onSuccess: (data) => {
|
||||||
|
handleSave({ ...values, avatarUrl: data?.data?.key });
|
||||||
|
},
|
||||||
|
onError: (error) => toast.error(extractErrorMessage(error)),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handleSave(values);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<div className='mt-5 flex h-64 items-center justify-center'>
|
||||||
|
<div className='text-lg'>در حال بارگذاری...</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mt-5'>
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<h1 className='text-lg font-light'>پروفایل</h1>
|
||||||
|
<Button
|
||||||
|
className='w-fit px-6'
|
||||||
|
onClick={() => formik.handleSubmit()}
|
||||||
|
isLoading={isUpdating || isUploading}
|
||||||
|
>
|
||||||
|
<div className='flex gap-1.5'>
|
||||||
|
<Edit size={18} color='black' />
|
||||||
|
<div className='text-[13px] font-light'>ذخیره تغییرات</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-8 flex-1 rounded-3xl bg-white p-6'>
|
||||||
|
{formik.values.avatarUrl && !file && (
|
||||||
|
<div className='mb-4'>
|
||||||
|
<PresignedImage
|
||||||
|
src={formik.values.avatarUrl}
|
||||||
|
className='h-20 w-20 rounded-full object-cover'
|
||||||
|
alt='آواتار'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<UploadBox
|
||||||
|
label='آواتار (اختیاری)'
|
||||||
|
onChange={(files) => setFile(files[0])}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className='rowTwoInput mt-6'>
|
||||||
|
<Input
|
||||||
|
label='نام'
|
||||||
|
placeholder='نام را وارد کنید'
|
||||||
|
{...formik.getFieldProps('firstName')}
|
||||||
|
error_text={
|
||||||
|
formik.touched.firstName && formik.errors.firstName
|
||||||
|
? formik.errors.firstName
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Input
|
||||||
|
label='نام خانوادگی'
|
||||||
|
placeholder='نام خانوادگی را وارد کنید'
|
||||||
|
{...formik.getFieldProps('lastName')}
|
||||||
|
error_text={
|
||||||
|
formik.touched.lastName && formik.errors.lastName
|
||||||
|
? formik.errors.lastName
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-6'>
|
||||||
|
<Input
|
||||||
|
label='شماره موبایل'
|
||||||
|
placeholder='شماره موبایل را وارد کنید'
|
||||||
|
{...formik.getFieldProps('phone')}
|
||||||
|
error_text={
|
||||||
|
formik.touched.phone && formik.errors.phone
|
||||||
|
? formik.errors.phone
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Profile;
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
import axios from "@/config/axios";
|
|
||||||
|
|
||||||
export interface ProfileData {
|
|
||||||
user: {
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
email: string;
|
|
||||||
profilePic?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useGetProfile = () => {
|
|
||||||
return useQuery({
|
|
||||||
queryKey: ["profile"],
|
|
||||||
queryFn: async (): Promise<{ data: ProfileData }> => {
|
|
||||||
const response = await axios.get("/profile");
|
|
||||||
return response.data;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -47,6 +47,7 @@ import UpdateUser from "@/pages/user/Update";
|
|||||||
import AdminList from "@/pages/admin/List";
|
import AdminList from "@/pages/admin/List";
|
||||||
import CreateAdmin from "@/pages/admin/Create";
|
import CreateAdmin from "@/pages/admin/Create";
|
||||||
import EditAdmin from "@/pages/admin/Update";
|
import EditAdmin from "@/pages/admin/Update";
|
||||||
|
import Profile from "@/pages/profile/Profile";
|
||||||
import RoleList from "@/pages/role/List";
|
import RoleList from "@/pages/role/List";
|
||||||
import CreateRole from "@/pages/role/Create";
|
import CreateRole from "@/pages/role/Create";
|
||||||
import UpdateRole from "@/pages/role/Update";
|
import UpdateRole from "@/pages/role/Update";
|
||||||
@@ -75,6 +76,7 @@ const MainRouter: FC = () => {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path={Paths.home} element={<Home />} />
|
<Route path={Paths.home} element={<Home />} />
|
||||||
|
<Route path={Paths.profile} element={<Profile />} />
|
||||||
<Route path={Paths.perfomaInvoice.list} element={<ProformaInvoice />} />
|
<Route path={Paths.perfomaInvoice.list} element={<ProformaInvoice />} />
|
||||||
<Route path={Paths.payments.list} element={<PaymentsList />} />
|
<Route path={Paths.payments.list} element={<PaymentsList />} />
|
||||||
<Route path={Paths.perfomaInvoice.create} element={<CreateInvoice />} />
|
<Route path={Paths.perfomaInvoice.create} element={<CreateInvoice />} />
|
||||||
|
|||||||
+4
-67
@@ -1,21 +1,16 @@
|
|||||||
import { type FC, useEffect, useState } from 'react'
|
import { type FC } from 'react'
|
||||||
import Input from '@/components/Input'
|
import Input from '@/components/Input'
|
||||||
import UserAvatar from '@/components/UserAvatar'
|
import UserAvatar from '@/components/UserAvatar'
|
||||||
import { ArrowDown2, CloseCircle, HambergerMenu, Logout } from 'iconsax-react'
|
import { HambergerMenu } from 'iconsax-react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import Notifications from '@/pages/notification/Notification'
|
import Notifications from '@/pages/notification/Notification'
|
||||||
import { useSharedStore } from './store/useSharedStore'
|
import { useSharedStore } from './store/useSharedStore'
|
||||||
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react'
|
|
||||||
import SidebarItem from './SidebarItem'
|
|
||||||
import { t } from '@/locale'
|
import { t } from '@/locale'
|
||||||
import { useGetAdminMe } from '@/pages/admin/hooks/useAdminData'
|
import { useGetAdminMe } from '@/pages/admin/hooks/useAdminData'
|
||||||
import { Paths } from '@/config/Paths'
|
import { Paths } from '@/config/Paths'
|
||||||
|
|
||||||
const Header: FC = () => {
|
const Header: FC = () => {
|
||||||
|
|
||||||
const location = useLocation();
|
|
||||||
const [popoverKey, setPopoverKey] = useState(0);
|
|
||||||
const { setOpenSidebar, openSidebar } = useSharedStore()
|
const { setOpenSidebar, openSidebar } = useSharedStore()
|
||||||
const { data } = useGetAdminMe()
|
const { data } = useGetAdminMe()
|
||||||
const admin = data?.data
|
const admin = data?.data
|
||||||
@@ -23,10 +18,6 @@ const Header: FC = () => {
|
|||||||
const displayName = [admin?.firstName, admin?.lastName].filter(Boolean).join(' ').trim()
|
const displayName = [admin?.firstName, admin?.lastName].filter(Boolean).join(' ').trim()
|
||||||
const roleTitle = admin?.role?.title || admin?.role?.name || ''
|
const roleTitle = admin?.role?.title || admin?.role?.name || ''
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPopoverKey((prevKey) => prevKey + 1);
|
|
||||||
}, [location.pathname]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='fixed z-10 left-[var(--layout-frame)] right-[var(--layout-frame)] top-[var(--layout-frame)] flex h-[var(--layout-header-height)] items-center justify-between rounded-[32px] bg-white px-6 xl:left-auto xl:right-[calc(var(--layout-frame)+var(--layout-main-offset))] xl:h-[var(--layout-header-height-xl)] xl:w-[calc(100%-(var(--layout-frame)*2)-var(--layout-main-offset))]'>
|
<div className='fixed z-10 left-[var(--layout-frame)] right-[var(--layout-frame)] top-[var(--layout-frame)] flex h-[var(--layout-header-height)] items-center justify-between rounded-[32px] bg-white px-6 xl:left-auto xl:right-[calc(var(--layout-frame)+var(--layout-main-offset))] xl:h-[var(--layout-header-height-xl)] xl:w-[calc(100%-(var(--layout-frame)*2)-var(--layout-main-offset))]'>
|
||||||
|
|
||||||
@@ -39,20 +30,10 @@ const Header: FC = () => {
|
|||||||
<div onClick={() => setOpenSidebar(!openSidebar)} className='xl:hidden block'>
|
<div onClick={() => setOpenSidebar(!openSidebar)} className='xl:hidden block'>
|
||||||
<HambergerMenu size={24} color='black' />
|
<HambergerMenu size={24} color='black' />
|
||||||
</div>
|
</div>
|
||||||
{/* <img src={LogoImage} className='h-6 xl:hidden block absolute right-0 left-0 mx-auto' /> */}
|
|
||||||
<div className='flex xl:gap-6 gap-4 items-center'>
|
<div className='flex xl:gap-6 gap-4 items-center'>
|
||||||
{/* <Link to={Pages.services.other}>
|
|
||||||
<Element3 color='black' className='xl:size-[18px] size-[17px]' />
|
|
||||||
</Link>
|
|
||||||
<Link className='xl:hidden' to={Pages.wallet}>
|
|
||||||
<Wallet className='xl:size-[18px] size-[17px]' color='black' />
|
|
||||||
</Link>
|
|
||||||
<Link className='hidden xl:block' to={Pages.wallet}> */}
|
|
||||||
<Notifications />
|
<Notifications />
|
||||||
{admin && (
|
{admin && (
|
||||||
<Popover className="relative" key={popoverKey}>
|
<Link to={Paths.profile} className='flex gap-2 items-center mt-2.5'>
|
||||||
<PopoverButton>
|
|
||||||
<div className='flex gap-2 items-center mt-2.5'>
|
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
src={admin.avatarUrl}
|
src={admin.avatarUrl}
|
||||||
firstName={admin.firstName}
|
firstName={admin.firstName}
|
||||||
@@ -60,8 +41,7 @@ const Header: FC = () => {
|
|||||||
className='size-6'
|
className='size-6'
|
||||||
textClassName='text-xs'
|
textClassName='text-xs'
|
||||||
/>
|
/>
|
||||||
<div className='xl:flex hidden gap-1 items-center'>
|
<div className='xl:flex hidden flex-col items-start'>
|
||||||
<div className='flex flex-col items-start'>
|
|
||||||
<div className='text-xs'>
|
<div className='text-xs'>
|
||||||
{displayName || String(admin.phone ?? '')}
|
{displayName || String(admin.phone ?? '')}
|
||||||
</div>
|
</div>
|
||||||
@@ -71,50 +51,7 @@ const Header: FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<ArrowDown2 size={14} color='#8C90A3' />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</PopoverButton>
|
|
||||||
|
|
||||||
<PopoverPanel style={{ minHeight: window.innerWidth < 1140 ? window.innerHeight : undefined }} anchor="bottom" className="flex xl:ml-6 overflow-auto flex-col gap-3 bg-white boxShadow xl:mt-7 z-30 py-4 text-xs rounded-2.5 xl:w-[300px] -mt-[50px] w-full fixed xl:h-fit h-full shadow-md">
|
|
||||||
<div className='absolute xl:hidden top-6 left-6'>
|
|
||||||
<CloseCircle onClick={() => setPopoverKey((prevKey) => prevKey + 1)} size={20} color='black' />
|
|
||||||
</div>
|
|
||||||
<Link to={`${Paths.admin.update}${admin.id}`} className='flex flex-col gap-2 items-center justify-center border-b border-[#EAEDF5] pb-4'>
|
|
||||||
<UserAvatar
|
|
||||||
src={admin.avatarUrl}
|
|
||||||
firstName={admin.firstName}
|
|
||||||
lastName={admin.lastName}
|
|
||||||
className='size-14'
|
|
||||||
textClassName='text-lg'
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{displayName || String(admin.phone ?? '')}
|
|
||||||
</div>
|
|
||||||
{roleTitle && (
|
|
||||||
<div className='text-description'>
|
|
||||||
{roleTitle}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className='text-description'>
|
|
||||||
{String(admin.phone ?? '')}
|
|
||||||
</div>
|
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
||||||
<div className='px-6 -mt-[2px]'>
|
|
||||||
<SidebarItem
|
|
||||||
icon={<Logout color={'black'} size={20} />}
|
|
||||||
title={t('sidebar.logout')}
|
|
||||||
isActive
|
|
||||||
link={Paths.auth.login}
|
|
||||||
isWithoutLine
|
|
||||||
isLogout
|
|
||||||
activeName=''
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</PopoverPanel>
|
|
||||||
</Popover>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-10
@@ -13,7 +13,6 @@ import {
|
|||||||
Printer,
|
Printer,
|
||||||
Receipt21,
|
Receipt21,
|
||||||
MoneyRecive,
|
MoneyRecive,
|
||||||
ShieldSecurity,
|
|
||||||
Teacher,
|
Teacher,
|
||||||
User,
|
User,
|
||||||
} from 'iconsax-react';
|
} from 'iconsax-react';
|
||||||
@@ -128,20 +127,12 @@ const SideBar: FC = () => {
|
|||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
icon={<User size={iconSizeSideBar} color="#4F5260" />}
|
icon={<User size={iconSizeSideBar} color="#4F5260" />}
|
||||||
title={'ادمین'}
|
title={'مدیران'}
|
||||||
isActive={isActive('admin')}
|
isActive={isActive('admin')}
|
||||||
link={Paths.admin.list}
|
link={Paths.admin.list}
|
||||||
activeName='manage_admins'
|
activeName='manage_admins'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SideBarItem
|
|
||||||
icon={<ShieldSecurity size={iconSizeSideBar} color="#4F5260" />}
|
|
||||||
title={'نقشها'}
|
|
||||||
isActive={isActive('role')}
|
|
||||||
link={Paths.role.list}
|
|
||||||
activeName='manage_roles'
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SideBarItem
|
<SideBarItem
|
||||||
icon={<ElementEqual size={iconSizeSideBar} color="#4F5260" />}
|
icon={<ElementEqual size={iconSizeSideBar} color="#4F5260" />}
|
||||||
title={'محصولات'}
|
title={'محصولات'}
|
||||||
|
|||||||
Reference in New Issue
Block a user