// dashboard.jsx — table, filters, regional matrix, parties card
const { Badge, ConfBar, FlagSet, OUTCOME_ORDER, OUTCOME_LABELS, needsAttention } = window.MC_HELPERS;
const { useState: dbUseState, useMemo: dbUseMemo } = React;
function StatsStrip({ counts, total, attnCount }) {
return (
Required
{counts.required}
filings to prepare
Borderline
{counts.borderline}
judgement call
Info needed
{counts.info_needed}
data to gather
Not required
{counts.not_required}
cleared
Needs attention
{attnCount}
of {total} total
);
}
function PartiesCard({ matter }) {
return (
Deal parties
{matter.parties.map((p, i) => (
{p.role}
{p.name}
WW {p.worldwide}
{p.eu &&
EU {p.eu}
}
))}
Combined worldwide
{matter.combinedWorldwide}
FX convention
{matter.fxYear}
);
}
function Filters({ filters, setFilters, counts, total, shown }) {
const toggleOutcome = (o) => {
const cur = filters.outcomes;
setFilters({ ...filters, outcomes: cur.includes(o) ? cur.filter(x => x !== o) : [...cur, o] });
};
const allOutcomes = ["required", "borderline", "info_needed", "not_required", "excluded"];
const hasActiveFilters = filters.outcomes.length > 0 || filters.attnOnly || filters.overOnly || filters.search.trim();
const clearAll = () => setFilters({ search: "", outcomes: [], attnOnly: false, overOnly: false });
return (
);
}
function JurisdictionTable({ rows, sort, setSort, selectedIso, onSelect, screenedOutCount, onClearFilters }) {
const headers = [
{ key: "iso", label: "ISO", cls: "col-iso" },
{ key: "name", label: "Jurisdiction", cls: "col-name" },
{ key: "region", label: "Region", cls: "col-region" },
{ key: "outcome", label: "Outcome", cls: "col-outcome" },
{ key: "toolOutcome",label: "AI view", cls: "col-tool", hint: "What the AI assessment said before any lawyer override" },
{ key: "confidence", label: "Conf.", cls: "col-conf" },
{ key: "flags", label: "Flags", cls: "col-flags" },
];
const setSortKey = (k) => {
if (sort.key === k) setSort({ key: k, dir: sort.dir === "asc" ? "desc" : "asc" });
else setSort({ key: k, dir: "asc" });
};
return (
Jurisdiction assessment
sortable · click row to inspect
{rows.length === 0 ? (
No jurisdictions match these filters
Try removing one of the active filters to see results.
{onClearFilters &&
}
) : (
{headers.map((h) => (
| setSortKey(h.key)}>
{h.label}
{sort.key === h.key ? (sort.dir === "asc" ? "▲" : "▼") : "↕"}
|
))}
{rows.map((r) => {
const eff = r.lawyerOutcome || r.outcome;
return (
onSelect(r.iso)}
>
| {r.iso} |
{r.name}{(r.iso === "EU" || r.iso === "COMESA" || r.iso === "CEMAC") && supranational} |
{regionShort(r.region)} |
|
{r.toolOutcome === eff ? "—" : window.MC_HELPERS.OUTCOME_LABELS[r.toolOutcome]} |
|
|
);
})}
)}
{screenedOutCount > 0 && rows.length > 0 && (
+ {screenedOutCount} jurisdictions deterministically screened out before LLM evaluation (below conservative turnover floor or no local nexus).
)}
);
}
function regionShort(r) {
return {
eu: "European Union",
eea: "Europe (non-EU)",
americas: "Americas",
apac: "Asia-Pacific",
mea: "Middle East & Africa",
}[r] || r;
}
// Regional matrix "map" — secondary visualization
function RegionalMatrix({ rows, regions, selectedIso, onSelect }) {
const byRegion = {};
rows.forEach((r) => {
if (!byRegion[r.region]) byRegion[r.region] = [];
byRegion[r.region].push(r);
});
return (
Regional overview
{regions.map((reg) => {
const items = byRegion[reg.id] || [];
if (!items.length) return null;
// Sort: required/borderline first, then info, notreq, excluded
const order = { required: 0, borderline: 1, info_needed: 2, not_required: 3, excluded: 4 };
items.sort((a, b) => order[a.outcome] - order[b.outcome] || a.name.localeCompare(b.name));
return (
{regionShort(reg.id)}
{items.map((r) => {
const isSupra = r.iso === "EU" || r.iso === "COMESA" || r.iso === "CEMAC";
return (
2 ? "wide" : ""} ${isSupra ? "supra" : ""}`}
title={`${r.name} — ${OUTCOME_LABELS[r.lawyerOutcome || r.outcome]}`}
onClick={() => onSelect(r.iso)}
>
{r.iso}
);
})}
);
})}
Required
Borderline
Info needed
Not required
Screened out
);
}
Object.assign(window, { StatsStrip, PartiesCard, Filters, JurisdictionTable, RegionalMatrix });