167 lines
8.7 KiB
TypeScript
167 lines
8.7 KiB
TypeScript
'use client';
|
|
|
|
import Button from '@/components/button/PrimaryButton';
|
|
import InputField from '@/components/input/InputField';
|
|
import { useFormik } from 'formik';
|
|
import { ArrowLeft } from 'iconsax-react';
|
|
import Image from 'next/image'
|
|
import { useRouter } from 'next/navigation';
|
|
import React from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { CreateReportType } from './types/Types';
|
|
import * as Yup from 'yup';
|
|
import { useCreateReport } from './hooks/useReportData';
|
|
import { toast } from '@/components/Toast';
|
|
import { extractErrorMessage } from '@/lib/func';
|
|
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
|
|
import { ContactScope } from './enum/Enum';
|
|
|
|
type Props = object;
|
|
|
|
function ReportIndex({ }: Props) {
|
|
|
|
const router = useRouter();
|
|
const { mutate: createReport, isPending } = useCreateReport();
|
|
const { t } = useTranslation('parallels', {
|
|
keyPrefix: 'Report'
|
|
})
|
|
|
|
const formik = useFormik<CreateReportType>({
|
|
initialValues: {
|
|
subject: '',
|
|
content: '',
|
|
scope: ContactScope.RESTAURANT,
|
|
},
|
|
validationSchema: Yup.object({
|
|
subject: Yup.string().required('این فیلد اجباری است'),
|
|
content: Yup.string().required('این فیلد اجباری است'),
|
|
scope: Yup.string().oneOf([ContactScope.APPLICATION, ContactScope.RESTAURANT]).required('این فیلد اجباری است'),
|
|
}),
|
|
onSubmit: (values) => {
|
|
createReport(values, {
|
|
onSuccess: () => {
|
|
toast('با موفقیت ثبت شد', 'success');
|
|
formik.resetForm()
|
|
router.back()
|
|
},
|
|
onError: (error) => {
|
|
toast(extractErrorMessage(error), 'error');
|
|
},
|
|
});
|
|
},
|
|
});
|
|
|
|
return (
|
|
<div className='h-full bg-inherit relative flex flex-col lg:gap-4'>
|
|
<div className='grid grid-cols-3 items-center'>
|
|
<span></span>
|
|
<h1 className='text-sm2 place-self-center font-medium'>{t("Heading")}</h1>
|
|
<ArrowLeft
|
|
className='cursor-pointer place-self-end'
|
|
size='24'
|
|
color='currentColor'
|
|
onClick={() => { router.back() }}
|
|
/>
|
|
</div>
|
|
<div className="flex lg:justify-center lg:items-center flex-1 bg-inherit">
|
|
<div className="w-full lg:w-fit lg:h-fit lg:min-w-3/4 lg:min-h-3/4 flex flex-col-reverse lg:grid lg:gap-8 lg:bg-container lg:grid-cols-2 lg:p-8 lg:rounded-container lg:justify-around lg:items-center bg-inherit">
|
|
<form className='flex-1 bg-inherit flex flex-col justify-between items-end' onSubmit={formik.handleSubmit}>
|
|
<div className='bg-inherit pb-4 lg:max-w-4/5 w-full flex flex-col justify-between flex-1'>
|
|
<div className="bg-inherit flex flex-col h-full">
|
|
<div className='w-full px-4 mt-10'>
|
|
<h2 className='text-sm2 font-medium'>{t('FormHeading')}</h2>
|
|
<p className='text-sm2 text-disabled-text mt-2'>{t('Description')}</p>
|
|
</div>
|
|
<InputField
|
|
className='w-full mt-6 px-4 bg-inherit'
|
|
inputClassName='text-xs!'
|
|
type='text'
|
|
placeholder={t('InputTitle.Placeholder')}
|
|
labelText={t('InputTitle.Label')}
|
|
htmlFor='subject'
|
|
name='subject'
|
|
value={formik.values.subject}
|
|
onChange={formik.handleChange}
|
|
onBlur={formik.handleBlur}
|
|
valid={!(formik.touched.subject && formik.errors.subject)}
|
|
aria-errormessage={formik.touched.subject && formik.errors.subject ? formik.errors.subject : undefined}
|
|
/>
|
|
|
|
|
|
|
|
<div className='relative bg-inherit mt-6 flex-1'>
|
|
<textarea
|
|
className={`w-full text-xs! px-4 py-2.5 leading-6 outline-0 border rounded-normal h-full max-h-[200px] min-h-[50px] resize-none focus:ring-0 ${formik.touched.content && formik.errors.content
|
|
? 'border-invalid'
|
|
: 'border-border'
|
|
}`}
|
|
placeholder={t('InputDescription.Placeholder')}
|
|
id='content'
|
|
name='content'
|
|
value={formik.values.content}
|
|
onChange={formik.handleChange}
|
|
onBlur={formik.handleBlur}
|
|
></textarea>
|
|
<span className='absolute -top-2 right-2 px-2 bg-inherit text-foreground text-xs'>
|
|
{t('InputDescription.Label')}
|
|
</span>
|
|
{formik.touched.content && formik.errors.content && (
|
|
<span className='absolute -bottom-5 right-2 px-2 text-xs text-invalid'>
|
|
{formik.errors.content}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className='w-full mt-4 px-4 bg-inherit'>
|
|
<h3 className='text-sm2 font-medium leading-5'>{t('InputScope.Label')}</h3>
|
|
<RadioGroup
|
|
value={formik.values.scope}
|
|
onValueChange={(value) => {
|
|
formik.setFieldValue('scope', value as ContactScope);
|
|
}}
|
|
className='flex flex-col gap-3 mt-2'
|
|
>
|
|
<div className='flex items-center justify-between'>
|
|
<RadioGroupItem value={ContactScope.RESTAURANT} id={`scope-${ContactScope.RESTAURANT}`} />
|
|
<label className='flex items-center gap-2 cursor-pointer' htmlFor={`scope-${ContactScope.RESTAURANT}`}>
|
|
<span className='text-xs mt-0.5'>{t('InputScope.Options.Restaurant')}</span>
|
|
</label>
|
|
</div>
|
|
<div className='flex items-center justify-between'>
|
|
<RadioGroupItem value={ContactScope.APPLICATION} id={`scope-${ContactScope.APPLICATION}`} />
|
|
<label className='flex items-center gap-2 cursor-pointer' htmlFor={`scope-${ContactScope.APPLICATION}`}>
|
|
<span className='text-xs mt-0.5'>{t('InputScope.Options.Application')}</span>
|
|
</label>
|
|
</div>
|
|
</RadioGroup>
|
|
</div>
|
|
</div>
|
|
<Button
|
|
className='w-full px-4 mt-6'
|
|
type='submit'
|
|
disabled={isPending || !formik.isValid}
|
|
>
|
|
{t('ButtonSubmit')}
|
|
</Button>
|
|
</div>
|
|
|
|
</form>
|
|
|
|
<div className='relative'>
|
|
<Image
|
|
className='place-self-center w-full px-4 mt-8 md:max-w-4/5'
|
|
src={'/assets/images/report-hero.svg'}
|
|
height={200}
|
|
width={312}
|
|
unoptimized
|
|
alt='report hero image'
|
|
/>
|
|
<hr className='absolute bottom-0 left-9 right-4 border-border' />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default ReportIndex |