From 34c0b38e7fb13a7c11029f937c7396678b7ad5e1 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Tue, 1 Jun 2021 01:19:48 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=AA=20Test=20cases=20for=20DatePicker?= =?UTF-8?q?=20&=20TimePicker=20(#92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/DatePicker/DatePicker.spec.tsx | 185 ++++++ .../components/DatePicker/TimePicker.spec.tsx | 544 ++++++++++++++++++ src/components/Calendar/Calendar.tsx | 8 +- src/components/DatePicker/TimePicker.tsx | 208 ++++--- 4 files changed, 851 insertions(+), 94 deletions(-) create mode 100644 __tests__/components/DatePicker/DatePicker.spec.tsx create mode 100644 __tests__/components/DatePicker/TimePicker.spec.tsx diff --git a/__tests__/components/DatePicker/DatePicker.spec.tsx b/__tests__/components/DatePicker/DatePicker.spec.tsx new file mode 100644 index 0000000..44e5fa0 --- /dev/null +++ b/__tests__/components/DatePicker/DatePicker.spec.tsx @@ -0,0 +1,185 @@ +import React from 'react'; +import { DatePicker } from '../../../src'; + +import '@testing-library/jest-dom'; +import { fireEvent, render, act, screen } from '@testing-library/react'; + +const CreateDatePicker = (props: { date?: Date; withTimePicker?: Record }) => { + const [date, updateDate] = React.useState(props.date); + return ( + updateDate(e)} timePickerProps={props.withTimePicker} /> + ); +}; + +describe('DatePicker', () => { + it('Should render a datepicker component', () => { + render(); + + const popoverElement = document.querySelector('.popover-element'); + expect(popoverElement).toHaveStyle(` + display: block; + `); + + const datePickerInput = popoverElement.querySelector('.sha-el-input'); + + expect(datePickerInput.querySelector('label').innerHTML).toBe('Enter Date '); + + const datePickerbutton = datePickerInput.querySelector('button'); + expect(datePickerbutton.querySelector('svg').innerHTML).toContain( + // Path for MdTimer icon + 'M368.005 272h-96v96h96v-96zm-32-208v32h-160V64h-48v32h-24.01c-22.002 0-40 17.998-40 40v272c0 22.002 17.998 40 40 40h304.01c22.002 0 40-17.998 40-40V136c0-22.002-17.998-40-40-40h-24V64h-48zm72 344h-304.01V196h304.01v212z', + ); + }); + + it('Should open a datepicker', () => { + render(); + + let datePickerCalendar = document.querySelector('.sha-el-calendar'); + expect(datePickerCalendar).toBeNull(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + datePickerCalendar = document.querySelector('.sha-el-calendar'); + expect(datePickerCalendar).toBeDefined(); + const timePicker = document.querySelector('.rc-tooltip').querySelectorAll('.popover-element')[2]; + expect(timePicker).not.toBeDefined(); + }); + + it('Should render a datepicker with today date', () => { + render(); + + const datePickerInput = document.querySelector('input'); + expect(datePickerInput.value).toBe(new Date().toLocaleDateString()); + }); + + it('Should re-render on date change', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + let datePickerCalendar = document.querySelector('.sha-el-calendar'); + + const monthButton = datePickerCalendar.querySelectorAll('.sha-el-col')[0].querySelector('button'); + act(() => { + fireEvent.click(monthButton); + }); + const monthArray = document.querySelectorAll('.rc-tooltip')[1].querySelectorAll('li'); + act(() => { + fireEvent.click(monthArray[6]); + }); + + const yearButton = datePickerCalendar.querySelectorAll('.sha-el-col')[1].querySelector('button'); + act(() => { + fireEvent.click(yearButton); + }); + const yearArray = document.querySelectorAll('.rc-tooltip')[2].querySelectorAll('li'); + act(() => { + fireEvent.click(yearArray[2007 - 1980]); + }); + + const dateArray = datePickerCalendar.querySelectorAll('.sha-el-row')[2].querySelectorAll('.sha-el-col'); + act(() => { + fireEvent.click(dateArray[6].querySelector('button')); + }); + + datePickerCalendar = document.querySelector('.sha-el-calendar'); + expect(datePickerCalendar).toBeNull(); + + const datePickerInput = document.querySelector('input'); + expect(datePickerInput.value).toBe('7/7/2007'); + }); + + it('Should render a datepicker with timepicker', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePicker = document.querySelector('.rc-tooltip').querySelectorAll('.popover-element')[2]; + expect(timePicker).toBeDefined(); + }); + + it('Should render datepicker with today date and time', () => { + let currentDateTime: string; + act(() => { + render(); + currentDateTime = new Date().toLocaleString(); + }); + + const datePickerInput = document.querySelector('input'); + expect(datePickerInput.value).toBe(currentDateTime); + }); + + it('Should close datepicker', () => { + render(); + + expect(document.querySelectorAll('.rc-tooltip').length).toBe(0); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + expect(document.querySelectorAll('.rc-tooltip').length).toBe(1); + + act(() => { + fireEvent.click(screen.getByText('Close').parentElement); + }); + expect(document.querySelectorAll('.rc-tooltip').length).toBe(0); + }); + + it('Should not close datepicker with time picker when clicked on a date', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + let datePickerCalendar = document.querySelector('.sha-el-calendar'); + + const dateArray = datePickerCalendar.querySelectorAll('.sha-el-row')[2].querySelectorAll('.sha-el-col'); + act(() => { + fireEvent.click(dateArray[0].querySelector('button')); + }); + + datePickerCalendar = document.querySelector('.sha-el-calendar'); + expect(datePickerCalendar).toBeDefined(); + }); + + it('Should re-render on time change', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePicker = document.querySelector('.rc-tooltip').querySelectorAll('.popover-element')[2]; + act(() => { + fireEvent.click(timePicker.querySelector('input')); + }); + const timePickerContainer = document.querySelectorAll('.rc-tooltip')[1].querySelector('.sha-el-row').parentElement; + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + act(() => { + fireEvent.click(hours[22]); + }); + + const minutes = timePickerContainer.querySelector('.min-column').querySelectorAll('p'); + act(() => { + fireEvent.click(minutes[45]); + }); + + const seconds = timePickerContainer.querySelector('.sec-column').querySelectorAll('p'); + act(() => { + fireEvent.click(seconds[49]); + }); + + act(() => { + fireEvent.click(screen.getByText('Close').parentElement); + }); + expect(document.querySelector('input').value).toBe('7/7/2021, 10:45:49 PM'); + }); +}); diff --git a/__tests__/components/DatePicker/TimePicker.spec.tsx b/__tests__/components/DatePicker/TimePicker.spec.tsx new file mode 100644 index 0000000..9f62a7c --- /dev/null +++ b/__tests__/components/DatePicker/TimePicker.spec.tsx @@ -0,0 +1,544 @@ +import React from 'react'; +import { TimePicker } from '../../../src'; + +import '@testing-library/jest-dom'; +import { fireEvent, render, act } from '@testing-library/react'; + +const CreateTimePicker = (props: { use12Hour?: boolean; disabled?: boolean; boderless?: boolean; time?: Date }) => { + const [time, updateTime] = React.useState(props.time); + return ( + <> + { + return updateTime(e); + }} + use12Hour={props.use12Hour} + disabled={props.disabled} + borderless={props.boderless} + /> +
+ + ); +}; + +// Convert 0: number -> 00: string to compare with TimePicker Input value +export const toInputString = (n: number) => (n < 10 ? '0' + n : n.toString()); + +describe('TimePicker', () => { + it('Should render a timepicker component', () => { + render(); + + const popoverElement = document.querySelector('.popover-element'); + expect(popoverElement).toHaveStyle(` + display: block; + `); + + const timePickerInput = document.querySelector('.sha-el-input'); + + expect(timePickerInput.querySelector('label').innerHTML).toBe('Time '); + expect(timePickerInput.querySelector('input').value).toBe('00:00:00'); + + const timePickerbutton = timePickerInput.querySelector('button'); + expect(timePickerbutton.querySelector('svg').innerHTML).toContain( + // Path for MdTimer icon + 'M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.03-6.61l1.42-1.42c-.43-.51-.9-.99-1.41-1.41l-1.42 1.42C16.07 4.74 14.12 4 12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9 9-4.03 9-9c0-2.12-.74-4.07-1.97-5.61zM12 20c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z', + ); + }); + + it('Should render a 12 hour format timepicker component', () => { + render(); + + const timePickerInput = document.querySelector('.sha-el-input'); + + expect(timePickerInput.querySelector('label').innerHTML).toBe('Time '); + expect(timePickerInput.querySelector('input').value).toBe('12:00:00 AM'); + }); + + it('Should open timepicker', () => { + render(); + + let tooltip = document.querySelector('.rc-tooltip'); + expect(tooltip).toBeNull(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + tooltip = document.querySelector('.rc-tooltip'); + expect(tooltip).toBeDefined(); + expect(tooltip).toHaveStyle(` + display: block; + `); + + expect(document.querySelectorAll('.rc-tooltip-arrow')[0]).toHaveStyle(` + display: none; + `); + expect(document.querySelectorAll('.rc-tooltip-arrow')[1]).toHaveStyle(` + display: none; + `); + + const timePickerContainer = tooltip.querySelector('.sha-el-row').parentElement; + expect(timePickerContainer).toHaveStyle(` + background: #ffffff; + `); + + const hourColumn = timePickerContainer.querySelector('.hour-column'); + expect(hourColumn).toHaveStyle(` + padding-left: 0px; + padding-right: 0px; + `); + expect(hourColumn).toHaveStyle(` + border-right: 1px solid #eee; + `); + expect(hourColumn).toHaveStyle(` + max-height: 300px; + overflow-y: hidden; + cursor: pointer; + min-width: 50px; + scroll-behavior: smooth; + `); + + const minColumn = timePickerContainer.querySelector('.min-column'); + expect(minColumn).toHaveStyle(` + padding-left: 0px; + padding-right: 0px; + `); + expect(minColumn).toHaveStyle(` + border-right: 1px solid #eee; + `); + expect(minColumn).toHaveStyle(` + max-height: 300px; + overflow-y: hidden; + cursor: pointer; + min-width: 50px; + scroll-behavior: smooth; + `); + + const secColumn = timePickerContainer.querySelector('.sec-column'); + expect(secColumn).toHaveStyle(` + padding-left: 0px; + padding-right: 0px; + `); + expect(secColumn).toHaveStyle(` + border-right: 1px solid #eee; + `); + expect(secColumn).toHaveStyle(` + max-height: 300px; + overflow-y: hidden; + cursor: pointer; + min-width: 50px; + scroll-behavior: smooth; + `); + + const hours = hourColumn.querySelectorAll('p'); + expect(hours.length).toBe(24); + expect(hours[0].innerHTML).toBe('0'); + expect(hours[23].innerHTML).toBe('23'); + expect(hours[0]).toHaveStyle(` + font-size: 16px; + font-weight: normal; + font-style: normal; + margin: 0; + padding: 5px 15px; + background: #536DFE; + `); + + const minutes = minColumn.querySelectorAll('p'); + expect(minutes.length).toBe(60); + expect(minutes[0].innerHTML).toBe('0'); + expect(minutes[59].innerHTML).toBe('59'); + expect(minutes[0]).toHaveStyle(` + font-size: 16px; + font-weight: normal; + font-style: normal; + margin: 0; + padding: 5px 15px; + background: #536DFE; + `); + + const seconds = secColumn.querySelectorAll('p'); + expect(seconds.length).toBe(60); + expect(seconds[0].innerHTML).toBe('0'); + expect(seconds[59].innerHTML).toBe('59'); + expect(seconds[0]).toHaveStyle(` + font-size: 16px; + font-weight: normal; + font-style: normal; + margin: 0; + padding: 5px 15px; + background: #536DFE; + `); + + const now = tooltip.querySelector('button'); + expect(now.innerHTML).toBe('Now'); + }); + + it('Should open a 12 hour format timepicker', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row').parentElement; + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + expect(hours.length).toBe(12); + expect(hours[0].innerHTML).toBe('12'); + expect(hours[11].innerHTML).toBe('11'); + + const twelveHourElements = timePickerContainer.querySelector('.am-column').querySelectorAll('p'); + expect(twelveHourElements.length).toBe(2); + expect(twelveHourElements[0].innerHTML).toBe('AM'); + expect(twelveHourElements[0]).toHaveStyle(` + font-size: 16px; + font-weight: normal; + font-style: normal; + margin: 0; + padding: 5px 15px; + background: #536DFE; + `); + expect(twelveHourElements[1].innerHTML).toBe('PM'); + expect(twelveHourElements[1]).toHaveStyle(` + font-size: 16px; + font-weight: normal; + font-style: normal; + margin: 0; + padding: 5px 15px; + `); + }); + + it('Should show current time when clicked on now button', () => { + render(); + + const timePickerInput = document.querySelector('.sha-el-input'); + expect(timePickerInput.querySelector('input').value).toBe('00:00:00'); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const tooltip = document.querySelector('.rc-tooltip'); + let currentTime: string[] = []; + act(() => { + fireEvent.click(tooltip.querySelector('button')); + currentTime = [ + toInputString(new Date().getHours()), + toInputString(new Date().getMinutes()), + toInputString(new Date().getSeconds()), + ]; + }); + + expect(timePickerInput.querySelector('input').value).toBe(`${currentTime[0]}:${currentTime[1]}:${currentTime[2]}`); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row'); + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + expect(hours[Number(currentTime[0])]).toHaveStyle(` + background: #536DFE; + `); + + const minutes = timePickerContainer.querySelector('.min-column').querySelectorAll('p'); + expect(minutes[Number(currentTime[1])]).toHaveStyle(` + background: #536DFE; + `); + + const seconds = timePickerContainer.querySelector('.sec-column').querySelectorAll('p'); + expect(seconds[Number(currentTime[2])]).toHaveStyle(` + background: #536DFE; + `); + }); + + it('Should show current time when clicked on now button in 12 hour format', () => { + render(); + + const timePickerInput = document.querySelector('.sha-el-input'); + expect(timePickerInput.querySelector('input').value).toBe('12:00:00 AM'); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const tooltip = document.querySelector('.rc-tooltip'); + let currentTime: string[] = []; + act(() => { + fireEvent.click(tooltip.querySelector('button')); + currentTime = [ + new Date().getHours() > 12 + ? toInputString(new Date().getHours() - 12) + : new Date().getHours() === 0 + ? '12' + : toInputString(new Date().getHours()), + toInputString(new Date().getMinutes()), + toInputString(new Date().getSeconds()), + new Date().getHours() < 12 ? 'AM' : 'PM', + ]; + }); + + expect(timePickerInput.querySelector('input').value).toBe( + `${currentTime[0]}:${currentTime[1]}:${currentTime[2]} ${currentTime[3]}`, + ); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row'); + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + expect(hours[Number(currentTime[0])]).toHaveStyle(` + background: #536DFE; + `); + + const minutes = timePickerContainer.querySelector('.min-column').querySelectorAll('p'); + expect(minutes[Number(currentTime[1])]).toHaveStyle(` + background: #536DFE; + `); + + const seconds = timePickerContainer.querySelector('.sec-column').querySelectorAll('p'); + expect(seconds[Number(currentTime[2])]).toHaveStyle(` + background: #536DFE; + `); + + const period = timePickerContainer.querySelector('.am-column').querySelectorAll('p'); + const index = currentTime[3] === 'AM' ? 0 : 1; + expect(period[index]).toHaveStyle(` + background: #536DFE; + `); + }); + + it('Should re-render on time change', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row'); + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + act(() => { + fireEvent.click(hours[22]); + }); + expect(hours[22]).toHaveStyle(` + background: #536DFE; + `); + + const minutes = timePickerContainer.querySelector('.min-column').querySelectorAll('p'); + act(() => { + fireEvent.click(minutes[45]); + }); + expect(minutes[45]).toHaveStyle(` + background: #536DFE; + `); + + const seconds = timePickerContainer.querySelector('.sec-column').querySelectorAll('p'); + act(() => { + fireEvent.click(seconds[49]); + }); + expect(seconds[49]).toHaveStyle(` + background: #536DFE; + `); + + expect(document.querySelector('input').value).toBe('22:45:49'); + }); + + it('Should re-render 12 hour format timeline on time change', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row'); + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + act(() => { + fireEvent.click(hours[9]); + }); + expect(hours[9]).toHaveStyle(` + background: #536DFE; + `); + + const minutes = timePickerContainer.querySelector('.min-column').querySelectorAll('p'); + act(() => { + fireEvent.click(minutes[45]); + }); + expect(minutes[45]).toHaveStyle(` + background: #536DFE; + `); + + const seconds = timePickerContainer.querySelector('.sec-column').querySelectorAll('p'); + act(() => { + fireEvent.click(seconds[0]); + }); + expect(seconds[0]).toHaveStyle(` + background: #536DFE; + `); + + const period = timePickerContainer.querySelector('.am-column').querySelectorAll('p'); + act(() => { + fireEvent.click(period[1]); + }); + expect(period[1]).toHaveStyle(` + background: #536DFE; + `); + + expect(document.querySelector('input').value).toBe('09:45:00 PM'); + }); + + it('Should check click on AM', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('input')); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row'); + const period = timePickerContainer.querySelector('.am-column').querySelectorAll('p'); + expect(period[0]).not.toHaveStyle(` + background: #536DFE; + `); + act(() => { + fireEvent.click(period[0]); + }); + expect(period[0]).toHaveStyle(` + background: #536DFE; + `); + }); + + it('Should render timepicker with time prop', () => { + render(); + + expect(document.querySelector('input').value).toBe('11:11:11'); + }); + + it('Should render a 12 hour format timepicker with time prop', () => { + render(); + + expect(document.querySelector('input').value).toBe('11:11:11 PM'); + }); + + it('Should re-render on input value change', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('.sha-el-input')); + }); + + const timePickerInput = document.querySelector('input'); + act(() => { + fireEvent.change(timePickerInput, { target: { value: '14:15:16' } }); + }); + + act(() => { + fireEvent.blur(document.querySelector('.sha-el-input')); + }); + + expect(timePickerInput.value).toBe('14:15:16'); + + act(() => { + fireEvent.click(timePickerInput); + }); + + const timePickerContainer = document.querySelector('.rc-tooltip').querySelector('.sha-el-row'); + + const hours = timePickerContainer.querySelector('.hour-column').querySelectorAll('p'); + act(() => { + fireEvent.click(hours[14]); + }); + expect(hours[14]).toHaveStyle(` + background: #536DFE; + `); + + const minutes = timePickerContainer.querySelector('.min-column').querySelectorAll('p'); + act(() => { + fireEvent.click(minutes[15]); + }); + expect(minutes[15]).toHaveStyle(` + background: #536DFE; + `); + + const seconds = timePickerContainer.querySelector('.sec-column').querySelectorAll('p'); + act(() => { + fireEvent.click(seconds[16]); + }); + expect(seconds[16]).toHaveStyle(` + background: #536DFE; + `); + }); + + it('Should re-render timepicker on enter key press', () => { + render(); + + act(() => { + fireEvent.click(document.querySelector('.sha-el-input')); + }); + + const timePickerInput = document.querySelector('input'); + + act(() => { + fireEvent.change(document.querySelector('input'), { target: { value: '04:15:16' } }); + }); + + act(() => { + fireEvent.keyDown(document.querySelector('.sha-el-input'), { key: 'Enter', Code: 'Enter' }); + }); + expect(timePickerInput.value).toBe('04:15:16'); + }); + + it('Should re-render 12 hour format timepicker on enter key press', () => { + render(); + + const timePickerInput = document.querySelector('input'); + + act(() => { + fireEvent.click(document.querySelector('.sha-el-input')); + }); + + act(() => { + fireEvent.change(document.querySelector('input'), { target: { value: '02:15:16 AM' } }); + }); + + act(() => { + fireEvent.keyDown(document.querySelector('.sha-el-input'), { key: 'Enter', Code: 'Enter' }); + }); + expect(timePickerInput.value).toBe('02:15:16 AM'); + }); + + it('Should open a timepicker on arrow down', () => { + render(); + + let tooltip = document.querySelector('.rc-tooltip'); + expect(tooltip).toBeNull(); + + act(() => { + fireEvent.keyDown(document.querySelector('.sha-el-input'), { key: 'ArrowDown', code: 'ArrowDown' }); + }); + + tooltip = document.querySelector('.rc-tooltip'); + expect(tooltip).toBeDefined(); + }); + + it('Should render a disabled timepicker', () => { + render(); + + const input = document.querySelector('input'); + expect(input).toHaveAttribute('disabled'); + expect(input).toHaveStyle(` + cursor: not-allowed; + `); + + const button = document.querySelector('button'); + expect(button).toHaveAttribute('disabled'); + expect(button).toHaveStyle(` + cursor: not-allowed; + `); + }); +}); diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 008045a..495fc4d 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -188,7 +188,13 @@ export const Calendar: React.FC = (props) => { }; return ( - + = (props) => { }} after={ <> - -
-); + + {arrayBetween(0, 60).map((v) => ( + onChange(undefined, v)} + key={v} + > + {v} + + ))} + + + {arrayBetween(0, 60).map((v) => ( + onChange(undefined, undefined, v)} + key={v} + > + {v} + + ))} + + {props.use12Hour && ( + + handleAmPmChange('AM', time, onChange)} + > + AM + + = 12 && 'primary'} + onClick={() => handleAmPmChange('PM', time, onChange)} + > + PM + + + )} + + + + ); +}; const scrollToEl = ( elem: Record<'hourEl' | 'minEl' | 'secEl', React.MutableRefObject>, @@ -228,7 +234,7 @@ const handleAmPmChange = (amPm: 'AM' | 'PM', time: Date, onChange: (h?: number, const formatTime = (time: Date, use12Hour: boolean) => { let hour = time.getHours(); if (use12Hour) { - hour = time.getHours() % 12; + hour = to12HourFormat(hour); } const formatNum = (n: number) => { @@ -256,5 +262,21 @@ const to24HourFormat = (hour: number, amPm: 'AM' | 'PM') => { return hour + 12; } + if (amPm === 'AM' && hour === 12) { + return 0; + } + + return hour; +}; + +const to12HourFormat = (hour: number) => { + if (hour > 12) { + return hour - 12; + } + + if (hour === 0) { + return 12; + } + return hour; };