home: hide dates on Featured posts site-wide; remove BB-AI trends sidebar
Dates
- FeaturedBentoFromDb hero + 4-up rail no longer render `ago(wp_published_at)`.
The whole component renders only Featured-category posts (filter is
category ILIKE 'featured'), so dropping the date display globally inside
it satisfies the "Featured posts have no date" requirement.
- /gear and /technology category cards: wrap the existing `{article.date}`
output in `{article.category !== "Featured" && ...}` so only non-Featured
posts continue to show their publish date.
- All other category landing pages, /news/<slug> detail, ArticleFeed, and
LiveWireTicker either don't render a visible article date or only use it
for SEO/structured-data fields (kept).
Trends sidebar
- Remove `BB AI · detected trends` block from the homepage (between
ArticleFeed and NewsletterSignup). Drop the unused import and delete
the orphaned TrendsSidebar.tsx component file. The detect-trends data
fetch and `bb_pulse_dot` mini-widget are gone from the page; nothing
else referenced them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,8 +62,12 @@ export default async function GearPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<span className="text-[#555] font-body text-[11px]">{article.date}</span>
|
{article.category !== "Featured" && (
|
||||||
<span className="text-[#444] text-[10px]">·</span>
|
<>
|
||||||
|
<span className="text-[#555] font-body text-[11px]">{article.date}</span>
|
||||||
|
<span className="text-[#444] text-[10px]">·</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<span className="text-[#555] font-body text-[11px]">{article.readTime}</span>
|
<span className="text-[#555] font-body text-[11px]">{article.readTime}</span>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="font-heading text-[#e0e0e0] text-sm font-bold leading-snug mb-2 group-hover:text-[#3b82f6] transition-colors line-clamp-3">
|
<h2 className="font-heading text-[#e0e0e0] text-sm font-bold leading-snug mb-2 group-hover:text-[#3b82f6] transition-colors line-clamp-3">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import Header from "@/components/Header";
|
|||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
import FeaturedBentoFromDb from '@/components/FeaturedBentoFromDb';
|
import FeaturedBentoFromDb from '@/components/FeaturedBentoFromDb';
|
||||||
import FeaturedCarouselServer from '@/components/FeaturedCarouselServer';
|
import FeaturedCarouselServer from '@/components/FeaturedCarouselServer';
|
||||||
import TrendsSidebar from '@/components/TrendsSidebar';
|
|
||||||
import LiveWireTicker from '@/components/LiveWireTicker';
|
import LiveWireTicker from '@/components/LiveWireTicker';
|
||||||
import NewsTicker from "./components/NewsTicker";
|
import NewsTicker from "./components/NewsTicker";
|
||||||
import FeaturedBento from "./components/FeaturedBento";
|
import FeaturedBento from "./components/FeaturedBento";
|
||||||
@@ -179,7 +178,6 @@ export default function HomePage() {
|
|||||||
|
|
||||||
{/* Newsletter signup */}
|
{/* Newsletter signup */}
|
||||||
<ScrollRevealSection className="section-enter section-enter-5">
|
<ScrollRevealSection className="section-enter section-enter-5">
|
||||||
<div className="max-w-container mx-auto px-4 mb-8"><TrendsSidebar /></div>
|
|
||||||
<NewsletterSignup />
|
<NewsletterSignup />
|
||||||
</ScrollRevealSection>
|
</ScrollRevealSection>
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,9 @@ export default async function TechnologyPage() {
|
|||||||
<h2 className="font-heading text-[#e0e0e0] text-sm font-bold leading-snug mb-1 group-hover:text-[#3b82f6] transition-colors line-clamp-2">
|
<h2 className="font-heading text-[#e0e0e0] text-sm font-bold leading-snug mb-1 group-hover:text-[#3b82f6] transition-colors line-clamp-2">
|
||||||
{article.title}
|
{article.title}
|
||||||
</h2>
|
</h2>
|
||||||
<span className="text-[#555] font-body text-[11px]">{article.date}</span>
|
{article.category !== "Featured" && (
|
||||||
|
<span className="text-[#555] font-body text-[11px]">{article.date}</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -106,8 +106,6 @@ export default async function FeaturedBento() {
|
|||||||
)}
|
)}
|
||||||
<div className="mt-4 flex flex-wrap items-center gap-3 text-[11px] font-mono text-[#9ca3af]">
|
<div className="mt-4 flex flex-wrap items-center gap-3 text-[11px] font-mono text-[#9ca3af]">
|
||||||
<span>{hero.author_name || "Broadcast Beat"}</span>
|
<span>{hero.author_name || "Broadcast Beat"}</span>
|
||||||
<span>·</span>
|
|
||||||
<span>{ago(hero.wp_published_at)}</span>
|
|
||||||
<span aria-hidden="true" className="text-[var(--color-text-info,#60a5fa)] ml-2">→ Read full story</span>
|
<span aria-hidden="true" className="text-[var(--color-text-info,#60a5fa)] ml-2">→ Read full story</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,9 +134,6 @@ export default async function FeaturedBento() {
|
|||||||
<h4 className="font-serif text-sm leading-tight text-[#e5e7eb] group-hover:text-[var(--color-text-info,#60a5fa)] line-clamp-3">
|
<h4 className="font-serif text-sm leading-tight text-[#e5e7eb] group-hover:text-[var(--color-text-info,#60a5fa)] line-clamp-3">
|
||||||
{r.title}
|
{r.title}
|
||||||
</h4>
|
</h4>
|
||||||
<div className="text-[10px] font-mono text-[#6b7280] mt-2">
|
|
||||||
{ago(r.wp_published_at)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
import { createClient } from "@supabase/supabase-js";
|
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
|
||||||
export const revalidate = 21600; // 6h
|
|
||||||
|
|
||||||
interface Article {
|
|
||||||
title: string;
|
|
||||||
excerpt: string | null;
|
|
||||||
tags: string[] | null;
|
|
||||||
published_at: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function detectTrends(recent: Article[], baseline: Article[]) {
|
|
||||||
const recentCounts: Record<string, number> = {};
|
|
||||||
for (const a of recent) for (const t of a.tags || []) {
|
|
||||||
const k = t.toLowerCase();
|
|
||||||
recentCounts[k] = (recentCounts[k] || 0) + 1;
|
|
||||||
}
|
|
||||||
const baseCounts: Record<string, number> = {};
|
|
||||||
for (const a of baseline) for (const t of a.tags || []) {
|
|
||||||
const k = t.toLowerCase();
|
|
||||||
baseCounts[k] = (baseCounts[k] || 0) + 1;
|
|
||||||
}
|
|
||||||
const scored = Object.entries(recentCounts).map(([k, c]) => {
|
|
||||||
const baseline_per_day = (baseCounts[k] || 0) / 30;
|
|
||||||
const recent_per_day = c / 7;
|
|
||||||
const lift = baseline_per_day > 0 ? recent_per_day / baseline_per_day : recent_per_day * 3;
|
|
||||||
return { entity: k, lift, count: c };
|
|
||||||
});
|
|
||||||
scored.sort((a, b) => b.lift - a.lift);
|
|
||||||
return scored.slice(0, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
function titleCase(s: string): string {
|
|
||||||
return s.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function TrendsSidebar() {
|
|
||||||
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 since7d = new Date(Date.now() - 7 * 86400000).toISOString();
|
|
||||||
const since30d = new Date(Date.now() - 30 * 86400000).toISOString();
|
|
||||||
const [recent, baseline] = await Promise.all([
|
|
||||||
sb
|
|
||||||
.from("wp_imported_posts")
|
|
||||||
.select("title, excerpt, tags, wp_published_at")
|
|
||||||
.eq("status", "published")
|
|
||||||
.gte("wp_published_at", since7d)
|
|
||||||
.order("wp_published_at", { ascending: false })
|
|
||||||
.limit(200),
|
|
||||||
sb
|
|
||||||
.from("wp_imported_posts")
|
|
||||||
.select("title, excerpt, tags, wp_published_at")
|
|
||||||
.eq("status", "published")
|
|
||||||
.gte("wp_published_at", since30d)
|
|
||||||
.lt("wp_published_at", since7d)
|
|
||||||
.order("wp_published_at", { ascending: false })
|
|
||||||
.limit(800),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const recentArts: Article[] = (recent.data || []).map((r: any) => ({
|
|
||||||
title: r.title, excerpt: r.excerpt, tags: r.tags, published_at: r.wp_published_at,
|
|
||||||
}));
|
|
||||||
const baselineArts: Article[] = (baseline.data || []).map((r: any) => ({
|
|
||||||
title: r.title, excerpt: r.excerpt, tags: r.tags, published_at: r.wp_published_at,
|
|
||||||
}));
|
|
||||||
const trends = detectTrends(recentArts, baselineArts);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<aside
|
|
||||||
className="rounded p-4"
|
|
||||||
style={{
|
|
||||||
background: "var(--color-trends-bg, #F5EFEB)",
|
|
||||||
color: "var(--color-trends-text, #2F4F5B)",
|
|
||||||
borderRadius: "var(--border-radius-md, 6px)",
|
|
||||||
}}
|
|
||||||
aria-label="BB AI detected trends"
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between mb-3">
|
|
||||||
<h2 className="font-serif text-base font-semibold">BB AI · detected trends</h2>
|
|
||||||
<span className="inline-flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-wider opacity-70">
|
|
||||||
<span className="bb-pulse-dot" style={{ background: "var(--color-trends-text, #2F4F5B)" }} />
|
|
||||||
live
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul className="space-y-1.5">
|
|
||||||
{trends.length === 0 && (
|
|
||||||
<li className="text-xs opacity-60">No trend data yet.</li>
|
|
||||||
)}
|
|
||||||
{trends.map((t) => (
|
|
||||||
<li key={t.entity} className="flex items-center justify-between text-sm">
|
|
||||||
<span className="truncate font-serif">{titleCase(t.entity)}</span>
|
|
||||||
<span className="font-mono text-[12px] opacity-80">
|
|
||||||
+{Math.round((t.lift - 1) * 100) || t.count}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</aside>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user