@paro.io/expert-shared-components 1.14.66 → 1.14.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 -2
  27. package/lib/tax-axis/components/documents/DocumentReviewModal.js +109 -295
  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 +335 -172
  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
@@ -38,6 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.MultiFileUploadSection = void 0;
39
39
  const react_1 = __importStar(require("react"));
40
40
  const core_1 = require("@material-ui/core");
41
+ const CheckCircle_1 = __importDefault(require("@material-ui/icons/CheckCircle"));
41
42
  const ExpandMore_1 = __importDefault(require("@material-ui/icons/ExpandMore"));
42
43
  const ExpandLess_1 = __importDefault(require("@material-ui/icons/ExpandLess"));
43
44
  const date_fns_1 = require("date-fns");
@@ -70,15 +71,13 @@ const generateOptions = (array, clientOptions, isClientPortal) => {
70
71
  ? `${item === null || item === void 0 ? void 0 : item.id}_${index}`
71
72
  : item === null || item === void 0 ? void 0 : item.split(" ").join("_").concat(index);
72
73
  if (clientOptions) {
73
- if (name && projectName) {
74
- newText = `${name} - ${projectName}`;
74
+ // Show only project name for project dropdown
75
+ if (projectName) {
76
+ newText = projectName;
75
77
  }
76
78
  else if (name) {
77
79
  newText = name;
78
80
  }
79
- else if (projectName) {
80
- newText = projectName;
81
- }
82
81
  else {
83
82
  newText = "N/A";
84
83
  }
@@ -94,7 +93,6 @@ const generateOptions = (array, clientOptions, isClientPortal) => {
94
93
  });
95
94
  };
96
95
  const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadExpertClientFiles, uploadInternalFile, foldername, refetchFiles, legacyFreelancerId, freelancerName, freelancerEmail, isClientPortal = false, documentUploadUrl, showAsPage, }) => {
97
- var _a;
98
96
  const [uploadItems, setUploadItems] = (0, react_1.useState)([]);
99
97
  const [isUploading, setIsUploading] = (0, react_1.useState)(false);
100
98
  const [showUploadSection, setShowUploadSection] = (0, react_1.useState)(true);
@@ -122,7 +120,9 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
122
120
  const excludedStatuses = ["complete", "completed", "doa", "churned"];
123
121
  const isValidProject = projectStatus &&
124
122
  !excludedStatuses.includes(projectStatus.toLowerCase());
125
- if (id && name) {
123
+ // Filter out "System Fee" expert on client side
124
+ const isSystemFee = isClientPortal && (name === null || name === void 0 ? void 0 : name.toLowerCase()) === "system fee";
125
+ if (id && name && !isSystemFee) {
126
126
  if (!groups.has(id)) {
127
127
  groups.set(id, {
128
128
  expert: { id, name },
@@ -193,7 +193,7 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
193
193
  if (!selectedExpert)
194
194
  return [];
195
195
  return clientOptions.filter((opt) => {
196
- var _a, _b;
196
+ var _a, _b, _c, _d;
197
197
  const isMatch = isClientPortal
198
198
  ? ((_a = opt.freelancer) === null || _a === void 0 ? void 0 : _a.id) === selectedExpert.id
199
199
  : ((_b = opt.client) === null || _b === void 0 ? void 0 : _b.id) === selectedExpert.id;
@@ -201,7 +201,12 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
201
201
  const excludedStatuses = ["complete", "completed", "doa", "churned"];
202
202
  const isValidProject = projectStatus &&
203
203
  !excludedStatuses.includes(projectStatus.toLowerCase());
204
- return isMatch && isValidProject;
204
+ // Filter out System Fee projects on client side
205
+ const expertName = isClientPortal
206
+ ? (_c = opt.freelancer) === null || _c === void 0 ? void 0 : _c.name
207
+ : (_d = opt.client) === null || _d === void 0 ? void 0 : _d.name;
208
+ const isSystemFee = isClientPortal && (expertName === null || expertName === void 0 ? void 0 : expertName.toLowerCase()) === "system fee";
209
+ return isMatch && isValidProject && !isSystemFee;
205
210
  });
206
211
  }, [selectedExpert, clientOptions, isClientPortal]);
207
212
  // Check if all files have projects assigned (for multi-project experts/clients)
@@ -210,6 +215,15 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
210
215
  return true;
211
216
  return uploadItems.every((item) => { var _a; return (_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value; });
212
217
  }, [uploadItems, hasMultipleProjects]);
218
+ // Count files that need projects
219
+ const filesNeedingProjects = react_1.default.useMemo(() => {
220
+ if (!selectedExpert)
221
+ return 0;
222
+ return uploadItems.filter((item) => { var _a; return !((_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) && item.status !== "success"; }).length;
223
+ }, [uploadItems, selectedExpert]);
224
+ // Determine step states
225
+ const step1Complete = selectedExpert !== null;
226
+ const step2Complete = step1Complete && uploadItems.length > 0 && allFilesHaveProjects;
213
227
  const handleFilesSelected = (files) => {
214
228
  const newItems = files.map((file) => ({
215
229
  id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
@@ -411,78 +425,198 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
411
425
  ".jpg",
412
426
  ".png",
413
427
  ], disabled: isUploading })),
414
- uploadItems.length > 0 &&
415
- !paroDocuments &&
416
- expertGroups.length > 0 && (react_1.default.createElement(core_1.Box, { mb: 3, p: 2, style: { backgroundColor: "#F7FAFC", borderRadius: "8px" } },
417
- react_1.default.createElement(core_1.Box, { display: "flex", alignItems: "center", mb: 2 },
428
+ uploadItems.length > 0 && (react_1.default.createElement(core_1.Box, { mb: 3 },
429
+ react_1.default.createElement(core_1.Typography, { variant: "h5", style: {
430
+ fontWeight: 700,
431
+ color: "#1a1a2e",
432
+ marginBottom: "4px",
433
+ } }, !paroDocuments
434
+ ? isClientPortal
435
+ ? "Send Files to Expert"
436
+ : "Send Files to Client"
437
+ : "Upload Documents"),
438
+ react_1.default.createElement(core_1.Typography, { variant: "body2", style: { color: "#8b8fa3" } }, "Choose a recipient, assign each file to a project, then upload."))),
439
+ !paroDocuments &&
440
+ expertGroups.length > 0 &&
441
+ uploadItems.length > 0 && (react_1.default.createElement(core_1.Paper, { elevation: 0, style: {
442
+ marginBottom: "24px",
443
+ borderRadius: "12px",
444
+ border: step1Complete
445
+ ? "2px solid #248384"
446
+ : "2px solid #a8a8a8",
447
+ backgroundColor: step1Complete ? "#FDFEFD" : "#fafafa",
448
+ overflow: "hidden",
449
+ } },
450
+ react_1.default.createElement(core_1.Box, { p: 2, style: {
451
+ backgroundColor: step1Complete ? "#F0FAF0" : "#f7f7f9",
452
+ borderBottom: "1px solid #f0f0f5",
453
+ display: "flex",
454
+ alignItems: "center",
455
+ gap: "12px",
456
+ } },
418
457
  react_1.default.createElement(core_1.Box, { style: {
419
- width: "32px",
420
- height: "32px",
458
+ width: "24px",
459
+ height: "24px",
421
460
  borderRadius: "50%",
422
- backgroundColor: "#48BB78",
423
- color: "white",
461
+ backgroundColor: step1Complete ? "white" : "gray",
462
+ color: step1Complete ? "#248384" : "white",
424
463
  display: "flex",
425
464
  alignItems: "center",
426
465
  justifyContent: "center",
427
- fontWeight: "bold",
428
- marginRight: "12px",
429
- } }, "1"),
430
- react_1.default.createElement(core_1.Typography, { variant: "subtitle1", style: { fontWeight: 600 } }, isClientPortal
431
- ? "SEND TO EXPERT — select who these files are for"
432
- : "SEND TO CLIENT — select which client these files are for")),
433
- react_1.default.createElement(core_1.Box, { display: "flex", flexWrap: "wrap", style: { gap: "8px" } }, expertGroups.map((group) => (react_1.default.createElement(core_1.Chip, { key: group.expert.id, label: react_1.default.createElement(core_1.Box, null,
434
- react_1.default.createElement("strong", null, group.expert.name),
435
- react_1.default.createElement(core_1.Box, { component: "span", ml: 1, style: { color: "#718096" } },
436
- group.projects.length,
437
- " ",
438
- group.projects.length === 1
439
- ? "project"
440
- : "projects")), onClick: () => handleExpertSelection(group.expert), clickable: true, disabled: group.projects.length === 0, color: "default", style: {
441
- padding: "8px 12px",
442
- height: "auto",
443
- borderRadius: "20px",
444
- border: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
445
- ? "2px solid #3182CE"
446
- : "1px solid #CBD5E0",
447
- backgroundColor: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
448
- ? "#EBF8FF"
449
- : "white",
450
- opacity: group.projects.length === 0 ? 0.5 : 1,
451
- cursor: group.projects.length === 0
452
- ? "not-allowed"
453
- : "pointer",
454
- } })))),
455
- selectedExpert && hasSingleProject && (react_1.default.createElement(core_1.Box, { mt: 2 },
456
- react_1.default.createElement(core_1.Chip, { label: "AUTO-ASSIGNED", size: "small", style: {
457
- backgroundColor: "#C6F6D5",
458
- color: "#22543D",
459
- fontWeight: 600,
460
- } }),
461
- react_1.default.createElement(core_1.Typography, { variant: "caption", style: { marginLeft: "8px", color: "#718096" } },
462
- ((_a = selectedExpertProjects[0]) === null || _a === void 0 ? void 0 : _a.name) || "Project",
463
- " \u2014 only project with ",
464
- selectedExpert.name))),
465
- selectedExpert && hasMultipleProjects && (react_1.default.createElement(core_1.Box, { mt: 2 },
466
- react_1.default.createElement(core_1.Chip, { label: `${selectedExpertProjects.length} PROJECTS`, size: "small", style: {
467
- backgroundColor: "#FEF5E7",
468
- color: "#D97706",
466
+ fontSize: "13px",
467
+ fontWeight: 700,
468
+ flexShrink: 0,
469
+ } }, step1Complete ? (react_1.default.createElement(CheckCircle_1.default, { style: { fontSize: "28px" } })) : ("1")),
470
+ react_1.default.createElement(core_1.Box, null,
471
+ react_1.default.createElement(core_1.Typography, { variant: "subtitle1", style: {
472
+ fontSize: "14px",
473
+ fontWeight: 600,
474
+ color: "#1a1a2e",
475
+ } }, "Select recipient"),
476
+ react_1.default.createElement(core_1.Typography, { variant: "caption", style: { fontSize: "12px", color: "#8b8fa3" } }, "Who should receive these files?"))),
477
+ react_1.default.createElement(core_1.Box, { p: 2 },
478
+ react_1.default.createElement(core_1.Box, { display: "flex", flexWrap: "wrap", style: { gap: "10px" } }, expertGroups.map((group) => (react_1.default.createElement(core_1.Chip, { key: group.expert.id, label: react_1.default.createElement(core_1.Box, { display: "flex", alignItems: "center", style: { gap: "6px" } },
479
+ (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id && (react_1.default.createElement(CheckCircle_1.default, { style: { fontSize: "20px" } })),
480
+ react_1.default.createElement("span", { style: { fontWeight: 600 } }, group.expert.name),
481
+ react_1.default.createElement("span", { style: {
482
+ fontSize: "11px",
483
+ fontWeight: 500,
484
+ padding: "2px 7px",
485
+ borderRadius: "10px",
486
+ backgroundColor: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
487
+ ? "#e2e8f0"
488
+ : "#f0f1f4",
489
+ color: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
490
+ ? "#248384"
491
+ : "#8b8fa3",
492
+ } },
493
+ group.projects.length,
494
+ " ",
495
+ group.projects.length === 1
496
+ ? "project"
497
+ : "projects")), onClick: () => handleExpertSelection(group.expert), clickable: true, disabled: group.projects.length === 0, style: {
498
+ padding: "10px 18px",
499
+ height: "auto",
500
+ borderRadius: "8px",
501
+ border: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
502
+ ? "2px solid #248384"
503
+ : "2px solid #e2e4ea",
504
+ backgroundColor: "#fff",
505
+ color: (selectedExpert === null || selectedExpert === void 0 ? void 0 : selectedExpert.id) === group.expert.id
506
+ ? "#248384"
507
+ : "#3d3f4a",
508
+ opacity: group.projects.length === 0 ? 0.5 : 1,
509
+ cursor: group.projects.length === 0
510
+ ? "not-allowed"
511
+ : "pointer",
512
+ } }))))))),
513
+ uploadItems.length > 0 && (react_1.default.createElement(core_1.Paper, { elevation: 0, style: {
514
+ marginBottom: "24px",
515
+ borderRadius: "12px",
516
+ border: step2Complete
517
+ ? "2px solid #248384"
518
+ : !paroDocuments && !step1Complete
519
+ ? "2px solid #e2e4ea"
520
+ : "2px solid #006cff",
521
+ backgroundColor: step2Complete
522
+ ? "#FDFEFD"
523
+ : !paroDocuments && !step1Complete
524
+ ? "#fafafa"
525
+ : "#ffffff",
526
+ overflow: "hidden",
527
+ opacity: !paroDocuments && !step1Complete ? 0.5 : 1,
528
+ pointerEvents: !paroDocuments && !step1Complete ? "none" : "auto",
529
+ } },
530
+ react_1.default.createElement(core_1.Box, { p: 2, style: {
531
+ backgroundColor: step2Complete
532
+ ? "#F0FAF0"
533
+ : !paroDocuments && !step1Complete
534
+ ? "#f7f7f9"
535
+ : "#f2f2f25e",
536
+ borderBottom: "1px solid #f0f0f5",
537
+ display: "flex",
538
+ alignItems: "center",
539
+ gap: "12px",
540
+ } },
541
+ react_1.default.createElement(core_1.Box, { style: {
542
+ width: "24px",
543
+ height: "24px",
544
+ borderRadius: "50%",
545
+ backgroundColor: step2Complete
546
+ ? "white"
547
+ : !paroDocuments && !step1Complete
548
+ ? "#ccc"
549
+ : "#006cff",
550
+ color: step2Complete ? "#248384" : "white",
551
+ display: "flex",
552
+ alignItems: "center",
553
+ justifyContent: "center",
554
+ fontSize: "13px",
555
+ fontWeight: 700,
556
+ flexShrink: 0,
557
+ } }, step2Complete ? (react_1.default.createElement(CheckCircle_1.default, { style: { fontSize: "28px" } })) : paroDocuments ? ("1") : ("2")),
558
+ react_1.default.createElement(core_1.Box, { flex: 1 },
559
+ react_1.default.createElement(core_1.Typography, { variant: "subtitle1", style: {
560
+ fontSize: "14px",
561
+ fontWeight: 600,
562
+ color: "#1a1a2e",
563
+ } }, "Assign files to projects"),
564
+ react_1.default.createElement(core_1.Typography, { variant: "caption", style: { fontSize: "12px", color: "#8b8fa3" } }, "Categorize each file and select its project")),
565
+ !paroDocuments && filesNeedingProjects > 0 && (react_1.default.createElement(core_1.Chip, { label: `${filesNeedingProjects} need${filesNeedingProjects === 1 ? "s" : ""} a project`, size: "small", style: {
566
+ fontSize: "11px",
469
567
  fontWeight: 600,
470
- }, icon: react_1.default.createElement(base_icons_1.IconExclamation, { stroke: "#D97706" }) }),
471
- react_1.default.createElement(core_1.Typography, { variant: "caption", style: { marginLeft: "8px", color: "#718096" } }, "Select which project each file is for below"))))),
472
- uploadItems.length > 0 && (react_1.default.createElement(core_1.Box, null,
473
- react_1.default.createElement(core_1.Box, null,
568
+ padding: "4px 10px",
569
+ backgroundColor: "#FFF3E0",
570
+ color: "#E65100",
571
+ } }))),
572
+ react_1.default.createElement(core_1.Box, { p: 2 },
474
573
  react_1.default.createElement(core_1.Grid, { container: true, spacing: 2 }, uploadItems.map((item, index) => {
475
- var _a;
574
+ var _a, _b, _c;
575
+ const needsProject = !paroDocuments && !((_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value);
476
576
  return (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, key: item.id },
477
577
  react_1.default.createElement(core_1.Paper, { elevation: 1, style: {
478
578
  padding: "12px 16px",
479
- backgroundColor: "white",
480
- border: "1px solid #E2E8F0",
481
- borderRadius: "4px",
579
+ backgroundColor: needsProject ? "#FFFBF5" : "white",
580
+ border: needsProject
581
+ ? "2px solid #FFE0B2"
582
+ : "1.5px solid #f0f1f4",
583
+ borderRadius: "10px",
482
584
  } },
483
585
  react_1.default.createElement(core_1.Grid, { container: true, spacing: 2 },
484
- react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: "auto", style: { display: "flex", alignItems: "center" } },
485
- react_1.default.createElement(base_icons_1.IconDocument, { size: "lg" })),
586
+ react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: "auto", style: {
587
+ display: "flex",
588
+ alignItems: "center",
589
+ } },
590
+ react_1.default.createElement(core_1.Box, { style: {
591
+ width: "36px",
592
+ height: "42px",
593
+ borderRadius: "4px",
594
+ display: "flex",
595
+ alignItems: "flex-end",
596
+ justifyContent: "center",
597
+ paddingBottom: "4px",
598
+ fontSize: "10px",
599
+ fontWeight: 700,
600
+ letterSpacing: "0.5px",
601
+ textTransform: "uppercase",
602
+ backgroundColor: item.file.name.endsWith(".csv")
603
+ ? "#E8F5E9"
604
+ : item.file.name.endsWith(".pdf")
605
+ ? "#FFF3E0"
606
+ : "#E3F2FD",
607
+ border: item.file.name.endsWith(".csv")
608
+ ? "1.5px solid #A5D6A7"
609
+ : item.file.name.endsWith(".pdf")
610
+ ? "1.5px solid #FFCC80"
611
+ : "1.5px solid #90CAF9",
612
+ color: item.file.name.endsWith(".csv")
613
+ ? "#248384"
614
+ : item.file.name.endsWith(".pdf")
615
+ ? "#E65100"
616
+ : "#1976D2",
617
+ } }, ((_b = item.file.name
618
+ .split(".")
619
+ .pop()) === null || _b === void 0 ? void 0 : _b.toUpperCase()) || "FILE")),
486
620
  react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: true },
487
621
  react_1.default.createElement(base_ui_1.Input, { type: "text", value: item.documentName, onChange: (e) => updateItem(item.id, {
488
622
  documentName: e.target.value,
@@ -511,7 +645,8 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
511
645
  }
512
646
  }, options: documentTypeOptions, disabled: item.status === "uploading" ||
513
647
  item.status === "success", required: false })),
514
- paroDocuments && item.docType === "EO Insurance" && (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: 3, style: { marginTop: "5px" } },
648
+ paroDocuments &&
649
+ item.docType === "EO Insurance" && (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: 3, style: { marginTop: "5px" } },
515
650
  react_1.default.createElement(core_1.TextField, { type: "date", label: "Expiration Date", value: item.expiryDate
516
651
  ? new Date(item.expiryDate)
517
652
  .toISOString()
@@ -546,7 +681,7 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
546
681
  }, disabled: item.status === "uploading" ||
547
682
  item.status === "success", fullWidth: true, variant: "outlined", size: "small", required: true, error: !!item.dateError, helperText: item.dateError }))),
548
683
  !paroDocuments && !hasSingleProject && (react_1.default.createElement(core_1.Grid, { item: true, xs: 12, sm: 3 },
549
- react_1.default.createElement(base_ui_1.Select, { value: ((_a = item.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) || "", onChange: (e) => {
684
+ react_1.default.createElement(base_ui_1.Select, { value: ((_c = item.clientAndProject) === null || _c === void 0 ? void 0 : _c.value) || "", onChange: (e) => {
550
685
  // Handle empty selection
551
686
  if (e.target.value === "") {
552
687
  updateItem(item.id, {
@@ -562,7 +697,7 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
562
697
  {
563
698
  id: "placeholder",
564
699
  value: "",
565
- label: "Which project?",
700
+ label: "Select project",
566
701
  },
567
702
  ...filteredProjectOptions,
568
703
  ], disabled: item.status === "uploading" ||
@@ -585,55 +720,19 @@ const MultiFileUploadSection = ({ paroDocuments, clientAndProjectsList, uploadEx
585
720
  react_1.default.createElement(core_1.Typography, { variant: "caption", style: { color: "#38A169" } }, "\u2713 Upload successful"))),
586
721
  item.status === "error" && (react_1.default.createElement(core_1.Box, { mt: 1, ml: { xs: 0, sm: 6 } },
587
722
  react_1.default.createElement(core_1.Typography, { variant: "caption", style: { color: "#E53E3E" } }, "\u2717 Upload failed"))))));
588
- }))),
589
- react_1.default.createElement(core_1.Divider, { style: { marginTop: "24px" } }),
590
- react_1.default.createElement(core_1.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2, mt: 2 },
591
- react_1.default.createElement(core_1.Box, null,
592
- react_1.default.createElement(core_1.Typography, { variant: "body2", style: { color: "#718096" } }, paroDocuments ? (react_1.default.createElement(react_1.default.Fragment, null,
593
- react_1.default.createElement("span", { style: { fontWeight: "bold" } }, uploadItems.filter((i) => i.status !== "success")
594
- .length),
595
- " ",
596
- uploadItems.filter((i) => i.status !== "success")
597
- .length === 1
598
- ? "file"
599
- : "files")) : (react_1.default.createElement(react_1.default.Fragment, null,
600
- react_1.default.createElement("span", { style: { fontWeight: "bold" } }, uploadItems.filter((i) => i.status !== "success")
601
- .length),
602
- " ",
603
- "files \u2022",
604
- " ",
605
- react_1.default.createElement("span", { style: { color: "#718096" } },
606
- react_1.default.createElement("span", { style: { fontWeight: "bold" } }, uploadItems.filter((i) => {
607
- var _a;
608
- return ((_a = i.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) &&
609
- i.status !== "success";
610
- }).length),
611
- " ",
612
- "project-assigned"),
613
- " ",
614
- "\u2022",
615
- " ",
616
- react_1.default.createElement("span", { style: { color: "#D97706" } },
617
- react_1.default.createElement("span", { style: { fontWeight: "bold" } }, uploadItems.filter((i) => {
618
- var _a;
619
- return !((_a = i.clientAndProject) === null || _a === void 0 ? void 0 : _a.value) &&
620
- i.status !== "success";
621
- }).length),
622
- " ",
623
- "need project"))))),
624
- react_1.default.createElement(core_1.Box, null,
625
- react_1.default.createElement(core_1.Box, { component: "span", ml: 1 },
626
- react_1.default.createElement(base_ui_1.Button, { label: isUploading
627
- ? "Uploading..."
628
- : `Upload ${uploadItems.filter((i) => i.status !== "success").length} Files`, onClick: handleUploadAll, disabled: uploadItems.length === 0 ||
629
- isUploading ||
630
- uploadItems.every((i) => i.status === "success") ||
631
- (!paroDocuments && !selectedExpert) ||
632
- (hasMultipleProjects && !allFilesHaveProjects) ||
633
- uploadItems.some((i) => paroDocuments &&
634
- i.docType === "EO Insurance" &&
635
- (!i.expiryDate || !!i.dateError) &&
636
- i.status !== "success"), color: "primary", isLoading: isUploading }))))))))));
723
+ }))))),
724
+ uploadItems.length > 0 && (react_1.default.createElement(core_1.Box, { display: "flex", justifyContent: "flex-end" },
725
+ react_1.default.createElement(base_ui_1.Button, { label: isUploading
726
+ ? "Uploading..."
727
+ : `Upload ${uploadItems.filter((i) => i.status !== "success").length} File${uploadItems.filter((i) => i.status !== "success").length !== 1 ? "s" : ""}`, onClick: handleUploadAll, disabled: uploadItems.length === 0 ||
728
+ isUploading ||
729
+ uploadItems.every((i) => i.status === "success") ||
730
+ (!paroDocuments && !selectedExpert) ||
731
+ (hasMultipleProjects && !allFilesHaveProjects) ||
732
+ uploadItems.some((i) => paroDocuments &&
733
+ i.docType === "EO Insurance" &&
734
+ (!i.expiryDate || !!i.dateError) &&
735
+ i.status !== "success"), color: "primary", isLoading: isUploading })))))));
637
736
  };
