x
This commit is contained in:
1 parent
d325cd8763
commit
c6bf2f70ac
45 files changed
+5195
-338
No files matched your search
@@ -0,0 +1,112 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Autoplay, Pagination } from 'swiper/modules';
|
||||
import { Link } from 'react-router-dom';
|
||||
import type { EditorialCarouselSectionPayload } from '@homaroma/types';
|
||||
|
||||
// Import Swiper styles
|
||||
import 'swiper/css';
|
||||
import 'swiper/css/pagination';
|
||||
|
||||
interface DynamicEditorialCarouselProps {
|
||||
payload: EditorialCarouselSectionPayload;
|
||||
}
|
||||
|
||||
export default function DynamicEditorialCarousel({ payload }: DynamicEditorialCarouselProps) {
|
||||
const { title, slides = [] } = payload;
|
||||
|
||||
if (slides.length === 0) return null;
|
||||
|
||||
const renderTitle = (text: string) => {
|
||||
if (!text) return null;
|
||||
return text.split('[').map((part, i) => {
|
||||
if (part.includes(']')) {
|
||||
const [accent, rest] = part.split(']');
|
||||
return (
|
||||
<span key={i}>
|
||||
<span className="text-spa-gold font-medium italic">
|
||||
{accent}
|
||||
</span>
|
||||
{rest}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <span key={i}>{part}</span>;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="w-full bg-[#1F3D2D] text-white py-20 px-6 md:px-16 overflow-hidden">
|
||||
<div className="max-w-7xl mx-auto space-y-12">
|
||||
{/* Section Header */}
|
||||
<div className="text-center space-y-3">
|
||||
<h2 className="text-3xl md:text-5xl font-light tracking-wide font-serif text-spa-gold">
|
||||
{renderTitle(title) || title}
|
||||
</h2>
|
||||
<div className="w-16 h-[1px] bg-spa-gold mx-auto"></div>
|
||||
</div>
|
||||
|
||||
{/* Swiper Slider */}
|
||||
<div className="relative select-none pb-12">
|
||||
<Swiper
|
||||
modules={[Autoplay, Pagination]}
|
||||
spaceBetween={30}
|
||||
slidesPerView={1}
|
||||
breakpoints={{
|
||||
640: { slidesPerView: 2 },
|
||||
1024: { slidesPerView: 3 }
|
||||
}}
|
||||
pagination={{ clickable: true, bulletActiveClass: 'swiper-pagination-bullet-active !bg-spa-gold' }}
|
||||
autoplay={{ delay: 5000, disableOnInteraction: false }}
|
||||
className="w-full"
|
||||
>
|
||||
{slides.map((slide, idx) => (
|
||||
<SwiperSlide key={idx} className="h-auto flex flex-col">
|
||||
<div className="bg-white/5 border border-white/5 rounded-3xl overflow-hidden flex flex-col h-full group hover:border-spa-gold/30 transition-all duration-300">
|
||||
{/* Image wrapper */}
|
||||
<div className="aspect-[4/3] overflow-hidden relative">
|
||||
<img
|
||||
src={slide.imageUrl}
|
||||
alt={slide.title}
|
||||
className="w-full h-full object-cover transition-transform duration-700 ease-out group-hover:scale-105"
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).style.display = 'none';
|
||||
}}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#1F3D2D]/60 via-transparent to-transparent"></div>
|
||||
</div>
|
||||
|
||||
{/* Content details */}
|
||||
<div className="p-6 md:p-8 flex flex-col flex-1 justify-between space-y-6">
|
||||
<div className="space-y-3">
|
||||
<span className="text-[10px] uppercase font-bold tracking-[0.2em] text-spa-gold block">
|
||||
{slide.category}
|
||||
</span>
|
||||
<h3 className="text-xl font-light font-serif tracking-wide text-spa-light">
|
||||
{renderTitle(slide.title) || slide.title}
|
||||
</h3>
|
||||
<p className="text-xs md:text-sm font-light text-spa-light/70 leading-relaxed line-clamp-3">
|
||||
{slide.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{slide.buttonText && slide.buttonLink && (
|
||||
<div className="pt-2">
|
||||
<Link
|
||||
to={slide.buttonLink}
|
||||
className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-spa-gold hover:text-white transition-colors group/link"
|
||||
>
|
||||
{slide.buttonText}
|
||||
<span className="group-hover/link:translate-x-1 transition-transform">→</span>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user