Compare commits
No commits in common. "f6c71b98977950683473cfa9dcbac8c600bd06d2" and "4774dcda11d2dd224788c4f36764a29d597d47d4" have entirely different histories.
f6c71b9897
...
4774dcda11
|
@ -1,18 +1,11 @@
|
||||||
import { isTrackHidden } from './utils.js';
|
import PropTypes from 'prop-types';
|
||||||
import Speaker from './Speaker.jsx';
|
|
||||||
import FeedbackLink from './FeedbackLink.jsx';
|
|
||||||
|
|
||||||
export default function Event(event) {
|
export default function Event({
|
||||||
return (<>
|
title,
|
||||||
<a href={'#lecture-'.concat(event.id)}>{event.title}</a>
|
}) {
|
||||||
<br />
|
return (<strong>{title}</strong>);
|
||||||
{event.participant_users && !isTrackHidden(event.track) && <>
|
|
||||||
{event.participant_users.map(speaker => speaker && <Speaker key={speaker.id} {...speaker} />)}
|
|
||||||
</>}
|
|
||||||
<p>
|
|
||||||
<i>
|
|
||||||
<FeedbackLink {...event} />
|
|
||||||
</i>
|
|
||||||
</p>
|
|
||||||
</>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event.propTypes = {
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
export default function FeedbackLink(event) {
|
|
||||||
return (<a href={event.feedback_url}>Submit feedback</a>);
|
|
||||||
}
|
|
|
@ -7,8 +7,6 @@ import Event from './Event.jsx';
|
||||||
import defaultSpeaker from '../assets/default-speaker.png';
|
import defaultSpeaker from '../assets/default-speaker.png';
|
||||||
import './Schedule.scss';
|
import './Schedule.scss';
|
||||||
import { langs } from './constants.js';
|
import { langs } from './constants.js';
|
||||||
import Speaker from './Speaker.jsx';
|
|
||||||
import FeedbackLink from './FeedbackLink.jsx';
|
|
||||||
|
|
||||||
export default function Schedule({
|
export default function Schedule({
|
||||||
conferenceId,
|
conferenceId,
|
||||||
|
@ -22,7 +20,6 @@ export default function Schedule({
|
||||||
slots,
|
slots,
|
||||||
isLoading,
|
isLoading,
|
||||||
loadingProgress,
|
loadingProgress,
|
||||||
isComplete,
|
|
||||||
} = useSchedule(conferenceId);
|
} = useSchedule(conferenceId);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -30,7 +27,6 @@ export default function Schedule({
|
||||||
rows,
|
rows,
|
||||||
} = useScheduleTable({
|
} = useScheduleTable({
|
||||||
events,
|
events,
|
||||||
tracks,
|
|
||||||
halls,
|
halls,
|
||||||
slots,
|
slots,
|
||||||
lang,
|
lang,
|
||||||
|
@ -38,46 +34,57 @@ export default function Schedule({
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
{isLoading && <progress value={loadingProgress}/>}
|
{isLoading && <progress value={loadingProgress}/>}
|
||||||
{isComplete && <div className="schedule">
|
<div className="schedule">
|
||||||
<hr />
|
<hr />
|
||||||
<table>
|
{header && rows && <>
|
||||||
<thead>
|
<table>
|
||||||
<tr>
|
<thead>
|
||||||
{header.map(hall => <th key={hall.id}>{hall.name}</th>)}
|
<tr>
|
||||||
</tr>
|
{header.map(hall => <th key={hall.id}>{hall.name}</th>)}
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{rows.map(row => <tr key={row.id}>
|
<tbody>
|
||||||
{row.cells.map(cell => <td key={cell.id} {...cell.attributes}>
|
{rows.map(row => <tr key={row.id}>
|
||||||
<Event {...cell.event} />
|
{row.cells.map(cell => <td key={cell.id} {...cell.attributes}>
|
||||||
</td>)}
|
<Event {...cell.event} />
|
||||||
</tr>)}
|
</td>)}
|
||||||
</tbody>
|
</tr>)}
|
||||||
<tfoot>
|
</tbody>
|
||||||
<tr>
|
<tfoot>
|
||||||
{header.map(hall => <th key={hall.id}>{hall.name}</th>)}
|
<tr>
|
||||||
</tr>
|
{header.map(hall => <th key={hall.id}>{hall.name}</th>)}
|
||||||
</tfoot>
|
</tr>
|
||||||
</table>
|
</tfoot>
|
||||||
<div className="separator"/>
|
</table>
|
||||||
<table>
|
<div className="separator"/>
|
||||||
<tbody>
|
</>}
|
||||||
{Object.entries(tracks).filter(([, track]) =>
|
{tracks && <>
|
||||||
!isTrackHidden(track)
|
<table>
|
||||||
).map(([trackId, track]) => <tr key={trackId}>
|
<tbody>
|
||||||
<td className={track.css_class}>{track.name[lang]}</td>
|
{Object.entries(tracks).filter(([, track]) =>
|
||||||
</tr>)}
|
!isTrackHidden(track)
|
||||||
{Object.entries(langs).map(([code, name]) => <tr key={code}>
|
).map(([trackId, track]) => <tr key={trackId}>
|
||||||
<td className={'schedule-'.concat(code)}>{name}</td>
|
<td className={track.css_class}>{track.name[lang]}</td>
|
||||||
</tr>)}
|
</tr>)}
|
||||||
</tbody>
|
{Object.entries(langs).map(([code, name]) => <tr key={code}>
|
||||||
</table>
|
<td className={'schedule-'.concat(code)}>{name}</td>
|
||||||
<div className="separator" />
|
</tr>)}
|
||||||
{Object.entries(events).map(([eventId, event]) => <section key={eventId} id={'lecture-'.concat(eventId)}>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div className="separator" />
|
||||||
|
</>}
|
||||||
|
{events && tracks && Object.entries(events).map(([eventId, event]) => <section key={eventId} id={'lecture-'.concat(eventId)}>
|
||||||
<p>
|
<p>
|
||||||
<strong>{event.title}</strong>
|
<strong>{event.title}</strong>
|
||||||
{event.participant_users && !isTrackHidden(event.track) && <>
|
{event.participant_user_ids && !isTrackHidden(tracks[event.track_id]) && speakers && <>
|
||||||
({event.participant_users.map(speaker => speaker && <Speaker key={speaker.id} {...speaker} />)})
|
({event.participant_user_ids.map(speakerId => speakers[speakerId] && <Fragment key={speakerId}>
|
||||||
|
<a key={speakerId} href={'#'.concat(getSpeakerName(speakers[speakerId]))}>
|
||||||
|
{getSpeakerName(speakers[speakerId])}
|
||||||
|
</a>
|
||||||
|
{speakers[speakerId].organisation && <>
|
||||||
|
/⁠{speakers[speakerId].organisation}⁠/
|
||||||
|
</>}
|
||||||
|
</Fragment>).filter(item => !!item)})
|
||||||
</>}
|
</>}
|
||||||
</p>
|
</p>
|
||||||
{event.abstract && <p>
|
{event.abstract && <p>
|
||||||
|
@ -85,12 +92,12 @@ export default function Schedule({
|
||||||
</p>}
|
</p>}
|
||||||
<p className="feedback">
|
<p className="feedback">
|
||||||
<strong>
|
<strong>
|
||||||
<FeedbackLink {...event} />
|
<a href={event.feedback_url}>Submit feedback</a>
|
||||||
</strong>
|
</strong>
|
||||||
</p>
|
</p>
|
||||||
<div className="separator" />
|
<div className="separator" />
|
||||||
</section>)}
|
</section>)}
|
||||||
{<>
|
{speakers && <>
|
||||||
<div className="grid members">
|
<div className="grid members">
|
||||||
{Object.entries(speakers).map(([speakerId, speaker]) => <div key={speakerId} className="col4 wmember">
|
{Object.entries(speakers).map(([speakerId, speaker]) => <div key={speakerId} className="col4 wmember">
|
||||||
<a href={'#'.concat(getSpeakerName(speaker))}>
|
<a href={'#'.concat(getSpeakerName(speaker))}>
|
||||||
|
@ -115,7 +122,7 @@ export default function Schedule({
|
||||||
<div className="separator" />
|
<div className="separator" />
|
||||||
</Fragment>)}
|
</Fragment>)}
|
||||||
</>}
|
</>}
|
||||||
</div>}
|
</div>
|
||||||
</>);
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { getSpeakerName } from './utils.js';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
export default function Speaker(speaker) {
|
|
||||||
return (<>
|
|
||||||
<a href={'#'.concat(getSpeakerName(speaker))}>{getSpeakerName(speaker)}</a>
|
|
||||||
{speaker.organisation && <>/⁠{speaker.organisation}⁠/</>}
|
|
||||||
</>);
|
|
||||||
}
|
|
||||||
|
|
||||||
Speaker.propTypes = {
|
|
||||||
first_name: PropTypes.string.isRequired,
|
|
||||||
last_name: PropTypes.string.isRequired,
|
|
||||||
organisation: PropTypes.string,
|
|
||||||
};
|
|
|
@ -4,65 +4,45 @@ 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 { addIdAndRelations, calculateProgress } from '../utils.js';
|
import { calculateProgress } from '../utils.js';
|
||||||
import { useMemo } from 'react';
|
|
||||||
|
|
||||||
export default function useSchedule(conferenceId) {
|
export default function useSchedule(conferenceId) {
|
||||||
const {
|
const {
|
||||||
data: speakersResponse,
|
data: events,
|
||||||
isLoading: speakersLoading,
|
|
||||||
isValidating: speakersValidating,
|
|
||||||
} = useSpeakers(conferenceId);
|
|
||||||
|
|
||||||
const speakers = useMemo(() => addIdAndRelations(speakersResponse || []), [speakersResponse]);
|
|
||||||
|
|
||||||
const {
|
|
||||||
data: tracksResponse,
|
|
||||||
isLoading: tracksLoading,
|
|
||||||
isValidating: tracksValidating,
|
|
||||||
} = useTracks(conferenceId);
|
|
||||||
|
|
||||||
const tracks = useMemo(() => addIdAndRelations(tracksResponse || []), [tracksResponse]);
|
|
||||||
|
|
||||||
const {
|
|
||||||
data: eventTypesResponse,
|
|
||||||
isLoading: eventTypesLoading,
|
|
||||||
isValidating: eventTypesValidating,
|
|
||||||
} = useEventTypes(conferenceId);
|
|
||||||
|
|
||||||
const eventTypes = useMemo(() => addIdAndRelations(eventTypesResponse || []), [eventTypesResponse]);
|
|
||||||
|
|
||||||
const {
|
|
||||||
data: hallsResponse,
|
|
||||||
isLoading: hallsLoading,
|
|
||||||
isValidating: hallsValidating,
|
|
||||||
} = useHalls(conferenceId);
|
|
||||||
|
|
||||||
const halls = useMemo(() => addIdAndRelations(hallsResponse || []), [hallsResponse]);
|
|
||||||
|
|
||||||
const {
|
|
||||||
data: eventsResponse,
|
|
||||||
isLoading: eventsLoading,
|
isLoading: eventsLoading,
|
||||||
isValidating: eventsValidating,
|
isValidating: eventsValidating,
|
||||||
} = useEvents(conferenceId);
|
} = useEvents(conferenceId);
|
||||||
|
|
||||||
const events = useMemo(() => addIdAndRelations(eventsResponse || [], [
|
const {
|
||||||
['event_type', eventTypes, 'event_type_id'],
|
data: speakers,
|
||||||
['track', tracks, 'track_id'],
|
isLoading: speakersLoading,
|
||||||
['participant_users', speakers, 'participant_user_ids'],
|
isValidating: speakersValidating,
|
||||||
]), [eventsResponse, eventTypes, tracks, speakers]);
|
} = useSpeakers(conferenceId);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: slotsResponse,
|
data: tracks,
|
||||||
|
isLoading: tracksLoading,
|
||||||
|
isValidating: tracksValidating,
|
||||||
|
} = useTracks(conferenceId);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: eventTypes,
|
||||||
|
isLoading: eventTypesLoading,
|
||||||
|
isValidating: eventTypesValidating,
|
||||||
|
} = useEventTypes(conferenceId);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: halls,
|
||||||
|
isLoading: hallsLoading,
|
||||||
|
isValidating: hallsValidating,
|
||||||
|
} = useHalls(conferenceId);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: slots,
|
||||||
isLoading: slotsLoading,
|
isLoading: slotsLoading,
|
||||||
isValidating: slotsValidating,
|
isValidating: slotsValidating,
|
||||||
} = useSlots(conferenceId);
|
} = useSlots(conferenceId);
|
||||||
|
|
||||||
const slots = useMemo(() => addIdAndRelations(slotsResponse || [], [
|
|
||||||
['hall', halls, 'hall_id'],
|
|
||||||
['event', events, 'event_id'],
|
|
||||||
]), [slotsResponse, halls, events]);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isStarted: isLoading,
|
isStarted: isLoading,
|
||||||
remainingProgress: loadingProgress,
|
remainingProgress: loadingProgress,
|
||||||
|
@ -73,10 +53,6 @@ export default function useSchedule(conferenceId) {
|
||||||
remainingProgress: validatingProgress,
|
remainingProgress: validatingProgress,
|
||||||
} = calculateProgress(eventsValidating, speakersValidating, tracksValidating, eventTypesValidating, hallsValidating, slotsValidating);
|
} = calculateProgress(eventsValidating, speakersValidating, tracksValidating, eventTypesValidating, hallsValidating, slotsValidating);
|
||||||
|
|
||||||
const {
|
|
||||||
isComplete,
|
|
||||||
} = calculateProgress(events, speakers, tracks, eventTypes, halls, slots);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
events,
|
events,
|
||||||
speakers,
|
speakers,
|
||||||
|
@ -88,6 +64,5 @@ export default function useSchedule(conferenceId) {
|
||||||
loadingProgress,
|
loadingProgress,
|
||||||
isValidating,
|
isValidating,
|
||||||
validatingProgress,
|
validatingProgress,
|
||||||
isComplete,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ export default function useScheduleTable({
|
||||||
cells: [{
|
cells: [{
|
||||||
id: 1,
|
id: 1,
|
||||||
attributes: {
|
attributes: {
|
||||||
className: 'schedule-'.concat(event.language).concat(' ').concat(event.track.css_class),
|
|
||||||
colSpan: 2,
|
colSpan: 2,
|
||||||
},
|
},
|
||||||
event,
|
event,
|
||||||
|
|
12
src/utils.js
12
src/utils.js
|
@ -41,15 +41,3 @@ export function calculateProgress(...elements) {
|
||||||
isNotStarted: completeCount === 0,
|
isNotStarted: completeCount === 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addIdAndRelations = (items, relations = []) =>
|
|
||||||
Object.fromEntries(Object.entries(items).map(([id, item]) =>
|
|
||||||
([id, {
|
|
||||||
id,
|
|
||||||
...item,
|
|
||||||
...Object.fromEntries(relations.map(([field, collection, idField]) => ([
|
|
||||||
field,
|
|
||||||
Array.isArray(item[idField]) ? item[idField].map(id => collection[id]) : collection[item[idField]],
|
|
||||||
]))),
|
|
||||||
}])
|
|
||||||
));
|
|
||||||
|
|
Loading…
Reference in New Issue