diff --git a/src/app/conf/2025/schedule/_components/schedule-list.tsx b/src/app/conf/2025/schedule/_components/schedule-list.tsx index f6d3f60c71..e2fedb469b 100644 --- a/src/app/conf/2025/schedule/_components/schedule-list.tsx +++ b/src/app/conf/2025/schedule/_components/schedule-list.tsx @@ -101,6 +101,19 @@ function getSessionsByDay( } } +const timeFormat = new Intl.DateTimeFormat(undefined, { + hour: "2-digit", + minute: "2-digit", +}) +const formatBlockTime = (start: string, end?: string) => { + const startDate = parseISO(start) + if (end) { + const endDate = parseISO(end) + return timeFormat.formatRange(startDate, endDate) + } + return timeFormat.format(startDate) +} + export interface ScheduleListProps { showFilter?: boolean scheduleData: ScheduleSession[] @@ -191,36 +204,64 @@ export function ScheduleList({ {format(parseISO(date), "EEEE, MMMM d")} {Object.entries(concurrentSessionsGroup).map( - ([sessionDate, sessions]) => ( -
-
-
- - {parseISO(sessionDate).toLocaleTimeString( - undefined, - { - hour: "2-digit", - minute: "2-digit", - }, - )} - + ([sessionDate, sessions], i, blocks) => { + const blockEnd = sessions[0]?.event_end + const nextBlockStart = blocks[i + 1]?.[0] + + const isBreak = + sessions[0]?.event_type + ?.toLowerCase() + .includes("break") || + blocks[i + 1]?.[1]?.[0]?.event_type + ?.toLowerCase() + .includes("break") + const hasDashedBorder = + blockEnd && blockEnd === nextBlockStart && !isBreak + + return ( +
+
+
+ + {formatBlockTime(sessionDate, blockEnd)} + +
+
+ {sessions.map(session => ( + + ))} +
-
- {sessions.map(session => ( - + - ))} -
+ + )}
-
- ), + ) + }, )}
), @@ -237,7 +278,7 @@ function BookmarkOnSched({ year }: { year: `202${number}` }) { href={`https://graphqlconf${year}.sched.com`} target="_blank" rel="noreferrer" - className="typography-link mb-8 block w-fit decoration-neu-400" + className="typography-link mb-8 block w-fit decoration-neu-400 max-lg:hidden" > Bookmark sessions & plan your days on Sched