Skip to content
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

App router pages #15114

Open
wants to merge 24 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
58eca70
intial home page migration to server component
pettinarip Mar 17, 2025
2f5ecd6
move run-a-node page
pettinarip Mar 17, 2025
884dd79
Merge branch 'dev' into app-router-pages
pettinarip Mar 17, 2025
4cad79d
include app dir in tailwind config
pettinarip Mar 18, 2025
b9c55ba
what is ethereum page
pettinarip Mar 18, 2025
82a8dd9
move more pages
pettinarip Mar 18, 2025
c45463d
and... more pages
pettinarip Mar 18, 2025
e311f8e
replace useRouter with useSearchParams to get the query from url
pettinarip Mar 18, 2025
ff20766
fix intl namespace
pettinarip Mar 18, 2025
15fa290
remove _app and _document
pettinarip Mar 18, 2025
7c9b6dd
migrate api endpoints
pettinarip Mar 18, 2025
686e609
keep old favicon png but with new name as it is used in the stablecoi…
pettinarip Mar 18, 2025
d3ce339
replace old hooks
pettinarip Mar 20, 2025
b389644
use nextjs fonts module
pettinarip Mar 20, 2025
895ddde
Merge branch 'dev' into app-router-pages
pettinarip Mar 20, 2025
7a96ca6
delete unused file
pettinarip Mar 20, 2025
a950503
replace pagemetadata
pettinarip Mar 20, 2025
07e4e1a
refactor name
pettinarip Mar 20, 2025
eea55b6
add matomo support with app router
pettinarip Mar 20, 2025
b053623
Merge branch 'dev' into app-router-pages
pettinarip Mar 21, 2025
e147ad5
Merge branch 'dev' into app-router-pages
pettinarip Mar 22, 2025
9e3d279
update favicon ref
pettinarip Mar 24, 2025
4964d78
update fonts load logic in storybook
pettinarip Mar 24, 2025
20a5743
bundle intl json files for runtime usage
pettinarip Mar 24, 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
2 changes: 1 addition & 1 deletion .storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { addons } from "@storybook/manager-api"

import favicon from "../public/images/favicon.png"
import favicon from "../public/images/eth-home-icon.png"

import theme from "./theme"

Expand Down
3 changes: 0 additions & 3 deletions .storybook/preview-head.html

This file was deleted.

28 changes: 22 additions & 6 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import isChromatic from "chromatic/isChromatic"
import { MotionGlobalConfig } from "framer-motion"
import { IBM_Plex_Mono, Inter } from "next/font/google"
import type { Preview } from "@storybook/react"

import ThemeProvider from "@/components/ThemeProvider"
Expand All @@ -9,11 +10,24 @@ import nextIntl, { baseLocales } from "./next-intl"
import { withNextThemes } from "./withNextThemes"

import "../src/styles/global.css"
import "../src/styles/fonts.css"
import "../src/styles/docsearch.css"

import "@docsearch/css"

const inter = Inter({
subsets: ["latin"],
display: "swap",
variable: "--font-inter",
preload: true,
})

const ibmPlexMono = IBM_Plex_Mono({
subsets: ["latin"],
weight: ["400"],
display: "swap",
variable: "--font-mono",
})

MotionGlobalConfig.skipAnimations = isChromatic()

