Skip to content

feat: graphql conf 2024 schedule and speakers #1722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 4, 2024
Merged
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
Binary file added public/img/conf/golden-gate-bridge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app/conf/2023/_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ async function fetchData<T>(url: string): Promise<T> {
}
}

const token = process.env.SCHED_ACCESS_TOKEN
const token = process.env.SCHED_ACCESS_TOKEN_2023

async function getUsernames(): Promise<string[]> {
const response = await fetchData<{ username: string }[]>(
Expand Down
9 changes: 8 additions & 1 deletion src/app/conf/2023/schedule/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { schedule } from "@/app/conf/2023/_data"
import { ScheduleList } from "@/app/conf/_components/schedule/schedule-list"
import { Metadata } from "next"
import { eventsColors } from "../utils"
import { filterCategories2023 } from "../../_components/schedule/filter-categories"

export const metadata: Metadata = {
title: "Schedule",
Expand Down Expand Up @@ -62,7 +64,12 @@ export default function SchedulePage() {
>
🔗 Bookmark sessions & plan your days on Sched
</a>
<ScheduleList scheduleData={schedule} />
<ScheduleList
filterCategories={filterCategories2023}
eventsColors={eventsColors}
year="2023"
scheduleData={schedule}
/>
</div>
</div>
</>
Expand Down
2 changes: 1 addition & 1 deletion src/app/conf/2023/sessions/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default function SessionPage({ params }: SessionProps) {
<div className="py-10">
<section className="text-[#333333] min-h-[80vh] flex-col mx-auto px-2 xs:px-0 lg:justify-between justify-center md:container">
<div className="flex flex-col lg:px-0">
<BackLink kind="sessions" />
<BackLink year="2023" kind="sessions" />
{recordingTitle.rating > 0.5 && (
<iframe
className="aspect-video max-w-[1000px] mx-auto size-full rounded-md"
Expand Down
5 changes: 5 additions & 0 deletions src/app/conf/2023/sessions/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Metadata } from "next"
import { SessionList } from "@/app/conf/_components/schedule/session-list"
import { schedule, speakers } from "@/app/conf/2023/_data"
import { eventsColors } from "../utils"
import { filterCategories2023 } from "../../_components/schedule/filter-categories"

export const metadata: Metadata = {
title: "Sessions",
Expand All @@ -11,6 +13,9 @@ export default function SessionsPage() {
<div className="bg-[#f4f6f8]">
<div className="container conf-block">
<SessionList
year="2023"
eventsColors={eventsColors}
filterCategories={filterCategories2023}
// @ts-expect-error -- fixme
scheduleData={schedule
.filter(schedule => schedule.speakers)
Expand Down
15 changes: 11 additions & 4 deletions src/app/conf/2023/speakers/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { Avatar } from "@/app/conf/_components/speakers/avatar"
import { speakers, schedule } from "@/app/conf/2023/_data"
import { ChevronLeftIcon } from "@/icons"
import NextLink from "next/link"
import { eventsColors } from "../../utils"
import { filterCategories2023 } from "@/app/conf/_components/schedule/filter-categories"

type SpeakerProps = { params: { id: string } }

Expand Down Expand Up @@ -45,8 +47,8 @@ export default function SpeakerPage({ params }: SpeakerProps) {
.filter(s => s.speakers && s.speakers.some(s => s.username === params.id))
.map(s => ({
...s,
speakers: s.speakers!.map(s =>
speakers.find(speaker => speaker.username === s.username),
speakers: s.speakers!.map(
s => speakers.find(speaker => speaker.username === s.username)!,
),
}))

Expand Down Expand Up @@ -104,8 +106,13 @@ export default function SpeakerPage({ params }: SpeakerProps) {
/>
</div>
<h1 className="conf-heading mb-10">Sessions</h1>
{/* @ts-expect-error */}
<SessionList showFilter={false} scheduleData={s} />
<SessionList
filterCategories={filterCategories2023}
eventsColors={eventsColors}
year="2023"
showFilter={false}
scheduleData={s}
/>
</div>
</div>
</section>
Expand Down
2 changes: 1 addition & 1 deletion src/app/conf/2023/speakers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function Page() {
<div className="bg-white">
<section className="container flex gap-8 flex-wrap lg:justify-between justify-center conf-block">
{speakers.map(speaker => (
<Speaker key={speaker.username} {...speaker} />
<Speaker key={speaker.username} {...speaker} year="2023" />
))}
</section>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/app/conf/2023/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ export type SchedSpeaker = {
role: string
location?: string
socialurls: { service: string; url: string }[]
year: "2024" | "2023"
}
84 changes: 84 additions & 0 deletions src/app/conf/2024/_data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import "server-only"
import { stripHtml } from "string-strip-html"
import { SchedSpeaker, ScheduleSession } from "@/app/conf/2023/types"
import pLimit from "p-limit"

async function fetchData<T>(url: string): Promise<T> {
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": "GraphQL Conf / GraphQL Foundation",
},
})
const data = await response.json()
return data
} catch (error) {
throw new Error(
`Error fetching data from ${url}: ${(error as Error).message || (error as Error).toString()}`,
)
}
}

const token = process.env.SCHED_ACCESS_TOKEN_2024

async function getUsernames(): Promise<string[]> {
const response = await fetchData<{ username: string }[]>(
`https://graphqlconf2024.sched.com/api/user/list?api_key=${token}&format=json&fields=username`,
)
return response.map(user => user.username)
}

const limit = pLimit(40) // rate limit is 30req/min

async function getSpeakers(): Promise<SchedSpeaker[]> {
const usernames = await getUsernames()

const users = await Promise.all(
usernames.map(username =>
limit(() => {
return fetchData<SchedSpeaker>(
`https://graphqlconf2024.sched.com/api/user/get?api_key=${token}&by=username&term=${username}&format=json&fields=username,company,position,name,about,location,url,avatar,role,socialurls`,
)
}),
),
)

const result = users
.filter(speaker => speaker.role.includes("speaker"))
.map(user => {
return {
...user,
about: stripHtml(user.about).result,
}
})

return result
}

async function getSchedule(): Promise<ScheduleSession[]> {
const sessions = await fetchData<ScheduleSession[]>(
`https://graphqlconf2024.sched.com/api/session/export?api_key=${token}&format=json`,
)

const result = sessions.map(session => {
const { description } = session
if (description?.includes("<")) {
// console.log(`Found HTML element in about field for session "${session.name}"`)
}

return {
...session,
description: description && stripHtml(description).result,
}
})

return result
}

// @ts-expect-error -- fixme
export const speakers = await getSpeakers()

// @ts-expect-error -- fixme
export const schedule = await getSchedule()
25 changes: 17 additions & 8 deletions src/app/conf/2024/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,17 @@ export default function Layout({
</NextLink>
}
links={[
{ children: <span>FAQ</span>, href: "/conf/2024/faq" },
{ children: <span>Register</span>, href: "/conf/2024#attend" },
{ children: <span>Partner</span>, href: "/conf/2024/partner" },
{
children: <span>Schedule</span>,
href: "https://graphqlconf2024.sched.com/",
href: "/conf/2024/schedule",
},
{
children: <span>Speakers</span>,
href: "/conf/2024/speakers",
},
{ children: <span>FAQ</span>, href: "/conf/2024/faq" },
{ children: <span>Register</span>, href: "/conf/2024#attend" },
{ children: <span>Partner</span>, href: "/conf/2024/partner" },
]}
/>
{children}
Expand All @@ -64,6 +68,14 @@ export default function Layout({
}
links={[
[
{
children: "Schedule",
href: "/conf/2024/schedule",
},
{
children: "Speakers",
href: "/conf/2024/speakers",
},
{ children: "Register", href: "https://cvent.me/gk2dRw" },
{ children: "Sponsor", href: "/conf/2024/partner" },
{ children: "Partner", href: "/conf/2024/partner#program" },
Expand All @@ -72,10 +84,7 @@ export default function Layout({
href: "/conf/2024/speakers",
"aria-disabled": true,
},
{
children: "Schedule",
href: "https://graphqlconf2024.sched.com/",
},

{ children: "GraphQLConf 2023", href: "/conf/2023" },
],
[
Expand Down
Loading
Loading