Skip to content

Back merge staging into dev #15544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
137 changes: 74 additions & 63 deletions app/[locale]/roadmap/_components/ReleaseCarousel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"use client"

import { useEffect, useState } from "react"
// TODO: Extract intl strings
// TODO: Fix RTL compatibility; currenly forced to LTR flow
import { useCallback, useEffect, useMemo, useState } from "react"
import { useLocale } from "next-intl"

import { Image } from "@/components/Image"
import { ButtonLink } from "@/components/ui/buttons/Button"
Expand All @@ -16,45 +19,39 @@ import {
import { cn } from "@/lib/utils/cn"
import { formatDate } from "@/lib/utils/date"

import { releasesData } from "@/data/roadmap/releases"
import { Release, releasesData } from "@/data/roadmap/releases"

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

// First try to find a release within the next 2 months
const upcomingReleaseIndex = releasesData.findIndex((release) => {
const releaseDate = new Date(release.releaseDate)
return releaseDate > today && releaseDate <= twoMonthsFromNow
})
const [api1, setApi1] = useState<CarouselApi>()
const [api2, setApi2] = useState<CarouselApi>()

// If no upcoming release found, find the most recent release up to today
if (upcomingReleaseIndex === -1) {
const pastReleases = releasesData.filter(
(release) => new Date(release.releaseDate) <= today
)
if (pastReleases.length > 0) {
const mostRecentRelease = pastReleases[pastReleases.length - 1]
return releasesData.findIndex(
(release) => release.releaseDate === mostRecentRelease.releaseDate
)
}
}
const startIndex = useMemo(() => {
const now = new Date()

return upcomingReleaseIndex
}
// Production: has a releaseDate in the past
const productionReleases = releasesData.filter((release) => {
if (!("releaseDate" in release) || !release.releaseDate) return false
const releaseDate = new Date(release.releaseDate)
return releaseDate <= now
})

const ReleaseCarousel = () => {
const todayDate = new Date()
const twoMonthsFromNow = new Date()
twoMonthsFromNow.setMonth(todayDate.getMonth() + 2)
// Upcoming: has a releaseDate, but is in the future
const upcomingReleases = releasesData.filter((release) => {
if (!("releaseDate" in release) || !release.releaseDate) return false
const releaseDate = new Date(release.releaseDate)
return releaseDate > now
})

const [api1, setApi1] = useState<CarouselApi>()
const [api2, setApi2] = useState<CarouselApi>()
const [currentIndex, setCurrentIndex] = useState(() =>
findLatestReleaseIndex()
)
// If upcoming releases exist, start index after production releases
if (upcomingReleases.length > 0) return productionReleases.length

// If no upcoming releases, start at the last production release
return productionReleases.length - 1
}, [])

const [currentIndex, setCurrentIndex] = useState(startIndex)

useEffect(() => {
if (!api1 || !api2) {
Expand All @@ -72,8 +69,29 @@ const ReleaseCarousel = () => {
})
}, [api1, api2])

const getStatus = useCallback((release: Release) => {
if (!("releaseDate" in release) || !release.releaseDate) return "dev"
if (new Date(release.releaseDate) <= new Date()) return "prod"
return "soon"
}, [])

const getDisplayDate = (release: Release): string => {
if (!("releaseDate" in release || "plannedReleaseYear" in release))
return ""

if ("plannedReleaseYear" in release && release.plannedReleaseYear)
return new Intl.DateTimeFormat(locale, {
year: "numeric",
}).format(new Date(Number(release.plannedReleaseYear), 0, 1))

if ("releaseDate" in release && release.releaseDate)
return formatDate(release.releaseDate)

return ""
}

return (
<div className="w-full max-w-[100vw] overflow-hidden">
<div className="w-full max-w-[100vw] overflow-hidden" dir="ltr">
<div className="mx-auto w-full max-w-screen-2xl px-4 sm:px-6">
<div className="w-full rounded-2xl bg-background-highlight py-6">
<div className="flex flex-col gap-6">
Expand All @@ -84,30 +102,23 @@ const ReleaseCarousel = () => {
opts={{
align: "center",
containScroll: false,
direction: "ltr",
loop: false,
startIndex: findLatestReleaseIndex(),
startIndex,
}}
>
<CarouselContent>
{releasesData.map((release, index) => {
const releaseDate = new Date(release.releaseDate)
const nextRelease =
releaseDate > todayDate && releaseDate <= twoMonthsFromNow
const labelType =
releaseDate < todayDate
? 1
: releaseDate < twoMonthsFromNow
? 2
: 3

const status = getStatus(release)
const displayDate = getDisplayDate(release)
return (
<CarouselItem
key={release.releaseName}
className="w-full md:basis-1/3"
>
<div className="flex w-full flex-col items-center justify-center gap-3">
<div className="mb-3 !h-6">
{labelType === 1 && (
{status === "prod" && (
<div
className={cn(
"w-fit rounded-lg bg-primary-low-contrast px-2 py-1",
Expand All @@ -117,7 +128,7 @@ const ReleaseCarousel = () => {
<p className="text-sm font-bold">In production</p>
</div>
)}
{labelType === 2 && (
{status === "soon" && (
<div
className={cn(
"w-fit rounded-lg bg-warning-light px-2 py-1",
Expand All @@ -129,7 +140,7 @@ const ReleaseCarousel = () => {
</p>
</div>
)}
{labelType === 3 && (
{status === "dev" && (
<div
className={cn(
"w-fit rounded-lg bg-card-gradient-secondary-hover px-2 py-1",
Expand All @@ -142,14 +153,15 @@ const ReleaseCarousel = () => {
</div>
)}
</div>
{/* Line-circle-line decoration —•— */}
<div className="flex w-full items-center justify-center text-center">
<div
className={cn(
"flex h-1 flex-1",
index !== 0
? nextRelease
? status === "soon"
? "bg-gradient-to-r from-primary to-primary-low-contrast"
: releaseDate.getTime() < todayDate.getTime()
: status === "prod"
? "bg-primary"
: "bg-primary-low-contrast"
: "bg-transparent"
Expand All @@ -158,21 +170,21 @@ const ReleaseCarousel = () => {
<div
className={cn(
"h-7 w-7 rounded-full",
releaseDate.getTime() < todayDate.getTime()
status === "prod"
? "bg-primary"
: "bg-primary-low-contrast",
nextRelease &&
status === "soon" &&
"border-2 border-primary bg-background"
)}
/>
<div
className={cn(
"flex h-1 flex-1",
index !== releasesData.length - 1
? index < findLatestReleaseIndex()
? "bg-primary"
: "bg-primary-low-contrast"
: "bg-transparent"
index < startIndex
? "bg-primary"
: "bg-primary-low-contrast",
index === releasesData.length - 1 &&
"bg-transparent"
)}
/>
</div>
Expand All @@ -181,7 +193,7 @@ const ReleaseCarousel = () => {
{release.releaseName}
</p>
<p className="font-mono text-sm text-body-medium">
{formatDate(release.releaseDate)}
{displayDate}
</p>
</div>
</div>
Expand All @@ -202,8 +214,9 @@ const ReleaseCarousel = () => {
opts={{
align: "center",
containScroll: false,
direction: "ltr",
loop: false,
startIndex: findLatestReleaseIndex(),
startIndex,
}}
>
<CarouselContent>
Expand All @@ -225,9 +238,7 @@ const ReleaseCarousel = () => {
<h2 className="text-4xl font-bold lg:text-6xl">
{release.releaseName}
</h2>
<p className="text-md">
{formatDate(release.releaseDate)}
</p>
<p className="text-md">{getDisplayDate(release)}</p>
</div>

<div>
Expand Down
65 changes: 47 additions & 18 deletions public/content/community/grants/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,61 @@ This list is curated by our community. If there's something missing or incorrect
These programs support the broad Ethereum ecosystem by offering grants to a wide scope of projects. These include solutions for scalability, community building, security, privacy, and more. These grants are not specific to any one Ethereum platform and are a good place to start if you're unsure.

- [EF Ecosystem Support Program](https://esp.ethereum.foundation) - _Funding open source projects that benefit Ethereum, with a particular focus on universal tools, infrastructure, research and public goods_
- [Moloch DAO](https://www.molochdao.com/) - _Privacy, layer 2 scaling, client security, and more_
- [DAO Grants](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) - _Google spreadsheet of organizations offering grants_
- [Academic Grants](https://esp.ethereum.foundation/academic-grants) - _Grants to support Ethereum-related academic work_

## Grant list aggregators and platforms {#grant-list-aggregators}

These resources compile and organize various grant opportunities across the Ethereum ecosystem, making it easier to discover funding opportunities that match your project's needs. We've organized them by persona to help you get you started finding the most relevant resources based on your specific funding needs.

### For all grant seekers: Comprehensive directories {#comprehensive-directories}

These general platforms offer broad coverage of grants across the entire Web3 space and are useful starting points for anyone looking for funding:

- [Blockworks Grantfarm](https://blockworks.co/grants/programs) - _Blockworks has compiled a comprehensive directory of all grants, RFPs, and bug bounties._
- [Find Blockchain Grants](https://findblockchaingrants.com/) - _Searchable database of blockchain grants_
- [Grantr](https://grantr.app/) - _Platform for discovering and applying to Web3 grants_
- [Blockchain Grants](https://www.blockchaingrants.org/) - _Directory of blockchain and crypto grants_

### For developers and builders {#for-developers-and-builders}

- [Web3 Grants](https://www.notion.so/Web3-Grants-dae38f9b5f524d36a15aaee1b6fa3089) - _Notion database of Web3 grant opportunities_
- [Grant Programs Viewer](https://airtable.com/shr86elKgWTSCP4AY) - _Public Airtable database of grant programs_
- [Web3 Grants Spreadsheet](https://docs.google.com/spreadsheets/d/1c8koZCI-GLnD8MG-eFcXPOBCNu1v8-aXIfwAAvc7AMc/edit#gid=0) - _Google spreadsheet of Web3 grant opportunities_

### For DeFi projects and financial applications {#for-defi-projects}

- [LlamaoGrants](https://wiki.defillama.com/wiki/LlamaoGrants) - _DeFi Llama's grant program directory_
- [AlphaGrowth Grants](https://alphagrowth.io/crypto-web3-grants-list) - _Comprehensive list of crypto and Web3 grants_

### For DAO contributors and governance innovators {#for-dao-contributors}

Resources for community-driven projects and governance experiments:

- [DAO Grants](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) - _Google spreadsheet of organizations offering grants_
- [MetaGov Database](https://docs.google.com/spreadsheets/d/1e5g-dlWWsK2DZoZGBgfxyfGNSddLk-V7sLEgfPjEhbA/edit#gid=780420708) - _Comprehensive Web3 grants map_

### For entrepreneurs and startups {#for-entrepreneurs-and-startups}

Resources for those building products and seeking investment beyond just grants:

## Project specific {#project-specific}
- [Web3Native](https://www.web3native.co/) - _Directory of Web3 grants, investors, and accelerator programs_
- [Cryptoneur Web3 Grants](https://www.cryptoneur.xyz/web3-grants) - _Platform for finding Web3 project funding_
- [Pentacle Grants](https://pentacle.xyz/grants) - _Grant opportunities in the Web3 space_

These projects have created their own grants for projects aimed at developing and experimenting with their own technology.
### Public goods and impact {#public-goods-and-impact}

- [Aave Grants Program](https://aavegrants.org/)_[Aave](https://aave.com/) grants DAO_
- [Balancer](https://grants.balancer.community/)_[Balancer](https://balancer.fi/) ecosystem fund_
- [Chainlink Grants Program](https://chain.link/community/grants) - _[Chainlink](https://chain.link/) community grants_
- [Decentraland Grants Program](https://governance.decentraland.org/grants/)_[Decentraland](https://decentraland.org/) DAO Metaverse_
- [Lido Ecosystem Grants Organisation (LEGO)](https://lido.fi/lego)_[Lido](https://lido.fi/) finance ecosystem_
- [MetaMask Program](https://metamaskgrants.org/) - _[MetaMask](https://metamask.io/) employee-led grants DAO_
- [SKALE Network Grants Program](https://skale.space/developers#grants) - _[SKALE Network](https://skale.space/) ecosystem_
- [Swarm Foundation Grants Program](https://my.ethswarm.org/grants) - _[Swarm Foundation](https://www.ethswarm.org/) ecosystem_
- [The Graph](https://thegraph.com/ecosystem/grants/)_[The Graph](https://thegraph.com/) ecosystem_
- [Uniswap Grants Program](https://www.uniswapfoundation.org/approach)_[Uniswap](https://uniswap.org/) community_
These programs focus on funding projects that benefit the broader community, public goods, and impact initiatives. These include grant providers, as well as donation platforms utilizing onchain funding allocation mechanisms including [quadratic funding](/defi/#quadratic-funding):

## Quadratic funding {#quadratic-funding}
- [Gitcoin](https://www.gitcoin.co/program) - _Gitcoin Grants utilizes multiple capital allocation mechanisms to fund open source projects and public goods in the Ethereum ecosystem_
- [Octant](https://octant.app/home) - _Public goods funding ecosystem that balances the common good and individual financial empowerment_
- [Giveth](https://giveth.io/) - _Crypto donation platform enabling direct donations from for-good projects with zero added fees_
- [Artizen](https://artizen.fund/) - _Helping creators match fund new projects at the frontier of art, science, technology and culture_
- [Quadratic Accelerator](https://qacc.giveth.io/) - _Start-up accelerator program that uses quadratic funding to support projects that benefit the public good_

The open source roots of Ethereum have led to the growth of an interesting new fundraising model: quadratic funding. This has the potential to improve the way we fund all types of public goods in the future. Quadratic funding makes sure that the projects that receive the most funding are those with the most unique demand. In other words, projects that stand to improve the lives of the most people. [More on quadratic funding.](/defi/#quadratic-funding)
### Additional resources {#additional-resources}

- [Gitcoin](https://gitcoin.co/grants)
- [clr.fund](https://clr.fund/)
- [Web3 Summits Grants](https://www.web3summits.io/grants) - _Grant opportunities from Web3 Summits_
- [Anke's Directory](https://docs.google.com/spreadsheets/d/1IdCCG-U7cGsih_nCNt7Yo4wXstZdCip1UKWbCK0qCZk/edit#gid=938115517) - _Web3 grant program directory_

## Work in Ethereum {#work-in-ethereum}

Expand Down
18 changes: 9 additions & 9 deletions src/components/Homepage/useHome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import type { CodeExample } from "@/lib/interfaces"

import { useBentoBox } from "@/components/Homepage/useBentoBox"
import BlockHeap from "@/components/icons/block-heap.svg"
import BuildAppsIcon from "@/components/icons/build-apps.svg"
import EthGlyphIcon from "@/components/icons/eth-glyph.svg"
import EthTokenIcon from "@/components/icons/eth-token.svg"
import PickWalletIcon from "@/components/icons/eth-wallet.svg"
import ChooseNetworkIcon from "@/components/icons/network-layers.svg"
import TryAppsIcon from "@/components/icons/phone-homescreen.svg"
import RoadmapSign from "@/components/icons/roadmap-sign.svg"
import Whitepaper from "@/components/icons/whitepaper.svg"
Expand Down Expand Up @@ -103,14 +103,6 @@ export const useHome = () => {
className: "text-accent-a hover:text-accent-a-hover",
eventName: "get eth",
},
{
label: t("page-index:page-index-cta-networks-label"),
description: t("page-index:page-index-cta-networks-description"),
href: "/layer-2/", // TODO: Update with new networks page when ready
Svg: ChooseNetworkIcon,
className: "text-accent-b hover:text-accent-b-hover",
eventName: "L2",
},
{
label: t("page-index:page-index-cta-dapps-label"),
description: t("page-index:page-index-cta-dapps-description"),
Expand All @@ -122,6 +114,14 @@ export const useHome = () => {
),
eventName: "dapps",
},
{
label: t("page-index:page-index-cta-build-apps-label"),
description: t("page-index:page-index-cta-build-apps-description"),
href: "/developers/",
Svg: BuildAppsIcon,
className: "text-accent-b hover:text-accent-b-hover",
eventName: "build apps",
},
]

const popularTopics = [
Expand Down
Loading
Loading