summaryrefslogtreecommitdiff
path: root/client/src/components
diff options
context:
space:
mode:
authorMichael Hunteman <michael@huntm.net>2024-07-09 18:24:15 -0700
committerMichael Hunteman <michael@huntm.net>2024-07-09 18:24:44 -0700
commita6b1fa31e890b51b043c4211b14cd4be29ed6fba (patch)
tree66a1fbc182fc3f9ed746958e2854d8a337782983 /client/src/components
parent03ca04fdb738cc151d775b76e1bc38aec792521a (diff)
Add success and error alerts
Diffstat (limited to 'client/src/components')
-rw-r--r--client/src/components/Admin.tsx2
-rw-r--r--client/src/components/GuestLogin.tsx79
-rw-r--r--client/src/components/Rsvp.tsx2
-rw-r--r--client/src/components/RsvpForm.tsx23
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>