fix role not found
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
hamid zarghami
2026-06-29 15:05:30 +03:30
parent b155c0b959
commit 4fc7d19766
3 changed files with 171 additions and 154 deletions
+36 -12
View File
@@ -17,30 +17,54 @@ type Props = {
} & SelectHTMLAttributes<HTMLSelectElement> } & SelectHTMLAttributes<HTMLSelectElement>
const Select: FC<Props> = (props: Props) => { const Select: FC<Props> = (props: Props) => {
const {
className,
items,
error_text,
placeholder,
label,
isNotRequired,
value,
...selectProps
} = props
const hasMatchingItem =
value !== undefined &&
value !== '' &&
items?.some((item) => String(item.value) === String(value))
const selectValue =
!value || hasMatchingItem || !items?.length
? (value ?? '')
: ''
return ( return (
<div className='w-full relative'> <div className='w-full relative'>
{ {
props.label && label &&
<div className='flex items-center gap-1'> <div className='flex items-center gap-1'>
<label className='text-sm'> <label className='text-sm'>
{props.label} {label}
</label> </label>
{props.isNotRequired && ( {isNotRequired && (
<span className='text-xs text-description'>(اختیاری)</span> <span className='text-xs text-description'>(اختیاری)</span>
)} )}
</div> </div>
} }
<select {...props} className={clx( <select
{...selectProps}
value={selectValue}
className={clx(
'w-full text-black block border appearance-none border-border !bg-white px-2.5 h-10 text-sm rounded-[10px] bg-gray', 'w-full text-black block border appearance-none border-border !bg-white px-2.5 h-10 text-sm rounded-[10px] bg-gray',
props.className, className,
props.label && 'mt-1' label && 'mt-1'
)}> )}>
{ {
props.placeholder && placeholder &&
<option value="" disabled selected>{props.placeholder}</option> <option value="" disabled>{placeholder}</option>
} }
{ {
props.items?.map((item) => { items?.map((item) => {
return ( return (
<option key={item.value} value={item.value}> <option key={item.value} value={item.value}>
{item.label} {item.label}
@@ -51,12 +75,12 @@ const Select: FC<Props> = (props: Props) => {
</select> </select>
<ArrowDown2 size={16} color='black' className={clx( <ArrowDown2 size={16} color='black' className={clx(
'absolute z-0 top-3 left-2', 'absolute z-0 top-3 left-2',
props.label && 'top-10' label && 'top-10'
)} /> )} />
{ {
props.error_text && props.error_text !== '' ? error_text && error_text !== '' ?
<Error <Error
errorText={props.error_text} errorText={error_text}
/> />
: null : null
} }
+134 -142
View File
@@ -1,156 +1,148 @@
import { type FC, useEffect } from 'react' import Button from "@/components/Button";
import { useFormik } from 'formik' import Input from "@/components/Input";
import * as Yup from 'yup' import Select from "@/components/Select";
import { TickCircle } from 'iconsax-react' import { extractErrorMessage } from "@/config/func";
import { toast } from 'react-toastify' import { Pages } from "@/config/Pages";
import { useNavigate, useParams } from 'react-router-dom' import type { ErrorType } from "@/helpers/types";
import Button from '@/components/Button' import { useGetRoles } from "@/pages/roles/hooks/useRolesData";
import Input from '@/components/Input' import { useFormik } from "formik";
import Select from '@/components/Select' import { TickCircle } from "iconsax-react";
import { useGetAdminById, useUpdateAdmin } from './hooks/useAdminData' import { type FC, useEffect } from "react";
import { useGetRoles } from '@/pages/roles/hooks/useRolesData' import { useNavigate, useParams } from "react-router-dom";
import type { CreateAdminType } from './types/Types' import { toast } from "react-toastify";
import { Pages } from '@/config/Pages' import * as Yup from "yup";
import type { ErrorType } from '@/helpers/types' import { useGetAdminById, useUpdateAdmin } from "./hooks/useAdminData";
import { extractErrorMessage } from '@/config/func' import type { CreateAdminType } from "./types/Types";
const UpdateAdmin: FC = () => { const UpdateAdmin: FC = () => {
const navigate = useNavigate() const navigate = useNavigate();
const { id } = useParams() const { id } = useParams();
const { data: adminData, isLoading } = useGetAdminById(id!) const { data: adminData, isLoading } = useGetAdminById(id!);
const { mutate: updateAdmin, isPending } = useUpdateAdmin() const { mutate: updateAdmin, isPending } = useUpdateAdmin();
const { data: rolesData } = useGetRoles() const { data: rolesData } = useGetRoles();
const roles = rolesData?.data?.map(role => ({ const roles =
label: role.name, rolesData?.data?.map((role) => ({
value: role.id label: role.name,
})) || [] value: role.id,
})) || [];
const admin = adminData?.data const admin = adminData?.data;
const formik = useFormik<CreateAdminType>({ const formik = useFormik<CreateAdminType>({
initialValues: { initialValues: {
phone: '', phone: "",
firstName: '', firstName: "",
lastName: '', lastName: "",
roleId: '', 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));
},
}, },
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 }, { useEffect(() => {
onSuccess: () => { if (admin) {
toast.success('مدیر با موفقیت به‌روزرسانی شد') formik.setValues({
navigate(Pages.admins.list) phone: admin.phone || "",
}, firstName: admin.firstName || "",
onError: (error: ErrorType) => { lastName: admin.lastName || "",
toast.error(extractErrorMessage(error)) roleId: admin.role?.id || "",
}, });
})
},
})
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>
)
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [admin]);
if (isLoading) {
return ( return (
<div className='mt-5'> <div className="w-full mt-4 flex justify-center items-center">
<div className='flex w-full justify-between items-center'> <div>در حال بارگذاری...</div>
<div className='text-lg font-light'> </div>
ویرایش مدیر );
</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'> if (!admin) {
<div className='bg-white rounded-3xl p-6'> return (
<div className='mb-4'> <div className="w-full mt-4 flex justify-center items-center">
<Input <div>مدیر یافت نشد</div>
label='نام' </div>
name='firstName' );
value={formik.values.firstName} }
onChange={formik.handleChange}
error_text={formik.touched.firstName && formik.errors.firstName ? formik.errors.firstName : ''} return (
/> <div className="mt-5">
</div> <div className="flex w-full justify-between items-center">
<div className='mt-6'> <div className="text-lg font-light">ویرایش مدیر</div>
<Input <div>
label='نام خانوادگی' <Button className="px-5" onClick={() => formik.handleSubmit()} isloading={isPending}>
name='lastName' <div className="flex gap-2 items-center">
value={formik.values.lastName} <TickCircle className="size-5" color="white" />
onChange={formik.handleChange} <div>ذخیره تغییرات</div>
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>
</Button>
</div> </div>
) </div>
}
export default UpdateAdmin <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;
+1
View File
@@ -28,6 +28,7 @@ export type Admin = {
lastName: string; lastName: string;
phone: string; phone: string;
roles: AdminRole[]; roles: AdminRole[];
role: RoleDetail;
}; };
export type GetAdminsParams = { export type GetAdminsParams = {