-
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.
- Loading branch information
1 parent
4808064
commit e8cc5bb
Showing
24 changed files
with
1,421 additions
and
0 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,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,94 @@ | ||
'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="flex items-center mb-4 gap-2"> | ||
<Icon className="w-6 h-6 text-[var(--accent-9)]" /> | ||
<h3 className="text-lg font-semibold dark:text-white text-gray-900"> | ||
{feature.title} | ||
</h3> | ||
</div> | ||
<p className="text-gray-500 dark: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,119 @@ | ||
'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' | ||
import {ArrowCircleDownIcon} from '@heroicons/react/solid' | ||
import {useTheme} from 'next-themes' | ||
import {cn} from '@/ui/utils' | ||
|
||
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> | ||
) | ||
|
||
function scrollToSignup(e: React.MouseEvent<HTMLAnchorElement>) { | ||
e.preventDefault() | ||
document.querySelector('#signup')?.scrollIntoView({behavior: 'smooth'}) | ||
} | ||
|
||
export default function Hero() { | ||
const {theme} = useTheme() | ||
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={cn( | ||
'absolute inset-0', | ||
theme === 'light' && 'pattern-dots-light', | ||
theme === 'dark' && '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 dark: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-500 max-w-3xl mx-auto leading-relaxed" | ||
> | ||
Join{' '} | ||
<span className="text-gray-900 dark:text-white font-medium"> | ||
John Lindquist | ||
</span> | ||
, founder of egghead.io, for an immersive, hands-on program that will | ||
revolutionize your dev workflow. In just{' '} | ||
<span className="text-gray-900 dark:text-white font-medium"> | ||
20 days | ||
</span> | ||
, you'll master building real-world AI applications that automate | ||
the tedious, amplify your capabilities, and{' '} | ||
<span className="text-gray-900 dark:text-white font-medium"> | ||
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" | ||
onClick={scrollToSignup} | ||
className="group flex flex-col items-center justify-center w-fit mx-auto hover:cursor-pointer" | ||
> | ||
<p className="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 group-hover:bg-[var(--accent-10)] group-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 | ||
</p> | ||
<ArrowCircleDownIcon className="group-hover:scale-105 w-8 h-8 transition-all duration-200" /> | ||
</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,47 @@ | ||
'use client' | ||
import {motion} from 'framer-motion' | ||
import Image from 'next/image' | ||
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"> | ||
<div className="mx-auto flex w-full max-w-3xl flex-col-reverse items-center justify-between gap-10 px-6 sm:gap-20 md:flex-row"> | ||
<div> | ||
<h2 className="mb-8 text-3xl font-bold dark:text-white flex flex-col items-center sm:items-start"> | ||
<span className="font-heading dark:text-primary text-sm uppercase tracking-widest"> | ||
{' '} | ||
Your Instructor | ||
</span> | ||
<span className="font-heading text-3xl font-semibold sm:text-4xl"> | ||
John Lindquist | ||
</span> | ||
</h2> | ||
<p className="mb-8 text-lg text-gray-500 dark:text-gray-400 text-left bg-white dark:bg-gray-900/80"> | ||
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 dark:text-gray-400 text-left bg-white dark:bg-gray-900/80"> | ||
Join John and a supportive community of developers as you build | ||
the skills needed to create impactful AI solutions. | ||
</p> | ||
</div> | ||
<Image | ||
src="https://res.cloudinary.com/dg3gyk0gu/image/upload/v1683164538/assets/john.webp" | ||
alt="John Lindquist" | ||
width={300} | ||
height={300} | ||
className="rounded-lg" | ||
/> | ||
</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,103 @@ | ||
'use client' | ||
|
||
import {useState} from 'react' | ||
import {Button} from './ui/button' | ||
import {Input} from './ui/input' | ||
import {motion} from 'framer-motion' | ||
import useCio from '@/hooks/use-cio' | ||
import {trpc} from '@/app/_trpc/client' | ||
|
||
export default function SignUpForm() { | ||
const [email, setEmail] = useState('') | ||
const [isSubmitting, setIsSubmitting] = useState(false) | ||
const {subscriber} = useCio() | ||
const identify = trpc.customerIO.identify.useMutation({ | ||
onSuccess: (data) => { | ||
console.log('IDENTIFY', data) | ||
}, | ||
onError: (error) => { | ||
console.log('ERROR', error) | ||
}, | ||
}) | ||
|
||
const handleSubmit = async (e: React.FormEvent) => { | ||
e.preventDefault() | ||
|
||
if (isSubmitting) return | ||
|
||
setIsSubmitting(true) | ||
let subscriberId = subscriber?.id | ||
|
||
try { | ||
console.log('Submitting email:', email) | ||
|
||
const currentDateTime = Math.floor(Date.now() * 0.001) // Customer.io uses seconds with their UNIX epoch timestamps | ||
|
||
if (!subscriberId) { | ||
identify.mutateAsync({ | ||
email, | ||
selectedInterests: {ai_bootcamp_waitlist: currentDateTime}, | ||
}) | ||
} else { | ||
identify.mutateAsync({ | ||
id: subscriberId, | ||
selectedInterests: {ai_bootcamp_waitlist: currentDateTime}, | ||
}) | ||
} | ||
|
||
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 dark:text-white text-gray-900"> | ||
Ready to Build a Team of AI Devs? | ||
</h2> | ||
<p className="mb-8 text-center text-gray-500 dark: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-gray-50 dark:bg-gray-800/50 dark:border-gray-800 border-gray-200 text-gray-900 dark:text-white placeholder:text-gray-500" | ||
/> | ||
<Button | ||
type="submit" | ||
disabled={isSubmitting} | ||
className="bg-blue-500 text-white 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.