Skip to content

Commit 7907b37

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into add-lychee-ci
2 parents f84e1d1 + 1a54816 commit 7907b37

File tree

645 files changed

+16691
-4262
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

645 files changed

+16691
-4262
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
* @wackerow @corwintines @pettinarip @minimalsm
99

1010
# Owners of specific files
11-
/src/data/consensus-bounty-hunters.json @djrtwo @asanso @fredriksvantes
11+
/src/data/consensus-bounty-hunters.json @asanso @fredriksvantes
1212
/src/data/wallets/new-to-crypto.ts @konopkja @minimalsm

app/[locale]/[...slug]/page.tsx

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import pick from "lodash.pick"
2+
import { notFound } from "next/navigation"
3+
import { getMessages, setRequestLocale } from "next-intl/server"
4+
5+
import I18nProvider from "@/components/I18nProvider"
6+
import mdComponents from "@/components/MdComponents"
7+
8+
import { dataLoader } from "@/lib/utils/data/dataLoader"
9+
import { getPostSlugs } from "@/lib/utils/md"
10+
import { getRequiredNamespacesForPage } from "@/lib/utils/translations"
11+
12+
import { LOCALES_CODES } from "@/lib/constants"
13+
14+
import { componentsMapping, layoutMapping } from "@/layouts"
15+
import { fetchGFIs } from "@/lib/api/fetchGFIs"
16+
import { getPageData } from "@/lib/md/data"
17+
import { getMdMetadata } from "@/lib/md/metadata"
18+
19+
const loadData = dataLoader([["gfissues", fetchGFIs]])
20+
21+
export default async function Page({
22+
params,
23+
}: {
24+
params: Promise<{ locale: string; slug: string[] }>
25+
}) {
26+
const { locale, slug: slugArray } = await params
27+
28+
// Check if this specific path is in our valid paths
29+
const validPaths = await generateStaticParams()
30+
const isValidPath = validPaths.some(
31+
(path) =>
32+
path.locale === locale && path.slug.join("/") === slugArray.join("/")
33+
)
34+
35+
if (!isValidPath) {
36+
notFound()
37+
}
38+
39+
// Enable static rendering
40+
setRequestLocale(locale)
41+
42+
const [gfissues] = await loadData()
43+
44+
const slug = slugArray.join("/")
45+
46+
const {
47+
content,
48+
frontmatter,
49+
tocItems,
50+
lastEditLocaleTimestamp,
51+
isTranslated,
52+
} = await getPageData({
53+
locale,
54+
slug,
55+
// TODO: Address component typing error here (flip `FC` types to prop object types)
56+
// @ts-expect-error Incompatible component function signatures
57+
components: { ...mdComponents, ...componentsMapping },
58+
scope: {
59+
gfissues,
60+
},
61+
})
62+
63+
// Determine the actual layout after we have the frontmatter
64+
const layout = frontmatter.template || "static"
65+
const Layout = layoutMapping[layout]
66+
67+
// Get i18n messages
68+
const allMessages = await getMessages({ locale })
69+
const requiredNamespaces = getRequiredNamespacesForPage(slug, layout)
70+
const messages = pick(allMessages, requiredNamespaces)
71+
72+
return (
73+
<I18nProvider locale={locale} messages={messages}>
74+
<Layout
75+
slug={slug}
76+
frontmatter={frontmatter}
77+
tocItems={tocItems}
78+
lastEditLocaleTimestamp={lastEditLocaleTimestamp}
79+
contentNotTranslated={!isTranslated}
80+
>
81+
{content}
82+
</Layout>
83+
</I18nProvider>
84+
)
85+
}
86+
87+
export async function generateStaticParams() {
88+
const slugs = await getPostSlugs("/", /\/developers/)
89+
90+
return LOCALES_CODES.flatMap((locale) =>
91+
slugs.map((slug) => ({
92+
slug: slug.split("/").slice(1),
93+
locale,
94+
}))
95+
)
96+
}
97+
98+
export async function generateMetadata({
99+
params,
100+
}: {
101+
params: Promise<{ locale: string; slug: string[] }>
102+
}) {
103+
const { locale, slug } = await params
104+
105+
return await getMdMetadata({
106+
locale,
107+
slug,
108+
})
109+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { join } from "path"
2+
3+
import pick from "lodash.pick"
4+
import { getMessages, setRequestLocale } from "next-intl/server"
5+
6+
import I18nProvider from "@/components/I18nProvider"
7+
import mdComponents from "@/components/MdComponents"
8+
9+
import { getPostSlugs } from "@/lib/utils/md"
10+
import { getRequiredNamespacesForPage } from "@/lib/utils/translations"
11+
12+
import { LOCALES_CODES } from "@/lib/constants"
13+
14+
import { docsComponents, DocsLayout } from "@/layouts"
15+
import { getPageData } from "@/lib/md/data"
16+
import { getMdMetadata } from "@/lib/md/metadata"
17+
18+
export default async function Page({
19+
params,
20+
}: {
21+
params: Promise<{ locale: string; doc?: string[] }>
22+
}) {
23+
const { locale, doc: docArray } = await params
24+
25+
// Enable static rendering
26+
setRequestLocale(locale)
27+
28+
const slug = join("developers/docs", ...(docArray || []))
29+
30+
const layout = "docs"
31+
32+
const {
33+
content,
34+
frontmatter,
35+
tocItems,
36+
lastEditLocaleTimestamp,
37+
contributors,
38+
isTranslated,
39+
} = await getPageData({
40+
locale,
41+
slug,
42+
// TODO: Address component typing error here (flip `FC` types to prop object types)
43+
// @ts-expect-error Incompatible component function signatures
44+
components: { ...mdComponents, ...docsComponents },
45+
layout,
46+
})
47+
48+
// Get i18n messages
49+
const allMessages = await getMessages({ locale })
50+
const requiredNamespaces = getRequiredNamespacesForPage(slug, layout)
51+
const messages = pick(allMessages, requiredNamespaces)
52+
53+
return (
54+
<I18nProvider locale={locale} messages={messages}>
55+
<DocsLayout
56+
slug={slug}
57+
frontmatter={frontmatter}
58+
tocItems={tocItems}
59+
lastEditLocaleTimestamp={lastEditLocaleTimestamp}
60+
contributors={contributors}
61+
contentNotTranslated={!isTranslated}
62+
>
63+
{content}
64+
</DocsLayout>
65+
</I18nProvider>
66+
)
67+
}
68+
69+
export async function generateStaticParams() {
70+
const slugs = await getPostSlugs("/developers/docs")
71+
72+
// Generate page paths for each supported locale
73+
return LOCALES_CODES.flatMap((locale) =>
74+
slugs.map((slug) => {
75+
return {
76+
// Splitting nested paths to generate proper slug
77+
doc: slug.replace("/developers/docs", "").split("/").slice(1),
78+
locale,
79+
}
80+
})
81+
)
82+
}
83+
84+
export async function generateMetadata({
85+
params,
86+
}: {
87+
params: Promise<{ locale: string; doc: string[] }>
88+
}) {
89+
const { locale, doc } = await params
90+
const slug = ["developers/docs", ...(doc || [])]
91+
92+
return await getMdMetadata({
93+
locale,
94+
slug,
95+
})
96+
}
97+
98+
export const dynamicParams = false
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { join } from "path"
2+
3+
import pick from "lodash.pick"
4+
import { getMessages, setRequestLocale } from "next-intl/server"
5+
6+
import I18nProvider from "@/components/I18nProvider"
7+
import mdComponents from "@/components/MdComponents"
8+
9+
import { dateToString } from "@/lib/utils/date"
10+
import { getPostSlugs } from "@/lib/utils/md"
11+
import { getRequiredNamespacesForPage } from "@/lib/utils/translations"
12+
13+
import { LOCALES_CODES } from "@/lib/constants"
14+
15+
import { TutorialLayout, tutorialsComponents } from "@/layouts"
16+
import { getPageData } from "@/lib/md/data"
17+
import { getMdMetadata } from "@/lib/md/metadata"
18+
19+
export default async function Page({
20+
params,
21+
}: {
22+
params: Promise<{ locale: string; tutorial: string[] }>
23+
}) {
24+
const { locale, tutorial: tutorialArray } = await params
25+
26+
// Enable static rendering
27+
setRequestLocale(locale)
28+
29+
const slug = join("developers/tutorials", ...tutorialArray)
30+
31+
const layout = "tutorial"
32+
33+
const {
34+
content,
35+
frontmatter,
36+
tocItems,
37+
lastEditLocaleTimestamp,
38+
contributors,
39+
isTranslated,
40+
} = await getPageData({
41+
locale,
42+
slug,
43+
// TODO: Address component typing error here (flip `FC` types to prop object types)
44+
// @ts-expect-error Incompatible component function signatures
45+
components: { ...mdComponents, ...tutorialsComponents },
46+
layout,
47+
})
48+
49+
// If the page has a published date, format it
50+
if ("published" in frontmatter) {
51+
frontmatter.published = dateToString(frontmatter.published)
52+
}
53+
54+
// Get i18n messages
55+
const allMessages = await getMessages({ locale })
56+
const requiredNamespaces = getRequiredNamespacesForPage(slug, layout)
57+
const messages = pick(allMessages, requiredNamespaces)
58+
59+
return (
60+
<I18nProvider locale={locale} messages={messages}>
61+
<TutorialLayout
62+
slug={slug}
63+
frontmatter={frontmatter}
64+
tocItems={tocItems}
65+
lastEditLocaleTimestamp={lastEditLocaleTimestamp}
66+
contributors={contributors}
67+
contentNotTranslated={!isTranslated}
68+
timeToRead={2}
69+
>
70+
{content}
71+
</TutorialLayout>
72+
</I18nProvider>
73+
)
74+
}
75+
76+
export async function generateStaticParams() {
77+
const slugs = await getPostSlugs("/developers/tutorials")
78+
79+
return LOCALES_CODES.flatMap((locale) =>
80+
slugs.map((slug) => ({
81+
tutorial: slug.replace("/developers/tutorials", "").split("/").slice(1),
82+
locale,
83+
}))
84+
)
85+
}
86+
87+
export async function generateMetadata({
88+
params,
89+
}: {
90+
params: Promise<{ locale: string; tutorial: string[] }>
91+
}) {
92+
const { locale, tutorial } = await params
93+
const slug = ["developers/tutorials", ...(tutorial || [])]
94+
95+
return await getMdMetadata({
96+
locale,
97+
slug,
98+
})
99+
}
100+
101+
export const dynamicParams = false

app/[locale]/error.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"use client"
2+
3+
import { useEffect } from "react"
4+
5+
import MainArticle from "@/components/MainArticle"
6+
import Translation from "@/components/Translation"
7+
import { Button } from "@/components/ui/buttons/Button"
8+
9+
export default function Error({
10+
error,
11+
reset,
12+
}: {
13+
error: Error
14+
reset: () => void
15+
}) {
16+
useEffect(() => {
17+
// TODO: log the error to an error reporting service
18+
console.error(error)
19+
}, [error])
20+
21+
return (
22+
<div className="mx-auto mb-0 mt-16 flex w-full flex-col items-center">
23+
<MainArticle className="my-8 w-full space-y-8 px-8 py-4">
24+
<h1>
25+
<Translation id="we-couldnt-find-that-page" />
26+
</h1>
27+
<p>Something went wrong.</p>
28+
<Button onClick={() => reset()}>Try again</Button>
29+
</MainArticle>
30+
</div>
31+
)
32+
}

0 commit comments

Comments
 (0)