Initial Next.js clone of Pars Elevator (plift.ir).
RTL Meshkee storefront with home/about/contact/products/blog, API auth/contact/blog wiring, and SEO sitemap-config. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { featuresSection } from "@/data/site";
|
||||
|
||||
export function FeaturesCarousel() {
|
||||
const items = featuresSection.items;
|
||||
const [index, setIndex] = useState(0);
|
||||
const [perView, setPerView] = useState(3);
|
||||
|
||||
useEffect(() => {
|
||||
const update = () => {
|
||||
const w = window.innerWidth;
|
||||
if (w < 768) setPerView(1);
|
||||
else if (w < 992) setPerView(2);
|
||||
else setPerView(3);
|
||||
};
|
||||
update();
|
||||
window.addEventListener("resize", update);
|
||||
return () => window.removeEventListener("resize", update);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (items.length <= perView) return;
|
||||
const id = window.setInterval(() => {
|
||||
setIndex((i) => (i + 1) % items.length);
|
||||
}, 3000);
|
||||
return () => window.clearInterval(id);
|
||||
}, [items.length, perView]);
|
||||
|
||||
const visible =
|
||||
perView >= items.length
|
||||
? items
|
||||
: Array.from({ length: perView }, (_, i) => items[(index + i) % items.length]);
|
||||
|
||||
const showNav = items.length > perView;
|
||||
|
||||
return (
|
||||
<section className="relative overflow-hidden bg-[#F6F6F6] pt-20 pb-24 md:pt-[6.5rem] md:pb-28">
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-x-0 top-4 hidden select-none overflow-hidden text-center text-[110px] font-semibold leading-none tracking-[-8px] text-white xl:block 2xl:text-[154px]"
|
||||
>
|
||||
آسانسور پارس
|
||||
</div>
|
||||
|
||||
<div className="container-plift relative z-10">
|
||||
<div className="mx-auto mb-12 max-w-2xl text-center lg:mb-14">
|
||||
<span className="mb-5 block text-[17px] font-medium text-[#A0A0A0]">
|
||||
{featuresSection.eyebrow}
|
||||
</span>
|
||||
<h2 className="text-[1.7rem] font-bold uppercase leading-snug text-dark md:text-[2rem]">
|
||||
{featuresSection.title}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid items-start gap-6 lg:grid-cols-12 lg:gap-5">
|
||||
{/* side intro — ~1/4 */}
|
||||
<div className="pt-2 lg:col-span-3">
|
||||
<span className="mb-5 block text-[17px] font-medium text-dark">
|
||||
{featuresSection.sideLabel}
|
||||
</span>
|
||||
<h3 className="mb-8 text-[1.35rem] font-bold leading-9 text-dark md:text-[1.55rem] md:leading-10">
|
||||
{featuresSection.sideTitle}
|
||||
</h3>
|
||||
|
||||
{showNav && (
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="بعدی"
|
||||
onClick={() => setIndex((i) => (i + 1) % items.length)}
|
||||
className="inline-flex h-10 w-10 items-center justify-center border border-[#ddd] text-lg text-dark transition hover:border-dark"
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="قبلی"
|
||||
onClick={() =>
|
||||
setIndex((i) => (i - 1 + items.length) % items.length)
|
||||
}
|
||||
className="inline-flex h-10 w-10 items-center justify-center border border-[#ddd] text-lg text-dark transition hover:border-dark"
|
||||
>
|
||||
›
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* cards — show 3 on desktop like original */}
|
||||
<div className="lg:col-span-9">
|
||||
<div
|
||||
className={`grid gap-5 ${
|
||||
perView === 1
|
||||
? "grid-cols-1"
|
||||
: perView === 2
|
||||
? "grid-cols-2"
|
||||
: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
|
||||
}`}
|
||||
>
|
||||
{visible.map((item, i) => (
|
||||
<article
|
||||
key={`${item.number}-${perView >= items.length ? item.number : `${index}-${i}`}`}
|
||||
className="border border-black/[0.08] bg-white"
|
||||
>
|
||||
<div className="px-7 py-10 md:px-8 md:py-12 xl:px-9">
|
||||
<div className="mb-5 text-[2.5rem] font-medium leading-none tracking-[-2px] text-[#A0A0A0]">
|
||||
{item.number}
|
||||
</div>
|
||||
<h4 className="mb-3 text-[16px] font-semibold uppercase leading-7 text-dark">
|
||||
{item.title}
|
||||
</h4>
|
||||
<p className="text-[14px] font-light leading-[26px] text-[#5C6873] text-justify">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user