@paro.io/expert-shared-components 1.12.34 → 1.12.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +2 -2
- package/lib/components/ClientReferencesSection/DeleteButton.js +11 -11
- package/lib/components/ClientReferencesSection/ParoError.js +10 -10
- package/lib/components/ClientReferencesSection/TagsSection.js +2 -2
- package/lib/components/ClientReferencesSection/styles/BrandedTypography.js +2 -2
- package/lib/components/ClientReferencesSection/styles/Buttons.js +15 -15
- package/lib/components/ClientReferencesSection/styles/Name.js +5 -5
- package/lib/components/ClientReferencesSection/styles/NullContentConditionalColor.js +4 -4
- package/lib/components/ClientReferencesSection/styles/SectionBody.js +11 -11
- package/lib/components/ClientReferencesSection/styles/SectionTitle.js +6 -6
- package/lib/components/ClientReferencesSection/styles/Tags.js +2 -2
- package/lib/components/DiscussionThread/chat.d.ts +22 -22
- package/lib/components/DiscussionThread/chat.js +106 -106
- package/lib/components/DocumentCenter/ClientDocumentsTable.d.ts +2 -1
- package/lib/components/DocumentCenter/ClientDocumentsTable.js +6 -5
- package/lib/components/DocumentCenter/DocumentCenter.d.ts +2 -1
- package/lib/components/DocumentCenter/DocumentCenter.js +2 -2
- package/lib/components/DocumentCenter/DocumentTable.d.ts +15 -15
- package/lib/components/DocumentCenter/DocumentTable.js +350 -350
- package/lib/components/DocumentCenter/UploadFilesButton.d.ts +6 -6
- package/lib/components/DocumentCenter/UploadFilesButton.js +29 -29
- package/lib/components/EarningsTracker/ActiveProjectCard.d.ts +52 -52
- package/lib/components/EarningsTracker/ActiveProjectCard.js +161 -161
- package/lib/components/EarningsTracker/CenterCardUI.d.ts +13 -13
- package/lib/components/EarningsTracker/CenterCardUI.js +134 -134
- package/lib/components/EarningsTracker/EarningsTracker.d.ts +52 -52
- package/lib/components/EarningsTracker/EarningsTracker.js +508 -508
- package/lib/components/EarningsTracker/EditDateModal.d.ts +22 -22
- package/lib/components/EarningsTracker/EditDateModal.js +149 -149
- package/lib/components/EarningsTracker/EmailModal.d.ts +14 -14
- package/lib/components/EarningsTracker/EmailModal.js +79 -79
- package/lib/components/EarningsTracker/EndProjectModal.d.ts +56 -56
- package/lib/components/EarningsTracker/EndProjectModal.js +221 -221
- package/lib/components/EarningsTracker/LeftCardUI.d.ts +18 -18
- package/lib/components/EarningsTracker/LeftCardUI.js +189 -189
- package/lib/components/EarningsTracker/LogTimeModalAuthenticated.d.ts +52 -52
- package/lib/components/EarningsTracker/LogTimeModalAuthenticated.js +358 -358
- package/lib/components/EarningsTracker/ProgressBar.d.ts +4 -4
- package/lib/components/EarningsTracker/ProgressBar.js +66 -66
- package/lib/components/EarningsTracker/ReviewRequestModal.d.ts +17 -17
- package/lib/components/EarningsTracker/ReviewRequestModal.js +135 -135
- package/lib/components/EarningsTracker/RightCardUI.d.ts +46 -46
- package/lib/components/EarningsTracker/RightCardUI.js +231 -231
- package/lib/components/EarningsTracker/index.d.ts +1 -1
- package/lib/components/EarningsTracker/index.js +5 -5
- package/lib/components/ExpertProfileHeader/ActionButtonSection.js +6 -6
- package/lib/components/ExpertProfileHeader/ProfileSection.js +7 -7
- package/lib/components/FileUploader/index.d.ts +10 -1
- package/lib/components/FileUploader/index.js +42 -14
- package/lib/components/Invoices/ClientDisputeProjectCard.d.ts +2 -1
- package/lib/components/Invoices/ClientDisputeProjectCard.js +11 -2
- package/lib/components/Invoices/DecisionSection.d.ts +2 -1
- package/lib/components/Invoices/DecisionSection.js +56 -25
- package/lib/components/Invoices/DisputeSection.d.ts +3 -1
- package/lib/components/Invoices/DisputeSection.js +13 -4
- package/lib/components/Invoices/InvoiceCard.d.ts +3 -1
- package/lib/components/Invoices/InvoiceCard.js +9 -5
- package/lib/components/Invoices/InvoiceDetails.js +2 -2
- package/lib/components/Invoices/TestDecisionSection.d.ts +1 -1
- package/lib/components/Invoices/TestDecisionSection.js +126 -126
- package/lib/components/OrganizationChart/OrganizationChart.d.ts +15 -15
- package/lib/components/OrganizationChart/OrganizationChart.js +312 -312
- package/lib/components/OrganizationChart/PersonCard.js +5 -5
- package/lib/components/OrganizationChart/utils.js +79 -79
- package/lib/components/ProjectCard/ProgressBar.js +4 -4
- package/lib/components/ProjectCard/ReviewRequestModal.js +5 -5
- package/lib/components/Reviews/Pagination.js +6 -6
- package/lib/components/ReviewsTab/RatingHeader.js +6 -6
- package/lib/components/ReviewsTab/expert-shared-components.code-workspace +20 -20
- package/lib/components/ReviewsTab/reviewRequestModal.js +5 -5
- package/lib/components/shared/Image.js +13 -13
- package/lib/components/shared/ProfileTextField.d.ts +18 -18
- package/lib/components/shared/ProfileTextField.js +16 -16
- package/lib/components/shared/StyledActionButtons.d.ts +7 -7
- package/lib/components/shared/StyledActionButtons.js +15 -15
- package/lib/components/shared/ToastNotification.d.ts +10 -10
- package/lib/components/shared/ToastNotification.js +63 -63
- package/lib/components/shared/utils.d.ts +1 -0
- package/lib/components/shared/utils.js +2 -1
- package/package.json +61 -61
|
@@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.fileUploader = void 0;
|
|
16
16
|
const UploadClient_1 = __importDefault(require("../shared/UploadClient"));
|
|
17
17
|
const utils_1 = require("../shared/utils");
|
|
18
|
-
const fileUploader = (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, projectId, documentUploadUrl, updateClientInvoiceDisputeMutation, bucketName, disputeId, previousFiles, isExpert, }) {
|
|
18
|
+
const fileUploader = (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, projectId, documentUploadUrl, updateClientInvoiceDisputeMutation, uploadExpertClientFiles, bucketName, disputeId, previousFiles, isExpert, disputeData, }) {
|
|
19
19
|
const documentLinks = previousFiles ? (typeof previousFiles === 'string' ? previousFiles.split(',') : [...previousFiles]) : [];
|
|
20
20
|
try {
|
|
21
21
|
(0, utils_1.showToast)('success', 'Starting Document Upload');
|
|
@@ -30,20 +30,48 @@ const fileUploader = (_a) => __awaiter(void 0, [_a], void 0, function* ({ file,
|
|
|
30
30
|
const resParsed = JSON.parse(res);
|
|
31
31
|
const documentLink = resParsed === null || resParsed === void 0 ? void 0 : resParsed.Location;
|
|
32
32
|
documentLinks.push(documentLink); // Add the new file to the documentLinks array
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
const promises = [];
|
|
34
|
+
if (disputeId) {
|
|
35
|
+
promises.push(updateClientInvoiceDisputeMutation({
|
|
36
|
+
variables: {
|
|
37
|
+
input: {
|
|
38
|
+
disputeId: disputeId,
|
|
39
|
+
projectDisputes: [
|
|
40
|
+
Object.assign({ projectId: projectId }, (isExpert ? {
|
|
41
|
+
expertDocumentLinks: documentLinks.join(',')
|
|
42
|
+
} : {
|
|
43
|
+
clientDocumentLinks: documentLinks.join(',')
|
|
44
|
+
}))
|
|
45
|
+
]
|
|
46
|
+
},
|
|
44
47
|
},
|
|
45
|
-
}
|
|
46
|
-
}
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
if (uploadExpertClientFiles && disputeData) {
|
|
51
|
+
promises.push(uploadExpertClientFiles({
|
|
52
|
+
variables: {
|
|
53
|
+
input: {
|
|
54
|
+
clientId: disputeData.clientId,
|
|
55
|
+
clientName: disputeData.clientName,
|
|
56
|
+
email: disputeData.email,
|
|
57
|
+
fileName: file.name,
|
|
58
|
+
fileSize: file.size,
|
|
59
|
+
fileType: 'DISPUTE_DOCUMENTS',
|
|
60
|
+
freelancerId: disputeData.freelancerId,
|
|
61
|
+
freelancerName: disputeData.freelancerName,
|
|
62
|
+
projectId: projectId,
|
|
63
|
+
projectName: disputeData.projectName,
|
|
64
|
+
uploadedBy: isExpert ? 'FREELANCER' : 'CLIENT',
|
|
65
|
+
data: "",
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
// Execute all promises in parallel
|
|
71
|
+
if (promises.length > 0) {
|
|
72
|
+
yield Promise.all(promises);
|
|
73
|
+
console.log('Document uploaded successfully to S3 and to Document Center');
|
|
74
|
+
}
|
|
47
75
|
console.log(`Multipart File uploaded successfully with ${res}`);
|
|
48
76
|
(0, utils_1.showToast)('success', 'Document Upload Successful');
|
|
49
77
|
}));
|
|
@@ -4,7 +4,8 @@ interface ClientDisputeProjectCardProps {
|
|
|
4
4
|
documentUploadUrl: string;
|
|
5
5
|
downloadDocumentUrl: string;
|
|
6
6
|
bucketName?: string;
|
|
7
|
+
uploadExpertClientFiles?: any;
|
|
7
8
|
}
|
|
8
9
|
export declare const handleDownloadDocument: (projectId: number, fileName: string, downloadDocumentUrl: string, bucketName: string | undefined) => Promise<void>;
|
|
9
|
-
export declare const ClientDisputeProjectCard: ({ clientInvoice, updateClientInvoiceDisputeMutation, documentUploadUrl, downloadDocumentUrl, bucketName }: ClientDisputeProjectCardProps) => JSX.Element;
|
|
10
|
+
export declare const ClientDisputeProjectCard: ({ clientInvoice, updateClientInvoiceDisputeMutation, documentUploadUrl, downloadDocumentUrl, bucketName, uploadExpertClientFiles }: ClientDisputeProjectCardProps) => JSX.Element;
|
|
10
11
|
export {};
|
|
@@ -145,7 +145,7 @@ const handleDownloadDocument = (projectId, fileName, downloadDocumentUrl, bucket
|
|
|
145
145
|
});
|
|
146
146
|
});
|
|
147
147
|
exports.handleDownloadDocument = handleDownloadDocument;
|
|
148
|
-
const ClientDisputeProjectCard = ({ clientInvoice, updateClientInvoiceDisputeMutation, documentUploadUrl, downloadDocumentUrl, bucketName }) => {
|
|
148
|
+
const ClientDisputeProjectCard = ({ clientInvoice, updateClientInvoiceDisputeMutation, documentUploadUrl, downloadDocumentUrl, bucketName, uploadExpertClientFiles }) => {
|
|
149
149
|
const [expandRow, setExpandRow] = (0, react_1.useState)(null);
|
|
150
150
|
const classes = useStyles();
|
|
151
151
|
const [projects, setProjects] = (0, react_1.useState)(clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects);
|
|
@@ -192,7 +192,7 @@ const ClientDisputeProjectCard = ({ clientInvoice, updateClientInvoiceDisputeMut
|
|
|
192
192
|
return new Promise((resolve, reject) => {
|
|
193
193
|
const reader = new FileReader();
|
|
194
194
|
reader.onloadend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
195
|
-
var _a, _b, _c, _d, _e;
|
|
195
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
196
196
|
try {
|
|
197
197
|
const res = yield (0, FileUploader_1.fileUploader)({
|
|
198
198
|
file: selectedFile,
|
|
@@ -204,6 +204,15 @@ const ClientDisputeProjectCard = ({ clientInvoice, updateClientInvoiceDisputeMut
|
|
|
204
204
|
updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation,
|
|
205
205
|
previousFiles: (_e = (_d = (_c = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.clientDocumentLinks) !== null && _e !== void 0 ? _e : [],
|
|
206
206
|
isExpert: false,
|
|
207
|
+
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
208
|
+
disputeData: {
|
|
209
|
+
clientId: (_f = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.invoice) === null || _f === void 0 ? void 0 : _f.clientId,
|
|
210
|
+
clientName: (_g = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.client) === null || _g === void 0 ? void 0 : _g.name,
|
|
211
|
+
email: (_h = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.freelancer) === null || _h === void 0 ? void 0 : _h.email,
|
|
212
|
+
freelancerId: clientInvoice.freelancerId,
|
|
213
|
+
freelancerName: ((_j = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.freelancer) === null || _j === void 0 ? void 0 : _j.firstName) + ' ' + ((_k = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.freelancer) === null || _k === void 0 ? void 0 : _k.lastName),
|
|
214
|
+
projectName: (_o = (_m = (_l = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.project) === null || _o === void 0 ? void 0 : _o.name
|
|
215
|
+
}
|
|
207
216
|
});
|
|
208
217
|
if (res) {
|
|
209
218
|
setProjects((prevProjects) => prevProjects.map((p) => {
|
|
@@ -6,6 +6,7 @@ interface DecisionSectionProps {
|
|
|
6
6
|
getClientInvoiceSummaryByMonth: any;
|
|
7
7
|
invoiceSummary: any;
|
|
8
8
|
updateClientInvoiceDisputeMutation: any;
|
|
9
|
+
addClientCredit: any;
|
|
9
10
|
}
|
|
10
|
-
export declare const DecisionSection: ({ dispute, onUpdateDispute, updateInvoiceMutation, updateClientInvoiceDisputeMutation, invoiceSummary, user, getClientInvoiceSummaryByMonth, }: DecisionSectionProps) => JSX.Element;
|
|
11
|
+
export declare const DecisionSection: ({ dispute, onUpdateDispute, updateInvoiceMutation, updateClientInvoiceDisputeMutation, invoiceSummary, user, getClientInvoiceSummaryByMonth, addClientCredit }: DecisionSectionProps) => JSX.Element;
|
|
11
12
|
export {};
|
|
@@ -42,14 +42,15 @@ const RESOLUTION_OPTIONS = [
|
|
|
42
42
|
{ value: 'DECLINED', label: 'Decline Dispute' },
|
|
43
43
|
{ value: 'PARTIAL', label: 'Partial Approval' },
|
|
44
44
|
];
|
|
45
|
-
const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, updateClientInvoiceDisputeMutation, invoiceSummary, user, getClientInvoiceSummaryByMonth, }) => {
|
|
46
|
-
var _a, _b;
|
|
45
|
+
const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, updateClientInvoiceDisputeMutation, invoiceSummary, user, getClientInvoiceSummaryByMonth, addClientCredit }) => {
|
|
46
|
+
var _a, _b, _c, _d;
|
|
47
47
|
const totalDisputeHours = (_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a.reduce((acc, project) => acc + (project === null || project === void 0 ? void 0 : project.disputeHours), 0);
|
|
48
48
|
const [resolution, setResolution] = (0, react_1.useState)('');
|
|
49
49
|
const [approvedHours, setApprovedHours] = (0, react_1.useState)(totalDisputeHours);
|
|
50
50
|
const [projectApprovedHours, setProjectApprovedHours] = (0, react_1.useState)({});
|
|
51
51
|
const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false);
|
|
52
52
|
const [showHoursModal, setShowHoursModal] = (0, react_1.useState)(false);
|
|
53
|
+
const isDisputePaid = ((_b = dispute === null || dispute === void 0 ? void 0 : dispute.invoice) === null || _b === void 0 ? void 0 : _b.clientInvoiceStatusId) === 4 || ((_c = dispute === null || dispute === void 0 ? void 0 : dispute.invoice) === null || _c === void 0 ? void 0 : _c.clientInvoiceStatusId) === 8;
|
|
53
54
|
// Initialize project approved hours when resolution changes to PARTIAL
|
|
54
55
|
const handleResolutionChange = (newResolution) => {
|
|
55
56
|
var _a;
|
|
@@ -84,7 +85,6 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
|
|
|
84
85
|
const handleApproveClick = () => {
|
|
85
86
|
if (!resolution)
|
|
86
87
|
return;
|
|
87
|
-
// Show modal for PARTIAL or APPROVED resolutions regardless of dispute type
|
|
88
88
|
if (resolution === 'PARTIAL' || resolution === 'APPROVED') {
|
|
89
89
|
setShowHoursModal(true);
|
|
90
90
|
}
|
|
@@ -100,19 +100,13 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
|
|
|
100
100
|
var _a, _b, _c;
|
|
101
101
|
setIsSubmitting(true);
|
|
102
102
|
try {
|
|
103
|
-
const resolutionType = resolution === 'APPROVED' ? 'Upheld' : 'Reduced';
|
|
104
|
-
const disputeProjectUpdates = ((_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a.map((project) => ({
|
|
105
|
-
projectId: project.projectId,
|
|
106
|
-
resolutionMode: 'Direct',
|
|
107
|
-
resolutionType: resolution === 'DECLINED' ? 'Canceled' : resolutionType
|
|
108
|
-
}))) || [];
|
|
109
103
|
let calculatedApprovedAmount = 0;
|
|
110
|
-
const fullDisputeAmount = (
|
|
104
|
+
const fullDisputeAmount = (_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a.reduce((acc, project) => acc + project.disputeAmount, 0);
|
|
111
105
|
if (resolution === 'APPROVED') {
|
|
112
106
|
calculatedApprovedAmount = fullDisputeAmount;
|
|
113
107
|
}
|
|
114
108
|
else {
|
|
115
|
-
(
|
|
109
|
+
(_b = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _b === void 0 ? void 0 : _b.forEach((project) => {
|
|
116
110
|
var _a, _b;
|
|
117
111
|
const approvedForProject = projectApprovedHours[project.projectId] || 0;
|
|
118
112
|
if (project.disputeType === 'Hourly') {
|
|
@@ -124,6 +118,50 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
|
|
|
124
118
|
}
|
|
125
119
|
});
|
|
126
120
|
}
|
|
121
|
+
if (submissionData) {
|
|
122
|
+
if (isDisputePaid) {
|
|
123
|
+
yield addClientCredit({
|
|
124
|
+
variables: {
|
|
125
|
+
input: {
|
|
126
|
+
clientId: submissionData.clientId,
|
|
127
|
+
amount: calculatedApprovedAmount,
|
|
128
|
+
description: `Credit from Dispute #${dispute.disputeId} - Invoice #${dispute.invoice.id}`,
|
|
129
|
+
updatedDate: new Date().toISOString()
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
yield updateInvoiceMutation({
|
|
136
|
+
variables: {
|
|
137
|
+
input: submissionData.input,
|
|
138
|
+
clientId: submissionData.clientId,
|
|
139
|
+
invoiceId: submissionData.invoiceId,
|
|
140
|
+
dateGenerated: submissionData.dateGenerated,
|
|
141
|
+
updateDescription: submissionData.updateDescription,
|
|
142
|
+
freelancerIds: submissionData.freelancerIds
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
let resolutionType;
|
|
148
|
+
if (isDisputePaid) {
|
|
149
|
+
resolutionType = 'FutureCredit';
|
|
150
|
+
}
|
|
151
|
+
else if (resolution === 'APPROVED') {
|
|
152
|
+
resolutionType = 'Upheld';
|
|
153
|
+
}
|
|
154
|
+
else if (resolution === 'PARTIAL') {
|
|
155
|
+
resolutionType = 'Reduced';
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
resolutionType = 'Canceled';
|
|
159
|
+
}
|
|
160
|
+
const disputeProjectUpdates = ((_c = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _c === void 0 ? void 0 : _c.map((project) => ({
|
|
161
|
+
projectId: project.projectId,
|
|
162
|
+
resolutionMode: 'Direct',
|
|
163
|
+
resolutionType: resolutionType
|
|
164
|
+
}))) || [];
|
|
127
165
|
const updateData = {
|
|
128
166
|
disputeId: dispute.disputeId,
|
|
129
167
|
status: "Resolved",
|
|
@@ -131,24 +169,17 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
|
|
|
131
169
|
finalDecisionOwnerId: (user === null || user === void 0 ? void 0 : user.userId) || null,
|
|
132
170
|
projectDisputes: disputeProjectUpdates
|
|
133
171
|
};
|
|
134
|
-
if (submissionData) {
|
|
135
|
-
yield updateInvoiceMutation({
|
|
136
|
-
variables: {
|
|
137
|
-
input: submissionData.input,
|
|
138
|
-
clientId: submissionData.clientId,
|
|
139
|
-
invoiceId: submissionData.invoiceId,
|
|
140
|
-
dateGenerated: submissionData.dateGenerated,
|
|
141
|
-
updateDescription: submissionData.updateDescription,
|
|
142
|
-
freelancerIds: submissionData.freelancerIds
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
172
|
yield onUpdateDispute({
|
|
147
173
|
variables: {
|
|
148
174
|
input: updateData,
|
|
149
175
|
},
|
|
150
176
|
});
|
|
151
|
-
(
|
|
177
|
+
if (isDisputePaid) {
|
|
178
|
+
(0, utils_1.showToast)('success', `Future credit applied: $${calculatedApprovedAmount} to Client ${dispute.client.name}'s balance`);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
(0, utils_1.showToast)('success', 'Thank you for resolving the dispute. The invoice has been updated with the new hours.');
|
|
182
|
+
}
|
|
152
183
|
}
|
|
153
184
|
catch (error) {
|
|
154
185
|
console.error('Failed to update dispute:', error);
|
|
@@ -158,7 +189,7 @@ const DecisionSection = ({ dispute, onUpdateDispute, updateInvoiceMutation, upda
|
|
|
158
189
|
setIsSubmitting(false);
|
|
159
190
|
}
|
|
160
191
|
});
|
|
161
|
-
const isPartialWithMultipleProjects = resolution === 'PARTIAL' && ((
|
|
192
|
+
const isPartialWithMultipleProjects = resolution === 'PARTIAL' && ((_d = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _d === void 0 ? void 0 : _d.length) > 0;
|
|
162
193
|
const isValidPartialApproval = () => {
|
|
163
194
|
if (resolution !== 'PARTIAL')
|
|
164
195
|
return true;
|
|
@@ -5,6 +5,8 @@ interface DisputeSectionProps {
|
|
|
5
5
|
bucketName: string;
|
|
6
6
|
isInternal: boolean;
|
|
7
7
|
updateClientInvoiceDisputeMutation: (variables: any) => Promise<any>;
|
|
8
|
+
uploadExpertClientFiles: (variables: any) => Promise<any>;
|
|
9
|
+
hasDisputeAdminRole?: boolean;
|
|
8
10
|
}
|
|
9
|
-
export declare const DisputeSection: ({ dispute, documentUploadUrl, downloadDocumentUrl, bucketName, isInternal, updateClientInvoiceDisputeMutation, }: DisputeSectionProps) => JSX.Element;
|
|
11
|
+
export declare const DisputeSection: ({ dispute, documentUploadUrl, downloadDocumentUrl, bucketName, isInternal, updateClientInvoiceDisputeMutation, uploadExpertClientFiles, hasDisputeAdminRole }: DisputeSectionProps) => JSX.Element;
|
|
10
12
|
export {};
|
|
@@ -47,7 +47,7 @@ const ACCEPTED_FILE_TYPES = [
|
|
|
47
47
|
'image/png',
|
|
48
48
|
'text/csv',
|
|
49
49
|
];
|
|
50
|
-
const DisputeSection = ({ dispute, documentUploadUrl, downloadDocumentUrl, bucketName, isInternal, updateClientInvoiceDisputeMutation, }) => {
|
|
50
|
+
const DisputeSection = ({ dispute, documentUploadUrl, downloadDocumentUrl, bucketName, isInternal, updateClientInvoiceDisputeMutation, uploadExpertClientFiles, hasDisputeAdminRole }) => {
|
|
51
51
|
var _a, _b, _c;
|
|
52
52
|
const expertFileInputRef = (0, react_1.useRef)(null);
|
|
53
53
|
const clientFileInputRef = (0, react_1.useRef)(null);
|
|
@@ -74,7 +74,7 @@ const DisputeSection = ({ dispute, documentUploadUrl, downloadDocumentUrl, bucke
|
|
|
74
74
|
Array.from(selectedFiles).forEach((selectedFile) => {
|
|
75
75
|
const reader = new FileReader();
|
|
76
76
|
reader.onloadend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
-
var _a, _b;
|
|
77
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
78
78
|
yield (0, FileUploader_1.fileUploader)({
|
|
79
79
|
file: selectedFile,
|
|
80
80
|
documentName: selectedFile.name,
|
|
@@ -82,9 +82,18 @@ const DisputeSection = ({ dispute, documentUploadUrl, downloadDocumentUrl, bucke
|
|
|
82
82
|
documentUploadUrl: documentUploadUrl,
|
|
83
83
|
bucketName: bucketName,
|
|
84
84
|
updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation,
|
|
85
|
+
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
85
86
|
disputeId: dispute === null || dispute === void 0 ? void 0 : dispute.disputeId,
|
|
86
87
|
previousFiles: isExpert ? expertDocumentLinks : clientDocumentLinks,
|
|
87
88
|
isExpert: isExpert,
|
|
89
|
+
disputeData: {
|
|
90
|
+
clientId: (_c = dispute === null || dispute === void 0 ? void 0 : dispute.invoice) === null || _c === void 0 ? void 0 : _c.clientId,
|
|
91
|
+
clientName: (_d = dispute === null || dispute === void 0 ? void 0 : dispute.client) === null || _d === void 0 ? void 0 : _d.name,
|
|
92
|
+
email: (_e = dispute === null || dispute === void 0 ? void 0 : dispute.freelancer) === null || _e === void 0 ? void 0 : _e.email,
|
|
93
|
+
freelancerId: dispute === null || dispute === void 0 ? void 0 : dispute.freelancerId,
|
|
94
|
+
freelancerName: `${(_f = dispute === null || dispute === void 0 ? void 0 : dispute.freelancer) === null || _f === void 0 ? void 0 : _f.firstName} ${(_g = dispute === null || dispute === void 0 ? void 0 : dispute.freelancer) === null || _g === void 0 ? void 0 : _g.lastName}`,
|
|
95
|
+
projectName: (_h = disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.project) === null || _h === void 0 ? void 0 : _h.name,
|
|
96
|
+
},
|
|
88
97
|
});
|
|
89
98
|
});
|
|
90
99
|
reader.readAsDataURL(selectedFile);
|
|
@@ -123,7 +132,7 @@ const DisputeSection = ({ dispute, documentUploadUrl, downloadDocumentUrl, bucke
|
|
|
123
132
|
}
|
|
124
133
|
} })))),
|
|
125
134
|
react_1.default.createElement("div", { className: "w-full mt-2" },
|
|
126
|
-
react_1.default.createElement(base_ui_1.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = clientFileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]", disabled: isInternal })))))),
|
|
135
|
+
react_1.default.createElement(base_ui_1.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = clientFileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]", disabled: isInternal && !hasDisputeAdminRole })))))),
|
|
127
136
|
react_1.default.createElement("div", { className: "space-y-4" },
|
|
128
137
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
129
138
|
react_1.default.createElement("div", { className: "text-lg font-bold text-[#333333]" }, "Expert Rebuttal")),
|
|
@@ -146,6 +155,6 @@ const DisputeSection = ({ dispute, documentUploadUrl, downloadDocumentUrl, bucke
|
|
|
146
155
|
}
|
|
147
156
|
} })))),
|
|
148
157
|
react_1.default.createElement("div", { className: "w-full mt-2" },
|
|
149
|
-
react_1.default.createElement(base_ui_1.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = expertFileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]", disabled: isInternal }))))))));
|
|
158
|
+
react_1.default.createElement(base_ui_1.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = expertFileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]", disabled: isInternal && !hasDisputeAdminRole }))))))));
|
|
150
159
|
};
|
|
151
160
|
exports.DisputeSection = DisputeSection;
|
|
@@ -13,7 +13,9 @@ interface InvoiceCardProps {
|
|
|
13
13
|
isClient?: boolean;
|
|
14
14
|
bucketName?: string;
|
|
15
15
|
reactAppUrl?: string;
|
|
16
|
+
addClientCredit?: any;
|
|
16
17
|
isLateDisputeAllowed?: boolean;
|
|
18
|
+
uploadExpertClientFiles?: any;
|
|
17
19
|
}
|
|
18
|
-
export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceDisputeMutation, updateInvoiceMutation, getClientInvoiceSummaryByMonth, invoiceSummary, documentUploadUrl, downloadDocumentUrl, isInternal, isClient, bucketName, reactAppUrl,
|
|
20
|
+
export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceDisputeMutation, uploadExpertClientFiles, updateInvoiceMutation, getClientInvoiceSummaryByMonth, invoiceSummary, documentUploadUrl, downloadDocumentUrl, isInternal, isClient, bucketName, reactAppUrl, addClientCredit, isLateDisputeAllowed }: InvoiceCardProps) => JSX.Element;
|
|
19
21
|
export {};
|
|
@@ -34,12 +34,16 @@ const DisputeSection_1 = require("./DisputeSection");
|
|
|
34
34
|
const DiscussionSection_1 = require("./DiscussionSection");
|
|
35
35
|
const DecisionSection_1 = require("./DecisionSection");
|
|
36
36
|
const ClientDisputeProjectCard_1 = require("./ClientDisputeProjectCard");
|
|
37
|
-
const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceDisputeMutation, updateInvoiceMutation, getClientInvoiceSummaryByMonth, invoiceSummary, documentUploadUrl, downloadDocumentUrl, isInternal = false, isClient = false, bucketName, reactAppUrl, isLateDisputeAllowed = false
|
|
37
|
+
const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceDisputeMutation, uploadExpertClientFiles, updateInvoiceMutation, getClientInvoiceSummaryByMonth, invoiceSummary, documentUploadUrl, downloadDocumentUrl, isInternal = false, isClient = false, bucketName, reactAppUrl, addClientCredit, isLateDisputeAllowed = false }) => {
|
|
38
|
+
var _a;
|
|
39
|
+
const envUrl = reactAppUrl === null || reactAppUrl === void 0 ? void 0 : reactAppUrl.split('.')[1];
|
|
40
|
+
const rolesUrl = `https://app.${envUrl}.io/roles`;
|
|
38
41
|
const [currentInvoice, setCurrentInvoice] = (0, react_1.useState)(clientInvoice);
|
|
39
42
|
(0, react_1.useEffect)(() => {
|
|
40
43
|
setCurrentInvoice(clientInvoice);
|
|
41
44
|
}, [clientInvoice]);
|
|
42
45
|
const disputeId = currentInvoice === null || currentInvoice === void 0 ? void 0 : currentInvoice.disputeId;
|
|
46
|
+
const hasDisputeAdminRole = (_a = user === null || user === void 0 ? void 0 : user[rolesUrl]) === null || _a === void 0 ? void 0 : _a.includes('disputes_admin');
|
|
43
47
|
return (react_1.default.createElement(base_ui_1.Card, { className: "w-full bg-white rounded-lg shadow-sm overflow-hidden mb-4" },
|
|
44
48
|
react_1.default.createElement(core_1.Accordion, null,
|
|
45
49
|
react_1.default.createElement(core_1.AccordionSummary, { expandIcon: react_1.default.createElement(base_icons_1.IconChevronDown, null), "aria-controls": "invoice-content", id: "invoice-header" },
|
|
@@ -48,11 +52,11 @@ const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user, chatMessag
|
|
|
48
52
|
react_1.default.createElement("div", { className: "p-6 space-y-6 w-full" },
|
|
49
53
|
react_1.default.createElement(InvoiceDetails_1.InvoiceDetails, { invoice: currentInvoice, isInternal: isInternal, isClient: isClient, reactAppUrl: reactAppUrl, isLateDisputeAllowed: isLateDisputeAllowed }),
|
|
50
54
|
isInternal ?
|
|
51
|
-
react_1.default.createElement(DisputeSection_1.DisputeSection, { dispute: currentInvoice, documentUploadUrl: documentUploadUrl, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation, downloadDocumentUrl: downloadDocumentUrl, bucketName: bucketName, isInternal: isInternal })
|
|
55
|
+
react_1.default.createElement(DisputeSection_1.DisputeSection, { dispute: currentInvoice, documentUploadUrl: documentUploadUrl, uploadExpertClientFiles: uploadExpertClientFiles, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation, downloadDocumentUrl: downloadDocumentUrl, bucketName: bucketName, isInternal: isInternal, hasDisputeAdminRole: hasDisputeAdminRole })
|
|
52
56
|
:
|
|
53
|
-
react_1.default.createElement(ClientDisputeProjectCard_1.ClientDisputeProjectCard, { clientInvoice: currentInvoice, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation, documentUploadUrl: documentUploadUrl, downloadDocumentUrl: downloadDocumentUrl, bucketName: bucketName }),
|
|
57
|
+
react_1.default.createElement(ClientDisputeProjectCard_1.ClientDisputeProjectCard, { clientInvoice: currentInvoice, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation, documentUploadUrl: documentUploadUrl, downloadDocumentUrl: downloadDocumentUrl, bucketName: bucketName, uploadExpertClientFiles: uploadExpertClientFiles }),
|
|
54
58
|
(currentInvoice === null || currentInvoice === void 0 ? void 0 : currentInvoice.chatEnabled) && disputeId && (react_1.default.createElement(DiscussionSection_1.DiscussionSection, { disputeId: disputeId, currentUser: user, messages: chatMessages, onCreateMessage: createDisputeChatMessage, isInternal: isInternal })),
|
|
55
|
-
isInternal &&
|
|
56
|
-
react_1.default.createElement(DecisionSection_1.DecisionSection, { dispute: currentInvoice, onUpdateDispute: updateClientInvoiceDisputeMutation, updateInvoiceMutation: updateInvoiceMutation, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation, invoiceSummary: invoiceSummary, user: user, getClientInvoiceSummaryByMonth: getClientInvoiceSummaryByMonth }))))));
|
|
59
|
+
isInternal && hasDisputeAdminRole &&
|
|
60
|
+
react_1.default.createElement(DecisionSection_1.DecisionSection, { dispute: currentInvoice, onUpdateDispute: updateClientInvoiceDisputeMutation, updateInvoiceMutation: updateInvoiceMutation, updateClientInvoiceDisputeMutation: updateClientInvoiceDisputeMutation, invoiceSummary: invoiceSummary, user: user, getClientInvoiceSummaryByMonth: getClientInvoiceSummaryByMonth, addClientCredit: addClientCredit }))))));
|
|
57
61
|
};
|
|
58
62
|
exports.InvoiceCard = InvoiceCard;
|
|
@@ -40,9 +40,9 @@ const InvoiceDetails = ({ invoice, isInternal = false, isClient = false, reactAp
|
|
|
40
40
|
const internalInvoiceUrl = `${reactAppUrl}/client/${(_d = invoice === null || invoice === void 0 ? void 0 : invoice.invoice) === null || _d === void 0 ? void 0 : _d.clientId}/invoices/${(_e = invoice === null || invoice === void 0 ? void 0 : invoice.invoice) === null || _e === void 0 ? void 0 : _e.id}?month=${(_f = invoice === null || invoice === void 0 ? void 0 : invoice.invoice) === null || _f === void 0 ? void 0 : _f.month}`;
|
|
41
41
|
const today = (0, dayjs_1.default)();
|
|
42
42
|
const firstDayOfMonth = (0, dayjs_1.default)().startOf('month');
|
|
43
|
-
const disputeDaysLeft =
|
|
43
|
+
const disputeDaysLeft = 14 - today.diff(firstDayOfMonth, 'day');
|
|
44
44
|
const daysLeft = disputeDaysLeft > 0;
|
|
45
|
-
const editableDate = (0, dayjs_1.default)().date(
|
|
45
|
+
const editableDate = (0, dayjs_1.default)().date(14).format("MMM DD");
|
|
46
46
|
return (react_1.default.createElement("div", { className: "space-y-6" },
|
|
47
47
|
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
48
48
|
react_1.default.createElement(base_ui_1.Tag, { color: (0, exports.getStatusColor)(invoice === null || invoice === void 0 ? void 0 : invoice.status), label: (0, exports.getStatusText)(invoice === null || invoice === void 0 ? void 0 : invoice.status), borderRadius: "full", variant: "subtle" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const TestDecisionSection: () => JSX.Element;
|
|
1
|
+
export declare const TestDecisionSection: () => JSX.Element;
|