Skip to content

Commit f1bd8e3

Browse files
committed
Specific code to present odd worlds assignment data
1 parent a476cef commit f1bd8e3

File tree

1 file changed

+131
-11
lines changed

1 file changed

+131
-11
lines changed

src/pages/Competition/Person/index.tsx

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ import { formatDate, formatToParts, roundTime } from '../../../lib/utils';
1111
import DisclaimerText from '../../../components/DisclaimerText';
1212
import { shortEventNameById } from '../../../lib/events';
1313
import classNames from 'classnames';
14+
import { Extension } from '@wca/helpers/lib/models/extension';
15+
import { Person } from '@wca/helpers';
16+
17+
const worldsAssignmentMap = {
18+
'wca booth': 'WCA Booth',
19+
'help desk': 'Help Desk',
20+
data: 'Data Entry',
21+
commentary: 'Commentary',
22+
media: 'Media',
23+
};
1424

1525
export const byDate = (
1626
a: { startTime: string } | undefined,
@@ -31,7 +41,7 @@ const RoomColored = styled(RoundedBg)`
3141
background-color: ${(p) => (p.$color ? `${p.$color}70` : 'inherit')};
3242
`;
3343

34-
export default function Person() {
44+
export default function PersonPage() {
3545
const { wcif, setTitle } = useWCIF();
3646
const { registrantId } = useParams();
3747
const [now, setNow] = useState(new Date());
@@ -43,7 +53,11 @@ export default function Person() {
4353
return () => clearInterval(interval);
4454
}, []);
4555

46-
const person = wcif?.persons?.find((p) => p.registrantId.toString() === registrantId);
56+
const person = wcif?.persons?.find(
57+
(p) => p.registrantId.toString() === registrantId
58+
) as Person & {
59+
extensions: Extension[];
60+
};
4761

4862
useEffect(() => {
4963
if (person) {
@@ -98,11 +112,47 @@ export default function Person() {
98112
[assignments]
99113
);
100114

101-
const assignmentsWithParsedDate = assignments
102-
.map((a) => ({
103-
...a,
104-
date: a.activity ? formatDate(new Date(a.activity.startTime)) : '???',
105-
}))
115+
const extraAssignments =
116+
(
117+
person?.extensions?.find(({ id }) => id === 'com.competitiongroups.worldsassignments')
118+
?.data as { assignments?: Array<{ staff: string; startTime: string; endTime: string }> }
119+
)?.assignments?.map((assignment) => ({
120+
assignmentCode: assignment.staff,
121+
activityId: null,
122+
activity: {
123+
startTime: assignment.startTime,
124+
endTime: assignment.endTime,
125+
room: { id: null },
126+
parent: null,
127+
},
128+
})) ?? [];
129+
130+
const allAssignments = [...assignments, ...extraAssignments].sort((a, b) =>
131+
byDate(a.activity, b.activity)
132+
);
133+
134+
const assignmentsWithParsedDate = allAssignments
135+
.map((a) => {
136+
const venue = a?.activity?.room?.id
137+
? wcif?.schedule.venues?.find((v) =>
138+
v.rooms.some((r) => r.id === a.activity?.room?.id || a.activity?.parent?.room?.id)
139+
)
140+
: wcif?.schedule.venues?.[0];
141+
142+
const dateTime = a.activity ? new Date(a.activity.startTime) : new Date(0);
143+
144+
return {
145+
...a,
146+
date:
147+
dateTime?.toLocaleDateString([], {
148+
weekday: 'long',
149+
year: 'numeric',
150+
month: 'numeric',
151+
day: 'numeric',
152+
timeZone: venue?.timezone,
153+
}) ?? 'foo',
154+
};
155+
})
106156
.sort((a, b) => byDate(a.activity, b.activity));
107157

108158
const getAssignmentsByDate = useCallback(
@@ -112,13 +162,33 @@ export default function Person() {
112162
[assignmentsWithParsedDate]
113163
);
114164

115-
const scheduleDays = assignments
165+
const scheduleDays = allAssignments
116166
.map((a) => {
167+
const venue = a?.activity?.room?.id
168+
? wcif?.schedule.venues?.find((v) =>
169+
v.rooms.some((r) => r.id === a.activity?.room?.id || a.activity?.parent?.room?.id)
170+
)
171+
: wcif?.schedule.venues?.[0];
172+
117173
const dateTime = a.activity ? new Date(a.activity.startTime) : new Date(0);
174+
118175
return {
119176
approxDateTime: dateTime.getTime(),
120-
date: formatDate(dateTime) || 'foo',
121-
dateParts: formatToParts(dateTime),
177+
date:
178+
dateTime.toLocaleDateString([], {
179+
weekday: 'long',
180+
year: 'numeric',
181+
month: 'numeric',
182+
day: 'numeric',
183+
timeZone: venue?.timezone,
184+
}) ?? 'foo',
185+
dateParts: new Intl.DateTimeFormat(navigator.language, {
186+
weekday: 'long',
187+
year: 'numeric',
188+
month: 'numeric',
189+
day: 'numeric',
190+
timeZone: venue?.timezone,
191+
}).formatToParts(dateTime),
122192
};
123193
})
124194
.filter((v, i, arr) => arr.findIndex(({ date }) => date === v.date) === i)
@@ -158,8 +228,58 @@ export default function Person() {
158228
)}
159229
{getAssignmentsByDate(date)
160230
.map((assignment) => ({ assignment, activity: getActivity(assignment) }))
161-
.sort((a, b) => byDate(a.activity, b.activity))
231+
.sort((a, b) => byDate(a.assignment.activity, b.assignment.activity))
162232
.map(({ assignment, activity }, index, sortedAssignments) => {
233+
if (!activity?.id) {
234+
const roundedStartTime = roundTime(
235+
new Date(assignment.activity?.startTime || 0),
236+
5
237+
);
238+
const roundedEndTime = roundTime(
239+
new Date(assignment.activity?.endTime || 0),
240+
5
241+
);
242+
243+
const formattedStartTime = roundedStartTime.toLocaleTimeString([], {
244+
hour: '2-digit',
245+
minute: '2-digit',
246+
timeZone: wcif?.schedule?.venues?.[0]?.timezone,
247+
});
248+
const formattedEndTime = roundedEndTime.toLocaleTimeString([], {
249+
hour: '2-digit',
250+
minute: '2-digit',
251+
timeZone: wcif?.schedule?.venues?.[0]?.timezone,
252+
});
253+
254+
const isOver = now > roundedEndTime;
255+
const isCurrent = now > roundedStartTime && now < roundedEndTime;
256+
257+
return (
258+
<tr
259+
key={`${assignment.date}-${formattedStartTime}-${assignment.assignmentCode}`}
260+
className={classNames(
261+
'table-row text-xs sm:text-sm hover:bg-slate-100 border-y',
262+
{
263+
'opacity-40': isOver,
264+
'bg-op': isCurrent,
265+
}
266+
)}>
267+
<td colSpan={2} className="py-2 text-center">
268+
{formattedStartTime} - {formattedEndTime}
269+
</td>
270+
<td colSpan={1} className="py-2 text-center">
271+
{worldsAssignmentMap[assignment.assignmentCode]}
272+
</td>
273+
<td></td>
274+
<td></td>
275+
</tr>
276+
);
277+
}
278+
279+
if (!assignment.activityId) {
280+
return;
281+
}
282+
163283
const { eventId, roundNumber, groupNumber, attemptNumber } =
164284
parseActivityCode(activity?.activityCode || '');
165285

0 commit comments

Comments
 (0)