"use client"; import { useRouter } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import { openBusinessDashboardAsAdmin } from "@/lib/session-handoff"; import { getSpecialBusinesses } from "@/services/special-businesses"; import type { BusinessStatus, MarketplaceBusiness } from "@/types/business"; import styles from "./BusinessCardList.module.css"; const STATUS_LABEL: Record = { draft: "Pending", pending_review: "Pending", published: "Published", hidden: "Hidden", rejected: "Rejected", }; const websiteUrl = process.env.NEXT_PUBLIC_WEBSITE_URL?.replace(/\/$/, "") || "http://localhost:3000"; function statusClass(status: BusinessStatus) { switch (status) { case "published": return styles.statusLive; case "pending_review": case "draft": return styles.statusReview; case "hidden": return styles.statusHidden; case "rejected": return styles.statusRejected; default: return styles.statusReview; } } function publicUrl(slug: string) { return `${websiteUrl}/businesses/${slug}`; } export default function BusinessCardList({ items, onApprove, onDisable, onRemove, onMetaTag, onMakeSpecial, busyId, specialTick = 0, emptyTitle = "No businesses yet", emptyCopy = "Marketplace listings will appear here once you link a Meshkee business.", }: { items: MarketplaceBusiness[]; onApprove?: (business: MarketplaceBusiness) => void; onDisable?: (business: MarketplaceBusiness) => void; onRemove?: (business: MarketplaceBusiness) => void; onMetaTag?: (business: MarketplaceBusiness) => void; onMakeSpecial?: (business: MarketplaceBusiness) => void; busyId?: string | null; /** Bump to reload special-carousel membership chips */ specialTick?: number; emptyTitle?: string; emptyCopy?: string; }) { const router = useRouter(); const [openMoreId, setOpenMoreId] = useState(null); const [specialCountByBusinessId, setSpecialCountByBusinessId] = useState< Map >(() => new Map()); const moreRefs = useRef>(new Map()); useEffect(() => { if (!openMoreId) return; const onPointerDown = (event: PointerEvent) => { const root = moreRefs.current.get(openMoreId); if (root && !root.contains(event.target as Node)) { setOpenMoreId(null); } }; window.addEventListener("pointerdown", onPointerDown); return () => window.removeEventListener("pointerdown", onPointerDown); }, [openMoreId]); useEffect(() => { let cancelled = false; void (async () => { try { const config = await getSpecialBusinesses(); if (cancelled) return; const next = new Map(); for (const carousel of config.carousels) { for (const businessId of carousel.businessIds) { next.set(businessId, (next.get(businessId) ?? 0) + 1); } } setSpecialCountByBusinessId(next); } catch { if (!cancelled) setSpecialCountByBusinessId(new Map()); } })(); return () => { cancelled = true; }; }, [specialTick, items.length]); if (items.length === 0) { return (

{emptyTitle}

{emptyCopy}

); } return (
    {items.map((business) => { const displayName = business.name || business.slug; const category = business.categoryName || "Uncategorized"; const categoryTrail = business.categoryTrail || business.categoryName || "Uncategorized"; const href = publicUrl(business.slug); const showHref = `/businesses/${business.id}`; const isHidden = business.status === "hidden"; const isPending = business.status === "pending_review" || business.status === "draft"; const canPublish = isPending || business.status === "rejected"; const isBusy = busyId === business.id; const moreOpen = openMoreId === business.id; const specialCount = specialCountByBusinessId.get(business.id) ?? 0; function openShow() { router.push(showHref); } return (
  • { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); openShow(); } }} >
    {business.bannerUrl ? ( ) : (
    )} {STATUS_LABEL[business.status]}
    {business.logoUrl ? ( ) : ( {displayName.slice(0, 1).toUpperCase()} )}

    {displayName}

    {category}

    {categoryTrail} {business.isFeatured ? ( Featured ) : null}
    event.stopPropagation()} onKeyDown={(event) => event.stopPropagation()} > {canPublish && onApprove ? ( ) : null}
    { if (node) moreRefs.current.set(business.id, node); else moreRefs.current.delete(business.id); }} >
    setOpenMoreId(null)} > Website {onMakeSpecial ? ( ) : null} {!isPending ? ( ) : null}
  • ); })}
); }