import { Button } from '@headlessui/react' import { zodResolver } from '@hookform/resolvers/zod' import { useEffect, useState, type ChangeEvent } from 'react' import { useFetcher } from 'react-router' import { RemixFormProvider, useRemixForm } from 'remix-hook-form' import { z } from 'zod' import { uploadCategorySchema, useAdminContext } from '~/contexts/admin' export const uploadSchema = z.object({ file: z.instanceof(File), category: uploadCategorySchema, }) export type TUploadSchema = z.infer export const FormUpload = () => { const { isUploadOpen, setUploadedFile, setIsUploadOpen } = useAdminContext() const fetcher = useFetcher() const [disabled, setDisabled] = useState(false) const [error, setError] = useState() const maxFileSize = 1024 // 1MB const formMethods = useRemixForm({ mode: 'onSubmit', fetcher, resolver: zodResolver(uploadSchema), }) const { handleSubmit, register, setValue } = formMethods useEffect(() => { if (!fetcher.data?.success) { setError(fetcher.data?.message) setDisabled(false) return } setUploadedFile(fetcher.data.uploadData.data.file_url) setIsUploadOpen(undefined) setDisabled(true) setError(undefined) // eslint-disable-next-line react-hooks/exhaustive-deps }, [fetcher]) const handleChange = async function (event: ChangeEvent) { event.preventDefault() if (event.target.files && event.target.files[0]) { const files: File[] = [...event.target.files] onChange(files, event) } } const onChange = async function ( files: File[], event: ChangeEvent, ) { const file = files[0] const img = new Image() if (!file.type.startsWith('image/')) { setError('Please upload an image file.') return } if (file.size > maxFileSize * 1024) { setError(`File size is too big!`) return } img.addEventListener('load', () => { handleFiles(event) }) img.src = URL.createObjectURL(file) } const handleFiles = (event: ChangeEvent) => { const files = event.target.files if (files && files.length > 0) { const file = files[0] setValue('file', file) } } return ( {error && (
{error}
)}
) }