Skip to content

Commit

Permalink
Create a dynamic modal (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
michho8 authored Oct 15, 2024
1 parent 087c7a2 commit 6b33d1f
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
56 changes: 56 additions & 0 deletions ui/src/components/modal/dynamic-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use client';

import {
AlertDialog,
AlertDialogHeader,
AlertDialogContent,
AlertDialogDescription,
AlertDialogTitle,
AlertDialogFooter,
AlertDialogCancel
} from '@/components/ui/alert-dialog';
import { ReactNode, useState } from 'react';
import { Button } from '@/components/ui/button';

const DynamicModal = ({
open,
title,
body,
buttons
}: {
open: boolean;
title: string;
body: string;
buttons?: ReactNode[];
}) => {
const [openDynamicModal, setOpenDynamicModal] = useState(open);

/**
* Closes the modal.
*/
const close = () => {
setOpenDynamicModal(false);
};

return (
<AlertDialog open={openDynamicModal}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{title}</AlertDialogTitle>
<AlertDialogDescription>{body}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => close()}>OK</AlertDialogCancel>
{/*Any buttons that should lead the user to a different page.*/}
{buttons?.map((button, index) => (
<Button key={index} onClick={() => close()}>
{button}
</Button>
))}
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};

export default DynamicModal;
74 changes: 74 additions & 0 deletions ui/tests/components/modal/dynamic-modal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { fireEvent, render, screen } from '@testing-library/react';
import DynamicModal from '@/components/modal/dynamic-modal';
import Link from 'next/link';

describe('DynamicModal', () => {
it('should open an informational modal with test contents and no extra buttons', () => {
render(<DynamicModal open={true} title="A Dynamic Title" body="Some dynamic message here." />);
fireEvent.focus(document);

expect(screen.getByRole('alertdialog', { name: 'A Dynamic Title' })).toBeInTheDocument();
expect(screen.getByRole('alertdialog')).toHaveTextContent('Some dynamic message here.');

expect(screen.getByRole('button', { name: 'OK' })).toBeInTheDocument();
});

it('should open an informational modal with test contents and extra buttons', () => {
render(
<DynamicModal
open={true}
title="A Dynamic Title"
body="Some dynamic message here."
buttons={[<>Button1</>, <>Button2</>]}
/>
);
fireEvent.focus(document);

expect(screen.getByRole('alertdialog', { name: 'A Dynamic Title' })).toBeInTheDocument();
expect(screen.getByRole('alertdialog')).toHaveTextContent('Some dynamic message here.');

expect(screen.getByRole('button', { name: 'OK' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Button1' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Button2' })).toBeInTheDocument();
});

it('should close the modal upon clicking the OK button', () => {
render(<DynamicModal open={true} title="A Dynamic Title" body="Some dynamic message here." buttons={[]} />);
fireEvent.focus(document);

expect(screen.getByRole('alertdialog', { name: 'A Dynamic Title' })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: 'A Dynamic Title' })).toBeInTheDocument();
expect(screen.getByRole('alertdialog')).toHaveTextContent('Some dynamic message here.');

expect(screen.getByRole('button', { name: 'OK' })).toBeInTheDocument();

fireEvent.click(screen.getByRole('button', { name: 'OK' }));
expect(screen.queryByRole('alertdialog', { name: 'A Dynamic Title' })).not.toBeInTheDocument();
});

it('should close the modal and route to the provided link (Feedback)', () => {
render(
<DynamicModal
open={true}
title="A Modal to the Feedback Page"
body="Click Feedback to go to the Feedback Page."
buttons={[
<Link key={'feedbackButton'} href={'/feedback'}>
Feedback
</Link>
]}
/>
);
fireEvent.focus(document);

expect(screen.getByRole('alertdialog', { name: 'A Modal to the Feedback Page' })).toBeInTheDocument();
expect(screen.getByRole('alertdialog')).toHaveTextContent('Click Feedback to go to the Feedback Page.');

expect(screen.getByRole('button', { name: 'OK' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Feedback' })).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Feedback' })).toHaveAttribute('href', '/feedback');

fireEvent.click(screen.getByRole('button', { name: 'Feedback' }));
expect(screen.queryByRole('alertdialog', { name: 'A Modal to the Feedback Page' })).not.toBeInTheDocument();
});
});

0 comments on commit 6b33d1f

Please sign in to comment.