Some checks are pending
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Waiting to run
Use mainwhite.svg on white sections with curvy green transitions into flat green bands, improve text and button contrast, and deploy via OpenNext on Cloudflare Workers. Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
2.7 KiB
TypeScript
75 lines
2.7 KiB
TypeScript
import Link from "next/link";
|
|
import {
|
|
speakers,
|
|
speakerGroupLabels,
|
|
speakerGroupOrder,
|
|
type SpeakerGroup,
|
|
} from "@/content/people";
|
|
import { site } from "@/content/site";
|
|
import { Section } from "@/components/layout/Section";
|
|
import { TopoProseSurface } from "@/components/layout/TopoProseSurface";
|
|
import { SpeakerCard } from "@/components/speakers/SpeakerCard";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
export function Speakers() {
|
|
const grouped = speakerGroupOrder.reduce(
|
|
(acc, group) => {
|
|
const list = speakers.filter((s) => s.group === group);
|
|
if (list.length) acc[group] = list;
|
|
return acc;
|
|
},
|
|
{} as Partial<Record<SpeakerGroup, typeof speakers>>
|
|
);
|
|
|
|
return (
|
|
<Section id="speakers">
|
|
<TopoProseSurface className="max-w-3xl">
|
|
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
|
Lineup
|
|
</p>
|
|
<h2 className="mt-2 text-4xl font-bold tracking-tight md:text-5xl">
|
|
Meet the voices of GRV Summit
|
|
</h2>
|
|
<p className="mt-4 text-muted-foreground leading-relaxed">
|
|
Keynotes, panelists, judges, and opening speakers — {site.dates.label} at{" "}
|
|
{site.venue.name}.
|
|
</p>
|
|
</TopoProseSurface>
|
|
|
|
<div className="relative z-20 mt-16 space-y-16">
|
|
{(Object.entries(grouped) as [SpeakerGroup, typeof speakers][]).map(
|
|
([group, list]) => (
|
|
<div key={group}>
|
|
<div className="mb-2 flex flex-wrap items-end justify-between gap-4 border-b border-border pb-4">
|
|
<div>
|
|
<h3 className="text-2xl font-bold md:text-3xl">
|
|
{speakerGroupLabels[group]}
|
|
</h3>
|
|
<p className="mt-1 text-sm text-muted-foreground">{site.dates.label}</p>
|
|
</div>
|
|
</div>
|
|
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
|
{list.map((speaker, i) => (
|
|
<SpeakerCard key={speaker.id} speaker={speaker} revealDelay={i * 60} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
)}
|
|
</div>
|
|
|
|
<div className="mt-12 flex flex-wrap justify-center gap-3">
|
|
<Button className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90" asChild>
|
|
<Link href="/program">View full program</Link>
|
|
</Button>
|
|
<Button variant="outline" className="rounded-full" asChild>
|
|
<Link href="/speakers">Full lineup page</Link>
|
|
</Button>
|
|
<Button variant="outline" className="rounded-full" asChild>
|
|
<Link href="/payment">Get tickets</Link>
|
|
</Button>
|
|
</div>
|
|
</Section>
|
|
);
|
|
}
|