export const breakpointSet: [token: string, value: string][] = [
Expand All @@ -39,11 +53,13 @@ const preview: Preview = {
defaultTheme: "light",
}),
(Story) => (
<ThemeProvider>
<TooltipProvider>
<Story />
</TooltipProvider>
</ThemeProvider>
<div className={`${inter.variable} ${ibmPlexMono.variable}`}>
<ThemeProvider>
<TooltipProvider>
<Story />
</TooltipProvider>
</ThemeProvider>
</div>
),
],
parameters: {
Expand Down
148 changes: 13 additions & 135 deletions src/pages/[locale]/index.tsx → app/[locale]/_components/home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client"

import { Fragment, lazy, Suspense } from "react"
import type { GetStaticProps, InferGetStaticPropsType } from "next"
import { FaDiscord, FaGithub } from "react-icons/fa6"
import { IoMdCopy } from "react-icons/io"
import { MdCheck } from "react-icons/md"
Expand All @@ -8,10 +9,9 @@ import type {
AllMetricData,
BasePageProps,
CommunityBlog,
Lang,
Params,
RSSItem,
} from "@/lib/types"
import { CommunityEvent } from "@/lib/interfaces"

import { ChevronNext } from "@/components/Chevron"
import CodeModal from "@/components/CodeModal"
Expand All @@ -24,8 +24,13 @@ import Calendar from "@/components/icons/calendar.svg"
import CalendarAdd from "@/components/icons/calendar-add.svg"
import { Image } from "@/components/Image"
import MainArticle from "@/components/MainArticle"
import PageMetadata from "@/components/PageMetadata"
import { TranslatathonBanner } from "@/components/Translatathon/TranslatathonBanner"
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
import { Button, ButtonLink } from "@/components/ui/buttons/Button"
import SvgButtonLink, {
type SvgButtonLinkProps,
Expand Down Expand Up @@ -56,43 +61,13 @@ import {
import WindowBox from "@/components/WindowBox"

import { cn } from "@/lib/utils/cn"
import { dataLoader } from "@/lib/utils/data/dataLoader"
import { isValidDate } from "@/lib/utils/date"
import { existsNamespace } from "@/lib/utils/existsNamespace"
import { getLastDeployDate } from "@/lib/utils/getLastDeployDate"
import { trackCustomEvent } from "@/lib/utils/matomo"
import { polishRSSList } from "@/lib/utils/rss"
import { breakpointAsNumber } from "@/lib/utils/screen"
import { getLocaleTimestamp } from "@/lib/utils/time"
import { getRequiredNamespacesForPage } from "@/lib/utils/translations"

import {
BASE_TIME_UNIT,
BLOG_FEEDS,
BLOGS_WITHOUT_FEED,
CALENDAR_DISPLAY_COUNT,
DEFAULT_LOCALE,
GITHUB_REPO_URL,
LOCALES_CODES,
RSS_DISPLAY_COUNT,
} from "@/lib/constants"

import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "../../components/ui/accordion"
import { GITHUB_REPO_URL } from "@/lib/constants"

import { useClipboard } from "@/hooks/useClipboard"
import loadNamespaces from "@/i18n/loadNamespaces"
import { fetchCommunityEvents } from "@/lib/api/calendarEvents"
import { fetchEthPrice } from "@/lib/api/fetchEthPrice"
import { fetchGrowThePie } from "@/lib/api/fetchGrowThePie"
import { fetchAttestantPosts } from "@/lib/api/fetchPosts"
import { fetchRSS } from "@/lib/api/fetchRSS"
import { fetchTotalEthStaked } from "@/lib/api/fetchTotalEthStaked"
import { fetchTotalValueLocked } from "@/lib/api/fetchTotalValueLocked"
import EventFallback from "@/public/images/events/event-placeholder.png"
import BuildersImage from "@/public/images/heroes/developers-hub-hero.jpg"
import ActivityImage from "@/public/images/heroes/layer-2-hub-hero.jpg"
Expand All @@ -111,110 +86,17 @@ const Codeblock = lazy(() =>

const StatsBoxGrid = lazy(() => import("@/components/StatsBoxGrid"))

// API calls
const fetchXmlBlogFeeds = async () => {
return await fetchRSS(BLOG_FEEDS)
}

type Props = BasePageProps & {
calendar: CommunityEvent[]
metricResults: AllMetricData
rssData: { rssItems: RSSItem[]; blogLinks: CommunityBlog[] }
}

// In seconds
const REVALIDATE_TIME = BASE_TIME_UNIT * 1

const loadData = dataLoader(
[
["ethPrice", fetchEthPrice],
["totalEthStaked", fetchTotalEthStaked],
["totalValueLocked", fetchTotalValueLocked],
["growThePieData", fetchGrowThePie],
["communityEvents", fetchCommunityEvents],
["attestantPosts", fetchAttestantPosts],
["rssData", fetchXmlBlogFeeds],
],
REVALIDATE_TIME * 1000
)

export async function getStaticPaths() {
return {
paths: LOCALES_CODES.map((locale) => ({ params: { locale } })),
fallback: false,
}
}

export const getStaticProps = (async ({ params }) => {
const { locale = DEFAULT_LOCALE } = params || {}

const [
ethPrice,
totalEthStaked,
totalValueLocked,
growThePieData,
communityEvents,
attestantPosts,
xmlBlogs,
] = await loadData()

const metricResults: AllMetricData = {
ethPrice,
totalEthStaked,
totalValueLocked,
txCount: growThePieData.txCount,
txCostsMedianUsd: growThePieData.txCostsMedianUsd,
}

const calendar = communityEvents.upcomingEventData
.sort((a, b) => {
const dateA = isValidDate(a.date) ? new Date(a.date).getTime() : -Infinity
const dateB = isValidDate(b.date) ? new Date(b.date).getTime() : -Infinity
return dateA - dateB
})
.slice(0, CALENDAR_DISPLAY_COUNT)

// load i18n required namespaces for the given page
const requiredNamespaces = getRequiredNamespacesForPage("/")

// check if the translated page content file exists for locale
const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[0])

// load last deploy date to pass to Footer in RootLayout
const lastDeployDate = getLastDeployDate()
const lastDeployLocaleTimestamp = getLocaleTimestamp(
locale as Lang,
lastDeployDate
)

// RSS feed items
const polishedRssItems = polishRSSList(attestantPosts, ...xmlBlogs)
const rssItems = polishedRssItems.slice(0, RSS_DISPLAY_COUNT)

const blogLinks = polishedRssItems.map(({ source, sourceUrl }) => ({
name: source,
href: sourceUrl,
})) as CommunityBlog[]
blogLinks.push(...BLOGS_WITHOUT_FEED)

const messages = await loadNamespaces(locale, requiredNamespaces)

return {
props: {
messages,
calendar,
contentNotTranslated,
lastDeployLocaleTimestamp,
metricResults,
rssData: { rssItems, blogLinks },
},
}
}) satisfies GetStaticProps<Props, Params>

const HomePage = ({
calendar,
metricResults,
rssData: { rssItems, blogLinks },
}: InferGetStaticPropsType<typeof getStaticProps>) => {
}: Props) => {
const {
t,
locale,
Expand All @@ -236,10 +118,6 @@ const HomePage = ({

return (
<MainArticle className="flex w-full flex-col items-center" dir={dir}>
<PageMetadata
title={t("page-index:page-index-meta-title")}
description={t("page-index:page-index-meta-description")}
/>
<TranslatathonBanner />
<HomeHero heroImg={Hero} className="w-full" />
<div className="w-full space-y-32 px-4 md:mx-6 lg:space-y-48">
Expand Down Expand Up @@ -504,7 +382,7 @@ const HomePage = ({
<button
key={title}
className={cn(
"flex flex-col gap-y-0.5 border-t px-6 py-4 text-start hover:bg-background-highlight max-md:hidden",
"flex flex-col gap-y-0.5 border-t px-6 py-4 hover:bg-background-highlight max-md:hidden",
isModalOpen &&
idx === activeCode &&
"bg-background-highlight"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
"use client"

import { HTMLAttributes } from "react"
import type { GetStaticProps } from "next/types"

import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types"
import type { ChildOnlyProp } from "@/lib/types"

import AssetDownload from "@/components/AssetDownload"
import FeedbackCard from "@/components/FeedbackCard"
import { Image } from "@/components/Image"
import MainArticle from "@/components/MainArticle"
import PageMetadata from "@/components/PageMetadata"
import { Center, Flex } from "@/components/ui/flex"
import InlineLink from "@/components/ui/Link"

import { existsNamespace } from "@/lib/utils/existsNamespace"
import { getLastDeployDate } from "@/lib/utils/getLastDeployDate"
import { getLocaleTimestamp } from "@/lib/utils/time"
// import efLogo from "@/public/images/ef-logo.png"
// import efLogoWhite from "@/public/images/ef-logo-white.png"
// import ethDiamondBlackHero from "@/public/images/assets/eth-diamond-black.png"
Expand All @@ -24,13 +21,8 @@ import { getLocaleTimestamp } from "@/lib/utils/time"
// import ethGifWaves from "@/public/images/eth-gif-waves.png"
// import ethPortraitPurpleWhite from "@/public/images/assets/ethereum-logo-portrait-purple-white.png"
// import leslieTheRhino from "@/public/images/upgrades/upgrade_rhino.png"
import { getRequiredNamespacesForPage } from "@/lib/utils/translations"

import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants"

import useColorModeValue from "@/hooks/useColorModeValue"
import { useTranslation } from "@/hooks/useTranslation"
import loadNamespaces from "@/i18n/loadNamespaces"
import ethDiamondBlack from "@/public/images/assets/eth-diamond-black.png"
import ethDiamondBlackGray from "@/public/images/assets/eth-diamond-black-gray.png"
import ethDiamondBlackWhite from "@/public/images/assets/eth-diamond-black-white.jpg"
Expand Down Expand Up @@ -98,37 +90,6 @@ const H3 = (props: ChildOnlyProp) => (
<h3 className="mb-0 mt-10 leading-xs" {...props} />
)

export async function getStaticPaths() {
return {
paths: LOCALES_CODES.map((locale) => ({ params: { locale } })),
fallback: false,
}
}

export const getStaticProps = (async ({ params }) => {
const { locale = DEFAULT_LOCALE } = params || {}

const requiredNamespaces = getRequiredNamespacesForPage("assets")

const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2])

const lastDeployDate = getLastDeployDate()
const lastDeployLocaleTimestamp = getLocaleTimestamp(
locale as Lang,
lastDeployDate
)

const messages = await loadNamespaces(locale, requiredNamespaces)

return {
props: {
messages,
contentNotTranslated,
lastDeployLocaleTimestamp,
},
}
}) satisfies GetStaticProps<BasePageProps, Params>

const AssetsPage = () => {
// Ignore locale in the URL for SVG path in public directory to fix broken link
// SVG path changes from /en/images => /images
Expand All @@ -141,10 +102,6 @@ const AssetsPage = () => {
)
return (
<Flex className="w-full flex-col">
<PageMetadata
title={t("page-assets-meta-title")}
description={t("page-assets-meta-desc")}
/>
<MainArticle className="px-8 py-4">
<Flex className="flex-col px-8 py-4">
<Center>
Expand Down
Loading