@paro.io/expert-shared-components 1.12.19 → 1.12.21

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.
@@ -73,6 +73,9 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
73
73
  };
74
74
  const getTotalApprovedHours = () => {
75
75
  var _a;
76
+ if (resolution === 'DECLINED') {
77
+ return 0;
78
+ }
76
79
  if (resolution === 'PARTIAL' && ((_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a.length) > 0) {
77
80
  return Object.values(projectApprovedHours).reduce((sum, hours) => sum + hours, 0);
78
81
  }
@@ -106,7 +109,7 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
106
109
  const disputeProjectUpdates = ((_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a.map((project) => ({
107
110
  projectId: project.projectId,
108
111
  resolutionMode: 'Direct',
109
- resolutionType: resolutionType
112
+ resolutionType: resolution === 'DECLINED' ? 'Canceled' : resolutionType
110
113
  }))) || [];
111
114
  // Calculate approved amount based on dispute types
112
115
  const hasNonHourlyProjects = (_b = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _b === void 0 ? void 0 : _b.some((project) => project.disputeType !== 'Hourly');
@@ -181,9 +184,9 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
181
184
  react_1.default.createElement("div", { className: "text-xs text-gray-500" }, project.disputeType === 'Hourly'
182
185
  ? `Disputed Hours: ${project.disputeHours}`
183
186
  : `Dispute Amount: $${((_a = project.disputeAmount) === null || _a === void 0 ? void 0 : _a.toFixed(2)) || '0.00'}`)),
184
- react_1.default.createElement("div", { className: "w-32" }, project.disputeType === 'Hourly' ? (react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: project.disputeHours, value: projectApprovedHours[project.projectId] || 0, onChange: (e) => handleProjectHoursChange(project.projectId, parseFloat(e.target.value) || 0), className: "w-full px-2 py-1 border border-[#CCCCCC] rounded text-sm focus:outline-none focus:ring-2 focus:ring-[#248384]", placeholder: "Hours" })) : (react_1.default.createElement("div", { className: "relative" },
187
+ react_1.default.createElement("div", { className: "w-32" }, project.disputeType === 'Hourly' ? (react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: project.disputeHours, value: projectApprovedHours[project.projectId] || '', onChange: (e) => handleProjectHoursChange(project.projectId, parseFloat(e.target.value) || 0), className: "w-full px-2 py-1 border border-[#CCCCCC] rounded text-sm focus:outline-none focus:ring-2 focus:ring-[#248384]", placeholder: "Hours" })) : (react_1.default.createElement("div", { className: "relative" },
185
188
  react_1.default.createElement("span", { className: "absolute left-2 top-1/2 transform -translate-y-1/2 text-gray-500" }, "$"),
186
- react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: project.disputeAmount, value: projectApprovedHours[project.projectId] || 0, onChange: (e) => handleProjectHoursChange(project.projectId, parseFloat(e.target.value) || 0), className: "w-full pl-2 pr-2 py-1 border border-[#CCCCCC] rounded text-sm focus:outline-none focus:ring-2 focus:ring-[#248384]", placeholder: "0.00" }))))));
189
+ react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: project.disputeAmount, value: projectApprovedHours[project.projectId] || '', onChange: (e) => handleProjectHoursChange(project.projectId, parseFloat(e.target.value) || 0), className: "w-full pl-2 pr-2 py-1 border border-[#CCCCCC] rounded text-sm focus:outline-none focus:ring-2 focus:ring-[#248384]", placeholder: "0.00" }))))));
187
190
  })),
188
191
  react_1.default.createElement("div", { className: "text-sm text-gray-600" }, dispute.disputeProjects.some((p) => p.disputeType === 'Hourly') &&
189
192
  dispute.disputeProjects.some((p) => p.disputeType !== 'Hourly') ? (
@@ -215,7 +218,6 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
215
218
  // All non-hourly disputes
216
219
  `Total Approved Amount: $${getTotalApprovedHours().toFixed(2)} / $${dispute.disputeProjects.reduce((sum, p) => sum + p.disputeAmount, 0).toFixed(2)}`)))),
