init project files
This commit is contained in:
121
components/sections/Hero.tsx
Normal file
121
components/sections/Hero.tsx
Normal file
@@ -0,0 +1,121 @@
|
||||
'use client';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { personal } from '@/content/personal';
|
||||
import styles from './Hero.module.scss';
|
||||
|
||||
const fadeUp = (delay = 0) => ({
|
||||
initial: { opacity: 0, y: 28 },
|
||||
animate: { opacity: 1, y: 0 },
|
||||
transition: { duration: 0.65, ease: [0.22, 0.61, 0.36, 1], delay },
|
||||
});
|
||||
|
||||
export default function Hero() {
|
||||
const [roleIndex, setRoleIndex] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setRoleIndex(i => (i + 1) % personal.roles.length);
|
||||
}, 2800);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className={styles.hero} id="home">
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
|
||||
{/* Availability Badge */}
|
||||
<motion.div className={styles.badge} {...fadeUp(0)}>
|
||||
<span className={styles.dot} />
|
||||
{personal.availabilityText}
|
||||
</motion.div>
|
||||
|
||||
{/* Heading */}
|
||||
<motion.h1 className={styles.title} {...fadeUp(0.1)}>
|
||||
Hi, I'm <span className={styles.name}>{personal.name}</span>
|
||||
</motion.h1>
|
||||
|
||||
{/* Animated Role */}
|
||||
<motion.div className={styles.roleWrapper} {...fadeUp(0.2)}>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.span
|
||||
key={roleIndex}
|
||||
className={styles.role}
|
||||
initial={{ opacity: 0, y: 12 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -12 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
>
|
||||
{personal.roles[roleIndex]}
|
||||
</motion.span>
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
|
||||
{/* Bio */}
|
||||
<motion.p className={styles.bio} {...fadeUp(0.3)}>
|
||||
{personal.bio}
|
||||
</motion.p>
|
||||
|
||||
{/* CTAs */}
|
||||
<motion.div className={styles.ctas} {...fadeUp(0.4)}>
|
||||
<motion.div whileHover={{ scale: 1.03 }} whileTap={{ scale: 0.98 }}>
|
||||
<Link href="#projects" className={styles.btnPrimary}>
|
||||
View Projects
|
||||
</Link>
|
||||
</motion.div>
|
||||
<motion.div whileHover={{ scale: 1.03 }} whileTap={{ scale: 0.98 }}>
|
||||
<Link href="#experience" className={styles.btnSecondary}>
|
||||
Experience
|
||||
</Link>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Right side: grid + terminal */}
|
||||
<motion.div
|
||||
className={styles.visual}
|
||||
initial={{ opacity: 0, y: 30, scale: 0.96 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
transition={{ duration: 0.9, ease: [0.22, 0.61, 0.36, 1], delay: 0.25 }}
|
||||
>
|
||||
<div className={styles.grid} aria-hidden="true">
|
||||
<motion.div
|
||||
className={styles.terminal}
|
||||
initial={{ opacity: 0, scale: 0.92 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.5, ease: [0.22, 0.61, 0.36, 1] }}
|
||||
>
|
||||
<div className={styles.terminalHeader}>
|
||||
<div className={styles.trafficLights}>
|
||||
<span className={styles.trafficRed} />
|
||||
<span className={styles.trafficYellow} />
|
||||
<span className={styles.trafficGreen} />
|
||||
</div>
|
||||
<span className={styles.terminalTitle}>zsh — portfolio</span>
|
||||
</div>
|
||||
<div className={styles.terminalBody}>
|
||||
<div className={styles.terminalLine}>
|
||||
<span className={styles.prompt}>$</span>{' '}
|
||||
<span className={styles.cmd}>whoami</span>
|
||||
</div>
|
||||
<div className={styles.terminalLine}><span className={styles.output}>{personal.name.replace(' ', '-').toLowerCase()}</span></div>
|
||||
<div className={styles.terminalLine}>
|
||||
<span className={styles.prompt}>$</span>{' '}
|
||||
<span className={styles.cmd}>cat role.txt</span>
|
||||
</div>
|
||||
<div className={styles.terminalLine}><span className={styles.accentLine}>{personal.role}</span></div>
|
||||
<div className={styles.terminalLine}>
|
||||
<span className={styles.prompt}>$</span>{' '}
|
||||
<span className={styles.cursor} />
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user