@paro.io/expert-shared-components 1.14.65 → 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.
Files changed (81) hide show
  1. package/lib/components/DocumentCenter/MultiFileUploadSection.js +220 -121
  2. package/lib/components/TaxAxis/TaxAxisApi.d.ts +0 -1
  3. package/lib/components/TaxAxis/TaxAxisShell.js +5 -80
  4. package/lib/components/shared/UploadClient.d.ts +2 -1
  5. package/lib/components/shared/UploadClient.js +6 -2
  6. package/lib/index.d.ts +1 -13
  7. package/lib/index.js +1 -27
  8. package/lib/tax-axis/components/clientReport/ExecutiveSummary.d.ts +4 -1
  9. package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +10 -6
  10. package/lib/tax-axis/components/clientReport/Methodology.js +2 -2
  11. package/lib/tax-axis/components/clientReport/RecommendedStrategies.d.ts +6 -1
  12. package/lib/tax-axis/components/clientReport/RecommendedStrategies.js +26 -24
  13. package/lib/tax-axis/components/clientReport/StrategyCard.d.ts +1 -1
  14. package/lib/tax-axis/components/clientReport/StrategyCard.js +39 -23
  15. package/lib/tax-axis/components/clientReport/TaxAxisClientReport.d.ts +5 -2
  16. package/lib/tax-axis/components/clientReport/TaxAxisClientReport.js +9 -7
  17. package/lib/tax-axis/components/dashboard/DashboardActions.js +6 -5
  18. package/lib/tax-axis/components/dashboard/DashboardSummary.d.ts +6 -1
  19. package/lib/tax-axis/components/dashboard/DashboardSummary.js +19 -10
  20. package/lib/tax-axis/components/dashboard/StrategyDetailPanel.d.ts +1 -1
  21. package/lib/tax-axis/components/dashboard/StrategyDetailPanel.js +122 -95
  22. package/lib/tax-axis/components/dashboard/TaxAxisDashboard.d.ts +58 -4
  23. package/lib/tax-axis/components/dashboard/TaxAxisDashboard.js +375 -56
  24. package/lib/tax-axis/components/documents/DocumentCard.d.ts +6 -3
  25. package/lib/tax-axis/components/documents/DocumentCard.js +72 -15
  26. package/lib/tax-axis/components/documents/DocumentReviewModal.d.ts +3 -1
  27. package/lib/tax-axis/components/documents/DocumentReviewModal.js +113 -263
  28. package/lib/tax-axis/components/documents/DocumentTier.d.ts +5 -4
  29. package/lib/tax-axis/components/documents/DocumentTier.js +2 -2
  30. package/lib/tax-axis/components/documents/TaxAxisDocuments.d.ts +28 -8
  31. package/lib/tax-axis/components/documents/TaxAxisDocuments.js +340 -156
  32. package/lib/tax-axis/components/documents/qbo/QboAvailableReportsModal.d.ts +13 -0
  33. package/lib/tax-axis/components/documents/qbo/QboAvailableReportsModal.js +180 -0
  34. package/lib/tax-axis/components/documents/qbo/QboClientSelectorModal.d.ts +10 -0
  35. package/lib/tax-axis/components/documents/qbo/QboClientSelectorModal.js +155 -0
  36. package/lib/tax-axis/components/documents/qbo/QboConnectBanner.d.ts +9 -0
  37. package/lib/tax-axis/components/documents/qbo/QboConnectBanner.js +55 -0
  38. package/lib/tax-axis/components/documents/qbo/QboDocumentMappingModal.d.ts +10 -0
  39. package/lib/tax-axis/components/documents/qbo/QboDocumentMappingModal.js +202 -0
  40. package/lib/tax-axis/components/documents/qbo/QboImportingModal.d.ts +8 -0
  41. package/lib/tax-axis/components/documents/qbo/QboImportingModal.js +75 -0
  42. package/lib/tax-axis/components/documents/qbo/QboPermissionsModal.d.ts +8 -0
  43. package/lib/tax-axis/components/documents/qbo/QboPermissionsModal.js +126 -0
  44. package/lib/tax-axis/components/documents/qbo/index.d.ts +8 -0
  45. package/lib/tax-axis/components/documents/qbo/index.js +17 -0
  46. package/lib/tax-axis/components/documents/qbo/qboConstants.d.ts +24 -0
  47. package/lib/tax-axis/components/documents/qbo/qboConstants.js +71 -0
  48. package/lib/tax-axis/components/documents/qbo/types.d.ts +43 -0
  49. package/lib/tax-axis/components/documents/qbo/types.js +3 -0
  50. package/lib/tax-axis/components/documents/qbo/useQboFlow.d.ts +19 -0
  51. package/lib/tax-axis/components/documents/qbo/useQboFlow.js +207 -0
  52. package/lib/tax-axis/components/intake/ClientParametersSection.js +14 -30
  53. package/lib/tax-axis/components/intake/CpaIntakeQuestionsSection.js +3 -3
  54. package/lib/tax-axis/components/intake/IntakeCtaCards.d.ts +1 -2
  55. package/lib/tax-axis/components/intake/IntakeCtaCards.js +6 -13
  56. package/lib/tax-axis/components/intake/RefineAnalysisSection.js +7 -7
  57. package/lib/tax-axis/components/intake/TaxAxisIntake.js +7 -95
  58. package/lib/tax-axis/components/intake/intakeSchema.d.ts +0 -3
  59. package/lib/tax-axis/components/intake/intakeSchema.js +2 -4
  60. package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.d.ts +23 -4
  61. package/lib/tax-axis/components/preparerWorkpaper/TaxAxisPreparerWorkpaper.js +15 -4
  62. package/lib/tax-axis/components/processing/TaxAxisProcessing.d.ts +2 -1
  63. package/lib/tax-axis/components/processing/TaxAxisProcessing.js +102 -31
  64. package/lib/tax-axis/components/prospectReport/ProspectPrintView.js +0 -2
  65. package/lib/tax-axis/components/prospectReport/ProspectStrategyCard.d.ts +1 -8
  66. package/lib/tax-axis/components/prospectReport/ProspectStrategyCard.js +5 -5
  67. package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.d.ts +1 -27
  68. package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.js +25 -43
  69. package/lib/tax-axis/index.d.ts +3 -1
  70. package/lib/tax-axis/index.js +4 -3
  71. package/lib/tax-axis/lib/adapters/useEngineOutput.d.ts +138 -13
  72. package/lib/tax-axis/lib/adapters/useEngineOutput.js +156 -7
  73. package/lib/tax-axis/lib/data/documents.d.ts +3 -2
  74. package/lib/tax-axis/lib/data/documents.js +225 -25
  75. package/lib/tax-axis/lib/data/strategies.js +9 -9
  76. package/lib/tax-axis/lib/documentFieldCatalog.d.ts +7 -12
  77. package/lib/tax-axis/lib/documentFieldCatalog.js +805 -8
  78. package/lib/tax-axis/lib/types/index.d.ts +13 -1
  79. package/package.json +1 -1
  80. package/lib/README.md +0 -2
  81. package/lib/package.json +0 -68
