Skip to content

Commit 40e8027

Browse files
committed
Merge remote-tracking branch 'origin/master' into Staging_badges
2 parents 5654ba8 + f3e6e4d commit 40e8027

File tree

1,192 files changed

+39601
-13395
lines changed

Some content is hidden

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

1,192 files changed

+39601
-13395
lines changed

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ package-lock.json
144144

145145

146146

147+
148+
149+
147150
# Remote content output paths
148151
content/docs/acps/103-dynamic-fees.mdx
149152
content/docs/acps/108-evm-event-importing.mdx
@@ -186,10 +189,10 @@ content/docs/cross-chain/teleporter/cli.mdx
186189
content/docs/cross-chain/teleporter/deep-dive.mdx
187190
content/docs/cross-chain/teleporter/overview.mdx
188191
content/docs/cross-chain/teleporter/upgradeability.mdx
189-
content/docs/nodes/chain-configs/c-chain.mdx
190-
content/docs/nodes/chain-configs/p-chain.mdx
192+
content/docs/nodes/chain-configs/primary-network/c-chain.mdx
193+
content/docs/nodes/chain-configs/primary-network/p-chain.mdx
194+
content/docs/nodes/chain-configs/primary-network/x-chain.mdx
191195
content/docs/nodes/chain-configs/subnet-evm.mdx
192-
content/docs/nodes/chain-configs/x-chain.mdx
193196
content/docs/nodes/configure/avalanche-l1-configs.mdx
194197
content/docs/nodes/configure/configs-flags.mdx
195198
content/docs/rpcs/c-chain/index.mdx

