/* eslint-disable */ /* © 2026 K2B NETWORK SOLUTIONS LLC. All rights reserved. Proprietary and confidential. Unauthorized copying, distribution, or use of this file, via any medium, is strictly prohibited. Original work product. */ // JBREWS DMS — Recon Tracker. Two views: // • Recon Budgets — every used unit's approved recon budget vs estimated / actual / projected recon work, status, // pending budget requests and over-budget alerts; unit detail with ROs, requests, alerts and the change history. // • Make-Ready Line — kanban Intake → … → Ready Line (DMS.setReconStage). // Also exports components the RO screen and app shell use: // — budget / projected / warning / request-increase box on a recon (internal) RO // — the owner's in-app over-budget alert list (badge count: window.jbReconAlertCount()) // All math + records live in ReconCore.jsx.txt (DMS.recon*). A warning never changes the approved budget; only a manager // approval (or a manager's explicit Set budget with reason) does. const rcMoney = (n) => "$" + (Number(n) || 0).toLocaleString("en-US", { maximumFractionDigits: 0 }); const rcDays = (iso) => iso ? Math.floor((Date.now() - new Date(iso)) / 86400000) : 0; const rcbMoney = (n) => (n == null ? "—" : (n < 0 ? "−$" : "$") + Math.abs(+n || 0).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })); const rcbWhen = (iso) => { if (!iso) return ""; const d = new Date(iso); return isNaN(d) ? String(iso) : d.toLocaleDateString("en-US", { month: "2-digit", day: "2-digit", year: "2-digit" }) + " " + d.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }); }; const rcbToast = (r) => { if (r && r.msg && window.k2bToast) window.k2bToast(r.msg, r.ok ? "ok" : "warn", r.ok ? 3600 : 5200); return r; }; const RCB_STATUS = { none: { label: "No budget", bg: "var(--jb-surface-2, #EEF1F5)", fg: "var(--jb-text-dim, #555)", bar: "#9AA5B4" }, ok: { label: "OK", bg: "var(--jb-green-tint, #E6F7EC)", fg: "#15803D", bar: "var(--jb-green, #16A34A)" }, approaching: { label: "Approaching", bg: "var(--jb-amber-tint, #FFF4DB)", fg: "var(--jb-amber, #9A6700)", bar: "var(--jb-amber, #D99A06)" }, over: { label: "OVER", bg: "var(--jb-red-tint, #FDECEC)", fg: "var(--jb-red, #B42318)", bar: "var(--jb-red, #D92D20)" }, }; const RCB_KIND = { "warn": "Approaching", "over-projected": "Over — projected", "over-actual": "Over — actual" }; const RCB_HIST = { "set": "Budget set", "increase-request": "Increase requested", "approved": "Increase approved", "denied": "Increase denied", "alert": "Alert", "ack": "Alert acknowledged" }; const rcbUseLive = () => { const [, force] = React.useReducer(n => n + 1, 0); React.useEffect(() => (window.DMS && window.DMS.subscribe) ? window.DMS.subscribe(force) : undefined, []); }; const RcbChip = ({ status, text }) => { const c = RCB_STATUS[status] || RCB_STATUS.none; return {text || c.label}; }; // Budget bar: actual (solid) + open estimates (striped), a tick at the warning %, 100% = approved budget. const RcbBar = ({ sum, height }) => { if (!sum || !sum.hasBudget) return
; const scale = Math.max(sum.budget, sum.projected) || 1; const w = (v) => Math.max(0, Math.min(100, v / scale * 100)) + "%"; const c = (RCB_STATUS[sum.status] || RCB_STATUS.ok).bar; return (
{sum.projected > sum.budget &&
}
); }; const rcbLbl = { fontSize: 10.5, fontWeight: 700, color: "var(--jb-text-muted, #6B7280)", textTransform: "uppercase", letterSpacing: ".04em" }; const rcbNum = { fontFamily: "var(--jb-mono)", fontSize: 13, fontWeight: 700, color: "var(--jb-text, #111)" }; const rcbInput = { width: "100%", boxSizing: "border-box", padding: "6px 8px", border: "1px solid var(--jb-border-strong, #B8C0CC)", borderRadius: "var(--jb-r-sm, 4px)", fontSize: 13, fontFamily: "var(--jb-font)" }; // Request an increase (anyone in service) — or, for a manager, set the budget directly. Neither is triggered by a warning. const RcbBudgetModal = ({ sum, mode, roId, onClose }) => { const D = window.DMS; const suggested = mode === "set" ? (sum.budget || "") : (sum.hasBudget ? Math.ceil(Math.max(sum.projected, sum.budget) / 50) * 50 + (sum.projected >= sum.budget ? 50 : 0) : Math.ceil((sum.projected || 0) / 50) * 50 || ""); const [amt, setAmt] = React.useState(String(suggested || "")); const [reason, setReason] = React.useState(""); const [err, setErr] = React.useState(""); const submit = () => { const r = mode === "set" ? D.reconSetBudget(sum.stock, +amt, reason) : D.reconRequestIncrease(sum.stock, { amount: +amt, reason, roId: roId || "" }); if (!r.ok) { setErr(r.msg); return; } rcbToast(r); onClose(); }; return ( {mode === "set" ? "Save budget" : "Send request"}Cancel}>
{sum.vehicle} · VIN {sum.vin || "—"}
Approved
{sum.hasBudget ? rcbMoney(sum.budget) : "none"}
Projected
{rcbMoney(sum.projected)}
Actual
{rcbMoney(sum.actual)}