update admin

This commit is contained in:
hamid zarghami
2025-11-23 14:58:22 +03:30
parent 6da0cb533a
commit c37c1929a7
5 changed files with 177 additions and 1 deletions
+156
View File
@@ -0,0 +1,156 @@
import { type FC, useEffect } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'
import { TickCircle } from 'iconsax-react'
import { toast } from 'react-toastify'
import { useNavigate, useParams } from 'react-router-dom'
import Button from '@/components/Button'
import Input from '@/components/Input'
import Select from '@/components/Select'
import { useGetAdminById, useUpdateAdmin } from './hooks/useAdminData'
import { useGetRoles } from '@/pages/roles/hooks/useRolesData'
import type { CreateAdminType } from './types/Types'
import { Pages } from '@/config/Pages'
import type { ErrorType } from '@/helpers/types'
import { extractErrorMessage } from '@/config/func'
const UpdateAdmin: FC = () => {
const navigate = useNavigate()
const { id } = useParams()
const { data: adminData, isLoading } = useGetAdminById(id!)
const { mutate: updateAdmin, isPending } = useUpdateAdmin()
const { data: rolesData } = useGetRoles()
const roles = rolesData?.data?.map(role => ({
label: role.name,
value: role.id
})) || []
const admin = adminData?.data
const formik = useFormik<CreateAdminType>({
initialValues: {
phone: '',
firstName: '',
lastName: '',
roleId: '',
},
validationSchema: Yup.object().shape({
phone: Yup.string().required('شماره تلفن الزامی است'),
firstName: Yup.string().required('نام الزامی است'),
lastName: Yup.string().required('نام خانوادگی الزامی است'),
roleId: Yup.string().required('نقش الزامی است'),
}),
onSubmit: (values) => {
if (!id) {
toast.error('شناسه مدیر یافت نشد')
return
}
updateAdmin({ id, params: values }, {
onSuccess: () => {
toast.success('مدیر با موفقیت به‌روزرسانی شد')
navigate(Pages.admins.list)
},
onError: (error: ErrorType) => {
toast.error(extractErrorMessage(error))
},
})
},
})
useEffect(() => {
if (admin) {
formik.setValues({
phone: admin.phone || '',
firstName: admin.firstName || '',
lastName: admin.lastName || '',
roleId: admin.roles?.[0]?.role?.id || '',
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [admin])
if (isLoading) {
return (
<div className='w-full mt-4 flex justify-center items-center'>
<div>در حال بارگذاری...</div>
</div>
)
}
if (!admin) {
return (
<div className='w-full mt-4 flex justify-center items-center'>
<div>مدیر یافت نشد</div>
</div>
)
}
return (
<div className='mt-5'>
<div className='flex w-full justify-between items-center'>
<div className='text-lg font-light'>
ویرایش مدیر
</div>
<div>
<Button
className='px-5'
onClick={() => formik.handleSubmit()}
isloading={isPending}
>
<div className='flex gap-2 items-center'>
<TickCircle className='size-5' color='white' />
<div>ذخیره تغییرات</div>
</div>
</Button>
</div>
</div>
<div className='mt-6'>
<div className='bg-white rounded-3xl p-6'>
<div className='mb-4'>
<Input
label='نام'
name='firstName'
value={formik.values.firstName}
onChange={formik.handleChange}
error_text={formik.touched.firstName && formik.errors.firstName ? formik.errors.firstName : ''}
/>
</div>
<div className='mt-6'>
<Input
label='نام خانوادگی'
name='lastName'
value={formik.values.lastName}
onChange={formik.handleChange}
error_text={formik.touched.lastName && formik.errors.lastName ? formik.errors.lastName : ''}
/>
</div>
<div className='mt-6'>
<Input
label='شماره تلفن'
name='phone'
value={formik.values.phone}
onChange={formik.handleChange}
error_text={formik.touched.phone && formik.errors.phone ? formik.errors.phone : ''}
/>
</div>
<div className='mt-6'>
<Select
label='نقش'
name='roleId'
value={formik.values.roleId}
onChange={formik.handleChange}
items={roles}
placeholder='نقش را انتخاب کنید'
error_text={formik.touched.roleId && formik.errors.roleId ? formik.errors.roleId : ''}
/>
</div>
</div>
</div>
</div>
)
}
export default UpdateAdmin
+8
View File
@@ -48,3 +48,11 @@ export const useUpdateAdmin = () => {
},
});
};
export const useGetAdminById = (id: string) => {
return useQuery({
queryKey: ["admin", id],
queryFn: () => api.getAdminById(id),
enabled: !!id,
});
};
+9 -1
View File
@@ -3,6 +3,7 @@ import type {
GetAdminsResponse,
GetAdminsParams,
CreateAdminType,
GetAdminByIdResponse,
} from "../types/Types";
export const getAdmins = async (
@@ -25,6 +26,13 @@ export const createAdmin = async (params: CreateAdminType) => {
};
export const updateAdmin = async (id: string, params: CreateAdminType) => {
const { data } = await axios.patch(`/admin/admins/${id}`, params);
const { data } = await axios.patch(`/admin/${id}`, params);
return data;
};
export const getAdminById = async (
adminId: string
): Promise<GetAdminByIdResponse> => {
const { data } = await axios.get<GetAdminByIdResponse>(`/admin/${adminId}`);
return data;
};
+2
View File
@@ -38,6 +38,8 @@ export type GetAdminsParams = {
export type GetAdminsResponse = IResponse<Admin[]>;
export type GetAdminByIdResponse = IResponse<Admin>;
export type CreateAdminType = {
phone: string;
firstName: string;
+2
View File
@@ -29,6 +29,7 @@ import CreatePaymentMethod from '@/pages/paymentMethods/Create'
import UpdatePaymentMethod from '@/pages/paymentMethods/Update'
import AdminList from '@/pages/admin/List'
import CreateAdmin from '@/pages/admin/Create'
import UpdateAdmin from '@/pages/admin/Update'
const MainRouter: FC = () => {
const { hasSubMenu } = useSharedStore()
@@ -71,6 +72,7 @@ const MainRouter: FC = () => {
<Route path={Pages.admins.list} element={<AdminList />} />
<Route path={Pages.admins.add} element={<CreateAdmin />} />
<Route path={Pages.admins.update + ':id'} element={<UpdateAdmin />} />
</Routes>
</div>
</div>