@@ -6,8 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DocumentCard = DocumentCard;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const TaxAxisBadge_1 = require("../shared/TaxAxisBadge");
9
- // Inline style values per status — mock T hex values for SVG strokes and
10
- // rgba borders that don't have direct Tailwind token equivalents.
11
9
  const STATUS_STYLES = {
12
10
  empty: {
13
11
  iconBg: "#171B44",
@@ -19,44 +17,79 @@ const STATUS_STYLES = {
19
17
  iconBorder: "rgba(251,154,29,0.25)",
20
18
  cardBorder: "rgba(251,154,29,0.25)",
21
19
  },
20
+ parsing: {
21
+ iconBg: "rgba(36,131,132,0.08)",
22
+ iconBorder: "rgba(36,131,132,0.25)",
23
+ cardBorder: "rgba(36,131,132,0.25)",
24
+ },
25
+ failed: {
26
+ iconBg: "rgba(197,48,48,0.08)",
27
+ iconBorder: "rgba(197,48,48,0.25)",
28
+ cardBorder: "rgba(197,48,48,0.25)",
29
+ },
22
30
  valid: {
23
31
  iconBg: "rgba(15,110,86,0.08)",
24
32
  iconBorder: "rgba(15,110,86,0.25)",
25
33
  cardBorder: "rgba(15,110,86,0.25)",
26
34
  },
27
35
  };
28
- function DocumentCard({ doc, tierBorderColor, tierBadgeColor, tierBadgeText, helpOverride, fieldCount, onUpload, onClear, onReview, }) {
29
- var _a;
36
+ function DocumentCard({ doc, tierBorderColor, tierBadgeColor, tierBadgeText, helpOverride, fieldCount, onUpload, onClear, onRemove, onReview, }) {
37
+ var _a, _b, _c;
30
38
  const ss = STATUS_STYLES[doc.status];
31
39
  const leftBorder = doc.status === "valid" ? "rgba(15,110,86,0.6)" : tierBorderColor;
40
+ const fileInputId = `tax-axis-upload-${doc.id}`;
41
+ const reuploadInputId = `tax-axis-reupload-${doc.id}`;
32
42
  return (react_1.default.createElement("div", { className: "bg-tax-axis-surface overflow-hidden", style: {
33
43
  border: `1px solid ${ss.cardBorder}`,
34
44
  borderLeft: `3px solid ${leftBorder}`,
35
45
  borderRadius: "0 10px 10px 0",
36
46
  boxShadow: "0 2px 12px rgba(6,8,33,0.5)",
37
47
  } },
38
- 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" },
39
49
  react_1.default.createElement("div", { className: "w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0", style: {
40
50
  background: ss.iconBg,
41
51
  border: `1px solid ${ss.iconBorder}`,
42
52
  } }, doc.status === "validating" ? (react_1.default.createElement("div", { className: "w-3.5 h-3.5 rounded-full animate-spin", style: {
43
53
  border: "2px solid transparent",
44
54
  borderTopColor: "#FB9A1D",
45
- } })) : doc.status === "valid" ? (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none" },
55
+ } })) : doc.status === "parsing" ? (react_1.default.createElement("div", { className: "w-3.5 h-3.5 rounded-full animate-spin", style: {
56
+ border: "2px solid transparent",
57
+ borderTopColor: "#248384",
58
+ } })) : doc.status === "failed" ? (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none" },
59
+ react_1.default.createElement("path", { d: "M4 4l6 6M10 4L4 10", stroke: "#C53030", strokeWidth: "2", strokeLinecap: "round" }))) : doc.status === "valid" ? (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none" },
46
60
  react_1.default.createElement("path", { d: "M2.5 7l3.5 3.5 5.5-6", stroke: "#0F6E56", strokeWidth: "2", strokeLinecap: "round" }))) : (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none" },
47
61
  react_1.default.createElement("circle", { cx: "7", cy: "7", r: "5", stroke: "#9498B8", strokeWidth: "1.5", strokeDasharray: "3 3" })))),
