Skip to content

Commit 9d05b41

Browse files
committed
fixes
1 parent 5f9e190 commit 9d05b41

File tree

6 files changed

+198
-11
lines changed

6 files changed

+198
-11
lines changed

next.config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import nextra from "nextra"
44
import path from "node:path"
55
import withLess from "next-with-less"
66
import { remarkGraphiQLComment } from "./src/remark-graphiql-comment.js"
7-
import vercelJSON from "./vercel.json" assert { type: "json" }
7+
import fs from "fs"
8+
9+
const vercelJSON = JSON.parse(fs.readFileSync("./vercel.json", 'utf-8'));
810

911
const withNextra = nextra({
1012
theme: "nextra-theme-docs",

src/app/conf/2024/gallery/page.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React from 'react'
2+
import { Metadata } from "next"
3+
import { images } from "../../2023/gallery/_conf-images"
4+
import NextImage from "next-image-export-optimizer"
5+
import { Zoom } from "../../_components/zoom"
6+
7+
export const metadata: Metadata = {
8+
title: "Gallery",
9+
}
10+
11+
function chunk<T>(arr: T[], len: number): T[][] {
12+
const chunks: T[][] = [];
13+
let i = 0;
14+
15+
while (i < arr.length) {
16+
chunks.push(arr.slice(i, i + len));
17+
i += len;
18+
}
19+
20+
return chunks;
21+
}
22+
23+
24+
export default function GalleryPage() {
25+
const currentImages = chunk(images, 6)
26+
27+
return (
28+
<div className="bg-[#f4f6f8]">
29+
<div className="container conf-block">
30+
{currentImages.map((c, i) => {
31+
function getCard(index: number) {
32+
return (
33+
c[index] && (
34+
<Zoom>
35+
<NextImage
36+
alt="Gallery"
37+
className="object-cover aspect-video w-full hover:opacity-75 rounded-md"
38+
src={c[index]}
39+
/>
40+
</Zoom>
41+
)
42+
)
43+
}
44+
45+
return (
46+
<div key={i} className="grid lg:grid-cols-2 gap-2 mb-2">
47+
<div className="gap-2 flex flex-col">
48+
<div className="grid grid-cols-2 gap-2">
49+
{getCard(0)}
50+
{getCard(1)}
51+
</div>
52+
{getCard(2)}
53+
</div>
54+
<div className="gap-2 flex flex-col">
55+
{getCard(3)}
56+
<div className="grid grid-cols-2 gap-2">
57+
{getCard(4)}
58+
{getCard(5)}
59+
</div>
60+
</div>
61+
</div>
62+
)
63+
})}
64+
</div>
65+
</div>
66+
)
67+
}

src/app/conf/2024/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export default function Layout({
4646
{ children: "FAQ", href: "/conf/2024/faq" },
4747
{ children: "Register", href: "/conf/2024#attend" },
4848
{ children: "Partner", href: "/conf/2024/partner" },
49+
{ children: "Gallery", href: "/conf/2024/gallery" },
4950
]}
5051
/>
5152
{children}
@@ -66,6 +67,7 @@ export default function Layout({
6667
{ children: "Register", href: "https://cvent.me/gk2dRw" },
6768
{ children: "Sponsor", href: "/conf/2024/partner" },
6869
{ children: "Partner", href: "/conf/2024/partner#program" },
70+
{ children: "Gallery", href: "/conf/2024/gallery" },
6971
{ children: "Speakers", href: "/conf/2024/speakers" },
7072
{ children: "GraphQLConf 2023", href: "/conf/2023" },
7173
],

src/app/conf/2024/pricing.tsx

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { Button } from "@/app/conf/_components/button"
2-
import { CheckIcon, ClockIcon } from "@/icons"
2+
import { CheckIcon } from "@/icons"
33
import { clsx } from "clsx"
4+
import { schedule, speakers } from './_data'
5+
import { InfiniteMovingSpeakers } from '../_components/infinite-moving-speakers'
6+
import { SessionList } from '../_components/schedule/session-list'
7+
import { filterCategories2024 } from '../_components/schedule/filter-categories'
8+
import { eventsColors } from './utils'
49

510
interface Pricing {
611
title: string
@@ -9,6 +14,27 @@ interface Pricing {
914
expiredDate: Date
1015
}
1116

17+
function shuffle<T extends any[]>(array: T): T {
18+
let currentIndex = array.length
19+
let randomIndex: number
20+
21+
// While there remain elements to shuffle.
22+
while (currentIndex > 0) {
23+
// Pick a remaining element.
24+
randomIndex = Math.floor(Math.random() * currentIndex)
25+
currentIndex--
26+
27+
// And swap it with the current element.
28+
;[array[currentIndex], array[randomIndex]] = [
29+
array[randomIndex],
30+
array[currentIndex],
31+
]
32+
}
33+
34+
return array
35+
}
36+
37+
1238
const pricing: Pricing[] = [
1339
{
1440
title: "Early Bird",
@@ -91,11 +117,56 @@ export function Pricing() {
91117
</div>
92118

93119
<div className={clsx(classes.container, "flex flex-col items-center")}>
94-
<ClockIcon className="text-primary h-10 mb-10" />
95-
<h3 className={classes.heading}>Speakers & Schedule</h3>
96-
<div className="flex gap-4">
97-
<Button href="/conf/2024/speakers">View the Speakers</Button>
98-
<Button href="/conf/2024/schedule">View the Schedule</Button>
120+
<h3 className="text-[45px] text-center font-bold mb-20">Our Special Speakers</h3>
121+
122+
<InfiniteMovingSpeakers pauseOnHover={true}>
123+
{speakers.filter((e) => e.avatar).map((speaker) => (
124+
<div
125+
key={speaker.username}
126+
className="group border-[1.5px] border-[rgba(255,255,255,0.4)] cursor-pointer hover:-translate-y-3 transition-transform duration-300 relative rounded-full overflow-hidden md:size-[210px]"
127+
>
128+
<a href={`/conf/2024/speakers/${speaker.username}`}>
129+
<img className="size-[120px] md:size-[210px] rounded-full" src={speaker.avatar} alt={speaker.name} />
130+
</a>
131+
<div className="pointer-events-none bg-[rgba(0,0,0,0.6)] h-[40px] text-sm md:text-base md:h-[55px] w-[120px] md:w-[210px] absolute left-0 bottom-0 opacity-1 md:opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex justify-center">
132+
<span className="mt-2.5 md:mt-3.5 font-medium">{speaker.name.split(" ")[0]}</span>
133+
</div>
134+
</div>
135+
))}
136+
</InfiniteMovingSpeakers>
137+
138+
139+
<div className="mt-14 flex gap-4">
140+
<Button href="/conf/2024/speakers">See all Speakers</Button>
141+
</div>
142+
143+
144+
145+
<div className='mt-16'>
146+
147+
<h3 className="text-[45px] text-center font-bold mb-16">The Schedule</h3>
148+
149+
<SessionList
150+
year="2024"
151+
filterCategories={filterCategories2024}
152+
eventsColors={eventsColors}
153+
showFilter={false}
154+
// @ts-expect-error -- fixme
155+
scheduleData={shuffle(schedule.filter((e)=>e.speakers))
156+
.slice(0, 3)
157+
.map(schedule => ({
158+
...schedule,
159+
speakers: schedule?.speakers?.map(speaker =>
160+
speakers.find(s => s.username === speaker.username),
161+
) || [],
162+
}))}
163+
/>
164+
165+
166+
</div>
167+
168+
<div className="mt-14 flex gap-4">
169+
<Button href="/conf/2024/speakers">View full schedule</Button>
99170
</div>
100171
</div>
101172
</>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React, { ReactElement, CSSProperties, Children, ReactNode } from "react"
2+
import { clsx } from "clsx"
3+
4+
5+
export function InfiniteMovingSpeakers({
6+
children,
7+
pauseOnHover = true,
8+
className,
9+
}: {
10+
children: ReactNode
11+
pauseOnHover?: boolean
12+
className?: string
13+
}): ReactElement {
14+
const content = Children.map(children, (child, index) => (
15+
<li key={index} className="shrink-0">
16+
{child}
17+
</li>
18+
))
19+
20+
return (
21+
<div
22+
className={clsx(
23+
"relative w-full overflow-x-hidden overflow-y-visible [mask-image:linear-gradient(to_right,transparent,white_20%,white_80%,transparent)]",
24+
className,
25+
)}
26+
style={
27+
{
28+
"--animation-duration": '300s',
29+
"--animation-direction": 'forwards'
30+
} as CSSProperties
31+
}
32+
>
33+
<ul
34+
className={clsx(
35+
"flex min-w-full shrink-0 gap-4 py-4 w-max flex-nowrap",
36+
"animate-scroll",
37+
pauseOnHover && "hover:[animation-play-state:paused]",
38+
)}
39+
>
40+
{content}
41+
{content}
42+
</ul>
43+
</div>
44+
)
45+
}

src/app/conf/_components/schedule/session-list.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,16 @@ export function SessionList({
164164
return (
165165
<NextLink
166166
key={session.id}
167-
className={clsx(
168-
"shadow-2xl rounded-md overflow-hidden flex flex-col text-current hover:no-underline focus:no-underline",
169-
)}
167+
className={`${clsx(
168+
"white shadow-2xl rounded-md overflow-hidden flex flex-col text-current hover:no-underline focus:no-underline",
169+
)} ${year === "2024" ? "bg-[#251f30]": ""}`}
170170
href={
171171
year === "2024"
172172
? `/conf/${year}/schedule/${session.id}`
173173
: `/conf/${year}/sessions/${session.id}`
174174
}
175175
>
176-
<div className="bg-[#251F30] text-white flex justify-between py-5 px-7 relative">
176+
<div className={`${year === '2024' ?'hidden' : ''} bg-[#251F30] text-white flex justify-between py-5 px-7 relative`}>
177177
<div className="text-sm flex flex-col gap-2 [*:hover>*>&]:opacity-0 transition-opacity duration-300 opacity-100">
178178
{year !== "2024" && (
179179
<div className="flex gap-3">

0 commit comments

Comments
 (0)