@paro.io/expert-shared-components 1.14.54 → 1.14.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/TaxAxis/TaxAxisApi.d.ts +2 -0
- package/lib/components/TaxAxis/TaxAxisShell.js +102 -13
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.d.ts +4 -1
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +10 -6
- package/lib/tax-axis/components/clientReport/RecommendedStrategies.d.ts +6 -1
- package/lib/tax-axis/components/clientReport/RecommendedStrategies.js +26 -24
- package/lib/tax-axis/components/clientReport/StrategyCard.d.ts +1 -1
- package/lib/tax-axis/components/clientReport/StrategyCard.js +39 -23
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.d.ts +3 -1
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +4 -4
- package/lib/tax-axis/components/dashboard/DashboardSummary.d.ts +6 -1
- package/lib/tax-axis/components/dashboard/DashboardSummary.js +14 -4
- package/lib/tax-axis/components/dashboard/StrategyDetailPanel.d.ts +1 -1
- package/lib/tax-axis/components/dashboard/StrategyDetailPanel.js +120 -91
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.d.ts +3 -2
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +91 -21
- package/lib/tax-axis/components/documents/TaxAxisDocuments.d.ts +2 -0
- package/lib/tax-axis/components/documents/TaxAxisDocuments.js +46 -10
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.d.ts +21 -1
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.js +10 -1
- package/lib/tax-axis/components/processing/TaxAxisProcessing.d.ts +3 -1
- package/lib/tax-axis/components/processing/TaxAxisProcessing.js +77 -31
- package/lib/tax-axis/lib/adapters/useEngineOutput.d.ts +7 -0
- package/lib/tax-axis/lib/adapters/useEngineOutput.js +8 -3
- package/lib/tax-axis/lib/types/index.d.ts +10 -1
- package/package.json +1 -1
|
@@ -5,26 +5,102 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.StrategyDetailPanel = StrategyDetailPanel;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const data_1 = require("../../lib/data");
|
|
9
8
|
const TaxAxisBadge_1 = require("../shared/TaxAxisBadge");
|
|
10
|
-
function Sec({ title, children }) {
|
|
9
|
+
function Sec({ title, children, titleColor }) {
|
|
11
10
|
return (react_1.default.createElement("div", { className: "mb-6" },
|
|
12
|
-
react_1.default.createElement("div", { className: "text-[11px] font-bold
|
|
11
|
+
react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest mb-2.5 font-tax-axis-mono", style: { color: titleColor || "#A1E5E6" } }, title),
|
|
13
12
|
children));
|
|
14
13
|
}
|
|
15
14
|
const fmtK = (n) => `$${(n / 1000).toFixed(n % 1000 ? 1 : 0)}K`;
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
function positionStrengthLabel(positionStrength) {
|
|
16
|
+
if (!positionStrength)
|
|
17
|
+
return { label: "Position Under Review", color: "#9498B8", dots: 2 };
|
|
18
|
+
const p = positionStrength.toUpperCase();
|
|
19
|
+
if (p.includes("SUBSTANTIAL"))
|
|
20
|
+
return { label: "Substantial Authority · Low §6694 Risk", color: "#0F6E56", dots: 4 };
|
|
21
|
+
if (p.includes("REASONABLE"))
|
|
22
|
+
return { label: "Reasonable Basis · Elevated §6694 Risk", color: "#FB9A1D", dots: 3 };
|
|
23
|
+
if (p.includes("DISCLOSURE") || p.includes("NEEDS_DISCLOSURE"))
|
|
24
|
+
return { label: "Needs Disclosure · High §6694 Risk", color: "#EF4444", dots: 2 };
|
|
25
|
+
return { label: positionStrength, color: "#9498B8", dots: 2 };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Split engagement_recommendation at the implementation/action boundary.
|
|
29
|
+
*
|
|
30
|
+
* The LLM writes engagement_recommendation as a single paragraph covering both
|
|
31
|
+
* the savings math AND the CPA implementation steps. We split at the first
|
|
32
|
+
* implementation keyword so the savings math shows under "HOW SAVINGS BREAK DOWN"
|
|
33
|
+
* and the CPA action steps show under "CPA ENGAGEMENT NOTES".
|
|
34
|
+
*
|
|
35
|
+
* Heuristic: split at "Implementation:", "CPA should", "CPA must", or numbered
|
|
36
|
+
* action lists "(1)". If no split point found, entire text goes to savings section.
|
|
37
|
+
*/
|
|
38
|
+
function splitEngagementText(text) {
|
|
39
|
+
if (!text)
|
|
40
|
+
return { savingsSection: "", cpaSection: "" };
|
|
41
|
+
// Try splitting on double-newline first (well-structured LLM output)
|
|
42
|
+
const paraBreak = text.indexOf("\n\n");
|
|
43
|
+
if (paraBreak !== -1) {
|
|
44
|
+
return {
|
|
45
|
+
savingsSection: text.slice(0, paraBreak).trim(),
|
|
46
|
+
cpaSection: text.slice(paraBreak).trim(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Single-paragraph: find the first implementation boundary
|
|
50
|
+
const splitPatterns = [
|
|
51
|
+
/\s+Implementation:\s+/i,
|
|
52
|
+
/\s+CPA should\s+/i,
|
|
53
|
+
/\s+CPA must\s+/i,
|
|
54
|
+
/\s+To implement:\s+/i,
|
|
55
|
+
/\s+\(1\)\s+/, // numbered list start
|
|
56
|
+
];
|
|
57
|
+
for (const pattern of splitPatterns) {
|
|
58
|
+
const match = text.search(pattern);
|
|
59
|
+
if (match > 80) { // only split if there's meaningful content before it
|
|
60
|
+
return {
|
|
61
|
+
savingsSection: text.slice(0, match).trim(),
|
|
62
|
+
cpaSection: text.slice(match).trim(),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// No clean split point — show everything as savings breakdown, nothing as CPA notes
|
|
67
|
+
return { savingsSection: text, cpaSection: "" };
|
|
68
|
+
}
|
|
69
|
+
function SourceDocRows({ docs, trace }) {
|
|
70
|
+
if (docs && docs.length > 0) {
|
|
71
|
+
return (react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
|
|
72
|
+
react_1.default.createElement("div", { className: "grid px-3.5 py-2", style: { background: "#161938", gridTemplateColumns: "1fr auto" } },
|
|
73
|
+
react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono" }, "Field \u00B7 Source"),
|
|
74
|
+
react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono text-right" }, "Value")),
|
|
75
|
+
docs.map((ref, i) => (react_1.default.createElement("div", { key: i, className: "grid px-3.5 py-2.5 items-center gap-3", style: { gridTemplateColumns: "1fr auto", borderTop: "1px solid rgba(36,131,132,0.08)" } },
|
|
76
|
+
react_1.default.createElement("div", null,
|
|
77
|
+
react_1.default.createElement("div", { className: "text-xs text-tax-axis-text font-tax-axis-body" }, ref.field_label),
|
|
78
|
+
react_1.default.createElement("div", { className: "text-[10px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, ref.source_hint)),
|
|
79
|
+
react_1.default.createElement("div", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-mono text-right whitespace-nowrap" }, ref.value_display))))));
|
|
80
|
+
}
|
|
81
|
+
const traceSteps = trace !== null && trace !== void 0 ? trace : [];
|
|
82
|
+
if (!traceSteps.length) {
|
|
83
|
+
return react_1.default.createElement("p", { className: "text-xs text-tax-axis-text-2 italic" }, "Detailed source mapping not available for this strategy.");
|
|
84
|
+
}
|
|
85
|
+
return (react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
|
|
86
|
+
react_1.default.createElement("div", { className: "grid grid-cols-2 px-3.5 py-2", style: { background: "#161938" } },
|
|
87
|
+
react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono" }, "Step"),
|
|
88
|
+
react_1.default.createElement("span", { className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono text-right" }, "Result")),
|
|
89
|
+
traceSteps.map((t, i) => (react_1.default.createElement("div", { key: i, className: "grid grid-cols-2 px-3.5 py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.08)" } },
|
|
90
|
+
react_1.default.createElement("div", null,
|
|
91
|
+
react_1.default.createElement("div", { className: "text-xs text-tax-axis-text font-tax-axis-body" }, t.step),
|
|
92
|
+
react_1.default.createElement("div", { className: "text-[10px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5 break-all" }, t.formula)),
|
|
93
|
+
react_1.default.createElement("div", { className: "text-right" },
|
|
94
|
+
react_1.default.createElement("div", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-mono" }, t.result),
|
|
95
|
+
t.src && react_1.default.createElement("div", { className: "text-[9px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, t.src)))))));
|
|
96
|
+
}
|
|
97
|
+
function StrategyDetailPanel({ s, profile: _profile, computed, onClose }) {
|
|
98
|
+
var _a, _b;
|
|
19
99
|
const c = computed === null || computed === void 0 ? void 0 : computed.get(s.rank);
|
|
20
100
|
const lo = (_a = c === null || c === void 0 ? void 0 : c.lo) !== null && _a !== void 0 ? _a : s.lo;
|
|
21
101
|
const hi = (_b = c === null || c === void 0 ? void 0 : c.hi) !== null && _b !== void 0 ? _b : s.hi;
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const whyText = narr ? narr.whyMatters(profile) : data_1.NARRATIVE_FALLBACK.whyMatters(s);
|
|
25
|
-
const breakdownText = narr ? narr.breakdown(profile, c) : data_1.NARRATIVE_FALLBACK.breakdown(s, c);
|
|
26
|
-
const specialistText = (narr === null || narr === void 0 ? void 0 : narr.whySpecialist) || data_1.NARRATIVE_FALLBACK.whySpecialist(s);
|
|
27
|
-
const nextText = narr ? narr.nextSteps : data_1.NARRATIVE_FALLBACK.nextSteps(s);
|
|
102
|
+
const pos = positionStrengthLabel(s.positionStrength);
|
|
103
|
+
const { savingsSection, cpaSection } = splitEngagementText(s.abstract || "");
|
|
28
104
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
29
105
|
react_1.default.createElement("div", { onClick: onClose, className: "fixed inset-0 z-[200]", style: { background: "rgba(6,8,33,0.7)", backdropFilter: "blur(4px)" } }),
|
|
30
106
|
react_1.default.createElement("div", { className: "fixed top-0 right-0 bottom-0 z-[201] flex flex-col", style: {
|
|
@@ -37,14 +113,14 @@ function StrategyDetailPanel({ s, profile, computed, onClose }) {
|
|
|
37
113
|
react_1.default.createElement("div", { className: "px-6 py-5 flex-shrink-0", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } },
|
|
38
114
|
react_1.default.createElement("div", { className: "flex justify-between items-start mb-3" },
|
|
39
115
|
react_1.default.createElement("div", null,
|
|
40
|
-
react_1.default.createElement("div", { className: "flex items-center gap-2 mb-1.5" },
|
|
116
|
+
react_1.default.createElement("div", { className: "flex items-center gap-2 mb-1.5 flex-wrap" },
|
|
41
117
|
react_1.default.createElement("span", { className: "text-xl font-bold text-tax-axis-text font-tax-axis-head" }, s.name),
|
|
42
118
|
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-teal-light bg-tax-axis-teal-bg px-2 py-0.5 rounded" }, s.code)),
|
|
43
|
-
react_1.default.createElement("div", { className: "flex gap-2" },
|
|
119
|
+
react_1.default.createElement("div", { className: "flex gap-2 flex-wrap" },
|
|
44
120
|
react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, null, s.priority),
|
|
45
121
|
react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "neutral" }, s.timeline),
|
|
46
|
-
s.
|
|
47
|
-
react_1.default.createElement("button", { onClick: onClose, className: "flex items-center justify-center w-8 h-8 rounded-lg", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
|
|
122
|
+
s.quickWin && react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "orange" }, "\u26A1 Quick Win"))),
|
|
123
|
+
react_1.default.createElement("button", { onClick: onClose, className: "flex items-center justify-center w-8 h-8 rounded-lg flex-shrink-0", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
|
|
48
124
|
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
|
|
49
125
|
react_1.default.createElement("path", { d: "M2.5 2.5l7 7M9.5 2.5l-7 7", stroke: "#9498B8", strokeWidth: "1.5", strokeLinecap: "round" })))),
|
|
50
126
|
react_1.default.createElement("div", { className: "font-tax-axis-head", style: { fontSize: 34, fontWeight: 900, color: "#A1E5E6", letterSpacing: "-1.5px" } },
|
|
@@ -53,87 +129,40 @@ function StrategyDetailPanel({ s, profile, computed, onClose }) {
|
|
|
53
129
|
fmtK(hi),
|
|
54
130
|
react_1.default.createElement("span", { className: "text-[13px] text-tax-axis-text-3 font-normal font-tax-axis-body ml-2" }, "est. annual savings"))),
|
|
55
131
|
react_1.default.createElement("div", { className: "flex-1 overflow-y-auto p-6" },
|
|
56
|
-
s.warning && (react_1.default.createElement("div", { className: "p-3 rounded-lg mb-6 text-xs leading-relaxed", style: {
|
|
57
|
-
background: "rgba(251,154,29,0.06)",
|
|
58
|
-
border: "1px solid rgba(251,154,29,0.25)",
|
|
59
|
-
color: "#FB9A1D",
|
|
60
|
-
} },
|
|
132
|
+
s.warning && (react_1.default.createElement("div", { className: "p-3 rounded-lg mb-6 text-xs leading-relaxed", style: { background: "rgba(251,154,29,0.06)", border: "1px solid rgba(251,154,29,0.25)", color: "#FB9A1D" } },
|
|
61
133
|
react_1.default.createElement("strong", null, "Flag: "),
|
|
62
134
|
s.warning)),
|
|
63
|
-
react_1.default.createElement(
|
|
64
|
-
react_1.default.createElement("
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
react_1.default.createElement("div", { className: "text-[
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
react_1.default.createElement(
|
|
72
|
-
react_1.default.createElement(
|
|
73
|
-
react_1.default.createElement("div", { className: "
|
|
74
|
-
|
|
75
|
-
react_1.default.createElement(Sec, { title: "
|
|
76
|
-
react_1.default.createElement("p", { className: "text-sm text-tax-axis-text leading-[1.8] font-tax-axis-body" }, s.abstract)),
|
|
77
|
-
react_1.default.createElement(Sec, { title: "Plain Language" },
|
|
78
|
-
react_1.default.createElement("div", { className: "p-3.5 rounded-[10px]", style: { background: "rgba(36,131,132,0.06)", border: "1px solid rgba(36,131,132,0.2)" } },
|
|
79
|
-
react_1.default.createElement("p", { className: "text-sm text-tax-axis-teal-light leading-[1.7] font-tax-axis-body italic" },
|
|
80
|
-
"\u201C",
|
|
81
|
-
s.clientBrief,
|
|
82
|
-
"\u201D"))),
|
|
83
|
-
react_1.default.createElement(Sec, { title: "Source Documents" },
|
|
84
|
-
react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
|
|
85
|
-
react_1.default.createElement("div", { className: "grid grid-cols-[1.2fr_1fr_.8fr_.8fr] px-3.5 py-2.5", style: { background: "#161938" } }, ["Field", "Document", "Line", "Value"].map((h) => (react_1.default.createElement("span", { key: h, className: "text-[10px] font-semibold text-tax-axis-text-3 uppercase tracking-wider font-tax-axis-mono" }, h)))),
|
|
86
|
-
sources.map((src, i) => (react_1.default.createElement("div", { key: i, className: "grid grid-cols-[1.2fr_1fr_.8fr_.8fr] px-3.5 py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.12)" } },
|
|
87
|
-
react_1.default.createElement("span", { className: "text-xs text-tax-axis-text" }, src.field),
|
|
88
|
-
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, src.doc),
|
|
89
|
-
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, src.line),
|
|
90
|
-
react_1.default.createElement("span", { className: "text-[13px] font-semibold text-tax-axis-teal-light font-tax-axis-mono" }, src.value)))))),
|
|
91
|
-
react_1.default.createElement(Sec, { title: "Calculation Trace" },
|
|
92
|
-
react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { border: "1px solid rgba(36,131,132,0.12)" } },
|
|
93
|
-
trace.map((t, i) => (react_1.default.createElement("div", { key: i, className: "p-3 flex gap-3 items-start", style: { borderTop: i ? "1px solid rgba(36,131,132,0.12)" : "none" } },
|
|
94
|
-
react_1.default.createElement("span", { className: "text-[11px] font-bold text-tax-axis-teal font-tax-axis-mono w-5 flex-shrink-0" }, t.n),
|
|
95
|
-
react_1.default.createElement("div", { className: "flex-1" },
|
|
96
|
-
react_1.default.createElement("div", { className: "text-[13px] font-medium text-tax-axis-text font-tax-axis-body mb-0.5" }, t.step),
|
|
97
|
-
react_1.default.createElement("div", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, t.formula)),
|
|
98
|
-
react_1.default.createElement("div", { className: "text-right flex-shrink-0" },
|
|
99
|
-
react_1.default.createElement("div", { className: "text-[13px] font-bold text-tax-axis-teal-light font-tax-axis-mono" }, t.result),
|
|
100
|
-
react_1.default.createElement("div", { className: "text-[9px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, t.src))))),
|
|
101
|
-
react_1.default.createElement("div", { className: "p-3.5", style: { borderTop: "1px solid rgba(36,131,132,0.12)", background: "#161938" } },
|
|
102
|
-
react_1.default.createElement("div", { className: "text-[10px] font-bold text-tax-axis-teal-light uppercase tracking-widest mb-2 font-tax-axis-mono" }, "Derivation"),
|
|
103
|
-
react_1.default.createElement("div", { className: "flex items-center gap-2 flex-wrap" }, trace.map((t, i) => (react_1.default.createElement("span", { key: i, className: "flex items-center gap-1.5" },
|
|
104
|
-
react_1.default.createElement("span", { className: "text-xs font-tax-axis-mono text-tax-axis-text px-2 py-0.5 rounded", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } }, t.result),
|
|
105
|
-
i < trace.length - 1 && (react_1.default.createElement("span", { className: "text-[11px] text-tax-axis-text-3 font-tax-axis-mono" }, "\u2192")))))),
|
|
106
|
-
trace.length > 1 && (react_1.default.createElement("div", { className: "mt-2 text-xs font-tax-axis-mono p-2 rounded-md leading-relaxed", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
|
|
107
|
-
react_1.default.createElement("span", { className: "text-tax-axis-text-2" }, "Result: "),
|
|
108
|
-
react_1.default.createElement("span", { className: "font-semibold text-tax-axis-teal-light" }, trace[trace.length - 1].result),
|
|
109
|
-
react_1.default.createElement("span", { className: "text-tax-axis-text-2" }, " via "),
|
|
110
|
-
react_1.default.createElement("span", { className: "text-tax-axis-text" }, trace[trace.length - 1].formula)))))),
|
|
111
|
-
react_1.default.createElement(Sec, { title: "IRS Authority" },
|
|
135
|
+
s.clientBrief && (react_1.default.createElement(Sec, { title: "Why This Matters" },
|
|
136
|
+
react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, s.clientBrief))),
|
|
137
|
+
savingsSection && (react_1.default.createElement(Sec, { title: "How Savings Break Down" },
|
|
138
|
+
react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body whitespace-pre-line" }, savingsSection))),
|
|
139
|
+
s.specialistNote && (react_1.default.createElement("div", { className: "mb-6 pl-3.5 py-1", style: { borderLeft: "3px solid #FB9A1D" } },
|
|
140
|
+
react_1.default.createElement("div", { className: "text-[11px] font-bold uppercase tracking-widest mb-2 font-tax-axis-mono", style: { color: "#FB9A1D" } }, "Why You Need a Specialist"),
|
|
141
|
+
react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-2 leading-[1.75] font-tax-axis-body" }, s.specialistNote))),
|
|
142
|
+
react_1.default.createElement(Sec, { title: "Data Used in This Analysis" },
|
|
143
|
+
react_1.default.createElement(SourceDocRows, { docs: s.sourceDocuments, trace: s.trace })),
|
|
144
|
+
cpaSection && (react_1.default.createElement(Sec, { title: "CPA Engagement Notes", titleColor: "#9498B8" },
|
|
145
|
+
react_1.default.createElement("div", { className: "rounded-[10px] p-3.5", style: { background: "rgba(14,17,50,0.6)", border: "1px solid rgba(36,131,132,0.10)" } },
|
|
146
|
+
react_1.default.createElement("p", { className: "text-[12px] text-tax-axis-text-3 leading-[1.75] font-tax-axis-body whitespace-pre-line" }, cpaSection)))),
|
|
147
|
+
react_1.default.createElement(Sec, { title: "IRS Authority", titleColor: "#9498B8" },
|
|
112
148
|
react_1.default.createElement("div", { className: "p-3.5 rounded-[10px] mb-3", style: { background: "#1A1D3A", border: "1px solid rgba(36,131,132,0.12)" } },
|
|
113
|
-
react_1.default.createElement("div", { className: "text-[13px] font-tax-axis-mono text-tax-axis-text mb-1" }, s.authority),
|
|
114
|
-
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2" },
|
|
149
|
+
react_1.default.createElement("div", { className: "text-[13px] font-tax-axis-mono text-tax-axis-text mb-1" }, s.authority || "See engagement notes"),
|
|
150
|
+
s.forms && (react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2" },
|
|
115
151
|
"Forms: ",
|
|
116
|
-
react_1.default.createElement("span", { className: "font-tax-axis-mono text-tax-axis-text" }, s.forms))),
|
|
152
|
+
react_1.default.createElement("span", { className: "font-tax-axis-mono text-tax-axis-text" }, s.forms)))),
|
|
117
153
|
react_1.default.createElement("div", { className: "rounded-[10px] overflow-hidden", style: { background: "rgba(36,131,132,0.06)", border: "1px solid rgba(36,131,132,0.2)" } },
|
|
118
154
|
react_1.default.createElement("div", { className: "p-3 flex gap-3 items-center", style: { borderBottom: "1px solid rgba(36,131,132,0.15)" } },
|
|
119
|
-
react_1.default.createElement("div", { className: "flex gap-[3px]" }, [1, 2, 3, 4, 5].map((i) => (react_1.default.createElement("div", { key: i, className: "w-2 h-2 rounded-sm", style: { background: i <=
|
|
120
|
-
react_1.default.createElement("span", { className: "text-[13px] font-semibold
|
|
155
|
+
react_1.default.createElement("div", { className: "flex gap-[3px]" }, [1, 2, 3, 4, 5].map((i) => (react_1.default.createElement("div", { key: i, className: "w-2 h-2 rounded-sm", style: { background: i <= pos.dots ? pos.color : "rgba(36,131,132,0.2)" } })))),
|
|
156
|
+
react_1.default.createElement("span", { className: "text-[13px] font-semibold font-tax-axis-head", style: { color: pos.color } }, pos.label)),
|
|
121
157
|
react_1.default.createElement("div", { className: "p-3" },
|
|
122
|
-
react_1.default.createElement("p", { className: "text-xs text-tax-axis-text leading-[1.7] font-tax-axis-body
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2 leading-relaxed font-tax-axis-body" }, "If the preparer knowingly disregards rules or regulations, the penalty is the greater of $5,000 or 75% of the fee earned."))),
|
|
130
|
-
react_1.default.createElement("div", { className: "p-2 rounded-md flex gap-2 items-start", style: { background: "rgba(15,110,86,0.06)", border: "1px solid rgba(15,110,86,0.15)" } },
|
|
131
|
-
react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", className: "flex-shrink-0 mt-0.5" },
|
|
132
|
-
react_1.default.createElement("path", { d: "M2.5 7l3.5 3.5 5.5-6", stroke: "#0F6E56", strokeWidth: "1.5", strokeLinecap: "round" })),
|
|
133
|
-
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text leading-relaxed font-tax-axis-body" },
|
|
134
|
-
react_1.default.createElement("strong", { style: { color: "#0F6E56" } }, "This strategy holds Substantial Authority"),
|
|
135
|
-
" \u2014 established IRS guidance, published revenue rulings, or settled case law support this position. Signing off on this carries low preparer penalty exposure under \u00A76694(a).")))))),
|
|
158
|
+
react_1.default.createElement("p", { className: "text-xs text-tax-axis-text leading-[1.7] font-tax-axis-body" },
|
|
159
|
+
"IRC \u00A76694 imposes penalties on preparers who sign off on positions that lack sufficient legal support.",
|
|
160
|
+
pos.dots >= 4
|
|
161
|
+
? " This strategy holds Substantial Authority — established IRS guidance supports this position. Low preparer penalty exposure under §6694(a)."
|
|
162
|
+
: pos.dots === 3
|
|
163
|
+
? " This strategy rests on Reasonable Basis. CPA should document the position before filing and consider disclosure on Form 8275."
|
|
164
|
+
: " This strategy requires preparer disclosure. Consult IRS guidance before taking this position."))))),
|
|
136
165
|
react_1.default.createElement("div", { className: "px-6 py-4 flex-shrink-0", style: { borderTop: "1px solid rgba(36,131,132,0.12)", background: "#0E1132" } },
|
|
137
|
-
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-3 mb-2" }, "
|
|
138
|
-
react_1.default.createElement("div", { className: "text-sm font-medium text-tax-axis-text" }, s.action)))));
|
|
166
|
+
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-3 uppercase tracking-widest font-tax-axis-mono mb-2" }, "What We'd Do Next"),
|
|
167
|
+
react_1.default.createElement("div", { className: "text-sm font-medium text-tax-axis-text leading-relaxed" }, s.action || "Work with your CPA to implement this strategy.")))));
|
|
139
168
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { ClientProfile, TaxAxisScreenProps } from "../../lib/types";
|
|
2
|
+
import type { ClientProfile, TaxAxisScreenProps, ExtractionDocument } from "../../lib/types";
|
|
3
3
|
export interface LlmStrategy {
|
|
4
4
|
strategyType: string;
|
|
5
5
|
applicable: boolean;
|
|
@@ -57,6 +57,7 @@ export interface LlmResult {
|
|
|
57
57
|
export interface TaxAxisDashboardProps extends TaxAxisScreenProps {
|
|
58
58
|
profile: ClientProfile;
|
|
59
59
|
llmResult?: LlmResult | null;
|
|
60
|
+
parsedDocuments?: ExtractionDocument[];
|
|
60
61
|
onDownloadClient: () => void;
|
|
61
62
|
onDownloadPreparer: () => void;
|
|
62
63
|
onPresent: () => void;
|
|
@@ -65,4 +66,4 @@ export interface TaxAxisDashboardProps extends TaxAxisScreenProps {
|
|
|
65
66
|
onReviewData?: () => void;
|
|
66
67
|
onUploadMore?: () => void;
|
|
67
68
|
}
|
|
68
|
-
export declare function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext, }: TaxAxisDashboardProps): React.JSX.Element;
|
|
69
|
+
export declare function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext, }: TaxAxisDashboardProps): React.JSX.Element;
|
|
@@ -27,6 +27,7 @@ exports.TaxAxisDashboard = TaxAxisDashboard;
|
|
|
27
27
|
const react_1 = __importStar(require("react"));
|
|
28
28
|
const data_1 = require("../../lib/data");
|
|
29
29
|
const compute_1 = require("../../lib/compute");
|
|
30
|
+
const useEngineOutput_1 = require("../../lib/adapters/useEngineOutput");
|
|
30
31
|
const TaxAxisButton_1 = require("../shared/TaxAxisButton");
|
|
31
32
|
const TaxAxisBadge_1 = require("../shared/TaxAxisBadge");
|
|
32
33
|
const DashboardSummary_1 = require("./DashboardSummary");
|
|
@@ -145,12 +146,47 @@ const BUCKETS = [
|
|
|
145
146
|
{ key: "30d", label: "Within 30 Days", desc: "Documentation or payroll changes" },
|
|
146
147
|
{ key: "90d", label: "Within 90 Days", desc: "Structural changes — new accounts or plan setup" },
|
|
147
148
|
];
|
|
148
|
-
function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext = "expert", }) {
|
|
149
|
-
var _a, _b;
|
|
149
|
+
function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext = "expert", }) {
|
|
150
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
150
151
|
const hasLlm = !!((_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.strategies) === null || _a === void 0 ? void 0 : _a.length);
|
|
152
|
+
// All live fields from rawOutput — nothing hardcoded
|
|
153
|
+
const rawOutput = (_c = (_b = llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) !== null && _b !== void 0 ? _b : llmResult === null || llmResult === void 0 ? void 0 : llmResult.engineOutput) !== null && _c !== void 0 ? _c : null;
|
|
154
|
+
const businessProfile = (_d = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.business_profile) !== null && _d !== void 0 ? _d : null;
|
|
155
|
+
const dataQualityFlags = (_e = businessProfile === null || businessProfile === void 0 ? void 0 : businessProfile.data_quality_flags) !== null && _e !== void 0 ? _e : [];
|
|
156
|
+
const riskDisclosures = (_f = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.risk_disclosures) !== null && _f !== void 0 ? _f : [];
|
|
157
|
+
const nexusFlags = (_g = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.nexus_flags) !== null && _g !== void 0 ? _g : [];
|
|
158
|
+
const engagementRecs = (_j = (_h = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.cpa_workflow) === null || _h === void 0 ? void 0 : _h.engagement_recommendations) !== null && _j !== void 0 ? _j : [];
|
|
159
|
+
const excludedStrategies = (_l = (_k = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.eligibility_screening) === null || _k === void 0 ? void 0 : _k.excluded_strategies) !== null && _l !== void 0 ? _l : [];
|
|
160
|
+
const clientSummaryOpening = (_o = (_m = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _m === void 0 ? void 0 : _m.opening) !== null && _o !== void 0 ? _o : "";
|
|
161
|
+
const clientSummaryClosing = (_q = (_p = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _p === void 0 ? void 0 : _p.closing) !== null && _q !== void 0 ? _q : "";
|
|
162
|
+
const dataQualityNote = (_s = (_r = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _r === void 0 ? void 0 : _r.data_quality_note) !== null && _s !== void 0 ? _s : "";
|
|
163
|
+
const interactionWarning = (_u = (_t = rawOutput === null || rawOutput === void 0 ? void 0 : rawOutput.client_summary) === null || _t === void 0 ? void 0 : _t.interaction_warning) !== null && _u !== void 0 ? _u : null;
|
|
164
|
+
// Extracted documents: live from session if provided, otherwise empty (no mock fallback)
|
|
165
|
+
const extractionDocs = parsedDocuments !== null && parsedDocuments !== void 0 ? parsedDocuments : [];
|
|
151
166
|
// ─── Derived data ──────────────────────────────────────────────
|
|
152
|
-
|
|
153
|
-
|
|
167
|
+
// Prefer useEngineOutput (full rich data: sourceDocuments, positionStrength,
|
|
168
|
+
// clientBrief from why_it_applies, etc.) over the thin mapLlmToStrategies fallback.
|
|
169
|
+
// engineOutput is at llmResult.engineOutput or llmResult.rawOutput (both present).
|
|
170
|
+
const engineOutputForAdapter = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.engineOutput) !== null && _a !== void 0 ? _a : llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) !== null && _b !== void 0 ? _b : null; }, [llmResult]);
|
|
171
|
+
const adapted = (0, useEngineOutput_1.useEngineOutput)(engineOutputForAdapter);
|
|
172
|
+
const llmStrategies = (0, react_1.useMemo)(() => {
|
|
173
|
+
var _a;
|
|
174
|
+
if (!hasLlm)
|
|
175
|
+
return [];
|
|
176
|
+
// Use adapted strategies when available — they carry the full engine data.
|
|
177
|
+
if ((_a = adapted === null || adapted === void 0 ? void 0 : adapted.strategies) === null || _a === void 0 ? void 0 : _a.length)
|
|
178
|
+
return adapted.strategies;
|
|
179
|
+
// Fallback to thin mapping for old payload shapes without engineOutput.
|
|
180
|
+
return mapLlmToStrategies(llmResult);
|
|
181
|
+
}, [hasLlm, adapted, llmResult]);
|
|
182
|
+
const llmComputed = (0, react_1.useMemo)(() => {
|
|
183
|
+
var _a;
|
|
184
|
+
if (!hasLlm)
|
|
185
|
+
return new Map();
|
|
186
|
+
if ((_a = adapted === null || adapted === void 0 ? void 0 : adapted.computedMap) === null || _a === void 0 ? void 0 : _a.size)
|
|
187
|
+
return adapted.computedMap;
|
|
188
|
+
return buildLlmComputed(llmStrategies);
|
|
189
|
+
}, [hasLlm, adapted, llmStrategies]);
|
|
154
190
|
const computed = (0, react_1.useMemo)(() => (hasLlm ? llmComputed : (0, compute_1.computeAllStrategies)(profile)), [hasLlm, llmComputed, profile]);
|
|
155
191
|
const dashEligible = (0, react_1.useMemo)(() => (hasLlm ? llmStrategies : (0, compute_1.filterEligibleStrategies)(profile)), [hasLlm, llmStrategies, profile]);
|
|
156
192
|
const maxSavings = Math.max(...dashEligible.map((s) => { var _a, _b; return (_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.hi) !== null && _b !== void 0 ? _b : s.hi; }), 1);
|
|
@@ -163,9 +199,13 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
|
|
|
163
199
|
// When LLM result is present, data is implicitly confirmed — skip the gate
|
|
164
200
|
const [dataConfirmed, setDataConfirmed] = (0, react_1.useState)(hasLlm);
|
|
165
201
|
const [reviewStatus, setReviewStatus] = (0, react_1.useState)({
|
|
166
|
-
unreviewed:
|
|
202
|
+
unreviewed: extractionDocs.reduce((a, d) => a + d.flagCount, 0),
|
|
167
203
|
edits: 0,
|
|
168
204
|
});
|
|
205
|
+
// Keep review count in sync when live docs arrive after initial render
|
|
206
|
+
(0, react_1.useEffect)(() => {
|
|
207
|
+
setReviewStatus((prev) => (Object.assign(Object.assign({}, prev), { unreviewed: extractionDocs.reduce((a, d) => a + d.flagCount, 0) })));
|
|
208
|
+
}, [extractionDocs]);
|
|
169
209
|
// Restore confirmed state on mount — flag persists until session reset
|
|
170
210
|
(0, react_1.useEffect)(() => {
|
|
171
211
|
if (typeof window !== "undefined" && sessionStorage.getItem("taxAxisDataConfirmed") === "true") {
|
|
@@ -216,19 +256,28 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
|
|
|
216
256
|
llmResult.meta.parsedDocumentCount,
|
|
217
257
|
" documents parsed",
|
|
218
258
|
" · ",
|
|
219
|
-
((
|
|
259
|
+
((_v = llmResult.meta.detectedDocumentTypes) === null || _v === void 0 ? void 0 : _v.length) || 0,
|
|
220
260
|
" document types detected"),
|
|
221
261
|
react_1.default.createElement("span", { className: "text-tax-axis-text-4" }, (() => {
|
|
222
262
|
var _a, _b;
|
|
223
263
|
const tokens = (_b = (_a = llmResult.meta.totalTokens) !== null && _a !== void 0 ? _a : llmResult.meta.tokenCount) !== null && _b !== void 0 ? _b : 0;
|
|
224
264
|
return tokens > 0 ? `${tokens} tokens` : "";
|
|
225
265
|
})()))),
|
|
226
|
-
react_1.default.createElement(DashboardSummary_1.DashboardSummary, { profile: profile, dashEligible: dashEligible, computed: computed, dataConfirmed: dataConfirmed, reviewUnreviewed: reviewStatus.unreviewed }),
|
|
266
|
+
react_1.default.createElement(DashboardSummary_1.DashboardSummary, { profile: profile, dashEligible: dashEligible, computed: computed, dataConfirmed: dataConfirmed, reviewUnreviewed: reviewStatus.unreviewed, liveSavingsMin: hasLlm ? llmResult.summary.estimatedSavingsMin : undefined, liveSavingsMax: hasLlm ? llmResult.summary.estimatedSavingsMax : undefined, liveStrategyCount: hasLlm ? llmResult.summary.applicableCount : undefined, confidenceTier: businessProfile === null || businessProfile === void 0 ? void 0 : businessProfile.confidence_tier, dataYears: businessProfile === null || businessProfile === void 0 ? void 0 : businessProfile.data_years }),
|
|
227
267
|
react_1.default.createElement(DashboardTopBar_1.DashboardTopBar, { topTab: topTab, setTopTab: setTopTab, dataConfirmed: dataConfirmed, reviewUnreviewed: reviewStatus.unreviewed }),
|
|
228
268
|
topTab === "extraction" && (react_1.default.createElement("div", null,
|
|
269
|
+
dataQualityFlags.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.2)", padding: "16px 20px" } },
|
|
270
|
+
react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2.5 flex items-center gap-2" },
|
|
271
|
+
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
|
|
272
|
+
react_1.default.createElement("path", { d: "M6 1.5l5 9H1L6 1.5z", stroke: "#FB9A1D", strokeWidth: "1.2", fill: "none" }),
|
|
273
|
+
react_1.default.createElement("path", { d: "M6 5v2.5M6 9h.005", stroke: "#FB9A1D", strokeWidth: "1.2", strokeLinecap: "round" })),
|
|
274
|
+
"Data Quality Flags"),
|
|
275
|
+
dataQualityFlags.map((flag, i) => (react_1.default.createElement("div", { key: i, className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body py-1.5", style: { borderTop: i > 0 ? "1px solid rgba(251,154,29,0.1)" : "none" } }, flag))))),
|
|
229
276
|
react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "#0E1132", border: "1px solid rgba(36,131,132,0.12)", padding: "20px 24px" } },
|
|
230
277
|
react_1.default.createElement("div", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head mb-3" }, "Document Extraction Summary"),
|
|
231
|
-
|
|
278
|
+
extractionDocs.length === 0 ? (react_1.default.createElement("div", { className: "text-[12px] text-tax-axis-text-3 font-tax-axis-body py-2" }, hasLlm
|
|
279
|
+
? "Parsed document data is loading..."
|
|
280
|
+
: "No documents have been parsed yet.")) : (extractionDocs.map((doc) => (react_1.default.createElement("div", { key: doc.docId, className: "flex items-center justify-between py-2.5", style: { borderTop: "1px solid rgba(36,131,132,0.08)" } },
|
|
232
281
|
react_1.default.createElement("div", { className: "flex items-center gap-3" },
|
|
233
282
|
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-teal-light bg-tax-axis-teal-bg px-2 py-0.5 rounded" }, doc.code),
|
|
234
283
|
react_1.default.createElement("span", { className: "text-[13px] text-tax-axis-text font-tax-axis-body" }, doc.docName)),
|
|
@@ -236,9 +285,8 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
|
|
|
236
285
|
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-3" },
|
|
237
286
|
doc.fields.length,
|
|
238
287
|
" fields"),
|
|
239
|
-
doc.flagCount > 0
|
|
240
|
-
|
|
241
|
-
react_1.default.createElement("path", { d: "M2.5 6l3 3 4.5-5", stroke: "#0F6E56", strokeWidth: "1.5", strokeLinecap: "round" })))))))),
|
|
288
|
+
doc.flagCount > 0 ? (react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono rounded-full min-w-[18px] text-center px-1.5 py-0.5", style: { color: "#FB9A1D", background: "rgba(251,154,29,0.06)" } }, doc.flagCount)) : (react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
|
|
289
|
+
react_1.default.createElement("path", { d: "M2.5 6l3 3 4.5-5", stroke: "#0F6E56", strokeWidth: "1.5", strokeLinecap: "round" }))))))))),
|
|
242
290
|
!dataConfirmed ? (react_1.default.createElement("div", { className: "rounded-[14px]", style: {
|
|
243
291
|
background: "linear-gradient(135deg, rgba(36,131,132,0.12), rgba(36,131,132,0.06))",
|
|
244
292
|
border: "1px solid rgba(36,131,132,0.3)",
|
|
@@ -421,17 +469,32 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
|
|
|
421
469
|
react_1.default.createElement("div", { className: "flex items-center gap-2.5" },
|
|
422
470
|
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, a.savings),
|
|
423
471
|
react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: a.priority === "MEDIUM" ? "orange" : "neutral", size: "xs" }, a.priority))))))),
|
|
424
|
-
react_1.default.createElement("div", { className: "rounded-[
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
react_1.default.createElement("
|
|
430
|
-
|
|
472
|
+
engagementRecs.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4 overflow-hidden", style: { background: "#0E1132", border: "1px solid rgba(36,131,132,0.12)" } },
|
|
473
|
+
react_1.default.createElement("div", { className: "px-5 py-3.5", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } },
|
|
474
|
+
react_1.default.createElement("span", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head" }, "CPA Engagement Notes")),
|
|
475
|
+
engagementRecs.map((rec, i) => (react_1.default.createElement("div", { key: i, className: "px-5 py-3.5 text-[12px] text-tax-axis-text leading-[1.7] font-tax-axis-body", style: { borderTop: i > 0 ? "1px solid rgba(36,131,132,0.08)" : "none" } }, rec))))),
|
|
476
|
+
nexusFlags.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "#0E1132", border: "1px solid rgba(36,131,132,0.12)", padding: "16px 20px" } },
|
|
477
|
+
react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2" }, "State Nexus"),
|
|
478
|
+
nexusFlags.map((f, i) => (react_1.default.createElement("div", { key: i, className: "text-[12px] text-tax-axis-text-2 font-tax-axis-body py-1.5", style: { borderTop: i > 0 ? "1px solid rgba(36,131,132,0.08)" : "none" } },
|
|
479
|
+
react_1.default.createElement("span", { className: "font-semibold text-tax-axis-teal-light mr-2" }, f.state),
|
|
480
|
+
f.flag_text))))),
|
|
481
|
+
riskDisclosures.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)", padding: "16px 20px" } },
|
|
482
|
+
react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2.5" }, "Risk Disclosures"),
|
|
483
|
+
riskDisclosures.map((r, i) => (react_1.default.createElement("div", { key: i, className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body py-1.5", style: { borderTop: i > 0 ? "1px solid rgba(251,154,29,0.08)" : "none" } }, r))))),
|
|
484
|
+
excludedStrategies.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4 overflow-hidden", style: { background: "#0E1132", border: "1px solid rgba(148,152,184,0.15)" } },
|
|
485
|
+
react_1.default.createElement("div", { className: "px-5 py-3.5", style: { borderBottom: "1px solid rgba(148,152,184,0.1)" } },
|
|
486
|
+
react_1.default.createElement("span", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head" },
|
|
487
|
+
excludedStrategies.length,
|
|
488
|
+
" Strategies Not Applicable")),
|
|
489
|
+
excludedStrategies.map((ex, i) => (react_1.default.createElement("div", { key: i, className: "px-5 py-2.5 flex items-start gap-3", style: { borderTop: i > 0 ? "1px solid rgba(148,152,184,0.08)" : "none" } },
|
|
490
|
+
react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono text-tax-axis-text-3 bg-tax-axis-surface px-2 py-0.5 rounded flex-shrink-0 mt-0.5" }, ex.strategy_id),
|
|
491
|
+
react_1.default.createElement("div", { className: "flex-1" },
|
|
492
|
+
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body" }, ex.reason),
|
|
493
|
+
ex.irs_cite && (react_1.default.createElement("div", { className: "text-[10px] text-tax-axis-text-3 font-tax-axis-mono mt-0.5" }, ex.irs_cite)))))))),
|
|
431
494
|
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadPreparer, className: "w-full" }, "Download Full Preparer Report"))) : (
|
|
432
495
|
/* ═══ CLIENT SUMMARY — Timeline View ═══ */
|
|
433
496
|
react_1.default.createElement("div", null,
|
|
434
|
-
react_1.default.createElement("p", { className: "text-sm text-tax-axis-text leading-[1.7] mb-6 font-tax-axis-body" },
|
|
497
|
+
clientSummaryOpening ? (react_1.default.createElement("div", { className: "rounded-[10px] mb-5 text-[12px] text-tax-axis-text leading-[1.7] font-tax-axis-body", style: { background: "rgba(36,131,132,0.04)", border: "1px solid rgba(36,131,132,0.1)", padding: "14px 16px" } }, clientSummaryOpening)) : (react_1.default.createElement("p", { className: "text-sm text-tax-axis-text leading-[1.7] mb-6 font-tax-axis-body" },
|
|
435
498
|
profile.bizName || "Client",
|
|
436
499
|
", here's your action plan organized by urgency.",
|
|
437
500
|
" ",
|
|
@@ -439,7 +502,13 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
|
|
|
439
502
|
dashEligible.length,
|
|
440
503
|
" strategies"),
|
|
441
504
|
" ",
|
|
442
|
-
"identified."),
|
|
505
|
+
"identified.")),
|
|
506
|
+
dataQualityNote && (react_1.default.createElement("div", { className: "rounded-[10px] mb-5 text-[11px] text-tax-axis-text-2 font-tax-axis-body flex items-start gap-2", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)", padding: "10px 14px" } },
|
|
507
|
+
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", className: "flex-shrink-0 mt-0.5" },
|
|
508
|
+
react_1.default.createElement("circle", { cx: "6", cy: "6", r: "5", stroke: "#FB9A1D", strokeWidth: "1" }),
|
|
509
|
+
react_1.default.createElement("path", { d: "M6 4v2.5M6 8h.005", stroke: "#FB9A1D", strokeWidth: "1", strokeLinecap: "round" })),
|
|
510
|
+
dataQualityNote)),
|
|
511
|
+
interactionWarning && (react_1.default.createElement("div", { className: "rounded-[10px] mb-5 text-[11px] text-tax-axis-text-2 font-tax-axis-body", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)", padding: "10px 14px" } }, interactionWarning)),
|
|
443
512
|
BUCKETS.map(({ key, label, desc }) => {
|
|
444
513
|
const items = dashEligible.filter((s) => s.timelineBucket === key);
|
|
445
514
|
if (!items.length)
|
|
@@ -488,7 +557,8 @@ function TaxAxisDashboard({ profile, llmResult, onDownloadClient, onDownloadPrep
|
|
|
488
557
|
s.cost && s.cost !== "$0" && (react_1.default.createElement("span", { className: "text-[11px] font-semibold font-tax-axis-mono", style: { color: "#FB9A1D" } }, s.cost)))));
|
|
489
558
|
})));
|
|
490
559
|
}),
|
|
491
|
-
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadClient, className: "w-full mt-1.5" }, "Download Client Summary")
|
|
560
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadClient, className: "w-full mt-1.5" }, "Download Client Summary"),
|
|
561
|
+
clientSummaryClosing && (react_1.default.createElement("div", { className: "mt-4 text-[11px] text-tax-axis-text-3 leading-[1.65] font-tax-axis-body", style: { borderTop: "1px solid rgba(36,131,132,0.08)", paddingTop: 14 } }, clientSummaryClosing)))),
|
|
492
562
|
react_1.default.createElement(DashboardActions_1.DashboardActions, { profile: profile, dashEligible: dashEligible, computed: computed, onDownloadPreparer: onDownloadPreparer, onPresent: onPresent, onSend: onSend, onReset: onReset }))),
|
|
493
563
|
enrichedSelected && (react_1.default.createElement(StrategyDetailPanel_1.StrategyDetailPanel, { s: enrichedSelected, profile: profile, computed: computed, onClose: () => setSelected(null) }))));
|
|
494
564
|
}
|
|
@@ -16,12 +16,14 @@ export interface TaxAxisDocumentsProps extends TaxAxisScreenProps {
|
|
|
16
16
|
}>;
|
|
17
17
|
onDeleteDocument?: (documentId: string) => Promise<void>;
|
|
18
18
|
fetchUploadedDocuments?: () => Promise<Array<{
|
|
19
|
+
documentId?: string;
|
|
19
20
|
fileName: string;
|
|
20
21
|
status: string;
|
|
21
22
|
documentType?: string | null;
|
|
22
23
|
parseError?: string | null;
|
|
23
24
|
updatedAt?: string | null;
|
|
24
25
|
parsedData?: Record<string, unknown> | null;
|
|
26
|
+
reviewedData?: Record<string, unknown> | null;
|
|
25
27
|
}>>;
|
|
26
28
|
parsedFieldCounts?: Record<string, number>;
|
|
27
29
|
jobId?: string;
|