Files
negareh-admin/src/pages/learning/Create.tsx
T
hamid zarghami 69a8bbc779 learning crud
2026-02-22 14:34:22 +03:30

172 lines
7.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { type FC, useState } from 'react'
// import { useTranslation } from 'react-i18next'
import Button from '../../components/Button'
import { useFormik } from 'formik'
import { type CategoryLearningType, type CreateLearningType } from './hooks/useLearningData'
import * as Yup from 'yup'
import { useCreateLearning, useGetCategory } from './hooks/useLearningData'
import { useSingleUpload } from '@/pages/uploader/hooks/useUploader'
import { TickCircle } from 'iconsax-react'
import Input from '../../components/Input'
import UploadBox from '../../components/UploadBox'
import Select from '../../components/Select'
import Textarea from '../../components/Textarea'
import DefaultTableSkeleton from '../../components/DefaultTableSkeleton'
import CreateLearningSidebar from './components/CreateLearningSidebar'
import { toast } from 'react-toastify'
import { useNavigate } from 'react-router-dom'
import { Paths } from '../../config/Paths'
import { extractErrorMessage } from '@/config/func'
const CreateLearning: FC = () => {
const navigate = useNavigate()
// const { t } = useTranslation('global')
const t = (key: string) => key; // Mock translation function
const singleUpload = useSingleUpload()
const createLearning = useCreateLearning()
const getCategory = useGetCategory()
const [videoFile, setVideoFile] = useState<File>()
const [coverFile, setCoverFile] = useState<File>()
const formik = useFormik<CreateLearningType>({
initialValues: {
title: '',
description: '',
coverUrl: '',
videoUrl: '',
videoDuration: '',
categoryId: ''
},
validationSchema: Yup.object().shape({
title: Yup.string().required(t('errors.required')),
description: Yup.string().required(t('errors.required')),
videoDuration: Yup.string().required(t('errors.required')),
categoryId: Yup.string().required(t('errors.required'))
}),
onSubmit: async (values) => {
if (videoFile && coverFile) {
const videoResult = await singleUpload.mutateAsync(videoFile)
values.videoUrl = videoResult?.data?.url ?? ''
const coverResult = await singleUpload.mutateAsync(coverFile)
values.coverUrl = coverResult?.data?.url ?? ''
createLearning.mutate(values, {
onSuccess: () => {
toast.success('با موفقیت ثبت شد')
navigate(Paths.learning.list)
},
onError: (error) => {
toast.error(extractErrorMessage(error))
}
})
} else {
toast.error('لطفا ویدیو و کاور را انتخاب کنید')
}
}
})
return (
<div className='w-full mt-4'>
<div className='flex w-full justify-between items-center'>
<div>
آموزش جدید
</div>
<div>
<Button
className='px-5'
onClick={() => formik.handleSubmit()}
isLoading={createLearning.isPending || singleUpload.isPending}
>
<div className='flex gap-2'>
<TickCircle
className='size-5'
color='black'
/>
<div>ثبت آموزش</div>
</div>
</Button>
</div>
</div>
{
getCategory.isPending ?
<DefaultTableSkeleton tdCount={2} />
:
<div className='flex gap-6'>
<div className='flex-1'>
<div className='flex-1 mt-10 bg-white py-8 xl:px-10 px-4 rounded-3xl'>
<Input
label='عنوان'
name='title'
onChange={formik.handleChange}
error_text={formik.touched.title && formik.errors.title ? formik.errors.title : ''}
/>
<div className='rowTwoInput mt-5'>
<div className='flex-1'>
<UploadBox
label='آپلود کاور'
onChange={(files: File[]) => setCoverFile(files[0])}
/>
</div>
<div className='flex-1'>
<UploadBox
label='آپلود ویدیو'
onChange={(files: File[]) => setVideoFile(files[0])}
/>
</div>
</div>
<div className='rowTwoInput mt-5'>
<Select
items={getCategory.data?.data?.categories?.map((item: CategoryLearningType) => ({ label: item.name, value: item.id.toString() }))}
label='دسته‌بندی'
placeholder='انتخاب کنید'
name='categoryId'
onChange={formik.handleChange}
error_text={formik.touched.categoryId && formik.errors.categoryId ? formik.errors.categoryId : ''}
/>
<Input
name='videoDuration'
label='مدت زمان ویدیو'
onChange={formik.handleChange}
error_text={formik.touched.videoDuration && formik.errors.videoDuration ? formik.errors.videoDuration : ''}
/>
</div>
<div className='mt-5'>
<div>توضیحات</div>
<div>
<Textarea
name='description'
placeholder='توضیحات'
onChange={formik.handleChange}
error_text={formik.touched.description && formik.errors.description ? formik.errors.description : ''}
/>
</div>
</div>
</div>
</div>
<CreateLearningSidebar
onChangeCoverFile={setCoverFile}
onChangeVideoFile={setVideoFile}
/>
</div>
}
</div>
)
}
export default CreateLearning