Skip to content

Commit fdf9ad1

Browse files
authored
feat: graphql conf 2024 schedule and speakers (#1722)
* feat: graphql conf 2024 schedule and speakers * fix * fix * fix partial data page rendering failure * chore: prettier * improve colors
1 parent 5e1f64e commit fdf9ad1

File tree

22 files changed

+658
-37
lines changed

22 files changed

+658
-37
lines changed
1.64 MB
Loading

src/app/conf/2023/_data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ async function fetchData<T>(url: string): Promise<T> {
2121
}
2222
}
2323

24-
const token = process.env.SCHED_ACCESS_TOKEN
24+
const token = process.env.SCHED_ACCESS_TOKEN_2023
2525

2626
async function getUsernames(): Promise<string[]> {
2727
const response = await fetchData<{ username: string }[]>(

src/app/conf/2023/schedule/page.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { schedule } from "@/app/conf/2023/_data"
22
import { ScheduleList } from "@/app/conf/_components/schedule/schedule-list"
33
import { Metadata } from "next"
4+
import { eventsColors } from "../utils"
5+
import { filterCategories2023 } from "../../_components/schedule/filter-categories"
46

57
export const metadata: Metadata = {
68
title: "Schedule",
@@ -62,7 +64,12 @@ export default function SchedulePage() {
6264
>
6365
🔗 Bookmark sessions & plan your days on Sched
6466
</a>
65-
<ScheduleList scheduleData={schedule} />
67+
<ScheduleList
68+
filterCategories={filterCategories2023}
69+
eventsColors={eventsColors}
70+
year="2023"
71+
scheduleData={schedule}
72+
/>
6673
</div>
6774
</div>
6875
</>

src/app/conf/2023/sessions/[id]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default function SessionPage({ params }: SessionProps) {
8787
<div className="py-10">
8888
<section className="text-[#333333] min-h-[80vh] flex-col mx-auto px-2 xs:px-0 lg:justify-between justify-center md:container">
8989
<div className="flex flex-col lg:px-0">
90-
<BackLink kind="sessions" />
90+
<BackLink year="2023" kind="sessions" />
9191
{recordingTitle.rating > 0.5 && (
9292
<iframe
9393
className="aspect-video max-w-[1000px] mx-auto size-full rounded-md"

src/app/conf/2023/sessions/page.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Metadata } from "next"
22
import { SessionList } from "@/app/conf/_components/schedule/session-list"
33
import { schedule, speakers } from "@/app/conf/2023/_data"
4+
import { eventsColors } from "../utils"
5+
import { filterCategories2023 } from "../../_components/schedule/filter-categories"
46

57
export const metadata: Metadata = {
68
title: "Sessions",
@@ -11,6 +13,9 @@ export default function SessionsPage() {
1113
<div className="bg-[#f4f6f8]">
1214
<div className="container conf-block">
1315
<SessionList
16+
year="2023"
17+
eventsColors={eventsColors}
18+
filterCategories={filterCategories2023}
1419
// @ts-expect-error -- fixme
1520
scheduleData={schedule
1621
.filter(schedule => schedule.speakers)

src/app/conf/2023/speakers/[id]/page.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { Avatar } from "@/app/conf/_components/speakers/avatar"
1111
import { speakers, schedule } from "@/app/conf/2023/_data"
1212
import { ChevronLeftIcon } from "@/icons"
1313
import NextLink from "next/link"
14+
import { eventsColors } from "../../utils"
15+
import { filterCategories2023 } from "@/app/conf/_components/schedule/filter-categories"
1416

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

@@ -45,8 +47,8 @@ export default function SpeakerPage({ params }: SpeakerProps) {
4547
.filter(s => s.speakers && s.speakers.some(s => s.username === params.id))
4648
.map(s => ({
4749
...s,
48-
speakers: s.speakers!.map(s =>
49-
speakers.find(speaker => speaker.username === s.username),
50+
speakers: s.speakers!.map(
51+
s => speakers.find(speaker => speaker.username === s.username)!,
5052
),
5153
}))
5254

@@ -104,8 +106,13 @@ export default function SpeakerPage({ params }: SpeakerProps) {
104106
/>
105107
</div>
106108
<h1 className="conf-heading mb-10">Sessions</h1>
107-
{/* @ts-expect-error */}
108-
<SessionList showFilter={false} scheduleData={s} />
109+
<SessionList
110+
filterCategories={filterCategories2023}
111+
eventsColors={eventsColors}
112+
year="2023"
113+
showFilter={false}
114+
scheduleData={s}
115+
/>
109116
</div>
110117
</div>
111118
</section>

src/app/conf/2023/speakers/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default function Page() {
2222
<div className="bg-white">
2323
<section className="container flex gap-8 flex-wrap lg:justify-between justify-center conf-block">
2424
{speakers.map(speaker => (
25-
<Speaker key={speaker.username} {...speaker} />
25+
<Speaker key={speaker.username} {...speaker} year="2023" />
2626
))}
2727
</section>
2828
</div>

src/app/conf/2023/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ export type SchedSpeaker = {
2323
role: string
2424
location?: string
2525
socialurls: { service: string; url: string }[]
26+
year: "2024" | "2023"
2627
}

src/app/conf/2024/_data.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import "server-only"
2+
import { stripHtml } from "string-strip-html"
3+
import { SchedSpeaker, ScheduleSession } from "@/app/conf/2023/types"
4+
import pLimit from "p-limit"
5+
6+
async function fetchData<T>(url: string): Promise<T> {
7+
try {
8+
const response = await fetch(url, {
9+
method: "POST",
10+
headers: {
11+
"Content-Type": "application/json",
12+
"User-Agent": "GraphQL Conf / GraphQL Foundation",
13+
},
14+
})
15+
const data = await response.json()
16+
return data
17+
} catch (error) {
18+
throw new Error(
19+
`Error fetching data from ${url}: ${(error as Error).message || (error as Error).toString()}`,
20+
)
21+
}
22+
}
23+
24+
const token = process.env.SCHED_ACCESS_TOKEN_2024
25+
26+
async function getUsernames(): Promise<string[]> {
27+
const response = await fetchData<{ username: string }[]>(
28+
`https://graphqlconf2024.sched.com/api/user/list?api_key=${token}&format=json&fields=username`,
29+
)
30+
return response.map(user => user.username)
31+
}
32+
33+
const limit = pLimit(40) // rate limit is 30req/min
34+
35+
async function getSpeakers(): Promise<SchedSpeaker[]> {
36+
const usernames = await getUsernames()
37+
38+
const users = await Promise.all(
39+
usernames.map(username =>
40+
limit(() => {
41+
return fetchData<SchedSpeaker>(
42+
`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`,
43+
)
44+
}),
45+
),
46+
)
47+
48+
const result = users
49+
.filter(speaker => speaker.role.includes("speaker"))
50+
.map(user => {
51+
return {
52+
...user,
53+
about: stripHtml(user.about).result,
54+
}
55+
})
56+
57+
return result
58+
}
59+
60+
async function getSchedule(): Promise<ScheduleSession[]> {
61+
const sessions = await fetchData<ScheduleSession[]>(
62+
`https://graphqlconf2024.sched.com/api/session/export?api_key=${token}&format=json`,
63+
)
64+
65+
const result = sessions.map(session => {
66+
const { description } = session
67+
if (description?.includes("<")) {
68+
// console.log(`Found HTML element in about field for session "${session.name}"`)
69+
}
70+
71+
return {
72+
...session,
73+
description: description && stripHtml(description).result,
74+
}
75+
})
76+
77+
return result
78+
}
79+
80+
// @ts-expect-error -- fixme
81+
export const speakers = await getSpeakers()
82+
83+
// @ts-expect-error -- fixme
84+
export const schedule = await getSchedule()

src/app/conf/2024/layout.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,17 @@ export default function Layout({
4242
</NextLink>
4343
}
4444
links={[
45-
{ children: <span>FAQ</span>, href: "/conf/2024/faq" },
46-
{ children: <span>Register</span>, href: "/conf/2024#attend" },
47-
{ children: <span>Partner</span>, href: "/conf/2024/partner" },
4845
{
4946
children: <span>Schedule</span>,
50-
href: "https://graphqlconf2024.sched.com/",
47+
href: "/conf/2024/schedule",
48+
},
49+
{
50+
children: <span>Speakers</span>,
51+
href: "/conf/2024/speakers",
5152
},
53+
{ children: <span>FAQ</span>, href: "/conf/2024/faq" },
54+
{ children: <span>Register</span>, href: "/conf/2024#attend" },
55+
{ children: <span>Partner</span>, href: "/conf/2024/partner" },
5256
]}
5357
/>
5458
{children}
@@ -64,6 +68,14 @@ export default function Layout({
6468
}
6569
links={[
6670
[
71+
{
72+
children: "Schedule",
73+
href: "/conf/2024/schedule",
74+
},
75+
{
76+
children: "Speakers",
77+
href: "/conf/2024/speakers",
78+
},
6779
{ children: "Register", href: "https://cvent.me/gk2dRw" },
6880
{ children: "Sponsor", href: "/conf/2024/partner" },
6981
{ children: "Partner", href: "/conf/2024/partner#program" },
@@ -72,10 +84,7 @@ export default function Layout({
7284
href: "/conf/2024/speakers",
7385
"aria-disabled": true,
7486
},
75-
{
76-
children: "Schedule",
77-
href: "https://graphqlconf2024.sched.com/",
78-
},
87+
7988
{ children: "GraphQLConf 2023", href: "/conf/2023" },
8089
],
8190
[

0 commit comments

Comments
 (0)