Skip to content

Commit 31e6161

Browse files
authored
update post event graphql conf 2023 (graphql#1581)
1 parent af22dc0 commit 31e6161

File tree

16 files changed

+557
-291
lines changed

16 files changed

+557
-291
lines changed

Diff for: gatsby-node.ts

+29-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { ScheduleSession } from "./src/components/Conf/Schedule/ScheduleList"
1+
import { ScheduleSession } from "./src/components/Conf/Schedule/session-list"
22
import { SchedSpeaker } from "./src/components/Conf/Speakers/Speaker"
33
import { GatsbyNode } from "gatsby"
44
import { createOpenGraphImage } from "gatsby-plugin-dynamic-open-graph-images"
55
import * as path from "path"
66
import { glob } from "glob"
7-
import _ from "lodash"
87
import { updateCodeData } from "./scripts/update-code-data/update-code-data"
98
import { organizeCodeData } from "./scripts/update-code-data/organize-code-data"
109
import { sortCodeData } from "./scripts/update-code-data/sort-code-data"
@@ -177,21 +176,29 @@ export const createPages: GatsbyNode["createPages"] = async ({
177176
)) as SchedSpeaker[]
178177
).filter(s => s.role.includes("speaker"))
179178

180-
// Create schedule page
181179
createPage({
182180
path: "/conf/schedule",
183181
component: path.resolve("./src/templates/schedule.tsx"),
184182
context: { schedule },
185183
})
186184

