209 lines
5.9 KiB
TypeScript
209 lines
5.9 KiB
TypeScript
|
|
import React, { useMemo } from "react";
|
|||
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|||
|
|
import { useForm, Controller } from "react-hook-form";
|
|||
|
|
import { z } from "zod";
|
|||
|
|
import { Grid } from "../../components/Grid/Grid";
|
|||
|
|
import Button from "../../components/Button/Button";
|
|||
|
|
import Textfield from "../../components/Textfeild/Textfeild";
|
|||
|
|
import { useUserProfileStore } from "../../context/zustand-store/userStore";
|
|||
|
|
import { useApiMutation } from "../../utils/useApiRequest";
|
|||
|
|
import { useToast } from "../../hooks/useToast";
|
|||
|
|
import { useDrawerStore } from "../../context/zustand-store/appStore";
|
|||
|
|
import { getCitiesOfProvinceInfo } from "../../utils/getCitiesOfProvinceInfo";
|
|||
|
|
import AutoComplete from "../../components/AutoComplete/AutoComplete";
|
|||
|
|
import {
|
|||
|
|
zValidateString,
|
|||
|
|
zValidateMobile,
|
|||
|
|
zValidateAutoComplete,
|
|||
|
|
} from "../../data/getFormTypeErrors";
|
|||
|
|
|
|||
|
|
interface SubmitNewUserProps {
|
|||
|
|
province: string;
|
|||
|
|
onSuccess?: () => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const schema = z.object({
|
|||
|
|
mobile: zValidateMobile("موبایل"),
|
|||
|
|
password: zValidateString("کلمه عبور"),
|
|||
|
|
fullname: zValidateString("نام کامل"),
|
|||
|
|
permissions: zValidateAutoComplete("دسترسیها"),
|
|||
|
|
city: zValidateAutoComplete("شهر"),
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
type FormValues = z.infer<typeof schema>;
|
|||
|
|
|
|||
|
|
export const SubmitNewUser: React.FC<SubmitNewUserProps> = ({ onSuccess }) => {
|
|||
|
|
const { profile } = useUserProfileStore();
|
|||
|
|
const showToast = useToast();
|
|||
|
|
const { closeDrawer } = useDrawerStore();
|
|||
|
|
|
|||
|
|
const {
|
|||
|
|
control,
|
|||
|
|
handleSubmit,
|
|||
|
|
setValue,
|
|||
|
|
formState: { errors, isSubmitting },
|
|||
|
|
} = useForm<FormValues>({
|
|||
|
|
resolver: zodResolver(schema),
|
|||
|
|
defaultValues: {
|
|||
|
|
mobile: "",
|
|||
|
|
password: "",
|
|||
|
|
fullname: "",
|
|||
|
|
permissions: [],
|
|||
|
|
city: [],
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const submitUserMutation = useApiMutation({
|
|||
|
|
api: "user",
|
|||
|
|
method: "post",
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const cityOptions = useMemo(() => {
|
|||
|
|
return getCitiesOfProvinceInfo(profile?.province || "").map((item) => ({
|
|||
|
|
key: item.en,
|
|||
|
|
value: item.fa,
|
|||
|
|
}));
|
|||
|
|
}, [profile?.province]);
|
|||
|
|
|
|||
|
|
const permissionOptions = useMemo(() => {
|
|||
|
|
return [
|
|||
|
|
{ key: "add", value: "ثبت کاربر" },
|
|||
|
|
{ key: "submit", value: "ثبت بازرسی" },
|
|||
|
|
];
|
|||
|
|
}, []);
|
|||
|
|
|
|||
|
|
const onSubmit = async (data: FormValues) => {
|
|||
|
|
try {
|
|||
|
|
const payload = {
|
|||
|
|
mobile: data.mobile,
|
|||
|
|
password: data.password,
|
|||
|
|
fullname: data.fullname,
|
|||
|
|
pic: "",
|
|||
|
|
permissions: data.permissions as string[],
|
|||
|
|
province: profile?.province,
|
|||
|
|
city:
|
|||
|
|
Array.isArray(data.city) && data.city.length > 0
|
|||
|
|
? String(data.city[0])
|
|||
|
|
: "",
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
await submitUserMutation.mutateAsync(payload);
|
|||
|
|
showToast("کاربر با موفقیت ثبت شد", "success");
|
|||
|
|
closeDrawer();
|
|||
|
|
if (onSuccess) {
|
|||
|
|
onSuccess();
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(error);
|
|||
|
|
showToast("مشکلی پیش آمده است، ممکن است کاربر تکراری باشد!", "error");
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|||
|
|
<Grid container column className="gap-4">
|
|||
|
|
<Controller
|
|||
|
|
name="mobile"
|
|||
|
|
control={control}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<Textfield
|
|||
|
|
placeholder="موبایل"
|
|||
|
|
value={field.value}
|
|||
|
|
onChange={field.onChange}
|
|||
|
|
error={!!errors.mobile}
|
|||
|
|
helperText={errors.mobile?.message}
|
|||
|
|
fullWidth
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<Controller
|
|||
|
|
name="password"
|
|||
|
|
control={control}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<Textfield
|
|||
|
|
placeholder="کلمه عبور"
|
|||
|
|
value={field.value}
|
|||
|
|
onChange={field.onChange}
|
|||
|
|
password
|
|||
|
|
error={!!errors.password}
|
|||
|
|
helperText={errors.password?.message}
|
|||
|
|
fullWidth
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<Controller
|
|||
|
|
name="fullname"
|
|||
|
|
control={control}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<Textfield
|
|||
|
|
placeholder="نام کامل"
|
|||
|
|
value={field.value}
|
|||
|
|
onChange={field.onChange}
|
|||
|
|
error={!!errors.fullname}
|
|||
|
|
helperText={errors.fullname?.message}
|
|||
|
|
fullWidth
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
<div className="w-full">
|
|||
|
|
<Controller
|
|||
|
|
name="city"
|
|||
|
|
control={control}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<AutoComplete
|
|||
|
|
data={cityOptions}
|
|||
|
|
selectedKeys={
|
|||
|
|
(Array.isArray(field.value) ? field.value : []) as (
|
|||
|
|
| string
|
|||
|
|
| number
|
|||
|
|
)[]
|
|||
|
|
}
|
|||
|
|
onChange={(keys) => setValue("city", keys as any)}
|
|||
|
|
title="شهر را انتخاب کنید"
|
|||
|
|
error={!!errors.city}
|
|||
|
|
helperText={errors.city?.message}
|
|||
|
|
multiselect={false}
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="w-full">
|
|||
|
|
<Controller
|
|||
|
|
name="permissions"
|
|||
|
|
control={control}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<AutoComplete
|
|||
|
|
data={permissionOptions}
|
|||
|
|
selectedKeys={
|
|||
|
|
(Array.isArray(field.value) ? field.value : []) as (
|
|||
|
|
| string
|
|||
|
|
| number
|
|||
|
|
)[]
|
|||
|
|
}
|
|||
|
|
onChange={(keys) => setValue("permissions", keys as any)}
|
|||
|
|
title="دسترسیها را انتخاب کنید"
|
|||
|
|
error={!!errors.permissions}
|
|||
|
|
helperText={errors.permissions?.message}
|
|||
|
|
multiselect={true}
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<Button
|
|||
|
|
type="submit"
|
|||
|
|
variant="submit"
|
|||
|
|
fullWidth
|
|||
|
|
disabled={isSubmitting || submitUserMutation.isPending}
|
|||
|
|
>
|
|||
|
|
ثبت کاربر
|
|||
|
|
</Button>
|
|||
|
|
</Grid>
|
|||
|
|
</form>
|
|||
|
|
);
|
|||
|
|
};
|