118 lines
4.9 KiB
TypeScript
118 lines
4.9 KiB
TypeScript
"use client";
|
|
import { useState } from 'react';
|
|
import Link from 'next/link';
|
|
import Image from 'next/image';
|
|
import { products } from '@/data/products';
|
|
import PriceDisplay from '@/components/PriceDisplay';
|
|
|
|
export default function ProductsPage() {
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const productsPerPage = 12;
|
|
|
|
// Calculate pagination
|
|
const indexOfLastProduct = currentPage * productsPerPage;
|
|
const indexOfFirstProduct = indexOfLastProduct - productsPerPage;
|
|
const currentProducts = products.slice(indexOfFirstProduct, indexOfLastProduct);
|
|
const totalPages = Math.ceil(products.length / productsPerPage);
|
|
const paginate = (pageNumber: number) => setCurrentPage(pageNumber);
|
|
|
|
return (
|
|
<div style={{ minHeight: '100vh' }}>
|
|
{/* Inner Banner */}
|
|
<section className="inner-banner fade-up">
|
|
<div className="inner-banner-content">
|
|
<h1 className="section-h2">Our <span>Product</span> Catalog</h1>
|
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
|
<Link href="/">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
|
Home
|
|
</Link>
|
|
<span className="separator">/</span>
|
|
<span>Products</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Grid Content */}
|
|
<section className="products-section section">
|
|
<div className="products-grid product-page">
|
|
{currentProducts.map((product) => (
|
|
<div key={product.slug} className="product-card" style={{ display: 'flex', flexDirection: 'column', height: '100%', textDecoration: 'none' }}>
|
|
<div style={{ position: 'relative', width: '100%', height: '240px', borderRadius: '8px', overflow: 'hidden', marginBottom: '20px', background: 'var(--gray-100)' }}>
|
|
<Image
|
|
src="/assets/about-fencing.png"
|
|
alt={product.name}
|
|
fill
|
|
style={{ objectFit: 'cover' }}
|
|
/>
|
|
</div>
|
|
<div className="product-name">{product.name}</div>
|
|
<div className="product-desc" style={{
|
|
display: '-webkit-box',
|
|
WebkitLineClamp: 3,
|
|
WebkitBoxOrient: 'vertical',
|
|
overflow: 'hidden',
|
|
minHeight: '4.8em',
|
|
marginBottom: '16px'
|
|
}}>
|
|
{product.description}
|
|
</div>
|
|
<div style={{ marginTop: 'auto' }}>
|
|
<PriceDisplay price={product.price} />
|
|
<Link href={`/products/${product.slug}`} className="btn-primary" style={{ width: '100%', textAlign: 'center', appearance: 'none', display: 'block' }}>
|
|
View Product →
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Pagination */}
|
|
{totalPages > 1 && (
|
|
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '12px', marginTop: '64px', flexWrap: 'wrap' }}>
|
|
<button
|
|
onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
|
|
disabled={currentPage === 1}
|
|
className="btn-secondary"
|
|
style={{ padding: '8px 20px', opacity: currentPage === 1 ? 0.3 : 1, color: 'var(--navy)', borderColor: 'var(--navy)' }}
|
|
>
|
|
Prev
|
|
</button>
|
|
|
|
<div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', justifyContent: 'center' }}>
|
|
{Array.from({ length: totalPages }, (_, i) => i + 1).map((num) => (
|
|
<button
|
|
key={num}
|
|
onClick={() => paginate(num)}
|
|
style={{
|
|
width: '40px',
|
|
height: '40px',
|
|
borderRadius: '4px',
|
|
border: '1px solid',
|
|
borderColor: currentPage === num ? 'var(--orange)' : 'var(--gray-200)',
|
|
background: currentPage === num ? 'var(--orange)' : 'transparent',
|
|
color: currentPage === num ? 'white' : 'var(--gray-600)',
|
|
cursor: 'pointer',
|
|
fontWeight: 600
|
|
}}
|
|
>
|
|
{num}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<button
|
|
onClick={() => setCurrentPage(prev => Math.min(prev + 1, totalPages))}
|
|
disabled={currentPage === totalPages}
|
|
className="btn-secondary"
|
|
style={{ padding: '8px 20px', opacity: currentPage === totalPages ? 0.3 : 1, color: 'var(--navy)', borderColor: 'var(--navy)' }}
|
|
>
|
|
Next
|
|
</button>
|
|
</div>
|
|
)}
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|