import { createClient } from "@supabase/supabase-js"; import { rewriteLegacyImageUrl } from "@/lib/legacy-image"; import FeaturedCarousel from "./FeaturedCarousel"; export const dynamic = "force-dynamic"; function initials(name: string): string { const parts = name.split(/\s+/).filter(Boolean); if (parts.length === 0) return "??"; const first = parts[0][0] || ""; const last = parts.length > 1 ? parts[parts.length - 1][0] || "" : ""; return (first + last).toUpperCase(); } function readTime(text: string | null | undefined): number { if (!text) return 1; const words = text.replace(/<[^>]+>/g, " ").split(/\s+/).filter(Boolean).length; return Math.max(1, Math.round(words / 200)); } function agoMinutes(iso: string | null): number { if (!iso) return 0; return Math.max(0, Math.floor((Date.now() - new Date(iso).getTime()) / 60000)); } export default async function FeaturedCarouselServer() { 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 [wp, ai] = await Promise.all([ sb .from("wp_imported_posts") .select("wp_id, wp_slug, title, excerpt, content, featured_image, author_name, category, wp_published_at, neural_summary") .eq("status", "published") .eq("featured", true) .order("wp_published_at", { ascending: false }) .limit(5), sb .from("ai_rewritten_articles") .select("id, slug, title, excerpt, body, category, published_at, neural_summary, persona:ai_personas(name, beat)") .eq("status", "published") .eq("featured", true) .order("published_at", { ascending: false, nullsFirst: false }) .limit(5), ]); const slides: any[] = []; for (const r of (ai.data || []) as any[]) { const persona = Array.isArray(r.persona) ? r.persona[0] : r.persona; const author = persona?.name || "Staff Reporter"; slides.push({ id: r.id, slug: r.slug, title: r.title, excerpt: r.excerpt || "", image: null, category: r.category || "News", author, author_initials: initials(author), author_beat: persona?.beat || null, date: r.published_at, read_min: readTime(r.body), ago_min: agoMinutes(r.published_at), neural_summary: r.neural_summary || null, }); } for (const r of (wp.data || []) as any[]) { const image = r.featured_image ? rewriteLegacyImageUrl(r.featured_image) : null; const author = r.author_name || "Staff Reporter"; slides.push({ id: String(r.wp_id), slug: r.wp_slug, title: r.title, excerpt: r.excerpt || "", image, category: r.category || "News", author, author_initials: initials(author), author_beat: null, date: r.wp_published_at, read_min: readTime(r.content), ago_min: agoMinutes(r.wp_published_at), neural_summary: r.neural_summary || null, }); } // Cap to 5 most recent across both sources slides.sort((a, b) => new Date(b.date || 0).getTime() - new Date(a.date || 0).getTime()); const top5 = slides.slice(0, 5); if (top5.length === 0) return null; return ; }