"use client"; import { useMemo, useState } from "react"; import Link from "next/link"; export type DirectoryMember = { id: number; name: string; description: string | null; city: string | null; address: string | null; categoryLabel: string | null; accent: string | null; hasPromo: boolean; promoBadge: string | null; }; const STRIPE_WARM = "repeating-linear-gradient(45deg,#efe9da,#efe9da 12px,#e6ddc9 12px,#e6ddc9 24px)"; const STRIPE_COOL = "repeating-linear-gradient(45deg,#eef0ec,#eef0ec 12px,#e2e8e6 12px,#e2e8e6 24px)"; export function AnnuaireClient({ members, categories, initialQuery = "", }: { members: DirectoryMember[]; categories: { label: string; accent: string }[]; initialQuery?: string; }) { const [query, setQuery] = useState(initialQuery); const [city, setCity] = useState("Toutes les communes"); const [cat, setCat] = useState("Tous"); const [sort, setSort] = useState<"az" | "promo">("az"); const communes = useMemo(() => { const set = new Set(); members.forEach((m) => m.city && set.add(m.city)); return Array.from(set).sort((a, b) => a.localeCompare(b, "fr")); }, [members]); const counts = useMemo(() => { const c: Record = { Tous: members.length }; members.forEach((m) => { if (m.categoryLabel) c[m.categoryLabel] = (c[m.categoryLabel] ?? 0) + 1; }); return c; }, [members]); const chips = useMemo(() => { const used = categories.filter((c) => (counts[c.label] ?? 0) > 0); return [{ label: "Tous", accent: "#13324F" }, ...used]; }, [categories, counts]); const list = useMemo(() => { const q = query.trim().toLowerCase(); let out = members.filter((m) => { if (cat !== "Tous" && m.categoryLabel !== cat) return false; if (city !== "Toutes les communes" && m.city !== city) return false; if ( q && !( m.name.toLowerCase().includes(q) || (m.categoryLabel ?? "").toLowerCase().includes(q) || (m.description ?? "").toLowerCase().includes(q) ) ) return false; return true; }); if (sort === "az") out = [...out].sort((a, b) => a.name.localeCompare(b.name, "fr")); else if (sort === "promo") out = [...out].sort((a, b) => Number(b.hasPromo) - Number(a.hasPromo)); return out; }, [members, query, city, cat, sort]); const filterLabel = (cat !== "Tous" ? " · " + cat : "") + (city !== "Toutes les communes" ? " · " + city : ""); function reset() { setQuery(""); setCity("Toutes les communes"); setCat("Tous"); setSort("az"); } const fieldStyle: React.CSSProperties = { border: "1px solid #ddd2bb", borderRadius: 11, padding: "0 13px", background: "#faf7ef", fontSize: 14, fontFamily: "'Public Sans'", color: "#3c3322", }; return ( <> {/* search + filters */}
setQuery(e.target.value)} placeholder="Nom du commerçant, métier…" style={{ border: "none", background: "transparent", outline: "none", padding: "13px 0", fontSize: 14.5, fontFamily: "'Public Sans'", width: "100%", color: "#3c3322" }} />
{chips.map((c) => { const active = cat === c.label; return ( ); })}
{/* result count + sort */}
{list.length} adhérent(s) {filterLabel}
Trier par
{/* grid / empty */} {list.length > 0 ? (
{list.map((m, i) => (
photo vitrine {m.categoryLabel && ( {m.categoryLabel} )} {m.hasPromo && m.promoBadge && ( {m.promoBadge} )}

{m.name}

{m.description}

{[m.address, m.city].filter(Boolean).join(" · ")}
))}
) : (
Aucun adhérent trouvé

Essayez un autre mot-clé, une autre commune ou catégorie.

)} ); }