diff --git a/src/app/conf/2023/page.tsx b/src/app/conf/2023/page.tsx index 5f58405460..c4e160cc40 100644 --- a/src/app/conf/2023/page.tsx +++ b/src/app/conf/2023/page.tsx @@ -24,7 +24,7 @@ export default function ConfPage() { function Hero() { return ( -
+
diff --git a/src/app/conf/2025/_data.ts b/src/app/conf/2025/_data.ts new file mode 100644 index 0000000000..36ad0528db --- /dev/null +++ b/src/app/conf/2025/_data.ts @@ -0,0 +1,85 @@ +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(url: string): Promise { + 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 { + 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 { + const usernames = await getUsernames() + + const users = await Promise.all( + usernames.map(username => + limit(() => { + return fetchData( + `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 { + const sessions = await fetchData( + `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}"`) + } + + // TODO: Preserve formatting?? + + return { + ...session, + description: description && stripHtml(description).result, + } + }) + + return result +} + +export const speakers = await getSpeakers() + +// TODO: Collect tags from schedule for speakers. +export const schedule = await getSchedule() diff --git a/src/app/conf/2025/_videos.ts b/src/app/conf/2025/_videos.ts new file mode 100644 index 0000000000..e8b9f74c8b --- /dev/null +++ b/src/app/conf/2025/_videos.ts @@ -0,0 +1,10 @@ +export const videos: { + id: string + title: string +}[] = [ + // temporary + { + id: "fA81OFu9BVY", + title: `Top 10 GraphQL Security Checks for Every Developer - Ankita Gupta, Ankush Jain - Akto.io`, + }, +] diff --git a/src/app/conf/2025/assets/graphql-foundation-wordmark.svg b/src/app/conf/2025/assets/graphql-foundation-wordmark.svg index 556ab3f50b..8ecff1b893 100644 --- a/src/app/conf/2025/assets/graphql-foundation-wordmark.svg +++ b/src/app/conf/2025/assets/graphql-foundation-wordmark.svg @@ -1,33 +1,113 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/conf/2025/components/become-a-sponsor/blur-blob.webp b/src/app/conf/2025/components/become-a-sponsor/blur-blob.webp new file mode 100644 index 0000000000..af6299d6bd Binary files /dev/null and b/src/app/conf/2025/components/become-a-sponsor/blur-blob.webp differ diff --git a/src/app/conf/2025/components/become-a-sponsor/index.tsx b/src/app/conf/2025/components/become-a-sponsor/index.tsx new file mode 100644 index 0000000000..09ed33dc7d --- /dev/null +++ b/src/app/conf/2025/components/become-a-sponsor/index.tsx @@ -0,0 +1,125 @@ +import clsx from "clsx" + +import { Button } from "../../../_design-system/button" + +import blurBlob from "./blur-blob.webp" +import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" + +export function BecomeASponsor() { + return ( +
+ +
+
+
+

Become a Sponsor

+

+ Connect with the global GraphQL community and showcase your brand + to industry leaders and decision-makers. +

+
+ +
+
+ + + + + + +
+
+ + ) +} + +function DefinitionListItem({ + className, + term, + definition, +}: { + className?: string + term: string + definition: string +}) { + return ( +
+
+ {term} +
+
{definition}
+
+ ) +} + +function Stripes() { + return ( +
+ +
+ ) +} diff --git a/src/app/conf/2025/components/call-for-proposals.tsx b/src/app/conf/2025/components/call-for-proposals.tsx index 3073122cd0..e2e9bd6924 100644 --- a/src/app/conf/2025/components/call-for-proposals.tsx +++ b/src/app/conf/2025/components/call-for-proposals.tsx @@ -44,7 +44,7 @@ function DefinitionListItem({ definition: string }) { return ( -
+
{term}
@@ -139,7 +139,7 @@ function NotesTab() { event. -

Preparing to Submit Your Proposal

+

Preparing to Submit Your Proposal

While it is not our intention to provide you with strict instructions on how to prepare your proposal, we hope you will take a moment to review @@ -160,7 +160,7 @@ function NotesTab() { letting you share your experiences, educate the community about an issue, or generate interest in a project.

-

How to Give a Great Talk

+

How to Give a Great Talk

We want to make sure submitters receive resources to help put together a great submission and if accepted, give the best presentation possible. @@ -175,7 +175,7 @@ function NotesTab() { .

-

+

Have More Questions? First Time Submitting? Don't Feel Intimidated

@@ -237,7 +237,7 @@ function ProcessTab() {

  • The new Subject Matter Experts initiative (SMEs)
  • The Program Committee
  • -

    The Technical Steering Committee

    +

    The Technical Steering Committee

    The TSC are a group of 11 individuals who are elected to serve a two year term to provide technical oversight of all GraphQL development @@ -251,7 +251,7 @@ function ProcessTab() {

  • Quality of Presentation
  • Importance
  • -

    Subject Matter Experts

    +

    Subject Matter Experts

    The SME initiative is new for 2025. This will be a panel of volunteers drawn from industry experts, working group members, security and @@ -265,7 +265,7 @@ function ProcessTab() {

  • Originality
  • Audience Engagement
  • -

    The Program Committee

    +

    The Program Committee

    The Program Committee is made up of representatives from the GraphQL Foundation board and interested members of the GraphQL community who @@ -275,7 +275,7 @@ function ProcessTab() { demographics, to ensure a varied and well-rounded representation of the GraphQL ecosystem.

    -

    +

    Have More Questions? First Time Submitting? Don't Feel Intimidated

    @@ -348,7 +348,7 @@ export function CallForProposals() { .

    -

    +

    Please be aware that the Linux Foundation uses Sessionize for CFP submissions. Sessionize is a cloud-based event content management software designed to be intuitive and user-friendly. If you need @@ -382,6 +382,7 @@ export function CallForProposals() { > {tabsInOrder.map((tab, i) => ( { diff --git a/src/app/conf/2025/components/cta-card-section/index.tsx b/src/app/conf/2025/components/cta-card-section/index.tsx new file mode 100644 index 0000000000..30f8c542d3 --- /dev/null +++ b/src/app/conf/2025/components/cta-card-section/index.tsx @@ -0,0 +1,66 @@ +import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration" + +import logoMask from "./logo-mask.webp" + +export interface CtaCardSectionProps + extends Omit, "title"> { + title: React.ReactNode + description: string + children: React.ReactNode +} + +export function CtaCardSection({ + className, + title: heading, + description, + children, + ...rest +}: CtaCardSectionProps) { + return ( +

    +
    +
    +
    +

    + {heading} +

    +

    + {description} +

    +
    + + {children} +
    + +
    + +
    +
    +
    + ) +} diff --git a/src/app/conf/2025/components/cta-card-section/logo-mask.webp b/src/app/conf/2025/components/cta-card-section/logo-mask.webp new file mode 100644 index 0000000000..8c83251f30 Binary files /dev/null and b/src/app/conf/2025/components/cta-card-section/logo-mask.webp differ diff --git a/src/app/conf/2025/components/footer/index.tsx b/src/app/conf/2025/components/footer/index.tsx index 14cee22cb9..dea6d2adb9 100644 --- a/src/app/conf/2025/components/footer/index.tsx +++ b/src/app/conf/2025/components/footer/index.tsx @@ -23,13 +23,15 @@ export function Footer({ return (