"use client"; import { use, useEffect, useRef } from "react"; import Link from "next/link"; import { ArrowLeft, ExternalLink, User } from "lucide-react"; import { useBill, useBillNews, useBillTrend } from "@/lib/hooks/useBills"; import { BriefPanel } from "@/components/bills/BriefPanel"; import { ActionTimeline } from "@/components/bills/ActionTimeline"; import { TrendChart } from "@/components/bills/TrendChart"; import { NewsPanel } from "@/components/bills/NewsPanel"; import { FollowButton } from "@/components/shared/FollowButton"; import { billLabel, congressLabel, formatDate, partyBadgeColor, cn } from "@/lib/utils"; export default function BillDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params); const billId = decodeURIComponent(id); const { data: bill, isLoading } = useBill(billId); const { data: trendData } = useBillTrend(billId, 30); const { data: newsArticles, refetch: refetchNews } = useBillNews(billId); // When the bill page is opened with no stored articles, the backend queues // a Celery news-fetch task that takes a few seconds to complete. // Retry up to 3 times (every 6 s) so articles appear without a manual refresh. // newsRetryRef resets on bill navigation so each bill gets its own retry budget. const newsRetryRef = useRef(0); useEffect(() => { newsRetryRef.current = 0; }, [billId]); useEffect(() => { if (newsArticles === undefined || newsArticles.length > 0) return; if (newsRetryRef.current >= 3) return; const timer = setTimeout(() => { newsRetryRef.current += 1; refetchNews(); }, 6000); return () => clearTimeout(timer); }, [newsArticles]); // eslint-disable-line react-hooks/exhaustive-deps if (isLoading) { return
Bill not found.
← Back to bills
Introduced: {formatDate(bill.introduced_date)}
{bill.congress_url && (
congress.gov