-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(bootcamp): adding entire landing page with ugly styles
- Loading branch information
1 parent
dc70eef
commit fe0a25b
Showing
14 changed files
with
642 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import {FC} from 'react' | ||
|
||
export const GridBackground: FC = () => ( | ||
<div className="absolute inset-0 bg-[linear-gradient(to_right,#ffffff06_1px,transparent_1px),linear-gradient(to_bottom,#ffffff06_1px,transparent_1px)] bg-[size:64px_64px]" /> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
'use client' | ||
import {motion} from 'framer-motion' | ||
import {fadeInUp} from './animations' | ||
|
||
export default function Conclusion() { | ||
return ( | ||
<section className="py-32 relative"> | ||
<div className="container mx-auto px-4 text-center relative z-10"> | ||
<motion.div {...fadeInUp} className="max-w-3xl mx-auto"> | ||
<h2 className="mb-4 text-3xl font-bold text-center text-white"> | ||
Ready to Join Our AI Mastery Bootcamp? | ||
</h2> | ||
<p className="mb-8 text-center text-gray-400 mx-auto"> | ||
Secure your spot in this unique, 20-day immersive training | ||
experience. You'll learn alongside a focused cohort of | ||
developers, all committed to mastering practical AI implementation. | ||
Enter your email below to be first in line when registration opens | ||
for our next intensive. | ||
</p> | ||
</motion.div> | ||
</div> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
'use client' | ||
import {motion} from 'framer-motion' | ||
import {Cpu, Database, Users, Calendar, Shield, Cloud} from 'lucide-react' | ||
import {fadeInUp, staggerContainer, staggerItem} from './animations' | ||
|
||
const features = [ | ||
{ | ||
id: 'ai-integration', | ||
title: 'Practical AI Integration', | ||
description: | ||
'Quickly integrate AI capabilities into new or existing applications using modern frameworks and tools.', | ||
icon: Cpu, | ||
}, | ||
{ | ||
id: 'data-handling', | ||
title: 'Intelligent Data Handling', | ||
description: | ||
'Implement vector search and semantic querying to give your users quick, context-aware answers—no matter the data set.', | ||
icon: Database, | ||
}, | ||
{ | ||
id: 'multi-agent', | ||
title: 'Multi-Agent Systems', | ||
description: | ||
'Build specialized agents (e.g., for support, data analysis, or automation) that work in tandem to serve different business needs.', | ||
icon: Users, | ||
}, | ||
{ | ||
id: 'accountability', | ||
title: 'Daily Accountability', | ||
description: | ||
'Participate in 1-hour live workshop sessions plus evening assignments, ensuring steady progress. Get real-time feedback from John and fellow participants in a shared cohort environment.', | ||
icon: Calendar, | ||
}, | ||
{ | ||
id: 'security', | ||
title: 'Testing & Security', | ||
description: | ||
'Learn best practices for automated testing of AI outputs and safeguarding sensitive data. Keep your enterprise environment secure and compliant.', | ||
icon: Shield, | ||
}, | ||
{ | ||
id: 'deployment', | ||
title: 'Production-Ready Deployment', | ||
description: | ||
'Deploy your AI-driven solutions confidently—either to a cloud platform or Docker environment—with built-in logging and analytics for ongoing improvements.', | ||
icon: Cloud, | ||
}, | ||
] | ||
|
||
export default function Features() { | ||
return ( | ||
<section className="py-32 relative"> | ||
<div className="container mx-auto px-4 relative z-10"> | ||
<motion.h2 | ||
{...fadeInUp} | ||
className="mb-16 text-3xl font-bold text-center text-white" | ||
> | ||
What You'll Learn | ||
</motion.h2> | ||
<motion.div | ||
variants={staggerContainer} | ||
initial="hidden" | ||
whileInView="show" | ||
viewport={{once: true}} | ||
className="grid gap-8 md:grid-cols-2 lg:grid-cols-3" | ||
> | ||
{features.map((feature) => { | ||
const Icon = feature.icon | ||
return ( | ||
<motion.div | ||
key={feature.id} | ||
variants={staggerItem} | ||
className="group relative bg-white dark:bg-gray-800 border-2 border-gray-200 dark:border-gray-800 rounded-lg p-6 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors drop-shadow-lg" | ||
> | ||
<div className="relative"> | ||
<div className="inline-flex items-center justify-center w-12 h-12 mb-4"> | ||
<Icon className="w-6 h-6 text-[var(--accent-9)]" /> | ||
</div> | ||
<h3 className="text-lg font-semibold text-white mb-2"> | ||
{feature.title} | ||
</h3> | ||
<p className="text-gray-400">{feature.description}</p> | ||
</div> | ||
</motion.div> | ||
) | ||
})} | ||
</motion.div> | ||
</div> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
'use client' | ||
import Link from 'next/link' | ||
import {motion, AnimatePresence} from 'framer-motion' | ||
import {fadeInUp, scaleIn} from './animations' | ||
import {useState, useEffect} from 'react' | ||
import '../styles.css' | ||
|
||
const phrases = [ | ||
'Level Up Your Skills With', | ||
'Join Our AI Deep Dive Using', | ||
'Master Real-World Apps With', | ||
'Transform Projects Using', | ||
'Start Your AI Journey With', | ||
'Join Our Hands-On Lab Using', | ||
'Build Production Apps With', | ||
'Power Your Future Using', | ||
] | ||
|
||
const AnimatedPhrase = ({text}: {text: string}) => ( | ||
<motion.span | ||
initial={{opacity: 0, y: -20}} | ||
animate={{opacity: 1, y: 0}} | ||
exit={{opacity: 0, y: 20}} | ||
transition={{duration: 0.5}} | ||
className="absolute left-0 right-0" | ||
> | ||
{text} | ||
</motion.span> | ||
) | ||
|
||
export default function Hero() { | ||
const [phraseIndex, setPhraseIndex] = useState(0) | ||
|
||
useEffect(() => { | ||
const timer = setInterval(() => { | ||
setPhraseIndex((current) => (current + 1) % phrases.length) | ||
}, 3000) | ||
return () => clearInterval(timer) | ||
}, []) | ||
|
||
return ( | ||
<section className="py-12 md:py-20 text-center relative overflow-hidden"> | ||
<div className="absolute inset-0 pattern-dots" /> | ||
<motion.div {...scaleIn} className="relative max-w-4xl mx-auto px-4"> | ||
<motion.h1 | ||
{...fadeInUp} | ||
className="relative mb-6 text-4xl font-extrabold tracking-tight text-white sm:text-5xl md:text-6xl leading-tight" | ||
> | ||
<span className="relative h-[1.2em] block mb-2"> | ||
<AnimatePresence mode="wait"> | ||
<AnimatedPhrase key={phraseIndex} text={phrases[phraseIndex]} /> | ||
</AnimatePresence> | ||
</span> | ||
<span className="dark:text-gray-400 text-gray-800 drop-shadow-lg dark:drop-shadow-lg"> | ||
AI | ||
</span>{' '} | ||
in Just{' '} | ||
<span className="dark:text-gray-400 text-gray-800 drop-shadow-lg dark:drop-shadow-lg"> | ||
20 Days | ||
</span> | ||
</motion.h1> | ||
|
||
<motion.p | ||
{...fadeInUp} | ||
transition={{delay: 0.1}} | ||
className="relative mb-8 text-lg md:text-xl text-gray-300 max-w-3xl mx-auto leading-relaxed" | ||
> | ||
Join <span className="emphasis-text">John Lindquist</span>, founder of{' '} | ||
egghead.io, for an immersive, hands-on program that will revolutionize | ||
your dev workflow. In just{' '} | ||
<span className="emphasis-text">20 days</span>, you'll master | ||
building real-world AI applications that automate the tedious, amplify | ||
your capabilities, and{' '} | ||
<span className="emphasis-text"> | ||
transform how your team ships software | ||
</span> | ||
. | ||
</motion.p> | ||
|
||
<motion.div | ||
{...fadeInUp} | ||
transition={{delay: 0.3, type: 'spring', stiffness: 200}} | ||
className="relative" | ||
> | ||
<Link | ||
href="#signup" | ||
className="group relative inline-flex items-center justify-center rounded-md bg-[var(--accent-9)] px-8 py-3 text-base font-semibold text-black dark:text-white transition-all duration-200 hover:bg-[var(--accent-10)] hover:scale-105 focus:outline-none focus:ring-2 focus:ring-[var(--accent-9)] focus:ring-offset-2 focus:ring-offset-gray-900" | ||
> | ||
Join the Waitlist | ||
</Link> | ||
</motion.div> | ||
</motion.div> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use client' | ||
import {motion} from 'framer-motion' | ||
import {fadeInUp} from './animations' | ||
|
||
export default function Instructor() { | ||
return ( | ||
<section className="py-32 relative"> | ||
<div className="container mx-auto px-4 text-center relative z-10"> | ||
<motion.div {...fadeInUp} className="max-w-3xl mx-auto"> | ||
<h2 className="mb-8 text-3xl font-bold text-white"> | ||
Meet Your Instructor, John Lindquist | ||
</h2> | ||
<p className="mb-8 text-lg text-gray-400"> | ||
John Lindquist is a recognized leader in developer education. He | ||
founded egghead.io—an innovative platform that has guided thousands | ||
of coders from novices to industry experts. With years of practical | ||
teaching experience and a genuine passion for helping others | ||
succeed, John will provide the clarity and support you need to | ||
master AI development. | ||
</p> | ||
<p className="text-md text-gray-500"> | ||
Join John and a supportive community of developers as you build the | ||
skills needed to create impactful AI solutions. | ||
</p> | ||
</motion.div> | ||
</div> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
'use client' | ||
|
||
import {useState} from 'react' | ||
import {Button} from './ui/button' | ||
import {Input} from './ui/input' | ||
import {motion} from 'framer-motion' | ||
import {nanoid} from 'nanoid' | ||
import useCio from '@/hooks/use-cio' | ||
|
||
export default function SignUpForm() { | ||
const [email, setEmail] = useState('') | ||
const [isSubmitting, setIsSubmitting] = useState(false) | ||
const {cioIdentify} = useCio() | ||
|
||
const handleSubmit = async (e: React.FormEvent) => { | ||
e.preventDefault() | ||
|
||
if (isSubmitting) return | ||
|
||
setIsSubmitting(true) | ||
const subscriberId = nanoid() | ||
|
||
try { | ||
console.log('Submitting email:', email) | ||
await cioIdentify(subscriberId, { | ||
email, | ||
created_at: Math.floor(Date.now() / 1000), | ||
source: 'landing_page_waitlist', | ||
}) | ||
|
||
setEmail('') | ||
console.log('Successfully submitted email') | ||
} catch (error) { | ||
console.error('Failed to submit:', error) | ||
} finally { | ||
setIsSubmitting(false) | ||
} | ||
} | ||
|
||
return ( | ||
<section id="signup" className="py-32 relative"> | ||
<div className="container mx-auto px-4 relative z-10"> | ||
<motion.div | ||
initial={{opacity: 1, y: 20}} | ||
whileInView={{opacity: 1, y: 0}} | ||
viewport={{once: true}} | ||
className="max-w-2xl mx-auto" | ||
> | ||
<h2 className="mb-4 text-3xl font-bold text-center text-white"> | ||
Ready to Build a Team of AI Devs? | ||
</h2> | ||
<p className="mb-8 text-center text-gray-400 mx-auto"> | ||
Secure your spot in this unique, 20-day cohort-based workshop. | ||
You'll learn alongside a supportive community of developers, | ||
all on the same journey to master AI. Enter your email below and be | ||
the first to know when registration opens. | ||
</p> | ||
<form onSubmit={handleSubmit} className="max-w-md mx-auto"> | ||
<div className="flex space-x-2"> | ||
<Input | ||
type="email" | ||
placeholder="Enter your email to stay informed" | ||
value={email} | ||
onChange={(e) => setEmail(e.target.value)} | ||
required | ||
disabled={isSubmitting} | ||
className="flex-grow bg-[#0A0A0A] border-gray-800 text-white placeholder:text-gray-500" | ||
/> | ||
<Button | ||
type="submit" | ||
disabled={isSubmitting} | ||
className="bg-[var(--accent-9)] hover:bg-[var(--accent-10)] text-black font-semibold transition-all duration-200 hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed" | ||
> | ||
{isSubmitting ? 'Joining...' : 'Join Waitlist'} | ||
</Button> | ||
</div> | ||
</form> | ||
<p className="mt-4 text-center text-sm text-gray-500"> | ||
We'll send you all the details—no spam, just practical info on | ||
how to join. | ||
</p> | ||
</motion.div> | ||
</div> | ||
</section> | ||
) | ||
} |
Oops, something went wrong.