@paro.io/expert-shared-components 1.14.57 → 1.14.59
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 +1 -0
- package/lib/components/TaxAxis/TaxAxisShell.d.ts +1 -1
- package/lib/components/TaxAxis/TaxAxisShell.js +52 -2
- package/lib/components/TaxAxis/types.d.ts +5 -0
- package/lib/tax-axis/components/dashboard/DashboardActions.js +4 -4
- package/lib/tax-axis/components/dashboard/DashboardSummary.js +5 -6
- package/lib/tax-axis/components/dashboard/StrategyDetailPanel.js +2 -4
- package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +57 -49
- package/lib/tax-axis/components/documents/DocumentCard.d.ts +1 -0
- package/lib/tax-axis/components/documents/DocumentCard.js +19 -3
- package/lib/tax-axis/components/documents/TaxAxisDocuments.d.ts +12 -1
- package/lib/tax-axis/components/documents/TaxAxisDocuments.js +110 -48
- 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 +1 -1
- package/lib/tax-axis/components/intake/CpaIntakeQuestionsSection.js +3 -3
- package/lib/tax-axis/components/intake/IntakeCtaCards.js +1 -1
- package/lib/tax-axis/components/intake/RefineAnalysisSection.js +7 -7
- package/lib/tax-axis/components/intake/TaxAxisIntake.js +2 -2
- package/package.json +1 -1
|
@@ -54,4 +54,5 @@ export type TaxAxisApi = {
|
|
|
54
54
|
updateReport: (reportId: string, reviewedReport: Record<string, unknown>) => Promise<any>;
|
|
55
55
|
generatePdf: (sessionId: string) => Promise<any>;
|
|
56
56
|
getArtifacts: (sessionId: string) => Promise<any[]>;
|
|
57
|
+
importQboReport?: (sessionId: string, expertId: string, year: number, reportType: string) => Promise<any>;
|
|
57
58
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { TaxAxisShellProps } from './types';
|
|
2
|
-
export declare const TaxAxisShell: ({ taxAxisApi, userContext, initialSessionId, initialProfile, onSessionChange, documentUploadUrl, uploadBucketName, sessionDefaults, }: TaxAxisShellProps) => JSX.Element;
|
|
2
|
+
export declare const TaxAxisShell: ({ taxAxisApi, userContext, initialSessionId, initialProfile, onSessionChange, documentUploadUrl, uploadBucketName, sessionDefaults, qboAuthorizeUrl, expertId, qboConnected, qboCompanyName, }: TaxAxisShellProps) => JSX.Element;
|
|
3
3
|
export default TaxAxisShell;
|
|
@@ -135,7 +135,7 @@ function ShellContainer({ children, fullWidth = false, }) {
|
|
|
135
135
|
return (react_1.default.createElement("div", { className: 'min-h-screen bg-tax-axis-navy text-white font-tax-axis-body' },
|
|
136
136
|
react_1.default.createElement("div", { className: 'max-w-[960px] mx-auto px-5 py-7' }, children)));
|
|
137
137
|
}
|
|
138
|
-
const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, initialProfile, onSessionChange, documentUploadUrl, uploadBucketName, sessionDefaults, }) => {
|
|
138
|
+
const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, initialProfile, onSessionChange, documentUploadUrl, uploadBucketName, sessionDefaults, qboAuthorizeUrl, expertId, qboConnected, qboCompanyName, }) => {
|
|
139
139
|
const [step, setStep] = (0, react_1.useState)('SESSION_SETUP');
|
|
140
140
|
const [profile, setProfile] = (0, react_1.useState)(initialProfile ? Object.assign({}, initialProfile) : null);
|
|
141
141
|
const [sessionId, setSessionId] = (0, react_1.useState)(initialSessionId || null);
|
|
@@ -147,6 +147,12 @@ 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
|
+
// QBO state driven by EPS props — not localStorage
|
|
151
|
+
const [qboConnectedState, setQboConnectedState] = (0, react_1.useState)(!!qboConnected);
|
|
152
|
+
const [qboCompanyNameState, setQboCompanyNameState] = (0, react_1.useState)(qboCompanyName !== null && qboCompanyName !== void 0 ? qboCompanyName : null);
|
|
153
|
+
// Sync if parent re-fetches EPS data
|
|
154
|
+
react_1.default.useEffect(() => { setQboConnectedState(!!qboConnected); }, [qboConnected]);
|
|
155
|
+
react_1.default.useEffect(() => { setQboCompanyNameState(qboCompanyName !== null && qboCompanyName !== void 0 ? qboCompanyName : null); }, [qboCompanyName]);
|
|
150
156
|
// Derive live strategies from engineOutput so CLIENT_REPORT and PREPARER_WORKPAPER
|
|
151
157
|
// render real engine data instead of the static STRATEGIES catalog.
|
|
152
158
|
const engineOutput = (0, react_1.useMemo)(() => { var _a; return (_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.engineOutput) !== null && _a !== void 0 ? _a : null; }, [llmResult]);
|
|
@@ -300,6 +306,17 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
300
306
|
const handleDeleteDocument = (0, react_1.useCallback)((documentId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
301
307
|
yield taxAxisApi.deleteDocument(documentId);
|
|
302
308
|
}), [taxAxisApi]);
|
|
309
|
+
const handleImportQboReport = (0, react_1.useCallback)((sid, _realmId, reportType, _accountingMethod, year) => __awaiter(void 0, void 0, void 0, function* () {
|
|
310
|
+
var _a;
|
|
311
|
+
if (!taxAxisApi.importQboReport) {
|
|
312
|
+
throw new Error('QBO import is not available.');
|
|
313
|
+
}
|
|
314
|
+
if (!expertId) {
|
|
315
|
+
throw new Error('Expert ID is required for QBO import.');
|
|
316
|
+
}
|
|
317
|
+
const taxYear = (_a = year !== null && year !== void 0 ? year : Number(profile === null || profile === void 0 ? void 0 : profile.year)) !== null && _a !== void 0 ? _a : new Date().getFullYear();
|
|
318
|
+
return taxAxisApi.importQboReport(sid, expertId, taxYear, reportType);
|
|
319
|
+
}), [taxAxisApi, expertId, profile]);
|
|
303
320
|
const pollForResult = (0, react_1.useCallback)((sid) => __awaiter(void 0, void 0, void 0, function* () {
|
|
304
321
|
const POLL_INTERVAL_MS = 4000;
|
|
305
322
|
const MAX_ATTEMPTS = 4500; // 300 minutes max
|
|
@@ -409,6 +426,28 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
409
426
|
react_1.default.createElement(TaxAxisProspectReport_1.TaxAxisProspectReport, { profile: profile, userContext: userContext, onUpgrade: () => setStep('DOCUMENT_UPLOAD'), onPresent: () => setStep('PRESENTATION'), onReset: handleReset })));
|
|
410
427
|
case 'DOCUMENT_UPLOAD':
|
|
411
428
|
return (react_1.default.createElement(ShellContainer, null,
|
|
429
|
+
react_1.default.createElement("div", { className: "flex items-center justify-between rounded-lg px-4 py-3 mb-5", style: {
|
|
430
|
+
background: '#1A1F3A',
|
|
431
|
+
border: '1px solid #2E3160',
|
|
432
|
+
} },
|
|
433
|
+
react_1.default.createElement("div", { className: "flex items-center gap-3 min-w-0" },
|
|
434
|
+
react_1.default.createElement("span", { className: "text-[14px] font-semibold text-white font-tax-axis-body truncate max-w-[160px] sm:max-w-none" }, profile.bizName || 'Untitled Client'),
|
|
435
|
+
profile.entity && (react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono flex-shrink-0", style: {
|
|
436
|
+
padding: '2px 8px',
|
|
437
|
+
borderRadius: 4,
|
|
438
|
+
background: 'rgba(36,131,132,0.10)',
|
|
439
|
+
border: '1px solid rgba(36,131,132,0.25)',
|
|
440
|
+
color: '#A1E5E6',
|
|
441
|
+
letterSpacing: '0.03em',
|
|
442
|
+
} }, profile.entity)),
|
|
443
|
+
profile.year && (react_1.default.createElement("span", { className: "hidden sm:inline text-[12px] text-tax-axis-text-3 font-tax-axis-body flex-shrink-0" },
|
|
444
|
+
"TY ",
|
|
445
|
+
profile.year))),
|
|
446
|
+
react_1.default.createElement("button", { onClick: () => isProspectFlow ? setStep('PROSPECT_REPORT') : setStep('SESSION_SETUP'), className: "text-[11px] font-semibold font-tax-axis-mono cursor-pointer flex-shrink-0 rounded-md px-3 py-1", style: {
|
|
447
|
+
background: 'rgba(99,102,241,0.12)',
|
|
448
|
+
border: '1px solid rgba(99,102,241,0.30)',
|
|
449
|
+
color: '#a5b4fc',
|
|
450
|
+
} }, "Edit")),
|
|
412
451
|
react_1.default.createElement(TaxAxisDocuments_1.TaxAxisDocuments, { key: sessionId || 'new', profile: profile, entityType: entityTypeKey(profile.entity), userContext: userContext, onUploadDocument: handleUploadDocument, onDeleteDocument: handleDeleteDocument, fetchUploadedDocuments: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
413
452
|
const ensuredSessionId = sessionId || (profile ? yield createSessionIfNeeded(profile) : null);
|
|
414
453
|
if (!ensuredSessionId) {
|
|
@@ -430,7 +469,13 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
430
469
|
});
|
|
431
470
|
}), jobId: sessionId || undefined, onSaveReviewedField: (documentId, reviewedData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
432
471
|
yield taxAxisApi.saveReviewedData(documentId, reviewedData);
|
|
433
|
-
}), onContinue: handleAnalyzeDocuments, onBack: () => isProspectFlow ? setStep('PROSPECT_REPORT') : setStep('SESSION_SETUP')
|
|
472
|
+
}), onContinue: handleAnalyzeDocuments, onBack: () => isProspectFlow ? setStep('PROSPECT_REPORT') : setStep('SESSION_SETUP'), qboConnected: qboConnectedState, qboCompanyName: qboCompanyNameState, qboAuthorizeUrl: qboAuthorizeUrl, qboClientConfirmed: qboConnectedState, onImportQboReport: taxAxisApi.importQboReport ? handleImportQboReport : undefined, onQboConnected: (companyName) => {
|
|
473
|
+
setQboConnectedState(true);
|
|
474
|
+
setQboCompanyNameState(companyName);
|
|
475
|
+
}, onQboDisconnected: () => {
|
|
476
|
+
setQboConnectedState(false);
|
|
477
|
+
setQboCompanyNameState(null);
|
|
478
|
+
} })));
|
|
434
479
|
case 'PROCESSING':
|
|
435
480
|
return (react_1.default.createElement(ShellContainer, null,
|
|
436
481
|
react_1.default.createElement(TaxAxisProcessing_1.TaxAxisProcessing, { profile: profile, userContext: userContext, reportReady: reportReady, onComplete: () => setStep('DASHBOARD') })));
|
|
@@ -469,6 +514,11 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
469
514
|
adapted,
|
|
470
515
|
reportReady,
|
|
471
516
|
parsedDocuments,
|
|
517
|
+
qboConnectedState,
|
|
518
|
+
qboCompanyNameState,
|
|
519
|
+
qboAuthorizeUrl,
|
|
520
|
+
expertId,
|
|
521
|
+
handleImportQboReport,
|
|
472
522
|
]);
|
|
473
523
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
474
524
|
error && (react_1.default.createElement("div", { className: 'fixed right-4 top-4 z-[200] max-w-sm rounded-lg border border-red-500/30 bg-tax-axis-surface px-4 py-3 text-xs text-red-200 shadow-lg' },
|
|
@@ -70,10 +70,10 @@ function DashboardActions({ profile, dashEligible, computed, onDownloadPreparer,
|
|
|
70
70
|
"across ",
|
|
71
71
|
dashEligible.length,
|
|
72
72
|
" strategies \u2014 use this to close the engagement or expand scope."),
|
|
73
|
-
react_1.default.createElement("div", { className: "flex gap-2.5 flex-wrap" },
|
|
74
|
-
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { variant: "orange", onClick: onSend }, "Send Report to Client"),
|
|
75
|
-
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onPresent }, "Present to Client"),
|
|
76
|
-
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { variant: "secondary" }, "Generate Engagement Letter")))),
|
|
73
|
+
react_1.default.createElement("div", { className: "flex flex-col sm:flex-row gap-2.5 flex-wrap" },
|
|
74
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { variant: "orange", onClick: onSend, className: "w-full sm:w-auto" }, "Send Report to Client"),
|
|
75
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onPresent, className: "w-full sm:w-auto" }, "Present to Client"),
|
|
76
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { variant: "secondary", className: "w-full sm:w-auto" }, "Generate Engagement Letter")))),
|
|
77
77
|
react_1.default.createElement("div", { className: "flex gap-4 mt-4 pt-3.5", style: { borderTop: "1px solid rgba(36,131,132,0.15)" } }, [
|
|
78
78
|
{ v: "3x", l: "Faster than Manual" },
|
|
79
79
|
{ v: String(dashEligible.length), l: "Strategies Found" },
|
|
@@ -23,10 +23,9 @@ function DashboardSummary({ profile, dashEligible, computed, dataConfirmed, revi
|
|
|
23
23
|
const fmtHero = (k) => k >= 1000 ? "$" + (k / 1000).toFixed(1) + "M" : "$" + k + "K";
|
|
24
24
|
const riskVal = parseInt(profile.riskTolerance) || 3;
|
|
25
25
|
const riskLabels = ["", "Very Conservative", "Conservative", "Moderate", "Aggressive", "Very Aggressive"];
|
|
26
|
-
return (react_1.default.createElement("div", { className: "relative overflow-hidden rounded-2xl mb-5", style: {
|
|
26
|
+
return (react_1.default.createElement("div", { className: "relative overflow-hidden rounded-2xl mb-5 p-4 sm:p-8", style: {
|
|
27
27
|
background: "radial-gradient(ellipse at 30% 0%, rgba(36,131,132,0.08) 0%, transparent 60%), #0E1132",
|
|
28
28
|
border: "1px solid rgba(36,131,132,0.12)",
|
|
29
|
-
padding: "32px 32px 28px",
|
|
30
29
|
boxShadow: "0 4px 20px rgba(6,8,33,0.3)",
|
|
31
30
|
} },
|
|
32
31
|
react_1.default.createElement("div", { className: "absolute inset-0 opacity-[0.02]", style: {
|
|
@@ -79,13 +78,13 @@ function DashboardSummary({ profile, dashEligible, computed, dataConfirmed, revi
|
|
|
79
78
|
profile.cpaName && (react_1.default.createElement("div", { className: "text-xs text-tax-axis-text-3 mt-1" },
|
|
80
79
|
"Preparer: ",
|
|
81
80
|
profile.cpaName)),
|
|
82
|
-
react_1.default.createElement("div", { className: "flex gap-6 mt-[22px] pt-[18px]", style: { borderTop: "1px solid rgba(36,131,132,0.12)" } }, [
|
|
83
|
-
{ v:
|
|
81
|
+
react_1.default.createElement("div", { className: "grid grid-cols-2 gap-4 sm:flex sm:gap-6 mt-[22px] pt-[18px]", style: { borderTop: "1px solid rgba(36,131,132,0.12)" } }, [
|
|
82
|
+
{ v: confidenceTier ? confidenceTier.replace(/-DATA$/, "").replace(/-/g, " ") : "—", u: "", l: "Confidence Tier", warn: false, ok: !!confidenceTier },
|
|
84
83
|
{ v: String(strategyCount), u: "", l: "Strategies Identified", warn: false, ok: false },
|
|
85
84
|
{
|
|
86
|
-
v: dataConfirmed ? "
|
|
85
|
+
v: dataConfirmed ? "Verified" : String(reviewUnreviewed),
|
|
87
86
|
u: "",
|
|
88
|
-
l:
|
|
87
|
+
l: "Data Quality",
|
|
89
88
|
warn: !dataConfirmed && reviewUnreviewed > 0,
|
|
90
89
|
ok: dataConfirmed,
|
|
91
90
|
},
|
|
@@ -103,13 +103,11 @@ function StrategyDetailPanel({ s, profile: _profile, computed, onClose }) {
|
|
|
103
103
|
const { savingsSection, cpaSection } = splitEngagementText(s.abstract || "");
|
|
104
104
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
105
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)" } }),
|
|
106
|
-
react_1.default.createElement("div", { className: "fixed top-0 right-0 bottom-0 z-[201] flex flex-col", style: {
|
|
107
|
-
width: 520,
|
|
108
|
-
maxWidth: "calc(100vw - 24px)",
|
|
106
|
+
react_1.default.createElement("div", { className: "fixed bottom-0 left-0 right-0 md:top-0 md:left-auto md:right-0 md:bottom-0 z-[201] flex flex-col w-full md:w-[520px] max-h-[85vh] md:max-h-none overflow-y-auto border-t border-tax-axis-border md:border-t-0 md:border-l", style: {
|
|
109
107
|
background: "#0E1132",
|
|
110
|
-
borderLeft: "1px solid rgba(36,131,132,0.12)",
|
|
111
108
|
boxShadow: "-8px 0 40px rgba(6,8,33,0.6)",
|
|
112
109
|
} },
|
|
110
|
+
react_1.default.createElement("div", { className: "w-10 h-1 rounded-full bg-tax-axis-text-4 mx-auto my-2 md:hidden" }),
|
|
113
111
|
react_1.default.createElement("div", { className: "px-6 py-5 flex-shrink-0", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } },
|
|
114
112
|
react_1.default.createElement("div", { className: "flex justify-between items-start mb-3" },
|
|
115
113
|
react_1.default.createElement("div", null,
|
|
@@ -32,7 +32,6 @@ const useEngineOutput_1 = require("../../lib/adapters/useEngineOutput");
|
|
|
32
32
|
const TaxAxisButton_1 = require("../shared/TaxAxisButton");
|
|
33
33
|
const TaxAxisBadge_1 = require("../shared/TaxAxisBadge");
|
|
34
34
|
const DashboardSummary_1 = require("./DashboardSummary");
|
|
35
|
-
const DashboardTopBar_1 = require("./DashboardTopBar");
|
|
36
35
|
const DashboardActions_1 = require("./DashboardActions");
|
|
37
36
|
const StrategyTile_1 = require("./StrategyTile");
|
|
38
37
|
const StrategyDetailPanel_1 = require("./StrategyDetailPanel");
|
|
@@ -244,7 +243,7 @@ const BUCKETS = [
|
|
|
244
243
|
{ key: "90d", label: "Within 90 Days", desc: "Structural changes — new accounts or plan setup" },
|
|
245
244
|
];
|
|
246
245
|
function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClient, onDownloadPreparer, onPresent, onSend, onReset, onReviewData, onUploadMore, userContext: _userContext = "expert", }) {
|
|
247
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u
|
|
246
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
248
247
|
const hasLlm = !!((_a = llmResult === null || llmResult === void 0 ? void 0 : llmResult.strategies) === null || _a === void 0 ? void 0 : _a.length);
|
|
249
248
|
// All live fields from rawOutput — nothing hardcoded
|
|
250
249
|
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;
|
|
@@ -340,29 +339,25 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
340
339
|
return map;
|
|
341
340
|
}, [uncalculated]);
|
|
342
341
|
const [uncalcExpanded, setUncalcExpanded] = (0, react_1.useState)(false);
|
|
342
|
+
const [excludedExpanded, setExcludedExpanded] = (0, react_1.useState)(false);
|
|
343
|
+
const [riskExpanded, setRiskExpanded] = (0, react_1.useState)(false);
|
|
343
344
|
return (react_1.default.createElement("div", null,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
react_1.default.createElement("span", { className: "text-tax-axis-text-4" }, (() => {
|
|
359
|
-
var _a, _b;
|
|
360
|
-
const tokens = (_b = (_a = llmResult.meta.totalTokens) !== null && _a !== void 0 ? _a : llmResult.meta.tokenCount) !== null && _b !== void 0 ? _b : 0;
|
|
361
|
-
return tokens > 0 ? `${tokens} tokens` : "";
|
|
362
|
-
})()))),
|
|
345
|
+
react_1.default.createElement("style", null, `
|
|
346
|
+
@media print {
|
|
347
|
+
* { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
|
|
348
|
+
.MuiDrawer-root, .MuiDrawer-paper, .MuiDrawer-permanent,
|
|
349
|
+
.MuiAppBar-root { display: none !important; }
|
|
350
|
+
.tax-axis-no-print { display: none !important; }
|
|
351
|
+
body { background: white !important; }
|
|
352
|
+
.min-h-screen.bg-tax-axis-navy { background: white !important; }
|
|
353
|
+
.flex.flex-col.w-full { margin-top: 0 !important; margin-left: 0 !important; }
|
|
354
|
+
main.w-full { width: 100% !important; margin: 0 !important; padding: 0 !important; }
|
|
355
|
+
.rounded-\\[14px\\] { page-break-inside: avoid; break-inside: avoid; }
|
|
356
|
+
.rounded-2xl { page-break-inside: avoid; break-inside: avoid; }
|
|
357
|
+
}
|
|
358
|
+
`),
|
|
363
359
|
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 }),
|
|
364
|
-
react_1.default.createElement(
|
|
365
|
-
topTab === "extraction" && (react_1.default.createElement("div", null,
|
|
360
|
+
false && (react_1.default.createElement("div", null,
|
|
366
361
|
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" } },
|
|
367
362
|
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" },
|
|
368
363
|
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
|
|
@@ -415,8 +410,8 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
415
410
|
border: "1px solid rgba(15,110,86,0.25)",
|
|
416
411
|
color: "#0F6E56",
|
|
417
412
|
} }, "View Report"))))),
|
|
418
|
-
|
|
419
|
-
react_1.default.createElement("div", { className: "flex gap-0 mb-5", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } }, [["report", "Preparer Report"], ["client", "Client Summary"]].map(([id, lbl]) => (react_1.default.createElement("button", { key: id, onClick: () => setReportTab(id), className: "bg-transparent border-0 font-tax-axis-body mr-6", style: {
|
|
413
|
+
(react_1.default.createElement("div", null,
|
|
414
|
+
react_1.default.createElement("div", { className: "flex gap-0 mb-5 tax-axis-no-print", style: { borderBottom: "1px solid rgba(36,131,132,0.12)" } }, [["report", "Preparer Report"], ["client", "Client Summary"]].map(([id, lbl]) => (react_1.default.createElement("button", { key: id, onClick: () => setReportTab(id), className: "bg-transparent border-0 font-tax-axis-body mr-6", style: {
|
|
420
415
|
padding: "10px 0",
|
|
421
416
|
fontSize: 14,
|
|
422
417
|
fontWeight: reportTab === id ? 600 : 400,
|
|
@@ -466,20 +461,14 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
466
461
|
const clo = (_d = (_c = computed.get(s.rank)) === null || _c === void 0 ? void 0 : _c.lo) !== null && _d !== void 0 ? _d : s.lo;
|
|
467
462
|
const w = (chi / maxSavings) * 100;
|
|
468
463
|
return (react_1.default.createElement("div", { key: s.rank, className: "flex items-center gap-3 cursor-pointer", style: { marginBottom: chartExpanded ? 14 : 10 }, onClick: () => setSelected(s) },
|
|
469
|
-
react_1.default.createElement("span", { className:
|
|
470
|
-
fontSize: chartExpanded ? 13 : 12,
|
|
471
|
-
width: chartExpanded ? 180 : 140,
|
|
472
|
-
} }, s.name),
|
|
464
|
+
react_1.default.createElement("span", { className: `text-tax-axis-text font-tax-axis-body flex-shrink-0 overflow-hidden text-ellipsis whitespace-nowrap ${chartExpanded ? "w-[100px] sm:w-[180px] text-[13px]" : "w-[100px] sm:w-[140px] text-[12px]"}` }, s.name),
|
|
473
465
|
react_1.default.createElement("div", { className: "flex-1 bg-tax-axis-surface-2 rounded-sm overflow-hidden", style: { height: chartExpanded ? 10 : 6 } },
|
|
474
466
|
react_1.default.createElement("div", { className: "h-full rounded-sm", style: {
|
|
475
467
|
width: `${w}%`,
|
|
476
468
|
background: "linear-gradient(90deg, #248384, #A1E5E6)",
|
|
477
469
|
transition: "width 0.8s cubic-bezier(.16,1,.3,1)",
|
|
478
470
|
} })),
|
|
479
|
-
react_1.default.createElement("span", { className:
|
|
480
|
-
fontSize: chartExpanded ? 13 : 12,
|
|
481
|
-
width: chartExpanded ? 100 : 80,
|
|
482
|
-
} },
|
|
471
|
+
react_1.default.createElement("span", { className: `font-semibold text-tax-axis-teal-light font-tax-axis-mono flex-shrink-0 text-right ${chartExpanded ? "w-[60px] sm:w-[100px] text-[13px]" : "w-[60px] sm:w-[80px] text-[12px]"}` },
|
|
483
472
|
fmtK(clo),
|
|
484
473
|
"\u2013",
|
|
485
474
|
fmtK(chi))));
|
|
@@ -497,7 +486,7 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
497
486
|
dashEligible.length,
|
|
498
487
|
" Strategies"),
|
|
499
488
|
react_1.default.createElement("span", { className: "font-normal normal-case tracking-normal text-tax-axis-text-2 text-xs font-tax-axis-body" }, "Click to explore")),
|
|
500
|
-
react_1.default.createElement("div", { className: "grid grid-cols-2 gap-2.5 mb-4" },
|
|
489
|
+
react_1.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2.5 mb-4" },
|
|
501
490
|
calculable.map((s, i) => {
|
|
502
491
|
var _a, _b;
|
|
503
492
|
const c = computed.get(s.rank);
|
|
@@ -566,29 +555,46 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
566
555
|
react_1.default.createElement("div", { className: "flex items-center gap-2.5" },
|
|
567
556
|
react_1.default.createElement("span", { className: "text-[11px] font-tax-axis-mono text-tax-axis-text-2" }, a.savings),
|
|
568
557
|
react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: a.priority === "MEDIUM" ? "orange" : "neutral", size: "xs" }, a.priority))))))),
|
|
569
|
-
engagementRecs.length > 0 && (react_1.default.createElement("div", { className: "
|
|
570
|
-
react_1.default.createElement("div", { className: "
|
|
571
|
-
|
|
572
|
-
|
|
558
|
+
engagementRecs.length > 0 && (react_1.default.createElement("div", { className: "mb-4" },
|
|
559
|
+
react_1.default.createElement("div", { className: "text-[13px] font-bold text-white uppercase tracking-widest font-tax-axis-head mb-3" }, "CPA Engagement Notes"),
|
|
560
|
+
react_1.default.createElement("div", { className: "flex flex-col gap-3" }, engagementRecs.map((rec, i) => {
|
|
561
|
+
const colonIdx = rec.indexOf(":");
|
|
562
|
+
const hasLabel = colonIdx > 0 && colonIdx < 60;
|
|
563
|
+
const label = hasLabel ? rec.slice(0, colonIdx).trim() : null;
|
|
564
|
+
const body = hasLabel ? rec.slice(colonIdx + 1).trim() : rec;
|
|
565
|
+
return (react_1.default.createElement("div", { key: i, className: "rounded-[10px] p-4", style: {
|
|
566
|
+
background: "#0E1132",
|
|
567
|
+
border: "1px solid rgba(36,131,132,0.12)",
|
|
568
|
+
borderLeft: "3px solid rgba(36,131,132,0.4)",
|
|
569
|
+
} },
|
|
570
|
+
label && (react_1.default.createElement("div", { className: "text-xs font-semibold tracking-wide text-tax-axis-teal-light font-tax-axis-mono mb-1.5 uppercase" }, label)),
|
|
571
|
+
react_1.default.createElement("div", { className: "text-[12px] text-tax-axis-text leading-[1.7] font-tax-axis-body" }, body)));
|
|
572
|
+
})))),
|
|
573
573
|
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" } },
|
|
574
574
|
react_1.default.createElement("div", { className: "text-[11px] font-bold text-white uppercase tracking-widest font-tax-axis-mono mb-2" }, "State Nexus"),
|
|
575
575
|
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" } },
|
|
576
576
|
react_1.default.createElement("span", { className: "font-semibold text-tax-axis-teal-light mr-2" }, f.state),
|
|
577
577
|
f.flag_text))))),
|
|
578
|
-
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)"
|
|
579
|
-
react_1.default.createElement("div", { className: "
|
|
580
|
-
|
|
578
|
+
riskDisclosures.length > 0 && (react_1.default.createElement("div", { className: "rounded-[14px] mb-4 overflow-hidden", style: { background: "rgba(251,154,29,0.04)", border: "1px solid rgba(251,154,29,0.15)" } },
|
|
579
|
+
react_1.default.createElement("div", { className: "px-5 py-3.5 flex items-center justify-between cursor-pointer", onClick: () => setRiskExpanded(p => !p) },
|
|
580
|
+
react_1.default.createElement("span", { className: "text-[13px] text-tax-axis-text-2 font-tax-axis-body" }, "Risk disclosures & IRC \u00A76694 notices"),
|
|
581
|
+
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", style: { transform: riskExpanded ? "rotate(180deg)" : "none", transition: "transform .2s" } },
|
|
582
|
+
react_1.default.createElement("path", { d: "M3 4.5l3 3 3-3", stroke: "#9498B8", strokeWidth: "1.5", strokeLinecap: "round" }))),
|
|
583
|
+
riskExpanded && (react_1.default.createElement("div", { style: { borderTop: "1px solid rgba(251,154,29,0.12)", padding: "12px 20px" } }, 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))))))),
|
|
581
584
|
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)" } },
|
|
582
|
-
react_1.default.createElement("div", { className: "px-5 py-3.5",
|
|
583
|
-
react_1.default.createElement("span", { className: "text-[13px]
|
|
585
|
+
react_1.default.createElement("div", { className: "px-5 py-3.5 flex items-center justify-between cursor-pointer", onClick: () => setExcludedExpanded(p => !p) },
|
|
586
|
+
react_1.default.createElement("span", { className: "text-[13px] text-tax-axis-text-2 font-tax-axis-body" },
|
|
584
587
|
excludedStrategies.length,
|
|
585
|
-
"
|
|
586
|
-
|
|
588
|
+
" strategies screened \u2014 not applicable to this client"),
|
|
589
|
+
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", style: { transform: excludedExpanded ? "rotate(180deg)" : "none", transition: "transform .2s" } },
|
|
590
|
+
react_1.default.createElement("path", { d: "M3 4.5l3 3 3-3", stroke: "#9498B8", strokeWidth: "1.5", strokeLinecap: "round" }))),
|
|
591
|
+
excludedExpanded && (react_1.default.createElement("div", { style: { borderTop: "1px solid rgba(148,152,184,0.1)" } }, 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" } },
|
|
587
592
|
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),
|
|
588
593
|
react_1.default.createElement("div", { className: "flex-1" },
|
|
589
594
|
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-2 font-tax-axis-body" }, ex.reason),
|
|
590
|
-
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)))))))),
|
|
591
|
-
react_1.default.createElement(
|
|
595
|
+
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)))))))))),
|
|
596
|
+
react_1.default.createElement("div", { className: "tax-axis-no-print" },
|
|
597
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadPreparer, className: "w-full" }, "Download Full Preparer Report")))) : (
|
|
592
598
|
/* ═══ CLIENT SUMMARY — Timeline View ═══ */
|
|
593
599
|
react_1.default.createElement("div", null,
|
|
594
600
|
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" },
|
|
@@ -654,8 +660,10 @@ function TaxAxisDashboard({ profile, llmResult, parsedDocuments, onDownloadClien
|
|
|
654
660
|
s.cost && s.cost !== "$0" && (react_1.default.createElement("span", { className: "text-[11px] font-semibold font-tax-axis-mono", style: { color: "#FB9A1D" } }, s.cost)))));
|
|
655
661
|
})));
|
|
656
662
|
}),
|
|
657
|
-
react_1.default.createElement(
|
|
663
|
+
react_1.default.createElement("div", { className: "tax-axis-no-print" },
|
|
664
|
+
react_1.default.createElement(TaxAxisButton_1.TaxAxisButton, { onClick: onDownloadClient, className: "w-full mt-1.5" }, "Download Client Summary")),
|
|
658
665
|
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)))),
|
|
659
|
-
react_1.default.createElement(
|
|
666
|
+
react_1.default.createElement("div", { className: "tax-axis-no-print" },
|
|
667
|
+
react_1.default.createElement(DashboardActions_1.DashboardActions, { profile: profile, dashEligible: dashEligible, computed: computed, onDownloadPreparer: onDownloadPreparer, onPresent: onPresent, onSend: onSend, onReset: onReset })))),
|
|
660
668
|
enrichedSelected && (react_1.default.createElement(StrategyDetailPanel_1.StrategyDetailPanel, { s: enrichedSelected, profile: profile, computed: computed, onClose: () => setSelected(null) }))));
|
|
661
669
|
}
|
|
@@ -45,7 +45,7 @@ function DocumentCard({ doc, tierBorderColor, tierBadgeColor, tierBadgeText, hel
|
|
|
45
45
|
borderRadius: "0 10px 10px 0",
|
|
46
46
|
boxShadow: "0 2px 12px rgba(6,8,33,0.5)",
|
|
47
47
|
} },
|
|
48
|
-
react_1.default.createElement("div", { className: "px-4 py-3 flex gap-3 items-center" },
|
|
48
|
+
react_1.default.createElement("div", { className: "px-4 py-3 flex flex-col sm:flex-row gap-3 items-start sm:items-center" },
|
|
49
49
|
react_1.default.createElement("div", { className: "w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0", style: {
|
|
50
50
|
background: ss.iconBg,
|
|
51
51
|
border: `1px solid ${ss.iconBorder}`,
|
|
@@ -63,13 +63,29 @@ function DocumentCard({ doc, tierBorderColor, tierBadgeColor, tierBadgeText, hel
|
|
|
63
63
|
react_1.default.createElement("div", { className: "flex items-center gap-1.5" },
|
|
64
64
|
react_1.default.createElement("span", { className: "text-[13px] font-medium text-white font-tax-axis-body" }, doc.name),
|
|
65
65
|
doc.status === "empty" && (react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: tierBadgeColor, size: "xs" }, tierBadgeText)),
|
|
66
|
-
doc.status === "failed" && (react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "red", size: "xs" }, "FAILED"))
|
|
66
|
+
doc.status === "failed" && (react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: "red", size: "xs" }, "FAILED")),
|
|
67
|
+
doc.status === "valid" && doc.qboSource && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
68
|
+
react_1.default.createElement("span", { style: {
|
|
69
|
+
fontSize: 9,
|
|
70
|
+
fontWeight: 700,
|
|
71
|
+
letterSpacing: "0.05em",
|
|
72
|
+
padding: "1px 6px",
|
|
73
|
+
borderRadius: 3,
|
|
74
|
+
background: "rgba(44,160,28,0.1)",
|
|
75
|
+
border: "1px solid rgba(44,160,28,0.2)",
|
|
76
|
+
color: "#2CA01C",
|
|
77
|
+
} }, "QUICKBOOKS"),
|
|
78
|
+
react_1.default.createElement("span", { style: {
|
|
79
|
+
fontSize: 9,
|
|
80
|
+
fontWeight: 600,
|
|
81
|
+
color: "#2CA01C",
|
|
82
|
+
} }, "Synced")))),
|
|
67
83
|
react_1.default.createElement("div", { className: "text-[11px] text-tax-axis-text-3 font-tax-axis-body mt-0.5" }, doc.status === "valid" && doc.fileName
|
|
68
84
|
? `${doc.fileName}${fieldCount ? ` \u00b7 ${fieldCount} fields extracted` : ""}`
|
|
69
85
|
: doc.status === "failed" && doc.parseError
|
|
70
86
|
? doc.parseError
|
|
71
87
|
: ((_a = doc.fileName) !== null && _a !== void 0 ? _a : (helpOverride !== null && helpOverride !== void 0 ? helpOverride : doc.help)))),
|
|
72
|
-
react_1.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" },
|
|
88
|
+
react_1.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0 w-full sm:w-auto" },
|
|
73
89
|
doc.status === "valid" && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
74
90
|
react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none" },
|
|
75
91
|
react_1.default.createElement("path", { d: "M2.5 7l3.5 3.5 5.5-6", stroke: "#0F6E56", strokeWidth: "2", strokeLinecap: "round" })),
|
|
@@ -28,5 +28,16 @@ export interface TaxAxisDocumentsProps extends TaxAxisScreenProps {
|
|
|
28
28
|
parsedFieldCounts?: Record<string, number>;
|
|
29
29
|
jobId?: string;
|
|
30
30
|
onSaveReviewedField?: (documentId: string, reviewedData: Record<string, unknown>) => Promise<void>;
|
|
31
|
+
qboConnected?: boolean;
|
|
32
|
+
qboCompanyName?: string | null;
|
|
33
|
+
qboAuthorizeUrl?: string;
|
|
34
|
+
onImportQboReport?: (sessionId: string, realmId: string, reportType: string, accountingMethod: string) => Promise<any>;
|
|
35
|
+
onQboConnected?: (companyName: string) => void;
|
|
36
|
+
onQboDisconnected?: () => void;
|
|
37
|
+
onQboImport?: (mappedDocs: {
|
|
38
|
+
slot: string;
|
|
39
|
+
fileName: string;
|
|
40
|
+
}[]) => void;
|
|
41
|
+
qboClientConfirmed?: boolean;
|
|
31
42
|
}
|
|
32
|
-
export declare function TaxAxisDocuments({ profile, entityType, onContinue, onBack, onUploadDocument, onDeleteDocument, fetchUploadedDocuments, parsedFieldCounts, jobId, onSaveReviewedField, userContext: _userContext, }: TaxAxisDocumentsProps): React.JSX.Element;
|
|
43
|
+
export declare function TaxAxisDocuments({ profile, entityType, onContinue, onBack, onUploadDocument, onDeleteDocument, fetchUploadedDocuments, parsedFieldCounts, jobId, onSaveReviewedField, userContext: _userContext, qboConnected, qboCompanyName, qboAuthorizeUrl, onImportQboReport, onQboConnected, onQboDisconnected, onQboImport, qboClientConfirmed, }: TaxAxisDocumentsProps): React.JSX.Element;
|