185+
// Create schedule page
186+
createPage({
187+
path: "/conf/sessions",
188+
component: path.resolve("./src/templates/session.tsx"),
189+
context: {
190+
schedule: withSpeakerInfo(schedule.filter(session => session.speakers)),
191+
},
192+
})
193+
187194
// Create schedule events' pages
188195
schedule.forEach(event => {
189196
const eventSpeakers = speakers.filter(e =>
190197
event.speakers?.find(({ username }) => username === e.username)
191198
)
192199

193200
createPage({
194-
path: `/conf/schedule/${event.id}`,
201+
path: `/conf/sessions/${event.id}`,
195202
component: path.resolve("./src/templates/event.tsx"),
196203
context: {
197204
event,
@@ -222,6 +229,15 @@ export const createPages: GatsbyNode["createPages"] = async ({
222229
}
223230
})
224231

232+
function withSpeakerInfo(session: ScheduleSession[]) {
233+
return session.map(session => ({
234+
...session,
235+
speakers: session.speakers
236+
.map(speaker => speakers.find(s => s.username === speaker.username))
237+
.filter(Boolean),
238+
}))
239+
}
240+
225241
// Create speakers list page
226242
createPage({
227243
path: "/conf/speakers",
@@ -239,7 +255,10 @@ export const createPages: GatsbyNode["createPages"] = async ({
239255
createPage({
240256
path: `/conf/speakers/${speaker.username}`,
241257
component: path.resolve("./src/templates/speaker.tsx"),
242-
context: { speaker, schedule: speakerSessions },
258+
context: {
259+
speaker,
260+
schedule: withSpeakerInfo(speakerSessions),
261+
},
243262
})
244263

245264
if (!process.env.GATSBY_CLOUD && !process.env.GITHUB_ACTIONS) {
@@ -274,6 +293,11 @@ export const createPages: GatsbyNode["createPages"] = async ({
274293
toPath: "/conf/schedule",
275294
})
276295

296+
createRedirect({
297+
fromPath: "/conf/schedule/*",
298+
toPath: "/conf/sessions/*",
299+
})
300+
277301
// redirect swapi with 200
278302
createRedirect({
279303
fromPath: `/swapi-graphql/*`,

Diff for: package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"scripts": {
66
"build": "gatsby build",
77
"develop": "gatsby develop",
8-
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
9-
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,md}\"",
8+
"format": "yarn format:check --write",
9+
"format:check": "prettier --cache --check \"**/*.{js,jsx,ts,tsx,json,md}\"",
1010
"start": "yarn develop",
1111
"serve": "gatsby serve",
1212
"clean": "gatsby clean",

Diff for: src/components/Conf/Header/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface LinkItem {
1010

1111
const links: LinkItem[] = [
1212
{ text: "Speakers", href: "/conf/speakers/" },
13+
{ text: "Sessions", href: "/conf/sessions/" },
1314
{ text: "Schedule", href: "/conf/schedule/" },
1415
{ text: "FAQ", href: "/conf/faq/" },
1516
]

Diff for: src/components/Conf/Schedule/BackLink.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React from "react"
22

3-
export const BackLink = ({ kind }: { kind: "speakers" | "schedule" }) => {
3+
export const BackLink = ({ kind }: { kind: "speakers" | "sessions" }) => {
44
return (
55
<a
66
href={`/conf/${kind}`}
77
className="w-max rounded-md underline-offset-2 cursor-pointer transition-all text-sm no-underline text-[#333333]"
88
>
99
<span>
10-
{"<"}&nbsp;&nbsp;Back to {kind === "speakers" ? "Speakers" : "Schedule"}
10+
&lt; &nbsp;Back to {kind === "speakers" ? "Speakers" : "Sessions"}
1111
</span>
1212
</a>
1313
)

Diff for: src/components/Conf/Schedule/Filters.tsx

+85-100
Original file line numberDiff line numberDiff line change
@@ -17,108 +17,93 @@ export default function Filters({
1717
onReset,
1818
}: FiltersProps) {
1919
return (
20-
<div className="">
21-
<div aria-labelledby="filter-heading">
22-
<div className="border-b border-gray-200 pb-4">
23-
<div className="flex items-center justify-between">
24-
{Object.values(filterState).flat().length > 0 && (
25-
<button
26-
onClick={onReset}
27-
className="cursor-pointer flex items-center gap-x-2 px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded-md text-sm font-medium text-gray-700 hover:text-gray-900"
28-
>
29-
Reset filters <XMarkIcon className="h-4 w-4 inline-block" />
30-
</button>
31-
)}
32-
<Menu as="div" className="relative inline-block text-left">
33-
<Transition
34-
enter="transition ease-out duration-100"
35-
enterFrom="transform opacity-0 scale-95"
36-
enterTo="transform opacity-100 scale-100"
37-
leave="transition ease-in duration-75"
38-
leaveFrom="transform opacity-100 scale-100"
39-
leaveTo="transform opacity-0 scale-95"
40-
>
41-
<Menu.Items className="absolute left-0 z-10 mt-2 w-40 origin-top-left rounded-md shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none">
42-
<div className="py-1">
43-
{categories.map(option => (
44-
<Menu.Item key={option.name}>
45-
<span
46-
className={clsx(
47-
filterState[option.name].length > 0
48-
? "font-medium text-gray-900"
49-
: "text-gray-500"
50-
)}
51-
>
52-
{option.name}
53-
</span>
54-
</Menu.Item>
55-
))}
56-
</div>
57-
</Menu.Items>
58-
</Transition>
59-
</Menu>
20+
<div className="flex justify-center pt-20 pb-10 gap-3">
21+
{Object.values(filterState).flat().length > 0 && (
22+
<button
23+
onClick={onReset}
24+
className="cursor-pointer flex items-center gap-x-2 px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded-md text-sm font-medium text-gray-700 hover:text-gray-900"
25+
>
26+
Reset filters <XMarkIcon className="h-4 w-4 inline-block" />
27+
</button>
28+
)}
29+
<Menu as="div" className="relative inline-block text-left">
30+
<Transition
31+
enter="transition ease-out duration-100"
32+
enterFrom="transform opacity-0 scale-95"
33+
enterTo="transform opacity-100 scale-100"
34+
leave="transition ease-in duration-75"
35+
leaveFrom="transform opacity-100 scale-100"
36+
leaveTo="transform opacity-0 scale-95"
37+
>
38+
<Menu.Items className="absolute left-0 z-10 mt-2 w-40 origin-top-left rounded-md shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none">
39+
<div className="py-1">
40+
{categories.map(option => (
41+
<Menu.Item key={option.name}>
42+
<span
43+
className={clsx(
44+
filterState[option.name].length > 0
45+
? "font-medium text-gray-900"
46+
: "text-gray-500"
47+
)}
48+
>
49+
{option.name}
50+
</span>
51+
</Menu.Item>
52+
))}
53+
</div>
54+
</Menu.Items>
55+
</Transition>
56+
</Menu>
57+
<Popover.Group className="flex items-baseline space-x-8">
58+
{categories.map((section, sectionIdx) => (
59+
<Popover
60+
as="div"
61+
key={section.name}
62+
id={`desktop-menu-${sectionIdx}`}
63+
className="relative inline-block text-left"
64+
>
65+
<Popover.Button className="cursor-pointer bg-inherit p-1 px-2 group inline-flex items-center justify-center text-sm font-medium text-gray-700 hover:text-gray-900">
66+
<span>{section.name}</span>
67+
{filterState[section.name].length ? (
68+
<span className="ml-1.5 rounded bg-gray-200 px-1.5 py-0.5 text-xs font-semibold tabular-nums text-gray-700">
69+
{filterState[section.name].length}
70+
</span>
71+
) : null}
72+
<ChevronDownIcon
73+
className="-mr-1 ml-1 h-5 w-5 shrink-0 text-gray-400 group-hover:text-gray-500"
74+
aria-hidden="true"
75+
/>
76+
</Popover.Button>
6077

61-
<div className="">
62-
<div className="flow-root">
63-
<Popover.Group className="flex items-baseline space-x-8">
64-
{categories.map((section, sectionIdx) => (
65-
<Popover
66-
as="div"
67-
key={section.name}
68-
id={`desktop-menu-${sectionIdx}`}
69-
className="relative inline-block text-left"
78+
<Popover.Panel className="absolute right-0 z-10 mt-2 origin-top-right rounded-md bg-white p-4 shadow-lg border border-black focus:outline-none">
79+
<form className="space-y-4 border border-black">
80+
{section.options.map((option, optionIdx) => (
81+
<div key={option} className="flex items-center gap-3">
82+
<input
83+
id={`filter-${section.name}-${optionIdx}`}
84+
name={`${section.name}[]`}
85+
defaultValue={option}
86+
onChange={e => {
87+
const { checked, value } = e.target
88+
onFilterChange(section.name, value, checked)
89+
}}
90+
checked={filterState[section.name].includes(option)}
91+
type="checkbox"
92+
className="cursor-pointer h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
93+
/>
94+
<label
95+
htmlFor={`filter-${section.name}-${optionIdx}`}
96+
className="cursor-pointer whitespace-nowrap pr-6 text-sm font-medium text-gray-900"
7097
>
71-
<div>
72-
<Popover.Button className="bg-inherit p-1 px-2 group inline-flex items-center justify-center text-sm font-medium text-gray-700 hover:text-gray-900">
73-
<span>{section.name}</span>
74-
{filterState[section.name].length ? (
75-
<span className="ml-1.5 rounded bg-gray-200 px-1.5 py-0.5 text-xs font-semibold tabular-nums text-gray-700">
76-
{filterState[section.name].length}
77-
</span>
78-
) : null}
79-
<ChevronDownIcon
80-
className="-mr-1 ml-1 h-5 w-5 shrink-0 text-gray-400 group-hover:text-gray-500"
81-
aria-hidden="true"
82-
/>
83-
</Popover.Button>
84-
</div>
85-
86-
<Popover.Panel className="absolute right-0 z-10 mt-2 origin-top-right rounded-md bg-white p-4 shadow-lg border border-black focus:outline-none">
87-
<form className="space-y-4 border border-black">
88-
{section.options.map((option, optionIdx) => (
89-
<div key={option} className="flex items-center">
90-
<input
91-
id={`filter-${section.name}-${optionIdx}`}
92-
name={`${section.name}[]`}
93-
defaultValue={option}
94-
onChange={e => {
95-
const { checked, value } = e.target
96-
onFilterChange(section.name, value, checked)
97-
}}
98-
checked={filterState[section.name].includes(
99-
option
100-
)}
101-
type="checkbox"
102-
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
103-
/>
104-
<label
105-
htmlFor={`filter-${section.name}-${optionIdx}`}
106-
className="ml-3 whitespace-nowrap pr-6 text-sm font-medium text-gray-900"
107-
>
108-
{option}
109-
</label>
110-
</div>
111-
))}
112-
</form>
113-
</Popover.Panel>
114-
</Popover>
115-
))}
116-
</Popover.Group>
117-
</div>
118-
</div>
119-
</div>
120-
</div>
121-
</div>
98+
{option}
99+
</label>
100+
</div>
101+
))}
102+
</form>
103+
</Popover.Panel>
104+
</Popover>
105+
))}
106+
</Popover.Group>
122107
</div>
123108
)
124109
}

0 commit comments

Comments
 (0)