48
62
  react_1.default.createElement("div", { className: "flex-1 min-w-0" },
49
63
  react_1.default.createElement("div", { className: "flex items-center gap-1.5" },
50
64
  react_1.default.createElement("span", { className: "text-[13px] font-medium text-white font-tax-axis-body" }, doc.name),
51
- doc.status === "empty" && (react_1.default.createElement(TaxAxisBadge_1.TaxAxisBadge, { color: tierBadgeColor, size: "xs" }, tierBadgeText))),
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")),
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")))),
52
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
53
84
  ? `${doc.fileName}${fieldCount ? ` \u00b7 ${fieldCount} fields extracted` : ""}`
54
- : ((_a = doc.fileName) !== null && _a !== void 0 ? _a : (helpOverride !== null && helpOverride !== void 0 ? helpOverride : doc.help)))),
55
- react_1.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" },
85
+ : doc.status === "failed" && doc.parseError
86
+ ? doc.parseError
87
+ : ((_a = doc.fileName) !== null && _a !== void 0 ? _a : (helpOverride !== null && helpOverride !== void 0 ? helpOverride : doc.help)))),
88
+ react_1.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0 w-full sm:w-auto" },
56
89
  doc.status === "valid" && (react_1.default.createElement(react_1.default.Fragment, null,
57
90
  react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none" },
58
91
  react_1.default.createElement("path", { d: "M2.5 7l3.5 3.5 5.5-6", stroke: "#0F6E56", strokeWidth: "2", strokeLinecap: "round" })),
59
- react_1.default.createElement("button", { onClick: onReview, className: "rounded-md px-3 py-1 text-[11px] font-semibold font-tax-axis-mono cursor-pointer flex items-center gap-1.5", style: {
92
+ onReview && (react_1.default.createElement("button", { onClick: onReview, className: "rounded-md px-3 py-1 text-[11px] font-semibold font-tax-axis-mono cursor-pointer flex items-center gap-1.5", style: {
60
93
  background: "rgba(99,102,241,0.12)",
61
94
  border: "1px solid rgba(99,102,241,0.30)",
62
95
  color: "#a5b4fc",
@@ -64,10 +97,34 @@ function DocumentCard({ doc, tierBorderColor, tierBadgeColor, tierBadgeText, hel
64
97
  react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
65
98
  react_1.default.createElement("rect", { x: "2", y: "1.5", width: "8", height: "9", rx: "1.5", stroke: "#a5b4fc", strokeWidth: "1.2" }),
66
99
  react_1.default.createElement("path", { d: "M4 4.5h4M4 6.5h4M4 8.5h2", stroke: "#a5b4fc", strokeWidth: "0.9", strokeLinecap: "round" })),
67
- "Review"),
100
+ "Review")),
68
101
  react_1.default.createElement("button", { onClick: onClear, className: "bg-transparent border-none p-1 text-tax-axis-text-4 text-sm cursor-pointer" }, "\u00D7"))),
69
- doc.status === "empty" && (react_1.default.createElement("button", { onClick: onUpload, className: "rounded-md px-3.5 py-1.5 text-[11px] font-semibold text-tax-axis-teal-light font-tax-axis-mono cursor-pointer", style: {
70
- background: "rgba(36,131,132,0.10)",
71
- border: "1px solid rgba(36,131,132,0.2)",
72
- } }, "Upload"))))));
102
+ (doc.status === "parsing" || doc.status === "validating") && (react_1.default.createElement("span", { className: "text-[10px] font-semibold font-tax-axis-mono", style: { color: doc.status === "parsing" ? "#248384" : "#FB9A1D" } }, doc.status === "parsing" ? "Parsing…" : "Uploading…")),
103
+ doc.status === "failed" && (react_1.default.createElement(react_1.default.Fragment, null,
104
+ react_1.default.createElement("input", { id: reuploadInputId, type: "file", className: "hidden", accept: (_b = doc.accept) === null || _b === void 0 ? void 0 : _b.join(","), onChange: (event) => {
105
+ var _a;
106
+ const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
107
+ if (file) {
108
+ onUpload(file);
109
+ }
110
+ event.currentTarget.value = "";
111
+ } }),
112
+ react_1.default.createElement("label", { htmlFor: reuploadInputId, className: "rounded-md px-2.5 py-1 text-[10px] font-semibold text-tax-axis-teal-light font-tax-axis-mono cursor-pointer", style: {
113
+ background: "rgba(36,131,132,0.10)",
114
+ border: "1px solid rgba(36,131,132,0.2)",
115
+ } }, "Re-upload"),
116
+ react_1.default.createElement("button", { onClick: onRemove || onClear, className: "bg-transparent border-none p-1 text-tax-axis-text-4 text-sm cursor-pointer", title: "Remove document" }, "\u00D7"))),
117
+ doc.status === "empty" && (react_1.default.createElement(react_1.default.Fragment, null,
118
+ react_1.default.createElement("input", { id: fileInputId, type: "file", className: "hidden", accept: (_c = doc.accept) === null || _c === void 0 ? void 0 : _c.join(","), onChange: (event) => {
119
+ var _a;
120
+ const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
121
+ if (file) {
122
+ onUpload(file);
123
+ }
124
+ event.currentTarget.value = "";
125
+ } }),
126
+ react_1.default.createElement("label", { htmlFor: fileInputId, className: "rounded-md px-3.5 py-1.5 text-[11px] font-semibold text-tax-axis-teal-light font-tax-axis-mono cursor-pointer", style: {
127
+ background: "rgba(36,131,132,0.10)",
128
+ border: "1px solid rgba(36,131,132,0.2)",
129
+ } }, "Upload")))))));
73
130
  }
