98 lines
3.2 KiB
TypeScript
98 lines
3.2 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
import Image from 'next/image';
|
|
import Link from 'next/link';
|
|
import { ChevronRight, ChevronLeft, Zap } from 'lucide-react';
|
|
import styles from './HomeHeroSlider.module.css';
|
|
|
|
const slides = [
|
|
{
|
|
title: 'KPRO V4.0',
|
|
subtitle: 'UNLEASHED PERFORMANCE',
|
|
desc: 'The ultimate tuning interface for Honda K-Series engines. Surgical precision meets raw performance.',
|
|
img: '/ecu_kpro.png',
|
|
link: '/products/kpro'
|
|
},
|
|
{
|
|
title: 'CAN FLASH',
|
|
subtitle: 'HIGH-SPEED TUNING',
|
|
desc: 'The definitive OBDII tuning interface for modern platforms. Advanced encryption and extreme flashing speed.',
|
|
img: '/engine_bay.png',
|
|
link: '/products/canflash'
|
|
},
|
|
{
|
|
title: 'S300 CORE',
|
|
subtitle: 'LEGACY REDEFINED',
|
|
desc: 'Professional grade engine management for OBD1 Honda ECUs. Real-time data logging and track-ready metrics.',
|
|
img: '/s300_board.png',
|
|
link: '/products/s300'
|
|
}
|
|
];
|
|
|
|
export default function HomeHeroSlider() {
|
|
const [current, setCurrent] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => {
|
|
setCurrent((prev) => (prev + 1) % slides.length);
|
|
}, 6000);
|
|
return () => clearInterval(timer);
|
|
}, []);
|
|
|
|
const next = () => setCurrent((prev) => (prev + 1) % slides.length);
|
|
const prev = () => setCurrent((prev) => (prev - 1 + slides.length) % slides.length);
|
|
|
|
return (
|
|
<div className={styles.wrapper}>
|
|
<AnimatePresence mode="wait">
|
|
<motion.div
|
|
key={current}
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ opacity: 0 }}
|
|
transition={{ duration: 0.8 }}
|
|
className={styles.slide}
|
|
>
|
|
<div className={styles.bgWrapper}>
|
|
<Image src={slides[current].img} alt={slides[current].title} fill className={styles.bgImg} priority />
|
|
</div>
|
|
<div className={styles.overlay}></div>
|
|
|
|
<div className={styles.container}>
|
|
<motion.div
|
|
initial={{ y: 50, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ delay: 0.4 }}
|
|
className={styles.content}
|
|
>
|
|
<span className={styles.subtitle}>{slides[current].subtitle}</span>
|
|
<h1 className={styles.title}>{slides[current].title}</h1>
|
|
<p className={styles.desc}>{slides[current].desc}</p>
|
|
<Link href={slides[current].link} className={styles.ctaBtn}>
|
|
EXPLORE SYSTEM <Zap size={18} />
|
|
</Link>
|
|
</motion.div>
|
|
</div>
|
|
</motion.div>
|
|
</AnimatePresence>
|
|
|
|
<div className={styles.nav}>
|
|
<button onClick={prev} className={styles.navBtn}><ChevronLeft size={32} /></button>
|
|
<button onClick={next} className={styles.navBtn}><ChevronRight size={32} /></button>
|
|
</div>
|
|
|
|
<div className={styles.dots}>
|
|
{slides.map((_, i) => (
|
|
<div
|
|
key={i}
|
|
className={`${styles.dot} ${i === current ? styles.activeDot : ''}`}
|
|
onClick={() => setCurrent(i)}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|