Skip to content

Commit 3c127af

Browse files
authored
Agent course distribution on website (#5489)
1 parent 6da0b64 commit 3c127af

File tree

6 files changed

+612
-0
lines changed

6 files changed

+612
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"use client";
2+
3+
import { useState, FormEvent } from "react";
4+
import { Button } from "@/components/ui/button";
5+
import { Small } from "@/components/ui/typography";
6+
import { CheckCircle } from "lucide-react";
7+
8+
export default function AgentCourseForm({ source }: { source: string }) {
9+
const [email, setEmail] = useState("");
10+
const [isSubmitting, setIsSubmitting] = useState(false);
11+
const [submitStatus, setSubmitStatus] = useState<"idle" | "success" | "error">("idle");
12+
const [errorMessage, setErrorMessage] = useState("");
13+
14+
const isValidEmail = (email: string) => {
15+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
16+
return emailRegex.test(email);
17+
};
18+
19+
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
20+
e.preventDefault();
21+
22+
if (!email || !isValidEmail(email)) {
23+
setSubmitStatus("error");
24+
setErrorMessage("Please enter a valid email address");
25+
return;
26+
}
27+
28+
setIsSubmitting(true);
29+
setSubmitStatus("idle");
30+
setErrorMessage("");
31+
32+
try {
33+
const response = await fetch("/api/agent-course-signup", {
34+
method: "POST",
35+
headers: {
36+
"Content-Type": "application/json"
37+
},
38+
body: JSON.stringify({
39+
email,
40+
source
41+
})
42+
});
43+
44+
if (!response.ok) {
45+
throw new Error("Failed to register for the course");
46+
}
47+
48+
setSubmitStatus("success");
49+
setEmail("");
50+
} catch (error) {
51+
setSubmitStatus("error");
52+
setErrorMessage("Something went wrong. Please try again.");
53+
} finally {
54+
setIsSubmitting(false);
55+
}
56+
};
57+
58+
if (submitStatus === "success") {
59+
return (
60+
<div className="flex flex-col gap-4 items-center p-6 bg-green-50 border border-green-200 rounded-lg">
61+
<CheckCircle size={48} className="text-green-600" />
62+
<p className="text-green-800 font-medium">
63+
🎉 Welcome! Check your email for the first lesson.
64+
</p>
65+
</div>
66+
);
67+
}
68+
69+
return (
70+
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
71+
<input
72+
type="email"
73+
placeholder="Your email (you@example.com)"
74+
value={email}
75+
onChange={(e) => setEmail(e.target.value)}
76+
disabled={isSubmitting}
77+
className="w-full px-4 py-3 border border-border rounded-lg focus:ring-2 focus:ring-brand focus:border-transparent disabled:opacity-50"
78+
/>
79+
<Button
80+
size="landing_page"
81+
variant="landing_primary"
82+
type="submit"
83+
disabled={isSubmitting}
84+
>
85+
{isSubmitting ? "REGISTERING..." : source === "hero-section" ? "REGISTER TODAY" : "START BUILDING TODAY"}
86+
</Button>
87+
{submitStatus === "error" && (
88+
<Small className="text-red-600">{errorMessage}</Small>
89+
)}
90+
</form>
91+
);
92+
}
93+

