diff --git a/src/Schedule/ScheduleChooser.jsx b/src/Schedule/ScheduleChooser.jsx
index 21dd99e..ea102e9 100644
--- a/src/Schedule/ScheduleChooser.jsx
+++ b/src/Schedule/ScheduleChooser.jsx
@@ -1,9 +1,8 @@
import ScheduleLoader from './ScheduleLoader.jsx';
import { langs } from './constants.js';
import { useMemo, useState } from 'react';
-import { dateSorter } from '../utils.js';
+import { sorter } from '../utils.js';
import useConferences from '../hooks/useConferences.js';
-import { getConferenceYear } from './utils.js';
export default function ScheduleChooser() {
const {
@@ -12,7 +11,7 @@ export default function ScheduleChooser() {
isLoading,
} = useConferences();
- const conferences = useMemo(() => Array.isArray(data) ? data.sort(dateSorter('start_date')) : data, [data]);
+ const conferences = useMemo(() => Array.isArray(data) ? data.sort(sorter('start_date')) : data, [data]);
const [ year, setYear ] = useState(2023);
const [ lang, setLang ] = useState('bg');
@@ -29,7 +28,7 @@ export default function ScheduleChooser() {
{conferences && <>
>}
Loading conferences...
} diff --git a/src/Schedule/utils.js b/src/Schedule/utils.js index 4c6f3ab..a1a7d75 100644 --- a/src/Schedule/utils.js +++ b/src/Schedule/utils.js @@ -1,5 +1,3 @@ -export const getConferenceYear = conference => (new Date(conference.start_date)).getFullYear(); - export const getSpeakerName = speaker => speaker.first_name.concat(' ').concat(speaker.last_name); export const isTrackHidden = track => track?.name?.en === 'Other' || track?.name?.bg === 'Други'; diff --git a/src/hooks/useConferences.js b/src/hooks/useConferences.js index 6a8edda..965c0a1 100644 --- a/src/hooks/useConferences.js +++ b/src/hooks/useConferences.js @@ -1,5 +1,24 @@ import useCfpRequest from './useCfpRequest.js'; +import { useMemo } from 'react'; +import { parseDateFields } from '../utils.js'; export default function useConferences() { - return useCfpRequest('.json'); + const { + data: conferences, + ...restOfRequest + } = useCfpRequest('.json'); + + const parsedConferences = useMemo(() => (conferences ?? []).map(conference => + parseDateFields(conference, [ + 'start_date', + 'end_date', + 'created_at', + 'updated_at', + ]) + ), [conferences]); + + return { + data: parsedConferences, + ...restOfRequest, + }; } diff --git a/src/hooks/useSchedule.js b/src/hooks/useSchedule.js index 24a2893..025c00d 100644 --- a/src/hooks/useSchedule.js +++ b/src/hooks/useSchedule.js @@ -4,7 +4,7 @@ import useTracks from './useTracks.js'; import useEventTypes from './useEventTypes.js'; import useHalls from './useHalls.js'; import useSlots from './useSlots.js'; -import { calculateProgress, normalizeResponse } from '../utils.js'; +import { calculateProgress, normalizeResponse, parseDateFields } from '../utils.js'; import { useMemo } from 'react'; export default function useSchedule(conferenceId) { @@ -61,7 +61,12 @@ export default function useSchedule(conferenceId) { const slots = useMemo(() => normalizeResponse(slotsResponse, [ ['hall', halls, 'hall_id'], ['event', events, 'event_id'], - ]), [slotsResponse, halls, events]); + ]).map(slot => + parseDateFields(slot, [ + 'starts_at', + 'ends_at', + ]) + ), [slotsResponse, halls, events]); const { isStarted: isLoading, diff --git a/src/hooks/useScheduleTable.js b/src/hooks/useScheduleTable.js index 3baf81b..9811ee7 100644 --- a/src/hooks/useScheduleTable.js +++ b/src/hooks/useScheduleTable.js @@ -1,4 +1,5 @@ import { useMemo } from 'react'; +import { sorter } from '../utils.js'; export default function useScheduleTable({ eventTypeId, @@ -9,10 +10,18 @@ export default function useScheduleTable({ return useMemo(() => { const filteredEvents = events.filter(event => eventTypeId > 0 ? event.event_type_id === eventTypeId : true); const filteredEventIds = filteredEvents.map(event => event.id); - const filteredSlots = slots.filter(slot => filteredEventIds.includes(slot.event_id)); + const filteredSlots = slots.sort(sorter('starts_at')).filter(slot => filteredEventIds.includes(slot.event_id)); + const days = Array.from(new Set(filteredSlots.map(slot => + slot.starts_at.setHours(0, 0, 0, 0) + ))).map(ts => new Date(ts)); const filteredHallIds = new Set(filteredSlots.map(slot => slot.hall_id)); - const header = halls.filter(hall => filteredHallIds.has(hall.id)); + const filteredHalls = halls.filter(hall => filteredHallIds.has(hall.id)); + const hallSlots = Object.fromEntries(filteredHalls.map(hall => [ + hall.id, + filteredSlots.filter(slot => slot.hall_id === hall.id), + ])); + const header = filteredHalls; const rows = filteredEvents.map(event => ({ id: event.id, cells: [{ diff --git a/src/utils.js b/src/utils.js index 46eea78..2ce61b5 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,13 +1,15 @@ -function sorter(a, b, fieldFn) { - const fieldA = fieldFn(a); - const fieldB = fieldFn(b); +export const sorter = field => (a, b) => { + const fieldA = a[field]; + const fieldB = b[field]; return fieldA === fieldB ? 0 : ( fieldA < fieldB ? -1 : 1 ); -} +}; -export const dateSorter = key => (a, b) => sorter(a, b, item => Date.parse(item[key])); +export const parseDateFields = (item, dateFields) => Object.fromEntries(Object.entries(item).map(([key, value]) => + [key, dateFields.includes(key) ? new Date(value) : value] +)); export function calculateProgress(...elements) { const totalCount = elements.length;