217
220
  react_1.default.createElement("div", { className: "flex justify-end space-x-4" },
218
- react_1.default.createElement(base_ui_1.Button, { label: "Decline Dispute", color: "error", onClick: () => handleResolutionChange('DECLINED'), disabled: isSubmitting, size: "md" }),
219
221
  react_1.default.createElement(base_ui_1.Button, { label: "Approve & Resolve", color: "primary", onClick: handleApproveClick, isLoading: isSubmitting, disabled: !resolution || (resolution === 'PARTIAL' && !isValidPartialApproval()), size: "md" }))),
220
222
  react_1.default.createElement(ProjectHoursAdjustmentModal_1.ProjectHoursAdjustmentModal, { isOpen: showHoursModal, onClose: () => setShowHoursModal(false), disputeProjects: (dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) || [], dispute: dispute, onSubmit: handleHoursSubmit, isSubmitting: isSubmitting, getClientInvoiceSummaryByMonth: getClientInvoiceSummaryByMonth, invoiceSummary: invoiceSummary, approvedHours: resolution === 'PARTIAL' ? getTotalApprovedHours() : totalDisputeHours, projectApprovedHours: isPartialWithMultipleProjects ? projectApprovedHours : {}, user: user })));
221
223
  };
@@ -31,7 +31,7 @@ const InvoiceHeader = ({ invoice, isInternal = false, isClient = false }) => {
31
31
  react_1.default.createElement("div", null,
32
32
  react_1.default.createElement("span", { className: "text-sm font-bold" }, "Dispute Status: "),
33
33
  react_1.default.createElement("span", { className: "ml-2" }, (invoice === null || invoice === void 0 ? void 0 : invoice.status) === "InProgress" ? "In Progress" : invoice === null || invoice === void 0 ? void 0 : invoice.status)),
34
- (invoice === null || invoice === void 0 ? void 0 : invoice.approvedAmount) && (react_1.default.createElement("div", null,
34
+ (invoice === null || invoice === void 0 ? void 0 : invoice.approvedAmount) >= 0 && (invoice === null || invoice === void 0 ? void 0 : invoice.status) === 'Resolved' && (react_1.default.createElement("div", null,
35
35
  react_1.default.createElement("span", { className: "text-sm font-bold" }, "Approved Amount: "),
36
36
  react_1.default.createElement("span", { className: "ml-2" },
37
37
  "$", invoice === null || invoice === void 0 ? void 0 :
@@ -95,8 +95,8 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
95
95
  projectSectionsData.forEach(section => {
96
96
  section.tasks.forEach(task => {
97
97
  initialAdjustedHours[task.projectHourId] = {
98
- originalHours: task.hours,
99
- newHours: task.hours
98
+ originalHours: parseFloat(task.hours.toFixed(2)),
99
+ newHours: parseFloat(task.hours.toFixed(2))
100
100
  };
101
101
  });
102
102
  });
@@ -115,7 +115,7 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
115
115
  });
116
116
  const handleHourChange = (projectHourId, newHours) => {
117
117
  var _a;
118
- const numericValue = parseFloat(newHours) || 0;
118
+ const numericValue = parseFloat(newHours);
119
119
  const originalHours = ((_a = adjustedHours[projectHourId]) === null || _a === void 0 ? void 0 : _a.originalHours) || 0;
120
120
  setAdjustedHours(prev => (Object.assign(Object.assign({}, prev), { [projectHourId]: Object.assign(Object.assign({}, prev[projectHourId]), { newHours: numericValue }) })));
121
121
  // Clear individual hour error
@@ -134,7 +134,7 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
134
134
  return 0;
135
135
  return section.tasks.reduce((total, task) => {
136
136
  const adjustment = adjustedHours[task.projectHourId];
137
- if (!adjustment)
137
+ if (!adjustment || isNaN(adjustment.newHours))
138
138
  return total;
139
139
  return total + (type === 'original' ? adjustment.originalHours : adjustment.newHours);
140
140
  }, 0);
@@ -182,7 +182,7 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
182
182
  var _a, _b;
183
183
  const projectHourId = task.projectHourId;
184
184
  const originalHours = ((_a = adjustedHours[projectHourId]) === null || _a === void 0 ? void 0 : _a.originalHours) || 0;
185
- const newHours = ((_b = adjustedHours[projectHourId]) === null || _b === void 0 ? void 0 : _b.newHours) || 0;
185
+ const newHours = (_b = adjustedHours[projectHourId]) === null || _b === void 0 ? void 0 : _b.newHours;
186
186
  if (newHours > originalHours) {
187
187
  newErrors[projectHourId] = 'New hours cannot exceed original hours';
188
188
  hasErrors = true;
@@ -241,7 +241,7 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
241
241
  inputArray.push({
242
242
  clientRate: task.rate,
243
243
  freelancerRate: task.freelancerRate,
244
- hours: calculatedHours,
244
+ hours: parseFloat(calculatedHours.toFixed(2)),
245
245
  projectId: section.projectId,
246
246
  projectHourId: task.projectHourId,
247
247
  projectName: section.projectName,
@@ -301,7 +301,7 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
301
301
  : "Please enter the new hours to settle the dispute for each of the project time log entries below"),
302
302
  react_1.default.createElement("div", { className: "space-y-8" }, projectSections.map((section) => {
303
303
  var _a, _b;
304
- const projectReduction = getProjectReduction(section.projectId);
304
+ const projectReduction = getProjectReduction(section.projectId) || 0;
305
305
  const maxAllowedReduction = projectApprovedHours[section.projectId] !== undefined
306
306
  ? projectApprovedHours[section.projectId]
307
307
  : section.disputeType === 'Hourly'
@@ -363,7 +363,7 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
363
363
  const projectHourId = task.projectHourId;
364
364
  const originalHours = task.hours;
365
365
  const originalAmount = task.hours * task.rate;
366
- const newHours = ((_a = adjustedHours[projectHourId]) === null || _a === void 0 ? void 0 : _a.newHours) || 0;
366
+ const newHours = (_a = adjustedHours[projectHourId]) === null || _a === void 0 ? void 0 : _a.newHours;
367
367
  const newAmount = newHours * task.rate;
368
368
  const hasError = errors[projectHourId];
369
369
  return (react_1.default.createElement("tr", { key: projectHourId, className: hasError ? 'bg-red-50' : '' },
@@ -374,10 +374,10 @@ const ProjectHoursAdjustmentModal = ({ isOpen, onClose, disputeProjects, dispute
374
374
  : `$${((_b = section.disputeAmount) === null || _b === void 0 ? void 0 : _b.toFixed(2)) || '0.00'}`),
375
375
  react_1.default.createElement("td", { className: "border border-gray-300 px-4 py-2" },
376
376
  react_1.default.createElement("div", null,
377
- section.disputeType === 'Hourly' ? (react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: originalHours, value: newHours, onChange: (e) => handleHourChange(projectHourId, e.target.value), className: `w-full px-2 py-1 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 ${hasError ? 'border-red-500' : 'border-gray-300'}` })) : (react_1.default.createElement("div", { className: "flex items-center" },
377
+ section.disputeType === 'Hourly' ? (react_1.default.createElement("input", { type: "number", step: "0.01", max: originalHours, value: newHours >= 0 ? newHours : '', onChange: (e) => handleHourChange(projectHourId, e.target.value), className: `w-full px-2 py-1 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 ${hasError ? 'border-red-500' : 'border-gray-300'}` })) : (react_1.default.createElement("div", { className: "flex items-center" },
378
378
  react_1.default.createElement("span", { className: "mr-1" }, "$"),
379
- react_1.default.createElement("span", null, newAmount.toFixed(2)),
380
- react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: originalHours, value: newHours, onChange: (e) => handleHourChange(projectHourId, e.target.value), className: `ml-2 w-20 px-2 py-1 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 ${hasError ? 'border-red-500' : 'border-gray-300'}`, placeholder: "hrs" }),
379
+ react_1.default.createElement("input", { type: "number", step: "0.01", min: "0", max: originalAmount, value: newAmount >= 0 ? newAmount : '', onChange: (e) => handleHourChange(projectHourId, (parseFloat(e.target.value) / task.rate).toString()), className: `w-32 px-2 py-1 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 ${hasError ? 'border-red-500' : 'border-gray-300'}`, placeholder: "$0.00" }),
380
+ react_1.default.createElement("span", { className: "ml-2" }, newHours.toFixed(2)),
381
381
  react_1.default.createElement("span", { className: "ml-1 text-xs text-gray-500" }, "hrs"))),
382
382
  hasError && (react_1.default.createElement("div", { className: "text-red-500 text-xs mt-1" }, hasError))))));
383
383
  }))))));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paro.io/expert-shared-components",
3
- "version": "1.12.19",
3
+ "version": "1.12.21",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {