Add chamber color badges, action history fallback, and task status polling
- Add chamberBadgeColor util: amber/gold for Senate, slate/silver for House - Apply chamber badge to BillCard and bill detail header - ActionTimeline: show latest_action_date/text as fallback when full history not yet fetched, with note that full history loads in background - Manual Controls: poll task status every 5s after triggering, show spinning indicator while running, task ID prefix, and completion/failure state Authored-By: Jack Levy
This commit is contained in:
@@ -4,10 +4,15 @@ import { formatDate } from "@/lib/utils";
|
||||
|
||||
interface ActionTimelineProps {
|
||||
actions: BillAction[];
|
||||
latestActionDate?: string;
|
||||
latestActionText?: string;
|
||||
}
|
||||
|
||||
export function ActionTimeline({ actions }: ActionTimelineProps) {
|
||||
if (!actions || actions.length === 0) {
|
||||
export function ActionTimeline({ actions, latestActionDate, latestActionText }: ActionTimelineProps) {
|
||||
const hasActions = actions && actions.length > 0;
|
||||
const hasFallback = !hasActions && latestActionText;
|
||||
|
||||
if (!hasActions && !hasFallback) {
|
||||
return (
|
||||
<div className="bg-card border border-border rounded-lg p-6">
|
||||
<h2 className="font-semibold mb-3 flex items-center gap-2">
|
||||
@@ -24,22 +29,38 @@ export function ActionTimeline({ actions }: ActionTimelineProps) {
|
||||
<h2 className="font-semibold mb-4 flex items-center gap-2">
|
||||
<Clock className="w-4 h-4" />
|
||||
Action History
|
||||
<span className="text-xs text-muted-foreground font-normal">({actions.length})</span>
|
||||
{hasActions && (
|
||||
<span className="text-xs text-muted-foreground font-normal">({actions.length})</span>
|
||||
)}
|
||||
</h2>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute left-2 top-0 bottom-0 w-px bg-border" />
|
||||
<ul className="space-y-4 pl-7">
|
||||
{actions.map((action, i) => (
|
||||
<li key={action.id} className="relative">
|
||||
<div className="absolute -left-5 top-1.5 w-2 h-2 rounded-full bg-primary/60 border-2 border-background" />
|
||||
{hasActions ? (
|
||||
actions.map((action) => (
|
||||
<li key={action.id} className="relative">
|
||||
<div className="absolute -left-5 top-1.5 w-2 h-2 rounded-full bg-primary/60 border-2 border-background" />
|
||||
<div className="text-xs text-muted-foreground mb-0.5">
|
||||
{formatDate(action.action_date)}
|
||||
{action.chamber && ` · ${action.chamber}`}
|
||||
</div>
|
||||
<p className="text-sm leading-snug">{action.action_text}</p>
|
||||
</li>
|
||||
))
|
||||
) : (
|
||||
<li className="relative">
|
||||
<div className="absolute -left-5 top-1.5 w-2 h-2 rounded-full bg-muted-foreground/40 border-2 border-background" />
|
||||
<div className="text-xs text-muted-foreground mb-0.5">
|
||||
{formatDate(action.action_date)}
|
||||
{action.chamber && ` · ${action.chamber}`}
|
||||
{formatDate(latestActionDate)}
|
||||
<span className="ml-1.5 italic">· latest known action</span>
|
||||
</div>
|
||||
<p className="text-sm leading-snug">{action.action_text}</p>
|
||||
<p className="text-sm leading-snug">{latestActionText}</p>
|
||||
<p className="text-xs text-muted-foreground mt-1 italic">
|
||||
Full history loads in the background — refresh to see all actions.
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user