Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 29 additions & 0 deletions src/pages/Home.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
import { describe, expect, it, vi } from "vitest"
import { MemoryRouter } from "react-router-dom"
import Home from "./Home"
import { render, screen } from "../test/setup"

vi.mock("@stellar/design-system", () => ({
Icon: {
Lightbulb01: () => null,
Trophy01: () => null,
Star01: () => null,
Users01: () => null,
},
}))

vi.mock("../hooks/useCourses", () => ({
useEnrolledCourses: () => ({
enrolledCourses: [],
isLoading: false,
}),
}))

describe("Home", () => {
it("renders scholarship alumni spotlight content", () => {
import userEvent from "@testing-library/user-event"
import { MemoryRouter } from "react-router-dom"
import { render, screen } from "../test/setup"
Expand Down Expand Up @@ -72,6 +94,13 @@ describe("Home page", () => {
</MemoryRouter>,
)

expect(
screen.getByRole("heading", { name: "Scholarship Alumni Spotlight" }),
).toBeInTheDocument()
expect(screen.getByText("Amina Diallo")).toBeInTheDocument()
expect(screen.getByText("Diego Alvarez")).toBeInTheDocument()
expect(screen.getByText("Grace Mwangi")).toBeInTheDocument()
expect(screen.getAllByText(/Class of 2025/i)).toHaveLength(2)
expect(screen.getByRole("heading", { name: /Learning is the proof of work/i })).toBeInTheDocument()
expect(screen.getByRole("heading", { name: /How It Works/i })).toBeInTheDocument()
expect(screen.getByRole("heading", { name: /What You Get/i })).toBeInTheDocument()
Expand Down
90 changes: 89 additions & 1 deletion src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ const FEATURES = [
},
]

const ALUMNI_SPOTLIGHT = [
{
name: "Amina Diallo",
cohort: "Backend Engineering Cohort",
year: "2025",
scholarshipAmount: "4,000 USDC",
outcome: "Now shipping smart contract audits at an African fintech startup.",
quote:
"The milestone-based scholarship made me accountable and gave me runway to focus on mastery.",
},
{
name: "Diego Alvarez",
cohort: "Frontend Product Cohort",
year: "2025",
scholarshipAmount: "3,200 USDC",
outcome: "Built an open-source design system now used by three community DAOs.",
quote:
"LearnVault turned my portfolio into verified on-chain proof that employers trusted instantly.",
},
{
name: "Grace Mwangi",
cohort: "Data + AI Cohort",
year: "2024",
scholarshipAmount: "5,100 USDC",
outcome: "Leading analytics automation for a public health nonprofit.",
quote:
"The alumni network and DAO mentors gave me feedback loops I couldn't get anywhere else.",
},
]

const Home: React.FC = () => {
const { enrolledCourses, isLoading: isLoadingCourses } = useEnrolledCourses()
const { address } = useWallet()
Expand Down Expand Up @@ -278,8 +308,66 @@ const Home: React.FC = () => {
</div>
</section>

{/* ── SCHOLARSHIP ALUMNI SPOTLIGHT ────────────────────────────── */}
<section className="flex flex-col gap-10 animate-in fade-in slide-in-from-bottom-6 duration-700 delay-500">
<div className="flex items-center gap-3">
<Icon.Users01 size="lg" className="text-brand-cyan shrink-0" />
<div>
<h2 className="text-2xl font-black">Scholarship Alumni Spotlight</h2>
<p className="text-white/45 text-sm mt-1 max-w-2xl">
Stories from scholars who completed tracks, secured milestone funding,
and are now building real-world impact.
</p>
</div>
</div>

<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{ALUMNI_SPOTLIGHT.map(
({
name,
cohort,
year,
scholarshipAmount,
outcome,
quote,
}) => (
<article
key={name}
className="glass-card rounded-3xl border border-white/10 p-7 flex flex-col gap-6 hover:border-brand-cyan/30 transition-colors"
>
<div className="flex items-center justify-between gap-4">
<div>
<h3 className="text-lg font-black">{name}</h3>
<p className="text-xs text-white/45 uppercase tracking-widest mt-1">
{cohort}
</p>
</div>
<span className="text-xs font-bold px-3 py-1 rounded-full border border-brand-cyan/40 text-brand-cyan bg-brand-cyan/10">
Class of {year}
</span>
</div>

<blockquote className="text-sm leading-relaxed text-white/75 italic">
“{quote}”
</blockquote>

<div className="space-y-2 text-sm">
<p className="text-white/55">
<span className="text-white/75 font-semibold">Scholarship:</span>{" "}
{scholarshipAmount}
</p>
<p className="text-white/55">
<span className="text-white/75 font-semibold">Outcome:</span> {outcome}
</p>
</div>
</article>
),
)}
</div>
</section>

{/* ── CTA BANNER ───────────────────────────────────────────────── */}
<section className="glass-card rounded-3xl border border-brand-cyan/15 p-10 text-center flex flex-col items-center gap-6 animate-in fade-in duration-700 delay-500">
<section className="glass-card rounded-3xl border border-brand-cyan/15 p-10 text-center flex flex-col items-center gap-6 animate-in fade-in duration-700 delay-[600ms]">
<h2 className="text-2xl font-black">Join the open-source sprint</h2>
<p className="text-white/40 max-w-md text-sm leading-relaxed">
LearnVault is built in the open. Pick an issue, ship a feature, and
Expand Down