diff --git a/src/app/home-page/page.tsx b/src/app/home-page/page.tsx index 50fc7f9..7f0b5b9 100644 --- a/src/app/home-page/page.tsx +++ b/src/app/home-page/page.tsx @@ -2,6 +2,7 @@ import React, { Suspense } from "react"; import type { Metadata } from "next"; import Header from "@/components/Header"; import Footer from "@/components/Footer"; +import FeaturedBentoFromDb from '@/components/FeaturedBentoFromDb'; import FeaturedCarouselServer from '@/components/FeaturedCarouselServer'; import TrendsSidebar from '@/components/TrendsSidebar'; import LiveWireTicker from '@/components/LiveWireTicker'; @@ -158,7 +159,7 @@ export default function HomePage() { {/* Featured articles bento */} }> - + diff --git a/src/components/FeaturedBentoFromDb.tsx b/src/components/FeaturedBentoFromDb.tsx new file mode 100644 index 0000000..e4fb61c --- /dev/null +++ b/src/components/FeaturedBentoFromDb.tsx @@ -0,0 +1,136 @@ +import Link from "next/link"; +import { createClient } from "@supabase/supabase-js"; +import { rewriteLegacyImageUrl } from "@/lib/legacy-image"; + +export const dynamic = "force-dynamic"; + +interface Row { + wp_id: number; + wp_slug: string; + title: string; + excerpt: string | null; + category: string | null; + featured_image: string | null; + featured_image_alt: string | null; + author_name: string | null; + wp_published_at: string | null; + featured: boolean; +} + +function ago(iso: string | null): string { + if (!iso) return ""; + const t = Date.now() - new Date(iso).getTime(); + const m = Math.floor(t / 60000); + if (m < 60) return `${m}m ago`; + const h = Math.floor(m / 60); + if (h < 24) return `${h}h ago`; + const d = Math.floor(h / 24); + return d < 30 ? `${d}d ago` : new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }); +} + +export default async function FeaturedBento() { + 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 }, + } + ); + + // Pool: every published row in the Featured category. Sort: pinned + // hero (featured=true) first, then by date desc. + const { data } = await sb + .from("wp_imported_posts") + .select("wp_id, wp_slug, title, excerpt, category, featured_image, featured_image_alt, author_name, wp_published_at, featured") + .eq("status", "published") + .ilike("category", "featured") + .order("featured", { ascending: false }) + .order("wp_published_at", { ascending: false, nullsFirst: false }) + .limit(7); + const rows = (data || []) as Row[]; + if (rows.length === 0) return null; + + const hero = rows[0]; + const rail = rows.slice(1, 5); + + function img(r: Row): string { + return r.featured_image ? rewriteLegacyImageUrl(r.featured_image) : "/assets/images/article-placeholder.svg"; + } + + return ( + + + + Featured · staff editorial + + + All featured → + + + + + + + + + + Featured + + + {hero.category || "News"} + + + + + + {hero.title} + + {hero.excerpt && ( + + {hero.excerpt} + + )} + + {hero.author_name || "Staff Reporter"} + · + {ago(hero.wp_published_at)} + + + + + + {rail.map((r) => ( + + + + + + + {r.category || "News"} + + + {r.title} + + + {ago(r.wp_published_at)} + + + + ))} + + + + ); +}
+ {hero.excerpt} +