244 lines
12 KiB
TypeScript
244 lines
12 KiB
TypeScript
import { FC, useState } from 'react'
|
||
import { useTranslation } from 'react-i18next'
|
||
import Input from '../../components/Input'
|
||
import Select from '../../components/Select'
|
||
import Textarea from '../../components/Textarea'
|
||
import UploadBox from '../../components/UploadBox'
|
||
import Button from '../../components/Button'
|
||
import { TickCircle, TickSquare } from 'iconsax-react'
|
||
import { useCreateTicket, useGetCategories } from './hooks/useTicketData'
|
||
import { useGetProfile } from '../profile/hooks/useProfileData'
|
||
import PageLoading from '../../components/PageLoading'
|
||
import { useFormik } from 'formik'
|
||
import * as Yup from 'yup'
|
||
import { ErrorType } from '../../helpers/types'
|
||
import { useNavigate } from 'react-router-dom'
|
||
import { Pages } from '../../config/Pages'
|
||
import { CreateTicketAdminType } from './types/TicketTypes'
|
||
import { toast } from 'react-toastify'
|
||
import { useMultiUpload } from '../service/hooks/useServiceData'
|
||
import { useGetCustomers } from '../customer/hooks/useCustomerData'
|
||
import { CustomerItemType } from '../customer/types/CustomerTypes'
|
||
|
||
const CreateTicket: FC = () => {
|
||
const { t } = useTranslation('global')
|
||
const navigate = useNavigate()
|
||
const [files, setFiles] = useState<File[]>([])
|
||
const getProfile = useGetProfile()
|
||
const getCategories = useGetCategories()
|
||
const multiUpload = useMultiUpload()
|
||
const createTicket = useCreateTicket()
|
||
const getCustomers = useGetCustomers(1, true)
|
||
|
||
|
||
const formik = useFormik<CreateTicketAdminType>({
|
||
initialValues: {
|
||
subject: '',
|
||
message: '',
|
||
categoryId: '',
|
||
priority: 'LOW',
|
||
attachmentUrls: [],
|
||
userId: ''
|
||
},
|
||
validationSchema: Yup.object({
|
||
subject: Yup.string().required(t('errors.required')),
|
||
message: Yup.string().required(t('errors.required')),
|
||
categoryId: Yup.string().required(t('errors.required')),
|
||
priority: Yup.string().required(t('errors.required')),
|
||
}),
|
||
onSubmit: async (values) => {
|
||
if (files.length > 0) {
|
||
const images = new FormData()
|
||
files.forEach(file => {
|
||
images.append('files', file)
|
||
})
|
||
await multiUpload.mutateAsync(images, {
|
||
onSuccess: async (data) => {
|
||
values.attachmentUrls = await data.data.map((item: { url: string }) => item?.url)
|
||
},
|
||
onError: (error: ErrorType) => {
|
||
toast.error(error.response?.data?.error?.message[0])
|
||
}
|
||
})
|
||
} else {
|
||
delete values.attachmentUrls
|
||
}
|
||
|
||
if (values.danakServiceId === '') {
|
||
delete values.danakServiceId
|
||
}
|
||
|
||
|
||
createTicket.mutate(values, {
|
||
onSuccess: (data) => {
|
||
toast.success(t('success'))
|
||
formik.resetForm()
|
||
navigate(Pages.ticket.detail + data.data?.ticketId)
|
||
},
|
||
onError: (error: ErrorType) => {
|
||
toast.error(error.response?.data?.error?.message[0])
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
|
||
return (
|
||
<div className='mt-4 pb-12'>
|
||
<div>
|
||
{t('ticket.new_ticket')}
|
||
</div>
|
||
|
||
{
|
||
getProfile.isPending || getCategories.isPending ?
|
||
<PageLoading />
|
||
:
|
||
<div className='flex gap-6 xl:mt-8 mt-4'>
|
||
<div className='flex-1 bg-white py-8 xl:px-10 px-4 rounded-3xl'>
|
||
<div>
|
||
{t('ticket.submit_your_message')}
|
||
</div>
|
||
|
||
<div className='mt-5'>
|
||
<Select
|
||
label={t('receip.customer')}
|
||
placeholder={t('select')}
|
||
items={getCustomers.data?.data?.customers?.map((item: CustomerItemType) => {
|
||
return {
|
||
label: item.firstName + ' ' + item.lastName,
|
||
value: item.id
|
||
}
|
||
})}
|
||
{...formik.getFieldProps('userId')}
|
||
/>
|
||
</div>
|
||
|
||
|
||
<div className='mt-6 rowTwoInput'>
|
||
<Input
|
||
label={t('ticket.subject')}
|
||
placeholder={t('ticket.enter_your_subject')}
|
||
name='subject'
|
||
value={formik.values.subject}
|
||
onChange={formik.handleChange}
|
||
error_text={formik.touched.subject && formik.errors.subject ? formik.errors.subject : ''}
|
||
/>
|
||
<Select
|
||
label={t('ticket.priority')}
|
||
items={[
|
||
{
|
||
label: t('ticket.low'),
|
||
value: 'LOW'
|
||
},
|
||
{
|
||
label: t('ticket.medium'),
|
||
value: 'MEDIUM'
|
||
},
|
||
{
|
||
label: t('ticket.high'),
|
||
value: 'HIGH'
|
||
}
|
||
]}
|
||
placeholder={t('select')}
|
||
className='border'
|
||
name='priority'
|
||
value={formik.values.priority}
|
||
onChange={formik.handleChange}
|
||
error_text={formik.touched.priority && formik.errors.priority ? formik.errors.priority : ''}
|
||
/>
|
||
</div>
|
||
|
||
<div className='mt-6 rowTwoInput'>
|
||
|
||
<Select
|
||
label={t('ticket.category')}
|
||
items={getCategories.data?.data?.ticketCategories?.map((item: { id: string, title: string }) => ({
|
||
label: item.title,
|
||
value: item.id
|
||
})
|
||
)}
|
||
placeholder={t('select')}
|
||
className='border'
|
||
name='categoryId'
|
||
value={formik.values.categoryId}
|
||
onChange={formik.handleChange}
|
||
error_text={formik.touched.categoryId && formik.errors.categoryId ? formik.errors.categoryId : ''}
|
||
/>
|
||
</div>
|
||
<div className='mt-6'>
|
||
<Textarea
|
||
label={t('description')}
|
||
placeholder={t('ticket.your_description')}
|
||
name='message'
|
||
value={formik.values.message}
|
||
onChange={formik.handleChange}
|
||
error_text={formik.touched.message && formik.errors.message ? formik.errors.message : ''}
|
||
/>
|
||
</div>
|
||
|
||
<div className='mt-6'>
|
||
<UploadBox
|
||
label={t('ticket.attachment')}
|
||
isMultiple
|
||
onChange={setFiles}
|
||
/>
|
||
</div>
|
||
|
||
<div className='mt-8 flex justify-end'>
|
||
<Button
|
||
className='xl:max-w-[100px]'
|
||
onClick={() => formik.handleSubmit()}
|
||
isLoading={createTicket.isPending || multiUpload.isPending}
|
||
>
|
||
<div className='flex gap-2 items-center'>
|
||
<TickCircle size={20} color='white' />
|
||
<div>
|
||
{t('ticket.send')}
|
||
</div>
|
||
</div>
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className='bg-white w-sidebar xl:block hidden py-10 px-5 h-fit rounded-3xl'>
|
||
<div className='text-sm'>
|
||
{t('ticket.title_hint')}
|
||
</div>
|
||
|
||
<div className='mt-6'>
|
||
<div className='flex items-start gap-2 border-b pb-5'>
|
||
<div>
|
||
<TickSquare size={20} color='black' variant='Bold' />
|
||
</div>
|
||
<div className='text-description text-xs leading-5'>
|
||
سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید.
|
||
</div>
|
||
</div>
|
||
<div className='flex items-start gap-2 mt-6 border-b pb-5'>
|
||
<div>
|
||
<TickSquare size={20} color='black' variant='Bold' />
|
||
</div>
|
||
<div className='text-description text-xs leading-5'>
|
||
لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است.
|
||
</div>
|
||
</div>
|
||
<div className='flex items-start gap-2 mt-6'>
|
||
<div>
|
||
<TickSquare size={20} color='black' variant='Bold' />
|
||
</div>
|
||
<div className='text-description text-xs leading-5'>
|
||
پاسخگویی 24 ساعته تلفنی را تنها از داناک می توانید انتظار داشته باشید .بخش پشتیبانی در هر ساعتی حتی در روز های تعطیل آماده پیگیری سریع مشکلات کاربران است.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
|
||
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default CreateTicket |