"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import { VitrineImage } from "./VitrineImage"; import { memberPath } from "@/lib/seo"; export type CarouselMember = { id: number; name: string; description: string | null; city: string | null; address: string | null; coverUrl: string | null; logoUrl: string | null; categoryLabel: string | null; accent: string | null; }; const VISIBLE = 3; const INTERVAL_MS = 20_000; const STAGGER_MS = 220; // décalage de disparition/apparition entre cartes const FADE_MS = 450; function Card({ m, visible, index }: { m: CarouselMember; visible: boolean; index: number }) { return ( {m.categoryLabel && ( {m.categoryLabel} )}

{m.name}

{m.description}

{[m.address, m.city].filter(Boolean).join(" · ")}
); } export function MembersCarousel({ members }: { members: CarouselMember[] }) { const [start, setStart] = useState(0); const [visible, setVisible] = useState(true); const total = members.length; const canRotate = total > VISIBLE; useEffect(() => { if (!canRotate) return; const tick = setInterval(() => { // Disparition une à une, puis changement, puis réapparition une à une. setVisible(false); const outMs = FADE_MS + STAGGER_MS * (VISIBLE - 1); setTimeout(() => { setStart((s) => (s + VISIBLE) % total); setVisible(true); }, outMs); }, INTERVAL_MS); return () => clearInterval(tick); }, [canRotate, total]); if (total === 0) return null; // Fenêtre de 3 cartes, avec bouclage propre si on dépasse la fin. const shown = Array.from({ length: Math.min(VISIBLE, total) }, (_, i) => members[(start + i) % total]); return (
{shown.map((m, i) => ( ))}
); }