@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] ||
|
|
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] ||
|
|
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)
|
|
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 = (
|
|
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 = (
|
|
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",
|
|
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("
|
|
380
|
-
react_1.default.createElement("
|
|
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
|
}))))));
|