diff options
author | Michael Hunteman <michael@huntm.net> | 2024-07-09 18:24:15 -0700 |
---|---|---|
committer | Michael Hunteman <michael@huntm.net> | 2024-07-09 18:24:44 -0700 |
commit | a6b1fa31e890b51b043c4211b14cd4be29ed6fba (patch) | |
tree | 66a1fbc182fc3f9ed746958e2854d8a337782983 /client/src/components | |
parent | 03ca04fdb738cc151d775b76e1bc38aec792521a (diff) |
Add success and error alerts
Diffstat (limited to 'client/src/components')
-rw-r--r-- | client/src/components/Admin.tsx | 2 | ||||
-rw-r--r-- | client/src/components/GuestLogin.tsx | 79 | ||||
-rw-r--r-- | client/src/components/Rsvp.tsx | 2 | ||||
-rw-r--r-- | client/src/components/RsvpForm.tsx | 23 |
4 files changed, 98 insertions, 8 deletions
diff --git a/client/src/components/Admin.tsx b/client/src/components/Admin.tsx index 1c941a5..f1845b4 100644 --- a/client/src/components/Admin.tsx +++ b/client/src/components/Admin.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useGetGuestsQuery } from '../apiSlice'; +import { useGetGuestsQuery } from '../slices/apiSlice'; function Admin() { const { diff --git a/client/src/components/GuestLogin.tsx b/client/src/components/GuestLogin.tsx new file mode 100644 index 0000000..c06bc6e --- /dev/null +++ b/client/src/components/GuestLogin.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; +import { Button, Container, TextField, Typography } from '@mui/material'; +import { useForm } from 'react-hook-form'; +import { setCredentials } from '../slices/authSlice'; +import { useLoginMutation } from '../slices/apiSlice'; +import type { LoginRequest } from '../slices/apiSlice'; + +function GuestLogin() { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [login] = useLoginMutation(); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm<LoginRequest>({ + defaultValues: { + firstName: '', + lastName: '', + }, + }); + + const onSubmit = async (data: LoginRequest) => { + try { + dispatch(setCredentials(await login(data).unwrap())); + navigate('/rsvp'); + } catch (e) { + console.log(e); + } + }; + + return ( + <Container + component="form" + maxWidth="xs" + noValidate + onSubmit={handleSubmit(onSubmit)} + > + <div + style={{ + marginTop: 80, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + }} + > + <Typography variant="h6">Guest Login</Typography> + <TextField + label="First Name" + variant="outlined" + margin="normal" + fullWidth + error={!!errors.firstName} + helperText={errors.firstName?.message} + required + {...register('firstName', { required: 'This field is required' })} + /> + <TextField + label="Last Name" + variant="outlined" + margin="normal" + fullWidth + error={!!errors.lastName} + helperText={errors.lastName?.message} + required + {...register('lastName', { required: 'This field is required' })} + /> + <Button type="submit" variant="contained" fullWidth sx={{ mt: 2 }}> + Log in + </Button> + </div> + </Container> + ); +} + +export default GuestLogin; diff --git a/client/src/components/Rsvp.tsx b/client/src/components/Rsvp.tsx index d908f75..d3d9677 100644 --- a/client/src/components/Rsvp.tsx +++ b/client/src/components/Rsvp.tsx @@ -4,7 +4,7 @@ import { useLocation, Navigate, Outlet } from 'react-router-dom'; import { useSelector } from 'react-redux'; import CssBaseline from '@mui/material/CssBaseline'; import NavBar from './NavBar'; -import { selectCurrentGuest } from '../features/auth/authSlice'; +import { selectCurrentGuest } from '../slices/authSlice'; const authenticate = () => { const guest = useSelector(selectCurrentGuest); diff --git a/client/src/components/RsvpForm.tsx b/client/src/components/RsvpForm.tsx index f20d810..d981053 100644 --- a/client/src/components/RsvpForm.tsx +++ b/client/src/components/RsvpForm.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { useRef } from 'react'; import { useNavigate, useOutletContext } from 'react-router-dom'; import { + Alert, Button, Container, FormControl, @@ -13,11 +14,12 @@ import { TextField, } from '@mui/material'; import { useForm, Controller, useFieldArray } from 'react-hook-form'; -import { useUpdateGuestMutation } from '../apiSlice'; -import type { Guest } from '../apiSlice'; +import { useUpdateGuestMutation } from '../slices/apiSlice'; +import type { Guest } from '../slices/apiSlice'; function RsvpForm() { - const [updateGuest] = useUpdateGuestMutation(); + const [updateGuest, { isSuccess: success, isError: error }] = + useUpdateGuestMutation(); const guest: Guest = useOutletContext(); const previousPartySize = useRef(guest?.partySize - 1); const navigate = useNavigate(); @@ -43,7 +45,6 @@ function RsvpForm() { const onSubmit = async (data: Guest) => { updateGuest({ ...data }); - navigate('/guest/login'); }; const { fields, append, remove } = useFieldArray({ @@ -120,7 +121,7 @@ function RsvpForm() { </FormControl> </div> </Grid> - <Grid item xs={9}> + <Grid item xs={8}> <TextField label="Email" type="email" @@ -128,7 +129,9 @@ function RsvpForm() { fullWidth error={!!errors.email} helperText={errors.email?.message} + required {...register('email', { + required: 'This field is required', pattern: { value: /\S+@\S+\.\S+/, message: 'Please enter a valid email address', @@ -136,7 +139,7 @@ function RsvpForm() { })} /> </Grid> - <Grid item xs={3}> + <Grid item xs={4}> <TextField label="Party Size" type="number" @@ -220,6 +223,14 @@ function RsvpForm() { RSVP </Button> </div> + <div + style={{ marginTop: 16, display: 'flex', justifyContent: 'center' }} + > + <div style={{ width: 180 }}> + {success && <Alert severity="success">RSVP updated</Alert>} + {error && <Alert severity="error">RSVP failed</Alert>} + </div> + </div> </Grid> </Grid> </Container> |