Skip to content

Commit 1f65410

Browse files
authored
Merge pull request #15610 from ethereum/master
Back-merge `master` into `dev`
2 parents aacd855 + 3e53e9c commit 1f65410

22 files changed

+202
-63
lines changed

app/[locale]/10years/_components/AdoptionSwiper.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@ import {
1111

1212
import { cn } from "@/lib/utils/cn"
1313

14-
import { adoptionCards, adoptionStyles } from "./data"
14+
import { AdoptionCard } from "./types"
1515

16-
const AdoptionSwiper = () => {
16+
type AdoptionCardProps = {
17+
adoptionCards: AdoptionCard[]
18+
adoptionStyles: string[]
19+
}
20+
const AdoptionSwiper = ({
21+
adoptionCards,
22+
adoptionStyles,
23+
}: AdoptionCardProps) => {
1724
return (
1825
<div className="flex flex-1 flex-col gap-6 md:hidden">
1926
<SwiperContainer className="mx-auto w-full max-w-[550px]">
20-
<Swiper>
27+
<Swiper spaceBetween={32}>
2128
{adoptionCards.map((card, index) => (
2229
<SwiperSlide key={card.title}>
2330
<div

app/[locale]/10years/_components/InnovationSwiper.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ export default function InnovationSwiper() {
1414
return (
1515
<div className="w-[100%]">
1616
<SwiperContainer className="mx-auto w-full max-w-[550px] xl:max-w-[700px]">
17-
<Swiper className="mx-auto w-full max-w-[550px] xl:max-w-[700px]">
17+
<Swiper
18+
className="mx-auto w-full max-w-[550px] xl:max-w-[700px]"
19+
spaceBetween={32}
20+
>
1821
{innovationCards.map((card, index) => (
1922
<SwiperSlide
2023
key={index}
@@ -23,7 +26,7 @@ export default function InnovationSwiper() {
2326
<Image
2427
src={card.image}
2528
alt={card.title}
26-
className="mx-auto my-4 h-auto max-w-full"
29+
className="mx-auto my-4 h-auto max-h-48 object-contain"
2730
/>
2831
<div>
2932
<h3 className="mb-4">{card.title}</h3>

app/[locale]/10years/_components/TenYearGlobe.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client"
22

3-
import { useEffect, useMemo, useRef, useState } from "react"
3+
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
44
import { useTheme } from "next-themes"
55
import Globe from "react-globe.gl"
66
import { type GlobeMethods } from "react-globe.gl"
@@ -12,6 +12,7 @@ import Link from "@/components/ui/Link"
1212
import countries from "./countries.json"
1313

1414
import { useBreakpointValue } from "@/hooks/useBreakpointValue"
15+
import { usePrefersReducedMotion } from "@/hooks/usePrefersReducedMotion"
1516
import EthLogo from "@/public/images/assets/eth-glyph-colored.png"
1617

1718
// Define a type for event data
@@ -42,11 +43,12 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
4243
const globeRef = useRef<GlobeMethods>()
4344
const globeContainerRef = useRef<HTMLDivElement>(null)
4445
const { resolvedTheme } = useTheme()
46+
const { prefersReducedMotion } = usePrefersReducedMotion()
4547

4648
const atmosphereColor = resolvedTheme === "dark" ? "#B38DF0" : "#945AF4"
4749

4850
const width = useBreakpointValue({
49-
base: 260,
51+
base: window?.innerWidth - 64 || 260, // Full width on mobile with padding
5052
sm: 400,
5153
md: 500,
5254
lg: 600,
@@ -61,7 +63,7 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
6163
const b = Math.min(255, Math.floor((basePurple & 0xff) * 1.3))
6264
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`
6365
})
64-
}, [countries.features, resolvedTheme])
66+
}, [resolvedTheme])
6567

6668
const hexPolygonColor = (feature: object) => {
6769
const idx = countries.features.indexOf(
@@ -78,10 +80,18 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
7880
return hexPolygonColors[idx]
7981
}
8082

83+
// Function to safely set auto-rotate based on motion preferences
84+
const setAutoRotate = useCallback(
85+
(controls: ExtendedOrbitControls, value: boolean) => {
86+
controls.autoRotate = value && !prefersReducedMotion
87+
},
88+
[prefersReducedMotion]
89+
)
90+
8191
useEffect(() => {
8292
if (globeRef.current) {
8393
const controls = globeRef.current.controls() as ExtendedOrbitControls
84-
controls.autoRotate = true
94+
setAutoRotate(controls, true)
8595
controls.enablePan = false
8696
controls.enableZoom = false
8797
controls.autoRotateSpeed = 2.0
@@ -90,7 +100,7 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
90100
const ambientLight = new THREE.AmbientLight(0xffffff, 1)
91101
globeRef.current.scene().add(ambientLight)
92102
}
93-
}, [])
103+
}, [setAutoRotate])
94104

95105
// Prepare htmlElementsData for EthLogo
96106
const htmlElementsData = events.map((event) => ({
@@ -176,7 +186,7 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
176186
}
177187
// Stop rotation immediately
178188
const controls = globeRef.current.controls() as ExtendedOrbitControls
179-
controls.autoRotate = false
189+
setAutoRotate(controls, false)
180190
if ("autoRotateSpeed" in controls) controls.autoRotateSpeed = 0
181191
if (controls._sphericalDelta) {
182192
controls._sphericalDelta.theta = 0
@@ -193,15 +203,15 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
193203
if (globeRef.current) {
194204
const controls =
195205
globeRef.current.controls() as ExtendedOrbitControls
196-
controls.autoRotate = true
206+
setAutoRotate(controls, true)
197207
if ("autoRotateSpeed" in controls) controls.autoRotateSpeed = 2.0
198208
}
199209
}
200210
}}
201211
onPointClick={() => {
202212
if (globeRef.current) {
203213
const controls = globeRef.current.controls() as ExtendedOrbitControls
204-
controls.autoRotate = false
214+
setAutoRotate(controls, false)
205215
if ("autoRotateSpeed" in controls) controls.autoRotateSpeed = 0
206216
if (controls._sphericalDelta) {
207217
controls._sphericalDelta.theta = 0
@@ -227,8 +237,8 @@ const TenYearGlobe = ({ events }: { events: EventData[] }) => {
227237
return (
228238
<div
229239
ref={globeContainerRef}
230-
className="relative cursor-grab"
231-
style={{ width: width, height: width }}
240+
className="relative w-full max-w-full cursor-grab active:cursor-grabbing"
241+
style={{ height: width }}
232242
>
233243
{MemoizedGlobe}
234244
{hoveredEvent && tooltipPos && (

app/[locale]/10years/_components/TenYearHero.tsx

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,32 @@ import ParallaxImage from "@/components/Image/ParallaxImage"
88
import TenYearBackgroundImage from "@/public/images/10-year-anniversary/10-year-background.png"
99
import TenYearGraphicImage from "@/public/images/10-year-anniversary/10-year-graphic.png"
1010

11+
const [initialText, ...initialWords] = [
12+
"censorship resistance",
13+
"100% uptime",
14+
"decentralization",
15+
"community building",
16+
"developer growth",
17+
"global collaboration",
18+
"cypherpunk values",
19+
"hackathons",
20+
"censorship resistance",
21+
"permissionless finance",
22+
"credible neutrality",
23+
"the infinite garden",
24+
"client diversity",
25+
]
26+
1127
const TenYearHero = () => {
1228
const [words, setWords] = useState<{ text: string; words: string[] }>({
13-
text: "censorship resistance",
14-
words: [
15-
"censorship resistance",
16-
"100% uptime",
17-
"decentralization",
18-
"community building",
19-
"developer growth",
20-
"global collaboration",
21-
"cypherpunk values",
22-
"hackathons",
23-
"censorship resistance",
24-
"permissionless finance",
25-
"credible neutrality",
26-
"the infinite garden",
27-
"client diversity",
28-
],
29+
text: initialText,
30+
words: initialWords,
2931
})
3032

3133
// loops over chars to morph a text to another
3234
const morpher = (start: string, end: string): void => {
3335
// array of chars to randomly morph the text between start and end
34-
const chars = "abcdefghijklmnopqrstuvwxyz".split("")
36+
const chars = "abcdfgijklnopqsvwxyz".split("")
3537
// duration of the global morph
3638
const duration = 3
3739
// speed of the morph for each letter
@@ -136,7 +138,17 @@ const TenYearHero = () => {
136138
</div>
137139
<p className="text-center text-3xl">
138140
Celebrating 10 years of{" "}
139-
<span className="font-bold text-accent-b">{words.text}</span>
141+
<span className="relative max-md:block md:w-fit">
142+
<span
143+
className="select-none opacity-0 max-md:hidden"
144+
data-label="space-holder"
145+
>
146+
{initialText}
147+
</span>
148+
<span className="font-bold text-accent-b md:absolute md:start-0 md:text-nowrap">
149+
{words.text}
150+
</span>
151+
</span>
140152
</p>
141153
</div>
142154
)

app/[locale]/10years/_components/TenYearHomeBanner.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ const TenYearHomeBanner = () => {
1515
<ParallaxImage
1616
src={TenYearGraphicImage}
1717
alt=""
18-
className="mx-auto -mb-2 -mt-16 max-w-[500px] object-contain sm:-mt-24 md:-mt-32"
18+
className="mx-auto -mb-2 -mt-16 max-w-[min(100%,500px)] object-contain sm:-mt-24 md:-mt-32"
1919
/>
20-
<div className="flex justify-center">
20+
<div className="mt-4 flex justify-center">
2121
<TenYearDesktopText className="mb-4 hidden object-contain text-body md:block" />
22-
<TenYearMobileText className="mb-4 block object-contain text-body md:hidden" />
22+
<TenYearMobileText className="mb-4 block object-contain text-5xl text-body md:hidden" />
2323
</div>
2424
<div className="mb-4 flex flex-col gap-2">
2525
<p>

app/[locale]/10years/_components/data.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import Link from "@/components/ui/Link"
22

3+
import { AdoptionCard } from "./types"
4+
35
import Adoption1Image from "@/public/images/10-year-anniversary/adoption-1.png"
46
import Adoption2Image from "@/public/images/10-year-anniversary/adoption-2.png"
57
import Adoption3Image from "@/public/images/10-year-anniversary/adoption-3.png"
68
import DefiSummerImage from "@/public/images/10-year-anniversary/defi-summer.png"
79
import EthETFImage from "@/public/images/10-year-anniversary/eth-etf.png"
810
import EthereumLaunchImage from "@/public/images/10-year-anniversary/ethereum-launch.png"
911
import NftImage from "@/public/images/10-year-anniversary/nft-frontier.png"
12+
import TheMergeImage from "@/public/images/10-year-anniversary/robot-and-crowd-cheering.png"
1013
import Adoption5Image from "@/public/images/10-year-anniversary/robot-walking.png"
11-
import TheMergeImage from "@/public/images/10-year-anniversary/the-merge.png"
1214
import StableCoinImage from "@/public/images/10-year-anniversary/the-pioneer-stablecoin.png"
1315
import Adoption4Image from "@/public/images/10-year-anniversary/walking-talking-1.png"
1416
import Adoption6Image from "@/public/images/10-year-anniversary/walking-talking-2.png"
1517

16-
const adoptionCards = [
18+
const adoptionCards: AdoptionCard[] = [
1719
{
1820
image: Adoption1Image,
1921
title: "Decade of Decentralization",
@@ -102,12 +104,12 @@ const adoptionCards = [
102104

103105
// duplicate 1 2 3, 1 2 3 to fix mobile slider bug where styles are not applied
104106
const adoptionStyles = [
105-
"bg-background bg-gradient-to-t from-20% to-60% from-accent-c/10 to-accent-c/5 dark:from-accent-c/20 dark:to-accent-c/10 border-accent-c/10",
107+
"bg-background bg-gradient-to-b from-20% to-60% from-accent-c/10 to-accent-c/5 dark:from-accent-c/20 dark:to-accent-c/10 border-accent-c/10",
106108
"bg-background bg-gradient-to-b from-20% to-60% from-accent-b/10 to-accent-b/5 dark:from-accent-b/20 dark:to-accent-b/10 border-accent-b/10",
107-
"bg-background bg-gradient-to-r from-20% to-60% from-accent-a/10 to-accent-a/5 dark:from-accent-a/20 dark:to-accent-a/10 border-accent-a/10",
108-
"bg-background bg-gradient-to-t from-20% to-60% from-accent-c/10 to-accent-c/5 dark:from-accent-c/20 dark:to-accent-c/10 border-accent-c/10",
109+
"bg-background bg-gradient-to-b from-20% to-60% from-accent-a/10 to-accent-a/5 dark:from-accent-a/20 dark:to-accent-a/10 border-accent-a/10",
110+
"bg-background bg-gradient-to-b from-20% to-60% from-accent-c/10 to-accent-c/5 dark:from-accent-c/20 dark:to-accent-c/10 border-accent-c/10",
109111
"bg-background bg-gradient-to-b from-20% to-60% from-accent-b/10 to-accent-b/5 dark:from-accent-b/20 dark:to-accent-b/10 border-accent-b/10",
110-
"bg-background bg-gradient-to-r from-20% to-60% from-accent-a/10 to-accent-a/5 dark:from-accent-a/20 dark:to-accent-a/10 border-accent-a/10",
112+
"bg-background bg-gradient-to-b from-20% to-60% from-accent-a/10 to-accent-a/5 dark:from-accent-a/20 dark:to-accent-a/10 border-accent-a/10",
111113
]
112114

113115
const innovationCards = [
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { StaticImageData } from "next/image"
2+
3+
export type Story = {
4+
storyEnglish: string
5+
storyOriginal: string
6+
category: string
7+
name: string
8+
date: string
9+
country: string
10+
twitter: string
11+
region: string
12+
}
13+
14+
export type AdoptionCard = {
15+
image: StaticImageData
16+
title: string
17+
description: React.ReactNode
18+
href: string
19+
linkText: string
20+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { formatDate, isValidDate } from "@/lib/utils/date"
2+
3+
import { DEFAULT_LOCALE } from "@/lib/constants"
4+
5+
import type { Story } from "./types"
6+
7+
const parseDate = (date: string, locale = DEFAULT_LOCALE): string => {
8+
// TODO: Remove this check when spreadsheet is fixed
9+
// Currently dates are in the formatted as "DD.MM." which is not parsable by Date.parse
10+
// If partially valid date, reformat it
11+
const partiallyValidDate = /^(\d{1,2})\.(\d{1})\.$/
12+
if (partiallyValidDate.test(date)) {
13+
const [, day, month] = date.match(partiallyValidDate) || []
14+
const newDate = `2025-${month.padStart(2, "0")}-${day.padStart(2, "0")}`
15+
return formatDate(newDate, locale)
16+
}
17+
18+
// If the date is already in a valid format, return it
19+
if (isValidDate(date)) return formatDate(date, locale)
20+
// If the date is not recognized, return original value
21+
return date
22+
}
23+
24+
export const parseStoryDates = (
25+
stories: Story[],
26+
locale = DEFAULT_LOCALE
27+
): Story[] =>
28+
stories.map(({ date, ...story }) => ({
29+
...story,
30+
date: parseDate(date, locale),
31+
}))

app/[locale]/10years/page.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import InnovationSwiper from "./_components/InnovationSwiper"
2929
import Stories from "./_components/Stories"
3030
import TenYearGlobe from "./_components/TenYearGlobe"
3131
import TenYearHero from "./_components/TenYearHero"
32+
import { parseStoryDates } from "./_components/utils"
3233

3334
import { fetch10YearEvents } from "@/lib/api/fetch10YearEvents"
3435
import { fetch10YearStories } from "@/lib/api/fetch10YearStories"
@@ -54,6 +55,8 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
5455

5556
const [fetched10YearEvents, fetched10YearStories] = await loadData()
5657

58+
const stories = parseStoryDates(fetched10YearStories, locale)
59+
5760
// Get i18n messages
5861
const allMessages = await getMessages({ locale })
5962
const requiredNamespaces = getRequiredNamespacesForPage("/10years")
@@ -271,13 +274,16 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
271274
</p>
272275
</div>
273276
</div>
274-
<AdoptionSwiper />
277+
<AdoptionSwiper
278+
adoptionCards={adoptionCards}
279+
adoptionStyles={adoptionStyles}
280+
/>
275281
<div className="hidden flex-1 flex-col gap-6 md:flex">
276282
{adoptionCards.map((card, index) => (
277283
<div
278284
key={card.title}
279285
className={cn(
280-
"w-[70%] rounded-2xl p-8",
286+
"w-[70%] rounded-2xl p-8 shadow",
281287
index % 2 === 0 && "ml-auto",
282288
index !== 0 && "-mt-10",
283289
zIndexClasses[index],
@@ -319,15 +325,15 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
319325
</ButtonLink>
320326
</div>
321327
</div>
322-
<Stories stories={fetched10YearStories} />
328+
<Stories stories={stories} />
323329
</div>
324330

325331
<div className="w-full gap-8 px-8 py-8 pt-32">
326332
<div className="flex flex-col items-center gap-4 rounded-2xl bg-ten-year-gradient p-8">
327333
<Image
328334
src={TenYearLogo}
329335
alt="10 year anniversary logo"
330-
className="-mb-4 max-h-80 object-contain"
336+
className="mb-8 max-h-80 object-contain sm:mb-12"
331337
/>
332338
<h3>Have an idea for how the community can celebrate?</h3>
333339
<p>

app/[locale]/_components/home.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,10 @@ const HomePage = ({
608608
</SectionContent>
609609
</Section>
610610

611-
<Section id="10-year-anniversary">
611+
<Section
612+
id="10-year-anniversary"
613+
className={cn(locale !== "en" && "hidden")} // TODO: Show again when translations ready
614+
>
612615
<TenYearHomeBanner />
613616
</Section>
614617

0 commit comments

Comments
 (0)