From 096a08708e2310becba56a237ef63b5cf6e3c4c4 Mon Sep 17 00:00:00 2001 From: Michael Hunteman Date: Sun, 25 Aug 2024 12:44:32 -0700 Subject: Add admin dashboard --- client/src/components/Admin.tsx | 29 ++++++++++++ client/src/components/AdminLogin.tsx | 90 ++++++++++++++++++++++++++++++++++++ client/src/components/Dashboard.tsx | 60 ++++++++++++++++++++++++ client/src/components/GuestLogin.tsx | 14 +++--- client/src/components/Rsvp.tsx | 4 +- client/src/components/RsvpForm.tsx | 4 +- 6 files changed, 190 insertions(+), 11 deletions(-) create mode 100644 client/src/components/Admin.tsx create mode 100644 client/src/components/AdminLogin.tsx create mode 100644 client/src/components/Dashboard.tsx (limited to 'client/src/components') diff --git a/client/src/components/Admin.tsx b/client/src/components/Admin.tsx new file mode 100644 index 0000000..6e772ab --- /dev/null +++ b/client/src/components/Admin.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { useMemo } from 'react'; +import { useLocation, Navigate, Outlet } from 'react-router-dom'; +import { useSelector } from 'react-redux'; +import CssBaseline from '@mui/material/CssBaseline'; +import NavBar from './NavBar'; +import { selectGuests } from '../slices/auth/adminSlice'; + +const authenticate = () => { + const guests = useSelector(selectGuests); + return useMemo(() => ({ guests }), [guests]); +}; + +function Rsvp() { + const auth = authenticate(); + const location = useLocation(); + + return auth?.guests ? ( + <> + + + + + ) : ( + + ); +} + +export default Rsvp; diff --git a/client/src/components/AdminLogin.tsx b/client/src/components/AdminLogin.tsx new file mode 100644 index 0000000..d9c1260 --- /dev/null +++ b/client/src/components/AdminLogin.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; +import { Button, Paper, TextField, Typography } from '@mui/material'; +import { useForm } from 'react-hook-form'; +import { setAdmin } from '../slices/auth/adminSlice'; +import { useLoginAdminMutation } from '../slices/api/adminSlice'; +import type { AdminLoginRequest } from '../slices/api/adminSlice'; + +function GuestLogin() { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const [login] = useLoginAdminMutation(); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + defaultValues: { + username: '', + password: '', + }, + }); + + const onSubmit = async (data: AdminLoginRequest) => { + try { + dispatch(setAdmin(await login(data).unwrap())); + navigate('/dashboard'); + } catch (e) { + console.log(e); + } + }; + + return ( +
+ + Admin Login + + + + +
+ ); +} + +export default GuestLogin; diff --git a/client/src/components/Dashboard.tsx b/client/src/components/Dashboard.tsx new file mode 100644 index 0000000..20758fc --- /dev/null +++ b/client/src/components/Dashboard.tsx @@ -0,0 +1,60 @@ +import React, { useMemo } from 'react'; +import { useOutletContext } from 'react-router-dom'; +import { + MaterialReactTable, + useMaterialReactTable, + type MRT_ColumnDef, +} from 'material-react-table'; +import type { Guest } from '../slices/api/adminSlice'; + +function Dashboard() { + const guests: Guest[] = useOutletContext(); + const columns = useMemo[]>( + () => [ + { + accessorKey: 'firstName', + header: 'First Name', + size: 150, + }, + { + accessorKey: 'lastName', + header: 'Last Name', + size: 150, + }, + { + accessorKey: 'attendance', + header: 'Attendance', + size: 50, + }, + { + accessorKey: 'email', + header: 'Email', + size: 150, + }, + { + accessorKey: 'message', + header: 'Message', + size: 200, + }, + { + accessorKey: 'partySize', + header: 'Party Size', + size: 50, + }, + // { + // accessorKey: 'partyList', + // header: 'Party List', + // size: 150, + // }, + ], + [] + ); + const table = useMaterialReactTable({ + columns, + data: guests, + }); + + return ; +} + +export default Dashboard; diff --git a/client/src/components/GuestLogin.tsx b/client/src/components/GuestLogin.tsx index cca2179..0e47384 100644 --- a/client/src/components/GuestLogin.tsx +++ b/client/src/components/GuestLogin.tsx @@ -3,29 +3,29 @@ import { useNavigate } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { Button, Paper, 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'; +import { setGuest } from '../slices/auth/guestSlice'; +import { useLoginGuestMutation } from '../slices/api/guestSlice'; +import type { GuestLoginRequest } from '../slices/api/guestSlice'; function GuestLogin() { const dispatch = useDispatch(); const navigate = useNavigate(); - const [login] = useLoginMutation(); + const [login] = useLoginGuestMutation(); const { register, handleSubmit, formState: { errors }, - } = useForm({ + } = useForm({ defaultValues: { firstName: '', lastName: '', }, }); - const onSubmit = async (data: LoginRequest) => { + const onSubmit = async (data: GuestLoginRequest) => { try { - dispatch(setCredentials(await login(data).unwrap())); + dispatch(setGuest(await login(data).unwrap())); navigate('/rsvp'); } catch (e) { console.log(e); diff --git a/client/src/components/Rsvp.tsx b/client/src/components/Rsvp.tsx index d3d9677..ab83cd7 100644 --- a/client/src/components/Rsvp.tsx +++ b/client/src/components/Rsvp.tsx @@ -4,10 +4,10 @@ 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 '../slices/authSlice'; +import { selectGuest } from '../slices/auth/guestSlice'; const authenticate = () => { - const guest = useSelector(selectCurrentGuest); + const guest = useSelector(selectGuest); return useMemo(() => ({ guest }), [guest]); }; diff --git a/client/src/components/RsvpForm.tsx b/client/src/components/RsvpForm.tsx index 1e03227..d72b92d 100644 --- a/client/src/components/RsvpForm.tsx +++ b/client/src/components/RsvpForm.tsx @@ -16,8 +16,8 @@ import { } from '@mui/material'; import MailIcon from '@mui/icons-material/Mail'; import { useForm, Controller, useFieldArray } from 'react-hook-form'; -import { useUpdateGuestMutation } from '../slices/apiSlice'; -import type { Guest } from '../slices/apiSlice'; +import { useUpdateGuestMutation } from '../slices/api/guestSlice'; +import type { Guest } from '../slices/api/guestSlice'; interface StatusProps { isError: boolean; -- cgit v1.2.3