- Replaces the prior Rocket scaffold (saved on pre-bb-clone-rollback branch) - Domain: broadcastbeat.com -> avbeat.com - Brand: Broadcast Beat -> AV Beat - Slug: broadcastbeat -> avbeat (package, identifiers) - Schema fallback: bb -> av (env var name unchanged) - Placeholder AV BEAT logo (gold->red gradient) at /assets/logos/av.svg - All BB/RMP logo references repointed Outstanding before public DNS swap: - Supabase av schema bootstrap (mirror of bb tables) - WordPress archive import (avbeat-com -> av.articles) - Coolify env vars - dev-avbeat.onsethost.com staging deploy + visual review
103 lines
3.5 KiB
TypeScript
103 lines
3.5 KiB
TypeScript
import Link from "next/link";
|
|
import { createAdminClient } from "@/lib/supabase/admin";
|
|
|
|
type Sponsor = {
|
|
slug: string;
|
|
name: string;
|
|
logoUrl: string | null;
|
|
};
|
|
|
|
async function fetchSponsors(): Promise<Sponsor[]> {
|
|
try {
|
|
const adv = createAdminClient("adv");
|
|
const { data: ads } = await adv
|
|
.from("active_advertisers_by_property")
|
|
.select("company_name_lower")
|
|
.eq("property", "avbeat");
|
|
const names = Array.from(new Set((ads || []).map((r: any) => String(r.company_name_lower))));
|
|
|
|
const bb = createAdminClient();
|
|
const bySlug = new Map<string, Sponsor>();
|
|
|
|
// Layer 1 — currently active advertisers.
|
|
if (names.length > 0) {
|
|
const { data: dir } = await bb
|
|
.from("tracked_companies")
|
|
.select("slug, company_name, logo_url")
|
|
.eq("directory_visible", true)
|
|
.in("company_name", names.map((n) => n));
|
|
for (const d of (dir || []) as any[]) {
|
|
bySlug.set(d.slug, { slug: d.slug, name: d.company_name, logoUrl: d.logo_url || null });
|
|
}
|
|
const matchedNames = new Set((dir || []).map((d: any) => String(d.company_name).toLowerCase()));
|
|
const missing = names.filter((n) => !matchedNames.has(n));
|
|
for (const n of missing) {
|
|
const { data: hit } = await bb
|
|
.from("tracked_companies")
|
|
.select("slug, company_name, logo_url")
|
|
.eq("directory_visible", true)
|
|
.ilike("company_name", n)
|
|
.limit(1)
|
|
.maybeSingle();
|
|
if (hit) bySlug.set(hit.slug, { slug: hit.slug, name: hit.company_name, logoUrl: hit.logo_url || null });
|
|
}
|
|
}
|
|
|
|
// Layer 2 — pinned content partners (directory.featured=true). These
|
|
// surface here whether or not they have an active ad campaign.
|
|
const { data: pinned } = await bb
|
|
.from("tracked_companies")
|
|
.select("slug, company_name, logo_url")
|
|
.eq("directory_visible", true)
|
|
.eq("featured", true)
|
|
.limit(40);
|
|
for (const d of (pinned || []) as any[]) {
|
|
if (!bySlug.has(d.slug)) {
|
|
bySlug.set(d.slug, { slug: d.slug, name: d.company_name, logoUrl: d.logo_url || null });
|
|
}
|
|
}
|
|
|
|
return Array.from(bySlug.values()).filter((s) => s.logoUrl);
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export default async function SponsorLogoStrip() {
|
|
const sponsors = await fetchSponsors();
|
|
if (sponsors.length === 0) return null;
|
|
|
|
return (
|
|
<section className="max-w-container mx-auto px-4 py-6 border-t border-b border-[#1a1a1a]" aria-label="Content partners">
|
|
<div className="flex items-center gap-4 mb-3">
|
|
<span className="text-[10px] uppercase tracking-widest text-[#3b82f6] font-bold">
|
|
Content Partners
|
|
</span>
|
|
<div className="flex-1 h-px bg-[#1a1a1a]" />
|
|
<Link href="/advertise" className="text-[10px] text-[#666] hover:text-[#3b82f6] font-mono">
|
|
Advertise →
|
|
</Link>
|
|
</div>
|
|
<div className="flex flex-wrap items-center justify-center gap-x-8 gap-y-4">
|
|
{sponsors.map((s) => (
|
|
<Link
|
|
key={s.slug}
|
|
href={`/manufacturers/${s.slug}`}
|
|
data-company-slug={s.slug}
|
|
className="block opacity-70 hover:opacity-100 transition-opacity"
|
|
title={s.name}
|
|
>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img
|
|
src={s.logoUrl || ""}
|
|
alt={s.name}
|
|
className="h-14 md:h-16 w-auto object-contain max-w-[180px] bg-white p-2 rounded"
|
|
loading="lazy"
|
|
/>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|