bifrost/app/agent-course/page.tsx

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
import { Layout } from "@/app/components/Layout";
2+
import { H1, H2, H4, P, Lead, Small } from "@/components/ui/typography";
3+
import { Card, CardContent, CardHeader } from "@/components/ui/card";
4+
import { Calendar, Code, Zap } from "lucide-react";
5+
import AgentCourseForm from "./AgentCourseForm";
6+
import Image from "next/image";
7+
8+
export default function AgentCoursePage() {
9+
10+
return (
11+
<Layout>
12+
<main className="bg-white text-foreground">
13+
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
14+
<div className="text-center space-y-6 mb-16">
15+
<H1 className="text-center">
16+
From Engineer to AI Engineer in 7 days
17+
</H1>
18+
<Lead className="text-center max-w-2xl mx-auto">
19+
<strong>Complete stack:</strong> agents, MCP, monitoring, context,
20+
and deployment.
21+
</Lead>
22+
23+
<div className="text-center space-y-4">
24+
<div className="max-w-lg mx-auto">
25+
<AgentCourseForm source="hero-section" />
26+
</div>
27+
</div>
28+
</div>
29+
30+
<section id="course-overview" className="space-y-12 mb-16">
31+
<div className="text-center">
32+
<H2>What You&apos;ll Build</H2>
33+
<Lead className="text-muted-foreground mt-4 max-w-3xl mx-auto">
34+
An agent for Founder Engineers.
35+
</Lead>
36+
</div>
37+
38+
<div className="grid md:grid-cols-3 gap-6">
39+
<Card>
40+
<CardHeader>
41+
<div className="flex items-center gap-3">
42+
<Code size={20} className="text-brand" />
43+
<H4>Analyze a codebase</H4>
44+
</div>
45+
</CardHeader>
46+
<CardContent>
47+
<P className="text-muted-foreground">
48+
Analyze a codebase, commits, and README files from GitHub
49+
repositories using the GitHub API.
50+
</P>
51+
</CardContent>
52+
</Card>
53+
54+
<Card>
55+
<CardHeader>
56+
<div className="flex items-center gap-3">
57+
<Zap size={20} className="text-brand" />
58+
<H4>Generate content</H4>
59+
</div>
60+
</CardHeader>
61+
<CardContent>
62+
<P className="text-muted-foreground">
63+
AI agent decides what type of marketing content to create
64+
and generates drafts for your product.
65+
</P>
66+
</CardContent>
67+
</Card>
68+
69+
<Card>
70+
<CardHeader>
71+
<div className="flex items-center gap-3">
72+
<Calendar size={20} className="text-brand" />
73+
<H4>Automate posting</H4>
74+
</div>
75+
</CardHeader>
76+
<CardContent>
77+
<P className="text-muted-foreground">
78+
Run on a cron job to schedule weekly content drafts
79+
published via MCP.
80+
</P>
81+
</CardContent>
82+
</Card>
83+
</div>
84+
</section>
85+
86+
<section className="space-y-8 mb-16">
87+
<div className="text-center">
88+
<H2>7-Day Curriculum</H2>
89+
<P className="text-muted-foreground mt-4">
90+
Each day builds on the previous, with working code and hands-on
91+
tutorials.
92+
</P>
93+
</div>
94+
95+
<div className="space-y-4">
96+
{[
97+
{
98+
day: 1,
99+
title: "Setup & LLM Requests",
100+
description:
101+
"Agents vs workflows fundamentals, TypeScript setup, first LLM request"
102+
},
103+
{
104+
day: 2,
105+
title: "The Agent Loop",
106+
description:
107+
"Core agent architecture (Think → Act → Observe), GitHub API integration"
108+
},
109+
{
110+
day: 3,
111+
title: "Tool Calling & Actions",
112+
description:
113+
"OpenAI function calling, tool definitions and execution, content generation"
114+
},
115+
{
116+
day: 4,
117+
title: "Memory & Context Management",
118+
description:
119+
"Conversation history, context window management, token optimization"
120+
},
121+
{
122+
day: 5,
123+
title: "Connecting to MCP Servers",
124+
description:
125+
"Model Context Protocol, external tool integration, social media posting"
126+
},
127+
{
128+
day: 6,
129+
title: "Monitoring & Observability",
130+
description:
131+
"Performance metrics, cost tracking, debugging with Helicone"
132+
},
133+
{
134+
day: 7,
135+
title: "Production Deployment",
136+
description:
137+
"Vercel deployment, cron scheduling, environment configuration"
138+
}
139+
].map((lesson) => (
140+
<Card key={lesson.day} className="border-l-4 border-l-brand">
141+
<CardContent className="p-6">
142+
<div className="flex gap-4">
143+
<div className="flex-shrink-0">
144+
<div className="w-8 h-8 bg-brand text-white rounded-full flex items-center justify-center text-sm font-semibold">
145+
{lesson.day}
146+
</div>
147+
</div>
148+
<div className="space-y-1">
149+
<H4>
150+
Day {lesson.day}: {lesson.title}
151+
</H4>
152+
<P className="text-muted-foreground text-sm">
153+
{lesson.description}
154+
</P>
155+
</div>
156+
</div>
157+
</CardContent>
158+
</Card>
159+
))}
160+
</div>
161+
</section>
162+
163+
<section className="space-y-12 mb-16">
164+
<div className="text-center">
165+
<H2>Why Learn from Helicone?</H2>
166+
<Lead className="text-muted-foreground mt-4 max-w-3xl mx-auto">
167+
We&apos;ve spent years building the infrastructure that powers production AI agents at scale. Now we&apos;re sharing what we&apos;ve learned.
168+
</Lead>
169+
</div>
170+
171+
<div className="bg-gradient-to-br from-[#f2f9fc] to-white rounded-2xl p-8 md:p-12">
172+
<div className="grid md:grid-cols-3 gap-8 mb-12">
173+
<div className="text-center">
174+
<div className="text-4xl font-bold text-brand mb-2">4.9B+</div>
175+
<P className="text-muted-foreground">
176+
Requests Processed
177+
</P>
178+
</div>
179+
<div className="text-center">
180+
<div className="text-4xl font-bold text-brand mb-2">1.1T</div>
181+
<P className="text-muted-foreground">
182+
Tokens Per Month
183+
</P>
184+
</div>
185+
<div className="text-center">
186+
<div className="text-4xl font-bold text-brand mb-2">28.6M</div>
187+
<P className="text-muted-foreground">
188+
Users Tracked
189+
</P>
190+
</div>
191+
</div>
192+
193+
<div className="space-y-8">
194+
<Card className="border-l-4 border-l-brand bg-white">
195+
<CardContent className="p-6">
196+
<div className="flex flex-col gap-6">
197+
<blockquote className="text-lg md:text-xl text-muted-foreground italic">
198+
&ldquo;Helicone is{" "}
199+
<span className="text-foreground font-semibold not-italic">
200+
essential for debugging our complex agentic flows
201+
</span>{" "}
202+
for AI code reviews. Can&apos;t imagine building without it.&rdquo;
203+
</blockquote>
204+
<div className="flex items-center gap-4">
205+
<Image
206+
src="/static/home/logos/soohoon.webp"
207+
alt="Soohoon Choi"
208+
width={48}
209+
height={48}
210+
className="w-12 h-12 rounded-full"
211+
/>
212+
<div>
213+
<P className="font-semibold">Soohoon Choi</P>
214+
<Small className="text-muted-foreground">
215+
CTO, Greptile
216+
</Small>
217+
</div>
218+
<Image
219+
src="/static/greptile.webp"
220+
alt="Greptile"
221+
width={96}
222+
height={24}
223+
className="w-24 ml-auto"
224+
/>
225+
</div>
226+
</div>
227+
</CardContent>
228+
</Card>
229+
230+
<Card className="border-l-4 border-l-brand bg-white">
231+
<CardContent className="p-6">
232+
<div className="flex flex-col gap-6">
233+
<blockquote className="text-lg md:text-xl text-muted-foreground italic">
234+
&ldquo;The{" "}
235+
<span className="text-foreground font-semibold not-italic">
236+
most impactful one-line change
237+
</span>{" "}
238+
I&apos;ve seen applied to our codebase.&rdquo;
239+
</blockquote>
240+
<div className="flex items-center gap-4">
241+
<Image
242+
src="/static/home/nishantshukla.webp"
243+
alt="Nishant Shukla"
244+
width={48}
245+
height={48}
246+
className="w-12 h-12 rounded-full"
247+
/>
248+
<div>
249+
<P className="font-semibold">Nishant Shukla</P>
250+
<Small className="text-muted-foreground">
251+
Sr. Director of AI, QA Wolf
252+
</Small>
253+
</div>
254+
<Image
255+
src="/static/qawolf.webp"
256+
alt="QA Wolf"
257+
width={96}
258+
height={24}
259+
className="w-24 ml-auto"
260+
/>
261+
</div>
262+
</div>
263+
</CardContent>
264+
</Card>
265+
</div>
266+
</div>
267+
</section>
268+
269+
<section className="text-center bg-gray-50 rounded-xl p-8">
270+
<H2>Ready to Build Your First AI Agent?</H2>
271+
<P className="text-muted-foreground mt-4 mb-8">
272+
Join the course and start building production-ready AI agents
273+
today.
274+
</P>
275+
276+
<div className="max-w-lg mx-auto">
277+
<AgentCourseForm source="bottom-cta" />
278+
</div>
279+
</section>
280+
</div>
281+
</main>
282+
</Layout>
283+
);
284+
}

0 commit comments

Comments
 (0)