Skip to content

Commit

Permalink
feat: allowing to click the room to see only one room at a time
Browse files Browse the repository at this point in the history
  • Loading branch information
martinheidegger committed Oct 26, 2024
1 parent 2fc57e7 commit 861b9a2
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 26 deletions.
11 changes: 11 additions & 0 deletions 2024/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
const schedulePages = [undefined, "A", "B", "C", "D"]

exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions

return new Promise((resolve, reject) => {
const mdTemplate = path.resolve(`./src/templates/markdown.tsx`)
const speakerTemplate = path.resolve(`./src/templates/speaker.tsx`)
const scheduleTemplate = path.resolve(`./src/templates/schedule.tsx`)
resolve(
graphql(`
query {
Expand Down Expand Up @@ -195,6 +197,15 @@ exports.createPages = ({ graphql, actions }) => {
},
})
})
schedulePages.forEach(track => {
createPage({
path: track ? `schedule/${track}` : "schedule",
component: scheduleTemplate,
context: {
selectedTrack: track,
},
})
})
}),
)
})
Expand Down
9 changes: 9 additions & 0 deletions 2024/src/components/InlineLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Link } from "gatsby"
import styled from "styled-components"

export const InlineLink = styled(Link)`
text-decoration: none;
font-family: ${({ theme }) => theme.fonts.text};
color: inherit;
text-align: left;
`
29 changes: 21 additions & 8 deletions 2024/src/components/RoomLegend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react"
import styled from "styled-components"
import { useTranslation } from "react-i18next"
import { Rooms, rooms } from "../util/misc"
import { InlineLink } from "./InlineLink"

const Box = styled.div`
display: flex;
Expand All @@ -15,17 +16,18 @@ const Box = styled.div`
gap: 1em;
}
`
const RoomBox = styled.div`
const RoomBox = styled(InlineLink)<{ disabled: boolean }>`
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
${({ disabled }) => (disabled ? `opacity: 0.5;` : "")}
`
const Circle = styled.div<{ area: Rooms }>`
const Circle = styled.div<{ track: Rooms }>`
width: 30px;
height: 30px;
border-radius: 30px;
background-color: ${({ area, theme }) => theme.colors[`room${area}Border`]};
background-color: ${({ track, theme }) => theme.colors[`room${track}Border`]};
`
const Text = styled.span`
flex: 1;
Expand All @@ -50,12 +52,21 @@ const TextBox = styled.div`

type RoomProps = {
track: Rooms
selectedTrack?: Rooms | undefined
}
export const Room = ({ track }: RoomProps) => {

export const Room = ({ track, selectedTrack }: RoomProps) => {
const { t } = useTranslation()
return (
<RoomBox key={track}>
<Circle area={track} />
<RoomBox
to={
selectedTrack && selectedTrack === track
? "/schedule"
: `/schedule/${track}`
}
disabled={!!selectedTrack && track != selectedTrack}
>
<Circle track={track} />
<TextBox>
<Text>{t(`room${track}`)}</Text>
<SubText>{t(`room${track}Sub`)}</SubText>
Expand All @@ -64,10 +75,12 @@ export const Room = ({ track }: RoomProps) => {
)
}

export const RoomLegend = () => (
export type RoomLegendProps = Pick<RoomProps, "selectedTrack">

export const RoomLegend = (props: RoomLegendProps) => (
<Box>
{rooms.map((track, i) => (
<Room key={i} track={track} />
<Room key={i} track={track} {...props} />
))}
</Box>
)
102 changes: 89 additions & 13 deletions 2024/src/pages/schedule.tsx → 2024/src/templates/schedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useLayoutEffect } from "react"
import styled from "styled-components"
import { useTranslation } from "react-i18next"
import { useStaticQuery, graphql } from "gatsby"
import { Link as _Link, navigate } from "gatsby-link"
import flatten from "lodash/flatten"

import { Layout } from "../components/Layout"
Expand Down Expand Up @@ -32,18 +33,33 @@ function getHours(time: string | Date) {
return time.getHours()
}

function getMinutes(time: string | Date) {
if (typeof time === "string") {
return parseInt(time.split(":")[1])
}
return time.getMinutes()
}

const Grid = styled.div<{
"starts-at": Date | string
"ends-at": Date | string
tracks: Rooms[]
}>`
display: grid;
grid-column-gap: 1em;
grid-template-columns: ${rooms
.concat(dummyTrack)
.map(r => `[${r}]`)
.join(" 1fr ")};
grid-template-columns: ${({ tracks }) =>
tracks
.concat(dummyTrack)
.map(r => `[${r}]`)
.join(" 1fr ")};
grid-template-rows: ${({ "starts-at": startsAt, "ends-at": endsAt }) =>
rangeTimeBoxes(5, getHours(startsAt), getHours(endsAt))
rangeTimeBoxes(
5,
getHours(startsAt),
getHours(endsAt),
getMinutes(startsAt),
getMinutes(endsAt),
)
.map(t => `[t-${escapeTime(t)}]`)
.join(" minmax(1em, max-content) ")};
Expand All @@ -57,13 +73,14 @@ const Area = styled(OptionalLink)<{
["starts-at"]: string
["ends-at"]: string
["$is-break"]: boolean
selectedTrack: string | undefined
}>`
margin-bottom: 1em;
padding: 1em;
text-decoration: none;
position: relative;
grid-column: ${({ track, "$is-break": isBreak }) =>
isBreak ? `A / ${dummyTrack}` : track};
grid-column: ${({ track, "$is-break": isBreak, selectedTrack }) =>
!selectedTrack && isBreak ? `A / ${dummyTrack}` : track};
grid-row: ${({ "starts-at": startsAt, "ends-at": endsAt }) =>
`t-${escapeTime(startsAt)} / t-${escapeTime(endsAt)}`};
background-color: ${({ track, "$is-break": isBreak, theme, to }) =>
Expand Down Expand Up @@ -168,7 +185,34 @@ export const Head = () => {
return <SEO title={t("schedule")} description={t("schedule.description")} />
}

export default function SchedulePage() {
function filterTrim<T>(array: T[], filter: (t: T) => boolean) {
let start = 0
let len = array.length
while (start < len) {
if (!filter(array[start])) {
break
}
start += 1
}
let end = len - 1
while (end > start) {
if (!filter(array[end])) {
break
}
end -= 1
}
return array.slice(start, end + 1)
}

export type SchedulePageProps = {
pageContext: {
selectedTrack?: Rooms
}
}

export default function SchedulePage({
pageContext: { selectedTrack },
}: SchedulePageProps) {
const { t, i18n } = useTranslation()
const enOrJa = useEnOrJa()
const { allSpeakersYaml, allSponsorsYaml, allTalksYaml } = useStaticQuery(
Expand Down Expand Up @@ -297,19 +341,50 @@ export default function SchedulePage() {
<Title>{t("schedule")}</Title>

{days.map(day => {
const { startsAt, endsAt } = times[day]
const sessions = flatten(
let { startsAt, endsAt } = times[day] as {
startsAt: Date | string
endsAt: Date | string
}
const allSessions = flatten(
timetable[day].map(({ sessions }) => sessions),
)
let sessions = allSessions
if (selectedTrack) {
sessions = filterTrim(
sessions
.filter(
session =>
session.track === selectedTrack ||
(session.break && session.track === "A"),
)
.map(event => {
if (event.break) {
return {
...event,
track: selectedTrack,
uuid: `${event.uuid}_${selectedTrack}`,
} as Session
}
return event
}),
session => session.break,
)
startsAt = sessions[0].startsAt
endsAt = sessions[sessions.length - 1].endsAt
}
return (
<React.Fragment key={day}>
<SubTitle id={day}>
{dateTimeFormatter.format(times[day].startsAt)}
</SubTitle>
<RoomLegendBox>
<RoomLegend />
<RoomLegend selectedTrack={selectedTrack} />
</RoomLegendBox>
<Grid starts-at={startsAt} ends-at={endsAt}>
<Grid
starts-at={startsAt}
ends-at={endsAt}
tracks={selectedTrack ? [selectedTrack] : rooms}
>
{sessions.map(s => {
const hasDescription =
s.uuid && (s.speakers.length || s.sponsors.length)
Expand All @@ -331,11 +406,12 @@ export default function SchedulePage() {
starts-at={s.startsAt}
ends-at={s.endsAt}
$is-break={s.break || false}
selectedTrack={selectedTrack}
>
<AreaTitle>
<EventTime session={s} />
</AreaTitle>
<Text>{getSessionName(s, sessions)}</Text>
<Text>{getSessionName(s, allSessions)}</Text>
<EventSpeakers session={s} />

<AreaFooter>
Expand Down
13 changes: 8 additions & 5 deletions 2024/src/util/rangeTimeBoxes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ export const rangeTimeBoxes = (
everyMinutes: number,
startHours: number,
endHours: number,
startMinutes: number = 0,
endMinutes: number = 0,
) => {
const timeboxes = []
const end = endHours * 60 + endMinutes
for (
let hour = startHours * 60;
hour <= endHours * 60;
hour += everyMinutes
let time = startHours * 60 + startMinutes;
time <= end;
time += everyMinutes
) {
const h = Math.floor(hour / 60)
const m = hour % 60
const h = Math.floor(time / 60)
const m = time % 60
timeboxes.push(`${zeroFill(h, 2)}:${zeroFill(m, 2)}`)
}
return timeboxes
Expand Down

0 comments on commit 861b9a2

Please sign in to comment.