Files
glassmond/components/product-carousel.tsx
Alireza HassaniandCursor 98fde02322 Create Glassmond storefront with Meshkee integration
Build the RTL Next.js experience with live catalog, journal, customer interactions, and SEO-ready canonical routes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-26 00:08:00 +03:30

96 lines
2.9 KiB
TypeScript

"use client";
import Image from "next/image";
import Link from "next/link";
import { Phone } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import {
productImage,
productUrl,
type Product,
} from "@/lib/meshkee";
function getPageSize() {
if (typeof window === "undefined") return 5;
if (window.innerWidth < 620) return 1;
if (window.innerWidth < 900) return 2;
return 5;
}
export function ProductCarousel({ products }: { products: Product[] }) {
const [pageSize, setPageSize] = useState(5);
const [page, setPage] = useState(0);
useEffect(() => {
const update = () => {
setPageSize(getPageSize());
setPage(0);
};
update();
window.addEventListener("resize", update);
return () => window.removeEventListener("resize", update);
}, []);
const pages = Math.max(1, products.length - pageSize + 1);
const visibleProducts = useMemo(() => {
const start = page;
return products.slice(start, start + pageSize);
}, [page, pageSize]);
return (
<div className="product-carousel">
<div
key={`${page}-${pageSize}`}
className="source-products-grid"
style={{ "--visible-products": pageSize } as React.CSSProperties}
aria-live="polite"
>
{visibleProducts.map((product) => (
<article className="source-product-card" key={product.id}>
<div className="source-product-image">
<Link href={productUrl(product)} aria-label={product.nameFa || product.title}>
<Image
src={productImage(product) || "/images/hero.jpg"}
alt={product.nameFa || product.title}
fill
sizes="(max-width: 620px) 100vw, (max-width: 900px) 50vw, (max-width: 1200px) 33vw, 20vw"
/>
</Link>
</div>
<div className="source-product-copy">
<div>
<h3>
<Link href={productUrl(product)}>{product.nameFa || product.title}</Link>
</h3>
<a href="tel:+989301293902">تماس بگیرید</a>
</div>
<a
className="product-phone"
href="tel:+989301293902"
aria-label={`تماس برای ${product.title}`}
>
<Phone />
</a>
</div>
</article>
))}
</div>
{pages > 1 && (
<div className="carousel-dots" aria-label="صفحات محصولات">
{Array.from({ length: pages }, (_, index) => (
<button
key={index}
type="button"
className={index === page ? "active" : ""}
onClick={() => setPage(index)}
aria-label={`صفحه ${index + 1}`}
aria-current={index === page ? "true" : undefined}
/>
))}
</div>
)}
</div>
);
}