106 lines
3.7 KiB
TypeScript
106 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { AlertTriangle, CheckCircle, Clock, Cpu, Tag } from "lucide-react";
|
|
import { BriefSchema } from "@/lib/types";
|
|
import { formatDate } from "@/lib/utils";
|
|
|
|
interface AIBriefCardProps {
|
|
brief?: BriefSchema | null;
|
|
}
|
|
|
|
export function AIBriefCard({ brief }: AIBriefCardProps) {
|
|
if (!brief) {
|
|
return (
|
|
<div className="bg-card border border-border rounded-lg p-6">
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<Cpu className="w-4 h-4 text-muted-foreground" />
|
|
<h2 className="font-semibold">AI Analysis</h2>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground italic">
|
|
Analysis not yet generated. It will appear once the bill text has been processed.
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="bg-card border border-border rounded-lg p-6 space-y-5">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<Cpu className="w-4 h-4 text-primary" />
|
|
<h2 className="font-semibold">AI Analysis</h2>
|
|
</div>
|
|
<span className="text-xs text-muted-foreground">
|
|
{brief.llm_provider}/{brief.llm_model} · {formatDate(brief.created_at)}
|
|
</span>
|
|
</div>
|
|
|
|
{brief.summary && (
|
|
<div>
|
|
<h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2">Summary</h3>
|
|
<p className="text-sm leading-relaxed whitespace-pre-line">{brief.summary}</p>
|
|
</div>
|
|
)}
|
|
|
|
{brief.key_points && brief.key_points.length > 0 && (
|
|
<div>
|
|
<h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2">Key Points</h3>
|
|
<ul className="space-y-1.5">
|
|
{brief.key_points.map((point, i) => (
|
|
<li key={i} className="flex items-start gap-2 text-sm">
|
|
<CheckCircle className="w-3.5 h-3.5 mt-0.5 text-green-500 shrink-0" />
|
|
<span>{point}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
|
|
{brief.risks && brief.risks.length > 0 && (
|
|
<div>
|
|
<h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2">Risks & Concerns</h3>
|
|
<ul className="space-y-1.5">
|
|
{brief.risks.map((risk, i) => (
|
|
<li key={i} className="flex items-start gap-2 text-sm">
|
|
<AlertTriangle className="w-3.5 h-3.5 mt-0.5 text-yellow-500 shrink-0" />
|
|
<span>{risk}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
|
|
{brief.deadlines && brief.deadlines.length > 0 && (
|
|
<div>
|
|
<h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-2">Deadlines</h3>
|
|
<ul className="space-y-1.5">
|
|
{brief.deadlines.map((d, i) => (
|
|
<li key={i} className="flex items-start gap-2 text-sm">
|
|
<Clock className="w-3.5 h-3.5 mt-0.5 text-blue-500 shrink-0" />
|
|
<span>
|
|
{d.date ? <strong>{formatDate(d.date)}: </strong> : ""}
|
|
{d.description}
|
|
</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
|
|
{brief.topic_tags && brief.topic_tags.length > 0 && (
|
|
<div className="flex items-center gap-2 pt-1 border-t border-border flex-wrap">
|
|
<Tag className="w-3.5 h-3.5 text-muted-foreground shrink-0" />
|
|
{brief.topic_tags.map((tag) => (
|
|
<span
|
|
key={tag}
|
|
className="text-xs px-2 py-1 bg-accent text-accent-foreground rounded-full"
|
|
>
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|