@paro.io/expert-shared-components 1.14.66 → 1.14.67
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/DocumentCenter/MultiFileUploadSection.js +220 -121
- package/lib/components/TaxAxis/TaxAxisApi.d.ts +0 -1
- package/lib/components/TaxAxis/TaxAxisShell.js +5 -80
- package/lib/components/shared/UploadClient.d.ts +2 -1
- package/lib/components/shared/UploadClient.js +6 -2
- package/lib/index.d.ts +1 -13
- package/lib/index.js +1 -27
- 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/Methodology.js +2 -2
- 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 +5 -2
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +9 -7
- package/lib/tax-axis/components/dashboard/DashboardActions.js +6 -5
- package/lib/tax-axis/components/dashboard/DashboardSummary.d.ts +6 -1
- package/lib/tax-axis/components/dashboard/DashboardSummary.js +19 -10
- package/lib/tax-axis/components/dashboard/StrategyDetailPanel.d.ts +1 -1
- package/lib/tax-axis/components/dashboard/StrategyDetailPanel.js +122 -95
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.d.ts +58 -4
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +375 -56
- package/lib/tax-axis/components/documents/DocumentCard.d.ts +6 -3
- package/lib/tax-axis/components/documents/DocumentCard.js +72 -15
- package/lib/tax-axis/components/documents/DocumentReviewModal.d.ts +3 -2
- package/lib/tax-axis/components/documents/DocumentReviewModal.js +109 -295
- package/lib/tax-axis/components/documents/DocumentTier.d.ts +5 -4
- package/lib/tax-axis/components/documents/DocumentTier.js +2 -2
- package/lib/tax-axis/components/documents/TaxAxisDocuments.d.ts +28 -8
- package/lib/tax-axis/components/documents/TaxAxisDocuments.js +335 -172
- package/lib/tax-axis/components/documents/qbo/QboAvailableReportsModal.d.ts +13 -0
- package/lib/tax-axis/components/documents/qbo/QboAvailableReportsModal.js +180 -0
- package/lib/tax-axis/components/documents/qbo/QboClientSelectorModal.d.ts +10 -0
- package/lib/tax-axis/components/documents/qbo/QboClientSelectorModal.js +155 -0
- package/lib/tax-axis/components/documents/qbo/QboConnectBanner.d.ts +9 -0
- package/lib/tax-axis/components/documents/qbo/QboConnectBanner.js +55 -0
- package/lib/tax-axis/components/documents/qbo/QboDocumentMappingModal.d.ts +10 -0
- package/lib/tax-axis/components/documents/qbo/QboDocumentMappingModal.js +202 -0
- package/lib/tax-axis/components/documents/qbo/QboImportingModal.d.ts +8 -0
- package/lib/tax-axis/components/documents/qbo/QboImportingModal.js +75 -0
- package/lib/tax-axis/components/documents/qbo/QboPermissionsModal.d.ts +8 -0
- package/lib/tax-axis/components/documents/qbo/QboPermissionsModal.js +126 -0
- package/lib/tax-axis/components/documents/qbo/index.d.ts +8 -0
- package/lib/tax-axis/components/documents/qbo/index.js +17 -0
- package/lib/tax-axis/components/documents/qbo/qboConstants.d.ts +24 -0
- package/lib/tax-axis/components/documents/qbo/qboConstants.js +71 -0
- package/lib/tax-axis/components/documents/qbo/types.d.ts +43 -0
- package/lib/tax-axis/components/documents/qbo/types.js +3 -0
- package/lib/tax-axis/components/documents/qbo/useQboFlow.d.ts +19 -0
- package/lib/tax-axis/components/documents/qbo/useQboFlow.js +207 -0
- package/lib/tax-axis/components/intake/ClientParametersSection.js +14 -30
- package/lib/tax-axis/components/intake/CpaIntakeQuestionsSection.js +3 -3
- package/lib/tax-axis/components/intake/IntakeCtaCards.d.ts +1 -2
- package/lib/tax-axis/components/intake/IntakeCtaCards.js +6 -13
- package/lib/tax-axis/components/intake/RefineAnalysisSection.js +7 -7
- package/lib/tax-axis/components/intake/TaxAxisIntake.js +7 -95
- package/lib/tax-axis/components/intake/intakeSchema.d.ts +0 -3
- package/lib/tax-axis/components/intake/intakeSchema.js +2 -4
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.d.ts +23 -4
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.js +15 -4
- package/lib/tax-axis/components/processing/TaxAxisProcessing.d.ts +2 -1
- package/lib/tax-axis/components/processing/TaxAxisProcessing.js +102 -31
- package/lib/tax-axis/components/prospectReport/ProspectPrintView.js +0 -2
- package/lib/tax-axis/components/prospectReport/ProspectStrategyCard.d.ts +1 -8
- package/lib/tax-axis/components/prospectReport/ProspectStrategyCard.js +5 -5
- package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.d.ts +1 -27
- package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.js +25 -43
- package/lib/tax-axis/index.d.ts +3 -1
- package/lib/tax-axis/index.js +4 -3
- package/lib/tax-axis/lib/adapters/useEngineOutput.d.ts +138 -13
- package/lib/tax-axis/lib/adapters/useEngineOutput.js +156 -7
- package/lib/tax-axis/lib/data/documents.d.ts +3 -2
- package/lib/tax-axis/lib/data/documents.js +225 -25
- package/lib/tax-axis/lib/data/strategies.js +9 -9
- package/lib/tax-axis/lib/documentFieldCatalog.d.ts +7 -12
- package/lib/tax-axis/lib/documentFieldCatalog.js +805 -8
- package/lib/tax-axis/lib/types/index.d.ts +13 -1
- package/package.json +1 -1
- package/lib/README.md +0 -2
- package/lib/package.json +0 -68
|
@@ -26,21 +26,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.TaxAxisProcessing = TaxAxisProcessing;
|
|
27
27
|
const react_1 = __importStar(require("react"));
|
|
28
28
|
const ProcessingStages_1 = require("./ProcessingStages");
|
|
29
|
+
const CRAWL_CEILING = 99; // pause here until reportReady
|
|
30
|
+
const CRAWL_TICK_MS = 300; // interval between crawl ticks
|
|
31
|
+
const CRAWL_STEP = 0.27; // % added each tick → 0.27 / 0.3s = 0.9%/s
|
|
32
|
+
const FINISH_MS = 400; // ms to animate from 99% → 100% once ready
|
|
33
|
+
const STAGE_ADVANCE_MS = 3200; // how often the displayed stage advances
|
|
29
34
|
function buildStages(profile) {
|
|
30
35
|
var _a;
|
|
31
36
|
if (!profile) {
|
|
32
37
|
return [
|
|
33
38
|
"Parsing source documents",
|
|
34
39
|
"Injecting IRS 2026 parameters",
|
|
35
|
-
"Screening
|
|
40
|
+
"Screening eligible strategies",
|
|
36
41
|
"Computing deterministic tax math",
|
|
37
42
|
"Generating IRS citations",
|
|
38
43
|
];
|
|
39
44
|
}
|
|
40
|
-
const entity = profile.entity || "your";
|
|
45
|
+
const entity = profile.entity || "your business";
|
|
41
46
|
const stateCount = ((_a = profile.states) === null || _a === void 0 ? void 0 : _a.length) || 1;
|
|
42
47
|
const bizName = profile.bizName || "your business";
|
|
43
|
-
// Verbatim from mock (App.jsx:1473-1477)
|
|
44
48
|
const base = [
|
|
45
49
|
"Parsing source documents",
|
|
46
50
|
"Injecting IRS 2026 parameters",
|
|
@@ -53,53 +57,120 @@ function buildStages(profile) {
|
|
|
53
57
|
if (entity === "S-Corporation") {
|
|
54
58
|
base.push("Benchmarking officer salary against BLS data");
|
|
55
59
|
}
|
|
56
|
-
base.push("Screening
|
|
60
|
+
base.push("Screening 30 eligible strategies", "Computing deterministic tax math", "Cross-validating source documents", "Generating IRS citations", `Assembling TaxAxis report for ${bizName}`);
|
|
57
61
|
return base;
|
|
58
62
|
}
|
|
59
|
-
function TaxAxisProcessing({ onComplete, profile, userContext: _userContext = "expert", }) {
|
|
63
|
+
function TaxAxisProcessing({ onComplete, profile, reportReady = false, userContext: _userContext = "expert", }) {
|
|
60
64
|
const stages = (0, react_1.useMemo)(() => buildStages(profile), [profile]);
|
|
61
65
|
const [progress, setProgress] = (0, react_1.useState)(0);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
|
|
66
|
+
const [stageIdx, setStageIdx] = (0, react_1.useState)(0);
|
|
67
|
+
const finishingRef = (0, react_1.useRef)(false);
|
|
68
|
+
const completedRef = (0, react_1.useRef)(false);
|
|
69
|
+
// Track current progress in a ref so the finish animation can read it synchronously
|
|
70
|
+
// without relying on the async functional-updater pattern.
|
|
71
|
+
const progressRef = (0, react_1.useRef)(0);
|
|
72
|
+
// ── Stall detection: show patience message after 35s of no progress change ──
|
|
73
|
+
const [showPatience, setShowPatience] = (0, react_1.useState)(false);
|
|
74
|
+
const lastProgressRef = (0, react_1.useRef)(0);
|
|
75
|
+
const stallTimerRef = (0, react_1.useRef)(null);
|
|
67
76
|
(0, react_1.useEffect)(() => {
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
if (finishingRef.current) {
|
|
78
|
+
setShowPatience(false);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (progress !== lastProgressRef.current) {
|
|
82
|
+
lastProgressRef.current = progress;
|
|
83
|
+
setShowPatience(false);
|
|
84
|
+
if (stallTimerRef.current)
|
|
85
|
+
clearTimeout(stallTimerRef.current);
|
|
86
|
+
stallTimerRef.current = setTimeout(() => {
|
|
87
|
+
if (!finishingRef.current)
|
|
88
|
+
setShowPatience(true);
|
|
89
|
+
}, 8000);
|
|
90
|
+
}
|
|
91
|
+
return () => {
|
|
92
|
+
if (stallTimerRef.current)
|
|
93
|
+
clearTimeout(stallTimerRef.current);
|
|
94
|
+
};
|
|
95
|
+
}, [progress]);
|
|
96
|
+
const setProgressSync = (v) => {
|
|
97
|
+
progressRef.current = v;
|
|
98
|
+
setProgress(v);
|
|
99
|
+
};
|
|
100
|
+
// ── Crawl: 0 → 80% — skipped entirely if reportReady already true on mount ──
|
|
101
|
+
(0, react_1.useEffect)(() => {
|
|
102
|
+
if (reportReady || finishingRef.current)
|
|
103
|
+
return;
|
|
70
104
|
const iv = setInterval(() => {
|
|
71
|
-
|
|
72
|
-
setProgress(i);
|
|
73
|
-
if (i >= stages.length) {
|
|
105
|
+
if (finishingRef.current) {
|
|
74
106
|
clearInterval(iv);
|
|
75
|
-
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const next = Math.min(progressRef.current + CRAWL_STEP, CRAWL_CEILING);
|
|
110
|
+
setProgressSync(next);
|
|
111
|
+
if (next >= CRAWL_CEILING)
|
|
112
|
+
clearInterval(iv);
|
|
113
|
+
}, CRAWL_TICK_MS);
|
|
114
|
+
return () => clearInterval(iv);
|
|
115
|
+
// reportReady intentionally in deps: if it arrives before mount effect runs, skip crawl
|
|
116
|
+
}, [reportReady]);
|
|
117
|
+
// ── Stage labels: advance every STAGE_ADVANCE_MS ─────────────────
|
|
118
|
+
(0, react_1.useEffect)(() => {
|
|
119
|
+
const iv = setInterval(() => {
|
|
120
|
+
setStageIdx((i) => (i + 1 < stages.length ? i + 1 : i));
|
|
121
|
+
}, STAGE_ADVANCE_MS);
|
|
122
|
+
return () => clearInterval(iv);
|
|
123
|
+
}, [stages.length]);
|
|
124
|
+
// ── Finish: reportReady → fast fill to 100%, then onComplete ─────
|
|
125
|
+
(0, react_1.useEffect)(() => {
|
|
126
|
+
if (!reportReady || finishingRef.current || completedRef.current)
|
|
127
|
+
return;
|
|
128
|
+
finishingRef.current = true;
|
|
129
|
+
setStageIdx(stages.length - 1);
|
|
130
|
+
// Read current progress synchronously from ref — not from stale state closure
|
|
131
|
+
const startPct = progressRef.current;
|
|
132
|
+
const startTime = Date.now();
|
|
133
|
+
const frame = () => {
|
|
134
|
+
const elapsed = Date.now() - startTime;
|
|
135
|
+
const t = Math.min(elapsed / FINISH_MS, 1);
|
|
136
|
+
const eased = t < 1 ? t * (2 - t) : 1;
|
|
137
|
+
setProgressSync(startPct + (100 - startPct) * eased);
|
|
138
|
+
if (t < 1) {
|
|
139
|
+
requestAnimationFrame(frame);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
setProgressSync(100);
|
|
143
|
+
if (!completedRef.current) {
|
|
144
|
+
completedRef.current = true;
|
|
145
|
+
setTimeout(onComplete, 150);
|
|
146
|
+
}
|
|
76
147
|
}
|
|
77
|
-
}, stageInterval);
|
|
78
|
-
return () => {
|
|
79
|
-
clearInterval(iv);
|
|
80
|
-
if (navTimer !== null)
|
|
81
|
-
clearTimeout(navTimer);
|
|
82
148
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
149
|
+
requestAnimationFrame(frame);
|
|
150
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
151
|
+
}, [reportReady, stages.length]);
|
|
152
|
+
const pct = Math.round(progress);
|
|
153
|
+
const title = (profile === null || profile === void 0 ? void 0 : profile.bizName) ? `Analyzing ${profile.bizName}` : "Running Analysis";
|
|
154
|
+
const isFinishing = finishingRef.current;
|
|
88
155
|
return (react_1.default.createElement("div", { className: "pt-[60px] text-center" },
|
|
89
156
|
react_1.default.createElement("div", { className: "relative w-[72px] h-[72px] mx-auto mb-7" },
|
|
90
157
|
react_1.default.createElement("div", { className: "absolute inset-0 rounded-full animate-ping", style: {
|
|
91
158
|
background: "radial-gradient(circle, #248384, transparent 70%)",
|
|
92
159
|
opacity: 0.15,
|
|
160
|
+
animationDuration: isFinishing ? "0.4s" : "1.4s",
|
|
93
161
|
} }),
|
|
94
162
|
react_1.default.createElement("div", { className: "absolute inset-0 w-[72px] h-[72px] rounded-full bg-tax-axis-surface flex items-center justify-center", style: { border: "2px solid rgba(36,131,132,0.4)" } },
|
|
95
|
-
react_1.default.createElement("span", { className: "
|
|
163
|
+
react_1.default.createElement("span", { className: "font-bold text-tax-axis-teal-light font-tax-axis-mono", style: { fontSize: pct === 100 ? 20 : 28 } }, pct === 100 ? "✓" : pct))),
|
|
96
164
|
react_1.default.createElement("h2", { className: "text-[22px] font-bold text-white font-tax-axis-head mb-1" }, title),
|
|
97
|
-
react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-3 font-tax-axis-body mb-7" }, "Deterministic
|
|
165
|
+
react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-3 font-tax-axis-body mb-7" }, isFinishing ? "Report ready — loading your results…" : "Deterministic · Temperature 0 · IRS-cited"),
|
|
98
166
|
react_1.default.createElement("div", { className: "max-w-[360px] mx-auto mb-6 h-0.5 bg-tax-axis-surface-2 rounded-sm overflow-hidden" },
|
|
99
|
-
react_1.default.createElement("div", { className: "h-full rounded-sm
|
|
100
|
-
width: `${
|
|
167
|
+
react_1.default.createElement("div", { className: "h-full rounded-sm", style: {
|
|
168
|
+
width: `${progress}%`,
|
|
101
169
|
background: "linear-gradient(90deg, #248384, #A1E5E6)",
|
|
102
170
|
boxShadow: "0 0 8px #248384",
|
|
171
|
+
transition: isFinishing ? "none" : "width 0.18s linear",
|
|
103
172
|
} })),
|
|
104
|
-
react_1.default.createElement(ProcessingStages_1.ProcessingStages, { stages: stages, progress:
|
|
173
|
+
react_1.default.createElement(ProcessingStages_1.ProcessingStages, { stages: stages, progress: stageIdx + 1 }),
|
|
174
|
+
pct >= CRAWL_CEILING && !isFinishing && (react_1.default.createElement("p", { className: "text-[11px] text-tax-axis-text-4 font-tax-axis-mono mt-4 animate-pulse" }, "Finalizing analysis\u2026")),
|
|
175
|
+
showPatience && !isFinishing && (react_1.default.createElement("p", { className: "text-[13px] text-tax-axis-text-3 font-tax-axis-body mt-4 text-center" }, "Still running \u2014 document analysis typically takes 2\u20133 minutes. Do not navigate away."))));
|
|
105
176
|
}
|
|
@@ -16,8 +16,6 @@ function ProspectPrintView({ profile, bizName, displayLo, displayHi, currentTax,
|
|
|
16
16
|
body * { visibility: hidden !important; }
|
|
17
17
|
.prospect-print-root, .prospect-print-root * { visibility: visible !important; }
|
|
18
18
|
.prospect-print-root { position: absolute !important; left: 0 !important; top: 0 !important; width: 100% !important; }
|
|
19
|
-
body, p, span, div, td, th, li { color: #212529 !important; }
|
|
20
|
-
h1, h2, h3, h4, h5, h6, strong, b { color: #060821 !important; }
|
|
21
19
|
.no-print { display: none !important; }
|
|
22
20
|
}
|
|
23
21
|
`),
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Strategy, ClientProfile, ComputedMap } from "../../lib/types";
|
|
3
|
-
interface BackendNarrative {
|
|
4
|
-
whyThisMatters: string;
|
|
5
|
-
howSavingsBreakDown: string;
|
|
6
|
-
whyYouNeedSpecialist: string;
|
|
7
|
-
whatWeDoNext: string;
|
|
8
|
-
}
|
|
9
3
|
interface ProspectStrategyCardProps {
|
|
10
4
|
strategy: Strategy;
|
|
11
5
|
index: number;
|
|
12
6
|
profile: ClientProfile;
|
|
13
7
|
computed: ComputedMap;
|
|
14
|
-
backendNarrative?: BackendNarrative | null;
|
|
15
8
|
}
|
|
16
|
-
export declare function ProspectStrategyCard({ strategy: s, index: i, profile, computed
|
|
9
|
+
export declare function ProspectStrategyCard({ strategy: s, index: i, profile, computed }: ProspectStrategyCardProps): React.JSX.Element;
|
|
17
10
|
export {};
|
|
@@ -8,15 +8,15 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const strategyNarrative_1 = require("../../lib/data/strategyNarrative");
|
|
9
9
|
const strategyProspect_1 = require("../../lib/data/strategyProspect");
|
|
10
10
|
const theme_1 = require("./theme");
|
|
11
|
-
function ProspectStrategyCard({ strategy: s, index: i, profile, computed
|
|
11
|
+
function ProspectStrategyCard({ strategy: s, index: i, profile, computed }) {
|
|
12
12
|
var _a, _b;
|
|
13
13
|
const p = strategyProspect_1.STRATEGY_PROSPECT[s.rank];
|
|
14
14
|
const narr = strategyNarrative_1.STRATEGY_NARRATIVE[s.rank];
|
|
15
15
|
const c = computed.get(s.rank);
|
|
16
|
-
const whyText =
|
|
17
|
-
const breakdownText =
|
|
18
|
-
const specialistText = (
|
|
19
|
-
const nextText =
|
|
16
|
+
const whyText = narr ? narr.whyMatters(profile) : strategyNarrative_1.NARRATIVE_FALLBACK.whyMatters(s);
|
|
17
|
+
const breakdownText = narr ? narr.breakdown(profile, c) : strategyNarrative_1.NARRATIVE_FALLBACK.breakdown(s, c);
|
|
18
|
+
const specialistText = (narr === null || narr === void 0 ? void 0 : narr.whySpecialist) || strategyNarrative_1.NARRATIVE_FALLBACK.whySpecialist(s);
|
|
19
|
+
const nextText = narr ? narr.nextSteps : strategyNarrative_1.NARRATIVE_FALLBACK.nextSteps(s);
|
|
20
20
|
const scaledLo = Math.round(((_a = c === null || c === void 0 ? void 0 : c.lo) !== null && _a !== void 0 ? _a : s.lo) / 1000);
|
|
21
21
|
const scaledHi = Math.round(((_b = c === null || c === void 0 ? void 0 : c.hi) !== null && _b !== void 0 ? _b : s.hi) / 1000);
|
|
22
22
|
return (react_1.default.createElement("div", { style: { background: theme_1.T.surface, border: `1px solid ${theme_1.T.border}`, borderRadius: 14, padding: "24px 28px", boxShadow: theme_1.T.shadow } },
|
|
@@ -1,35 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { ClientProfile, TaxAxisScreenProps } from "../../lib/types";
|
|
3
|
-
export interface BackendProspectResults {
|
|
4
|
-
sessionId: string;
|
|
5
|
-
strategies: Array<{
|
|
6
|
-
strategyId: string;
|
|
7
|
-
strategyName: string;
|
|
8
|
-
priorityTier: string;
|
|
9
|
-
savingsLo: number;
|
|
10
|
-
savingsHi: number;
|
|
11
|
-
score: number;
|
|
12
|
-
quickWin: boolean;
|
|
13
|
-
timeline: string;
|
|
14
|
-
ircCite: string;
|
|
15
|
-
narrative: {
|
|
16
|
-
whyThisMatters: string;
|
|
17
|
-
howSavingsBreakDown: string;
|
|
18
|
-
whyYouNeedSpecialist: string;
|
|
19
|
-
whatWeDoNext: string;
|
|
20
|
-
};
|
|
21
|
-
}>;
|
|
22
|
-
executiveSummary: string;
|
|
23
|
-
totalSavingsLo: number;
|
|
24
|
-
totalSavingsHi: number;
|
|
25
|
-
eligibleCount: number;
|
|
26
|
-
generatedAt: string;
|
|
27
|
-
}
|
|
28
3
|
export interface TaxAxisProspectReportProps extends TaxAxisScreenProps {
|
|
29
4
|
profile: ClientProfile;
|
|
30
|
-
backendResults?: BackendProspectResults | null;
|
|
31
5
|
onUpgrade?: () => void;
|
|
32
6
|
onPresent?: () => void;
|
|
33
7
|
onReset?: () => void;
|
|
34
8
|
}
|
|
35
|
-
export declare function TaxAxisProspectReport({ profile,
|
|
9
|
+
export declare function TaxAxisProspectReport({ profile, onUpgrade, onPresent, onReset, }: TaxAxisProspectReportProps): React.JSX.Element;
|
|
@@ -35,24 +35,10 @@ const SampleAnalysisPreview_1 = require("./SampleAnalysisPreview");
|
|
|
35
35
|
const ProspectDocuments_1 = require("./ProspectDocuments");
|
|
36
36
|
const ProspectNextSteps_1 = require("./ProspectNextSteps");
|
|
37
37
|
const ProspectPrintView_1 = require("./ProspectPrintView");
|
|
38
|
-
function TaxAxisProspectReport({ profile,
|
|
38
|
+
function TaxAxisProspectReport({ profile, onUpgrade, onPresent, onReset, }) {
|
|
39
39
|
const bizName = profile.bizName || "Client";
|
|
40
40
|
const [confirmReset, setConfirmReset] = (0, react_1.useState)(false);
|
|
41
41
|
const [printMode, setPrintMode] = (0, react_1.useState)(false);
|
|
42
|
-
// ═══ BACKEND NARRATIVE LOOKUP ═══
|
|
43
|
-
// Build a map from strategy rank (number) to backend narrative when available.
|
|
44
|
-
// strategyId format: "S1", "S2", etc.
|
|
45
|
-
const narrativeLookup = (0, react_1.useMemo)(() => {
|
|
46
|
-
if (!(backendResults === null || backendResults === void 0 ? void 0 : backendResults.strategies))
|
|
47
|
-
return null;
|
|
48
|
-
const map = new Map();
|
|
49
|
-
for (const s of backendResults.strategies) {
|
|
50
|
-
const rank = parseInt(s.strategyId.replace("S", ""), 10);
|
|
51
|
-
if (!isNaN(rank))
|
|
52
|
-
map.set(rank, s.narrative);
|
|
53
|
-
}
|
|
54
|
-
return map;
|
|
55
|
-
}, [backendResults]);
|
|
56
42
|
// ═══ ELIGIBLE STRATEGIES ═══
|
|
57
43
|
const eligible = (0, react_1.useMemo)(() => (0, compute_1.filterEligibleStrategies)(profile), [profile]);
|
|
58
44
|
const high = eligible.filter(s => s.priority === "HIGH");
|
|
@@ -123,30 +109,29 @@ function TaxAxisProspectReport({ profile, backendResults, onUpgrade, onPresent,
|
|
|
123
109
|
react_1.default.createElement("span", { style: { fontSize: 11, fontWeight: 700, color: theme_1.T.accent, fontFamily: theme_1.T.mono } }, "01"),
|
|
124
110
|
react_1.default.createElement("span", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: theme_1.T.text4, fontFamily: theme_1.T.body } }, "EXECUTIVE SUMMARY")),
|
|
125
111
|
react_1.default.createElement("div", { style: { height: 2, background: theme_1.T.accent, width: 48, marginBottom: 16 } }),
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
" These are profile-based estimates \u2014 uploading financial documents will refine savings calculations and unlock all 25 strategies.")))),
|
|
112
|
+
react_1.default.createElement("div", { style: { fontSize: 14, color: theme_1.T.text2, fontFamily: theme_1.T.body, lineHeight: 1.8, marginBottom: 12 } },
|
|
113
|
+
"We evaluated ",
|
|
114
|
+
bizName,
|
|
115
|
+
"'s tax position against 25 federal strategies and identified ",
|
|
116
|
+
react_1.default.createElement("strong", { style: { color: theme_1.T.white } },
|
|
117
|
+
eligible.length,
|
|
118
|
+
" applicable opportunities"),
|
|
119
|
+
" with combined estimated savings of ",
|
|
120
|
+
react_1.default.createElement("strong", { style: { color: theme_1.T.accentLt } },
|
|
121
|
+
"$",
|
|
122
|
+
displayLo,
|
|
123
|
+
"K\u2013$",
|
|
124
|
+
displayHi,
|
|
125
|
+
"K annually"),
|
|
126
|
+
". ",
|
|
127
|
+
high.length,
|
|
128
|
+
" strategies could have significant impact."),
|
|
129
|
+
react_1.default.createElement("div", { style: { fontSize: 14, color: theme_1.T.text2, fontFamily: theme_1.T.body, lineHeight: 1.8 } },
|
|
130
|
+
"The top ",
|
|
131
|
+
top3.length,
|
|
132
|
+
" strategies are detailed below.",
|
|
133
|
+
quick.length > 0 ? ` ${quick.length} can be implemented this week with no structural changes.` : "",
|
|
134
|
+
" These are profile-based estimates \u2014 uploading financial documents will refine savings calculations and unlock all 25 strategies.")),
|
|
150
135
|
react_1.default.createElement("div", { style: { background: theme_1.T.surface, border: `1px solid ${theme_1.T.border}`, borderRadius: 14, padding: "20px 24px", marginBottom: 24, boxShadow: theme_1.T.shadow } },
|
|
151
136
|
react_1.default.createElement("div", { style: { fontSize: 10, fontWeight: 700, color: theme_1.T.text4, textTransform: "uppercase", letterSpacing: "0.12em", marginBottom: 12, fontFamily: theme_1.T.mono } }, "SAVINGS DISTRIBUTION"),
|
|
152
137
|
barData.map((b, i) => (react_1.default.createElement("div", { key: i, style: { display: "flex", alignItems: "center", gap: 10, marginBottom: i < barData.length - 1 ? 8 : 0 } },
|
|
@@ -166,10 +151,7 @@ function TaxAxisProspectReport({ profile, backendResults, onUpgrade, onPresent,
|
|
|
166
151
|
react_1.default.createElement("span", { style: { fontSize: 11, fontWeight: 700, color: theme_1.T.accent, fontFamily: theme_1.T.mono } }, "02"),
|
|
167
152
|
react_1.default.createElement("span", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em", color: theme_1.T.text4, fontFamily: theme_1.T.body } }, "RECOMMENDED STRATEGIES")),
|
|
168
153
|
react_1.default.createElement("div", { style: { height: 2, background: theme_1.T.accent, width: 48, marginBottom: 16 } }),
|
|
169
|
-
react_1.default.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 14 } }, top3.map((s, i) => {
|
|
170
|
-
var _a;
|
|
171
|
-
return (react_1.default.createElement(ProspectStrategyCard_1.ProspectStrategyCard, { key: s.rank, strategy: s, index: i, profile: profile, computed: computed, backendNarrative: (_a = narrativeLookup === null || narrativeLookup === void 0 ? void 0 : narrativeLookup.get(s.rank)) !== null && _a !== void 0 ? _a : null }));
|
|
172
|
-
}))),
|
|
154
|
+
react_1.default.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 14 } }, top3.map((s, i) => (react_1.default.createElement(ProspectStrategyCard_1.ProspectStrategyCard, { key: s.rank, strategy: s, index: i, profile: profile, computed: computed }))))),
|
|
173
155
|
remaining > 0 && (react_1.default.createElement("div", { style: { marginBottom: 24 } },
|
|
174
156
|
react_1.default.createElement("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 6 } },
|
|
175
157
|
react_1.default.createElement("span", { style: { fontSize: 11, fontWeight: 700, color: theme_1.T.accent, fontFamily: theme_1.T.mono } }, "03"),
|
package/lib/tax-axis/index.d.ts
CHANGED
|
@@ -5,11 +5,13 @@ export { SectionHeader } from "./components/shared/SectionHeader";
|
|
|
5
5
|
export * from "./lib/types";
|
|
6
6
|
export * from "./lib/data";
|
|
7
7
|
export * from "./lib/compute";
|
|
8
|
+
export { useEngineOutput } from "./lib/adapters/useEngineOutput";
|
|
9
|
+
export type { EngineOutput, EngineOutputAdapterResult, EngineStrategyAnalysis, EngineCpaWorkflow } from "./lib/adapters/useEngineOutput";
|
|
8
10
|
export { TaxAxisIntake } from "./components/intake/TaxAxisIntake";
|
|
9
11
|
export type { TaxAxisIntakeProps } from "./components/intake/TaxAxisIntake";
|
|
10
12
|
export { TaxAxisDocuments } from "./components/documents/TaxAxisDocuments";
|
|
11
13
|
export type { TaxAxisDocumentsProps } from "./components/documents/TaxAxisDocuments";
|
|
12
|
-
export { DocumentReviewModal
|
|
14
|
+
export { DocumentReviewModal } from "./components/documents/DocumentReviewModal";
|
|
13
15
|
export type { DocumentReviewModalProps } from "./components/documents/DocumentReviewModal";
|
|
14
16
|
export { TaxAxisProcessing } from "./components/processing/TaxAxisProcessing";
|
|
15
17
|
export type { TaxAxisProcessingProps } from "./components/processing/TaxAxisProcessing";
|
package/lib/tax-axis/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TaxAxisPresentationMode = exports.TaxAxisProspectReport = exports.TaxAxisExtractionReview = exports.TaxAxisPreparerWorkpaper = exports.TaxAxisClientReport = exports.TaxAxisDashboard = exports.TaxAxisProcessing = exports.
|
|
17
|
+
exports.TaxAxisPresentationMode = exports.TaxAxisProspectReport = exports.TaxAxisExtractionReview = exports.TaxAxisPreparerWorkpaper = exports.TaxAxisClientReport = exports.TaxAxisDashboard = exports.TaxAxisProcessing = exports.DocumentReviewModal = exports.TaxAxisDocuments = exports.TaxAxisIntake = exports.useEngineOutput = exports.SectionHeader = exports.TaxAxisButton = exports.TaxAxisBadge = exports.TaxAxisCard = void 0;
|
|
18
18
|
// Shared primitives
|
|
19
19
|
var TaxAxisCard_1 = require("./components/shared/TaxAxisCard");
|
|
20
20
|
Object.defineProperty(exports, "TaxAxisCard", { enumerable: true, get: function () { return TaxAxisCard_1.TaxAxisCard; } });
|
|
@@ -30,6 +30,9 @@ __exportStar(require("./lib/types"), exports);
|
|
|
30
30
|
__exportStar(require("./lib/data"), exports);
|
|
31
31
|
// Compute
|
|
32
32
|
__exportStar(require("./lib/compute"), exports);
|
|
33
|
+
// Adapters
|
|
34
|
+
var useEngineOutput_1 = require("./lib/adapters/useEngineOutput");
|
|
35
|
+
Object.defineProperty(exports, "useEngineOutput", { enumerable: true, get: function () { return useEngineOutput_1.useEngineOutput; } });
|
|
33
36
|
// Screens
|
|
34
37
|
var TaxAxisIntake_1 = require("./components/intake/TaxAxisIntake");
|
|
35
38
|
Object.defineProperty(exports, "TaxAxisIntake", { enumerable: true, get: function () { return TaxAxisIntake_1.TaxAxisIntake; } });
|
|
@@ -37,8 +40,6 @@ var TaxAxisDocuments_1 = require("./components/documents/TaxAxisDocuments");
|
|
|
37
40
|
Object.defineProperty(exports, "TaxAxisDocuments", { enumerable: true, get: function () { return TaxAxisDocuments_1.TaxAxisDocuments; } });
|
|
38
41
|
var DocumentReviewModal_1 = require("./components/documents/DocumentReviewModal");
|
|
39
42
|
Object.defineProperty(exports, "DocumentReviewModal", { enumerable: true, get: function () { return DocumentReviewModal_1.DocumentReviewModal; } });
|
|
40
|
-
Object.defineProperty(exports, "EXTRACTED_FIELDS_QUERY", { enumerable: true, get: function () { return DocumentReviewModal_1.EXTRACTED_FIELDS_QUERY; } });
|
|
41
|
-
Object.defineProperty(exports, "SAVE_FIELD_EDIT_MUTATION", { enumerable: true, get: function () { return DocumentReviewModal_1.SAVE_FIELD_EDIT_MUTATION; } });
|
|
42
43
|
var TaxAxisProcessing_1 = require("./components/processing/TaxAxisProcessing");
|
|
43
44
|
Object.defineProperty(exports, "TaxAxisProcessing", { enumerable: true, get: function () { return TaxAxisProcessing_1.TaxAxisProcessing; } });
|
|
44
45
|
var TaxAxisDashboard_1 = require("./components/dashboard/TaxAxisDashboard");
|
|
@@ -1,26 +1,151 @@
|
|
|
1
1
|
import type { Strategy, ComputedMap } from "../types";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
export interface SourceDocumentRef {
|
|
3
|
+
field_label: string;
|
|
4
|
+
value_display: string;
|
|
5
|
+
source_hint: string;
|
|
6
|
+
}
|
|
7
|
+
export interface EngineCalculationTrace {
|
|
8
|
+
strategy_id: string;
|
|
9
|
+
branch_executed: string | null;
|
|
10
|
+
formula: string;
|
|
11
|
+
inputs: Record<string, unknown>;
|
|
12
|
+
result_gross: number | null;
|
|
13
|
+
confidence_interval: {
|
|
14
|
+
low: number;
|
|
15
|
+
high: number;
|
|
16
|
+
basis: string;
|
|
17
|
+
} | null;
|
|
18
|
+
position_strength: string;
|
|
19
|
+
irs_cite: string;
|
|
20
|
+
data_quality_flag: string | null;
|
|
21
|
+
forms_required: string[];
|
|
22
|
+
deadline_flag: string | null;
|
|
23
|
+
amt_flag: boolean;
|
|
24
|
+
source_documents?: SourceDocumentRef[];
|
|
25
|
+
specialist_note?: string | null;
|
|
8
26
|
}
|
|
9
|
-
/** Single strategy analysis entry from the engine. */
|
|
10
27
|
export interface EngineStrategyAnalysis {
|
|
11
28
|
strategy_id: string;
|
|
12
29
|
strategy_name: string;
|
|
13
|
-
priority_tier:
|
|
30
|
+
priority_tier: "HIGH" | "MEDIUM" | "LOW" | "NOT_RECOMMENDED";
|
|
14
31
|
weighted_score: number;
|
|
32
|
+
scores: {
|
|
33
|
+
financial_impact: number;
|
|
34
|
+
applicability: number;
|
|
35
|
+
complexity: number;
|
|
36
|
+
risk: number;
|
|
37
|
+
cash_flow: number;
|
|
38
|
+
};
|
|
15
39
|
quick_win: boolean;
|
|
40
|
+
calculation_trace: EngineCalculationTrace;
|
|
16
41
|
engagement_recommendation: string;
|
|
17
|
-
|
|
18
|
-
|
|
42
|
+
risk_disclosure: string | null;
|
|
43
|
+
}
|
|
44
|
+
export interface EngineClientSummaryStrategy {
|
|
45
|
+
slot: number;
|
|
46
|
+
strategy_name: string;
|
|
47
|
+
savings_range: string;
|
|
48
|
+
why_it_applies: string;
|
|
49
|
+
next_step: string;
|
|
50
|
+
quick_win_badge: boolean;
|
|
51
|
+
deadline_flag?: string | null;
|
|
19
52
|
}
|
|
20
|
-
/** CPA workflow section from the engine. */
|
|
21
53
|
export interface EngineCpaWorkflow {
|
|
22
54
|
workpaper_codes: string[] | null;
|
|
55
|
+
section_6694_notices: Array<{
|
|
56
|
+
strategy_id: string;
|
|
57
|
+
position_strength: string;
|
|
58
|
+
notice: string;
|
|
59
|
+
}>;
|
|
60
|
+
prior_year_flags: string[];
|
|
61
|
+
conflict_of_interest_checklist: Array<{
|
|
62
|
+
strategy_id: string;
|
|
63
|
+
conflict_prompt: string;
|
|
64
|
+
confirmed_no_conflict: boolean;
|
|
65
|
+
}>;
|
|
23
66
|
engagement_recommendations: string[];
|
|
24
|
-
[key: string]: unknown;
|
|
25
67
|
}
|
|
26
|
-
export
|
|
68
|
+
export interface EngineOutput {
|
|
69
|
+
engagement_id: string;
|
|
70
|
+
generated_at: string;
|
|
71
|
+
algorithm_version: string;
|
|
72
|
+
business_profile: {
|
|
73
|
+
entity_type: string;
|
|
74
|
+
industry: string;
|
|
75
|
+
industry_vertical: string;
|
|
76
|
+
states: string[];
|
|
77
|
+
data_years: number;
|
|
78
|
+
confidence_tier: string;
|
|
79
|
+
effective_tax_rate: number | null;
|
|
80
|
+
data_quality_flags: string[];
|
|
81
|
+
};
|
|
82
|
+
eligibility_screening: {
|
|
83
|
+
excluded_strategies: Array<{
|
|
84
|
+
strategy_id: string;
|
|
85
|
+
status: "EXCLUDED";
|
|
86
|
+
reason: string;
|
|
87
|
+
irs_cite: string;
|
|
88
|
+
}>;
|
|
89
|
+
};
|
|
90
|
+
strategy_analysis: EngineStrategyAnalysis[];
|
|
91
|
+
strategy_interaction_warnings: Array<{
|
|
92
|
+
strategy_pair: [string, string];
|
|
93
|
+
warning_text: string;
|
|
94
|
+
}>;
|
|
95
|
+
implementation_roadmap: {
|
|
96
|
+
quick_wins: Array<{
|
|
97
|
+
strategy_id: string;
|
|
98
|
+
action: string;
|
|
99
|
+
deadline?: string | null;
|
|
100
|
+
}>;
|
|
101
|
+
immediate: Array<{
|
|
102
|
+
strategy_id: string;
|
|
103
|
+
action: string;
|
|
104
|
+
deadline?: string | null;
|
|
105
|
+
}>;
|
|
106
|
+
thirty_day: Array<{
|
|
107
|
+
strategy_id: string;
|
|
108
|
+
action: string;
|
|
109
|
+
deadline?: string | null;
|
|
110
|
+
}>;
|
|
111
|
+
ninety_day: Array<{
|
|
112
|
+
strategy_id: string;
|
|
113
|
+
action: string;
|
|
114
|
+
deadline?: string | null;
|
|
115
|
+
}>;
|
|
116
|
+
annual: Array<{
|
|
117
|
+
strategy_id: string;
|
|
118
|
+
action: string;
|
|
119
|
+
deadline?: string | null;
|
|
120
|
+
}>;
|
|
121
|
+
};
|
|
122
|
+
cpa_workflow: EngineCpaWorkflow;
|
|
123
|
+
client_summary: {
|
|
124
|
+
opening: string;
|
|
125
|
+
strategies: EngineClientSummaryStrategy[];
|
|
126
|
+
data_quality_note: string | null;
|
|
127
|
+
interaction_warning: string | null;
|
|
128
|
+
closing: string;
|
|
129
|
+
};
|
|
130
|
+
risk_disclosures: string[];
|
|
131
|
+
client_risk_disclosures: {
|
|
132
|
+
accuracy_penalty_warning: string | null;
|
|
133
|
+
applies_to_strategies: string[];
|
|
134
|
+
};
|
|
135
|
+
amt_flags: Array<{
|
|
136
|
+
trigger: string;
|
|
137
|
+
strategy_id: string;
|
|
138
|
+
flag_text: string;
|
|
139
|
+
}>;
|
|
140
|
+
nexus_flags: Array<{
|
|
141
|
+
state: string;
|
|
142
|
+
nexus_type: string;
|
|
143
|
+
flag_text: string;
|
|
144
|
+
}>;
|
|
145
|
+
}
|
|
146
|
+
export interface EngineOutputAdapterResult {
|
|
147
|
+
strategies: Strategy[];
|
|
148
|
+
computedMap: ComputedMap;
|
|
149
|
+
engineOutput: EngineOutput;
|
|
150
|
+
}
|
|
151
|
+
export declare function useEngineOutput(engineOutput: EngineOutput | null | undefined): EngineOutputAdapterResult | null;
|