import { useState } from 'react' import { useRouter } from 'next/router' import { mutate } from 'swr' interface FormData { name: string owner_name: string species: string age: number poddy_trained: boolean diet: string[] image_url: string likes: string[] dislikes: string[] } interface Error { name?: string owner_name?: string species?: string image_url?: string } type Props = { formId: string petForm: FormData forNewPet?: boolean } const Form = ({ formId, petForm, forNewPet = true }: Props) => { const router = useRouter() const contentType = 'application/json' const [errors, setErrors] = useState({}) const [message, setMessage] = useState('') const [form, setForm] = useState({ name: petForm.name, owner_name: petForm.owner_name, species: petForm.species, age: petForm.age, poddy_trained: petForm.poddy_trained, diet: petForm.diet, image_url: petForm.image_url, likes: petForm.likes, dislikes: petForm.dislikes, }) /* The PUT method edits an existing entry in the mongodb database. */ const putData = async (form: FormData) => { const { id } = router.query try { const res = await fetch(`/api/pets/${id}`, { method: 'PUT', headers: { Accept: contentType, 'Content-Type': contentType, }, body: JSON.stringify(form), }) // Throw error with status code in case Fetch API req failed if (!res.ok) { throw new Error(res.status.toString()) } const { data } = await res.json() mutate(`/api/pets/${id}`, data, false) // Update the local data without a revalidation router.push('/') } catch (error) { setMessage('Failed to update pet') } } /* The POST method adds a new entry in the mongodb database. */ const postData = async (form: FormData) => { try { const res = await fetch('/api/pets', { method: 'POST', headers: { Accept: contentType, 'Content-Type': contentType, }, body: JSON.stringify(form), }) // Throw error with status code in case Fetch API req failed if (!res.ok) { throw new Error(res.status.toString()) } router.push('/') } catch (error) { setMessage('Failed to add pet') } } const handleChange = ( e: React.ChangeEvent ) => { const target = e.target const value = target.name === 'poddy_trained' ? (target as HTMLInputElement).checked : target.value const name = target.name setForm({ ...form, [name]: value, }) } /* Makes sure pet info is filled for pet name, owner name, species, and image url*/ const formValidate = () => { let err: Error = {} if (!form.name) err.name = 'Name is required' if (!form.owner_name) err.owner_name = 'Owner is required' if (!form.species) err.species = 'Species is required' if (!form.image_url) err.image_url = 'Image URL is required' return err } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() const errs = formValidate() if (Object.keys(errs).length === 0) { forNewPet ? postData(form) : putData(form) } else { setErrors({ errs }) } } return ( <>