Parse dates in the API response, simplify sorting
This commit is contained in:
parent
a3a2ed8c3f
commit
66ac808f42
|
@ -1,9 +1,8 @@
|
||||||
import ScheduleLoader from './ScheduleLoader.jsx';
|
import ScheduleLoader from './ScheduleLoader.jsx';
|
||||||
import { langs } from './constants.js';
|
import { langs } from './constants.js';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { dateSorter } from '../utils.js';
|
import { sorter } from '../utils.js';
|
||||||
import useConferences from '../hooks/useConferences.js';
|
import useConferences from '../hooks/useConferences.js';
|
||||||
import { getConferenceYear } from './utils.js';
|
|
||||||
|
|
||||||
export default function ScheduleChooser() {
|
export default function ScheduleChooser() {
|
||||||
const {
|
const {
|
||||||
|
@ -12,7 +11,7 @@ export default function ScheduleChooser() {
|
||||||
isLoading,
|
isLoading,
|
||||||
} = useConferences();
|
} = 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 [ year, setYear ] = useState(2023);
|
||||||
const [ lang, setLang ] = useState('bg');
|
const [ lang, setLang ] = useState('bg');
|
||||||
|
@ -29,7 +28,7 @@ export default function ScheduleChooser() {
|
||||||
{conferences && <>
|
{conferences && <>
|
||||||
<select value={year} onChange={e => setYear(parseInt(e.target.value, 10))}>
|
<select value={year} onChange={e => setYear(parseInt(e.target.value, 10))}>
|
||||||
{conferences.map(conference =>
|
{conferences.map(conference =>
|
||||||
<option key={conference.id} value={getConferenceYear(conference)}>{conference.title}</option>)}
|
<option key={conference.id} value={conference.start_date.getFullYear()}>{conference.title}</option>)}
|
||||||
</select>
|
</select>
|
||||||
</>}
|
</>}
|
||||||
<ScheduleLoader year={year} lang={lang} />
|
<ScheduleLoader year={year} lang={lang} />
|
||||||
|
|
|
@ -13,10 +13,8 @@ export default function ScheduleLoader({
|
||||||
isLoading,
|
isLoading,
|
||||||
} = useConferences();
|
} = useConferences();
|
||||||
|
|
||||||
const conferenceId = useMemo(() => data && data.filter(conference => {
|
const conferenceId = useMemo(() => data && data.filter(conference =>
|
||||||
const dt = new Date(Date.parse(conference.start_date));
|
conference.start_date.getFullYear() === year)?.[0]?.id, [data, year]);
|
||||||
return dt.getFullYear() === year;
|
|
||||||
})?.[0]?.id, [data, year]);
|
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
{isLoading && <p>Loading conferences...</p>}
|
{isLoading && <p>Loading conferences...</p>}
|
||||||
|
|
|
@ -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 getSpeakerName = speaker => speaker.first_name.concat(' ').concat(speaker.last_name);
|
||||||
|
|
||||||
export const isTrackHidden = track => track?.name?.en === 'Other' || track?.name?.bg === 'Други';
|
export const isTrackHidden = track => track?.name?.en === 'Other' || track?.name?.bg === 'Други';
|
||||||
|
|
|
@ -1,5 +1,24 @@
|
||||||
import useCfpRequest from './useCfpRequest.js';
|
import useCfpRequest from './useCfpRequest.js';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { parseDateFields } from '../utils.js';
|
||||||
|
|
||||||
export default function useConferences() {
|
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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import useTracks from './useTracks.js';
|
||||||
import useEventTypes from './useEventTypes.js';
|
import useEventTypes from './useEventTypes.js';
|
||||||
import useHalls from './useHalls.js';
|
import useHalls from './useHalls.js';
|
||||||
import useSlots from './useSlots.js';
|
import useSlots from './useSlots.js';
|
||||||
import { calculateProgress, normalizeResponse } from '../utils.js';
|
import { calculateProgress, normalizeResponse, parseDateFields } from '../utils.js';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export default function useSchedule(conferenceId) {
|
export default function useSchedule(conferenceId) {
|
||||||
|
@ -61,7 +61,12 @@ export default function useSchedule(conferenceId) {
|
||||||
const slots = useMemo(() => normalizeResponse(slotsResponse, [
|
const slots = useMemo(() => normalizeResponse(slotsResponse, [
|
||||||
['hall', halls, 'hall_id'],
|
['hall', halls, 'hall_id'],
|
||||||
['event', events, 'event_id'],
|
['event', events, 'event_id'],
|
||||||
]), [slotsResponse, halls, events]);
|
]).map(slot =>
|
||||||
|
parseDateFields(slot, [
|
||||||
|
'starts_at',
|
||||||
|
'ends_at',
|
||||||
|
])
|
||||||
|
), [slotsResponse, halls, events]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isStarted: isLoading,
|
isStarted: isLoading,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { sorter } from '../utils.js';
|
||||||
|
|
||||||
export default function useScheduleTable({
|
export default function useScheduleTable({
|
||||||
eventTypeId,
|
eventTypeId,
|
||||||
|
@ -9,10 +10,18 @@ export default function useScheduleTable({
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const filteredEvents = events.filter(event => eventTypeId > 0 ? event.event_type_id === eventTypeId : true);
|
const filteredEvents = events.filter(event => eventTypeId > 0 ? event.event_type_id === eventTypeId : true);
|
||||||
const filteredEventIds = filteredEvents.map(event => event.id);
|
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 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 => ({
|
const rows = filteredEvents.map(event => ({
|
||||||
id: event.id,
|
id: event.id,
|
||||||
cells: [{
|
cells: [{
|
||||||
|
|
12
src/utils.js
12
src/utils.js
|
@ -1,13 +1,15 @@
|
||||||
function sorter(a, b, fieldFn) {
|
export const sorter = field => (a, b) => {
|
||||||
const fieldA = fieldFn(a);
|
const fieldA = a[field];
|
||||||
const fieldB = fieldFn(b);
|
const fieldB = b[field];
|
||||||
|
|
||||||
return fieldA === fieldB ? 0 : (
|
return fieldA === fieldB ? 0 : (
|
||||||
fieldA < fieldB ? -1 : 1
|
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) {
|
export function calculateProgress(...elements) {
|
||||||
const totalCount = elements.length;
|
const totalCount = elements.length;
|
||||||
|
|
Loading…
Reference in New Issue