diff options
author | Michael Hunteman <michael@huntm.net> | 2024-03-18 19:23:16 -0700 |
---|---|---|
committer | Michael Hunteman <michael@huntm.net> | 2024-03-18 19:23:16 -0700 |
commit | 288214312525e5a23d44f20c952ae9098f902b49 (patch) | |
tree | 469232346b5dc47e0e6a0d5560617bb5ac110823 | |
parent | 3c878200e4fb012de5a4ac0b93377a6643e33027 (diff) |
Update form based on party size
-rw-r--r-- | src/components/RsvpForm.tsx | 84 |
1 files changed, 81 insertions, 3 deletions
diff --git a/src/components/RsvpForm.tsx b/src/components/RsvpForm.tsx index 56d8c62..7173f32 100644 --- a/src/components/RsvpForm.tsx +++ b/src/components/RsvpForm.tsx @@ -9,20 +9,37 @@ import { RadioGroup, TextField, } from '@mui/material'; -import { useForm, Controller } from 'react-hook-form'; +import { useForm, Controller, useFieldArray } from 'react-hook-form'; import { useOutletContext } from 'react-router-dom'; import { useUpdateGuestMutation, Guest } from '../apiSlice'; +import { useState } from 'react'; + +type FormValues = { + id: number; + firstName: string; + lastName: string; + attendance: string; + email: string; + partySize: number; + message: string; + partyList: { + firstName: string; + lastName: string; + }[]; +}; function RsvpForm() { const [updateGuest] = useUpdateGuestMutation(); const guest: Guest = useOutletContext(); + const [previousPartySize, setPreviousPartySize] = useState(1); const { register, handleSubmit, control, + watch, formState: { errors }, - } = useForm({ + } = useForm<FormValues>({ defaultValues: { id: guest?.id, firstName: guest?.firstName, @@ -38,6 +55,34 @@ function RsvpForm() { updateGuest({ ...data }); }; + const { fields, append, remove } = useFieldArray({ + control, + name: 'partyList', + }); + + const handleParty = () => { + const partySize = Number(watch('partySize')); + if (partySize > previousPartySize && partySize > 1 && partySize < 10) { + append( + new Array(partySize - previousPartySize).fill({ + firstName: '', + lastName: '', + }) + ); + setPreviousPartySize(partySize); + } else if (partySize < previousPartySize && partySize > 0) { + remove( + [...Array(previousPartySize - partySize).keys()].map( + (_, i) => partySize + i - 1 + ) + ); + setPreviousPartySize(partySize); + } else { + // TODO: use react-hook-form setError + console.log('error'); + } + }; + return ( <Container component="form" @@ -47,7 +92,7 @@ function RsvpForm() { > <Grid container spacing={2} sx={{ mt: 8 }}> <Grid item xs={12}> - <p> + <p style={{ textAlign: 'center' }}> Please RSVP for the wedding by March 10, 2025. The ceremony will commence at 3 pm on April 26 in Divine Shepherd. The reception will follow at 5 pm in A Venue on the Ridge. @@ -110,6 +155,7 @@ function RsvpForm() { helperText={errors.partySize?.message} required {...register('partySize', { + onChange: handleParty, required: 'This field is required', min: { value: 1, message: 'Please enter a positive integer' }, max: { @@ -129,6 +175,38 @@ function RsvpForm() { {...register('message')} /> </Grid> + {fields.map((field, index) => { + return ( + <Grid container item columnSpacing={2} key={field.id}> + <Grid item xs={12} md={6} lg={6}> + <TextField + label="First Name" + variant="outlined" + fullWidth + error={!!errors.partyList?.[index]?.firstName} + helperText={errors.partyList?.[index]?.firstName?.message} + required + {...register(`partyList.${index}.firstName`, { + required: 'This field is required', + })} + /> + </Grid> + <Grid item xs={12} md={6} lg={6}> + <TextField + label="Last Name" + variant="outlined" + fullWidth + error={!!errors.partyList?.[index]?.lastName} + helperText={errors.partyList?.[index]?.lastName?.message} + required + {...register(`partyList.${index}.lastName`, { + required: 'This field is required', + })} + /> + </Grid> + </Grid> + ); + })} <Grid item xs={12}> <div style={{ |