@@ -6,6 +6,8 @@ export interface DocumentReviewModalProps {
6
6
  documentName: string;
7
7
  fileName: string;
8
8
  jobId: string;
9
+ parsedData?: Record<string, unknown> | null;
10
+ onSaveReviewedData?: (fields: Record<string, string>) => Promise<void>;
9
11
  onClose: () => void;
10
12
  }
11
- export declare function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, onClose, }: DocumentReviewModalProps): React.JSX.Element;
13
+ export declare function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, parsedData, onSaveReviewedData, onClose, }: DocumentReviewModalProps): React.JSX.Element;
@@ -22,19 +22,21 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
25
34
  Object.defineProperty(exports, "__esModule", { value: true });
26
35
  exports.SAVE_FIELD_EDIT_MUTATION = exports.EXTRACTED_FIELDS_QUERY = void 0;
27
36
  exports.DocumentReviewModal = DocumentReviewModal;
28
37
  const react_1 = __importStar(require("react"));
29
38
  const extractedData_1 = require("../../lib/data/extractedData");
30
- // ═══════════════════════════════════════════════════════════════════
31
- // DocumentReviewModal — inspect and edit parser-extracted fields.
32
- // Opens from the document row "Review" button. Sections, flagged
33
- // fields, inline editing with debounced auto-save.
34
- //
35
- // Data: stub-backed from EXTRACTED_DATA for now. GraphQL query and
36
- // mutation constants are exported for future wiring by consuming apps.
37
- // ═══════════════════════════════════════════════════════════════════
39
+ const documentFieldCatalog_1 = require("../../lib/documentFieldCatalog");
38
40
  // ── GraphQL contracts (for consuming apps to use once resolvers land) ──
39
41
  exports.EXTRACTED_FIELDS_QUERY = `
40
42
  query ExtractedDocumentFields($jobId: ID!, $documentId: ID!) {
@@ -64,69 +66,58 @@ exports.SAVE_FIELD_EDIT_MUTATION = `
64
66
  }
65
67
  }
