@paro.io/expert-shared-components 1.12.51 → 1.12.53
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/lib/components/Escalations/AccountSuspensionBanner.js +2 -5
- package/lib/components/Escalations/EscalationChat.js +50 -56
- package/lib/components/Escalations/EscalationIssueCard.js +2 -2
- package/lib/components/Escalations/EscalationRespondForm.js +52 -58
- package/lib/components/Escalations/EscalationSubmitForm.js +58 -60
- package/lib/components/Escalations/MarkResolvedModal.js +1 -1
- package/lib/components/Escalations/ViewResponseModal.d.ts +8 -0
- package/lib/components/Escalations/ViewResponseModal.js +27 -0
- package/package.json +1 -1
|
@@ -13,15 +13,12 @@ const AccountSuspensionBanner = ({ setShowSuspensionModal, suspended = false })
|
|
|
13
13
|
react_1.default.createElement(base_icons_1.IconExclamation, { className: "h-6 w-6 text-white" })),
|
|
14
14
|
react_1.default.createElement("div", { className: "flex-1" },
|
|
15
15
|
react_1.default.createElement("h3", { className: "text-lg font-bold text-white" }, "\uD83D\uDEAB Account Suspended"),
|
|
16
|
-
react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" }, "Your account has been suspended due to escalation
|
|
16
|
+
react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" }, "Your account has been suspended due to an escalation. You must complete comprehensive training to regain access to new opportunities."),
|
|
17
17
|
react_1.default.createElement("div", { className: "mt-3 bg-white bg-opacity-10 rounded p-3" },
|
|
18
18
|
react_1.default.createElement("div", { className: "flex items-center justify-between text-sm" },
|
|
19
19
|
react_1.default.createElement("div", null,
|
|
20
20
|
react_1.default.createElement("span", { className: "text-red-100" }, "Suspension: "),
|
|
21
|
-
react_1.default.createElement("span", { className: "text-white font-medium" }, "30 days (Medium Severity)"))
|
|
22
|
-
react_1.default.createElement("div", null,
|
|
23
|
-
react_1.default.createElement("span", { className: "text-red-100" }, "Started: "),
|
|
24
|
-
react_1.default.createElement("span", { className: "text-white font-medium" }, "May 29, 2025"))))))
|
|
21
|
+
react_1.default.createElement("span", { className: "text-white font-medium" }, "30 days (Medium Severity)"))))))
|
|
25
22
|
:
|
|
26
23
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
27
24
|
react_1.default.createElement("div", { className: "flex items-center" },
|
|
@@ -48,66 +48,60 @@ const EscalationChat = ({ activeChatIssue, showEscalationChat, setShowEscalation
|
|
|
48
48
|
const [uploadingFile, setUploadingFile] = (0, react_1.useState)(false);
|
|
49
49
|
const fileInputRef = (0, react_1.useRef)(null);
|
|
50
50
|
const handleFileUpload = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
-
const selectedFiles = event.target.files;
|
|
52
|
-
if (!selectedFiles)
|
|
53
|
-
return;
|
|
54
51
|
setUploadingFile(true);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (validFileNames && validFileNames.length > 0) {
|
|
61
|
-
const uploadPromises = Array.from(selectedFiles).map((selectedFile) => {
|
|
62
|
-
return new Promise((resolve, reject) => {
|
|
63
|
-
const reader = new FileReader();
|
|
64
|
-
reader.onloadend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
66
|
-
try {
|
|
67
|
-
const res = yield (0, FileUploader_1.fileUploader)({
|
|
68
|
-
file: selectedFile,
|
|
69
|
-
documentName: selectedFile.name,
|
|
70
|
-
escalationId: activeChatIssue.escalationId,
|
|
71
|
-
projectId: activeChatIssue.projectDetails.length > 0 ? activeChatIssue.projectDetails[0].projectId : '',
|
|
72
|
-
documentUploadUrl: documentUploadUrl,
|
|
73
|
-
bucketName: bucketName,
|
|
74
|
-
isExpert: false,
|
|
75
|
-
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
76
|
-
createProjectEscalation: createProjectEscalation,
|
|
77
|
-
extraData: {
|
|
78
|
-
clientId: (_a = activeChatIssue.client.id) !== null && _a !== void 0 ? _a : 0,
|
|
79
|
-
clientName: (_b = activeChatIssue.client.name) !== null && _b !== void 0 ? _b : '',
|
|
80
|
-
email: isExpert ? (_e = (_d = (_c = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.client) === null || _c === void 0 ? void 0 : _c.primaryContact) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : '' : (_f = user === null || user === void 0 ? void 0 : user.email) !== null && _f !== void 0 ? _f : '',
|
|
81
|
-
freelancerId: (_g = activeChatIssue.freelancer.id) !== null && _g !== void 0 ? _g : 0,
|
|
82
|
-
freelancerName: (_h = activeChatIssue.freelancer.name) !== null && _h !== void 0 ? _h : '',
|
|
83
|
-
projectName: activeChatIssue.projectDetails.length > 0 ? activeChatIssue.projectDetails[0].projectName : '',
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
if (res) {
|
|
87
|
-
setUploadFiles(prev => [...prev, ...res]);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
console.error("faile upload failed", error);
|
|
92
|
-
}
|
|
93
|
-
finally {
|
|
94
|
-
resolve();
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
reader.readAsDataURL(selectedFile);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
try {
|
|
101
|
-
const res = yield Promise.all(uploadPromises);
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
console.error('Error uploading files:', error);
|
|
52
|
+
try {
|
|
53
|
+
const selectedFiles = event.target.files;
|
|
54
|
+
if (!selectedFiles) {
|
|
55
|
+
setUploadingFile(false);
|
|
56
|
+
return;
|
|
105
57
|
}
|
|
106
|
-
|
|
58
|
+
const validFiles = Array.from(selectedFiles).filter(file => (0, EscalationRespondForm_1.validateFileUpload)(file));
|
|
59
|
+
if (validFiles.length === 0) {
|
|
107
60
|
setUploadingFile(false);
|
|
61
|
+
return;
|
|
108
62
|
}
|
|
63
|
+
const uploadPromises = validFiles.map((selectedFile) => {
|
|
64
|
+
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
66
|
+
try {
|
|
67
|
+
const res = yield (0, FileUploader_1.fileUploader)({
|
|
68
|
+
file: selectedFile,
|
|
69
|
+
documentName: selectedFile.name,
|
|
70
|
+
escalationId: activeChatIssue.escalationId,
|
|
71
|
+
projectId: activeChatIssue.projectDetails.length > 0 ? activeChatIssue.projectDetails[0].projectId : '',
|
|
72
|
+
documentUploadUrl: documentUploadUrl,
|
|
73
|
+
bucketName: bucketName,
|
|
74
|
+
previousFiles: isExpert ? activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.clientDocumentLinks : activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.expertDocumentlinks,
|
|
75
|
+
isExpert: isExpert,
|
|
76
|
+
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
77
|
+
createProjectEscalation: createProjectEscalation,
|
|
78
|
+
extraData: {
|
|
79
|
+
clientId: isExpert ? (_b = (_a = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.client) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 0 : (_d = (_c = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.client) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : 0,
|
|
80
|
+
clientName: isExpert ? (_f = (_e = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.client) === null || _e === void 0 ? void 0 : _e.name) !== null && _f !== void 0 ? _f : '' : (_g = user === null || user === void 0 ? void 0 : user.name) !== null && _g !== void 0 ? _g : '',
|
|
81
|
+
email: isExpert ? (_k = (_j = (_h = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.client) === null || _h === void 0 ? void 0 : _h.primaryContact) === null || _j === void 0 ? void 0 : _j.email) !== null && _k !== void 0 ? _k : '' : (_m = (_l = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.freelancer) === null || _l === void 0 ? void 0 : _l.email) !== null && _m !== void 0 ? _m : '',
|
|
82
|
+
freelancerId: isExpert ? (_o = user === null || user === void 0 ? void 0 : user.userId) !== null && _o !== void 0 ? _o : 0 : (_q = (_p = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.freelancer) === null || _p === void 0 ? void 0 : _p.id) !== null && _q !== void 0 ? _q : 0,
|
|
83
|
+
freelancerName: isExpert ? (_r = user === null || user === void 0 ? void 0 : user.name) !== null && _r !== void 0 ? _r : '' : (_t = (_s = activeChatIssue === null || activeChatIssue === void 0 ? void 0 : activeChatIssue.freelancer) === null || _s === void 0 ? void 0 : _s.name) !== null && _t !== void 0 ? _t : '',
|
|
84
|
+
projectName: activeChatIssue.projectDetails.length > 0 ? activeChatIssue.projectDetails[0].projectName : '',
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
if (res) {
|
|
88
|
+
setUploadFiles(prev => [...prev, ...res]);
|
|
89
|
+
}
|
|
90
|
+
resolve();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
reject(error);
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
});
|
|
97
|
+
yield Promise.all(uploadPromises);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error('Error uploading files:', error);
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
setUploadingFile(false);
|
|
109
104
|
}
|
|
110
|
-
;
|
|
111
105
|
});
|
|
112
106
|
const docs = [activeChatIssue.expertSupportingDocuments, activeChatIssue.clientSupportingDocuments, activeChatIssue.internalSupportingDocuments, ...uploadFiles];
|
|
113
107
|
const processedDocs = docs
|
|
@@ -144,7 +138,7 @@ const EscalationChat = ({ activeChatIssue, showEscalationChat, setShowEscalation
|
|
|
144
138
|
react_1.default.createElement("div", { className: "space-y-3" },
|
|
145
139
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
146
140
|
react_1.default.createElement("div", { className: "flex items-center space-x-2" },
|
|
147
|
-
react_1.default.createElement("input", { id: "upload-file", type: "file", multiple:
|
|
141
|
+
react_1.default.createElement("input", { id: "upload-file", type: "file", multiple: false, accept: ".pdf,.doc,.docx,.jpeg,.png,.gif,.csv,.xslx", style: { display: 'none' }, ref: fileInputRef, onChange: handleFileUpload }),
|
|
148
142
|
react_1.default.createElement(base_ui_1.Button, { label: "Attach Files", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, color: "info", className: "mx-2", isLoading: uploadingFile })),
|
|
149
143
|
react_1.default.createElement("div", { className: "flex space-x-2" },
|
|
150
144
|
react_1.default.createElement(base_ui_1.Button, { label: "cancel", onClick: () => setShowEscalationChat(false), disabled: uploadingFile })))))))));
|
|
@@ -32,7 +32,7 @@ const base_ui_1 = require("@paro.io/base-ui");
|
|
|
32
32
|
const ClientDisputeProjectCard_1 = require("../Invoices/ClientDisputeProjectCard");
|
|
33
33
|
const base_icons_1 = require("@paro.io/base-icons");
|
|
34
34
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
35
|
-
const
|
|
35
|
+
const ViewResponseModal_1 = __importDefault(require("./ViewResponseModal"));
|
|
36
36
|
const MarkResolvedModal_1 = __importDefault(require("./MarkResolvedModal"));
|
|
37
37
|
const getBackgroundColor = (type) => {
|
|
38
38
|
switch (type) {
|
|
@@ -108,7 +108,7 @@ const EscalationIssueCard = ({ issues, isExpert, openEscalationChat, showRespond
|
|
|
108
108
|
showMarkResolvedButton && (react_1.default.createElement(base_ui_1.Button, { label: getResponseButtonText(issue), onClick: () => { setViewResponseModal(issue); }, color: 'primary', disabled: getResponseButtonText(issue) === 'Awaiting Response' })),
|
|
109
109
|
showMarkResolvedButton && !isExpert && (react_1.default.createElement(base_ui_1.Button, { onClick: () => { setMarkAsResolved(issue); }, label: "Mark as Resolved", color: "primary" })))));
|
|
110
110
|
}),
|
|
111
|
-
!!viewResponseModal && react_1.default.createElement(
|
|
111
|
+
!!viewResponseModal && react_1.default.createElement(ViewResponseModal_1.default, { response: isExpert ? viewResponseModal.clientResponse : viewResponseModal.expertResponse, isExpert: isExpert, open: !!viewResponseModal, onClose: () => setViewResponseModal(null) }),
|
|
112
112
|
!!markAsResolved && react_1.default.createElement(MarkResolvedModal_1.default, { escalationId: markAsResolved.escalationId, expertName: (_b = (_a = markAsResolved === null || markAsResolved === void 0 ? void 0 : markAsResolved.freelancer) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'Expert', open: !!markAsResolved, onClose: () => setMarkAsResolved(false), updateProjectEscalation: updateProjectEscalation })));
|
|
113
113
|
};
|
|
114
114
|
exports.default = EscalationIssueCard;
|
|
@@ -46,6 +46,7 @@ exports.ACCEPTED_FILE_TYPES = [
|
|
|
46
46
|
'image/jpeg',
|
|
47
47
|
'image/png',
|
|
48
48
|
'text/csv',
|
|
49
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
49
50
|
];
|
|
50
51
|
const validateFileUpload = (file) => {
|
|
51
52
|
if (!file) {
|
|
@@ -85,67 +86,60 @@ const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downl
|
|
|
85
86
|
const [submitting, setSubmitting] = (0, react_1.useState)(false);
|
|
86
87
|
const fileInputRef = (0, react_1.useRef)(null);
|
|
87
88
|
const handleFileUpload = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
-
const selectedFiles = event.target.files;
|
|
89
|
-
if (!selectedFiles)
|
|
90
|
-
return;
|
|
91
89
|
setUploadingFile(true);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (validFileNames && validFileNames.length > 0) {
|
|
98
|
-
const uploadPromises = Array.from(selectedFiles).map((selectedFile) => {
|
|
99
|
-
return new Promise((resolve, reject) => {
|
|
100
|
-
const reader = new FileReader();
|
|
101
|
-
reader.onloadend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
103
|
-
try {
|
|
104
|
-
const res = yield (0, FileUploader_1.fileUploader)({
|
|
105
|
-
file: selectedFile,
|
|
106
|
-
documentName: selectedFile.name,
|
|
107
|
-
escalationId: selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.escalationId,
|
|
108
|
-
projectId: selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.projectDetails[0].projectId,
|
|
109
|
-
documentUploadUrl: documentUploadUrl,
|
|
110
|
-
bucketName: bucketName,
|
|
111
|
-
previousFiles: (selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.isExpert) ? (_a = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.clientDocumentLinks) !== null && _a !== void 0 ? _a : [] : selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.expertDocumentlinks,
|
|
112
|
-
isExpert: false,
|
|
113
|
-
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
114
|
-
updateProjectEscalation: updateProjectEscalation,
|
|
115
|
-
extraData: {
|
|
116
|
-
clientId: selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.client.id,
|
|
117
|
-
clientName: (_b = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.client.name) !== null && _b !== void 0 ? _b : '',
|
|
118
|
-
email: isExpert ? (_d = (_c = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.freelancer) === null || _c === void 0 ? void 0 : _c.email) !== null && _d !== void 0 ? _d : '' : (_g = (_f = (_e = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.client) === null || _e === void 0 ? void 0 : _e.primaryContact) === null || _f === void 0 ? void 0 : _f.email) !== null && _g !== void 0 ? _g : '',
|
|
119
|
-
freelancerId: selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.freelancer.id,
|
|
120
|
-
freelancerName: (_h = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.freelancer.name) !== null && _h !== void 0 ? _h : '',
|
|
121
|
-
projectName: selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.projectDetails[0].projectName,
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
if (res) {
|
|
125
|
-
setUploadFiles(prev => [...prev, ...res]);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
console.error("Failed to upload file", error);
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
resolve();
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
reader.readAsDataURL(selectedFile);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
try {
|
|
139
|
-
yield Promise.all(uploadPromises);
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
console.error('Error uploading files:', error);
|
|
90
|
+
try {
|
|
91
|
+
const selectedFiles = event.target.files;
|
|
92
|
+
if (!selectedFiles) {
|
|
93
|
+
setUploadingFile(false);
|
|
94
|
+
return;
|
|
143
95
|
}
|
|
144
|
-
|
|
96
|
+
const validFiles = Array.from(selectedFiles).filter(file => (0, exports.validateFileUpload)(file));
|
|
97
|
+
if (validFiles.length === 0) {
|
|
145
98
|
setUploadingFile(false);
|
|
99
|
+
return;
|
|
146
100
|
}
|
|
101
|
+
const uploadPromises = validFiles.map((selectedFile) => {
|
|
102
|
+
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
104
|
+
try {
|
|
105
|
+
const res = yield (0, FileUploader_1.fileUploader)({
|
|
106
|
+
file: selectedFile,
|
|
107
|
+
documentName: selectedFile.name,
|
|
108
|
+
escalationId: selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.escalationId,
|
|
109
|
+
projectId: (_b = (_a = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.projectDetails) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.projectId,
|
|
110
|
+
documentUploadUrl: documentUploadUrl,
|
|
111
|
+
bucketName: bucketName,
|
|
112
|
+
previousFiles: isExpert ? selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.clientDocumentLinks : selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.expertDocumentlinks,
|
|
113
|
+
isExpert: isExpert,
|
|
114
|
+
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
115
|
+
updateProjectEscalation: updateProjectEscalation,
|
|
116
|
+
extraData: {
|
|
117
|
+
clientId: (_c = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.client) === null || _c === void 0 ? void 0 : _c.id,
|
|
118
|
+
clientName: (_e = (_d = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.client) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : '',
|
|
119
|
+
email: isExpert ? (_h = (_g = (_f = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.client) === null || _f === void 0 ? void 0 : _f.primaryContact) === null || _g === void 0 ? void 0 : _g.email) !== null && _h !== void 0 ? _h : '' : (_k = (_j = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.freelancer) === null || _j === void 0 ? void 0 : _j.email) !== null && _k !== void 0 ? _k : '',
|
|
120
|
+
freelancerId: (_l = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.freelancer) === null || _l === void 0 ? void 0 : _l.id,
|
|
121
|
+
freelancerName: (_o = (_m = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.freelancer) === null || _m === void 0 ? void 0 : _m.name) !== null && _o !== void 0 ? _o : '',
|
|
122
|
+
projectName: (_q = (_p = selectedIssue === null || selectedIssue === void 0 ? void 0 : selectedIssue.projectDetails) === null || _p === void 0 ? void 0 : _p[0]) === null || _q === void 0 ? void 0 : _q.projectName,
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
if (res) {
|
|
126
|
+
setUploadFiles(prev => [...prev, ...res]);
|
|
127
|
+
}
|
|
128
|
+
resolve();
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
reject(error);
|
|
132
|
+
}
|
|
133
|
+
}));
|
|
134
|
+
});
|
|
135
|
+
yield Promise.all(uploadPromises);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.error('Error uploading files:', error);
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
setUploadingFile(false);
|
|
147
142
|
}
|
|
148
|
-
;
|
|
149
143
|
});
|
|
150
144
|
const submitResponse = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
145
|
setSubmitting(true);
|
|
@@ -155,7 +149,7 @@ const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downl
|
|
|
155
149
|
input: {
|
|
156
150
|
escalationId: selectedIssue.escalationId,
|
|
157
151
|
[isExpert ? 'expertResponse' : 'clientResponse']: responseInput,
|
|
158
|
-
[isExpert ? 'expertSupportingDocuments' : 'clientSupportingDocuments']: uploadFiles.join(", "),
|
|
152
|
+
[isExpert ? 'expertSupportingDocuments' : 'clientSupportingDocuments']: uploadFiles.length > 0 ? uploadFiles.join(", ") : '',
|
|
159
153
|
}
|
|
160
154
|
}
|
|
161
155
|
});
|
|
@@ -209,7 +203,7 @@ const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downl
|
|
|
209
203
|
react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Supporting Documents (Optional)"),
|
|
210
204
|
react_1.default.createElement("div", { className: "border border-dashed border-gray-300 rounded-md p-6 text-center" },
|
|
211
205
|
react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-2" }, "Upload any supporting documentation"),
|
|
212
|
-
react_1.default.createElement("input", { id: "upload-file", type: "file", multiple:
|
|
206
|
+
react_1.default.createElement("input", { id: "upload-file", type: "file", multiple: false, accept: ".pdf,.doc,.docx,.jpeg,.png,.gif,.csv,.xslx", style: { display: 'none' }, ref: fileInputRef, onChange: handleFileUpload }),
|
|
213
207
|
react_1.default.createElement(base_ui_1.Button, { label: "Attach Files", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, color: "info", className: "mx-2", isLoading: uploadingFile, size: "sm" }),
|
|
214
208
|
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2 mt-4" },
|
|
215
209
|
react_1.default.createElement("span", { className: "text-sm font-bold text-gray-500 items-center" }, "Supporting Documents: "),
|
|
@@ -100,66 +100,59 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
100
100
|
}
|
|
101
101
|
}, [projects, selectedUser]);
|
|
102
102
|
const handleFileUpload = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
-
const selectedFiles = event.target.files;
|
|
104
|
-
if (!selectedFiles)
|
|
105
|
-
return;
|
|
106
103
|
setUploadingFile(true);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (validFileNames && validFileNames.length > 0) {
|
|
113
|
-
const uploadPromises = Array.from(selectedFiles).map((selectedFile) => {
|
|
114
|
-
return new Promise((resolve, reject) => {
|
|
115
|
-
const reader = new FileReader();
|
|
116
|
-
reader.onloadend = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
118
|
-
try {
|
|
119
|
-
const res = yield (0, FileUploader_1.fileUploader)({
|
|
120
|
-
file: selectedFile,
|
|
121
|
-
documentName: selectedFile.name,
|
|
122
|
-
escalationId: escalationId,
|
|
123
|
-
projectId: selectedProjects.length > 0 ? selectedProjects[0].id : '',
|
|
124
|
-
documentUploadUrl: documentUploadUrl,
|
|
125
|
-
bucketName: bucketName,
|
|
126
|
-
isExpert: false,
|
|
127
|
-
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
128
|
-
createProjectEscalation: createProjectEscalation,
|
|
129
|
-
extraData: {
|
|
130
|
-
clientId: isExpert ? (_a = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id) !== null && _a !== void 0 ? _a : 0 : clientId,
|
|
131
|
-
clientName: isExpert ? (_b = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) !== null && _b !== void 0 ? _b : '' : (_c = user === null || user === void 0 ? void 0 : user.name) !== null && _c !== void 0 ? _c : '',
|
|
132
|
-
email: isExpert ? (_e = (_d = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.primaryContact) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : '' : (_f = user === null || user === void 0 ? void 0 : user.email) !== null && _f !== void 0 ? _f : '',
|
|
133
|
-
freelancerId: isExpert ? (_g = user === null || user === void 0 ? void 0 : user.userId) !== null && _g !== void 0 ? _g : 0 : (_h = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id) !== null && _h !== void 0 ? _h : 0,
|
|
134
|
-
freelancerName: isExpert ? (_j = user === null || user === void 0 ? void 0 : user.name) !== null && _j !== void 0 ? _j : '' : (_k = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) !== null && _k !== void 0 ? _k : '',
|
|
135
|
-
projectName: selectedProjects.length > 0 ? selectedProjects[0].name : '',
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
if (res) {
|
|
139
|
-
setUploadFiles(prev => [...prev, ...res]);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
reject(error);
|
|
144
|
-
}
|
|
145
|
-
finally {
|
|
146
|
-
resolve();
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
reader.readAsDataURL(selectedFile);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
try {
|
|
153
|
-
const res = yield Promise.all(uploadPromises);
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
console.error('Error uploading files:', error);
|
|
104
|
+
try {
|
|
105
|
+
const selectedFiles = event.target.files;
|
|
106
|
+
if (!selectedFiles) {
|
|
107
|
+
setUploadingFile(false);
|
|
108
|
+
return;
|
|
157
109
|
}
|
|
158
|
-
|
|
110
|
+
const validFiles = Array.from(selectedFiles).filter(file => (0, EscalationRespondForm_1.validateFileUpload)(file));
|
|
111
|
+
if (validFiles.length === 0) {
|
|
159
112
|
setUploadingFile(false);
|
|
113
|
+
return;
|
|
160
114
|
}
|
|
115
|
+
const uploadPromises = validFiles.map((selectedFile) => {
|
|
116
|
+
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
118
|
+
try {
|
|
119
|
+
const res = yield (0, FileUploader_1.fileUploader)({
|
|
120
|
+
file: selectedFile,
|
|
121
|
+
documentName: selectedFile.name,
|
|
122
|
+
escalationId: escalationId,
|
|
123
|
+
projectId: selectedProjects.length > 0 ? selectedProjects[0].id : '',
|
|
124
|
+
documentUploadUrl: documentUploadUrl,
|
|
125
|
+
bucketName: bucketName,
|
|
126
|
+
isExpert: isExpert,
|
|
127
|
+
uploadExpertClientFiles: uploadExpertClientFiles,
|
|
128
|
+
createProjectEscalation: createProjectEscalation,
|
|
129
|
+
extraData: {
|
|
130
|
+
clientId: isExpert ? (_a = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id) !== null && _a !== void 0 ? _a : 0 : clientId,
|
|
131
|
+
clientName: isExpert ? (_b = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) !== null && _b !== void 0 ? _b : '' : (_c = user === null || user === void 0 ? void 0 : user.name) !== null && _c !== void 0 ? _c : '',
|
|
132
|
+
email: isExpert ? (_e = (_d = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.primaryContact) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : '' : (_f = user === null || user === void 0 ? void 0 : user.email) !== null && _f !== void 0 ? _f : '',
|
|
133
|
+
freelancerId: isExpert ? (_g = user === null || user === void 0 ? void 0 : user.userId) !== null && _g !== void 0 ? _g : 0 : (_h = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id) !== null && _h !== void 0 ? _h : 0,
|
|
134
|
+
freelancerName: isExpert ? (_j = user === null || user === void 0 ? void 0 : user.name) !== null && _j !== void 0 ? _j : '' : (_k = selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) !== null && _k !== void 0 ? _k : '',
|
|
135
|
+
projectName: selectedProjects.length > 0 ? selectedProjects[0].name : '',
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
if (res) {
|
|
139
|
+
setUploadFiles(prev => [...prev, ...res]);
|
|
140
|
+
}
|
|
141
|
+
resolve();
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
reject(error);
|
|
145
|
+
}
|
|
146
|
+
}));
|
|
147
|
+
});
|
|
148
|
+
yield Promise.all(uploadPromises);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error('Error uploading files:', error);
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
setUploadingFile(false);
|
|
161
155
|
}
|
|
162
|
-
;
|
|
163
156
|
});
|
|
164
157
|
const isFormValid = () => {
|
|
165
158
|
const requiredProjectSelection = isExpert || (!isExpert && selectedProjects.length > 0);
|
|
@@ -188,8 +181,11 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
188
181
|
outcome: outcomeInput,
|
|
189
182
|
submittedByUserId: user.userId,
|
|
190
183
|
status: 'InProgress',
|
|
191
|
-
[isExpert ? 'expertSupportingDocuments' : 'clientSupportingDocuments']: uploadFiles.join(", "),
|
|
184
|
+
[isExpert ? 'expertSupportingDocuments' : 'clientSupportingDocuments']: uploadFiles.length > 0 ? uploadFiles.join(", ") : '',
|
|
192
185
|
statusChangedBy: user.userId,
|
|
186
|
+
requiresFollowUp: false,
|
|
187
|
+
firstReviewerId: isExpert ? user.userId : selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id,
|
|
188
|
+
followOnReviewerId: isExpert ? selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id : clientId,
|
|
193
189
|
};
|
|
194
190
|
try {
|
|
195
191
|
yield createProjectEscalation({
|
|
@@ -220,7 +216,9 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
220
216
|
react_1.default.createElement(base_icons_1.IconChevronLeft, { size: "xs" }),
|
|
221
217
|
" Back"),
|
|
222
218
|
react_1.default.createElement("div", { className: "mb-6" },
|
|
223
|
-
react_1.default.createElement("h2", { className: "text-xl font-bold" },
|
|
219
|
+
react_1.default.createElement("h2", { className: "text-xl font-bold" },
|
|
220
|
+
"Report Issue with Your ",
|
|
221
|
+
isExpert ? 'Client' : 'Expert'),
|
|
224
222
|
react_1.default.createElement("p", { className: "text-gray-600 mt-1" }, "Provide details about the issue you're experiencing and we'll resolve it within 4-8 hours")),
|
|
225
223
|
react_1.default.createElement("div", { className: "bg-red-50 border border-red-200 rounded-lg p-4 mb-6" },
|
|
226
224
|
react_1.default.createElement("div", { className: "flex items-start" },
|
|
@@ -265,9 +263,9 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
265
263
|
.filter(opt => selected.includes(opt.value))
|
|
266
264
|
.map(opt => opt.label)
|
|
267
265
|
.join(', ');
|
|
268
|
-
}, placeholder: `Select
|
|
266
|
+
}, placeholder: `Select Project(s)` },
|
|
269
267
|
react_1.default.createElement(core_1.MenuItem, { disabled: true, value: "" },
|
|
270
|
-
react_1.default.createElement("em", null, "Select
|
|
268
|
+
react_1.default.createElement("em", null, "Select Project(s)...")),
|
|
271
269
|
projectOptions.map(option => (react_1.default.createElement(core_1.MenuItem, { key: option.value.id, value: option.value }, option.label))))),
|
|
272
270
|
react_1.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" },
|
|
273
271
|
react_1.default.createElement("div", null,
|
|
@@ -307,7 +305,7 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
307
305
|
react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Supporting Documents (Optional)"),
|
|
308
306
|
react_1.default.createElement("div", { className: "border border-dashed border-gray-300 rounded-md p-6 text-center" },
|
|
309
307
|
react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-2" }, "Upload screenshots, emails, or documents"),
|
|
310
|
-
react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple:
|
|
308
|
+
react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: false, accept: ".pdf,.doc,.docx,.jpeg,.png,.gif,.csv, .xslx", hidden: true, onChange: handleFileUpload }),
|
|
311
309
|
react_1.default.createElement(base_ui_1.Button, { label: "Attach Files", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, color: "info", isLoading: uploadingFile, disabled: selectedUser === null, size: "sm" }),
|
|
312
310
|
uploadFiles.length > 0 && (react_1.default.createElement("ul", { className: "mt-2 text-sm text-gray-600 list-disc list-inside" }, uploadFiles.map(f => react_1.default.createElement("li", { key: f.name }, f.split('%2F')[1])))))),
|
|
313
311
|
react_1.default.createElement("div", { className: "bg-[#EFF6FF] p-3 rounded" },
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const base_icons_1 = require("@paro.io/base-icons");
|
|
8
|
+
const core_1 = require("@material-ui/core");
|
|
9
|
+
const ViewResponseModal = ({ response, open, onClose, isExpert }) => {
|
|
10
|
+
return (react_1.default.createElement(core_1.Dialog, { open: open, onClose: onClose, maxWidth: 'sm' },
|
|
11
|
+
react_1.default.createElement(core_1.DialogTitle, null,
|
|
12
|
+
react_1.default.createElement("div", { className: "text-black mb-1 p-2 pl-4 absolute top-0 left-0 w-full flex flex-row justify-between items-center z-50" },
|
|
13
|
+
react_1.default.createElement("div", { className: "flex flex-col items-start" },
|
|
14
|
+
react_1.default.createElement("h1", { className: "text-md font-bold mr-2" }, isExpert ? 'Client Response' : 'Expert Response')),
|
|
15
|
+
react_1.default.createElement("div", { className: "flex items-center space-x-4" },
|
|
16
|
+
react_1.default.createElement(core_1.IconButton, { onClick: onClose },
|
|
17
|
+
react_1.default.createElement(base_icons_1.IconX, null))))),
|
|
18
|
+
react_1.default.createElement(core_1.DialogContent, null,
|
|
19
|
+
react_1.default.createElement("div", { className: "bg-green-50 border-green-800 border border-l-4 rounded p-4 mt-4 mb-4" },
|
|
20
|
+
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
21
|
+
"Status: ",
|
|
22
|
+
react_1.default.createElement("span", { className: "font-normal" }, "Responded")),
|
|
23
|
+
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
24
|
+
"Response: ",
|
|
25
|
+
react_1.default.createElement("span", { className: "font-normal" }, response))))));
|
|
26
|
+
};
|
|
27
|
+
exports.default = ViewResponseModal;
|