save request

This commit is contained in:
hamid zarghami
2026-06-07 12:43:43 +03:30
parent 032050bacc
commit 6653e3db82
4 changed files with 85 additions and 48 deletions
+57 -47
View File
@@ -2,36 +2,30 @@ import Button from "@/components/Button";
import DatePicker from "@/components/DatePicker";
import Error from "@/components/Error";
import Input from "@/components/Input";
import Select from "@/components/Select";
import Textarea from "@/components/Textarea";
import { toast } from "@/components/Toast";
import UploadBoxDraggble from "@/components/UploadBoxDraggble";
import { extractErrorMessage } from "@/helpers/utils";
import { usePageTitle } from "@/hooks/usePageTitle";
import { useSingleUpload } from "@/pages/uploader/hooks/useUploaderData";
import { Form, Formik, type FormikProps } from "formik";
import { useInitiateDesignRequest } from "@/pages/designer/hooks/useDesignerData";
import { useMultipleUpload } from "@/pages/uploader/hooks/useUploaderData";
import { Form, Formik, type FormikHelpers, type FormikProps } from "formik";
import { type FC } from "react";
import * as Yup from "yup";
const PRICE_PER_PAGE = 1000;
const pageCountOptions = Array.from({ length: 20 }, (_, index) => {
const value = index + 1;
return {
value: String(value),
label: String(value),
};
});
export type DesignerRequestFormValues = {
title: string;
count: number;
count: number | "";
desc: string;
expectedDate: string;
attachments: string[];
attachments: File[];
};
const initialValues: DesignerRequestFormValues = {
title: "",
count: 1,
count: "",
desc: "",
expectedDate: "",
attachments: [],
@@ -39,16 +33,16 @@ const initialValues: DesignerRequestFormValues = {
const validationSchema = Yup.object({
title: Yup.string().trim().required("عنوان کاتالوگ الزامی است"),
count: Yup.number().min(1, "حداقل تعداد صفحات ۱ است").max(20, "حداکثر تعداد صفحات ۲۰ است").required("تعداد صفحات الزامی است"),
count: Yup.number()
.transform((value, originalValue) => (originalValue === "" ? undefined : value))
.optional()
.min(1, "حداقل تعداد صفحات ۱ است"),
desc: Yup.string().trim(),
expectedDate: Yup.string().required("زمان تحویل الزامی است"),
attachments: Yup.array().of(Yup.string()),
attachments: Yup.array(),
});
type DesignerRequestFormFieldsProps = FormikProps<DesignerRequestFormValues> & {
uploadFile: ReturnType<typeof useSingleUpload>["mutateAsync"];
isUploading: boolean;
};
type DesignerRequestFormFieldsProps = FormikProps<DesignerRequestFormValues>;
const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
values,
@@ -59,26 +53,12 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
setFieldTouched,
handleChange,
handleBlur,
uploadFile,
isUploading,
}) => {
const totalPrice = values.count * PRICE_PER_PAGE;
const totalPrice = (values.count === "" ? 0 : values.count) * PRICE_PER_PAGE;
const handleAttachmentChange = async (files: File[]) => {
if (files.length === 0) {
await setFieldValue("attachments", []);
const handleAttachmentChange = (files: File[]) => {
setFieldValue("attachments", files);
setFieldTouched("attachments", true);
return;
}
try {
const response = await uploadFile(files[0]);
await setFieldValue("attachments", [response.data.url]);
} catch {
await setFieldValue("attachments", []);
} finally {
setFieldTouched("attachments", true);
}
};
return (
@@ -96,12 +76,16 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
}}
error_text={touched.expectedDate ? errors.expectedDate : undefined}
/>
<Select
<Input
label="تعداد صفحات"
name="count"
value={String(values.count)}
items={pageCountOptions}
onChange={(event) => setFieldValue("count", Number(event.target.value))}
type="number"
isNotRequired
value={values.count}
onChange={(event) => {
const value = event.target.value;
setFieldValue("count", value === "" ? "" : Number(value));
}}
onBlur={handleBlur}
error_text={touched.count ? errors.count : undefined}
/>
@@ -111,7 +95,7 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
<div>
<div className="mb-2 text-sm">فایل های ضمیمه</div>
<UploadBoxDraggble label="فایل مورد نظر را آپلود کنید" onChange={handleAttachmentChange} isMultiple={false} isFile isLoading={isUploading} />
<UploadBoxDraggble label="فایل مورد نظر را آپلود کنید" onChange={handleAttachmentChange} isMultiple isFile isLoading={isSubmitting} loadingLabel="در حال ثبت درخواست..." />
{touched.attachments && errors.attachments ? <Error errorText={String(errors.attachments)} /> : null}
</div>
@@ -126,7 +110,7 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
</div>
<div className="flex justify-end mt-5">
<Button type="submit" className="w-fit px-6" disabled={isSubmitting || isUploading}>
<Button type="submit" className="w-fit px-6" disabled={isSubmitting}>
ثبت درخواست
</Button>
</div>
@@ -136,10 +120,36 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
const DesignerRequest: FC = () => {
usePageTitle("درخواست طراحی");
const { mutateAsync: uploadFile, isPending: isUploading } = useSingleUpload();
const { mutateAsync: uploadFiles } = useMultipleUpload();
const { mutateAsync: initiateDesignRequest } = useInitiateDesignRequest();
const handleSubmit = (values: DesignerRequestFormValues) => {
console.log(values);
const handleSubmit = async (
values: DesignerRequestFormValues,
{ setSubmitting, resetForm }: FormikHelpers<DesignerRequestFormValues>,
) => {
try {
let attachmentUrls: string[] = [];
if (values.attachments.length > 0) {
const uploadResponse = await uploadFiles(values.attachments);
attachmentUrls = uploadResponse.data.map((item) => item.url);
}
await initiateDesignRequest({
title: values.title,
...(values.count !== "" ? { count: values.count } : {}),
desc: values.desc,
expectedDate: values.expectedDate,
attachments: attachmentUrls,
});
toast("درخواست با موفقیت ثبت شد", "success");
resetForm();
} catch (error) {
toast(extractErrorMessage(error), "error");
} finally {
setSubmitting(false);
}
};
return (
@@ -147,7 +157,7 @@ const DesignerRequest: FC = () => {
<h1 className="">درخواست طراحی کاتالوگ</h1>
<div className="rounded-[32px] bg-white p-4 md:p-6 lg:p-8 mt-6">
<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit}>
{(formikProps) => <DesignerRequestFormFields {...formikProps} uploadFile={uploadFile} isUploading={isUploading} />}
{(formikProps) => <DesignerRequestFormFields {...formikProps} />}
</Formik>
</div>
</div>
@@ -0,0 +1,8 @@
import { useMutation } from "@tanstack/react-query";
import * as api from "../service/DesignerService";
export const useInitiateDesignRequest = () => {
return useMutation({
mutationFn: api.initiateDesignRequest,
});
};
@@ -0,0 +1,12 @@
import axios from "@/config/axios";
import type { DesignRequestInitiateParams } from "../types/Types";
export const initiateDesignRequest = async (
params: DesignRequestInitiateParams,
) => {
const { data } = await axios.post(
"/admin/design-request/initiate",
params,
);
return data;
};
+7
View File
@@ -0,0 +1,7 @@
export type DesignRequestInitiateParams = {
title: string;
count?: number;
desc: string;
expectedDate: string;
attachments: string[];
};