638
737
  exports.MultiFileUploadSection = MultiFileUploadSection;
639
738
  exports.default = exports.MultiFileUploadSection;
@@ -55,5 +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: Record<string, unknown>) => Promise<any>;
59
58
  };
@@ -113,36 +113,6 @@ function entityTypeKey(entity) {
113
113
  return undefined;
114
114
  return (_a = ENTITY_DISPLAY_TO_KEY[entity]) !== null && _a !== void 0 ? _a : entity;
115
115
  }
116
- const GENERATING_STAGES = [
117
- 'Analyzing entity structure…',
118
- 'Evaluating deduction strategies…',
119
- 'Modeling tax scenarios…',
120
- 'Scoring strategy opportunities…',
121
- 'Generating prospect insights…',
122
- ];
123
- function GeneratingOverlay() {
124
- const [elapsed, setElapsed] = (0, react_1.useState)(0);
125
- const [mounted, setMounted] = (0, react_1.useState)(false);
126
- (0, react_1.useEffect)(() => { setMounted(true); }, []);
127
- (0, react_1.useEffect)(() => {
128
- const id = setInterval(() => setElapsed((s) => s + 1), 1000);
129
- return () => clearInterval(id);
130
- }, []);
131
- const stageIdx = Math.min(Math.floor(elapsed / 9), GENERATING_STAGES.length - 1);
132
- return (react_1.default.createElement("div", { className: 'fixed inset-0 z-[180] bg-black/25' },
133
- react_1.default.createElement("div", { className: 'absolute left-1/2 top-1/3 -translate-x-1/2 rounded-xl bg-tax-axis-surface px-8 py-6 text-center shadow-lg border border-tax-axis-border', style: { maxWidth: 360, width: '100%' } },
134
- react_1.default.createElement("div", { className: 'w-full h-1.5 rounded-full bg-tax-axis-border mb-4 overflow-hidden' },
135
- react_1.default.createElement("div", { className: 'h-full rounded-full', style: {
136
- background: 'linear-gradient(90deg, #248384, #2dd4bf)',
137
- width: mounted ? '95%' : '0%',
138
- transition: 'width 45s ease-out',
139
- } })),
140
- react_1.default.createElement("div", { className: 'text-sm font-semibold text-white mb-1 font-tax-axis-body' }, "Generating Prospect Report"),
141
- react_1.default.createElement("div", { className: 'text-xs text-tax-axis-text-3 font-tax-axis-body mb-2', style: { minHeight: 18 } }, GENERATING_STAGES[stageIdx]),
142
- react_1.default.createElement("div", { className: 'text-[10px] text-tax-axis-text-4 font-tax-axis-mono' },
143
- elapsed,
144
- "s elapsed"))));
145
- }
146
116
  function buildSessionInput(profile) {
147
117
  const taxYear = Number(profile.year) || new Date().getFullYear();
148
118
  return {
@@ -158,30 +128,6 @@ function buildSessionInput(profile) {
158
128
  states: profile.states || [],
159
129
  };
160
130
  }
161
- function buildProspectInput(profile) {
162
- var _a;
163
- const fedRateStr = (profile.federalRate || '24%').replace('%', '');
164
- const stateRateStr = (profile.stateRate || '0').replace('%', '');
165
- return {
166
- businessName: profile.bizName || 'Client',
167
- entityType: profile.entity || 'S-Corporation',
168
- primaryState: ((_a = profile.states) === null || _a === void 0 ? void 0 : _a[0]) || 'IL',
169
- states: profile.states || [],
170
- industry: profile.industry || 'Professional Services',
171
- annualRevenue: toInt(profile.revenue),
172
- netIncome: toInt(profile.netIncome) || null,
173
- ownerCompensation: toInt(profile.ownerComp) || null,
174
- employees: toInt(profile.employees) || null,
175
- federalRate: parseFloat(fedRateStr) / 100 || 0.24,
176
- stateRate: parseFloat(stateRateStr) / 100 || 0,
177
- taxYear: Number(profile.year) || new Date().getFullYear(),
178
- analysisPeriod: profile.period || 'Full Year',
179
- riskTolerance: profile.riskTolerance || null,
180
- equipmentPurchased: toInt(profile.equipmentPurchased) || null,
181
- realEstateValue: toInt(profile.realEstateValue) || null,
182
- capitalGains: toInt(profile.capitalGains) || null,
183
- };
184
- }
185
131
  function ShellContainer({ children, fullWidth = false, }) {
186
132
  if (fullWidth) {
187
133
  return react_1.default.createElement(react_1.default.Fragment, null, children);
@@ -200,8 +146,6 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
200
146
  const [error, setError] = (0, react_1.useState)(null);
201
147
  const [busyMessage, setBusyMessage] = (0, react_1.useState)('Syncing Tax Axis session...');
202
148
  const [reportReady, setReportReady] = (0, react_1.useState)(false);
203
- const [backendResults, setBackendResults] = (0, react_1.useState)(null);
204
- const [generating, setGenerating] = (0, react_1.useState)(false);
205
149
  const isPollingRef = react_1.default.useRef(false);
206
150
  // QBO state driven by EPS props — not localStorage
207
151
  const [qboConnectedState, setQboConnectedState] = (0, react_1.useState)(!!qboConnected);
@@ -268,12 +212,12 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
268
212
  }
269
213
  }, [onSessionChange]);
