From aacf26f374f48b88d532d1528d9d07aabf537610 Mon Sep 17 00:00:00 2001 From: Michael Hunteman Date: Sat, 5 Oct 2024 11:06:50 -0700 Subject: Add calendar invite --- client/src/components/AdminLogin.tsx | 2 +- client/src/components/CalendarDialog.tsx | 71 +++++++++++++++++++++++++++ client/src/components/GlobalSnackbar.test.tsx | 2 +- client/src/components/GlobalSnackbar.tsx | 6 +-- client/src/components/GuestLogin.tsx | 2 +- client/src/components/RsvpForm.tsx | 2 +- client/src/components/Schedule.test.tsx | 22 +++++++++ client/src/components/Schedule.tsx | 32 +++++++++++- 8 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 client/src/components/CalendarDialog.tsx create mode 100644 client/src/components/Schedule.test.tsx (limited to 'client/src/components') diff --git a/client/src/components/AdminLogin.tsx b/client/src/components/AdminLogin.tsx index a4fce8d..bfc96d2 100644 --- a/client/src/components/AdminLogin.tsx +++ b/client/src/components/AdminLogin.tsx @@ -5,7 +5,7 @@ import { useForm } from 'react-hook-form'; import { useAppDispatch } from '../hooks'; import { setAdmin } from '../slices/auth/adminSlice'; import { useLoginAdminMutation } from '../slices/api/adminSlice'; -import { showSnackbar } from '../slices/snackbarSlice'; +import { showSnackbar } from '../slices/uiSlice'; import { isFetchBaseQueryError } from '../error'; import type { Credentials } from '../models'; import type { Data } from '../error'; diff --git a/client/src/components/CalendarDialog.tsx b/client/src/components/CalendarDialog.tsx new file mode 100644 index 0000000..cff5512 --- /dev/null +++ b/client/src/components/CalendarDialog.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import { + Dialog, + DialogContent, + DialogContentText, + DialogTitle, + IconButton, + useTheme, +} from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import { useAppDispatch, useAppSelector } from '../hooks'; +import { hideDialog, selectUIState } from '../slices/uiSlice'; + +function CalendarDialog() { + const dispatch = useAppDispatch(); + const { dialogOpen } = useAppSelector(selectUIState); + const theme = useTheme(); + + const handleClose = () => { + dispatch(hideDialog()); + }; + + return ( + + + Calendar Invitation + + ({ + position: 'absolute', + right: 8, + top: 8, + color: theme.palette.grey[500], + })} + > + + + + + Scan the QR code or click the link below to add the calendar invite to + your device. + + + + Add to calendar + + + + ); +} + +export default CalendarDialog; diff --git a/client/src/components/GlobalSnackbar.test.tsx b/client/src/components/GlobalSnackbar.test.tsx index 2643816..ce6a6ba 100644 --- a/client/src/components/GlobalSnackbar.test.tsx +++ b/client/src/components/GlobalSnackbar.test.tsx @@ -4,7 +4,7 @@ import { describe, expect, it } from 'vitest'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; import { renderWithProviders } from '../renderWithProviders'; import routes from '../routes'; -import { showSnackbar } from '../slices/snackbarSlice'; +import { showSnackbar } from '../slices/uiSlice'; import setupStore from '../store'; describe('Global Snackbar', async () => { diff --git a/client/src/components/GlobalSnackbar.tsx b/client/src/components/GlobalSnackbar.tsx index c4457af..83d6582 100644 --- a/client/src/components/GlobalSnackbar.tsx +++ b/client/src/components/GlobalSnackbar.tsx @@ -1,18 +1,18 @@ import React from 'react'; import { Alert, Snackbar } from '@mui/material'; import { useAppDispatch, useAppSelector } from '../hooks'; -import { hideSnackbar, selectSnackbarState } from '../slices/snackbarSlice'; +import { hideSnackbar, selectUIState } from '../slices/uiSlice'; function GlobalSnackbar() { const dispatch = useAppDispatch(); - const { open, message, severity } = useAppSelector(selectSnackbarState); + const { snackbarOpen, message, severity } = useAppSelector(selectUIState); const handleClose = () => { dispatch(hideSnackbar()); }; return ( - +
{message} diff --git a/client/src/components/GuestLogin.tsx b/client/src/components/GuestLogin.tsx index 2f5a3eb..c2bfeb9 100644 --- a/client/src/components/GuestLogin.tsx +++ b/client/src/components/GuestLogin.tsx @@ -5,7 +5,7 @@ import { useForm } from 'react-hook-form'; import { useAppDispatch } from '../hooks'; import { setGuest } from '../slices/auth/guestSlice'; import { useLoginGuestMutation } from '../slices/api/guestSlice'; -import { showSnackbar } from '../slices/snackbarSlice'; +import { showSnackbar } from '../slices/uiSlice'; import { isFetchBaseQueryError } from '../error'; import type { Data } from '../error'; import type { Name } from '../models'; diff --git a/client/src/components/RsvpForm.tsx b/client/src/components/RsvpForm.tsx index eae34c3..2a3552f 100644 --- a/client/src/components/RsvpForm.tsx +++ b/client/src/components/RsvpForm.tsx @@ -17,7 +17,7 @@ import { useForm, Controller, useFieldArray } from 'react-hook-form'; import { useAppDispatch } from '../hooks'; import { useUpdateGuestMutation } from '../slices/api/guestSlice'; import { isFetchBaseQueryError } from '../error'; -import { showSnackbar } from '../slices/snackbarSlice'; +import { showSnackbar } from '../slices/uiSlice'; import type { Data } from '../error'; import type { Guest } from '../models'; diff --git a/client/src/components/Schedule.test.tsx b/client/src/components/Schedule.test.tsx new file mode 100644 index 0000000..76f0f91 --- /dev/null +++ b/client/src/components/Schedule.test.tsx @@ -0,0 +1,22 @@ +import '@testing-library/jest-dom'; +import React from 'react'; +import { fireEvent } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; +import { describe, expect, it } from 'vitest'; +import { createMemoryRouter, RouterProvider } from 'react-router-dom'; +import { renderWithProviders } from '../renderWithProviders'; +import routes from '../routes'; + +describe('Schedule', async () => { + const memoryRouter = createMemoryRouter(routes, { + initialEntries: ['/schedule'], + }); + it('displays calendar dialog', async () => { + const { getByLabelText, findByText } = renderWithProviders( + + ); + + fireEvent.click(getByLabelText(/insert invitation/i)); + expect(await findByText(/calendar invitation/i)).toBeInTheDocument(); + }); +}); diff --git a/client/src/components/Schedule.tsx b/client/src/components/Schedule.tsx index 0ce7e4c..64140e4 100644 --- a/client/src/components/Schedule.tsx +++ b/client/src/components/Schedule.tsx @@ -1,10 +1,25 @@ import React from 'react'; -import { Paper, Typography, useMediaQuery, useTheme } from '@mui/material'; +import { + IconButton, + Paper, + Typography, + useMediaQuery, + useTheme, +} from '@mui/material'; import divineShepherd from '/divine-shepherd.jpg'; +import InsertInvitationIcon from '@mui/icons-material/InsertInvitation'; +import { useAppDispatch } from '../hooks'; +import { showDialog } from '../slices/uiSlice'; function Schedule() { + const dispatch = useAppDispatch(); const theme = useTheme(); const isMobile = useMediaQuery('(max-width: 768px)'); + + const handleOpen = () => { + dispatch(showDialog()); + }; + return (

April 26, 2025

-
+
Wedding Schedule + + +

-- cgit v1.2.3