66
68
  `;
67
- // ── Stub section data (maps EXTRACTED_DATA grouped sections) ──
68
- const STUB_SECTIONS = {
69
- pnl: [
70
- {
71
- head: "Revenue",
72
- fields: [
73
- { key: "pnl-gross-revenue", label: "Gross Revenue", value: "$1,847,200", sourceRef: "Line 1a", confidence: 0.95 },
74
- { key: "pnl-cogs", label: "Cost of Goods Sold", value: "$412,500", sourceRef: "Line 2", confidence: 0.92 },
75
- { key: "pnl-gross-profit", label: "Gross Profit", value: "$1,434,700", sourceRef: "Computed", confidence: 0.99 },
76
- { key: "pnl-other-income", label: "Other Income", value: "$18,400", sourceRef: "Line 6", confidence: 0.62 },
77
- ],
78
- },
79
- {
80
- head: "Operating Expenses",
81
- fields: [
82
- { key: "pnl-wages", label: "Wages & Salaries", value: "$487,000", sourceRef: "Line 13", confidence: 0.94 },
83
- { key: "pnl-officer-comp", label: "Officer Compensation", value: "$180,000", sourceRef: "Line 7", confidence: 0.91 },
84
- { key: "pnl-rent", label: "Rent / Lease", value: "$84,000", sourceRef: "Line 15", confidence: 0.88 },
85
- { key: "pnl-meals", label: "Meals & Entertainment", value: "$8,400", sourceRef: "Line 19", confidence: 0.85 },
86
- { key: "pnl-prof-fees", label: "Professional Fees", value: "$24,000", sourceRef: "Line 17", confidence: 0.93 },
87
- { key: "pnl-depreciation", label: "Depreciation", value: "$62,300", sourceRef: "Line 14", confidence: 0.96 },
88
- ],
89
- },
90
- {
91
- head: "Net Income",
92
- fields: [
93
- { key: "pnl-net-ordinary", label: "Net Ordinary Income", value: "$598,000", sourceRef: "Line 21", confidence: 0.97 },
94
- { key: "pnl-tax-income", label: "Taxable Income", value: "$580,200", sourceRef: "Line 28", confidence: 0.90 },
95
- { key: "pnl-net-income", label: "Net Income", value: "$142,000", sourceRef: "Line 30", confidence: 0.93 },
96
- ],
97
- },
98
- ],
99
- balance: [
100
- {
101
- head: "Assets",
102
- fields: [
103
- { key: "bs-cash", label: "Cash & Equivalents", value: "$128,400", sourceRef: "Line 1", confidence: 0.97 },
104
- { key: "bs-ar", label: "Accounts Receivable", value: "$42,000", sourceRef: "Line 2", confidence: 0.94 },
105
- { key: "bs-inventory", label: "Inventory", value: "$45,000", sourceRef: "Line 3", confidence: 0.91 },
106
- { key: "bs-total-assets", label: "Total Assets", value: "$340,000", sourceRef: "Line 11", confidence: 0.98 },
107
- ],
108
- },
109
- {
110
- head: "Liabilities",
111
- fields: [
112
- { key: "bs-ap", label: "Accounts Payable", value: "$31,200", sourceRef: "Line 15", confidence: 0.93 },
113
- { key: "bs-loans", label: "Loans Payable", value: "$78,000", sourceRef: "Line 17", confidence: 0.90 },
114
- { key: "bs-total-liab", label: "Total Liabilities", value: "$109,200", sourceRef: "Line 22", confidence: 0.96 },
115
- ],
116
- },
117
- {
118
- head: "Equity",
119
- fields: [
120
- { key: "bs-retained", label: "Retained Earnings", value: "$188,800", sourceRef: "Line 24", confidence: 0.92 },
121
- { key: "bs-total-equity", label: "Total Equity", value: "$230,800", sourceRef: "Line 27", confidence: 0.95 },
122
- ],
123
- },
124
- ],
125
- };
69
+ // ── Format a raw value for display ──
70
+ function formatValue(v) {
71
+ if (v === null || v === undefined)
72
+ return "";
73
+ if (typeof v === "number")
74
+ return `$${v.toLocaleString()}`;
75
+ if (typeof v === "boolean")
76
+ return v ? "Yes" : "No";
77
+ return String(v);
78
+ }
79
+ // ── Build ReviewSection[] from real parsedData using the catalog ──
80
+ function buildSectionsFromCatalog(documentType, fields) {
81
+ const catalog = documentFieldCatalog_1.DOCUMENT_FIELD_CATALOG[documentType];
82
+ if (!catalog) {
83
+ // Unknown doc type — render all non-null scalar fields in one flat section
84
+ const flatFields = Object.entries(fields)
85
+ .filter(([, v]) => v !== null && v !== undefined && typeof v !== "object")
86
+ .map(([key, val]) => ({
87
+ key,
88
+ label: key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
89
+ value: formatValue(val),
90
+ sourceRef: "",
91
+ confidence: 0.9,
92
+ }));
93
+ return flatFields.length > 0 ? [{ head: "Extracted Fields", fields: flatFields }] : [];
94
+ }
95
+ return catalog.sections
96
+ .map((section) => {
97
+ const sectionFields = section.fields
98
+ .filter((key) => {
99
+ const v = fields[key];
100
+ // Include all scalar fields from the catalog — show empty string for null/undefined.
101
+ // Skip only object/array values (dicts, arrays) which can't be inline-edited.
102
+ return typeof v !== "object" || v === null || v === undefined;
103
+ })
104
+ .map((key) => {
105
+ var _a, _b;
106
+ const def = catalog.fields[key];
107
+ return {
108
+ key,
109
+ label: (_a = def === null || def === void 0 ? void 0 : def.label) !== null && _a !== void 0 ? _a : key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
110
+ value: formatValue(fields[key]),
111
+ sourceRef: (_b = def === null || def === void 0 ? void 0 : def.sourceRef) !== null && _b !== void 0 ? _b : "",
112
+ confidence: 0.9,
113
+ };
114
+ });
115
+ return { head: section.head, fields: sectionFields };
116
+ })
117
+ .filter((s) => s.fields.length > 0);
118
+ }
119
+ // ── Stub fallback when no real parsedData is available ──
126
120
  function getStubSections(documentId) {
127
- if (STUB_SECTIONS[documentId])
128
- return STUB_SECTIONS[documentId];
129
- // Fallback: build sections from EXTRACTED_DATA if available
130
121
  const doc = extractedData_1.EXTRACTED_DATA.find((d) => d.docId === documentId);
131
122
  if (!doc)
132
123
  return [];
@@ -147,251 +138,110 @@ function getTotalFieldCount(sections) {
147
138
  return sections.reduce((sum, s) => sum + s.fields.length, 0);
148
139
  }
149
140
  // ── Component ──
150
- function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, onClose, }) {
141
+ function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, parsedData, onSaveReviewedData, onClose, }) {
151
142
  const [loading, setLoading] = (0, react_1.useState)(true);
152
143
  const [sections, setSections] = (0, react_1.useState)([]);
153
144
  const [saveStatus, setSaveStatus] = (0, react_1.useState)("idle");
154
145
  const debounceTimers = (0, react_1.useRef)({});
155
- // Stub fetch: simulate loading delay
156
146
  (0, react_1.useEffect)(() => {
147
+ var _a;
148
+ if (parsedData && typeof parsedData === "object") {
149
+ const fields = ((_a = parsedData.fields) !== null && _a !== void 0 ? _a : parsedData);
150
+ const documentType = parsedData.documentType || documentId;
151
+ setSections(buildSectionsFromCatalog(documentType, fields));
152
+ setLoading(false);
153
+ return;
154
+ }
155
+ // Fallback: stub loading delay
157
156
  const t = setTimeout(() => {
158
157
  setSections(getStubSections(documentId));
159
158
  setLoading(false);
160
159
  }, 400);
161
160
  return () => clearTimeout(t);
162
- }, [documentId]);
161
+ }, [documentId, parsedData]);
163
162
  const handleFieldChange = (0, react_1.useCallback)((sectionIdx, fieldIdx, newValue) => {
164
163
  setSections((prev) => prev.map((sec, si) => si === sectionIdx
165
164
  ? Object.assign(Object.assign({}, sec), { fields: sec.fields.map((f, fi) => fi === fieldIdx ? Object.assign(Object.assign({}, f), { value: newValue }) : f) }) : sec));
166
165
  const timerKey = `${sectionIdx}-${fieldIdx}`;
167
- if (debounceTimers.current[timerKey]) {
168
- clearTimeout(debounceTimers.current[timerKey]);
169
- }
166
+ clearTimeout(debounceTimers.current[timerKey]);
170
167
  setSaveStatus("saving");
171
168
  debounceTimers.current[timerKey] = setTimeout(() => {
172
- // Stub save — replace with GraphQL mutation when resolvers are ready
173
169
  setSaveStatus("saved");
174
170
  setTimeout(() => setSaveStatus("idle"), 1500);
175
171
  }, 900);
176
- }, []);
177
- // Cleanup debounce timers on unmount
172
+ }, [sections]);
173
+ const handleDone = (0, react_1.useCallback)(() => __awaiter(this, void 0, void 0, function* () {
174
+ if (onSaveReviewedData && sections.length > 0) {
175
+ const allFields = {};
176
+ sections.forEach((sec) => sec.fields.forEach((f) => { allFields[f.key] = f.value; }));
177
+ try {
178
+ yield onSaveReviewedData(allFields);
179
+ }
180
+ catch ( /* non-fatal */_a) { /* non-fatal */ }
181
+ }
182
+ onClose();
183
+ }), [onSaveReviewedData, sections, onClose]);
178
184
  (0, react_1.useEffect)(() => {
179
185
  const timers = debounceTimers.current;
180
- return () => {
181
- Object.values(timers).forEach(clearTimeout);
182
- };
186
+ return () => { Object.values(timers).forEach(clearTimeout); };
183
187
  }, []);
184
188
  const totalFields = getTotalFieldCount(sections);
185
189
  const isFlagged = (f) => f.confidence < 0.8;
186
- return (
187
- // Overlay
188
- react_1.default.createElement("div", { onClick: onClose, style: {
189
- position: "fixed",
190
- inset: 0,
191
- zIndex: 9999,
192
- background: "rgba(0,0,0,0.65)",
193
- display: "flex",
194
- alignItems: "center",
195
- justifyContent: "center",
196
- } },
197
- react_1.default.createElement("div", { onClick: (e) => e.stopPropagation(), style: {
198
- width: 520,
199
- maxHeight: "85vh",
200
- background: "#111827",
201
- border: "1px solid #1f2937",
202
- borderRadius: 16,
203
- display: "flex",
204
- flexDirection: "column",
205
- boxShadow: "0 25px 60px rgba(0,0,0,0.5)",
206
- } },
207
- react_1.default.createElement("div", { style: {
208
- padding: "20px 24px 16px",
209
- borderBottom: "1px solid #1f2937",
210
- display: "flex",
211
- alignItems: "flex-start",
212
- gap: 14,
213
- } },
214
- react_1.default.createElement("div", { style: {
215
- width: 40,
216
- height: 40,
217
- borderRadius: 10,
218
- background: "rgba(99,102,241,0.12)",
219
- border: "1px solid rgba(99,102,241,0.25)",
220
- display: "flex",
221
- alignItems: "center",
222
- justifyContent: "center",
223
- flexShrink: 0,
224
- } },
190
+ return (react_1.default.createElement("div", { onClick: onClose, style: { position: "fixed", inset: 0, zIndex: 9999, background: "rgba(0,0,0,0.65)", display: "flex", alignItems: "center", justifyContent: "center" } },
191
+ react_1.default.createElement("div", { onClick: (e) => e.stopPropagation(), style: { width: 520, maxHeight: "85vh", background: "#111827", border: "1px solid #1f2937", borderRadius: 16, display: "flex", flexDirection: "column", boxShadow: "0 25px 60px rgba(0,0,0,0.5)" } },
192
+ react_1.default.createElement("div", { style: { padding: "20px 24px 16px", borderBottom: "1px solid #1f2937", display: "flex", alignItems: "flex-start", gap: 14 } },
193
+ react_1.default.createElement("div", { style: { width: 40, height: 40, borderRadius: 10, background: "rgba(99,102,241,0.12)", border: "1px solid rgba(99,102,241,0.25)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 } },
225
194
  react_1.default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" },
226
195
  react_1.default.createElement("rect", { x: "3", y: "2", width: "12", height: "14", rx: "2", stroke: "#818cf8", strokeWidth: "1.5" }),
227
196
  react_1.default.createElement("path", { d: "M6 6h6M6 9h6M6 12h4", stroke: "#818cf8", strokeWidth: "1.2", strokeLinecap: "round" }))),
228
197
  react_1.default.createElement("div", { style: { flex: 1, minWidth: 0 } },
229
- react_1.default.createElement("div", { className: "font-tax-axis-body", style: {
230
- fontSize: 15,
231
- fontWeight: 600,
232
- color: "#f3f4f6",
233
- marginBottom: 3,
234
- } },
198
+ react_1.default.createElement("div", { className: "font-tax-axis-body", style: { fontSize: 15, fontWeight: 600, color: "#f3f4f6", marginBottom: 3 } },
235
199
  documentName,
236
200
  " \u2014 Extracted Fields"),
237
201
  react_1.default.createElement("div", { className: "font-tax-axis-body", style: { fontSize: 12, color: "#9ca3af" } },
238
202
  fileName,
239
- !loading && (react_1.default.createElement(react_1.default.Fragment, null,
203
+ !loading && react_1.default.createElement(react_1.default.Fragment, null,
240
204
  " ",
241
205
  "\u00B7 ",
242
206
  totalFields,
243
- " fields \u00B7 Review and correct parsed values")))),
244
- react_1.default.createElement("button", { onClick: onClose, style: {
245
- background: "transparent",
246
- border: "none",
247
- color: "#6b7280",
248
- fontSize: 20,
249
- cursor: "pointer",
250
- padding: "2px 6px",
251
- lineHeight: 1,
252
- } }, "\u00D7")),
253
- react_1.default.createElement("div", { style: {
254
- flex: 1,
255
- overflowY: "auto",
256
- padding: "16px 24px 8px",
257
- } }, loading ? (react_1.default.createElement(LoadingSkeleton, null)) : (sections.map((section, si) => (react_1.default.createElement("div", { key: section.head, style: { marginBottom: 20 } },
258
- react_1.default.createElement("div", { style: {
259
- display: "flex",
260
- alignItems: "center",
261
- gap: 10,
262
- marginBottom: 10,
263
- } },
264
- react_1.default.createElement("span", { className: "font-tax-axis-mono", style: {
265
- fontSize: 10,
266
- fontWeight: 700,
267
- letterSpacing: "0.08em",
268
- textTransform: "uppercase",
269
- color: "#6b7280",
270
- } }, section.head),
271
- react_1.default.createElement("div", { style: {
272
- flex: 1,
273
- height: 1,
274
- background: "#1f2937",
275
- } })),
276
- react_1.default.createElement("div", { style: {
277
- background: "#0d1117",
278
- borderRadius: 10,
279
- border: "1px solid #1f2937",
280
- overflow: "hidden",
281
- } }, section.fields.map((field, fi) => {
207
+ " fields \u00B7 Review and correct parsed values"))),
208
+ react_1.default.createElement("button", { onClick: onClose, style: { background: "transparent", border: "none", color: "#6b7280", fontSize: 20, cursor: "pointer", padding: "2px 6px", lineHeight: 1 } }, "\u00D7")),
209
+ react_1.default.createElement("div", { style: { flex: 1, overflowY: "auto", padding: "16px 24px 8px" } }, loading ? (react_1.default.createElement(LoadingSkeleton, null)) : sections.length === 0 ? (react_1.default.createElement("div", { style: { color: "#6b7280", fontSize: 13, textAlign: "center", padding: "32px 0" } }, "No extracted fields available for this document.")) : (sections.map((section, si) => (react_1.default.createElement("div", { key: section.head, style: { marginBottom: 20 } },
210
+ react_1.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10, marginBottom: 10 } },
211
+ react_1.default.createElement("span", { className: "font-tax-axis-mono", style: { fontSize: 10, fontWeight: 700, letterSpacing: "0.08em", textTransform: "uppercase", color: "#6b7280" } }, section.head),
212
+ react_1.default.createElement("div", { style: { flex: 1, height: 1, background: "#1f2937" } })),
213
+ react_1.default.createElement("div", { style: { background: "#0d1117", borderRadius: 10, border: "1px solid #1f2937", overflow: "hidden" } }, section.fields.map((field, fi) => {
282
214
  const flagged = isFlagged(field);
283
- return (react_1.default.createElement("div", { key: field.key, style: {
284
- display: "grid",
285
- gridTemplateColumns: "140px 1fr auto",
286
- alignItems: "center",
287
- padding: "10px 14px",
288
- borderBottom: fi < section.fields.length - 1
289
- ? "1px solid #1f2937"
290
- : "none",
291
- gap: 12,
292
- } },
293
- react_1.default.createElement("span", { className: "font-tax-axis-body", style: {
294
- fontSize: 12,
295
- color: flagged ? "#fbbf24" : "#9ca3af",
296
- display: "flex",
297
- alignItems: "center",
298
- gap: 5,
299
- } },
215
+ return (react_1.default.createElement("div", { key: field.key, style: { display: "grid", gridTemplateColumns: "160px 1fr auto", alignItems: "center", padding: "10px 14px", borderBottom: fi < section.fields.length - 1 ? "1px solid #1f2937" : "none", gap: 12 } },
216
+ react_1.default.createElement("span", { className: "font-tax-axis-body", style: { fontSize: 12, color: flagged ? "#fbbf24" : "#9ca3af", display: "flex", alignItems: "center", gap: 5 } },
300
217
  flagged && (react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
301
218
  react_1.default.createElement("path", { d: "M6 1L11 10H1L6 1Z", stroke: "#fbbf24", strokeWidth: "1.2", strokeLinejoin: "round" }),
302
219
  react_1.default.createElement("path", { d: "M6 4.5V6.5M6 8V8.01", stroke: "#fbbf24", strokeWidth: "1.1", strokeLinecap: "round" }))),
303
220
  field.label),
304
- react_1.default.createElement("input", { type: "text", value: field.value, onChange: (e) => handleFieldChange(si, fi, e.target.value), style: {
305
- background: "#0d1117",
306
- border: `1px solid ${flagged ? "rgba(251,191,36,0.4)" : "#1f2937"}`,
307
- borderRadius: 6,
308
- padding: "7px 10px",
309
- color: "#e5e7eb",
310
- fontSize: 13,
311
- fontFamily: "monospace",
312
- outline: "none",
313
- width: "100%",
314
- boxSizing: "border-box",
315
- } }),
316
- react_1.default.createElement("span", { className: "font-tax-axis-mono", style: {
317
- fontSize: 11,
318
- color: flagged ? "#fbbf24" : "#4ade80",
319
- whiteSpace: "nowrap",
320
- display: "flex",
321
- alignItems: "center",
322
- gap: 4,
323
- } },
324
- field.sourceRef,
221
+ react_1.default.createElement("input", { type: "text", value: field.value, onChange: (e) => handleFieldChange(si, fi, e.target.value), style: { background: "#0d1117", border: `1px solid ${flagged ? "rgba(251,191,36,0.4)" : "#1f2937"}`, borderRadius: 6, padding: "7px 10px", color: "#e5e7eb", fontSize: 13, fontFamily: "monospace", outline: "none", width: "100%", boxSizing: "border-box" } }),
222
+ react_1.default.createElement("span", { className: "font-tax-axis-mono", style: { fontSize: 11, color: flagged ? "#fbbf24" : "#4ade80", whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: 4 } },
223
+ field.sourceRef || "",
325
224
  " ",
326
- flagged ? (react_1.default.createElement("span", { style: { fontSize: 10 } }, "\u25B2")) : (react_1.default.createElement("span", { style: { color: "#4ade80", fontSize: 12 } }, "\u2713")))));
225
+ flagged ? react_1.default.createElement("span", { style: { fontSize: 10 } }, "\u25B2") : react_1.default.createElement("span", { style: { fontSize: 12 } }, "\u2713"))));
327
226
  }))))))),
328
- react_1.default.createElement("div", { style: {
329
- padding: "14px 24px",
330
- borderTop: "1px solid #1f2937",
331
- display: "flex",
332
- alignItems: "center",
333
- justifyContent: "space-between",
334
- } },
335
- react_1.default.createElement("span", { className: "font-tax-axis-body", style: {
336
- fontSize: 11,
337
- color: "#6b7280",
338
- display: "flex",
339
- alignItems: "center",
340
- gap: 6,
341
- } },
227
+ react_1.default.createElement("div", { style: { padding: "14px 24px", borderTop: "1px solid #1f2937", display: "flex", alignItems: "center", justifyContent: "space-between" } },
228
+ react_1.default.createElement("span", { className: "font-tax-axis-body", style: { fontSize: 11, color: "#6b7280", display: "flex", alignItems: "center", gap: 6 } },
342
229
  saveStatus === "idle" && (react_1.default.createElement(react_1.default.Fragment, null,
343
230
  react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
344
231
  react_1.default.createElement("circle", { cx: "6", cy: "6", r: "5", stroke: "#6b7280", strokeWidth: "1.2" }),
345
232
  react_1.default.createElement("path", { d: "M6 3.5V6.5L8 7.5", stroke: "#6b7280", strokeWidth: "1.1", strokeLinecap: "round" })),
346
233
  "Changes save automatically")),
347
234
  saveStatus === "saving" && (react_1.default.createElement(react_1.default.Fragment, null,
348
- react_1.default.createElement("div", { style: {
349
- width: 10,
350
- height: 10,
351
- borderRadius: "50%",
352
- border: "2px solid transparent",
353
- borderTopColor: "#818cf8",
354
- animation: "spin 0.6s linear infinite",
355
- } }),
235
+ react_1.default.createElement("div", { style: { width: 10, height: 10, borderRadius: "50%", border: "2px solid transparent", borderTopColor: "#818cf8", animation: "spin 0.6s linear infinite" } }),
356
236
  "Saving\u2026")),
357
- saveStatus === "saved" && (react_1.default.createElement("span", { style: { color: "#4ade80" } }, "Saved \u2713"))),
358
- react_1.default.createElement("button", { onClick: onClose, className: "font-tax-axis-body", style: {
359
- background: "rgba(99,102,241,0.9)",
360
- border: "none",
361
- borderRadius: 8,
362
- padding: "9px 28px",
363
- color: "#fff",
364
- fontSize: 13,
365
- fontWeight: 600,
366
- cursor: "pointer",
367
- } }, "Done"))),
368
- react_1.default.createElement("style", null, `
369
- @keyframes spin {
370
- to { transform: rotate(360deg); }
371
- }
372
- `)));
237
+ saveStatus === "saved" && react_1.default.createElement("span", { style: { color: "#4ade80" } }, "Saved \u2713")),
238
+ react_1.default.createElement("button", { onClick: handleDone, className: "font-tax-axis-body", style: { background: "rgba(99,102,241,0.9)", border: "none", borderRadius: 8, padding: "9px 28px", color: "#fff", fontSize: 13, fontWeight: 600, cursor: "pointer" } }, "Done"))),
239
+ react_1.default.createElement("style", null, `@keyframes spin { to { transform: rotate(360deg); } }`)));
373
240
  }
374
- // ── Loading skeleton ──
375
241
  function LoadingSkeleton() {
376
242
  return (react_1.default.createElement("div", null, [1, 2].map((i) => (react_1.default.createElement("div", { key: i, style: { marginBottom: 20 } },
377
- react_1.default.createElement("div", { style: {
378
- width: 100,
379
- height: 10,
380
- background: "#1f2937",
381
- borderRadius: 4,
382
- marginBottom: 10,
383
- } }),
384
- react_1.default.createElement("div", { style: {
385
- background: "#0d1117",
386
- borderRadius: 10,
387
- border: "1px solid #1f2937",
388
- padding: 14,
389
- } }, [1, 2, 3].map((j) => (react_1.default.createElement("div", { key: j, style: {
390
- display: "grid",
391
- gridTemplateColumns: "140px 1fr 60px",
392
- gap: 12,
393
- marginBottom: j < 3 ? 12 : 0,
394
- } },
243
+ react_1.default.createElement("div", { style: { width: 100, height: 10, background: "#1f2937", borderRadius: 4, marginBottom: 10 } }),
244
+ react_1.default.createElement("div", { style: { background: "#0d1117", borderRadius: 10, border: "1px solid #1f2937", padding: 14 } }, [1, 2, 3].map((j) => (react_1.default.createElement("div", { key: j, style: { display: "grid", gridTemplateColumns: "160px 1fr 60px", gap: 12, marginBottom: j < 3 ? 12 : 0 } },
395
245
  react_1.default.createElement("div", { style: { height: 14, background: "#1f2937", borderRadius: 4 } }),
396
246
  react_1.default.createElement("div", { style: { height: 32, background: "#1f2937", borderRadius: 6 } }),
397
247
  react_1.default.createElement("div", { style: { height: 14, background: "#1f2937", borderRadius: 4 } }))))))))));