Skip to content

Commit 72bb52c

Browse files
feat: implement better landing page
1 parent b1c66f1 commit 72bb52c

File tree

13 files changed

+498
-28
lines changed

13 files changed

+498
-28
lines changed

index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
name="viewport"
88
content="width=device-width, initial-scale=1.0"
99
/>
10+
<meta
11+
name="description"
12+
content="Master React design patterns through interactive Pokemon-themed exercises. Learn advanced patterns from fundamentals to expert-level techniques with hands-on examples."
13+
/>
1014
<title>React Design Patterns</title>
1115
</head>
1216
<body>

src/App.tsx

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
11
import { Analytics } from '@vercel/analytics/react';
2+
import { LandingPage } from './app/LandingPage';
23

34
const App = () => {
45
return (
56
<>
6-
<main className="flex flex-col items-center justify-center bg-code-950 h-screen text-center text-white px-4">
7-
<h1 className="font-semibold text-4xl md:text-6xl mb-6">
8-
⚛️ React Design Patterns
9-
</h1>
10-
<p className="text-lg mb-8 max-w-2xl">
11-
Welcome to React Design Patterns 👋🏻! <br /> <br /> This
12-
course educates developers on best practices for writing
13-
React components, utilizing patterns and providing practical
14-
guides with real-world examples.
15-
</p>
16-
<a
17-
href="/storybook"
18-
className="middle none center rounded-lg bg-code-600 py-3 px-8 font-sans text-base font-semibold text-white shadow-md shadow-code-600/20 transition-all hover:shadow-lg hover:shadow-code-600/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
19-
>
20-
Get started
21-
</a>
22-
<p className="text-sm mt-8">
23-
Made with ❤️ by Matt Claffey{' '}
24-
<a
25-
href="https://github.com/code-mattclaffey"
26-
target="_blank"
27-
rel="noreferrer"
28-
className="underline-offset-1 underline font-semibold"
29-
>
30-
@code-mattclaffey
31-
</a>
32-
</p>
33-
</main>
7+
<LandingPage />
348
<Analytics />
359
</>
3610
);

src/app/LandingPage.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Header } from './components/Header';
2+
import { Hero } from './components/Hero';
3+
import { CourseStructure } from './components/CourseStructure';
4+
import { CallToAction } from './components/CallToAction';
5+
import { Footer } from './components/Footer';
6+
import { Features } from './components/Features';
7+
8+
export const LandingPage = () => {
9+
return (
10+
<div className="min-h-screen">
11+
<Header />
12+
<Hero />
13+
<Features />
14+
<CourseStructure />
15+
<CallToAction />
16+
<Footer />
17+
</div>
18+
);
19+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
export const CallToAction = () => {
2+
return (
3+
<section className="py-24 bg-blue-950">
4+
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
5+
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-bold text-white mb-6 leading-tight">
6+
Ready to Master React Patterns?
7+
</h2>
8+
<p className="text-lg sm:text-xl text-blue-200 mb-8 max-w-2xl mx-auto font-medium leading-relaxed">
9+
Join thousands of developers who have leveled up their React skills with our interactive course.
10+
</p>
11+
12+
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center mb-12">
13+
<a href="/storybook" className="px-8 py-4 bg-blue-600 text-white font-semibold rounded-lg text-lg hover:bg-blue-700 focus:outline-none focus:ring-4 focus:ring-blue-500/50 transition-colors duration-200">
14+
Start Learning Now
15+
</a>
16+
17+
<a href="https://github.com/code-mattclaffey/react-design-patterns" target="_blank" rel="noreferrer" className="px-8 py-4 border-2 border-blue-800 text-white font-semibold rounded-lg text-lg hover:border-blue-700 hover:bg-blue-900 focus:outline-none focus:ring-4 focus:ring-blue-500/50 transition-colors duration-200">
18+
View Course Content
19+
</a>
20+
</div>
21+
22+
<div className="grid sm:grid-cols-3 gap-8 text-center">
23+
<div>
24+
<div className="text-3xl font-bold text-blue-400 mb-2">15+</div>
25+
<div className="text-blue-200 font-medium">Design Patterns</div>
26+
</div>
27+
<div>
28+
<div className="text-3xl font-bold text-blue-400 mb-2">50+</div>
29+
<div className="text-blue-200 font-medium">Interactive Examples</div>
30+
</div>
31+
<div>
32+
<div className="text-3xl font-bold text-blue-400 mb-2">100%</div>
33+
<div className="text-blue-200 font-medium">Free & Open Source</div>
34+
</div>
35+
</div>
36+
</div>
37+
</section>
38+
);
39+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { courseLevels } from '../content';
2+
3+
export const CourseStructure = () => {
4+
return (
5+
<section className="py-24 bg-slate-50">
6+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
7+
<div className="text-center mb-16">
8+
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-bold text-slate-900 mb-4 leading-tight">
9+
Progressive Learning Path
10+
</h2>
11+
<p className="text-lg sm:text-xl text-slate-700 max-w-3xl mx-auto font-medium leading-relaxed">
12+
Master React patterns step by step, from fundamental concepts to advanced techniques
13+
</p>
14+
</div>
15+
16+
<div className="grid lg:grid-cols-3 gap-8">
17+
{courseLevels.map((level, index) => (
18+
<div
19+
key={level.title}
20+
className="relative bg-blue-900 border-blue-800 border-2 rounded-2xl p-8 shadow-sm hover:shadow-lg transition-all duration-300"
21+
>
22+
<div className="text-center mb-6">
23+
<div className="w-20 h-20 bg-blue-800 rounded-2xl flex items-center justify-center shadow-sm mx-auto mb-4">
24+
<span className="text-3xl">{level.emoji}</span>
25+
</div>
26+
<h3 className="text-2xl font-bold text-white mb-2">
27+
{level.title}
28+
</h3>
29+
<p className="text-blue-300 font-semibold">{level.subtitle}</p>
30+
</div>
31+
32+
<ul className="space-y-3">
33+
{level.patterns.map((pattern) => (
34+
<li key={pattern} className="flex items-center text-blue-200">
35+
<div className="w-2 h-2 bg-blue-400 rounded-full mr-3 flex-shrink-0"></div>
36+
<span className="text-base font-medium">{pattern}</span>
37+
</li>
38+
))}
39+
</ul>
40+
41+
<div className="absolute top-6 right-6 w-8 h-8 bg-blue-800 rounded-full flex items-center justify-center">
42+
<span className="text-blue-300 font-bold text-sm">
43+
{String(index + 1).padStart(2, '0')}
44+
</span>
45+
</div>
46+
</div>
47+
))}
48+
</div>
49+
</div>
50+
</section>
51+
);
52+
};

src/app/components/Features.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { features } from '../content';
2+
3+
export const Features = () => {
4+
return (
5+
<section className="py-24 bg-slate-50">
6+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
7+
<div className="text-center mb-16">
8+
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-bold text-slate-900 mb-4 leading-tight">
9+
Why This Course?
10+
</h2>
11+
<p className="text-lg sm:text-xl text-slate-700 max-w-3xl mx-auto font-medium leading-relaxed">
12+
Learn React design patterns the right way with interactive examples and real-world context
13+
</p>
14+
</div>
15+
16+
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
17+
{features.map((feature) => (
18+
<div
19+
key={feature.title}
20+
className="group p-8 rounded-xl border border-slate-200 hover:border-slate-300 hover:shadow-md transition-all duration-200 bg-white"
21+
>
22+
<div className="text-4xl mb-4">
23+
{feature.icon}
24+
</div>
25+
<h3 className="text-xl font-bold text-slate-900 mb-3">
26+
{feature.title}
27+
</h3>
28+
<p className="text-slate-700 leading-relaxed font-medium">
29+
{feature.description}
30+
</p>
31+
</div>
32+
))}
33+
</div>
34+
</div>
35+
</section>
36+
);
37+
};

src/app/components/Footer.tsx

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
export const Footer = () => {
2+
return (
3+
<>
4+
<footer className="bg-blue-950 text-blue-300 py-12">
5+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
6+
<div className="border-t border-blue-800 mb-4"></div>
7+
<div className="grid md:grid-cols-3 gap-8">
8+
<div className="md:col-span-2">
9+
<div className="flex items-center space-x-3 mb-4">
10+
<div className="text-2xl">⚛️</div>
11+
<div className="text-xl font-bold text-white">
12+
React Design Patterns
13+
</div>
14+
</div>
15+
<p className="text-blue-200 mb-4 max-w-md">
16+
Master React design patterns through interactive
17+
Pokemon-themed exercises. From fundamentals to
18+
advanced techniques.
19+
</p>
20+
<div className="flex space-x-4">
21+
<a
22+
href="https://github.com/code-mattclaffey/react-design-patterns"
23+
className="text-blue-200 hover:text-white transition-colors duration-200"
24+
target="_blank"
25+
rel="noreferrer"
26+
aria-label="View React Design Patterns on GitHub"
27+
>
28+
<svg
29+
className="w-6 h-6"
30+
fill="currentColor"
31+
viewBox="0 0 24 24"
32+
>
33+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
34+
</svg>
35+
</a>
36+
</div>
37+
</div>
38+
39+
<div>
40+
<h3 className="text-white font-semibold mb-4">
41+
Course
42+
</h3>
43+
<ul className="space-y-2">
44+
<li>
45+
<a
46+
href="/storybook?path=/docs/introduction-01-welcome--docs"
47+
className="text-blue-200 hover:text-white transition-colors duration-200"
48+
>
49+
Bronze Level
50+
</a>
51+
</li>
52+
<li>
53+
<a
54+
href="/storybook?path=/docs/introduction-01-welcome--docs"
55+
className="text-blue-200 hover:text-white transition-colors duration-200"
56+
>
57+
Silver Level
58+
</a>
59+
</li>
60+
<li>
61+
<a
62+
href="/storybook?path=/docs/introduction-01-welcome--docs"
63+
className="text-blue-200 hover:text-white transition-colors duration-200"
64+
>
65+
Gold Level
66+
</a>
67+
</li>
68+
<li>
69+
<a
70+
href="/storybook?path=/docs/introduction-01-welcome--docs"
71+
className="text-blue-200 hover:text-white transition-colors duration-200"
72+
>
73+
All Patterns
74+
</a>
75+
</li>
76+
</ul>
77+
</div>
78+
</div>
79+
80+
<div className="border-t border-blue-800 mt-8 pt-8 text-center text-blue-200">
81+
<p>
82+
Made with ❤️ by{' '}
83+
<a
84+
href="https://github.com/code-mattclaffey"
85+
target="_blank"
86+
rel="noreferrer"
87+
className="underline-offset-1 underline font-semibold hover:text-white transition-colors duration-200"
88+
>
89+
@code-mattclaffey
90+
</a>
91+
</p>
92+
</div>
93+
</div>
94+
</footer>
95+
</>
96+
);
97+
};

src/app/components/Header.tsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { useState } from 'react';
2+
3+
export const Header = () => {
4+
const [isMenuOpen, setIsMenuOpen] = useState(false);
5+
6+
return (
7+
<header className="absolute top-0 left-0 right-0 z-50">
8+
<nav className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
9+
<div className="flex items-center justify-between">
10+
<div className="flex items-center space-x-3">
11+
<div className="text-2xl">⚛️</div>
12+
<div className="text-xl font-bold text-white">
13+
React Design Patterns
14+
</div>
15+
</div>
16+
17+
<div className="hidden md:flex items-center space-x-8">
18+
<a
19+
href="#course"
20+
className="text-slate-300 hover:text-white transition-colors duration-200"
21+
>
22+
Course
23+
</a>
24+
<a
25+
href="https://github.com/code-mattclaffey/react-design-patterns"
26+
target="_blank"
27+
rel="noopener noreferrer"
28+
className="text-slate-300 hover:text-white transition-colors duration-200"
29+
>
30+
GitHub
31+
</a>
32+
<a
33+
href="/storybook"
34+
className="px-4 py-2 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-4 focus:ring-blue-500/50 transition-colors duration-200"
35+
>
36+
Get Started
37+
</a>
38+
</div>
39+
40+
<button
41+
className="md:hidden text-white"
42+
aria-label={isMenuOpen ? 'Close navigation menu' : 'Open navigation menu'}
43+
aria-expanded={isMenuOpen}
44+
onClick={() => setIsMenuOpen(!isMenuOpen)}
45+
>
46+
<svg
47+
className="w-6 h-6"
48+
fill="none"
49+
stroke="currentColor"
50+
viewBox="0 0 24 24"
51+
>
52+
<path
53+
strokeLinecap="round"
54+
strokeLinejoin="round"
55+
strokeWidth={2}
56+
d={isMenuOpen ? "M6 18L18 6M6 6l12 12" : "M4 6h16M4 12h16M4 18h16"}
57+
/>
58+
</svg>
59+
</button>
60+
</div>
61+
62+
{isMenuOpen && (
63+
<div className="md:hidden mt-4 pb-4 border-t border-blue-800">
64+
<div className="flex flex-col space-y-4 pt-4">
65+
<a
66+
href="#course"
67+
className="text-slate-300 hover:text-white transition-colors duration-200"
68+
onClick={() => setIsMenuOpen(false)}
69+
>
70+
Course
71+
</a>
72+
<a
73+
href="https://github.com/code-mattclaffey/react-design-patterns"
74+
target="_blank"
75+
rel="noopener noreferrer"
76+
className="text-slate-300 hover:text-white transition-colors duration-200"
77+
onClick={() => setIsMenuOpen(false)}
78+
>
79+
GitHub
80+
</a>
81+
<a
82+
href="/storybook"
83+
className="px-4 py-2 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-4 focus:ring-blue-500/50 transition-colors duration-200 text-center"
84+
onClick={() => setIsMenuOpen(false)}
85+
>
86+
Get Started
87+
</a>
88+
</div>
89+
</div>
90+
)}
91+
</nav>
92+
</header>
93+
);
94+
};

0 commit comments

Comments
 (0)