diff --git a/src/components/EventCard/EventCard.test.tsx b/src/components/EventCard/EventCard.test.tsx index f5cec39..51d0ad3 100644 --- a/src/components/EventCard/EventCard.test.tsx +++ b/src/components/EventCard/EventCard.test.tsx @@ -55,6 +55,23 @@ describe('The EventCard component', () => { expect(normalizedText).toBe('02/12/2024 | 08:30 - 03/12/2024 | 09:30'); }); + it('does not display start and end time if allDay property set "true"', () => { + setup({ + event: { + ...defaultProps.event, + allDay: true, + }, + }); + + const textContent = screen.getByText( + /02\/12\/2024\s*-\s*03\/12\/2024/i + ).textContent; + + const normalizedText = textContent?.replace(/\s+/g, ' ').trim(); + + expect(normalizedText).toBe('02/12/2024 - 03/12/2024'); + }); + it('displays the speakers', async () => { setup(); diff --git a/src/components/EventCard/EventCard.tsx b/src/components/EventCard/EventCard.tsx index 6c0ea77..14d740b 100644 --- a/src/components/EventCard/EventCard.tsx +++ b/src/components/EventCard/EventCard.tsx @@ -36,7 +36,7 @@ import { BREAKPOINT_MD_QUERY } from '../../constants/breakpoints'; import StrapiEvent, { EventType } from '../../models/strapi/StrapiEvent'; import { IntlContext } from '../ContextProvider'; import strapiMediaUrl from '../../utils/strapiMediaUrl'; -import convertStrapiTime from '../../utils/convertStrapiTime'; +import isSameDate from '../../utils/isSameDate'; export interface EventCardProps { event: StrapiEvent; @@ -209,22 +209,46 @@ export const EventCard = ({ event }: EventCardProps): JSX.Element => { color={'var(--boemly-colors-primary-700)'} /> - {formatDate(event.startDate, { + {formatDate(event.start, { year: 'numeric', month: '2-digit', day: '2-digit', })} - {event.startTime && - ` | ${convertStrapiTime(event.startTime, formatNumber)} `} - {(event.endDate || event.endTime) && ' - '} - {event.endDate && - formatDate(event.endDate, { - year: 'numeric', - month: '2-digit', - day: '2-digit', - })} - {event.endTime && event.endDate && ' | '} - {event.endTime && convertStrapiTime(event.endTime, formatNumber)} + + {!event.allDay && + ` | ${formatNumber(new Date(event.start).getUTCHours(), { + minimumIntegerDigits: 2, + })}:${formatNumber(new Date(event.start).getUTCMinutes(), { + minimumIntegerDigits: 2, + })}`} + + {event.end && + !isSameDate(new Date(event.start), new Date(event.end)) && ( + <> + {' - '} + {formatDate(event.end, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + })} + + {!event.allDay && + ` | ${formatNumber(new Date(event.end).getUTCHours(), { + minimumIntegerDigits: 2, + })}:${formatNumber(new Date(event.end).getUTCMinutes(), { + minimumIntegerDigits: 2, + })}`} + + )} + + {event.end && + !event.allDay && + isSameDate(new Date(event.start), new Date(event.end)) && + ` - ${formatNumber(new Date(event.end).getUTCHours(), { + minimumIntegerDigits: 2, + })}:${formatNumber(new Date(event.end).getUTCMinutes(), { + minimumIntegerDigits: 2, + })}`} diff --git a/src/models/strapi/StrapiEvent.ts b/src/models/strapi/StrapiEvent.ts index 00f23fd..91aadd0 100644 --- a/src/models/strapi/StrapiEvent.ts +++ b/src/models/strapi/StrapiEvent.ts @@ -41,10 +41,9 @@ interface StrapiEvent { location?: string; locale: Locale; online?: boolean; - startDate: Date; - startTime?: string; - endDate?: Date; - endTime?: string; + start: Date; + end?: Date; + allDay?: boolean; slices: any[]; localizations: StrapiLocalization[]; topBanner?: StrapiTopBanner; diff --git a/src/slices/Events/Events.test.tsx b/src/slices/Events/Events.test.tsx index fcd59d9..f6f601b 100644 --- a/src/slices/Events/Events.test.tsx +++ b/src/slices/Events/Events.test.tsx @@ -19,7 +19,7 @@ const pastEventMock = { attributes: { ...strapiEventMock.attributes, title: 'Past Event', - startDate: '2024-12-01', + start: '2024-12-01T10:00:00.000Z', eventTypes: [{ id: 1, eventType: EventType.MEET_UP }], languages: [{ id: 1, language: 'English', countryCode: 'GB' }], }, @@ -30,7 +30,7 @@ const upcomingEventMock = { attributes: { ...strapiEventMock.attributes, title: 'Upcoming Event', - startDate: '2025-02-01', + start: '2024-12-01T10:00:00.000Z', eventTypes: [{ id: 1, eventType: EventType.CONFERENCE }], languages: [{ id: 1, language: 'German', countryCode: 'DE' }], }, @@ -68,7 +68,7 @@ describe('The Events slice', () => { const key = getKey(0, null); getKeyCalls.push(key.toString()); - if (getKey.toString().includes('filters[startDate][$gte]')) { + if (getKey.toString().includes('filters[start][$gte]')) { return { data: [{ body: { data: [upcomingEventMock] } }], isLoading: false, @@ -77,7 +77,7 @@ describe('The Events slice', () => { loadMore: jest.fn(), }; } - if (getKey.toString().includes('filters[startDate][$lt]')) { + if (getKey.toString().includes('filters[start][$lt]')) { return { data: [{ body: { data: [pastEventMock] } }], isLoading: false, @@ -149,7 +149,7 @@ describe('The Events slice', () => { // Use past events for the testing, because the batch for past events is defined as 2 and // the "Load button" will be shown when there are more then 2 past events (useEvents as jest.Mock).mockImplementation(({ getKey }) => { - if (getKey.toString().includes('filters[startDate][$lt]')) { + if (getKey.toString().includes('filters[start][$lt]')) { return { data: [ { @@ -243,7 +243,7 @@ describe('The Events slice', () => { await waitFor(() => { expect(getKeyCalls.map(decodeURIComponent)).toEqual( expect.arrayContaining([ - expect.stringContaining('filters[startDate][$gte]'), + expect.stringContaining('filters[start][$gte]'), expect.stringContaining( 'filters[$or][0][eventTypes][eventType]=Conference' ), @@ -278,7 +278,7 @@ describe('The Events slice', () => { await waitFor(() => { expect(getKeyCalls.map(decodeURIComponent)).toEqual( expect.arrayContaining([ - expect.stringContaining('filters[startDate][$gte]'), + expect.stringContaining('filters[start][$gte]'), expect.stringContaining( 'filters[$or][0][languages][language]=German' ), @@ -303,7 +303,7 @@ describe('The Events slice', () => { expect(getKeyCalls.map(decodeURIComponent)).toEqual( expect.arrayContaining([ expect.stringContaining( - `filters[startDate][$gte]=${NOW.toISOString()}` + `filters[start][$gte]=${NOW.toISOString()}` ), ]) ); @@ -341,9 +341,7 @@ describe('The Events slice', () => { await waitFor(() => { expect(getKeyCalls.map(decodeURIComponent)).toEqual( expect.arrayContaining([ - expect.stringContaining( - `filters[startDate][$lt]=${NOW.toISOString()}` - ), + expect.stringContaining(`filters[start][$lt]=${NOW.toISOString()}`), ]) ); }); diff --git a/src/slices/Events/Events.tsx b/src/slices/Events/Events.tsx index 12c7c62..07914b4 100644 --- a/src/slices/Events/Events.tsx +++ b/src/slices/Events/Events.tsx @@ -96,9 +96,9 @@ export const Events: React.FC = ({ slice }: EventsProps) => { url.searchParams.append('pLevel', STRAPI_DEFAULT_POPULATE_DEPTH); if (sort[0] === Sort.OLDEST_FIRST) { - url.searchParams.append('sort', 'startDate:asc'); + url.searchParams.append('sort', 'start:asc'); } else { - url.searchParams.append('sort', 'startDate:desc'); + url.searchParams.append('sort', 'start:desc'); } if (eventTypeFilter.length) { @@ -123,13 +123,12 @@ export const Events: React.FC = ({ slice }: EventsProps) => { const getUpcomingKey: SWRInfiniteKeyLoader = useCallback( (index) => - buildEventsUrl(index, UPCOMING_BATCH_SIZE, 'filters[startDate][$gte]'), + buildEventsUrl(index, UPCOMING_BATCH_SIZE, 'filters[start][$gte]'), [eventTypeFilter, languageFilter, sort] ); const getPastKey: SWRInfiniteKeyLoader = useCallback( - (index) => - buildEventsUrl(index, PAST_BATCH_SIZE, 'filters[startDate][$lt]'), + (index) => buildEventsUrl(index, PAST_BATCH_SIZE, 'filters[start][$lt]'), [eventTypeFilter, languageFilter, sort] ); diff --git a/src/test/strapiMocks/strapiEventMock.ts b/src/test/strapiMocks/strapiEventMock.ts index 133c3d5..f9fc080 100644 --- a/src/test/strapiMocks/strapiEventMock.ts +++ b/src/test/strapiMocks/strapiEventMock.ts @@ -14,10 +14,9 @@ export const strapiEventMock: IStrapiData = { logo: { id: 1, alt: 'Logo alt text 1', img: { data: strapiMediaMock } }, eventTypes: [{ id: 1, eventType: EventType.MEET_UP }], languages: [{ id: 1, language: 'English', countryCode: 'GB' }], - startDate: new Date('2024-02-12'), - startTime: '08:30:00.000', - endDate: new Date('2024-03-12'), - endTime: '09:30:00.000', + start: new Date('2024-02-12T08:30:00Z'), + end: new Date('2024-03-12T09:30:00Z'), + allDay: false, title: 'Event Title', description: 'Event Description', button: { id: 1, text: 'Button text', url: 'https://tree.ly' }, diff --git a/src/utils/convertStrapiTime.test.ts b/src/utils/convertStrapiTime.test.ts deleted file mode 100644 index 14382d9..0000000 --- a/src/utils/convertStrapiTime.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import convertStrapiTime from './convertStrapiTime'; - -describe('The convertStrapiTime util', () => { - it('returns the correct time', () => { - const formatNumber = jest.fn((number) => - number.toString().padStart(2, '0') - ); - const time = '12:45:00.000'; - - expect(convertStrapiTime(time, formatNumber)).toBe('12:45'); - }); - - it('returns the correct amount of digits', () => { - const formatNumber = jest.fn((number) => - number.toString().padStart(2, '0') - ); - const time = '08:05:00.000'; - - expect(convertStrapiTime(time, formatNumber)).toBe('08:05'); - }); -}); diff --git a/src/utils/convertStrapiTime.ts b/src/utils/convertStrapiTime.ts deleted file mode 100644 index e2072e5..0000000 --- a/src/utils/convertStrapiTime.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { FormatNumberOptions } from 'react-intl'; - -const convertStrapiTime = ( - date: string, - formatNumber: (value: number | bigint, opts?: FormatNumberOptions) => string -): string => { - let tempTime = date.split(':'); - let dt = new Date(); - dt.setHours(parseInt(tempTime[0], 10), parseInt(tempTime[1], 10), 0, 0); - const time = new Date(dt.getTime() - dt.getTimezoneOffset() * 60000); - - return `${formatNumber(time.getUTCHours(), { - minimumIntegerDigits: 2, - })}:${formatNumber(time.getUTCMinutes(), { - minimumIntegerDigits: 2, - })}`; -}; - -export default convertStrapiTime; diff --git a/src/utils/isSameDate.test.ts b/src/utils/isSameDate.test.ts new file mode 100644 index 0000000..5365c64 --- /dev/null +++ b/src/utils/isSameDate.test.ts @@ -0,0 +1,18 @@ +import isSameDate from './isSameDate'; + +describe('The getCountryFlag util', () => { + it('returns flag icon', () => { + expect( + isSameDate( + new Date('2024-02-12T08:30:00Z'), + new Date('2024-02-12T08:30:00Z') + ) + ).toEqual(true); + expect( + isSameDate( + new Date('2025-02-12T08:30:00Z'), + new Date('2024-02-10T08:30:00Z') + ) + ).toEqual(false); + }); +}); diff --git a/src/utils/isSameDate.ts b/src/utils/isSameDate.ts new file mode 100644 index 0000000..f091e0e --- /dev/null +++ b/src/utils/isSameDate.ts @@ -0,0 +1,9 @@ +const isSameDate = (date1: Date, date2: Date): boolean => { + return ( + date1.getFullYear() === date2.getFullYear() && + date1.getMonth() === date2.getMonth() && + date1.getDate() === date2.getDate() + ); +}; + +export default isSameDate;