backend_and_cms/frontend/src/components/AboutUs/AddAboutUs.tsx

218 lines
6.0 KiB
TypeScript

import { useState } from 'react';
import {
Button,
FormControl,
FormErrorMessage,
FormLabel,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
NumberInput,
NumberInputField,
NumberInputStepper,
NumberIncrementStepper,
NumberDecrementStepper,
} from "@chakra-ui/react"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { type SubmitHandler, useForm } from "react-hook-form"
import { type ApiError, type AboutUsCreate, AboutUsService } from "../../client"
import useCustomToast from "../../hooks/useCustomToast"
import { handleError } from "../../utils"
import { EditorState, convertToRaw } from 'draft-js';
import { Editor } from "react-draft-wysiwyg";
import draftToHtml from 'draftjs-to-html';
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
interface AddAboutUsProps {
isOpen: boolean
onClose: () => void
}
// type FileUploadProps = {
// register: UseFormRegisterReturn
// accept?: string
// multiple?: boolean
// children?: ReactNode
// }
// const FileUpload = (props: FileUploadProps) => {
// const { register, accept, multiple, children } = props
// const inputRef = useRef<HTMLInputElement | null>(null)
// const { ref, ...rest } = register as { ref: (instance: HTMLInputElement | null) => void }
// const handleClick = () => inputRef.current?.click()
// return (
// <InputGroup onClick={handleClick}>
// <input
// type={'file'}
// multiple={multiple || false}
// hidden
// accept={accept}
// {...rest}
// ref={(e) => {
// ref(e)
// inputRef.current = e
// }}
// />
// <>
// {children}
// </>
// </InputGroup>
// )
// }
const AddAboutUs = ({ isOpen, onClose }: AddAboutUsProps) => {
const queryClient = useQueryClient()
const showToast = useCustomToast()
const {
register,
handleSubmit,
reset,
formState: { errors, isSubmitting },
} = useForm<AboutUsCreate>({
mode: "onBlur",
criteriaMode: "all",
defaultValues: {
index: 0,
description: "",
image: undefined,
},
})
const [editorState, setEditorState] = useState<EditorState>(EditorState.createEmpty());
const [content, setContent] = useState<string>('');
// const validateFiles = (value: File) => {
// if (typeof value === 'string') return true;
// const fsMb = value.size / (1024 * 1024)
// const MAX_FILE_SIZE = 10
// if (fsMb > MAX_FILE_SIZE) {
// return 'Max file size 10mb'
// }
// return true
// }
// type FormValues = {
// file_: FileList
// }
const mutation = useMutation({
mutationFn: (data: AboutUsCreate) =>
AboutUsService.createAboutUs({ formData: data }),
onSuccess: () => {
showToast("Success!", "About Us created successfully.", "success")
reset()
setEditorState(EditorState.createEmpty());
onClose()
},
onError: (err: ApiError) => {
handleError(err, showToast)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ["aboutUs"] })
},
})
const onSubmit: SubmitHandler<AboutUsCreate> = (data) => {
if (data.image instanceof FileList && data.image.length > 0) {
data.image = data.image[0]
}
mutation.mutate(data)
console.log(data)
}
return (
<>
<Modal
isOpen={isOpen}
onClose={onClose}
size={'xl'}
isCentered
>
<ModalOverlay />
<ModalContent as="form" onSubmit={handleSubmit(onSubmit)}>
<ModalHeader>Add About Us</ModalHeader>
<ModalCloseButton />
<ModalBody pb={30}>
<FormControl isRequired isInvalid={!!errors.description}>
<Editor
editorState={editorState}
wrapperClassName="wrapper-class"
editorClassName="demo-editor"
onEditorStateChange={newState => {
setEditorState(newState);
setContent(draftToHtml(convertToRaw(newState.getCurrentContent())));
reset({
description: content,
});
}}
toolbar={{
options: ['inline', 'blockType', 'fontSize', 'list', 'textAlign', 'history', 'embedded', 'emoji', 'image'],
inline: { inDropdown: true },
list: { inDropdown: true },
textAlign: { inDropdown: true },
link: { inDropdown: true },
history: { inDropdown: true },
}}
/>
</FormControl>
<FormControl isRequired isInvalid={!!errors.index}>
<FormLabel htmlFor="index">Index</FormLabel >
<NumberInput min={0} max={20} >
<NumberInputField {...register("index", {
required: "index is required.",
})} />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
{errors.index && (
<FormErrorMessage>{errors.index.message}</FormErrorMessage>
)}
</FormControl>
<FormControl isInvalid={!!errors.image} isRequired>
<FormLabel>{'Image Upload'}</FormLabel>
<input type="file" {...register("image", {
required: "index is required.",
})} />
<FormErrorMessage>
{errors.image && errors?.image.message}
</FormErrorMessage>
</FormControl>
</ModalBody>
<ModalFooter gap={3}>
<Button variant="primary" type="submit" isLoading={isSubmitting}>
Save
</Button>
<Button onClick={onClose}>Cancel</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
export default AddAboutUs