@paro.io/expert-shared-components 1.14.70 → 1.14.71
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 +0 -8
- package/lib/components/TaxAxis/TaxAxisShell.js +13 -29
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +10 -6
- package/lib/tax-axis/components/clientReport/ImplementationRoadmap.d.ts +2 -1
- package/lib/tax-axis/components/clientReport/ImplementationRoadmap.js +11 -8
- package/lib/tax-axis/components/clientReport/ImplementationTimelineChart.d.ts +2 -1
- package/lib/tax-axis/components/clientReport/ImplementationTimelineChart.js +9 -3
- package/lib/tax-axis/components/clientReport/QuarterlyCashChart.d.ts +2 -1
- package/lib/tax-axis/components/clientReport/QuarterlyCashChart.js +9 -3
- package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +9 -2
- package/lib/tax-axis/components/dashboard/StrategyDetailPanel.js +3 -1
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +5 -2
- package/lib/tax-axis/components/intake/ClientParametersSection.js +14 -4
- package/lib/tax-axis/components/intake/IntakeCtaCards.d.ts +2 -8
- package/lib/tax-axis/components/intake/IntakeCtaCards.js +7 -70
- package/lib/tax-axis/components/intake/TaxAxisIntake.js +1 -1
- package/lib/tax-axis/components/intake/intakeSchema.js +1 -1
- package/lib/tax-axis/components/preparerWorkpaper/EngagementHeader.js +6 -2
- package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.js +3 -3
- package/lib/tax-axis/components/processing/TaxAxisProcessing.d.ts +1 -5
- package/lib/tax-axis/components/processing/TaxAxisProcessing.js +11 -27
- package/lib/tax-axis/components/prospectReport/ProspectNextSteps.js +1 -3
- package/lib/tax-axis/components/prospectReport/ProspectStrategyCard.d.ts +1 -7
- package/lib/tax-axis/components/prospectReport/ProspectStrategyCard.js +6 -8
- package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.d.ts +1 -33
- package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.js +56 -57
- package/lib/tax-axis/lib/adapters/useEngineOutput.d.ts +42 -58
- package/lib/tax-axis/lib/adapters/useEngineOutput.js +99 -35
- package/lib/tax-axis/lib/data/nextSteps.js +13 -13
- package/lib/tax-axis/lib/data/sourceDescriptions.js +6 -0
- package/lib/tax-axis/lib/documentFieldCatalog.d.ts +10 -5
- package/lib/tax-axis/lib/documentFieldCatalog.js +329 -115
- package/lib/tax-axis/lib/types/index.d.ts +2 -0
- package/package.json +1 -1
- package/lib/tax-axis/components/prospectReport/ProspectReportSkeleton.d.ts +0 -2
- package/lib/tax-axis/components/prospectReport/ProspectReportSkeleton.js +0 -78
|
@@ -55,12 +55,4 @@ export type TaxAxisApi = {
|
|
|
55
55
|
generatePdf: (sessionId: string) => Promise<any>;
|
|
56
56
|
getArtifacts: (sessionId: string) => Promise<any[]>;
|
|
57
57
|
importQboReport?: (sessionId: string, expertId: string, year: number, reportType: string) => Promise<any>;
|
|
58
|
-
generateProspectReport?: (input: {
|
|
59
|
-
freelancerId?: number | null;
|
|
60
|
-
clientProfile: Record<string, unknown>;
|
|
61
|
-
}) => Promise<{
|
|
62
|
-
reportId: string;
|
|
63
|
-
computePayload: Record<string, unknown>;
|
|
64
|
-
outputPayload: Record<string, unknown>;
|
|
65
|
-
}>;
|
|
66
58
|
};
|
|
@@ -147,8 +147,6 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
147
147
|
const [busyMessage, setBusyMessage] = (0, react_1.useState)('Syncing Tax Axis session...');
|
|
148
148
|
const [reportReady, setReportReady] = (0, react_1.useState)(false);
|
|
149
149
|
const isPollingRef = react_1.default.useRef(false);
|
|
150
|
-
const [prospectLoading, setProspectLoading] = (0, react_1.useState)(false);
|
|
151
|
-
const [prospectData, setProspectData] = (0, react_1.useState)(null);
|
|
152
150
|
// QBO state driven by EPS props — not localStorage
|
|
153
151
|
const [qboConnectedState, setQboConnectedState] = (0, react_1.useState)(!!qboConnected);
|
|
154
152
|
const [qboCompanyNameState, setQboCompanyNameState] = (0, react_1.useState)(qboCompanyName !== null && qboCompanyName !== void 0 ? qboCompanyName : null);
|
|
@@ -157,8 +155,12 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
157
155
|
react_1.default.useEffect(() => { setQboCompanyNameState(qboCompanyName !== null && qboCompanyName !== void 0 ? qboCompanyName : null); }, [qboCompanyName]);
|
|
158
156
|
// Derive live strategies from engineOutput so CLIENT_REPORT and PREPARER_WORKPAPER
|
|
159
157
|
// render real engine data instead of the static STRATEGIES catalog.
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
// preComputed comes from the formula engine — only strategies with status=COMPLETE
|
|
159
|
+
// should appear in reports. Without preComputed, the hook falls back to
|
|
160
|
+
// _reconciledPreComputed flags on strategy_analysis entries.
|
|
161
|
+
const engineOutput = (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]);
|
|
162
|
+
const preComputed = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.meta) === null || _a === void 0 ? void 0 : _a.preComputed) !== null && _b !== void 0 ? _b : null; }, [llmResult]);
|
|
163
|
+
const adapted = (0, useEngineOutput_1.useEngineOutput)(engineOutput, preComputed);
|
|
162
164
|
const fetchAndSetParsedDocuments = (0, react_1.useCallback)((sid) => __awaiter(void 0, void 0, void 0, function* () {
|
|
163
165
|
try {
|
|
164
166
|
const docs = yield taxAxisApi.getDocuments(sid);
|
|
@@ -240,30 +242,11 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
240
242
|
setReportReady(false);
|
|
241
243
|
updateSessionId(null);
|
|
242
244
|
}, [updateSessionId]);
|
|
243
|
-
const handleProspect = (
|
|
245
|
+
const handleProspect = (0, react_1.useCallback)((nextProfile) => {
|
|
244
246
|
setProfile(nextProfile);
|
|
245
247
|
setIsProspectFlow(true);
|
|
246
|
-
setProspectData(null);
|
|
247
|
-
setProspectLoading(true);
|
|
248
248
|
setStep('PROSPECT_REPORT');
|
|
249
|
-
|
|
250
|
-
if (taxAxisApi.generateProspectReport) {
|
|
251
|
-
const result = yield taxAxisApi.generateProspectReport({
|
|
252
|
-
clientProfile: nextProfile,
|
|
253
|
-
});
|
|
254
|
-
setProspectData({
|
|
255
|
-
computePayload: result.computePayload,
|
|
256
|
-
outputPayload: result.outputPayload,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
catch (err) {
|
|
261
|
-
console.error('[TaxAxisShell] generateProspectReport failed', err);
|
|
262
|
-
}
|
|
263
|
-
finally {
|
|
264
|
-
setProspectLoading(false);
|
|
265
|
-
}
|
|
266
|
-
});
|
|
249
|
+
}, []);
|
|
267
250
|
const handleFullAnalysis = (0, react_1.useCallback)((nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
268
251
|
setProfile(nextProfile);
|
|
269
252
|
setIsProspectFlow(false);
|
|
@@ -432,7 +415,7 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
432
415
|
}
|
|
433
416
|
}), [sessionId, taxAxisApi]);
|
|
434
417
|
const currentView = (0, react_1.useMemo)(() => {
|
|
435
|
-
var _a, _b, _c, _d
|
|
418
|
+
var _a, _b, _c, _d;
|
|
436
419
|
if (step === 'SESSION_SETUP') {
|
|
437
420
|
return (react_1.default.createElement(ShellContainer, null,
|
|
438
421
|
react_1.default.createElement(TaxAxisIntake_1.TaxAxisIntake, { userContext: userContext, initialProfile: initialProfile, onProspect: handleProspect, onFullAnalysis: handleFullAnalysis })));
|
|
@@ -443,7 +426,8 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
443
426
|
}
|
|
444
427
|
switch (step) {
|
|
445
428
|
case 'PROSPECT_REPORT':
|
|
446
|
-
return (react_1.default.createElement(ShellContainer, null,
|
|
429
|
+
return (react_1.default.createElement(ShellContainer, null,
|
|
430
|
+
react_1.default.createElement(TaxAxisProspectReport_1.TaxAxisProspectReport, { profile: profile, userContext: userContext, onUpgrade: () => setStep('DOCUMENT_UPLOAD'), onPresent: () => setStep('PRESENTATION'), onReset: handleReset })));
|
|
447
431
|
case 'DOCUMENT_UPLOAD':
|
|
448
432
|
return (react_1.default.createElement(ShellContainer, null,
|
|
449
433
|
react_1.default.createElement("div", { className: "flex items-center justify-between rounded-lg px-4 py-3 mb-5", style: {
|
|
@@ -507,10 +491,10 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
507
491
|
react_1.default.createElement(TaxAxisDashboard_1.TaxAxisDashboard, { profile: profile, userContext: userContext, llmResult: llmResult, parsedDocuments: parsedDocuments, onDownloadClient: () => setStep('CLIENT_REPORT'), onDownloadPreparer: () => setStep('PREPARER_WORKPAPER'), onPresent: () => setStep('PRESENTATION'), onSend: handleSendReport, onReviewData: () => setStep('PARSED_REVIEW'), onReset: handleReset })));
|
|
508
492
|
case 'CLIENT_REPORT':
|
|
509
493
|
return (react_1.default.createElement(ShellContainer, { fullWidth: true },
|
|
510
|
-
react_1.default.createElement(TaxAxisClientReport_1.TaxAxisClientReport, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onNavigatePreparer: () => setStep('PREPARER_WORKPAPER'), liveStrategies: adapted === null || adapted === void 0 ? void 0 : adapted.strategies, liveComputedMap: adapted === null || adapted === void 0 ? void 0 : adapted.computedMap, engineRawOutput: (
|
|
494
|
+
react_1.default.createElement(TaxAxisClientReport_1.TaxAxisClientReport, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onNavigatePreparer: () => setStep('PREPARER_WORKPAPER'), liveStrategies: adapted === null || adapted === void 0 ? void 0 : adapted.strategies, liveComputedMap: adapted === null || adapted === void 0 ? void 0 : adapted.computedMap, engineRawOutput: (_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) !== null && _a !== void 0 ? _a : llmResult === null || llmResult === void 0 ? void 0 : llmResult.engineOutput })));
|
|
511
495
|
case 'PREPARER_WORKPAPER':
|
|
512
496
|
return (react_1.default.createElement(ShellContainer, { fullWidth: true },
|
|
513
|
-
react_1.default.createElement(TaxAxisPreparerWorkpaper_1.TaxAxisPreparerWorkpaper, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onToggleToClient: () => setStep('CLIENT_REPORT'), liveStrategies: adapted === null || adapted === void 0 ? void 0 : adapted.strategies, liveComputedMap: adapted === null || adapted === void 0 ? void 0 : adapted.computedMap, cpaWorkflow: (
|
|
497
|
+
react_1.default.createElement(TaxAxisPreparerWorkpaper_1.TaxAxisPreparerWorkpaper, { profile: profile, userContext: userContext, onBack: () => setStep('DASHBOARD'), onToggleToClient: () => setStep('CLIENT_REPORT'), liveStrategies: adapted === null || adapted === void 0 ? void 0 : adapted.strategies, liveComputedMap: adapted === null || adapted === void 0 ? void 0 : adapted.computedMap, cpaWorkflow: (_b = llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) === null || _b === void 0 ? void 0 : _b.cpa_workflow, riskDisclosures: (_c = llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) === null || _c === void 0 ? void 0 : _c.risk_disclosures, businessProfile: (_d = llmResult === null || llmResult === void 0 ? void 0 : llmResult.rawOutput) === null || _d === void 0 ? void 0 : _d.business_profile })));
|
|
514
498
|
case 'PRESENTATION':
|
|
515
499
|
return (react_1.default.createElement(ShellContainer, { fullWidth: true },
|
|
516
500
|
react_1.default.createElement(TaxAxisPresentationMode_1.TaxAxisPresentationMode, { profile: profile, userContext: userContext, onBack: () => setStep(isProspectFlow ? 'PROSPECT_REPORT' : 'DASHBOARD') })));
|
|
@@ -8,13 +8,15 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const compute_1 = require("../../lib/compute");
|
|
9
9
|
const SectionOpener_1 = require("./SectionOpener");
|
|
10
10
|
const ETRChart_1 = require("./ETRChart");
|
|
11
|
+
// Format K values: >= 1000K -> "$X.XM", otherwise "$XK"
|
|
12
|
+
const fmtKRange = (k) => k >= 1000 ? "$" + (k / 1000).toFixed(1) + "M" : "$" + k + "K";
|
|
11
13
|
function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, nowCount, top3, palette, effectiveTaxRate, confidenceTier, dataYears }) {
|
|
12
14
|
const bizName = profile.bizName || "Client";
|
|
13
15
|
const rev = parseInt((profile.revenue || "0").replace(/,/g, "")) || 500000;
|
|
14
16
|
const dataYearsLabel = dataYears ? `${dataYears} year${dataYears > 1 ? "s" : ""}` : (profile.taxDataYears || "1 year");
|
|
15
17
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
16
18
|
react_1.default.createElement(SectionOpener_1.SectionOpener, { number: "01", eyebrow: "EXECUTIVE SUMMARY", headline: "Where " + bizName + "'s tax dollars are going \u2014 and where they don't have to.", bullets: [
|
|
17
|
-
eligible.length + " strategies apply to your current profile, with combined estimated savings of
|
|
19
|
+
eligible.length + " strategies apply to your current profile, with combined estimated savings of " + fmtKRange(totalLo) + "\u2013" + fmtKRange(totalHi) + " annually.",
|
|
18
20
|
nowCount > 0
|
|
19
21
|
? nowCount + " can be initiated this week without any structural changes to your business."
|
|
20
22
|
: "Implementation timeline spans the current tax year with no structural changes required.",
|
|
@@ -24,7 +26,7 @@ function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, nowCo
|
|
|
24
26
|
react_1.default.createElement("div", { style: { background: palette.gray50, border: "1px solid " + palette.gray200, borderRadius: 10, padding: "24px 28px", marginBottom: 20 } },
|
|
25
27
|
react_1.default.createElement("div", { style: { fontSize: 10, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.15em", color: palette.gray400, marginBottom: 16, fontFamily: palette.mono } }, "KEY METRICS"),
|
|
26
28
|
react_1.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 16 } }, [
|
|
27
|
-
{ v:
|
|
29
|
+
{ v: fmtKRange(totalLo) + "\u2013" + fmtKRange(totalHi), l: "Est. Annual Savings" },
|
|
28
30
|
{ v: String(eligible.length), l: "Strategies Identified" },
|
|
29
31
|
{ v: String(nowCount), l: "Immediate Actions" },
|
|
30
32
|
{ v: String(top3.length), l: "Priority Recommendations" },
|
|
@@ -39,21 +41,23 @@ function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, nowCo
|
|
|
39
41
|
eligible.length,
|
|
40
42
|
" applicable strategies"),
|
|
41
43
|
" with combined estimated savings of ",
|
|
42
|
-
react_1.default.createElement("strong", { style: { color: palette.teal } },
|
|
44
|
+
react_1.default.createElement("strong", { style: { color: palette.teal } }, fmtKRange(totalLo) + "\u2013" + fmtKRange(totalHi) + " annually"),
|
|
43
45
|
"."),
|
|
44
46
|
react_1.default.createElement("div", { style: { fontSize: 14, color: palette.gray700, lineHeight: 1.8, fontFamily: palette.body, marginBottom: 16 } },
|
|
45
47
|
top3.length,
|
|
46
48
|
" strategies represent the highest-impact opportunities and are detailed below. ",
|
|
47
49
|
nowCount > 0 ? "Of these and the broader eligible set, " + nowCount + " can be initiated this week with no structural changes to your business." : "",
|
|
48
50
|
" Savings estimates reflect your current revenue of ",
|
|
49
|
-
"$" + Math.round(rev / 1000) + "K",
|
|
51
|
+
rev >= 1000000 ? "$" + (rev / 1000000).toFixed(1) + "M" : "$" + Math.round(rev / 1000) + "K",
|
|
50
52
|
", an effective tax rate of ",
|
|
51
|
-
effectiveTaxRate != null ? Math.round((effectiveTaxRate <= 1 ? effectiveTaxRate * 100 : effectiveTaxRate) * 10) / 10 : (parseFloat(profile.federalRate || "24") + parseFloat(profile.stateRate || "4.95")),
|
|
53
|
+
effectiveTaxRate != null ? Math.round((effectiveTaxRate <= 1 ? effectiveTaxRate * 100 : effectiveTaxRate) * 10) / 10 : ((profile.entity === "C-Corporation" ? 21 : parseFloat(profile.federalRate || "24")) + parseFloat(profile.stateRate || "4.95")),
|
|
52
54
|
"%, and ",
|
|
53
55
|
dataYearsLabel,
|
|
54
56
|
" of financial data."),
|
|
55
57
|
(() => {
|
|
56
|
-
|
|
58
|
+
// C-Corps have a flat 21% federal rate
|
|
59
|
+
const isCCorp = profile.entity === "C-Corporation";
|
|
60
|
+
const fedRate = isCCorp ? 21 : parseFloat(profile.federalRate || "24");
|
|
57
61
|
const stateRate = parseFloat(profile.stateRate || "4.95");
|
|
58
62
|
// If engine provided effective_tax_rate (as a decimal 0-1), convert to percentage
|
|
59
63
|
const currentRate = effectiveTaxRate != null
|
|
@@ -21,6 +21,7 @@ interface ImplementationRoadmapProps {
|
|
|
21
21
|
bucketTotals: Record<string, BucketTotal>;
|
|
22
22
|
activeBuckets: BucketDef[];
|
|
23
23
|
palette: Palette;
|
|
24
|
+
taxYear?: string;
|
|
24
25
|
}
|
|
25
|
-
export declare function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bucketDefs, bucketTotals, activeBuckets, palette, }: ImplementationRoadmapProps): React.JSX.Element;
|
|
26
|
+
export declare function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bucketDefs, bucketTotals, activeBuckets, palette, taxYear, }: ImplementationRoadmapProps): React.JSX.Element;
|
|
26
27
|
export {};
|
|
@@ -9,7 +9,7 @@ const data_1 = require("../../lib/data");
|
|
|
9
9
|
const SectionOpener_1 = require("./SectionOpener");
|
|
10
10
|
const QuarterlyCashChart_1 = require("./QuarterlyCashChart");
|
|
11
11
|
const ImplementationTimelineChart_1 = require("./ImplementationTimelineChart");
|
|
12
|
-
function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bucketDefs, bucketTotals, activeBuckets, palette, }) {
|
|
12
|
+
function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bucketDefs, bucketTotals, activeBuckets, palette, taxYear, }) {
|
|
13
13
|
const card = {
|
|
14
14
|
background: palette.white,
|
|
15
15
|
border: "1px solid " + palette.gray200,
|
|
@@ -31,8 +31,8 @@ function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bu
|
|
|
31
31
|
"Time-sensitive elections and filings have firm deadlines noted in each strategy detail above.",
|
|
32
32
|
"Year-end planning items will be reviewed in a coordinated session before December 31.",
|
|
33
33
|
], palette: palette }),
|
|
34
|
-
react_1.default.createElement(QuarterlyCashChart_1.QuarterlyCashChart, { eligible: eligible, computed: computed, palette: palette }),
|
|
35
|
-
react_1.default.createElement(ImplementationTimelineChart_1.ImplementationTimelineChart, { top3: top3, computed: computed, palette: palette }),
|
|
34
|
+
react_1.default.createElement(QuarterlyCashChart_1.QuarterlyCashChart, { eligible: eligible, computed: computed, palette: palette, taxYear: taxYear }),
|
|
35
|
+
react_1.default.createElement(ImplementationTimelineChart_1.ImplementationTimelineChart, { top3: top3, computed: computed, palette: palette, taxYear: taxYear }),
|
|
36
36
|
react_1.default.createElement("div", { style: { marginBottom: 28 } }, activeBuckets.map(b => {
|
|
37
37
|
const bt = bucketTotals[b.key];
|
|
38
38
|
const midK = Math.round((bt.lo + bt.hi) / 2 / 1000);
|
|
@@ -42,10 +42,13 @@ function ImplementationRoadmap({ eligible, computed, top3, nowCount, nowMidK, bu
|
|
|
42
42
|
react_1.default.createElement("div", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.1em", color: b.color, fontFamily: palette.mono } }, b.label),
|
|
43
43
|
react_1.default.createElement("div", { style: { fontSize: 11, color: palette.gray400, fontFamily: palette.mono } }, bt.strategies.length + " " + (bt.strategies.length === 1 ? "strategy" : "strategies"))),
|
|
44
44
|
react_1.default.createElement("div", { style: { fontSize: 13, fontWeight: 700, color: palette.teal, fontFamily: palette.mono } }, "~$" + midK + "K midpoint")),
|
|
45
|
-
bt.strategies.map(s =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
react_1.default.createElement("div", { style: {
|
|
49
|
-
|
|
45
|
+
bt.strategies.map(s => {
|
|
46
|
+
var _a;
|
|
47
|
+
return (react_1.default.createElement("div", { key: s.rank, style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", padding: "10px 0", borderBottom: "1px solid " + palette.gray100 } },
|
|
48
|
+
react_1.default.createElement("div", { style: { flex: 1 } },
|
|
49
|
+
react_1.default.createElement("div", { style: { fontSize: 14, fontWeight: 600, color: palette.gray800, fontFamily: palette.head } }, s.name),
|
|
50
|
+
react_1.default.createElement("div", { style: { fontSize: 12, color: palette.gray500, marginTop: 2, fontFamily: palette.body } }, data_1.NEXT_STEPS[(_a = s.strategyNumber) !== null && _a !== void 0 ? _a : s.rank] || "Discuss with your preparer.")),
|
|
51
|
+
react_1.default.createElement("div", { style: { fontSize: 13, fontWeight: 700, color: palette.teal, fontFamily: palette.mono, flexShrink: 0, marginLeft: 12 } }, stSavings(s))));
|
|
52
|
+
})));
|
|
50
53
|
}))));
|
|
51
54
|
}
|
|
@@ -5,6 +5,7 @@ interface ImplementationTimelineChartProps {
|
|
|
5
5
|
top3: Strategy[];
|
|
6
6
|
computed: ComputedMap;
|
|
7
7
|
palette: Palette;
|
|
8
|
+
taxYear?: string;
|
|
8
9
|
}
|
|
9
|
-
export declare function ImplementationTimelineChart({ top3, computed, palette }: ImplementationTimelineChartProps): React.JSX.Element;
|
|
10
|
+
export declare function ImplementationTimelineChart({ top3, computed, palette, taxYear }: ImplementationTimelineChartProps): React.JSX.Element;
|
|
10
11
|
export {};
|
|
@@ -5,17 +5,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ImplementationTimelineChart = ImplementationTimelineChart;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
function ImplementationTimelineChart({ top3, computed, palette }) {
|
|
8
|
+
function ImplementationTimelineChart({ top3, computed, palette, taxYear }) {
|
|
9
9
|
const W = 640, H = Math.max(180, 60 + top3.length * 44);
|
|
10
10
|
const padL = 180, padR = 80, padT = 44, padB = 24;
|
|
11
11
|
const plotW = W - padL - padR, plotH = H - padT - padB;
|
|
12
12
|
const BUCKET_RANGE = { now: [0, 2], "30d": [0, 4], "90d": [2, 12], filing: [36, 52] };
|
|
13
13
|
const weekScale = (w) => padL + (w / 52) * plotW;
|
|
14
14
|
const qDividers = [13, 26, 39];
|
|
15
|
+
const currentYear = new Date().getFullYear();
|
|
16
|
+
const year = taxYear || String(currentYear);
|
|
17
|
+
const yearNum = parseInt(year, 10);
|
|
18
|
+
const isHistorical = yearNum < currentYear;
|
|
19
|
+
const chartTitle = isHistorical ? "IMPLEMENTATION SEQUENCE" : "IMPLEMENTATION TIMELINE";
|
|
15
20
|
const qLabels = ["Q1", "Q2", "Q3", "Q4"];
|
|
16
21
|
return (react_1.default.createElement("div", { className: "chart-block", style: { background: palette.white, border: "1px solid " + palette.gray200, borderRadius: 10, padding: "24px 28px", marginBottom: 24 } },
|
|
17
22
|
react_1.default.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 18 } },
|
|
18
|
-
react_1.default.createElement("div", { style: { fontSize: 10, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.15em", color: palette.gray400, fontFamily: palette.mono } },
|
|
23
|
+
react_1.default.createElement("div", { style: { fontSize: 10, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.15em", color: palette.gray400, fontFamily: palette.mono } }, chartTitle),
|
|
19
24
|
react_1.default.createElement("div", { style: { fontSize: 11, fontWeight: 700, color: palette.teal, fontFamily: palette.mono } }, "top " + top3.length + " priorities")),
|
|
20
25
|
react_1.default.createElement("svg", { viewBox: "0 0 " + W + " " + H, style: { width: "100%", height: "auto", display: "block" } },
|
|
21
26
|
[0, 1, 2, 3].map(qi => {
|
|
@@ -27,7 +32,8 @@ function ImplementationTimelineChart({ top3, computed, palette }) {
|
|
|
27
32
|
const cx = weekScale(qi * 13 + 6.5);
|
|
28
33
|
return react_1.default.createElement("text", { key: q, x: cx, y: padT - 18, fontSize: "10", fontWeight: "700", fill: palette.gray400, fontFamily: palette.mono, textAnchor: "middle" },
|
|
29
34
|
q,
|
|
30
|
-
"
|
|
35
|
+
" ",
|
|
36
|
+
year);
|
|
31
37
|
}),
|
|
32
38
|
qDividers.map(w => (react_1.default.createElement("line", { key: w, x1: weekScale(w), y1: padT - 12, x2: weekScale(w), y2: padT + plotH + 4, stroke: palette.gray200, strokeWidth: "1", strokeDasharray: "2,3" }))),
|
|
33
39
|
top3.map((s, i) => {
|
|
@@ -5,6 +5,7 @@ interface QuarterlyCashChartProps {
|
|
|
5
5
|
eligible: Strategy[];
|
|
6
6
|
computed: ComputedMap;
|
|
7
7
|
palette: Palette;
|
|
8
|
+
taxYear?: string;
|
|
8
9
|
}
|
|
9
|
-
export declare function QuarterlyCashChart({ eligible, computed, palette }: QuarterlyCashChartProps): React.JSX.Element;
|
|
10
|
+
export declare function QuarterlyCashChart({ eligible, computed, palette, taxYear }: QuarterlyCashChartProps): React.JSX.Element;
|
|
10
11
|
export {};
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.QuarterlyCashChart = QuarterlyCashChart;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
function QuarterlyCashChart({ eligible, computed, palette }) {
|
|
8
|
+
function QuarterlyCashChart({ eligible, computed, palette, taxYear }) {
|
|
9
9
|
const W = 600, H = 240;
|
|
10
10
|
const padL = 56, padR = 24, padT = 32, padB = 52;
|
|
11
11
|
const plotW = W - padL - padR, plotH = H - padT - padB;
|
|
@@ -25,8 +25,14 @@ function QuarterlyCashChart({ eligible, computed, palette }) {
|
|
|
25
25
|
const yScale = (v) => padT + plotH - (v / maxVal) * plotH;
|
|
26
26
|
const barW = Math.min(72, (plotW - 60) / 4);
|
|
27
27
|
const slot = plotW / 4;
|
|
28
|
-
const
|
|
29
|
-
const
|
|
28
|
+
const currentYear = new Date().getFullYear();
|
|
29
|
+
const year = taxYear || String(currentYear);
|
|
30
|
+
const yearNum = parseInt(year, 10);
|
|
31
|
+
const isHistorical = yearNum < currentYear;
|
|
32
|
+
const labels = [`Q1 ${year}`, `Q2 ${year}`, `Q3 ${year}`, `Q4 ${year}`];
|
|
33
|
+
const sublabels = isHistorical
|
|
34
|
+
? ["Q1 actions", "Q2 actions", "Q3 actions", "Q4 actions"]
|
|
35
|
+
: ["Now / 30 days", "Within 90 days", "Mid-year", "At filing"];
|
|
30
36
|
const tickStep = maxVal > 200000 ? 100000 : maxVal > 100000 ? 50000 : 25000;
|
|
31
37
|
const yTicks = [];
|
|
32
38
|
for (let v = 0; v <= maxVal * 1.05; v += tickStep)
|
|
@@ -55,7 +55,14 @@ function TaxAxisClientReport({ profile, onBack, onNavigatePreparer, liveStrategi
|
|
|
55
55
|
];
|
|
56
56
|
const bucketTotals = {};
|
|
57
57
|
bucketDefs.forEach(b => {
|
|
58
|
-
const strategies = eligible.filter(s =>
|
|
58
|
+
const strategies = eligible.filter(s => {
|
|
59
|
+
var _a, _b, _c, _d;
|
|
60
|
+
if (s.timelineBucket !== b.key)
|
|
61
|
+
return false;
|
|
62
|
+
const clo = (_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.lo) !== null && _b !== void 0 ? _b : s.lo;
|
|
63
|
+
const chi = (_d = (_c = computed.get(s.rank)) === null || _c === void 0 ? void 0 : _c.hi) !== null && _d !== void 0 ? _d : s.hi;
|
|
64
|
+
return clo > 0 || chi > 0;
|
|
65
|
+
}).sort((a, c) => c.score - a.score);
|
|
59
66
|
const lo = strategies.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.lo) !== null && _b !== void 0 ? _b : s.lo); }, 0);
|
|
60
67
|
const hi = strategies.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.hi) !== null && _b !== void 0 ? _b : s.hi); }, 0);
|
|
61
68
|
bucketTotals[b.key] = { strategies, lo, hi };
|
|
@@ -115,7 +122,7 @@ function TaxAxisClientReport({ profile, onBack, onNavigatePreparer, liveStrategi
|
|
|
115
122
|
"This summary was prepared using TaxAxis, Paro's AI-powered tax analysis engine. Savings estimates are based on financial data provided for tax year " + profile.year + " (" + (profile.taxDataYears || "1 year") + " of data). All figures are estimates. Your tax preparer has reviewed these recommendations.",
|
|
116
123
|
hasOBBBA && " Some strategies reference provisions from the One Big Beautiful Bill Act (OBBBA), signed July 4, 2025, with limited IRS guidance."),
|
|
117
124
|
react_1.default.createElement(RecommendedStrategies_1.RecommendedStrategies, { profile: profile, eligible: eligible, computed: computed, top3: top3, hasOBBBA: hasOBBBA, palette: palette_1.P, interactionWarnings: engineRawOutput === null || engineRawOutput === void 0 ? void 0 : engineRawOutput.strategy_interaction_warnings }),
|
|
118
|
-
react_1.default.createElement(ImplementationRoadmap_1.ImplementationRoadmap, { eligible: eligible, computed: computed, top3: top3, nowCount: nowCount, nowMidK: nowMidK, bucketDefs: bucketDefs, bucketTotals: bucketTotals, activeBuckets: activeBuckets, palette: palette_1.P }),
|
|
125
|
+
react_1.default.createElement(ImplementationRoadmap_1.ImplementationRoadmap, { eligible: eligible, computed: computed, top3: top3, nowCount: nowCount, nowMidK: nowMidK, bucketDefs: bucketDefs, bucketTotals: bucketTotals, activeBuckets: activeBuckets, palette: palette_1.P, taxYear: profile.year }),
|
|
119
126
|
react_1.default.createElement(Methodology_1.Methodology, { profile: profile, eligible: eligible, palette: palette_1.P }),
|
|
120
127
|
react_1.default.createElement("div", { style: { padding: "16px 20px", marginBottom: 16, fontSize: 10, color: palette_1.P.gray400, lineHeight: 1.7, fontFamily: palette_1.P.body } }, "This summary was generated by TaxAxis, an AI-powered analysis tool by Paro. Recommendations are based on financial data provided and current tax law as of April 2026, including OBBBA provisions. These are estimates, not guarantees. Consult your tax preparer before implementing any strategy. This is not legal or financial advice."),
|
|
121
128
|
react_1.default.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", padding: "12px 0", borderTop: "1px solid " + palette_1.P.gray200, fontSize: 10, color: palette_1.P.gray400, fontFamily: palette_1.P.mono } },
|
|
@@ -11,7 +11,9 @@ function Sec({ title, children, titleColor }) {
|
|
|
11
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),
|
|
12
12
|
children));
|
|
13
13
|
}
|
|
14
|
-
const fmtK = (n) =>
|
|
14
|
+
const fmtK = (n) => n >= 1000000
|
|
15
|
+
? `$${(n / 1000000).toFixed(1)}M`
|
|
16
|
+
: `$${(n / 1000).toFixed(n % 1000 ? 1 : 0)}K`;
|
|
15
17
|
function positionStrengthLabel(positionStrength) {
|
|
16
18
|
if (!positionStrength)
|
|
17
19
|
return { label: "Position Under Review", color: "#9498B8", dots: 2 };
|
|
@@ -235,7 +235,9 @@ function buildLlmComputed(strategies) {
|
|
|
235
235
|
return map;
|
|
236
236
|
}
|
|
237
237
|
// ─── Formatting helper ──────────────────────────────────────────
|
|
238
|
-
const fmtK = (n) =>
|
|
238
|
+
const fmtK = (n) => n >= 1000000
|
|
239
|
+
? `$${(n / 1000000).toFixed(1)}M`
|
|
240
|
+
: `$${(n / 1000).toFixed(n % 1000 ? 1 : 0)}K`;
|
|
239
241
|
// ─── Timeline buckets for Client Summary ────────────────────────
|
|
240
242
|
const BUCKETS = [
|
|
241
243
|
{ key: "now", label: "Act Now", desc: "Claim on your return or adjust this pay period" },
|
|
@@ -264,7 +266,8 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
264
266
|
// clientBrief from why_it_applies, etc.) over the thin mapLlmToStrategies fallback.
|
|
265
267
|
// engineOutput is at llmResult.engineOutput or llmResult.rawOutput (both present).
|
|
266
268
|
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]);
|
|
267
|
-
const
|
|
269
|
+
const preComputedForAdapter = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.meta) === null || _a === void 0 ? void 0 : _a.preComputed) !== null && _b !== void 0 ? _b : null; }, [llmResult]);
|
|
270
|
+
const adapted = (0, useEngineOutput_1.useEngineOutput)(engineOutputForAdapter, preComputedForAdapter);
|
|
268
271
|
const llmStrategies = (0, react_1.useMemo)(() => {
|
|
269
272
|
var _a;
|
|
270
273
|
if (!hasLlm)
|
|
@@ -66,10 +66,20 @@ const INDUSTRY_OPTIONS = [
|
|
|
66
66
|
"Real Estate",
|
|
67
67
|
"Other",
|
|
68
68
|
];
|
|
69
|
-
const
|
|
70
|
-
const YEAR_OPTIONS = ["2024", "2025", "2026"];
|
|
69
|
+
const CURRENT_YEAR = new Date().getFullYear();
|
|
70
|
+
const YEAR_OPTIONS = ["2023", "2024", "2025", "2026"];
|
|
71
71
|
function ClientParametersSection({ userContext = "expert", }) {
|
|
72
|
-
const { control, formState: { errors }, } = (0, react_hook_form_1.useFormContext)();
|
|
72
|
+
const { control, formState: { errors }, watch, setValue, } = (0, react_hook_form_1.useFormContext)();
|
|
73
|
+
const selectedYear = watch("year");
|
|
74
|
+
const yearNum = parseInt(selectedYear || "2026", 10);
|
|
75
|
+
const isCurrentOrFuture = yearNum >= CURRENT_YEAR;
|
|
76
|
+
const periodOptions = isCurrentOrFuture ? ["YTD"] : ["Full Year", "YTD"];
|
|
77
|
+
// Auto-switch period to "YTD" when user selects a current/future tax year
|
|
78
|
+
react_1.default.useEffect(() => {
|
|
79
|
+
if (isCurrentOrFuture) {
|
|
80
|
+
setValue("period", "YTD");
|
|
81
|
+
}
|
|
82
|
+
}, [isCurrentOrFuture, setValue]);
|
|
73
83
|
const [expanded, setExpanded] = (0, react_1.useState)(true);
|
|
74
84
|
return (react_1.default.createElement(TaxAxisCard_1.TaxAxisCard, null,
|
|
75
85
|
react_1.default.createElement("div", { onClick: () => setExpanded((prev) => !prev), className: "flex items-center justify-between cursor-pointer", style: { marginBottom: expanded ? 14 : 0 } },
|
|
@@ -103,7 +113,7 @@ function ClientParametersSection({ userContext = "expert", }) {
|
|
|
103
113
|
react_1.default.createElement(react_hook_form_1.Controller, { name: "period", control: control, render: ({ field }) => {
|
|
104
114
|
var _a;
|
|
105
115
|
return (react_1.default.createElement("div", { className: "relative" },
|
|
106
|
-
react_1.default.createElement("select", Object.assign({}, field, { value: (_a = field.value) !== null && _a !== void 0 ? _a : "Full Year", className: selectCls }),
|
|
116
|
+
react_1.default.createElement("select", Object.assign({}, field, { value: (_a = field.value) !== null && _a !== void 0 ? _a : (isCurrentOrFuture ? "YTD" : "Full Year"), className: selectCls }), periodOptions.map(o => (react_1.default.createElement("option", { key: o, value: o, className: "bg-tax-axis-surface-2" }, o)))),
|
|
107
117
|
react_1.default.createElement(Chevron, null)));
|
|
108
118
|
} })),
|
|
109
119
|
react_1.default.createElement("div", null,
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
3
|
-
interface ProspectReadiness {
|
|
4
|
-
ready: boolean;
|
|
5
|
-
missingFields: string[];
|
|
6
|
-
}
|
|
7
|
-
export declare function isProspectReady(profile: Partial<ClientProfile>): ProspectReadiness;
|
|
2
|
+
import { UserContext } from "../../lib/types";
|
|
8
3
|
interface IntakeCtaCardsProps {
|
|
9
|
-
profile: Partial<ClientProfile>;
|
|
10
4
|
onProspect: () => void;
|
|
11
5
|
onFullAnalysis: () => void;
|
|
12
6
|
userContext?: UserContext;
|
|
13
7
|
}
|
|
14
|
-
export declare function IntakeCtaCards({
|
|
8
|
+
export declare function IntakeCtaCards({ onProspect, onFullAnalysis, userContext, }: IntakeCtaCardsProps): React.JSX.Element;
|
|
15
9
|
export {};
|
|
@@ -1,84 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
4
|
};
|
|
25
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.isProspectReady = isProspectReady;
|
|
27
6
|
exports.IntakeCtaCards = IntakeCtaCards;
|
|
28
|
-
const react_1 =
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
29
8
|
const TaxAxisButton_1 = require("../shared/TaxAxisButton");
|
|
30
9
|
const TaxAxisBadge_1 = require("../shared/TaxAxisBadge");
|
|
31
|
-
function
|
|
32
|
-
const missing = [];
|
|
33
|
-
if (!profile.entity)
|
|
34
|
-
missing.push("Entity Type");
|
|
35
|
-
if (!profile.states || profile.states.length === 0)
|
|
36
|
-
missing.push("States of Operation");
|
|
37
|
-
if (!profile.federalRate)
|
|
38
|
-
missing.push("Federal Marginal Rate");
|
|
39
|
-
if (!profile.stateRate)
|
|
40
|
-
missing.push("State Marginal Rate");
|
|
41
|
-
if (!profile.taxDataYears)
|
|
42
|
-
missing.push("Tax Data Years Available");
|
|
43
|
-
if (!profile.riskTolerance)
|
|
44
|
-
missing.push("Client Risk Tolerance");
|
|
45
|
-
const hasFinancial = parseFloat(profile.netIncome || "0") > 0 ||
|
|
46
|
-
parseFloat(profile.equipmentPurchased || "0") > 0 ||
|
|
47
|
-
parseFloat(profile.capitalGains || "0") > 0 ||
|
|
48
|
-
parseFloat(profile.revenue || "0") > 0;
|
|
49
|
-
if (!hasFinancial)
|
|
50
|
-
missing.push("Annual Revenue or Net Income (at least one > 0)");
|
|
51
|
-
return { ready: missing.length === 0, missingFields: missing };
|
|
52
|
-
}
|
|
53
|
-
function IntakeCtaCards({ profile, onProspect, onFullAnalysis, userContext = "expert", }) {
|
|
54
|
-
const [showTooltip, setShowTooltip] = (0, react_1.useState)(false);
|
|
55
|
-
const { ready, missingFields } = isProspectReady(profile);
|
|
10
|
+
function IntakeCtaCards({ onProspect, onFullAnalysis, userContext = "expert", }) {
|
|
56
11
|
return (react_1.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" },
|
|
57
12
|
react_1.default.createElement("div", { className: "bg-tax-axis-surface border border-tax-axis-border rounded-xl p-4 min-h-[140px] flex flex-col transition-all" },
|
|
58
13
|
react_1.default.createElement("div", { className: "text-[11px] font-bold text-tax-axis-orange uppercase tracking-widest mb-2.5 font-tax-axis-body" }, "Prospect Report"),
|
|
59
14
|
react_1.default.createElement("div", { className: "text-xs text-tax-axis-text-3 font-tax-axis-body mb-3" }, "Top 3 strategies \u00B7 Savings ranges \u00B7 ~2 min \u00B7 No docs"),
|
|
60
15
|
react_1.default.createElement("div", { className: "flex-1" }),
|
|
61
|
-
react_1.default.createElement(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
: "Generate Prospect Report"),
|
|
65
|
-
!ready && showTooltip && (react_1.default.createElement("div", { style: {
|
|
66
|
-
position: "absolute",
|
|
67
|
-
bottom: "calc(100% + 8px)",
|
|
68
|
-
left: 0,
|
|
69
|
-
right: 0,
|
|
70
|
-
background: "#1a1f3d",
|
|
71
|
-
border: "1px solid #2a2f5d",
|
|
72
|
-
borderRadius: 8,
|
|
73
|
-
padding: "10px 12px",
|
|
74
|
-
zIndex: 50,
|
|
75
|
-
boxShadow: "0 4px 24px rgba(0,0,0,0.5)",
|
|
76
|
-
} },
|
|
77
|
-
react_1.default.createElement("div", { style: { fontSize: 10, fontWeight: 700, color: "#f97316", marginBottom: 6, textTransform: "uppercase", letterSpacing: "0.1em" } }, "Required to generate:"),
|
|
78
|
-
missingFields.map((f) => (react_1.default.createElement("div", { key: f, style: { fontSize: 11, color: "#94a3b8", marginBottom: 2, display: "flex", alignItems: "center", gap: 6 } },
|
|
79
|
-
react_1.default.createElement("span", { style: { color: "#f97316", fontSize: 9 } }, "\u25CF"),
|
|
80
|
-
" ",
|
|
81
|
-
f))))))),
|
|
16
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { variant: "orange", onClick: onProspect, className: "w-full text-xs" }, userContext === "cpa-firm-client"
|
|
17
|
+
? "Generate My Savings Report"
|
|
18
|
+
: "Generate Prospect Report")),
|
|
82
19
|
react_1.default.createElement("div", { className: "bg-tax-axis-surface border border-tax-axis-teal rounded-xl p-4 min-h-[140px] flex flex-col transition-all", style: {
|
|
83
20
|
background: "radial-gradient(ellipse at 50% 0%,rgba(36,131,132,0.06) 0%,transparent 70%) #0F1330",
|
|
84
21
|
boxShadow: "0 0 30px rgba(36,131,132,0.15)",
|
|
@@ -32,7 +32,7 @@ function TaxAxisIntake({ userContext = "expert", onProspect, onFullAnalysis, ini
|
|
|
32
32
|
react_1.default.createElement(ClientParametersSection_1.ClientParametersSection, { userContext: userContext }),
|
|
33
33
|
react_1.default.createElement(RefineAnalysisSection_1.RefineAnalysisSection, { userContext: userContext }),
|
|
34
34
|
react_1.default.createElement(CpaIntakeQuestionsSection_1.CpaIntakeQuestionsSection, { userContext: userContext }),
|
|
35
|
-
react_1.default.createElement(IntakeCtaCards_1.IntakeCtaCards, {
|
|
35
|
+
react_1.default.createElement(IntakeCtaCards_1.IntakeCtaCards, { onProspect: handleProspect, onFullAnalysis: handleFull, userContext: userContext })),
|
|
36
36
|
react_1.default.createElement("div", { className: "hidden sm:block sm:sticky sm:top-5 sm:self-start" },
|
|
37
37
|
react_1.default.createElement(StrategyRadar_1.StrategyRadar, { profile: profile })))));
|
|
38
38
|
}
|
|
@@ -18,14 +18,18 @@ function EngagementHeader({ profile, palette }) {
|
|
|
18
18
|
marginBottom: 16,
|
|
19
19
|
boxShadow: "0 1px 3px rgba(0,0,0,0.04)",
|
|
20
20
|
};
|
|
21
|
+
// C-Corps have a flat 21% federal rate and no filing status
|
|
22
|
+
const isCCorp = profile.entity === "C-Corporation";
|
|
23
|
+
const fedRateDisplay = isCCorp ? "21%" : (profile.federalRate || "24%");
|
|
24
|
+
const filingDisplay = isCCorp ? "\u2014" : (profile.filingStatus || "MFJ");
|
|
21
25
|
const rows = [
|
|
22
26
|
["Entity", profile.entity],
|
|
23
27
|
["Industry", profile.industry],
|
|
24
28
|
["States", states.join(", ") || "\u2014"],
|
|
25
29
|
["Tax Year", profile.year],
|
|
26
|
-
["Filing",
|
|
30
|
+
["Filing", filingDisplay],
|
|
27
31
|
["SSTB", profile.sstb || "No"],
|
|
28
|
-
["Fed Rate",
|
|
32
|
+
["Fed Rate", fedRateDisplay],
|
|
29
33
|
["State Rate", (profile.stateRate || "4.95") + "%"],
|
|
30
34
|
["Revenue", "$" + (rev || 0).toLocaleString()],
|
|
31
35
|
["Net Income", "$" + (0, compute_1.parseNum)(profile.netIncome).toLocaleString()],
|
|
@@ -50,9 +50,9 @@ function TaxAxisPreparerWorkpaper({ profile, onBack, onToggleToClient, liveStrat
|
|
|
50
50
|
const grouped = priorityOrder
|
|
51
51
|
.map(p => ({ priority: p, items: eligible.filter(s => s.priority === p).sort((a, b) => b.score - a.score) }))
|
|
52
52
|
.filter(g => g.items.length > 0);
|
|
53
|
-
// Interaction pairs
|
|
54
|
-
const
|
|
55
|
-
const activeInteractions = data_1.WORKPAPER_INTERACTION_PAIRS.filter(([a, b]) =>
|
|
53
|
+
// Interaction pairs — match on original catalog strategy number, not re-indexed rank
|
|
54
|
+
const eligibleStrategyNumbers = new Set(eligible.map(s => { var _a; return (_a = s.strategyNumber) !== null && _a !== void 0 ? _a : s.rank; }));
|
|
55
|
+
const activeInteractions = data_1.WORKPAPER_INTERACTION_PAIRS.filter(([a, b]) => eligibleStrategyNumbers.has(a) && eligibleStrategyNumbers.has(b));
|
|
56
56
|
// Savings summary
|
|
57
57
|
const sortedByMid = [...eligible].sort((a, b) => {
|
|
58
58
|
var _a, _b, _c, _d;
|
|
@@ -5,9 +5,5 @@ export interface TaxAxisProcessingProps extends TaxAxisScreenProps {
|
|
|
5
5
|
profile?: ClientProfile;
|
|
6
6
|
/** Set to true by the shell poller when stage===REPORT_READY is detected. */
|
|
7
7
|
reportReady?: boolean;
|
|
8
|
-
/** Override crawl speed. Default: 0.27%/tick (full analysis ~110s). Prospect report: use ~6 for ~15s. */
|
|
9
|
-
crawlStep?: number;
|
|
10
|
-
/** 'prospect' shows lightweight stages without document parsing steps */
|
|
11
|
-
mode?: 'full' | 'prospect';
|
|
12
8
|
}
|
|
13
|
-
export declare function TaxAxisProcessing({ onComplete, profile, reportReady,
|
|
9
|
+
export declare function TaxAxisProcessing({ onComplete, profile, reportReady, userContext: _userContext, }: TaxAxisProcessingProps): React.JSX.Element;
|