Skip to content

update post event graphql conf 2023 #1581

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 10 commits into from
Oct 5, 2023
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
34 changes: 29 additions & 5 deletions gatsby-node.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ScheduleSession } from "./src/components/Conf/Schedule/ScheduleList"
import { ScheduleSession } from "./src/components/Conf/Schedule/session-list"
import { SchedSpeaker } from "./src/components/Conf/Speakers/Speaker"
import { GatsbyNode } from "gatsby"
import { createOpenGraphImage } from "gatsby-plugin-dynamic-open-graph-images"
import * as path from "path"
import { glob } from "glob"
import _ from "lodash"
import { updateCodeData } from "./scripts/update-code-data/update-code-data"
import { organizeCodeData } from "./scripts/update-code-data/organize-code-data"
import { sortCodeData } from "./scripts/update-code-data/sort-code-data"
Expand Down Expand Up @@ -177,21 +176,29 @@ export const createPages: GatsbyNode["createPages"] = async ({
)) as SchedSpeaker[]
).filter(s => s.role.includes("speaker"))

// Create schedule page
createPage({
path: "/conf/schedule",
component: path.resolve("./src/templates/schedule.tsx"),
context: { schedule },
})

// Create schedule page
createPage({
path: "/conf/sessions",
component: path.resolve("./src/templates/session.tsx"),
context: {
schedule: withSpeakerInfo(schedule.filter(session => session.speakers)),
},
})

