Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/PeopleList/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './PeopleList';
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export * from './LastFetchedAt';
export * from './LinkButton';
export * from './Notebox';
export * from './PinCompetitionButton';
export * from './PeopleList';
69 changes: 69 additions & 0 deletions src/containers/Schedule/Activity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Activity, activityCodeToName } from '@wca/helpers';
import { useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { Container } from '@/components/Container';
import { getAllActivities } from '@/lib/activities';
import { parseActivityCodeFlexible } from '@/lib/activityCodes';
import { useWCIF } from '@/providers/WCIFProvider';
import { EventActivity } from './EventActivity';
import { OtherActivity } from './OtherActivity';

export function CompetitionActivity() {
const { wcif } = useWCIF();
const { activityId } = useParams();

const activity = useMemo(
() =>
wcif && getAllActivities(wcif).find((a) => activityId && a.id === parseInt(activityId, 10)),
[wcif, activityId],
);

const everyoneInActivity = useMemo(
() =>
wcif
? wcif.persons
.map((person) => ({
...person,
assignments: person.assignments?.filter(
(a) => activityId && a.activityId === parseInt(activityId, 10), // TODO this is a hack because types aren't fixed yet for @wca/helpers
),
}))
.filter(({ assignments }) => assignments && assignments.length > 0)
: [],
[wcif, activityId],
);

if (!activity) {
return (
<Container>
<h2>Activity not found</h2>
</Container>
);
}

const { eventId } = parseActivityCodeFlexible(activity.activityCode);

const isEventGroup = !eventId?.startsWith('other');
const GroupComponent = isEventGroup ? EventActivity : OtherActivity;

return (
<Container>
{wcif?.id && activity && everyoneInActivity && (
<GroupComponent competitionId={wcif.id} activity={activity} persons={everyoneInActivity} />
)}
</Container>
);
}

export const niceActivityName = (activty: Activity) => {
if (activty.activityCode.startsWith('other')) {
return activty.name;
} else {
try {
return activityCodeToName(activty.activityCode);
} catch (e) {
console.error(e);
return activty.name;
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import {
import { useCallback, useEffect, useMemo } from 'react';
import { Link } from 'react-router-dom';
import { CutoffTimeLimitPanel } from '@/components/CutoffTimeLimitPanel';
import { PeopleList } from '@/components/PeopleList';
import { getRooms } from '@/lib/activities';
import { isRankedBySingle } from '@/lib/events';
import { renderResultByEventId } from '@/lib/results';
import { formatDateTimeRange } from '@/lib/time';
import { useWCIF } from '@/providers/WCIFProvider';
import { PeopleList } from './PeopleList';

const isAssignment = (assignment) => (a) =>
a.assignments.some(({ assignmentCode }) => assignmentCode === assignment);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Activity, AssignmentCode, Person } from '@wca/helpers';
import { useEffect, useMemo } from 'react';
import { Link } from 'react-router-dom';
import { PeopleList } from '@/components/PeopleList';
import { getRooms } from '@/lib/activities';
import { formatDateTimeRange } from '@/lib/time';
import { useWCIF } from '@/providers/WCIFProvider';
import { PeopleList } from './PeopleList';

interface OtherGroupProps {
competitionId: string;
Expand Down
132 changes: 132 additions & 0 deletions src/containers/Schedule/Room.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { useCallback, useEffect, useMemo } from 'react';
import { Link, useParams } from 'react-router-dom';
import { ActivityRow, Container } from '@/components';
import { getAllChildActivities } from '@/lib/activities';
import { formatToParts } from '@/lib/time';
import { byDate } from '@/lib/utils';
import { useWCIF } from '@/providers/WCIFProvider';

export function CompetitionRoom() {
const { wcif, setTitle } = useWCIF();
const { roomId } = useParams();

useEffect(() => {
setTitle('Schedule');
}, [setTitle]);

const venue = wcif?.schedule?.venues?.find((venue) =>
venue.rooms.some((room) => room.id.toString() === roomId),
);
const room = venue?.rooms?.find((room) => room.id.toString() === roomId);

const timeZone = venue?.timezone ?? wcif?.schedule.venues?.[0]?.timezone ?? '';

const activities = useMemo(
() =>
room?.activities
.flatMap((activity) =>
activity?.childActivities?.length ? getAllChildActivities(activity) : activity,
)
.sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime()) || [],
[room?.activities],
);

const scheduleDays = activities
.map((activity) => {
const venue =
wcif?.schedule.venues?.find((v) =>
v.rooms.some((r) =>
r.activities.some(
(a) => a.id === activity.id || a.childActivities?.some((ca) => ca.id === activity.id),
),
),
) || wcif?.schedule.venues?.[0];

const dateTime = new Date(activity.startTime);

return {
approxDateTime: dateTime.getTime(),
date: dateTime.toLocaleDateString([], {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: venue?.timezone,
}),
dateParts: formatToParts(dateTime),
};
})
.filter((v, i, arr) => arr.findIndex(({ date }) => date === v.date) === i)
.sort((a, b) => a.approxDateTime - b.approxDateTime);

const activitiesWithParsedDate = activities
.map((activity) => {
const venue =
wcif?.schedule.venues?.find((v) =>
v.rooms.some((r) =>
r.activities.some(
(a) => a.id === activity.id || a.childActivities?.some((ca) => ca.id === activity.id),
),
),
) || wcif?.schedule.venues?.[0];

const dateTime = new Date(activity.startTime);

return {
...activity,
date: dateTime.toLocaleDateString([], {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: venue?.timezone,
}),
};
})
.sort((a, b) => byDate(a, b));

const getActivitiesByDate = useCallback(
(date) => {
return activitiesWithParsedDate.filter((a) => a.date === date);
},
[activitiesWithParsedDate],
);

return (
<Container>
<div className="flex w-full flex-col text-sm md:text-base py-2">
<div className="p-2">
<h3 className="font-bold text-lg -mb-2">{room?.name}</h3>
<span className="text-xs">{venue?.name}</span>
</div>

{scheduleDays.map((day) => (
<div key={day.date} className="flex flex-col">
<p className="w-full text-center bg-slate-50 font-bold text-lg mb-1">{day.date}</p>
<div className="flex flex-col">
{getActivitiesByDate(day.date).map((activity) => {
return (
<ActivityRow
key={activity.id}
activity={activity}
timeZone={timeZone}
room={room}
showRoom={false}
/>
);
})}
</div>
</div>
))}
<hr className="my-2" />
<div className="flex flex-row justify-between">
<Link
to={`/competitions/${wcif?.id}/rooms`}
className="w-full border bg-blue-200 rounded-md p-2 px-1 flex cursor-pointer hover:bg-blue-400 group transition-colors my-1 flex-row">
Back to list of Rooms
</Link>
</div>
</div>
</Container>
);
}
40 changes: 40 additions & 0 deletions src/containers/Schedule/Rooms.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useEffect } from 'react';
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container';
import { useWCIF } from '@/providers/WCIFProvider';

export function CompetitionRooms() {
const { wcif, setTitle } = useWCIF();

useEffect(() => {
setTitle('Rooms');
}, [setTitle]);

return (
<Container>
<div className="flex flex-col p-1">
{wcif?.schedule?.venues?.map((venue) => (
<div key={venue.id} className="flex flex-col mb-4">
<p>
<span className="font-bold">{venue.name}</span> ({venue.timezone})
</p>
<br />
<div className="flex flex-col space-y-4">
{venue.rooms.map((room) => (
<Link key={room.id} to={`/competitions/${wcif.id}/rooms/${room.id}`}>
<div
className="flex flex-col shadow-md w-full cursor-pointer hover:opacity-90 rounded"
style={{
backgroundColor: `${room?.color}70`,
}}>
<h3 className="text-lg w-full p-2">{room.name}</h3>
</div>
</Link>
))}
</div>
</div>
))}
</div>
</Container>
);
}
5 changes: 5 additions & 0 deletions src/containers/Schedule/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export * from './Schedule';
export * from './Activity';
export * from './Room';
export * from './Rooms';
export * from './EventActivity';
export * from './OtherActivity';
70 changes: 1 addition & 69 deletions src/pages/Competition/Schedule/Activity.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1 @@
import { Activity, activityCodeToName } from '@wca/helpers';
import { useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { Container } from '@/components/Container';
import { getAllActivities } from '@/lib/activities';
import { parseActivityCodeFlexible } from '@/lib/activityCodes';
import { useWCIF } from '@/providers/WCIFProvider';
import { EventActivity } from './EventActivity';
import { OtherActivity } from './OtherActivity';

export function CompetitionActivity() {
const { wcif } = useWCIF();
const { activityId } = useParams();

const activity = useMemo(
() =>
wcif && getAllActivities(wcif).find((a) => activityId && a.id === parseInt(activityId, 10)),
[wcif, activityId],
);

const everyoneInActivity = useMemo(
() =>
wcif
? wcif.persons
.map((person) => ({
...person,
assignments: person.assignments?.filter(
(a) => activityId && a.activityId === parseInt(activityId, 10), // TODO this is a hack because types aren't fixed yet for @wca/helpers
),
}))
.filter(({ assignments }) => assignments && assignments.length > 0)
: [],
[wcif, activityId],
);

if (!activity) {
return (
<Container>
<h2>Activity not found</h2>
</Container>
);
}

const { eventId } = parseActivityCodeFlexible(activity.activityCode);

const isEventGroup = !eventId?.startsWith('other');
const GroupComponent = isEventGroup ? EventActivity : OtherActivity;

return (
<Container>
{wcif?.id && activity && everyoneInActivity && (
<GroupComponent competitionId={wcif.id} activity={activity} persons={everyoneInActivity} />
)}
</Container>
);
}

export const niceActivityName = (activty: Activity) => {
if (activty.activityCode.startsWith('other')) {
return activty.name;
} else {
try {
return activityCodeToName(activty.activityCode);
} catch (e) {
console.error(e);
return activty.name;
}
}
};
export { CompetitionActivity } from '@/containers/Schedule';
Loading