@@ -2,36 +2,30 @@ import Button from "@/components/Button";
import DatePicker from "@/components/DatePicker" ;
import DatePicker from "@/components/DatePicker" ;
import Error from "@/components/Error" ;
import Error from "@/components/Error" ;
import Input from "@/components/Input" ;
import Input from "@/components/Input" ;
import Select from "@/components/Select" ;
import Textarea from "@/components/Textarea" ;
import Textarea from "@/components/Textarea" ;
import { toast } from "@/components/Toast" ;
import UploadBoxDraggble from "@/components/UploadBoxDraggble" ;
import UploadBoxDraggble from "@/components/UploadBoxDraggble" ;
import { extractErrorMessage } from "@/helpers/utils" ;
import { usePageTitle } from "@/hooks/usePageTitle" ;
import { usePageTitle } from "@/hooks/usePageTitle" ;
import { useSingleUpload } from "@/pages/upload er/hooks/useUpload erData" ;
import { useInitiateDesignRequest } from "@/pages/design er/hooks/useDesign erData" ;
import { Form , Formik , type FormikProps } from "formik ";
import { useMultipleUpload } from "@/pages/uploader/hooks/useUploaderData ";
import { Form , Formik , type FormikHelpers , type FormikProps } from "formik" ;
import { type FC } from "react" ;
import { type FC } from "react" ;
import * as Yup from "yup" ;
import * as Yup from "yup" ;
const PRICE_PER_PAGE = 1000 ;
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 = {
export type DesignerRequestFormValues = {
title : string ;
title : string ;
count : number ;
count : number | "" ;
desc : string ;
desc : string ;
expectedDate : string ;
expectedDate : string ;
attachments : string [ ] ;
attachments : File [ ] ;
} ;
} ;
const initialValues : DesignerRequestFormValues = {
const initialValues : DesignerRequestFormValues = {
title : "" ,
title : "" ,
count : 1 ,
count : "" ,
desc : "" ,
desc : "" ,
expectedDate : "" ,
expectedDate : "" ,
attachments : [ ] ,
attachments : [ ] ,
@@ -39,16 +33,16 @@ const initialValues: DesignerRequestFormValues = {
const validationSchema = Yup . object ( {
const validationSchema = Yup . object ( {
title : Yup.string ( ) . trim ( ) . required ( "عنوان کاتالوگ الزامی است" ) ,
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 ( ) ,
desc : Yup.string ( ) . trim ( ) ,
expectedDate : Yup.string ( ) . required ( "زمان تحویل الزامی است" ) ,
expectedDate : Yup.string ( ) . required ( "زمان تحویل الزامی است" ) ,
attachments : Yup.array ( ) . of ( Yup . string ( ) ) ,
attachments : Yup.array ( ) ,
} ) ;
} ) ;
type DesignerRequestFormFieldsProps = FormikProps < DesignerRequestFormValues > & {
type DesignerRequestFormFieldsProps = FormikProps < DesignerRequestFormValues > ;
uploadFile : ReturnType < typeof useSingleUpload > [ "mutateAsync" ] ;
isUploading : boolean ;
} ;
const DesignerRequestFormFields : FC < DesignerRequestFormFieldsProps > = ( {
const DesignerRequestFormFields : FC < DesignerRequestFormFieldsProps > = ( {
values ,
values ,
@@ -59,26 +53,12 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
setFieldTouched ,
setFieldTouched ,
handleChange ,
handleChange ,
handleBlur ,
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 [ ] ) = > {
const handleAttachmentChange = ( files : File [ ] ) = > {
if ( files . length === 0 ) {
setFieldValue ( "attachments" , files ) ;
await setFieldValue ( "attachments" , [ ] ) ;
setFieldTouched ( "attachments" , true ) ;
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 (
return (
@@ -96,12 +76,16 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
} }
} }
error_text = { touched . expectedDate ? errors.expectedDate : undefined }
error_text = { touched . expectedDate ? errors.expectedDate : undefined }
/ >
/ >
< Select
< Input
label = "تعداد صفحات"
label = "تعداد صفحات"
name = "count"
name = "count"
value = { String ( values . count ) }
type = "number"
items = { pageCountOptions }
isNotRequired
onChange = { ( event ) = > setFieldValue ( "count" , Number ( event . target . value ) ) }
value = { values . count }
onChange = { ( event ) = > {
const value = event . target . value ;
setFieldValue ( "count" , value === "" ? "" : Number ( value ) ) ;
} }
onBlur = { handleBlur }
onBlur = { handleBlur }
error_text = { touched . count ? errors.count : undefined }
error_text = { touched . count ? errors.count : undefined }
/ >
/ >
@@ -111,7 +95,7 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
< div >
< div >
< div className = "mb-2 text-sm" > ف ا ی ل ه ا ی ض م ی م ه < / 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 }
{ touched . attachments && errors . attachments ? < Error errorText = { String ( errors . attachments ) } / > : null }
< / div >
< / div >
@@ -126,7 +110,7 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
< / div >
< / div >
< div className = "flex justify-end mt-5" >
< 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 >
< / Button >
< / div >
< / div >
@@ -136,10 +120,36 @@ const DesignerRequestFormFields: FC<DesignerRequestFormFieldsProps> = ({
const DesignerRequest : FC = ( ) = > {
const DesignerRequest : FC = ( ) = > {
usePageTitle ( "درخواست طراحی" ) ;
usePageTitle ( "درخواست طراحی" ) ;
const { mutateAsync : uploadFile , isPending : isUploading } = useSingleUpload ( ) ;
const { mutateAsync : uploadFiles } = useMultipleUpload ( ) ;
const { mutateAsync : initiateDesignRequest } = useInitiateDesignRequest ( ) ;
const handleSubmit = ( values : DesignerRequestFormValues ) = > {
const handleSubmit = async (
console . log ( values ) ;
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 (
return (
@@ -147,7 +157,7 @@ const DesignerRequest: FC = () => {
< h1 className = "" > د ر خ و ا س ت ط ر ا ح ی ک ا ت ا ل و گ < / h1 >
< h1 className = "" > د ر خ و ا س ت ط ر ا ح ی ک ا ت ا ل و گ < / h1 >
< div className = "rounded-[32px] bg-white p-4 md:p-6 lg:p-8 mt-6" >
< div className = "rounded-[32px] bg-white p-4 md:p-6 lg:p-8 mt-6" >
< Formik initialValues = { initialValues } validationSchema = { validationSchema } onSubmit = { handleSubmit } >
< Formik initialValues = { initialValues } validationSchema = { validationSchema } onSubmit = { handleSubmit } >
{ ( formikProps ) = > < DesignerRequestFormFields { ...formikProps } uploadFile = { uploadFile } isUploading = { isUploading } / > }
{ ( formikProps ) = > < DesignerRequestFormFields { ...formikProps } / > }
< / Formik >
< / Formik >
< / div >
< / div >
< / div >
< / div >