// Create schedule events' pages
schedule.forEach(event => {
const eventSpeakers = speakers.filter(e =>
event.speakers?.find(({ username }) => username === e.username)
)

createPage({
path: `/conf/schedule/${event.id}`,
path: `/conf/sessions/${event.id}`,
component: path.resolve("./src/templates/event.tsx"),
context: {
event,
Expand Down Expand Up @@ -222,6 +229,15 @@ export const createPages: GatsbyNode["createPages"] = async ({
}
})

function withSpeakerInfo(session: ScheduleSession[]) {
return session.map(session => ({
...session,
speakers: session.speakers
.map(speaker => speakers.find(s => s.username === speaker.username))
.filter(Boolean),
}))
}

// Create speakers list page
createPage({
path: "/conf/speakers",
Expand All @@ -239,7 +255,10 @@ export const createPages: GatsbyNode["createPages"] = async ({
createPage({
path: `/conf/speakers/${speaker.username}`,
component: path.resolve("./src/templates/speaker.tsx"),
context: { speaker, schedule: speakerSessions },
context: {
speaker,
schedule: withSpeakerInfo(speakerSessions),
},
})

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

createRedirect({
fromPath: "/conf/schedule/*",
toPath: "/conf/sessions/*",
})

// redirect swapi with 200
createRedirect({
fromPath: `/swapi-graphql/*`,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,md}\"",
"format": "yarn format:check --write",
"format:check": "prettier --cache --check \"**/*.{js,jsx,ts,tsx,json,md}\"",
"start": "yarn develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
Expand Down
1 change: 1 addition & 0 deletions src/components/Conf/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface LinkItem {

const links: LinkItem[] = [
{ text: "Speakers", href: "/conf/speakers/" },
{ text: "Sessions", href: "/conf/sessions/" },
{ text: "Schedule", href: "/conf/schedule/" },
{ text: "FAQ", href: "/conf/faq/" },
]
Expand Down
4 changes: 2 additions & 2 deletions src/components/Conf/Schedule/BackLink.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react"

export const BackLink = ({ kind }: { kind: "speakers" | "schedule" }) => {
export const BackLink = ({ kind }: { kind: "speakers" | "sessions" }) => {
return (
<a
href={`/conf/${kind}`}
className="w-max rounded-md underline-offset-2 cursor-pointer transition-all text-sm no-underline text-[#333333]"
>
<span>
{"<"}&nbsp;&nbsp;Back to {kind === "speakers" ? "Speakers" : "Schedule"}
&lt; &nbsp;Back to {kind === "speakers" ? "Speakers" : "Sessions"}
</span>
</a>
)
Expand Down
185 changes: 85 additions & 100 deletions src/components/Conf/Schedule/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,108 +17,93 @@ export default function Filters({
onReset,
}: FiltersProps) {
return (
<div className="">
<div aria-labelledby="filter-heading">
<div className="border-b border-gray-200 pb-4">
<div className="flex items-center justify-between">
{Object.values(filterState).flat().length > 0 && (
<button
onClick={onReset}
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"
>
Reset filters <XMarkIcon className="h-4 w-4 inline-block" />
</button>
)}
<Menu as="div" className="relative inline-block text-left">
<Transition
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<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">
<div className="py-1">
{categories.map(option => (
<Menu.Item key={option.name}>
<span
className={clsx(
filterState[option.name].length > 0
? "font-medium text-gray-900"
: "text-gray-500"
)}
>
{option.name}
</span>
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
<div className="flex justify-center pt-20 pb-10 gap-3">
{Object.values(filterState).flat().length > 0 && (
<button
onClick={onReset}
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"
>
Reset filters <XMarkIcon className="h-4 w-4 inline-block" />
</button>
)}
<Menu as="div" className="relative inline-block text-left">
<Transition
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<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">
<div className="py-1">
{categories.map(option => (
<Menu.Item key={option.name}>
<span
className={clsx(
filterState[option.name].length > 0
? "font-medium text-gray-900"
: "text-gray-500"
)}
>
{option.name}
</span>
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
<Popover.Group className="flex items-baseline space-x-8">
{categories.map((section, sectionIdx) => (
<Popover
as="div"
key={section.name}
id={`desktop-menu-${sectionIdx}`}
className="relative inline-block text-left"
>
<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">
<span>{section.name}</span>
{filterState[section.name].length ? (
<span className="ml-1.5 rounded bg-gray-200 px-1.5 py-0.5 text-xs font-semibold tabular-nums text-gray-700">
{filterState[section.name].length}
</span>
) : null}
<ChevronDownIcon
className="-mr-1 ml-1 h-5 w-5 shrink-0 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</Popover.Button>

<div className="">
<div className="flow-root">
<Popover.Group className="flex items-baseline space-x-8">
{categories.map((section, sectionIdx) => (
<Popover
as="div"
key={section.name}
id={`desktop-menu-${sectionIdx}`}
className="relative inline-block text-left"
<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">
<form className="space-y-4 border border-black">
{section.options.map((option, optionIdx) => (
<div key={option} className="flex items-center gap-3">
<input
id={`filter-${section.name}-${optionIdx}`}
name={`${section.name}[]`}
defaultValue={option}
onChange={e => {
const { checked, value } = e.target
onFilterChange(section.name, value, checked)
}}
checked={filterState[section.name].includes(option)}
type="checkbox"
className="cursor-pointer h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/>
<label
htmlFor={`filter-${section.name}-${optionIdx}`}
className="cursor-pointer whitespace-nowrap pr-6 text-sm font-medium text-gray-900"
>
<div>
<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">
<span>{section.name}</span>
{filterState[section.name].length ? (
<span className="ml-1.5 rounded bg-gray-200 px-1.5 py-0.5 text-xs font-semibold tabular-nums text-gray-700">
{filterState[section.name].length}
</span>
) : null}
<ChevronDownIcon
className="-mr-1 ml-1 h-5 w-5 shrink-0 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</Popover.Button>
</div>

<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">
<form className="space-y-4 border border-black">
{section.options.map((option, optionIdx) => (
<div key={option} className="flex items-center">
<input
id={`filter-${section.name}-${optionIdx}`}
name={`${section.name}[]`}
defaultValue={option}
onChange={e => {
const { checked, value } = e.target
onFilterChange(section.name, value, checked)
}}
checked={filterState[section.name].includes(
option
)}
type="checkbox"
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/>
<label
htmlFor={`filter-${section.name}-${optionIdx}`}
className="ml-3 whitespace-nowrap pr-6 text-sm font-medium text-gray-900"
>
{option}
</label>
</div>
))}
</form>
</Popover.Panel>
</Popover>
))}
</Popover.Group>
</div>
</div>
</div>
</div>
</div>
{option}
</label>
</div>
))}
</form>
</Popover.Panel>
</Popover>
))}
</Popover.Group>
</div>
)
}
Loading