"use client";
import { use } from "react";
import Link from "next/link";
import Image from "next/image";
import {
ArrowLeft,
ExternalLink,
MapPin,
Phone,
Globe,
Star,
FileText,
Users,
} from "lucide-react";
import { useMember, useMemberBills, useMemberTrend, useMemberNews } from "@/lib/hooks/useMembers";
import { TrendChart } from "@/components/bills/TrendChart";
import { NewsPanel } from "@/components/bills/NewsPanel";
import { FollowButton } from "@/components/shared/FollowButton";
import { BillCard } from "@/components/shared/BillCard";
import { cn, partyBadgeColor } from "@/lib/utils";
function ordinal(n: number) {
const s = ["th", "st", "nd", "rd"];
const v = n % 100;
return n + (s[(v - 20) % 10] || s[v] || s[0]);
}
export default function MemberDetailPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = use(params);
const { data: member, isLoading } = useMember(id);
const { data: billsData } = useMemberBills(id);
const { data: trendData } = useMemberTrend(id, 30);
const { data: newsData } = useMemberNews(id);
if (isLoading) return
Loading...
;
if (!member) return Member not found.
;
const currentLeadership = member.leadership_json?.filter((l) => l.current);
const termsSorted = [...(member.terms_json || [])].reverse();
return (
{/* Back */}
Members
{/* Bio header */}
{member.photo_url ? (
) : (
)}
{member.name}
{member.party && (
{member.party}
)}
{member.chamber && {member.chamber}}
{member.state && {member.state}}
{member.district && District {member.district}}
{member.birth_year && (
b. {member.birth_year}
)}
{/* Leadership */}
{currentLeadership && currentLeadership.length > 0 && (
{currentLeadership.map((l, i) => (
{l.type}
))}
)}
{/* Contact */}
{member.address && (
{member.address}
)}
{member.phone && (
)}
{member.official_url && (
)}
{member.congress_url && (
)}
{/* Left column */}
{/* Sponsored bills */}
Sponsored Bills
{billsData?.total != null && (
({billsData.total})
)}
{!billsData?.items?.length ? (
No bills found.
) : (
{billsData.items.map((bill) => )}
)}
{/* Right column */}
{/* Public Interest */}
{/* News */}
{/* Legislation stats */}
{(member.sponsored_count != null || member.cosponsored_count != null) && (
Legislation
{member.sponsored_count != null && (
Sponsored
{member.sponsored_count.toLocaleString()}
)}
{member.cosponsored_count != null && (
Cosponsored
{member.cosponsored_count.toLocaleString()}
)}
)}
{/* Service history */}
{termsSorted.length > 0 && (
Service History
{termsSorted.map((term, i) => (
{term.congress ? `${ordinal(term.congress)} Congress` : ""}
{term.startYear && term.endYear
? ` (${term.startYear}–${term.endYear})`
: term.startYear
? ` (${term.startYear}–present)`
: ""}
{[term.chamber, term.partyName, term.stateName].filter(Boolean).join(" · ")}
{term.district ? ` · District ${term.district}` : ""}
))}
)}
{/* All leadership roles */}
{member.leadership_json && member.leadership_json.length > 0 && (
Leadership Roles
{member.leadership_json.map((l, i) => (
{l.type}
{l.congress ? `${ordinal(l.congress)}` : ""}
))}
)}
);
}