diff --git a/app/create-group-page/page.test.tsx b/app/create-group-page/page.test.tsx index c1370528..971e5640 100644 --- a/app/create-group-page/page.test.tsx +++ b/app/create-group-page/page.test.tsx @@ -4,12 +4,11 @@ import { render, screen } from '@testing-library/react'; import CreateGroupPage from './page'; import { Calendar } from '@/components/Calendar/calendar'; +import userEvent from '@testing-library/user-event'; +import { BUDGET_OPTIONS } from '@/constants/exchangeGroupOptions'; jest.mock('next/navigation', () => ({ - useRouter: () => ({ - push: jest.fn(), - refresh: jest.fn(), - }), + useRouter: () => {}, })); class MockResizeObserver { @@ -86,4 +85,64 @@ describe('Create Group Page', () => { expect(tomorrow).not.toBeDisabled(); }); }); + + describe('Budget input', () => { + beforeEach(() => { + Element.prototype.scrollIntoView = jest.fn(); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('closes the popover when a selection is made', async () => { + render(); + + const user = userEvent.setup(); + const budgetOptionsTriggerButton = screen.getByTestId('budget-button'); + await user.click(budgetOptionsTriggerButton); + const budgetOptions = screen.getAllByRole('option'); + expect(budgetOptions).toHaveLength(BUDGET_OPTIONS.length); + + const firstBudgetOption = budgetOptions[0]; + await user.click(firstBudgetOption); + expect(screen.queryByRole('option')).not.toBeInTheDocument(); + }); + }); + + describe('Drawing date calendar input', () => { + it('closes the popover when a selection is made', async () => { + render(); + + const user = userEvent.setup(); + const drawingDateTriggerButton = screen.getByTestId( + 'drawing-date-button', + ); + expect(screen.queryByRole('gridcell')).not.toBeInTheDocument(); + + await user.click(drawingDateTriggerButton); + const calendarDays = screen.getAllByRole('gridcell'); + const firstCalendarDay = calendarDays[calendarDays.length - 1]; + await user.click(firstCalendarDay); + expect(screen.queryByRole('gridcell')).not.toBeInTheDocument(); + }); + }); + + describe('Exchange date calendar input', () => { + it('closes the popover when a selection is made', async () => { + render(); + + const user = userEvent.setup(); + const drawingDateTriggerButton = screen.getByTestId( + 'exchange-date-button', + ); + expect(screen.queryByRole('gridcell')).not.toBeInTheDocument(); + + await user.click(drawingDateTriggerButton); + const calendarDays = screen.getAllByRole('gridcell'); + const firstCalendarDay = calendarDays[calendarDays.length - 1]; + await user.click(firstCalendarDay); + expect(screen.queryByRole('gridcell')).not.toBeInTheDocument(); + }); + }); }); diff --git a/app/create-group-page/page.tsx b/app/create-group-page/page.tsx index 6a543c5f..0e26b304 100644 --- a/app/create-group-page/page.tsx +++ b/app/create-group-page/page.tsx @@ -39,20 +39,10 @@ import { } from '@/components/ImageSelector/ImageSelector'; import { useRouter } from 'next/navigation'; import LinkCustom from '@/components/LinkCustom/LinkCustom'; +import { useState } from 'react'; +import { BUDGET_OPTIONS } from '@/constants/exchangeGroupOptions'; import Link from 'next/link'; -const priceRanges = [ - { label: '$10 - $20', value: '10-20' }, - { label: '$20 - $30', value: '20-30' }, - { label: '$30 - $40', value: '30-40' }, - { label: '$40 - $50', value: '40-50' }, - { label: '$50 - $60', value: '50-60' }, - { label: '$60 - $70', value: '60-70' }, - { label: '$70 - $80', value: '70-80' }, - { label: '$80 - $90', value: '80-90' }, - { label: '$90 - $100', value: '90-100' }, -] as const; - const groupImageUrls = GROUP_IMAGES.map((image) => image.src); const formSchema = z @@ -66,7 +56,7 @@ const formSchema = z drawing_date: z.date(), exchange_date: z.date(), budget: z.string({ - required_error: 'Please select a Price Range.', + required_error: 'Please select a budget.', }), group_image: z.string().refine((val) => groupImageUrls.includes(val), { message: 'Group Theme Image must be selected', @@ -80,6 +70,10 @@ const formSchema = z export default function CreateGroupPage() { const router = useRouter(); + const [budgetOpen, setBudgetOpen] = useState(false); + const [drawingDateOpen, setDrawingDateOpen] = useState(false); + const [exchangeDateOpen, setExchangeDateOpen] = useState(false); + const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { @@ -185,157 +179,185 @@ export default function CreateGroupPage() { ( - - Price Range - - - - - - - - - - - No framework found. - - {priceRanges.map((priceRanges) => ( - { - form.setValue('budget', priceRanges.value); - }} - > - {priceRanges.label} - - - ))} - - - - - - - Please select the price range for your Secret Santa group! - - - - )} + render={({ field }) => { + return ( + + Price Range + + + + + + + + + + + No framework found. + + {BUDGET_OPTIONS.map((budgetOption) => ( + { + form.setValue( + 'budget', + budgetOption.value, + ); + setBudgetOpen(false); + }} + > + {budgetOption.label} + + + ))} + + + + + + + Please select the price range for your Secret Santa + group! + + + + ); + }} /> ( - - - Gift Drawing Date - - - - - - - - - - - - - When names will be drawn for the gift exchange. - - - - )} + render={({ field }) => { + return ( + + + Gift Drawing Date + + + + + + + + + { + field.onChange(inputValue); + setDrawingDateOpen(false); + }} + disabled={[{ before: new Date() }]} + initialFocus + /> + + + + When names will be drawn for the gift exchange. + + + + ); + }} /> ( - - - Gift Exchange Date - - - - - - - - - - - - - When the gift exchange will take place. - - - - )} + render={({ field }) => { + return ( + + + Gift Exchange Date + + + + + + + + + { + field.onChange(inputValue); + setExchangeDateOpen(false); + }} + disabled={[ + { before: addDays(new Date(giftDrawingDate), 1) }, + ]} + initialFocus + /> + + + + When the gift exchange will take place. + + + + ); + }} />
- - - - - - - No Price Selected - - {priceRanges.map((priceRanges) => ( - { - form.setValue('budget', priceRanges.value); - }} - > - {priceRanges.label} - - - ))} - - - - - - - Please select the price range for your Secret Santa group! - - - - )} + render={({ field }) => { + return ( + + Price Range + + + + + + + + + + + No Price Selected + + {BUDGET_OPTIONS.map((budgetOption) => ( + { + form.setValue( + 'budget', + budgetOption.value, + ); + setBudgetOpen(false); + }} + > + {budgetOption.label} + + + ))} + + + + + + + Please select the price range for your Secret Santa + group! + + + + ); + }} /> ( - - - Gift Drawing Date - - - - - - - - - - - - - When names will be randomly drawn for the gift exchange. - - - - )} + render={({ field }) => { + return ( + + + Gift Drawing Date + + + + + + + + + { + field.onChange(inputValue); + setDrawingDateOpen(false); + }} + disabled={[{ before: new Date() }]} + initialFocus + /> + + + + When names will be randomly drawn for the gift exchange. + + + + ); + }} /> ( - - - Gift Exchange Date - - - - - - - - - - - - - When the gift exchange will take place. - - - - )} + render={({ field }) => { + return ( + + + Gift Exchange Date + + + + + + + + + { + field.onChange(inputValue); + setExchangeDateOpen(false); + }} + disabled={[ + { before: addDays(new Date(giftDrawingDate), 1) }, + ]} + initialFocus + /> + + + + When the gift exchange will take place. + + + + ); + }} />