- Header.tsx: bare linkedin/instagram/facebook URLs → /broadcastbeat handles; remove TwitterXIcon from social bar + import (Footer retains TwitterXIcon per "DO NOT OVERRIDE" marker) - AboutDropdown.tsx: drop "Press kit" item (the page itself stays at /about/press-kit, just delisted from menu) - SystemStatusBar.tsx: remove "Index online" pulse-dot and "N wire sources" span (keep articles count + events count + build version) - /about, /about/team, /about/press-kit: wrap in Header+Footer (previously rendered bare <main>) - /newsletter/page.tsx (new): redirect to /newsletter/archive — Header was 404'ing on /newsletter - /rss/route.ts (new): dynamic RSS feed reading from legacy-source news section; replaces 404 at /rss Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
2.5 KiB
TypeScript
74 lines
2.5 KiB
TypeScript
import { createClient } from "@supabase/supabase-js";
|
|
import Header from "@/components/Header";
|
|
import Footer from "@/components/Footer";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
export const revalidate = 600;
|
|
|
|
export const metadata = {
|
|
title: "Editorial team — BroadcastBeat",
|
|
description: "Meet the BroadcastBeat editorial team — staff journalists covering broadcast, streaming, and post-production beats.",
|
|
};
|
|
|
|
interface Persona {
|
|
slug: string;
|
|
name: string;
|
|
bio: string | null;
|
|
beat: string | null;
|
|
avatar_url: string | null;
|
|
}
|
|
|
|
export default async function TeamPage() {
|
|
const sb = createClient(
|
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
{
|
|
db: { schema: (process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb") as "public" },
|
|
auth: { persistSession: false },
|
|
}
|
|
);
|
|
const { data } = await sb
|
|
.from("ai_personas")
|
|
.select("slug, name, bio, beat, avatar_url")
|
|
.eq("active", true);
|
|
const team = (data || []) as Persona[];
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background">
|
|
<Header />
|
|
<main className="mx-auto max-w-5xl px-6 py-12 text-[#e5e7eb]">
|
|
<h1 className="font-serif text-4xl font-bold tracking-tight mb-2">Editorial team</h1>
|
|
<p className="text-sm text-[#9ca3af] mb-10">
|
|
Staff journalists by beat. We are a mix of human reporters and trained
|
|
AI personas operating under house style.
|
|
</p>
|
|
<ul className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
|
{team.map((p) => (
|
|
<li key={p.slug} className="rounded border border-[#252525] bg-[#0b0f17] p-5 flex gap-4">
|
|
{p.avatar_url && (
|
|
<img
|
|
src={p.avatar_url}
|
|
alt={p.name}
|
|
width={64}
|
|
height={64}
|
|
className="rounded-full border border-[#252525]"
|
|
/>
|
|
)}
|
|
<div className="flex-1">
|
|
<h2 className="font-serif text-lg font-semibold">{p.name}</h2>
|
|
{p.beat && (
|
|
<div className="text-[10px] font-mono uppercase tracking-wider text-[var(--color-text-info,#60a5fa)] mt-0.5">
|
|
{p.beat.replace(/-/g, " ")}
|
|
</div>
|
|
)}
|
|
{p.bio && <p className="text-sm text-[#9ca3af] mt-2 leading-relaxed">{p.bio}</p>}
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</main>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|