Skip to content
Draft
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
a6a3a58
setup future data
corwintines Apr 25, 2025
dec12b2
fix sticky bug
corwintines Apr 25, 2025
2252c1e
Merge branch 'roadmap-page' into roadmap-tracks-page
corwintines Apr 25, 2025
725a017
Merge branch 'roadmap-page' into roadmap-tracks-page
corwintines Apr 25, 2025
29e9d08
setup hero section
corwintines Apr 28, 2025
cbe52f2
setup nav bar
corwintines Apr 28, 2025
8b55655
setup tracks
corwintines Apr 28, 2025
388136c
benefits content
corwintines Apr 28, 2025
023d5cc
fix spacing
corwintines Apr 28, 2025
02d920a
implement accordion
corwintines Apr 29, 2025
5e34648
Merge branch 'roadmap-page' into roadmap-tracks-page
corwintines Apr 29, 2025
5ffdde8
Merge branch 'roadmap-page' into roadmap-tracks-page
corwintines Apr 29, 2025
a5c4722
Merge branch 'dev' into roadmap-tracks-page
corwintines Apr 30, 2025
09234a8
button, styling cleanup, default state
corwintines Apr 30, 2025
2e0aee5
content setup
corwintines Apr 30, 2025
5d3ca0f
setup ReactFlow nodes
corwintines Apr 30, 2025
8b71de1
POC for shipped nodes
corwintines May 1, 2025
dcc6531
end goal node
corwintines May 2, 2025
0afbfd9
style tweaking
corwintines May 2, 2025
88c8851
refactor and task idea node
corwintines May 4, 2025
0e82222
task research node
corwintines May 4, 2025
8c35c87
cleanup
corwintines May 4, 2025
ed84629
sheduled and cleanup
corwintines May 4, 2025
f4a5bf9
Feature scheduled node
corwintines May 4, 2025
3e8d1f3
feature shipped node
corwintines May 4, 2025
3e743fc
group node tests
corwintines May 4, 2025
b768f9d
test
corwintines May 4, 2025
ef5796d
merge track
corwintines May 5, 2025
9296509
Rollup node, track node, and surge chart
corwintines May 5, 2025
4b5dc86
scourge nodes
corwintines May 5, 2025
5a91422
purge track nodes
corwintines May 5, 2025
9117463
verge track nodes
corwintines May 5, 2025
91b8867
splurge track nodes
corwintines May 6, 2025
251530e
fix some bugs
corwintines May 6, 2025
1a1cf93
mock dialog
corwintines May 6, 2025
7872c6c
Refactor to popover instead
corwintines May 6, 2025
3a4a772
setup gradients and top section for popover
corwintines May 6, 2025
afd1726
popover body and todo list
corwintines May 7, 2025
c2cdf24
percentage bar
corwintines May 7, 2025
4cd59ce
Merge branch 'dev' into roadmap-tracks-page
corwintines May 7, 2025
b3e114b
Explore ethereum roadmap section
corwintines May 7, 2025
6806dd0
Add zoom in and out buttons, remove banner
corwintines May 7, 2025
1a6f039
future releseases added
corwintines May 8, 2025
e18a44d
nav bar
corwintines May 8, 2025
e2e9b19
change requests
corwintines May 8, 2025
ede0fe3
change requests
corwintines May 8, 2025
3386b7b
Draft Merge Copy
minimalsm May 27, 2025
5bc40fc
refactor: use tailwind native bg gradient classes
wackerow May 28, 2025
73b5916
Merge pull request #15524 from ethereum/tracks-gradients
corwintines May 28, 2025
cc13a9c
Merge pull request #15512 from ethereum/copyRoadmap
wackerow Sep 9, 2025
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
24 changes: 14 additions & 10 deletions app/[locale]/roadmap/_components/ReleaseCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,27 @@ import {
import { cn } from "@/lib/utils/cn"
import { formatDate } from "@/lib/utils/date"

import { releasesData } from "@/data/roadmap/releases"
import { releasesDataWithFuture } from "@/data/roadmap/releases"

const findLatestReleaseIndex = () => {
const today = new Date()
const twoMonthsFromNow = new Date()
twoMonthsFromNow.setMonth(today.getMonth() + 2)

// First try to find a release within the next 2 months
const upcomingReleaseIndex = releasesData.findIndex((release) => {
const upcomingReleaseIndex = releasesDataWithFuture.findIndex((release) => {
const releaseDate = new Date(release.releaseDate)
return releaseDate > today && releaseDate <= twoMonthsFromNow
})

// If no upcoming release found, find the most recent release up to today
if (upcomingReleaseIndex === -1) {
const pastReleases = releasesData.filter(
const pastReleases = releasesDataWithFuture.filter(
(release) => new Date(release.releaseDate) <= today
)
if (pastReleases.length > 0) {
const mostRecentRelease = pastReleases[pastReleases.length - 1]
return releasesData.findIndex(
return releasesDataWithFuture.findIndex(
(release) => release.releaseDate === mostRecentRelease.releaseDate
)
}
Expand Down Expand Up @@ -89,7 +89,7 @@ const ReleaseCarousel = () => {
}}
>
<CarouselContent>
{releasesData.map((release, index) => {
{releasesDataWithFuture.map((release, index) => {
const releaseDate = new Date(release.releaseDate)
const nextRelease =
releaseDate > todayDate && releaseDate <= twoMonthsFromNow
Expand Down Expand Up @@ -168,11 +168,11 @@ const ReleaseCarousel = () => {
<div
className={cn(
"flex h-1 flex-1",
index !== releasesData.length - 1
index !== releasesDataWithFuture.length - 1
? index < findLatestReleaseIndex()
? "bg-primary"
: "bg-primary-low-contrast"
: "bg-transparent"
: "border-2 border-dashed border-primary-low-contrast"
)}
/>
</div>
Expand All @@ -181,7 +181,9 @@ const ReleaseCarousel = () => {
{release.releaseName}
</p>
<p className="font-mono text-sm text-body-medium">
{formatDate(release.releaseDate)}
{release.releaseDate === "Future"
? "Future"
: formatDate(release.releaseDate)}
</p>
</div>
</div>
Expand All @@ -207,7 +209,7 @@ const ReleaseCarousel = () => {
}}
>
<CarouselContent>
{releasesData.map((release) => (
{releasesDataWithFuture.map((release) => (
<CarouselItem
key={release.releaseName}
className="w-full pl-4"
Expand All @@ -226,7 +228,9 @@ const ReleaseCarousel = () => {
{release.releaseName}
</h2>
<p className="text-md">
{formatDate(release.releaseDate)}
{release.releaseDate === "Future"
? "Future"
: formatDate(release.releaseDate)}
</p>
</div>

Expand Down
35 changes: 33 additions & 2 deletions app/[locale]/roadmap/_components/roadmap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useTranslation } from "@/hooks/useTranslation"
import ethBlocksImage from "@/public/images/developers-eth-blocks.png"
import communityHeroImg from "@/public/images/heroes/community-hero.png"
import roadmapHeroImg from "@/public/images/heroes/roadmap-hub-hero.jpg"
import roadmapTracksImage from "@/public/images/roadmap/roadmap-tracks-image.png"

const RoadmapPage = () => {
const { t } = useTranslation("page-roadmap")
Expand Down Expand Up @@ -162,11 +163,11 @@ const RoadmapPage = () => {
{changesComingItems.map((item) => (
<div
key={item.title}
className="bg-roadmap-card-gradient flex h-full flex-col gap-4 rounded-3xl border p-6"
className="flex h-full flex-col gap-4 rounded-3xl border bg-card-gradient p-6"
>
<div className="flex flex-row items-center justify-between gap-4">
<h3 className="m-0">{item.title}</h3>
<div className="flex h-12 w-12 items-center justify-center">
<div className="flex h-12 w-12 items-center justify-center text-primary">
{item.icon}
</div>
</div>
Expand All @@ -179,6 +180,36 @@ const RoadmapPage = () => {
</div>
</div>

<div className="flex w-full px-8 py-4">
<div className="flex w-full flex-col overflow-hidden rounded-3xl border bg-card-gradient lg:flex-row-reverse">
<div className="relative flex max-h-[300px] min-h-[250px] flex-1">
<Image
src={roadmapTracksImage}
alt="Ethereum roadmap"
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-background/90 lg:bg-gradient-to-l" />
</div>
<div className="z-10 -mt-10 flex flex-col justify-center gap-4 p-8 lg:mt-0 lg:flex-1">
<h3>Explore Ethereum&apos;s roadmap</h3>
<p>
Ethereum&apos;s future is shaped by everyone, not just one
person.
</p>
<p>
In 2022, Vitalik Buterin shared a vision for what could come
next. Today, developers, researchers, and the community continue
to evolve Ethereum with their own ideas and proposals.
</p>
<div className="flex w-full lg:w-fit">
<ButtonLink href="/roadmap/tracks">
View the progress
</ButtonLink>
</div>
</div>
</div>
</div>

<div className="flex flex-col-reverse gap-12 px-8 py-4 md:w-full md:flex-row">
<div className="max-w-screen-md flex-1">
<h2 className="mb-8">Why does Ethereum need a roadmap?</h2>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client"

import { Handle, Position } from "@xyflow/react"

type EndGoalNodeProps = {
data: {
label: string
leftNode?: boolean
}
}

const EndGoalNode = ({ data }: EndGoalNodeProps) => {
return (
<>
{data.leftNode && (
<Handle
id="left"
type="target"
position={Position.Left}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableEnd={true}
/>
)}
<div className="flex h-36 max-h-36 w-36 max-w-36 items-center justify-center rounded-full bg-primary p-4 text-center">
<p className="font-inter text-[14px] font-bold leading-[160%] text-body-inverse">
{data.label}
</p>
</div>
</>
)
}

export default EndGoalNode
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"use client"

import { Handle, Position } from "@xyflow/react"

type FeatureResearchNodeProps = {
data: {
label: string
topNode: boolean
leftNode: boolean
rightNode: boolean
bottomNode: boolean
}
}

const FeatureResearchNode = ({ data }: FeatureResearchNodeProps) => {
const { topNode, leftNode, rightNode, bottomNode } = data

return (
<>
{topNode && (
<Handle
id="top"
type="target"
position={Position.Top}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableStart={true}
isConnectableEnd={true}
/>
)}
{topNode && (
<Handle
id="top-source"
type="source"
position={Position.Top}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableStart={true}
isConnectableEnd={true}
/>
)}
{leftNode && (
<Handle
id="left"
type="target"
position={Position.Left}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableEnd={true}
/>
)}
{rightNode && (
<Handle
id="right"
type="source"
position={Position.Right}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableStart={true}
/>
)}
{bottomNode && (
<Handle
id="bottom"
type="target"
position={Position.Bottom}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableStart={true}
/>
)}
<div className="z-0 flex w-44 max-w-44 flex-col items-center justify-center gap-2 rounded-lg border border-primary bg-primary-low-contrast p-8">
<div className="text-center">
<p className="text-md font-bold">{data.label}</p>
</div>
<div className="rounded-full bg-background-medium px-2 py-1">
<p className="text-xs">RESEARCH</p>
</div>
</div>
</>
)
}

export default FeatureResearchNode
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"use client"

import { Handle, Position } from "@xyflow/react"

type FeatureScheduledNodeProps = {
data: {
label: string
topNode: boolean
leftNode: boolean
rightNode: boolean
bottomNode: boolean
}
}

const FeatureScheduledNode = ({ data }: FeatureScheduledNodeProps) => {
const { topNode, leftNode, rightNode, bottomNode } = data

return (
<>
{topNode && (
<Handle
type="target"
position={Position.Top}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableEnd={true}
/>
)}
{leftNode && (
<Handle
type="target"
position={Position.Left}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableEnd={true}
/>
)}
{rightNode && (
<Handle
type="source"
position={Position.Right}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableStart={true}
/>
)}
{bottomNode && (
<Handle
type="source"
position={Position.Bottom}
style={{
width: "14px",
height: "14px",
border: "2px solid hsla(var(--primary))",
backgroundColor: "hsla(var(--background))",
}}
isConnectable={true}
isConnectableStart={true}
/>
)}
<div className="z-0 flex w-44 max-w-44 flex-col items-center justify-center gap-2 rounded-lg border border-primary bg-primary-low-contrast p-8">
<div className="text-center">
<p className="text-md font-bold">{data.label}</p>
</div>
<div className="rounded-full bg-warning px-2 py-1">
<p className="text-xs text-black">SCHEDULED</p>
</div>
Comment on lines +80 to +82
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like us to be able to build on top of existing DS components.

IMO we should use the Tag component in this case https://dev--63b7ea99632763723c7f4d6b.chromatic.com/?path=/story/molecules-display-content-tags--style-variants-basic

</div>
</>
)
}

export default FeatureScheduledNode
Loading