69 lines
2.6 KiB
React
69 lines
2.6 KiB
React
|
|
// Mobile-tuned atoms — larger touch targets, same visual language.
|
|||
|
|
// Re-uses .chip / .entity-badge / .tier / .amount from colors_and_type.css.
|
|||
|
|
|
|||
|
|
function MEntityBadge({ entity, size = "md" }) {
|
|||
|
|
const map = {
|
|||
|
|
personal: "personal", tfox: "tfox", finacode: "finacode",
|
|||
|
|
all: "personal"
|
|||
|
|
};
|
|||
|
|
const labels = { personal: "Personal", tfox: "9TFox", finacode: "Finacode", all: "All" };
|
|||
|
|
return <span className={`m-entity-badge ${map[entity]} sz-${size}`}>{labels[entity]}</span>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function MConfidenceChip({ score, tier }) {
|
|||
|
|
let cls = "low";
|
|||
|
|
if (tier === "rules" || (score !== null && score >= 1)) cls = "rules";
|
|||
|
|
else if (score !== null && score >= 0.85) cls = "high";
|
|||
|
|
else if (score !== null && score >= 0.70) cls = "mid";
|
|||
|
|
const display = score === null ? "—" : score.toFixed(2);
|
|||
|
|
return <span className={`m-chip ${cls}`}>★ {display}</span>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function MTierBadge({ tier }) {
|
|||
|
|
const map = { rules: "Rules", llm: "LLM", agent: "Agent", unmatched: "Unmatched" };
|
|||
|
|
return <span className={`m-tier ${tier}`}>{map[tier]}</span>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function MAmount({ value, ccy, big = false }) {
|
|||
|
|
if (value === null || value === undefined) return <span className="m-amount muted">—</span>;
|
|||
|
|
const cls = value > 0 ? "pos" : "neg";
|
|||
|
|
const sign = value > 0 ? "+ " : "− ";
|
|||
|
|
const abs = Math.abs(value);
|
|||
|
|
const formatted = abs.toLocaleString("en-US", { maximumFractionDigits: ccy === "EUR" ? 2 : 0 });
|
|||
|
|
return (
|
|||
|
|
<span className={`m-amount ${cls} ${big ? "big" : ""}`}>
|
|||
|
|
{sign}{formatted}<span className="m-ccy"> {ccy}</span>
|
|||
|
|
</span>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function MIcon({ name, size = 18, stroke = 1.5, color = "currentColor" }) {
|
|||
|
|
const d = window.ICONS_DATA[name];
|
|||
|
|
if (!d) return null;
|
|||
|
|
return (
|
|||
|
|
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round">
|
|||
|
|
<path d={d}/>
|
|||
|
|
</svg>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
window.ICONS_DATA = {
|
|||
|
|
check: "M20 6 L9 17 L4 12",
|
|||
|
|
x: "M18 6 L6 18 M6 6 L18 18",
|
|||
|
|
search: "M11 4 a7 7 0 1 0 0 14 a7 7 0 0 0 0 -14 M21 21 L16.65 16.65",
|
|||
|
|
chevDown: "M6 9 L12 15 L18 9",
|
|||
|
|
chevRight: "M9 6 L15 12 L9 18",
|
|||
|
|
chevLeft: "M15 6 L9 12 L15 18",
|
|||
|
|
plus: "M12 5 L12 19 M5 12 L19 12",
|
|||
|
|
more: "M5 12 h.01 M12 12 h.01 M19 12 h.01",
|
|||
|
|
arrowRight: "M5 12 H19 M13 6 L19 12 L13 18",
|
|||
|
|
filter: "M3 5 H21 L14 13 V20 L10 22 V13 L3 5",
|
|||
|
|
rule: "M4 4 H20 V20 H4 Z M4 9 H20 M4 14 H20 M9 9 V20",
|
|||
|
|
ledger: "M5 3 H17 a2 2 0 0 1 2 2 V21 L12 17 L5 21 Z",
|
|||
|
|
activity: "M22 12 H18 L15 21 L9 3 L6 12 H2",
|
|||
|
|
import: "M12 2 L12 22 M19 15 L12 22 L5 15",
|
|||
|
|
refresh: "M21 12 a9 9 0 1 1 -3 -6.7 M21 4 V10 H15",
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
Object.assign(window, { MEntityBadge, MConfidenceChip, MTierBadge, MAmount, MIcon });
|