spb/cancerindex
Public
1import Link from 'next/link';2import { Badge, ClaimBadge, StatusBadge } from '@/components/ui/badge';3import { SourceBadge } from '@/components/ui/source-badge';4import type { ApprovalRow } from '@/lib/queries/drugs';5import type { ProvRow } from '@/lib/queries/provenance';6import { toInfo } from '@/lib/queries/provenance';7import { fmtDate } from '@/lib/format';89/** Jurisdiction-aware regulatory status (§13). Never a bare "approved". */10export function ApprovalsTable({ rows, prov, showDrug = true, showCancer = true }: { rows: ApprovalRow[]; prov: Map<number, ProvRow>; showDrug?: boolean; showCancer?: boolean }) {11 return (12 <div className="ci-table-wrap">13 <table className="ci-table">14 <thead>15 <tr>16 {showDrug ? <th>Drug</th> : null}17 <th>Jurisdiction · authority</th>18 {showCancer ? <th>Cancer</th> : null}19 <th>Indication</th>20 <th>Status</th>21 <th>Approval date</th>22 <th>Source</th>23 </tr>24 </thead>25 <tbody>26 {rows.map((a) => (27 <tr key={a.id}>28 {showDrug ? (29 <td>30 <Link className="ci-link" href={`/drug/${a.drug_slug}`}>31 {a.drug_name}32 </Link>33 </td>34 ) : null}35 <td className="whitespace-nowrap">36 <span className="ci-mono font-medium">{a.jurisdiction}</span> <span className="text-ink-3">{a.authority}</span>37 </td>38 {showCancer ? (39 <td>40 {a.tumor_agnostic ? <Badge tone="accent">Tumor-agnostic</Badge> : null}41 {a.cancer_slug ? (42 <Link className="ci-link" href={`/cancer/${a.cancer_slug}`}>43 {a.cancer_name}44 </Link>45 ) : !a.tumor_agnostic ? (46 <span className="text-ink-3">—</span>47 ) : null}48 </td>49 ) : null}50 <td className="min-w-[280px] max-w-[520px] text-[12.5px]">51 {a.indication}52 <span className="mt-0.5 flex flex-wrap gap-1">53 {a.line_of_therapy ? <Badge tone="outline">{a.line_of_therapy}</Badge> : null}54 {a.disease_stage ? <Badge tone="outline">{a.disease_stage}</Badge> : null}55 {a.accelerated ? <Badge tone="warn">accelerated</Badge> : null}56 {a.conditional ? <Badge tone="warn">conditional</Badge> : null}57 {a.biomarker_ids.length ? <Badge tone="outline">biomarker-restricted</Badge> : null}58 </span>59 </td>60 <td>61 <StatusBadge status={a.status} />62 {a.withdrawal_date ? <span className="block text-[11px] text-danger">withdrawn {fmtDate(a.withdrawal_date)}</span> : null}63 </td>64 <td className="whitespace-nowrap">{fmtDate(a.approval_date)}</td>65 <td>66 <span className="inline-flex gap-1">67 <SourceBadge p={toInfo(prov.get(a.provenance_id)) ?? { sourceSlug: a.source_slug, sourceName: a.source_name }} />68 <ClaimBadge kind="regulatory" />69 </span>70 </td>71 </tr>72 ))}73 </tbody>74 </table>75 </div>76 );77}78