@paro.io/expert-shared-components 1.13.6 → 1.13.8
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 -9
- package/lib/components/Escalations/AccountSuspensionModal.js +2 -2
- package/lib/components/Escalations/EscalationChat.js +1 -1
- package/lib/components/Escalations/EscalationIssueCard.js +22 -15
- package/lib/components/Escalations/EscalationRespondForm.d.ts +10 -0
- package/lib/components/Escalations/EscalationRespondForm.js +22 -3
- package/lib/components/Escalations/EscalationSubmitForm.js +34 -15
- package/lib/components/Escalations/EscalationTabsContent.js +3 -1
- package/lib/components/Escalations/Escalations.js +22 -15
- package/lib/components/Escalations/MarkResolvedModal.js +1 -1
- package/lib/components/Escalations/ViewResponseModal.js +10 -6
- package/package.json +1 -1
|
@@ -13,12 +13,7 @@ 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 an escalation. You must complete comprehensive training to regain access to new opportunities.")
|
|
17
|
-
react_1.default.createElement("div", { className: "mt-3 bg-white bg-opacity-10 rounded p-3" },
|
|
18
|
-
react_1.default.createElement("div", { className: "flex items-center justify-between text-sm" },
|
|
19
|
-
react_1.default.createElement("div", null,
|
|
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)"))))))
|
|
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.")))
|
|
22
17
|
:
|
|
23
18
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
24
19
|
react_1.default.createElement("div", { className: "flex items-center" },
|
|
@@ -26,9 +21,7 @@ const AccountSuspensionBanner = ({ setShowSuspensionModal, suspended = false })
|
|
|
26
21
|
react_1.default.createElement(base_icons_1.IconExclamation, { className: "h-6 w-6 text-white" })),
|
|
27
22
|
react_1.default.createElement("div", null,
|
|
28
23
|
react_1.default.createElement("h3", { className: "text-lg font-bold text-white" }, "Account Suspension Risk"),
|
|
29
|
-
react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" }, "Unresolved escalations can lead to automatic suspension. Response times matter for client satisfaction."),
|
|
30
|
-
react_1.default.createElement("div", { className: "flex items-center mt-2 text-red-100 text-xs" },
|
|
31
|
-
react_1.default.createElement("span", null, "3 warnings: Medium=30d \u2022 2 warnings: High=60d \u2022 1 offense: Critical=Permanent")))),
|
|
24
|
+
react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" }, "Unresolved escalations can lead to automatic suspension. Response times matter for client satisfaction."))),
|
|
32
25
|
react_1.default.createElement(base_ui_1.Button, { label: "view details", onClick: () => setShowSuspensionModal(true), iconLeft: react_1.default.createElement(base_icons_1.IconInfoCircle, { size: "sm" }), color: "danger", className: "bg-white hover:bg-danger text-danger-dark hover:text-white" }))));
|
|
33
26
|
};
|
|
34
27
|
exports.default = AccountSuspensionBanner;
|
|
@@ -20,7 +20,7 @@ const AccountSuspensionModal = ({ showSuspensionModal, onClose }) => {
|
|
|
20
20
|
react_1.default.createElement(base_icons_1.IconBriefcase, { className: "h-5 w-5 text-red-500 mt-0.5 mr-2 flex-shrink-0" }),
|
|
21
21
|
react_1.default.createElement("div", null,
|
|
22
22
|
react_1.default.createElement("p", { className: "font-medium text-red-800" }, "Critical Information"),
|
|
23
|
-
react_1.default.createElement("p", { className: "text-sm text-red-700 mt-1" }, "
|
|
23
|
+
react_1.default.createElement("p", { className: "text-sm text-red-700 mt-1" }, "Engagment support issues require timely attention to maintain client relationships and project success. Multiple unresolved issues may result in account warnings and potential suspension."))))),
|
|
24
24
|
react_1.default.createElement("div", { className: "space-y-6" },
|
|
25
25
|
react_1.default.createElement("div", { className: "relative" },
|
|
26
26
|
react_1.default.createElement("div", { className: "absolute left-4 top-8 bottom-0 w-0.5 bg-gray-200" }),
|
|
@@ -104,7 +104,7 @@ const AccountSuspensionModal = ({ showSuspensionModal, onClose }) => {
|
|
|
104
104
|
react_1.default.createElement("div", { className: "mt-6 bg-gray-50 rounded-lg p-4" },
|
|
105
105
|
react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Important Reminders"),
|
|
106
106
|
react_1.default.createElement("ul", { className: "text-sm text-gray-600 space-y-1" },
|
|
107
|
-
react_1.default.createElement("li", null, "\u2022 All
|
|
107
|
+
react_1.default.createElement("li", null, "\u2022 All issues are tracked and contribute to your warning count"),
|
|
108
108
|
react_1.default.createElement("li", null, "\u2022 Training completion is required before suspension can be lifted"),
|
|
109
109
|
react_1.default.createElement("li", null, "\u2022 Warnings are cumulative across all severity levels"),
|
|
110
110
|
react_1.default.createElement("li", null, "\u2022 All actions are logged and affect your expert rating")))))));
|
|
@@ -117,7 +117,7 @@ const EscalationChat = ({ activeChatIssue, showEscalationChat, onClose, user, cr
|
|
|
117
117
|
react_1.default.createElement("div", { className: "flex flex-col items-start" },
|
|
118
118
|
react_1.default.createElement("div", { className: "flex flex-row items-center" },
|
|
119
119
|
react_1.default.createElement("h1", { className: "text-md font-bold mr-2" },
|
|
120
|
-
"
|
|
120
|
+
"Engagement Support #",
|
|
121
121
|
activeChatIssue.escalationNumber),
|
|
122
122
|
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: activeChatIssue.status === "InProgress" ? "In Progress" : activeChatIssue.status, customColor: isExpert ? 'bg-neutral border-neutral' : 'bg-[#B0B5D3] border-[#181027]' })),
|
|
123
123
|
react_1.default.createElement("p", { className: "text-xs" },
|
|
@@ -69,24 +69,19 @@ const EscalationIssueCard = ({ issues, isExpert, openEscalationChat, showRespond
|
|
|
69
69
|
return "View Response";
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
|
-
return issue.expertResponse ? "View Response" : "Awaiting Response";
|
|
72
|
+
return issue.expertResponse || issue.clientResponse ? "View Response" : "Awaiting Response";
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
if (userTypeId === 1) { // Submitted by Expert
|
|
76
76
|
if (isExpert) {
|
|
77
|
-
return issue.clientResponse ? "View Response" : "Awaiting Response";
|
|
77
|
+
return issue.clientResponse || issue.expertResponse ? "View Response" : "Awaiting Response";
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
80
|
return "View Response";
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
if (userTypeId === 2) { // Submitted by Paro internal
|
|
84
|
-
|
|
85
|
-
return issue.clientResponse ? "View Response" : "Awaiting Response";
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
return issue.expertResponse ? "View Response" : "Awaiting Response";
|
|
89
|
-
}
|
|
84
|
+
return issue.clientResponse || issue.expertResponse ? "View Response" : "Awaiting Response";
|
|
90
85
|
}
|
|
91
86
|
return "Awaiting Response";
|
|
92
87
|
};
|
|
@@ -94,7 +89,7 @@ const EscalationIssueCard = ({ issues, isExpert, openEscalationChat, showRespond
|
|
|
94
89
|
return react_1.default.createElement("div", null, "No issues.");
|
|
95
90
|
return (react_1.default.createElement("div", { className: "space-y-4" },
|
|
96
91
|
issues.map((issue) => {
|
|
97
|
-
var _a, _b, _c, _d, _e
|
|
92
|
+
var _a, _b, _c, _d, _e;
|
|
98
93
|
const project = issue.projectDetails && Array.isArray(issue.projectDetails) && issue.projectDetails.length > 0
|
|
99
94
|
? `${(_a = issue.projectDetails[0]) === null || _a === void 0 ? void 0 : _a.projectName}${issue.projectDetails.length > 1 ? ` +${issue.projectDetails.length - 1} more` : ''} `
|
|
100
95
|
: '';
|
|
@@ -104,12 +99,10 @@ const EscalationIssueCard = ({ issues, isExpert, openEscalationChat, showRespond
|
|
|
104
99
|
react_1.default.createElement("div", { className: "flex items-center justify-between mb-3" },
|
|
105
100
|
react_1.default.createElement("div", { className: "flex-1 ml-2" },
|
|
106
101
|
react_1.default.createElement("div", { className: "flex flex-row justify-start gap-2" },
|
|
107
|
-
react_1.default.createElement("div", { className: "font-bold" },
|
|
102
|
+
react_1.default.createElement("div", { className: "font-bold" }, project),
|
|
108
103
|
react_1.default.createElement(exports.CustomTag, { label: issue.severityLevel })),
|
|
109
104
|
react_1.default.createElement("div", { className: "text-xs text-gray-500 font-bold" },
|
|
110
|
-
isExpert ? (
|
|
111
|
-
" \u2022 ",
|
|
112
|
-
project,
|
|
105
|
+
isExpert ? `${(_b = issue === null || issue === void 0 ? void 0 : issue.client) === null || _b === void 0 ? void 0 : _b.name} (Client)` : `${(_c = issue === null || issue === void 0 ? void 0 : issue.freelancer) === null || _c === void 0 ? void 0 : _c.name} (Expert)`,
|
|
113
106
|
" \u2022 Case #",
|
|
114
107
|
issue.escalationNumber)),
|
|
115
108
|
react_1.default.createElement(exports.CustomTag, { label: issue.escalationType, customColor: `bg-[#B0B5D3] border-[#181027]` })),
|
|
@@ -117,11 +110,25 @@ const EscalationIssueCard = ({ issues, isExpert, openEscalationChat, showRespond
|
|
|
117
110
|
react_1.default.createElement("div", { className: "flex items-center justify-between mb-2" },
|
|
118
111
|
react_1.default.createElement("div", { className: "text-sm text-gray-500" },
|
|
119
112
|
"Submitted by: ",
|
|
120
|
-
react_1.default.createElement("span", { className: "font-bold" },
|
|
113
|
+
react_1.default.createElement("span", { className: "font-bold" },
|
|
114
|
+
((_d = issue === null || issue === void 0 ? void 0 : issue.submittedByUser) === null || _d === void 0 ? void 0 : _d.firstName) + " " + ((_e = issue === null || issue === void 0 ? void 0 : issue.submittedByUser) === null || _e === void 0 ? void 0 : _e.lastName),
|
|
115
|
+
" ",
|
|
116
|
+
issue.submittedByUser.userTypeId === 1 ? '(Expert)' : issue.submittedByUser.userTypeId === 2 ? '(Paro)' : '(Client)'),
|
|
121
117
|
(issue === null || issue === void 0 ? void 0 : issue.createdAt) && react_1.default.createElement(react_1.default.Fragment, null,
|
|
122
118
|
" \u2022 Submitted on: ",
|
|
123
119
|
react_1.default.createElement("span", { className: "font-bold" }, (0, dayjs_1.default)(issue === null || issue === void 0 ? void 0 : issue.createdAt).format("MM-DD-YYYY"))))),
|
|
124
|
-
react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-
|
|
120
|
+
react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-2" },
|
|
121
|
+
react_1.default.createElement("span", { className: "font-bold" }, "Projects Affected:"),
|
|
122
|
+
" ",
|
|
123
|
+
issue.projectDetails.map((p) => p.projectName).join(", ")),
|
|
124
|
+
react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-2" },
|
|
125
|
+
react_1.default.createElement("span", { className: "font-bold" }, "Problem:"),
|
|
126
|
+
" ",
|
|
127
|
+
issue.problem),
|
|
128
|
+
react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-2" },
|
|
129
|
+
react_1.default.createElement("span", { className: "font-bold" }, "Desired Outcome:"),
|
|
130
|
+
" ",
|
|
131
|
+
issue.outcome),
|
|
125
132
|
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
|
|
126
133
|
react_1.default.createElement("span", { className: "text-sm font-bold text-gray-500 items-center" }, "Supporting Documents: "),
|
|
127
134
|
processedDocs.map((d, idx) => (react_1.default.createElement(exports.CustomTag, { key: idx, customColor: `bg-success border-success`, label: d.split('%2F')[1], iconLeft: react_1.default.createElement(base_icons_1.IconDocumentDownload, { size: "xs" }), onClick: () => {
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
export declare const ACCEPTED_FILE_TYPES: string[];
|
|
2
2
|
export declare const validateFileUpload: (file: File | null) => boolean;
|
|
3
|
+
export declare const clientResponseTypes: {
|
|
4
|
+
label: string;
|
|
5
|
+
description: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}[];
|
|
8
|
+
export declare const expertResponseTypes: {
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
value: string;
|
|
12
|
+
}[];
|
|
3
13
|
declare const EscalationRespondForm: ({ goBack, selectedIssue, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, updateProjectEscalation, bucketName, goHome, isExpert, userId, }: {
|
|
4
14
|
goBack: () => void;
|
|
5
15
|
selectedIssue: any;
|
|
@@ -32,7 +32,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.validateFileUpload = exports.ACCEPTED_FILE_TYPES = void 0;
|
|
35
|
+
exports.expertResponseTypes = exports.clientResponseTypes = exports.validateFileUpload = exports.ACCEPTED_FILE_TYPES = void 0;
|
|
36
36
|
const react_1 = __importStar(require("react"));
|
|
37
37
|
const base_icons_1 = require("@paro.io/base-icons");
|
|
38
38
|
const base_ui_1 = require("@paro.io/base-ui");
|
|
@@ -58,7 +58,7 @@ const validateFileUpload = (file) => {
|
|
|
58
58
|
return true;
|
|
59
59
|
};
|
|
60
60
|
exports.validateFileUpload = validateFileUpload;
|
|
61
|
-
|
|
61
|
+
exports.clientResponseTypes = [
|
|
62
62
|
{
|
|
63
63
|
label: "Acknowledge issue and provide resolution plan",
|
|
64
64
|
description: "Explain circumstances and apologize",
|
|
@@ -66,7 +66,7 @@ const responseTypes = [
|
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
68
|
label: "Dispute issue and provide counter-evidence",
|
|
69
|
-
description: "Challenge the
|
|
69
|
+
description: "Challenge the expert's concerns with documentation",
|
|
70
70
|
value: "Disputed",
|
|
71
71
|
},
|
|
72
72
|
{
|
|
@@ -75,7 +75,25 @@ const responseTypes = [
|
|
|
75
75
|
value: "NoResponse",
|
|
76
76
|
},
|
|
77
77
|
];
|
|
78
|
+
exports.expertResponseTypes = [
|
|
79
|
+
{
|
|
80
|
+
label: "Acknowledge issue and provide resolution plan",
|
|
81
|
+
description: "Explain circumstances and apologize",
|
|
82
|
+
value: "Acknowledged",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
label: "Challenge the client's concerns with documentation",
|
|
86
|
+
description: "Challenge the client's concerns with documentation",
|
|
87
|
+
value: "NeedsHelp",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
label: "Request clarification",
|
|
91
|
+
description: "Ask for more details about the issue",
|
|
92
|
+
value: "NoResponse",
|
|
93
|
+
},
|
|
94
|
+
];
|
|
78
95
|
const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, updateProjectEscalation, bucketName, goHome, isExpert, userId, }) => {
|
|
96
|
+
const responseTypes = isExpert ? exports.expertResponseTypes : exports.clientResponseTypes;
|
|
79
97
|
const [selectedType, setSelectedType] = (0, react_1.useState)(responseTypes[0].value);
|
|
80
98
|
const [responseInput, setResponseInput] = (0, react_1.useState)('');
|
|
81
99
|
const [uploadFiles, setUploadFiles] = (0, react_1.useState)([]);
|
|
@@ -149,6 +167,7 @@ const EscalationRespondForm = ({ goBack, selectedIssue, documentUploadUrl, downl
|
|
|
149
167
|
variables: {
|
|
150
168
|
input: {
|
|
151
169
|
escalationId: selectedIssue.escalationId,
|
|
170
|
+
[isExpert ? 'expertResponseType' : 'clientResponseType']: selectedType,
|
|
152
171
|
[isExpert ? 'expertResponse' : 'clientResponse']: responseInput,
|
|
153
172
|
[isExpert ? 'expertSupportingDocuments' : 'clientSupportingDocuments']: uploadFiles.length > 0 ? uploadFiles.join(", ") : '',
|
|
154
173
|
statusChangedBy: userId,
|
|
@@ -44,6 +44,7 @@ const dayjs_1 = __importDefault(require("dayjs"));
|
|
|
44
44
|
const EscalationRespondForm_1 = require("./EscalationRespondForm");
|
|
45
45
|
const FileUploader_1 = require("../FileUploader");
|
|
46
46
|
const utils_1 = require("../shared/utils");
|
|
47
|
+
const EscalationIssueCard_1 = require("./EscalationIssueCard");
|
|
47
48
|
const issueTypeOptions = [
|
|
48
49
|
{ value: 'CommunicationIssues', label: 'Communication Issues' },
|
|
49
50
|
{ value: 'Professionalism', label: 'Professionalism' },
|
|
@@ -176,7 +177,7 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
176
177
|
escalationId: escalationId,
|
|
177
178
|
freelancerId: isExpert ? user.userId : selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id,
|
|
178
179
|
clientId: isExpert ? selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id : clientId,
|
|
179
|
-
projectDetails: selectedProjects.map((p) => { return { projectId: p.id, projectName: p.name }; }),
|
|
180
|
+
projectDetails: selectedProjects.filter((p) => p !== undefined).map((p) => { return { projectId: p.id, projectName: p.name }; }),
|
|
180
181
|
issueStartDate: issueStartDate,
|
|
181
182
|
escalationType: issueType,
|
|
182
183
|
severityLevel: severity,
|
|
@@ -193,7 +194,7 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
193
194
|
input: formData
|
|
194
195
|
}
|
|
195
196
|
});
|
|
196
|
-
(0, utils_1.showToast)("success", "Issue created successfully
|
|
197
|
+
(0, utils_1.showToast)("success", "Issue created successfully. You can find it under the `In Progress` section");
|
|
197
198
|
}
|
|
198
199
|
catch (error) {
|
|
199
200
|
console.error("Failed to create an issue!", error);
|
|
@@ -220,17 +221,21 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
220
221
|
"Report Issue with Your ",
|
|
221
222
|
isExpert ? 'Client' : 'Expert'),
|
|
222
223
|
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")),
|
|
223
|
-
react_1.default.createElement("div",
|
|
224
|
-
react_1.default.createElement("
|
|
225
|
-
|
|
226
|
-
react_1.default.createElement("div",
|
|
227
|
-
react_1.default.createElement(
|
|
228
|
-
react_1.default.createElement("
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
224
|
+
react_1.default.createElement("div", null,
|
|
225
|
+
react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Priority Levels for Issues"),
|
|
226
|
+
react_1.default.createElement("div", { className: "space-y-2 text-sm" },
|
|
227
|
+
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
228
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Critical" }),
|
|
229
|
+
react_1.default.createElement("span", null, "All deliverables are currently blocked; the project cannot move forward.")),
|
|
230
|
+
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
231
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "High" }),
|
|
232
|
+
react_1.default.createElement("span", null, "Key deliverables are blocked, preventing meaningful progress.")),
|
|
233
|
+
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
234
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Medium" }),
|
|
235
|
+
react_1.default.createElement("span", null, "Deliverables are still in progress, but timelines are at risk.")),
|
|
236
|
+
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
237
|
+
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Low" }),
|
|
238
|
+
react_1.default.createElement("span", null, "Minor issue or inconvenience that does not affect overall project flow.")))),
|
|
234
239
|
react_1.default.createElement("div", { className: "border rounded-lg overflow-hidden mb-6" },
|
|
235
240
|
react_1.default.createElement("div", { className: "bg-gray-50 p-3 border-b" },
|
|
236
241
|
react_1.default.createElement("h3", { className: "font-medium" }, "Issue Details")),
|
|
@@ -263,10 +268,24 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
|
|
|
263
268
|
.filter(opt => selected.includes(opt.value))
|
|
264
269
|
.map(opt => opt.label)
|
|
265
270
|
.join(', ');
|
|
266
|
-
}, placeholder: `Select Project(s)
|
|
271
|
+
}, placeholder: `Select Project(s)`, MenuProps: {
|
|
272
|
+
PaperProps: {
|
|
273
|
+
style: {
|
|
274
|
+
maxHeight: 300,
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
} },
|
|
267
278
|
react_1.default.createElement(core_1.MenuItem, { disabled: true, value: "" },
|
|
268
279
|
react_1.default.createElement("em", null, "Select Project(s)...")),
|
|
269
|
-
projectOptions.map(option => (react_1.default.createElement(core_1.MenuItem, { key: option.value.id, value: option.value }, option.label)))
|
|
280
|
+
projectOptions.map(option => (react_1.default.createElement(core_1.MenuItem, { key: option.value.id, value: option.value }, option.label))),
|
|
281
|
+
react_1.default.createElement(core_1.MenuItem, { disableRipple: true, disableGutters: true },
|
|
282
|
+
react_1.default.createElement(base_ui_1.Button, { label: "save & continue", className: "mx-4", color: "primary", onClick: (e) => {
|
|
283
|
+
const menu = e.target.closest('[role="presentation"]');
|
|
284
|
+
if (menu) {
|
|
285
|
+
const escEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true });
|
|
286
|
+
menu.dispatchEvent(escEvent);
|
|
287
|
+
}
|
|
288
|
+
} })))),
|
|
270
289
|
react_1.default.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" },
|
|
271
290
|
react_1.default.createElement("div", null,
|
|
272
291
|
react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Issue Type"),
|
|
@@ -76,7 +76,9 @@ const EscalationTabsContent = ({ activeTab, openEscalationChat, setSelectedIssue
|
|
|
76
76
|
react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
|
|
77
77
|
react_1.default.createElement("span", { className: "text-xs text-gray-500" },
|
|
78
78
|
"Resolved By ",
|
|
79
|
-
issue.statusChangedByUser.firstName + " " + issue.statusChangedByUser.lastName
|
|
79
|
+
issue.statusChangedByUser.firstName + " " + issue.statusChangedByUser.lastName,
|
|
80
|
+
" ",
|
|
81
|
+
issue.statusChangedByUser.userTypeId === 2 && '(Paro)')))),
|
|
80
82
|
issue.status === 'Resolved' && (0, dayjs_1.default)().diff((0, dayjs_1.default)(issue.updatedAt), 'day') <= 30 &&
|
|
81
83
|
react_1.default.createElement(base_ui_1.Button, { onClick: () => openEscalationChat(issue.escalationNumber), label: "Chat", color: "primary" }))));
|
|
82
84
|
}))
|
|
@@ -53,13 +53,20 @@ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations
|
|
|
53
53
|
const userTypeId = (_a = issue === null || issue === void 0 ? void 0 : issue.submittedByUser) === null || _a === void 0 ? void 0 : _a.userTypeId;
|
|
54
54
|
const internalEscalationTo = issue === null || issue === void 0 ? void 0 : issue.internalEscalationTo;
|
|
55
55
|
const status = issue === null || issue === void 0 ? void 0 : issue.status;
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
?
|
|
59
|
-
:
|
|
60
|
-
|
|
61
|
-
(
|
|
62
|
-
|
|
56
|
+
const isDifferentUserType = userTypeId !== user.userTypeId;
|
|
57
|
+
const isPendingResponse = isExpert
|
|
58
|
+
? issue.expertResponse === null
|
|
59
|
+
: issue.clientResponse === null;
|
|
60
|
+
const isValidInternalEscalation = userTypeId === 2
|
|
61
|
+
? (isExpert
|
|
62
|
+
? internalEscalationTo !== "client" // expert should NOT see escalations to client
|
|
63
|
+
: internalEscalationTo !== "expert") // client should NOT see escalations to expert
|
|
64
|
+
: userTypeId !== user.userTypeId;
|
|
65
|
+
const shouldInclude = isDifferentUserType &&
|
|
66
|
+
isPendingResponse &&
|
|
67
|
+
isValidInternalEscalation &&
|
|
68
|
+
status === 'InProgress';
|
|
69
|
+
return shouldInclude;
|
|
63
70
|
});
|
|
64
71
|
const inProgressIssues = escalations.filter(issue => { var _a; return ((((_a = issue === null || issue === void 0 ? void 0 : issue.submittedByUser) === null || _a === void 0 ? void 0 : _a.userTypeId) === user.userTypeId) || (isExpert ? issue.expertResponse !== null : issue.clientResponse !== null)) && (issue === null || issue === void 0 ? void 0 : issue.status) === 'InProgress'; });
|
|
65
72
|
const resolvedIssues = escalations.filter(issue => (issue === null || issue === void 0 ? void 0 : issue.status) === 'Resolved');
|
|
@@ -88,7 +95,7 @@ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations
|
|
|
88
95
|
react_1.default.createElement("div", { className: isExpert ? "p-6" : "mx-auto p-6 border-solid border-t-2" },
|
|
89
96
|
activeSection === 'support' && selectedIssueId === null && react_1.default.createElement("div", null,
|
|
90
97
|
react_1.default.createElement("div", { className: "flex justify-between items-center mb-1 mt-2" },
|
|
91
|
-
react_1.default.createElement("h2", { className: "text-xl font-bold" }, "
|
|
98
|
+
react_1.default.createElement("h2", { className: "text-xl font-bold" }, "Engagement Management"),
|
|
92
99
|
activeIssues.length > 0 ? react_1.default.createElement("div", { className: "flex items-center space-x-2" },
|
|
93
100
|
react_1.default.createElement("div", { className: `border box-border text-center px-4 pb-0.5 pt-1 text-sm inline-block break-words text-[#A73A43] rounded-full bg-[#F9BABF] border-[#F9BABF] font-medium` },
|
|
94
101
|
activeIssues.length,
|
|
@@ -112,7 +119,7 @@ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations
|
|
|
112
119
|
react_1.default.createElement("span", null,
|
|
113
120
|
react_1.default.createElement("strong", null, "Step 2:"),
|
|
114
121
|
" ",
|
|
115
|
-
`${isExpert ? 'Client' : 'Expert
|
|
122
|
+
`${isExpert ? 'Client response provided' : 'Expert response provided'}`)),
|
|
116
123
|
react_1.default.createElement("div", { className: "flex items-center" },
|
|
117
124
|
react_1.default.createElement("div", { className: "bg-blue-500 w-2 h-2 rounded-full mr-2" }),
|
|
118
125
|
react_1.default.createElement("span", null,
|
|
@@ -121,22 +128,22 @@ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations
|
|
|
121
128
|
react_1.default.createElement("div", { className: "mt-3 text-xs text-gray-600 bg-white p-2 rounded border" },
|
|
122
129
|
react_1.default.createElement("strong", null, "Chat integration:"),
|
|
123
130
|
" ",
|
|
124
|
-
`All
|
|
131
|
+
`All issues include asynchronous messaging with your ${isExpert ? 'client' : 'expert'} and the support team for transparent communication`)),
|
|
125
132
|
react_1.default.createElement("div", null,
|
|
126
|
-
react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Priority Levels
|
|
133
|
+
react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Priority Levels for Issues"),
|
|
127
134
|
react_1.default.createElement("div", { className: "space-y-2 text-sm" },
|
|
128
135
|
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
129
136
|
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Critical" }),
|
|
130
|
-
react_1.default.createElement("span", null, "All
|
|
137
|
+
react_1.default.createElement("span", null, "All deliverables are currently blocked; the project cannot move forward.")),
|
|
131
138
|
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
132
139
|
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "High" }),
|
|
133
|
-
react_1.default.createElement("span", null, "
|
|
140
|
+
react_1.default.createElement("span", null, "Key deliverables are blocked, preventing meaningful progress.")),
|
|
134
141
|
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
135
142
|
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Medium" }),
|
|
136
|
-
react_1.default.createElement("span", null, "
|
|
143
|
+
react_1.default.createElement("span", null, "Deliverables are still in progress, but timelines are at risk.")),
|
|
137
144
|
react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
|
|
138
145
|
react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Low" }),
|
|
139
|
-
react_1.default.createElement("span", null, "Minor
|
|
146
|
+
react_1.default.createElement("span", null, "Minor issue or inconvenience that does not affect overall project flow.")))))),
|
|
140
147
|
isExpert &&
|
|
141
148
|
react_1.default.createElement("div", { className: "rounded-lg p-2 mb-4 shadow-lg" },
|
|
142
149
|
react_1.default.createElement("div", { className: "flex items-center justify-between" },
|
|
@@ -53,7 +53,7 @@ const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProj
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
|
-
(0, utils_1.showToast)("success", "Issue marked as resolved
|
|
56
|
+
(0, utils_1.showToast)("success", "Issue marked as resolved. You can now find it in the `Resolved` section");
|
|
57
57
|
}
|
|
58
58
|
catch (error) {
|
|
59
59
|
console.error("Failed to update escalation!", error);
|
|
@@ -8,10 +8,17 @@ const base_icons_1 = require("@paro.io/base-icons");
|
|
|
8
8
|
const core_1 = require("@material-ui/core");
|
|
9
9
|
const utils_1 = require("../shared/utils");
|
|
10
10
|
const EscalationIssueCard_1 = require("./EscalationIssueCard");
|
|
11
|
+
const EscalationRespondForm_1 = require("./EscalationRespondForm");
|
|
11
12
|
const ViewResponseModal = ({ selectedIssue, open, onClose, isExpert }) => {
|
|
13
|
+
var _a, _b, _c, _d, _e;
|
|
12
14
|
const docs = [selectedIssue.expertSupportingDocuments, selectedIssue.clientSupportingDocuments, selectedIssue.internalSupportingDocuments];
|
|
13
15
|
const processedDocs = (0, utils_1.processDocs)(docs);
|
|
14
|
-
|
|
16
|
+
const responseType = isExpert ? (_a = selectedIssue.clientResponseType) !== null && _a !== void 0 ? _a : selectedIssue.expertResponseType : (_b = selectedIssue.expertResponseType) !== null && _b !== void 0 ? _b : selectedIssue.clientResponseType;
|
|
17
|
+
const responseTypeLabel = ((_c = [...new Set([...EscalationRespondForm_1.clientResponseTypes, ...EscalationRespondForm_1.expertResponseTypes])].find(opt => opt.value === responseType)) === null || _c === void 0 ? void 0 : _c.label) || responseType || "";
|
|
18
|
+
const response = isExpert ? (_d = selectedIssue.clientResponse) !== null && _d !== void 0 ? _d : selectedIssue.expertResponse : (_e = selectedIssue.expertResponse) !== null && _e !== void 0 ? _e : selectedIssue.clientResponse;
|
|
19
|
+
return (react_1.default.createElement(core_1.Dialog, { open: open, onClose: onClose, maxWidth: 'md', PaperProps: {
|
|
20
|
+
style: { minWidth: '40%' }
|
|
21
|
+
} },
|
|
15
22
|
react_1.default.createElement(core_1.DialogTitle, null,
|
|
16
23
|
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" },
|
|
17
24
|
react_1.default.createElement("div", { className: "flex flex-col items-start" },
|
|
@@ -21,15 +28,12 @@ const ViewResponseModal = ({ selectedIssue, open, onClose, isExpert }) => {
|
|
|
21
28
|
react_1.default.createElement(base_icons_1.IconX, null))))),
|
|
22
29
|
react_1.default.createElement(core_1.DialogContent, null,
|
|
23
30
|
react_1.default.createElement("div", { className: "bg-green-50 border-green-800 border border-l-4 rounded p-4 mt-4 mb-4" },
|
|
24
|
-
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
25
|
-
"Status: ",
|
|
26
|
-
react_1.default.createElement("span", { className: "font-normal" }, "Responded")),
|
|
27
31
|
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
28
32
|
"Response Type: ",
|
|
29
|
-
react_1.default.createElement("span", { className: "font-normal" },
|
|
33
|
+
react_1.default.createElement("span", { className: "font-normal" }, responseTypeLabel)),
|
|
30
34
|
react_1.default.createElement("p", { className: "text-sm font-medium" },
|
|
31
35
|
"Response: ",
|
|
32
|
-
react_1.default.createElement("span", { className: "font-normal" },
|
|
36
|
+
react_1.default.createElement("span", { className: "font-normal" }, response))),
|
|
33
37
|
processedDocs && processedDocs.length > 0 && (react_1.default.createElement("div", { className: "flex flex-wrap gap-2 mt-4 mb-2" },
|
|
34
38
|
react_1.default.createElement("span", { className: "text-sm font-bold text-gray-500 items-center" }, "Supporting Documents: "),
|
|
35
39
|
processedDocs.map((d, idx) => (react_1.default.createElement(EscalationIssueCard_1.CustomTag, { key: idx, label: d.split('%2F')[1], customColor: `bg-success border-success` }))))))));
|