169 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState, useEffect, useCallback } from "react";
import ContactPopup from '@/components/common/ContactPopup/ContactPopup';
const features = [
{
img: "/assets/img/home/section5/conversion.webp",
title: "Conversion-Focused Website Architecture",
desc: "We design every page with one goal — turning visitors into leads or customers. From clear CTAs to strategic layout flow, your website will guide users toward action.",
},
{
img: "/assets/img/home/section5/speed.webp",
title: "Speed & Performance Optimized",
desc: "A slow website kills conversions. We build lightweight, optimized websites that load fast, improve user experience, and boost your Google rankings.",
},
{
img: "/assets/img/home/section5/seo.webp",
title: "SEO-Ready Development",
desc: "Your website is built with clean code, proper structure, meta setup, schema basics, and search-friendly URLs — helping you rank better on Google from day one.",
},
{
img: "/assets/img/home/section5/mobile.webp",
title: "Mobile-First & Fully Responsive",
desc: "Over 70% of traffic comes from mobile. We ensure your website looks perfect and functions smoothly on smartphones, tablets, and desktops.",
}
];
// Group features into pairs (columns of 2 cards each)
const columns: typeof features[] = [];
for (let i = 0; i < features.length; i += 2) {
columns.push(features.slice(i, i + 2));
}
const KeyFeatures = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const [visibleCols, setVisibleCols] = useState(2);
const [isContactOpen, setIsContactOpen] = useState(false);
const totalCols = columns.length; // 2 columns
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 576) setVisibleCols(1);
else setVisibleCols(2);
};
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
const maxIndex = Math.max(0, totalCols - visibleCols);
const handleNext = useCallback(() => {
setCurrentIndex((prev) => (prev < maxIndex ? prev + 1 : 0));
}, [maxIndex]);
const handlePrev = useCallback(() => {
setCurrentIndex((prev) => (prev > 0 ? prev - 1 : maxIndex));
}, [maxIndex]);
// Auto-slide every 5s
useEffect(() => {
const timer = setInterval(handleNext, 5000);
return () => clearInterval(timer);
}, [handleNext]);
// Clamp index on resize
useEffect(() => {
if (currentIndex > maxIndex) setCurrentIndex(maxIndex);
}, [maxIndex, currentIndex]);
return (
<section className="kf-section kf-section-light">
<div className="kf-container">
{/* Left Single Full Image */}
<div className="kf-image-column">
<img
src="/assets/img/home/section4/4.webp"
alt="Key Features"
style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', borderRadius: '12px' }}
loading="lazy"
/>
</div>
{/* Right Slider */}
<div className="kf-slider-column">
<div className="kf-header">
<h2 className="kf-title">
Key <span className="kf-highlight">Features</span>
</h2>
</div>
<div className="kf-slider-window">
<div
className="kf-slider-track"
style={{
transform: `translateX(calc(-${currentIndex} * (100% + 1.5rem) / ${visibleCols}))`,
}}
>
{columns.map((column, colIdx) => (
<div
key={colIdx}
className="kf-column-wrapper"
style={{
flexBasis: `calc((100% - (${visibleCols} - 1) * 1.5rem) / ${visibleCols})`,
width: `calc((100% - (${visibleCols} - 1) * 1.5rem) / ${visibleCols})`,
}}
>
{column.map((feature, idx) => (
<div key={idx} className="kf-card">
<div className="kf-icon-box">
<img
src={feature.img}
alt={feature.title}
className="kf-card-img"
loading="lazy"
/>
</div>
<div className="kf-card-content">
<h5 className="kf-card-name">{feature.title}</h5>
<p className="kf-card-desc">
{feature.desc}
</p>
</div>
</div>
))}
{column.length < 2 && <div className="kf-card-placeholder" />}
</div>
))}
</div>
</div>
{/* Dots */}
<div className="kf-dots">
{Array.from({ length: maxIndex + 1 }).map((_, idx) => (
<div
key={idx}
className={`kf-dot${currentIndex === idx ? " kf-dot-active" : ""}`}
onClick={() => setCurrentIndex(idx)}
/>
))}
</div>
{/* Controls + CTA */}
<div className="kf-controls-row">
<div className="kf-controls">
<button className="kf-control-btn" onClick={handlePrev} aria-label="Previous">
&#8592;
</button>
<button className="kf-control-btn" onClick={handleNext} aria-label="Next">
&#8594;
</button>
</div>
<button onClick={() => setIsContactOpen(true)} className="kf-demo-btn">
Book Free Strategy Call
<i className="fa-solid fa-angle-right"></i></button>
</div>
</div>
<ContactPopup isOpen={isContactOpen} onClose={() => setIsContactOpen(false)} />
</div >
</section >
);
};
export default KeyFeatures;