270
214
  const createSessionIfNeeded = (0, react_1.useCallback)((nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
271
- var _a;
215
+ var _a, _b;
272
216
  if (sessionId)
273
217
  return sessionId;
274
218
  try {
275
219
  const sessionInput = buildSessionInput(nextProfile);
276
- const created = yield taxAxisApi.createSession(Object.assign(Object.assign({}, sessionInput), { clientId: (_a = sessionDefaults === null || sessionDefaults === void 0 ? void 0 : sessionDefaults.clientId) !== null && _a !== void 0 ? _a : null, freelancerId: (sessionDefaults === null || sessionDefaults === void 0 ? void 0 : sessionDefaults.freelancerId) || sessionInput.freelancerId }));
220
+ const created = yield taxAxisApi.createSession(Object.assign(Object.assign({}, sessionInput), { clientId: (_a = sessionDefaults === null || sessionDefaults === void 0 ? void 0 : sessionDefaults.clientId) !== null && _a !== void 0 ? _a : null, freelancerId: (_b = sessionDefaults === null || sessionDefaults === void 0 ? void 0 : sessionDefaults.freelancerId) !== null && _b !== void 0 ? _b : sessionInput.freelancerId }));
277
221
  const maybeSessionId = (created === null || created === void 0 ? void 0 : created.sessionId) || (created === null || created === void 0 ? void 0 : created.id) || null;
278
222
  if (maybeSessionId) {
279
223
  updateSessionId(maybeSessionId);
@@ -292,29 +236,13 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
292
236
  setIsProspectFlow(false);
293
237
  setError(null);
294
238
  setReportReady(false);
295
- setBackendResults(null);
296
239
  updateSessionId(null);
297
240
  }, [updateSessionId]);
298
- const handleProspect = (0, react_1.useCallback)((nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
241
+ const handleProspect = (0, react_1.useCallback)((nextProfile) => {
299
242
  setProfile(nextProfile);
300
243
  setIsProspectFlow(true);
301
- setBackendResults(null);
302
- if (taxAxisApi.generateProspectReport) {
303
- setGenerating(true);
304
- try {
305
- const input = buildProspectInput(nextProfile);
306
- const result = yield taxAxisApi.generateProspectReport(Object.assign(Object.assign({}, input), { freelancerId: sessionDefaults === null || sessionDefaults === void 0 ? void 0 : sessionDefaults.freelancerId }));
307
- if (result) {
308
- setBackendResults(result);
309
- }
310
- }
311
- catch (_err) {
312
- // LLM call failed — fall through to template mode
313
- }
314
- setGenerating(false);
315
- }
316
244
  setStep('PROSPECT_REPORT');
317
- }), [taxAxisApi, sessionDefaults === null || sessionDefaults === void 0 ? void 0 : sessionDefaults.freelancerId]);
245
+ }, []);
318
246
  const handleFullAnalysis = (0, react_1.useCallback)((nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
319
247
  setProfile(nextProfile);
320
248
  setIsProspectFlow(false);
@@ -495,7 +423,7 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
495
423
  switch (step) {
496
424
  case 'PROSPECT_REPORT':
497
425
  return (react_1.default.createElement(ShellContainer, null,
498
- react_1.default.createElement(TaxAxisProspectReport_1.TaxAxisProspectReport, { profile: profile, userContext: userContext, backendResults: backendResults, onUpgrade: () => setStep('DOCUMENT_UPLOAD'), onPresent: () => setStep('PRESENTATION'), onReset: handleReset })));
426
+ react_1.default.createElement(TaxAxisProspectReport_1.TaxAxisProspectReport, { profile: profile, userContext: userContext, onUpgrade: () => setStep('DOCUMENT_UPLOAD'), onPresent: () => setStep('PRESENTATION'), onReset: handleReset })));
499
427
  case 'DOCUMENT_UPLOAD':
500
428
  return (react_1.default.createElement(ShellContainer, null,
501
429
  react_1.default.createElement("div", { className: "flex items-center justify-between rounded-lg px-4 py-3 mb-5", style: {
@@ -585,8 +513,6 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
585
513
  llmResult,
586
514
  adapted,
587
515
  reportReady,
588
- backendResults,
589
- generating,
590
516
  parsedDocuments,
591
517
  qboConnectedState,
592
518
  qboCompanyNameState,
@@ -604,7 +530,6 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
604
530
  react_1.default.createElement("div", { className: 'flex items-center gap-2' },
605
531
  react_1.default.createElement("div", { className: 'w-3 h-3 rounded-full animate-spin flex-shrink-0', style: { border: '2px solid transparent', borderTopColor: '#248384' } }),
606
532
  busyMessage)))),
607
- generating && react_1.default.createElement(GeneratingOverlay, null),
608
533
  currentView));
609
534
  };
610
535
  exports.TaxAxisShell = TaxAxisShell;
@@ -8,9 +8,10 @@ export default class UploadClient {
8
8
  bucketName: string;
9
9
  escalationId?: string;
10
10
  taskId?: string;
11
+ keyPrefix?: string;
11
12
  };
12
13
  constructor(props: any);
13
- generateS3Key(projectId: number, escalationId: string, fileName: string, taskId: string): string;
14
+ generateS3Key(projectId: number, escalationId: string, fileName: string, taskId: string, keyPrefix?: string): string;
14
15
  triggerMultipartUpload(): Promise<string | undefined>;
15
16
  uploadMultiPartFile(): Promise<string | undefined>;
16
17
  completeUpload(partsArray: any): Promise<string | undefined>;