@@ -11,6 +11,16 @@ import { formatDate, formatToParts, roundTime } from '../../../lib/utils';
1111import DisclaimerText from '../../../components/DisclaimerText' ;
1212import { shortEventNameById } from '../../../lib/events' ;
1313import 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
1525export 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