app/(home)/academy/avalanche-developer.config.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { AcademyLandingPageConfig } from '@/components/academy/shared/academy-types';
2+
3+
export const avalancheDeveloperAcademyLandingPageConfig: AcademyLandingPageConfig = {
4+
id: 'academy-avalanche-l1',
5+
name: 'Avalanche L1 Academy',
6+
heroTitle: 'Avalanche',
7+
heroAccent: 'L1',
8+
heroAccentWords: ['L1 Developer', 'Blockchain', 'Entrepreneur'],
9+
heroDescription: 'Learn through our Avalanche L1, Blockchain and Entrepreneur Academies. Use the navigation buttons below to switch between academies and discover each learning tree with courses tailored to your journey.',
10+
pathType: 'avalanche',
11+
showBlogs: true,
12+
};
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import type { Metadata } from "next";
2+
import Link from "next/link";
3+
import { BookOpen, ArrowRight, ExternalLink } from "lucide-react";
4+
import { createMetadata } from "@/utils/metadata";
5+
import { blog } from "@/lib/source";
6+
import { AcademyLayout } from "@/components/academy/shared/academy-layout";
7+
import { avalancheDeveloperAcademyLandingPageConfig } from "./config";
8+
import { entrepreneurAcademyLandingPageConfig } from "../entrepreneur/config";
9+
import type { AcademyPathType } from "@/components/academy/shared/academy-types";
10+
import { Suspense } from "react";
11+
12+
export const metadata: Metadata = createMetadata({
13+
title: "Avalanche L1 Academy",
14+
description:
15+
"Learn Avalanche L1 development with courses designed for builders launching custom blockchains",
16+
openGraph: {
17+
url: "/academy/avalanche-l1",
18+
images: {
19+
url: "/api/og/academy",
20+
width: 1200,
21+
height: 630,
22+
alt: "Avalanche L1 Academy",
23+
},
24+
},
25+
twitter: {
26+
images: {
27+
url: "/api/og/academy",
28+
width: 1200,
29+
height: 630,
30+
alt: "Avalanche L1 Academy",
31+
},
32+
},
33+
});
34+
35+
type PageProps = {
36+
searchParams?: {
37+
path?: string;
38+
};
39+
};
40+
41+
const isPathType = (value: string | undefined): value is AcademyPathType => {
42+
return value === "avalanche" || value === "blockchain" || value === "entrepreneur";
43+
};
44+
45+
export default function AvalancheAcademyPage({ searchParams }: PageProps): React.ReactElement {
46+
// Get all guides server-side
47+
const blogPages = [...blog.getPages()]
48+
.sort(
49+
(a, b) =>
50+
new Date((b.data.date as string) ?? b.url).getTime() -
51+
new Date((a.data.date as string) ?? a.url).getTime()
52+
)
53+
.slice(0, 9); // Limit to 9 guides
54+
55+
// Serialize blog data to pass to client component
56+
const blogs = blogPages.map((page) => ({
57+
url: page.url,
58+
data: {
59+
title: page.data.title || "Untitled",
60+
description: page.data.description || "",
61+
topics: (page.data.topics as string[]) || [],
62+
date:
63+
page.data.date instanceof Date
64+
? page.data.date.toISOString()
65+
: (page.data.date as string) || "",
66+
},
67+
file: {
68+
name: page.url, // Use URL instead of file.name in v16
69+
},
70+
}));
71+
72+
const { features } = entrepreneurAcademyLandingPageConfig;
73+
74+
const entrepreneurBlogsFromConfig = (features?.highlights?.blogs ?? []).map((blogEntry) => ({
75+
url: blogEntry.link,
76+
data: {
77+
title: blogEntry.title,
78+
description: blogEntry.description,
79+
topics: ['Entrepreneur'],
80+
date: blogEntry.date || '',
81+
},
82+
file: {
83+
name: blogEntry.id,
84+
},
85+
}));
86+
87+
const entrepreneurHighlights = features?.highlights ? (
88+
<div className="mb-16">
89+
<div className="flex items-center gap-3 mb-8">
90+
<BookOpen className="h-6 w-6 text-red-600" />
91+
<h2 className="text-2xl font-bold text-zinc-900 dark:text-white">
92+
{features.highlights.title}
93+
</h2>
94+
</div>
95+
96+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
97+
{features.highlights.blogs.map((blog) => (
98+
<Link
99+
key={blog.id}
100+
href={blog.link}
101+
target="_blank"
102+
rel="noopener noreferrer"
103+
className="group relative flex flex-col rounded-xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 p-6 hover:shadow-lg transition-all duration-200 cursor-pointer"
104+
>
105+
<div className="flex items-start justify-between mb-4">
106+
<h3 className="font-semibold text-lg text-zinc-900 dark:text-white group-hover:text-red-600 dark:group-hover:text-red-500 transition-colors pr-4">
107+
{blog.title}
108+
</h3>
109+
<ExternalLink className="h-5 w-5 text-zinc-400 group-hover:text-red-600 transition-colors flex-shrink-0" />
110+
</div>
111+
112+
{blog.date && (
113+
<p className="text-sm text-zinc-500 dark:text-zinc-400 mb-3">
114+
{blog.date}
115+
</p>
116+
)}
117+
118+
<p className="text-sm text-zinc-600 dark:text-zinc-400 flex-grow">
119+
{blog.description}
120+
</p>
121+
122+
<div className="mt-4 inline-flex items-center gap-1 text-sm font-medium text-red-600 group-hover:text-red-700 dark:text-red-500 dark:hover:text-red-400">
123+
Read article
124+
<ArrowRight className="h-4 w-4" />
125+
</div>
126+
</Link>
127+
))}
128+
</div>
129+
</div>
130+
) : null;
131+
132+
const initialPathType = isPathType(searchParams?.path) ? searchParams?.path : undefined;
133+
134+
return (
135+
<Suspense fallback={<div className="min-h-screen flex items-center justify-center"><div className="text-zinc-600 dark:text-zinc-400">Loading...</div></div>}>
136+
<AcademyLayout
137+
config={avalancheDeveloperAcademyLandingPageConfig}
138+
blogs={blogs}
139+
blogsByPath={{
140+
avalanche: blogs,
141+
blockchain: blogs,
142+
entrepreneur: entrepreneurBlogsFromConfig.length > 0 ? entrepreneurBlogsFromConfig : blogs,
143+
}}
144+
afterLearningPathByPath={{
145+
entrepreneur: entrepreneurHighlights,
146+
}}
147+
initialPathType={initialPathType}
148+
/>
149+
</Suspense>
150+
);
151+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { AcademyLandingPageConfig } from '@/components/academy/shared/academy-types';
2+
3+
export const blockchainAcademyLandingPageConfig: AcademyLandingPageConfig = {
4+
id: 'academy-blockchain',
5+
name: 'Blockchain Academy',
6+
heroTitle: 'Blockchain',
7+
heroAccent: 'Developer',
8+
heroAccentWords: ['Developer', 'Smart Contracts', 'Privacy'],
9+
heroDescription: 'Start your blockchain development journey from the ground up. Master the fundamentals of blockchain technology, learn Solidity programming, and explore privacy-enhancing technologies to build secure and innovative decentralized applications.',
10+
pathType: 'blockchain',
11+
showBlogs: true,
12+
};
13+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import type { Metadata } from "next";
2+
import { createMetadata } from "@/utils/metadata";
3+
import { blog } from "@/lib/source";
4+
import { AcademyLayout } from "@/components/academy/shared/academy-layout";
5+
import { blockchainAcademyLandingPageConfig } from "./config";
6+
import { Suspense } from "react";
7+
8+
export const metadata: Metadata = createMetadata({
9+
title: "Blockchain Academy",
10+
description:
11+
"Master blockchain fundamentals and smart contract development from the ground up",
12+
openGraph: {
13+
url: "/academy/blockchain",
14+
images: {
15+
url: "/api/og/academy",
16+
width: 1200,
17+
height: 630,
18+
alt: "Blockchain Academy",
19+
},
20+
},
21+
twitter: {
22+
images: {
23+
url: "/api/og/academy",
24+
width: 1200,
25+
height: 630,
26+
alt: "Blockchain Academy",
27+
},
28+
},
29+
});
30+
31+
export default function BlockchainAcademyPage(): React.ReactElement {
32+
// Get all guides server-side
33+
const blogPages = [...blog.getPages()]
34+
.sort(
35+
(a, b) =>
36+
new Date((b.data.date as string) ?? b.url).getTime() -
37+
new Date((a.data.date as string) ?? a.url).getTime()
38+
)
39+
.slice(0, 9); // Limit to 9 guides
40+
41+
// Serialize blog data to pass to client component
42+
const blogs = blogPages.map((page) => ({
43+
url: page.url,
44+
data: {
45+
title: page.data.title || "Untitled",
46+
description: page.data.description || "",
47+
topics: (page.data.topics as string[]) || [],
48+
date:
49+
page.data.date instanceof Date
50+
? page.data.date.toISOString()
51+
: (page.data.date as string) || "",
52+
},
53+
file: {
54+
name: page.url, // Use URL instead of file.name in v16
55+
},
56+
}));
57+
58+
return (
59+
<Suspense fallback={<div className="min-h-screen flex items-center justify-center"><div className="text-zinc-600 dark:text-zinc-400">Loading...</div></div>}>
60+
<AcademyLayout
61+
config={blockchainAcademyLandingPageConfig}
62+
blogs={blogs}
63+
blogsByPath={{
64+
avalanche: blogs,
65+
blockchain: blogs,
66+
entrepreneur: blogs,
67+
}}
68+
/>
69+
</Suspense>
70+
);
71+
}
72+
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import type { AcademyLandingPageConfig } from '@/components/academy/shared/academy-types';
22

3-
export const codebaseEntrepreneurLandingPageConfig: AcademyLandingPageConfig = {
4-
id: 'codebase-entrepreneur',
5-
name: 'Codebase Entrepreneur Academy',
6-
heroTitle: 'Codebase',
3+
export const entrepreneurAcademyLandingPageConfig: AcademyLandingPageConfig = {
4+
id: 'academy-entrepreneur',
5+
name: 'Entrepreneur Academy',
6+
heroTitle: 'Avalanche',
77
heroAccent: 'Entrepreneur',
8+
heroAccentWords: ['Entrepreneur', 'Founder', 'Builder'],
89
heroDescription: 'Join the next generation of Web3 entrepreneurs. Learn how to build, launch, and scale your blockchain startup with guidance from industry experts and successful founders.',
910
pathType: 'entrepreneur',
10-
showBlogs: false,
11+
showBlogs: true,
1112
features: {
12-
codebaseBlogs: {
13-
title: 'Codebase Blogs',
13+
highlights: {
14+
title: 'Entrepreneur Highlights',
1415
blogs: [
1516
{
1617
id: 'suzaku-raises-1-5m',

0 commit comments

Comments
 (0)