forked from UKSOURCE/ipv6
81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
const BASE = process.env.NEXT_PUBLIC_BASE_PATH || "";
|
|
|
|
type GalleryItem = {
|
|
src: string;
|
|
alt: string;
|
|
span: "wide" | "normal" | "full";
|
|
};
|
|
|
|
type Props = {
|
|
data: {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
items: GalleryItem[];
|
|
};
|
|
};
|
|
|
|
// Map span → Tailwind col-span classes
|
|
const spanClass: Record<GalleryItem["span"], string> = {
|
|
wide: "md:col-span-2 lg:col-span-2",
|
|
normal: "",
|
|
full: "md:col-span-2 lg:col-span-3",
|
|
};
|
|
|
|
// Map span → chiều cao ảnh
|
|
const heightClass: Record<GalleryItem["span"], string> = {
|
|
wide: "h-[240px] md:h-[340px] lg:h-[420px]",
|
|
normal: "h-[240px] md:h-[340px] lg:h-[420px]",
|
|
full: "h-[260px] md:h-[360px] lg:h-[480px]",
|
|
};
|
|
|
|
export default function GallerySection({ data }: Props) {
|
|
return (
|
|
<section
|
|
className="py-16 lg:py-32 max-w-hd mx-auto px-[var(--spacing-gutter)]"
|
|
id="gallery"
|
|
>
|
|
{/* Header */}
|
|
<div className="text-center mb-12 lg:mb-20">
|
|
<span className="font-[var(--font-label-caps)] text-xs lg:text-sm text-primary block mb-4 lg:mb-6 tracking-[0.25em] uppercase">
|
|
{data.eyebrow}
|
|
</span>
|
|
<h2 className="font-[var(--font-display-lg)] text-on-surface mb-4 lg:mb-6 text-[clamp(2rem,4vw+1rem,4.5rem)] leading-tight">
|
|
{data.title}
|
|
</h2>
|
|
<p className="font-[var(--font-body-base)] text-on-surface-variant text-base lg:text-[20px] max-w-2xl mx-auto opacity-70 leading-relaxed">
|
|
{data.description}
|
|
</p>
|
|
</div>
|
|
|
|
{/* Grid masonry-style */}
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-6">
|
|
{data.items.map((item, i) => (
|
|
<div
|
|
key={i}
|
|
className={[
|
|
spanClass[item.span],
|
|
"overflow-hidden rounded-2xl border border-primary/20 hover:border-primary/50",
|
|
"shadow-lg group transition-all duration-500",
|
|
].join(" ")}
|
|
>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img
|
|
src={`${BASE}${item.src}`}
|
|
alt={item.alt}
|
|
className={[
|
|
"w-full object-cover",
|
|
heightClass[item.span],
|
|
"transition-transform duration-700 group-hover:scale-105",
|
|
].join(" ")}
|
|
loading={i < 3 ? "eager" : "lazy"}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|