import React, { useState } from 'react'; import { Box, Grid, useToast, Text, Flex, Button, Textarea, FormControl, FormLabel, InputGroup, InputRightElement, Input, } from '@chakra-ui/react'; import { MdCloudUpload } from 'react-icons/md'; import { SubmitHandler, useForm, useWatch, Controller } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import AsyncSelect from '@educt/components/AsyncSelect'; import FileSelect from '@educt/components/FileSelect'; /** * Types */ import { OptionType } from '@educt/types'; import { CourseStatusEnum, UserRoleEnum } from '@educt/enums'; /** * Hooks */ import { useHistory } from 'react-router'; import { useRootStore } from '@educt/hooks/useRootStore'; import { useErrorHandler } from 'react-error-boundary'; import useIsMountedRef from '@educt/hooks/useIsMountedRef'; /** * Schema */ import CreateCourseSchema from './CreateCourseForm.validator'; type CreateCourseInputType = { title: string; image: File; category_id: string; description: string; teacher_id: string; }; type CreateCourseFormProps = {}; const CreateCourseForm: React.FC = () => { const { userStore: { userService }, categoryStore: { categoryService }, courseStore: { courseService }, } = useRootStore(); const { register, handleSubmit, formState: { errors }, control, watch, reset, } = useForm({ resolver: yupResolver(CreateCourseSchema), }); const handleError = useErrorHandler(); const toast = useToast(); const history = useHistory(); const isMountedRef = useIsMountedRef(); const [isLoading, setIsLoading] = useState(false); const [status, setStatus] = useState(undefined); const title = useWatch({ control, name: 'title', defaultValue: '', }); /** * Load users into select field */ const loadUsersOptions = async (): Promise => { try { const users = await userService.fetchAll({ limit: 12, role: UserRoleEnum.TEACHER }); return users.data.map(user => ({ label: user.fullname, value: user.id, })); } catch (error: any) { if (error.response) { toast({ title: 'Error' }); } else { handleError(error); } } }; /** * Load categories into select filed */ const loadCategoriesOptions = async (): Promise => { try { const categories = await categoryService.fetchAll(); return categories.data.map(category => ({ label: category.title, value: category.id, })); } catch (error: any) { if (error.response) { toast({ title: 'Error' }); } else { handleError(error); } } }; /** * Submit form handler */ const onSubmit: SubmitHandler = async data => { try { setIsLoading(true); await courseService.create({ title: data.title, description: data.description, teacher_id: data.teacher_id, category_id: data.category_id, image: data.image, status: status ?? CourseStatusEnum.DRAFT, }); toast({ title: `Course successfully created.`, status: 'success' }); history.push('/courses'); } catch (error: any) { if (error.response) { if (error.response.status === 422) { toast({ title: `${error.response.data.errors[0].message}`, status: 'error' }); } else { toast({ title: `${error.message}`, status: 'error' }); } } else { handleError(error); } } finally { if (isMountedRef.current) { setIsLoading(false); setStatus(undefined); } } }; return (
Title 90 ? 'red.500' : 'gray.500'}> {title.length}/90 } /> {errors.title?.message} Image ( onChange(file)} supportedFormats={['JPG', 'JPEG', 'PNG', 'WEBP']} /> )} /> {errors.image?.message} Category ( onChange(selected)} value={value} placeholder='Select Category' noOptionsMessage='There are no categories.' loadingText='Wait...' /> )} /> {errors.category_id?.message} Teacher ( onChange(selected)} value={value} placeholder='Select Teacher' noOptionsMessage='There are no teachers.' loadingText='Wait...' /> )} /> {errors.teacher_id?.message} Description