Compare commits
2 commits
08ae2bb88a
...
9a04e25c20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a04e25c20 | ||
|
|
363413cd38 |
2 changed files with 60 additions and 29 deletions
|
|
@ -10,6 +10,7 @@ interface ScheduleEvent {
|
||||||
name: string;
|
name: string;
|
||||||
eventDate: string | null;
|
eventDate: string | null;
|
||||||
eventStartsAt?: Date | string | null;
|
eventStartsAt?: Date | string | null;
|
||||||
|
earliestGameTime?: string | null;
|
||||||
eventType: string;
|
eventType: string;
|
||||||
isComplete: boolean;
|
isComplete: boolean;
|
||||||
completedAt?: Date | string | null;
|
completedAt?: Date | string | null;
|
||||||
|
|
@ -52,10 +53,13 @@ function getEventTypeLabel(eventType: string): string {
|
||||||
export function EventSchedule({ upcomingEvents, recentEvents, leagueId, sportsSeasonId }: EventScheduleProps) {
|
export function EventSchedule({ upcomingEvents, recentEvents, leagueId, sportsSeasonId }: EventScheduleProps) {
|
||||||
const isMounted = useHasMounted();
|
const isMounted = useHasMounted();
|
||||||
|
|
||||||
function getDisplayDate(event: Pick<ScheduleEvent, "eventDate" | "eventStartsAt">): string {
|
function getDisplayDate(event: Pick<ScheduleEvent, "eventDate" | "eventStartsAt" | "earliestGameTime">): string {
|
||||||
if (isMounted && event.eventStartsAt) {
|
if (isMounted) {
|
||||||
const d = new Date(event.eventStartsAt as string);
|
const ts = event.earliestGameTime ?? (event.eventStartsAt as string | null | undefined);
|
||||||
if (!isNaN(d.getTime())) return format(d, "MMM d, yyyy");
|
if (ts) {
|
||||||
|
const d = new Date(ts);
|
||||||
|
if (!isNaN(d.getTime())) return format(d, "MMM d, yyyy");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return formatEventDate(event.eventDate);
|
return formatEventDate(event.eventDate);
|
||||||
}
|
}
|
||||||
|
|
@ -109,8 +113,8 @@ export function EventSchedule({ upcomingEvents, recentEvents, leagueId, sportsSe
|
||||||
<p className="text-xs text-muted-foreground flex items-center gap-1 mt-0.5">
|
<p className="text-xs text-muted-foreground flex items-center gap-1 mt-0.5">
|
||||||
<Calendar className="h-3 w-3" />
|
<Calendar className="h-3 w-3" />
|
||||||
<span>{getDisplayDate(event)}</span>
|
<span>{getDisplayDate(event)}</span>
|
||||||
{isMounted && event.eventStartsAt && (
|
{isMounted && (event.earliestGameTime ?? event.eventStartsAt) && (
|
||||||
<span>· {format(new Date(event.eventStartsAt), "h:mm a")}</span>
|
<span>· {new Date(event.earliestGameTime ?? (event.eventStartsAt as string)).toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit" })}</span>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -310,33 +310,54 @@ export async function getUpcomingScoringEvents(
|
||||||
|
|
||||||
if (events.length === 0) return [];
|
if (events.length === 0) return [];
|
||||||
|
|
||||||
// Find earliest upcoming game time per event from bracket match games.
|
// Find earliest upcoming game time per event from both bracket match games
|
||||||
|
// and group stage matches (FIFA World Cup style).
|
||||||
const eventIds = events.map((e) => e.id);
|
const eventIds = events.map((e) => e.id);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const gameTimeRows = await db
|
|
||||||
.select({
|
const [gameTimeRows, groupStageTimeRows] = await Promise.all([
|
||||||
eventId: schema.scoringEvents.id,
|
db
|
||||||
scheduledAt: schema.playoffMatchGames.scheduledAt,
|
.select({
|
||||||
})
|
eventId: schema.scoringEvents.id,
|
||||||
.from(schema.scoringEvents)
|
scheduledAt: schema.playoffMatchGames.scheduledAt,
|
||||||
.innerJoin(
|
})
|
||||||
schema.playoffMatches,
|
.from(schema.scoringEvents)
|
||||||
eq(schema.playoffMatches.scoringEventId, schema.scoringEvents.id)
|
.innerJoin(
|
||||||
)
|
schema.playoffMatches,
|
||||||
.innerJoin(
|
eq(schema.playoffMatches.scoringEventId, schema.scoringEvents.id)
|
||||||
schema.playoffMatchGames,
|
|
||||||
eq(schema.playoffMatchGames.playoffMatchId, schema.playoffMatches.id)
|
|
||||||
)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
inArray(schema.scoringEvents.id, eventIds),
|
|
||||||
isNotNull(schema.playoffMatchGames.scheduledAt),
|
|
||||||
gte(schema.playoffMatchGames.scheduledAt, now)
|
|
||||||
)
|
)
|
||||||
);
|
.innerJoin(
|
||||||
|
schema.playoffMatchGames,
|
||||||
|
eq(schema.playoffMatchGames.playoffMatchId, schema.playoffMatches.id)
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
inArray(schema.scoringEvents.id, eventIds),
|
||||||
|
isNotNull(schema.playoffMatchGames.scheduledAt),
|
||||||
|
gte(schema.playoffMatchGames.scheduledAt, now)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
db
|
||||||
|
.select({
|
||||||
|
eventId: schema.tournamentGroups.scoringEventId,
|
||||||
|
scheduledAt: schema.groupStageMatches.scheduledAt,
|
||||||
|
})
|
||||||
|
.from(schema.groupStageMatches)
|
||||||
|
.innerJoin(
|
||||||
|
schema.tournamentGroups,
|
||||||
|
eq(schema.groupStageMatches.tournamentGroupId, schema.tournamentGroups.id)
|
||||||
|
)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
inArray(schema.tournamentGroups.scoringEventId, eventIds),
|
||||||
|
isNotNull(schema.groupStageMatches.scheduledAt),
|
||||||
|
gte(schema.groupStageMatches.scheduledAt, now)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
const earliestGameById = new Map<string, Date>();
|
const earliestGameById = new Map<string, Date>();
|
||||||
for (const row of gameTimeRows) {
|
for (const row of [...gameTimeRows, ...groupStageTimeRows]) {
|
||||||
if (!row.scheduledAt) continue;
|
if (!row.scheduledAt) continue;
|
||||||
const prev = earliestGameById.get(row.eventId);
|
const prev = earliestGameById.get(row.eventId);
|
||||||
if (!prev || row.scheduledAt < prev) {
|
if (!prev || row.scheduledAt < prev) {
|
||||||
|
|
@ -353,7 +374,13 @@ export async function getUpcomingScoringEvents(
|
||||||
return candidates.length > 0 ? Math.min(...candidates) : Infinity;
|
return candidates.length > 0 ? Math.min(...candidates) : Infinity;
|
||||||
};
|
};
|
||||||
|
|
||||||
return events.toSorted((a, b) => getEffectiveMs(a) - getEffectiveMs(b)).slice(0, limit);
|
return events
|
||||||
|
.toSorted((a, b) => getEffectiveMs(a) - getEffectiveMs(b))
|
||||||
|
.slice(0, limit)
|
||||||
|
.map((e) => ({
|
||||||
|
...e,
|
||||||
|
earliestGameTime: earliestGameById.get(e.id)?.toISOString() ?? null,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue