198 lines
7.5 KiB
TypeScript
198 lines
7.5 KiB
TypeScript
import { useState } from 'react';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
import Image from 'next/image';
|
|
import { AlertTriangle, CheckCircle, Info, X } from 'lucide-react';
|
|
import styles from './KProHWInstall.module.css';
|
|
|
|
export default function KProHWInstall() {
|
|
const [selectedImage, setSelectedImage] = useState<string | null>(null);
|
|
const steps = [
|
|
{
|
|
title: 'Modify R243',
|
|
desc: 'Install 22kΩ resistor in place of R243 jumper.',
|
|
image: '/hw_install_1.jpg',
|
|
},
|
|
{
|
|
title: 'Bridge J250',
|
|
desc: 'Bridge J250 with solder.',
|
|
image: '/hw_install_2.jpg',
|
|
},
|
|
{
|
|
title: 'Solder J270',
|
|
desc: 'Solder 1-pin connector at the J270 location.',
|
|
image: '/hw_install_3.jpg',
|
|
},
|
|
{
|
|
title: 'Solder CN2',
|
|
desc: 'Solder 5-pin connector at the CN2 location.',
|
|
image: '/hw_install_4.jpg',
|
|
},
|
|
{
|
|
title: 'Solder CN3',
|
|
desc: 'Solder 5-pin connector at the CN3 location.',
|
|
image: '/hw_install_5.jpg',
|
|
},
|
|
{
|
|
title: 'Jumper Wires',
|
|
desc: 'Solder 3 jumper wires between the points shown in the picture.',
|
|
image: '/hw_install_6.jpg',
|
|
},
|
|
{
|
|
title: 'Wire Soldering Example',
|
|
desc: 'Example of correct wire soldering execution.',
|
|
image: '/hw_install_7.jpg',
|
|
},
|
|
{
|
|
title: 'Physical Installation',
|
|
desc: 'Drill hole for USB. Install KPro board with supplied screws.',
|
|
image: '/hw_install_8.jpg',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className={styles.wrapper}>
|
|
{/* HEADER SECTION */}
|
|
<section className={styles.header}>
|
|
<div className={styles.container}>
|
|
<motion.div
|
|
className={styles.titleBox}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
>
|
|
<span className={styles.label}>TECHNICAL DOCUMENTATION</span>
|
|
<h1 className={styles.title}>K<span className={styles.red}>PRO</span> HARDWARE INSTALLATION GUIDE</h1>
|
|
|
|
<div className={styles.warningBox}>
|
|
<AlertTriangle className={styles.warnIcon} size={32} />
|
|
<div className={styles.warnText}>
|
|
<h4>WARNING: PROFESSIONAL INSTALLATION REQUIRED</h4>
|
|
<p>Do not attempt to solder the ECU yourself unless you are a qualified and experienced technician. For professional assistance, please contact us. By attempting to modify the ECU, you assume full responsibility for any damage caused to the vehicle.</p>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* OVERVIEW SECTION */}
|
|
<section className={styles.overview}>
|
|
<div className={styles.container}>
|
|
<motion.div
|
|
className={styles.overviewBox}
|
|
initial={{ opacity: 0, scale: 0.95 }}
|
|
whileInView={{ opacity: 1, scale: 1 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<div className={styles.overviewContent}>
|
|
<h3><CheckCircle size={20} className={styles.red} /> MODIFICATION CHECKLIST</h3>
|
|
<p>Five components must be modified on the ECU PCB to properly install the daughterboard. Prepare your workstation and ensure you locate these exact points on the board.</p>
|
|
<ul className={styles.componentsList}>
|
|
<li>CN2</li>
|
|
<li>CN3</li>
|
|
<li>J270</li>
|
|
<li>J250</li>
|
|
<li>R243</li>
|
|
</ul>
|
|
</div>
|
|
<div className={styles.overviewImageWrapper}>
|
|
{/* OVERVIEW IMAGE SLOT */}
|
|
<div className={styles.imagePlaceholder} onClick={() => setSelectedImage("/hw_install_9.jpg")}>
|
|
<Image src="/hw_install_9.jpg" alt="ECU Overview" fill style={{ objectFit: 'cover' }} />
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* STEPS GRID SECTION */}
|
|
<section className={styles.steps}>
|
|
<div className={styles.container}>
|
|
<div className={styles.stepsGrid}>
|
|
{steps.map((step, index) => (
|
|
<motion.div
|
|
key={index}
|
|
className={styles.stepCard}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ delay: index * 0.05 }}
|
|
>
|
|
<div className={styles.stepImageWrapper} onClick={() => setSelectedImage(step.image)}>
|
|
{/* STEP IMAGE SLOT */}
|
|
<Image src={step.image} alt={step.title} fill style={{ objectFit: 'cover' }} />
|
|
<div className={styles.stepNumber}>{index + 1}</div>
|
|
</div>
|
|
<div className={styles.stepContent}>
|
|
<h3>{step.title}</h3>
|
|
<p>{step.desc}</p>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* FIRST UPLOAD SECTION */}
|
|
<section className={styles.firstUpload}>
|
|
<div className={styles.container}>
|
|
<motion.div
|
|
className={styles.uploadBox}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<div className={styles.uploadText}>
|
|
<h2>FIRST <span className={styles.red}>UPLOAD</span></h2>
|
|
<p>Before you can successfully upload a tune to the ECU for the first time, you must clear the security settings in the KPro Manager software.</p>
|
|
|
|
<div className={styles.instructionList}>
|
|
<div className={styles.instItem}>
|
|
<Info size={18} className={styles.red} />
|
|
<span>Open <strong>KPro Manager</strong> on your connected PC.</span>
|
|
</div>
|
|
<div className={styles.instItem}>
|
|
<Info size={18} className={styles.red} />
|
|
<span>Navigate to the <strong>Online</strong> menu.</span>
|
|
</div>
|
|
<div className={styles.instItem}>
|
|
<Info size={18} className={styles.red} />
|
|
<span>Select <strong>Erase ECU (Clear Security)</strong>.</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.uploadImageWrapper}>
|
|
{/* FIRST UPLOAD IMAGE SLOT */}
|
|
<div className={styles.imagePlaceholder} onClick={() => setSelectedImage("/hw_install_10.png")}>
|
|
<Image src="/hw_install_10.png" alt="First Upload Instructions" fill style={{ objectFit: 'contain' }} />
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
<AnimatePresence>
|
|
{selectedImage && (
|
|
<motion.div
|
|
className={styles.modalOverlay}
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ opacity: 0 }}
|
|
onClick={() => setSelectedImage(null)}
|
|
>
|
|
<button className={styles.closeBtn} onClick={() => setSelectedImage(null)}><X size={32} /></button>
|
|
<motion.div
|
|
className={styles.modalContent}
|
|
initial={{ scale: 0.9 }}
|
|
animate={{ scale: 1 }}
|
|
exit={{ scale: 0.9 }}
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<Image src={selectedImage} alt="Full screen image" fill style={{ objectFit: 'contain' }} />
|
|
</motion.div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
);
|
|
}
|