@paro.io/expert-shared-components 1.13.8 → 1.13.10

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.
@@ -1,5 +1,9 @@
1
- declare const AccountSuspensionBanner: ({ setShowSuspensionModal, suspended }: {
1
+ export declare const suspensionLevels: {
2
+ value: string;
3
+ label: string;
4
+ }[];
5
+ declare const AccountSuspensionBanner: ({ setShowSuspensionModal, escalationDisputeStatistics, }: {
2
6
  setShowSuspensionModal: (showSuspensionModal: boolean) => void;
3
- suspended: boolean;
7
+ escalationDisputeStatistics: any;
4
8
  }) => JSX.Element;
5
9
  export default AccountSuspensionBanner;
@@ -3,17 +3,63 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.suspensionLevels = void 0;
6
7
  const react_1 = __importDefault(require("react"));
7
8
  const base_icons_1 = require("@paro.io/base-icons");
8
9
  const base_ui_1 = require("@paro.io/base-ui");
9
- const AccountSuspensionBanner = ({ setShowSuspensionModal, suspended = false }) => {
10
- return (react_1.default.createElement("div", { className: "bg-[#EF5360] rounded-lg p-4 mb-6 shadow-lg" }, suspended ?
10
+ const dayjs_1 = __importDefault(require("dayjs"));
11
+ exports.suspensionLevels = [
12
+ { value: "LEVEL_1", label: "Low" },
13
+ { value: "LEVEL_2", label: "Medium" },
14
+ { value: "LEVEL_3", label: "High" },
15
+ { value: "LEVEL_4", label: "Critical" },
16
+ ];
17
+ const getSuspensionDuration = (label) => {
18
+ switch (label) {
19
+ case "Medium":
20
+ return "30 days";
21
+ case "High":
22
+ return "60 days";
23
+ case "Critical":
24
+ return "Permanent";
25
+ case "Low":
26
+ default:
27
+ return "No suspension";
28
+ }
29
+ };
30
+ const AccountSuspensionBanner = ({ setShowSuspensionModal, escalationDisputeStatistics, }) => {
31
+ var _a, _b, _c, _d, _e, _f, _g;
32
+ const suspensionLevel = (_b = (_a = exports.suspensionLevels.find((obj) => obj.value === escalationDisputeStatistics.suspensionLevel)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : "Low";
33
+ const suspensionStartDate = (_c = (0, dayjs_1.default)(escalationDisputeStatistics.suspensionStartDate).format("MM/DD/YYYY")) !== null && _c !== void 0 ? _c : "N/A";
34
+ const suspensionEndDate = (_d = (0, dayjs_1.default)(escalationDisputeStatistics.suspensionEndDate).format("MM/DD/YYYY")) !== null && _d !== void 0 ? _d : "N/A";
35
+ const mediumWarnings = (_e = escalationDisputeStatistics.mediumSeverityEscalationCount) !== null && _e !== void 0 ? _e : 0;
36
+ const highWarnings = (_f = escalationDisputeStatistics.highSeverityEscalationCount) !== null && _f !== void 0 ? _f : 0;
37
+ const criticalWarnings = (_g = escalationDisputeStatistics.criticalSeverityEscalationCount) !== null && _g !== void 0 ? _g : 0;
38
+ return (react_1.default.createElement("div", { className: "bg-[#EF5360] rounded-lg p-4 mb-6 shadow-lg" }, suspensionLevel !== "Low" ?
11
39
  react_1.default.createElement("div", { className: "flex items-center" },
12
40
  react_1.default.createElement("div", { className: "bg-white bg-opacity-20 rounded-full p-2 mr-3" },
13
41
  react_1.default.createElement(base_icons_1.IconExclamation, { className: "h-6 w-6 text-white" })),
14
42
  react_1.default.createElement("div", { className: "flex-1" },
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.")))
43
+ react_1.default.createElement("h3", { className: "text-lg font-bold text-white" }, "\uD83D\uDEAB Account Suspended due to: Engagement Issues"),
44
+ react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" },
45
+ "Your account has been suspended due to engagement issues. If you have any problems with the suspension, please go to the Engagement Support section to respond to your issues or reach out to",
46
+ ' ',
47
+ react_1.default.createElement("a", { href: "mailto:expertsupport@paro.io", className: "underline text-white hover:text-red-200 cursor-pointer" }, "expertsupport@paro.io"),
48
+ "."),
49
+ react_1.default.createElement("div", { className: "mt-3 bg-white bg-opacity-10 rounded p-3" },
50
+ react_1.default.createElement("div", { className: "flex items-center justify-between text-sm" },
51
+ react_1.default.createElement("div", null,
52
+ react_1.default.createElement("span", { className: "text-red-100" }, "Suspension: "),
53
+ react_1.default.createElement("span", { className: "text-white font-medium" },
54
+ getSuspensionDuration(suspensionLevel),
55
+ ' ',
56
+ suspensionLevel)),
57
+ react_1.default.createElement("div", null,
58
+ react_1.default.createElement("span", { className: "text-red-100" }, "Suspension Started Date: "),
59
+ react_1.default.createElement("span", { className: "text-white font-medium" }, suspensionStartDate)),
60
+ react_1.default.createElement("div", null,
61
+ react_1.default.createElement("span", { className: "text-red-100" }, "Suspension End Date: "),
62
+ react_1.default.createElement("span", { className: "text-white font-medium" }, suspensionEndDate))))))
17
63
  :
18
64
  react_1.default.createElement("div", { className: "flex items-center justify-between" },
19
65
  react_1.default.createElement("div", { className: "flex items-center" },
@@ -21,7 +67,15 @@ const AccountSuspensionBanner = ({ setShowSuspensionModal, suspended = false })
21
67
  react_1.default.createElement(base_icons_1.IconExclamation, { className: "h-6 w-6 text-white" })),
22
68
  react_1.default.createElement("div", null,
23
69
  react_1.default.createElement("h3", { className: "text-lg font-bold text-white" }, "Account Suspension Risk"),
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."))),
70
+ 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."),
71
+ react_1.default.createElement("div", { className: "flex items-center mt-2 text-red-100 text-xs" },
72
+ react_1.default.createElement("span", null,
73
+ mediumWarnings,
74
+ "/3 warnings: Medium = 30 days \u2022 ",
75
+ highWarnings,
76
+ "/2 warnings: High = 60 days \u2022 ",
77
+ criticalWarnings,
78
+ "/1 offense: Critical = Permanent")))),
25
79
  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" }))));
26
80
  };
27
81
  exports.default = AccountSuspensionBanner;
@@ -29,7 +29,7 @@ const AccountSuspensionModal = ({ showSuspensionModal, onClose }) => {
29
29
  react_1.default.createElement(base_icons_1.IconCheckCircle, { className: "h-5 w-5 text-white" })),
30
30
  react_1.default.createElement("div", { className: "flex-1 pb-8" },
31
31
  react_1.default.createElement("div", { className: "flex justify-between items-start mb-2" },
32
- react_1.default.createElement("h4", { className: "font-semibold text-green-800" }, "Level 1: Light Issues"),
32
+ react_1.default.createElement("h4", { className: "font-semibold text-green-800" }, "Level 1: Low Issues"),
33
33
  react_1.default.createElement("div", { className: "text-xs bg-green-100 text-green-700 px-2 py-1 rounded-full" }, "Coaching Only")),
34
34
  react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-2" }, "Email coaching and guidance. No account restrictions."),
35
35
  react_1.default.createElement("div", { className: "text-xs text-gray-500" },
@@ -1,4 +1,5 @@
1
- declare const EscalationReportBanner: ({ onReport }: {
1
+ declare const EscalationReportBanner: ({ onReport, isExpert }: {
2
2
  onReport: () => void;
3
+ isExpert: boolean;
3
4
  }) => JSX.Element;
4
5
  export default EscalationReportBanner;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const base_icons_1 = require("@paro.io/base-icons");
8
8
  const base_ui_1 = require("@paro.io/base-ui");
9
- const EscalationReportBanner = ({ onReport }) => {
9
+ const EscalationReportBanner = ({ onReport, isExpert }) => {
10
10
  return (react_1.default.createElement("div", { className: "bg-[#EF5360] rounded-lg p-2 mb-4 shadow-lg" },
11
11
  react_1.default.createElement("div", { className: "flex items-center justify-between" },
12
12
  react_1.default.createElement("div", { className: "flex items-center" },
@@ -14,7 +14,12 @@ const EscalationReportBanner = ({ onReport }) => {
14
14
  react_1.default.createElement(base_icons_1.IconExclamation, { className: "text-white" })),
15
15
  react_1.default.createElement("div", null,
16
16
  react_1.default.createElement("h3", { className: "text-xl font-bold text-white" }, "Having Issues with Your Expert?"),
17
- react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" }, "Report communication problems, quality concerns, or missed deadlines. We'll resolve it within 4-8 hours."))),
17
+ react_1.default.createElement("p", { className: "text-red-100 text-sm mt-1" }, isExpert ? (`Report communication problems, quality concerns, or missed deadlines. We'll resolve it within 4-8 hours.`) : (react_1.default.createElement(react_1.default.Fragment, null,
18
+ "Report communication problems, quality concerns, or missed deadlines. All issues right now will be submitted to the Expert and Paro. If you want to submit issues directly to Paro please email",
19
+ ' ',
20
+ react_1.default.createElement("a", { href: "mailto:clientsupport@paro.io", className: "underline text-white hover:text-red-200 cursor-pointer" }, "clientsupport@paro.io"),
21
+ ' ',
22
+ "or your Account Executive."))))),
18
23
  react_1.default.createElement(base_ui_1.Button, { label: "Report issue now", onClick: onReport, size: "sm", color: "danger", className: "bg-white hover:bg-danger text-danger-dark hover:text-white" }))));
19
24
  };
20
25
  exports.default = EscalationReportBanner;
@@ -220,7 +220,12 @@ const EscalationSubmitForm = ({ goBack, goHome, expertsOrClients, projects, docu
220
220
  react_1.default.createElement("h2", { className: "text-xl font-bold" },
221
221
  "Report Issue with Your ",
222
222
  isExpert ? 'Client' : 'Expert'),
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("p", { className: "text-gray-600 mt-1" }, isExpert ? (`Provide details about the issue you're experiencing and we'll resolve it within 4-8 hours`) : (react_1.default.createElement(react_1.default.Fragment, null,
224
+ "Report communication problems, quality concerns, or missed deadlines. All issues right now will be submitted to the Expert and Paro. If you want to submit issues directly to Paro please email",
225
+ ' ',
226
+ react_1.default.createElement("a", { href: "mailto:clientsupport@paro.io", className: "underline text-white hover:text-red-200 cursor-pointer" }, "clientsupport@paro.io"),
227
+ ' ',
228
+ "or your Account Executive.")))),
224
229
  react_1.default.createElement("div", null,
225
230
  react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Priority Levels for Issues"),
226
231
  react_1.default.createElement("div", { className: "space-y-2 text-sm" },
@@ -58,24 +58,35 @@ const EscalationTabsContent = ({ activeTab, openEscalationChat, setSelectedIssue
58
58
  react_1.default.createElement("div", { className: "flex items-start" },
59
59
  react_1.default.createElement("div", null,
60
60
  react_1.default.createElement("div", { className: "flex flex-row justify-start items-center mb-3" },
61
- react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-1 mr-4" }, issue.problem),
61
+ react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-1 mr-4" }, project),
62
62
  react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: issue.severityLevel })),
63
63
  react_1.default.createElement("div", { className: "flex items-center text-sm text-gray-600 mb-2" },
64
- react_1.default.createElement("span", null, issue.submittedByUser.firstName + " " + issue.submittedByUser.lastName),
65
- react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
66
- react_1.default.createElement("span", null, project),
64
+ react_1.default.createElement("span", null,
65
+ "Submitted By: ",
66
+ issue.submittedByUser.firstName + " " + issue.submittedByUser.lastName),
67
67
  react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
68
68
  react_1.default.createElement("span", null,
69
69
  "Case #",
70
70
  issue.escalationNumber)),
71
- react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-3" }, issue.internalResolution ? issue.internalResolution : isExpert ? issue.clientResolution : issue.expertResolution),
71
+ react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-2" },
72
+ react_1.default.createElement("span", { className: "font-bold" }, "Problem:"),
73
+ " ",
74
+ issue.problem),
75
+ react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-2" },
76
+ react_1.default.createElement("span", { className: "font-bold" }, "Desired Outcome:"),
77
+ " ",
78
+ issue.outcome),
79
+ react_1.default.createElement("div", { className: "text-sm text-gray-600 mb-2" },
80
+ react_1.default.createElement("span", { className: "font-bold" }, "Resolution:"),
81
+ " ",
82
+ issue.internalResolution ? issue.internalResolution : issue.clientResolution),
72
83
  react_1.default.createElement("div", { className: "flex items-center text-sm text-gray-600 mb-2" },
73
84
  react_1.default.createElement("span", { className: "text-xs text-gray-500" },
74
- "Resolved ",
85
+ "Resolved: ",
75
86
  (0, dayjs_1.default)(issue.updatedAt).format("MM-DD-YYYY")),
76
87
  react_1.default.createElement("span", { className: "mx-2" }, "\u2022"),
77
88
  react_1.default.createElement("span", { className: "text-xs text-gray-500" },
78
- "Resolved By ",
89
+ "Resolved By: ",
79
90
  issue.statusChangedByUser.firstName + " " + issue.statusChangedByUser.lastName,
80
91
  " ",
81
92
  issue.statusChangedByUser.userTypeId === 2 && '(Paro)')))),
@@ -12,6 +12,7 @@ interface EscalationsProps {
12
12
  bucketName: string;
13
13
  user: any;
14
14
  clientId?: number;
15
+ escalationDisputeStatistics?: any;
15
16
  }
16
- export declare const Escalations: ({ expertsOrClients, projects, isExpert, escalations, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, createProjectEscalation, updateProjectEscalation, createEscalationChatMessage, bucketName, user, clientId, }: EscalationsProps) => JSX.Element;
17
+ export declare const Escalations: ({ expertsOrClients, projects, isExpert, escalations, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, createProjectEscalation, updateProjectEscalation, createEscalationChatMessage, bucketName, user, clientId, escalationDisputeStatistics, }: EscalationsProps) => JSX.Element;
17
18
  export {};
@@ -40,7 +40,7 @@ const AccountSuspensionModal_1 = __importDefault(require("./AccountSuspensionMod
40
40
  const base_icons_1 = require("@paro.io/base-icons");
41
41
  const EscalationIssueCard_1 = require("./EscalationIssueCard");
42
42
  const react_hot_toast_1 = require("react-hot-toast");
43
- const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, createProjectEscalation, updateProjectEscalation, createEscalationChatMessage, bucketName, user, clientId = 0, }) => {
43
+ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations, documentUploadUrl, downloadDocumentUrl, uploadExpertClientFiles, createProjectEscalation, updateProjectEscalation, createEscalationChatMessage, bucketName, user, clientId = 0, escalationDisputeStatistics, }) => {
44
44
  const [activeSection, setActiveSection] = (0, react_1.useState)('support');
45
45
  const [selectedProject, setSelectedProject] = (0, react_1.useState)(null);
46
46
  const [selectedIssueId, setSelectedIssueId] = (0, react_1.useState)(null); // using selectedIssueId 0 for new escalation submission
@@ -156,9 +156,9 @@ const Escalations = ({ expertsOrClients, projects, isExpert = false, escalations
156
156
  react_1.default.createElement("p", { className: "text-xs" }, "Report payment, scope, or communication activeIssues")))),
157
157
  react_1.default.createElement(base_ui_1.Button, { label: "Report issue", onClick: () => setSelectedIssueId(0), iconLeft: react_1.default.createElement(base_icons_1.IconExclamation, { size: "sm", className: "text-white" }), color: "primary" }))),
158
158
  isExpert &&
159
- react_1.default.createElement(AccountSuspensionBanner_1.default, { setShowSuspensionModal: setShowSuspensionModal, suspended: false }),
159
+ react_1.default.createElement(AccountSuspensionBanner_1.default, { setShowSuspensionModal: setShowSuspensionModal, escalationDisputeStatistics: escalationDisputeStatistics }),
160
160
  !isExpert &&
161
- react_1.default.createElement(EscalationReportBanner_1.default, { onReport: () => setSelectedIssueId(0) }),
161
+ react_1.default.createElement(EscalationReportBanner_1.default, { onReport: () => setSelectedIssueId(0), isExpert: isExpert }),
162
162
  escalations.length > 0 ? react_1.default.createElement(EscalationTabs_1.default, { activeTab: activeEscalationTab, setActiveTab: setActiveEscalationTab, activeIssues: activeIssues.length, inProgressIssues: inProgressIssues.length, resolvedIssues: resolvedIssues.length }) : null,
163
163
  react_1.default.createElement(EscalationTabsContent_1.default, { activeTab: activeEscalationTab, openEscalationChat: openEscalationChat, setSelectedIssueId: setSelectedIssueId, activeIssues: activeIssues, inProgressIssues: inProgressIssues, resolvedIssues: resolvedIssues, updateProjectEscalation: updateProjectEscalation, isExpert: isExpert, downloadDocumentUrl: downloadDocumentUrl, bucketName: bucketName, userId: user.userId })),
164
164
  activeSection === 'support' && activeIssues.filter((issue) => issue.escalationNumber === selectedIssueId).length > 0 && (react_1.default.createElement(EscalationRespondForm_1.default, { goBack: goBack, selectedIssue: activeIssues.find((issue) => issue.escalationNumber === selectedIssueId), documentUploadUrl: documentUploadUrl, downloadDocumentUrl: downloadDocumentUrl, bucketName: bucketName, uploadExpertClientFiles: uploadExpertClientFiles, updateProjectEscalation: updateProjectEscalation, goHome: goHome, isExpert: isExpert, userId: user.userId })),
@@ -40,6 +40,7 @@ const utils_1 = require("../shared/utils");
40
40
  const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProjectEscalation, userId, }) => {
41
41
  const [resolutionText, setResolutionText] = (0, react_1.useState)(null);
42
42
  const [submitting, setSubmitting] = (0, react_1.useState)(false);
43
+ const [expertResponsibility, setExpertResponsibility] = (0, react_1.useState)('');
43
44
  const handleSubmit = () => __awaiter(void 0, void 0, void 0, function* () {
44
45
  setSubmitting(true);
45
46
  try {
@@ -50,6 +51,7 @@ const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProj
50
51
  clientResolution: resolutionText,
51
52
  status: 'Resolved',
52
53
  statusChangedBy: userId,
54
+ isExpertAtFault: expertResponsibility === 'atFault' ? true : false,
53
55
  }
54
56
  }
55
57
  });
@@ -78,10 +80,23 @@ const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProj
78
80
  react_1.default.createElement("div", { className: "mt-6 mb-4" },
79
81
  react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" }, "Please provide additional details before marking this issue as resolved."),
80
82
  react_1.default.createElement(base_ui_1.Input, { type: "text", value: resolutionText, placeholder: "Enter details here...", onChange: (e) => setResolutionText(e.target.value) })),
83
+ react_1.default.createElement("p", null, "Please provide additional details before marking this issue as resolved."),
84
+ react_1.default.createElement("div", { style: { marginTop: '1em', marginBottom: '1em' } },
85
+ react_1.default.createElement("label", { className: "block text-sm font-normal mb-1" },
86
+ "Expert Responsibility ",
87
+ react_1.default.createElement("span", { className: "text-sm text-red-800" }, "*")),
88
+ react_1.default.createElement("div", null,
89
+ react_1.default.createElement("label", null,
90
+ react_1.default.createElement("input", { type: "radio", name: "expertResponsibility", value: "atFault", checked: expertResponsibility === 'atFault', onChange: () => setExpertResponsibility('atFault'), required: true }),
91
+ "Expert is at fault for this issue")),
92
+ react_1.default.createElement("div", null,
93
+ react_1.default.createElement("label", null,
94
+ react_1.default.createElement("input", { type: "radio", name: "expertResponsibility", value: "notAtFault", checked: expertResponsibility === 'notAtFault', onChange: () => setExpertResponsibility('notAtFault'), required: true }),
95
+ "Expert is NOT at fault"))),
81
96
  react_1.default.createElement("div", { className: "flex items-center justify-between" },
82
97
  react_1.default.createElement("div", { className: "flex space-x-2" },
83
98
  react_1.default.createElement(base_ui_1.Button, { label: "Cancel", onClick: onClose, disabled: submitting })),
84
99
  react_1.default.createElement("div", { className: "flex space-x-2" },
85
- react_1.default.createElement(base_ui_1.Button, { label: "Submit", color: "primary", onClick: handleSubmit, isLoading: submitting }))))));
100
+ react_1.default.createElement(base_ui_1.Button, { label: "Submit", color: "primary", onClick: handleSubmit, isLoading: submitting, disabled: expertResponsibility === '' }))))));
86
101
  };
87
102
  exports.default = MarkResolvedModal;
@@ -16,5 +16,6 @@ interface EarningsSectionProps {
16
16
  hasCompletedProjects: boolean;
17
17
  lifetimeFSV: any;
18
18
  }
19
+ export declare const EarningsInfo: ({ label, value, textColor }: any) => JSX.Element;
19
20
  declare const EarningsSection: ({ expertServiceLinesPlus, firmTags, haveATeamProp, expertLevels, currentMonthGoalHours, expertIRPRRatio, winRate, expertIRPRRatioPrev, winRatePrev, earnings, upsell, crossSell, lifetimeIRPR, lifetimeWinRate, hasCompletedProjects, lifetimeFSV }: EarningsSectionProps) => JSX.Element;
20
21
  export default EarningsSection;
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.EarningsInfo = void 0;
17
18
  const core_1 = require("@material-ui/core");
18
19
  const styles_1 = require("@material-ui/core/styles");
19
20
  const react_1 = __importDefault(require("react"));
@@ -64,6 +65,7 @@ const FirmTags = (_a) => {
64
65
  const EarningsInfo = ({ label, value, textColor = 'black' }) => (react_1.default.createElement(core_1.Box, { mr: 2, display: "flex", justifyContent: "space-between", alignItems: "center" },
65
66
  react_1.default.createElement(core_1.Typography, { variant: "body2" }, label),
66
67
  react_1.default.createElement("b", { style: { color: textColor } }, value)));
68
+ exports.EarningsInfo = EarningsInfo;
67
69
  const DataCell = ({ label, value }) => {
68
70
  //@ts-ignore
69
71
  const classes = useStyles();
@@ -129,16 +131,16 @@ const EarningsSection = ({ expertServiceLinesPlus, firmTags, haveATeamProp, expe
129
131
  react_1.default.createElement(core_1.Box, { mb: 1 },
130
132
  react_1.default.createElement("b", null, "Expert Earnings :")),
131
133
  hasCompletedProjects ? (react_1.default.createElement(react_1.default.Fragment, null,
132
- react_1.default.createElement(EarningsInfo, { label: "Monthly Goal", value: currentMonthGoalHours > 0 ? `$ ${ToLocalStringFn(currentMonthGoalHours)}` : 'N/A' }),
134
+ react_1.default.createElement(exports.EarningsInfo, { label: "Monthly Goal", value: currentMonthGoalHours > 0 ? `$ ${ToLocalStringFn(currentMonthGoalHours)}` : 'N/A' }),
133
135
  react_1.default.createElement(core_1.Box, { mb: 2 },
134
136
  react_1.default.createElement(core_1.Divider, null)),
135
- react_1.default.createElement(EarningsInfo, { label: "Monthly Earnings", value: (earnings === null || earnings === void 0 ? void 0 : earnings.length) > 0 ? `$ ${ToLocalStringFn(earning)}` : 'N/A' }),
137
+ react_1.default.createElement(exports.EarningsInfo, { label: "Monthly Earnings", value: (earnings === null || earnings === void 0 ? void 0 : earnings.length) > 0 ? `$ ${ToLocalStringFn(earning)}` : 'N/A' }),
136
138
  react_1.default.createElement(core_1.Box, { mb: 2 },
137
139
  react_1.default.createElement(core_1.Divider, null)),
138
- react_1.default.createElement(EarningsInfo, { label: "% to Goal", value: currentMonthGoalHours && earning ? `${ToLocalStringFn(((earning / currentMonthGoalHours) * 100).toFixed(2))} %` : 'N/A' }),
140
+ react_1.default.createElement(exports.EarningsInfo, { label: "% to Goal", value: currentMonthGoalHours && earning ? `${ToLocalStringFn(((earning / currentMonthGoalHours) * 100).toFixed(2))} %` : 'N/A' }),
139
141
  react_1.default.createElement(core_1.Box, { mb: 2 },
140
142
  react_1.default.createElement(core_1.Divider, null)),
141
- react_1.default.createElement(EarningsInfo, { label: "Lifetime FSV", value: lifetimeFSV ? ToLocalStringFn(lifetimeFSV) : 'N/A', textColor: backgroundColor }),
143
+ react_1.default.createElement(exports.EarningsInfo, { label: "Lifetime FSV", value: lifetimeFSV ? ToLocalStringFn(lifetimeFSV) : 'N/A', textColor: backgroundColor }),
142
144
  react_1.default.createElement(core_1.Box, { mb: 2 },
143
145
  react_1.default.createElement(core_1.Divider, null)),
144
146
  react_1.default.createElement(ExpertStatsTable, { expertIRPRRatioPrev: expertIRPRRatioPrev, expertIRPRRatio: expertIRPRRatio, winRatePrev: winRatePrev, winRate: winRate, lifetimeIRPR: lifetimeIRPR, lifetimeWinRate: lifetimeWinRate }))) : (react_1.default.createElement(core_1.Typography, { variant: "body1" }, "This Expert has not billed yet")))));
@@ -64,6 +64,8 @@ type QueryAndMutationProps = {
64
64
  getExpertVanityTitles?: any;
65
65
  getExpertRates?: any;
66
66
  updateExpert?: any;
67
+ escalationDisputeStatistics?: any;
68
+ escalationDisputeStatisticsLoading?: any;
67
69
  };
68
70
  type ChangeEmailPasswordProps = {
69
71
  getUserByEmail?: any;
@@ -79,5 +81,5 @@ type ProfileCompletedPercentageProps = {
79
81
  handleScrollToBottom?: () => void;
80
82
  clientReferencesSectionCompleted: boolean;
81
83
  };
82
- export declare const ExpertProfileHeader: ({ expertId, legacyFreelancerId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, clientReferencesSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, openServiceLinesTemplate, setOpenServiceLinesTemplate, getExpertVanityTitles, getExpertRates, updateExpert, vanityTitle, }: SectionContents & PersonalInformationType & ProfileCompletedPercentageProps & QueryAndMutationProps & ChangeEmailPasswordProps) => JSX.Element;
84
+ export declare const ExpertProfileHeader: ({ expertId, legacyFreelancerId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, clientReferencesSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, openServiceLinesTemplate, setOpenServiceLinesTemplate, getExpertVanityTitles, getExpertRates, updateExpert, vanityTitle, escalationDisputeStatistics, escalationDisputeStatisticsLoading, }: SectionContents & PersonalInformationType & ProfileCompletedPercentageProps & QueryAndMutationProps & ChangeEmailPasswordProps) => JSX.Element;
83
85
  export {};
@@ -76,7 +76,7 @@ const convertRegionToStateAbbreviation = (region) => {
76
76
  const personalInformationReducer = (state, updatedState) => {
77
77
  return Object.assign(Object.assign({}, state), updatedState);
78
78
  };
79
- const ExpertProfileHeader = ({ expertId, legacyFreelancerId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, clientReferencesSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, openServiceLinesTemplate, setOpenServiceLinesTemplate, getExpertVanityTitles, getExpertRates, updateExpert, vanityTitle, }) => {
79
+ const ExpertProfileHeader = ({ expertId, legacyFreelancerId, address: addressForReducer, companyName: companyNameForReducer, legacyMetadata: legacyMetadataForReducer, legacyMetadata: { primaryServiceLine, applicationStatus }, user: userForReducer, user: { id, imageUrl, email }, firmTags, detailsSectionCompleted, clientReferencesSectionCompleted, preferenceTasks, isWhiteLabel, handleScrollToBottom, haveATeamProp, expertFirms, paroAppUrl, isExpertOps, internalUserId, getExpertByLegacyFreelancerIdDocument, createExpertPublicProfileTrackingRecord, updateFreelancerServiceLine, serviceLineLoading, serviceLineData, serviceLineError, reviewData, profileReviewError, availabilityData, nextMonthAvailabilityData, expertStatusData, expertStatusLoading, expertLevelsData, projectsData, paroProjectsLoading, expertMetricsData, expertMetricsLoading, upSellCrossSellData, upSellCrossSellLoading, projectChangeLogData, projectChangeLogLoading, updateAddressMutation, addressUpdateLoading, updateUserMutation, userUpdateLoading, updateUserError, updateFreelancerMutation, updateFreelancerLoading, updateFreelancerError, getFreelancerEarnings, getQualityKPIs, expertLevelsTrainings, trainingsDataLoading, assignLetterTrainingToExpert, assignTrainingLoading, assignTrainingError, getUserDocument, getExpertStatusDocument, uploadUserPhotoMutation, loadingNewImage, imageUpdateError, getUserByEmail, updateUserEmail, getUserByEmailLazyQuery, updateUserPassword, verifyUserPassword, openServiceLinesTemplate, setOpenServiceLinesTemplate, getExpertVanityTitles, getExpertRates, updateExpert, vanityTitle, escalationDisputeStatistics, escalationDisputeStatisticsLoading, }) => {
80
80
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
81
81
  const [leftSideStatus, setLeftSideStatus] = react_1.default.useState("");
82
82
  const [rightSideStatus, setRightSideStatus] = react_1.default.useState("");
@@ -142,7 +142,7 @@ const ExpertProfileHeader = ({ expertId, legacyFreelancerId, address: addressFor
142
142
  const expertServiceLinesPlus = (serviceLineData === null || serviceLineData === void 0 ? void 0 : serviceLineData.getExpertByLegacyFreelancerId.serviceLinesPlus) || [];
143
143
  const expertLevels = expertLevelsData === null || expertLevelsData === void 0 ? void 0 : expertLevelsData.getExpertLevelsData;
144
144
  if ((expertStatuses && expertMetricsData && leftSideStatus === "" && rightSideStatus === "") || triggerNewStatus) {
145
- (0, ExpertStatusCalculator_1.default)(expertStatuses, setLeftSideStatus, setRightSideStatus, setInfoColor, expertMetricsData, earnings, applicationStatus, setTriggerNewStatus);
145
+ (0, ExpertStatusCalculator_1.default)(expertStatuses, setLeftSideStatus, setRightSideStatus, setInfoColor, expertMetricsData, earnings, applicationStatus, setTriggerNewStatus, escalationDisputeStatistics);
146
146
  }
147
147
  const [open, setOpen] = react_1.default.useState(false);
148
148
  const [reducedPersonalInformation, dispatchUpdatedPersonalInformationUpdate] = react_1.default.useReducer(personalInformationReducer, {
@@ -165,7 +165,7 @@ const ExpertProfileHeader = ({ expertId, legacyFreelancerId, address: addressFor
165
165
  return react_1.default.createElement(ParoError_1.ParoError, null);
166
166
  }
167
167
  const publicProfileLink = `${paroAppUrl}/public/${id}`;
168
- if (expertStatusLoading || expertMetricsLoading || serviceLineLoading || paroProjectsLoading || projectChangeLogLoading || upSellCrossSellLoading) {
168
+ if (expertStatusLoading || expertMetricsLoading || serviceLineLoading || paroProjectsLoading || projectChangeLogLoading || upSellCrossSellLoading || escalationDisputeStatisticsLoading) {
169
169
  return react_1.default.createElement(Loader_1.default, { size: '30px', text: 'Loading Expert Stats...' });
170
170
  }
171
171
  const ServiceLines = [
@@ -219,7 +219,7 @@ const ExpertProfileHeader = ({ expertId, legacyFreelancerId, address: addressFor
219
219
  react_1.default.createElement(ProfileSection_1.default, { legacyFreelancerId: Number(legacyFreelancerId), imageUrl: imageUrl, shouldAllowEditProfile: isExpertOps !== null && isExpertOps !== void 0 ? isExpertOps : false, firstName: firstName, lastName: lastName, primaryServiceLine: primaryServiceLine, editServiceLine: editServiceLine, city: city, stateAbbreviation: stateAbbreviation, email: email, phone: phone, setOpen: setOpen, paroTenure: paroTenure, hourlyRate: defaultHourlyRate, paroProjectsData: paroProjectsData, getUserDocument: getUserDocument, uploadUserPhotoMutation: uploadUserPhotoMutation, loadingNewImage: loadingNewImage, imageUpdateError: imageUpdateError, isInternal: isInternal, getUserByEmail: getUserByEmail, updateUserEmail: updateUserEmail, updateUserMutation: updateUserMutation, getUserByEmailLazyQuery: getUserByEmailLazyQuery, updateUserPassword: updateUserPassword, verifyUserPassword: verifyUserPassword, getExpertRates: getExpertRates }),
220
220
  react_1.default.createElement(core_1.Divider, { orientation: isSmallScreen ? 'horizontal' : 'vertical', style: { marginLeft: '0px !important' } })),
221
221
  react_1.default.createElement(core_1.Grid, { item: true, container: true, direction: 'column', justify: 'space-between', xs: 12, md: true, style: { flex: '1', width: 'auto' } },
222
- react_1.default.createElement(NetworkSection_1.default, { handleScrollToBottom: isInternal && handleScrollToBottom ? handleScrollToBottom : () => { }, preferenceTasks: preferenceTasks, isWhiteLabel: isWhiteLabel, detailsSectionCompleted: detailsSectionCompleted, clientReferencesSectionCompleted: clientReferencesSectionCompleted, infoColor: infoColor, leftSideStatus: leftSideStatus, rightSideStatus: rightSideStatus, isInternal: isInternal, paroTenure: paroTenure, getExpertVanityTitles: getExpertVanityTitles, updateExpert: updateExpert, expertId: expertId, legacyFreelancerId: Number(legacyFreelancerId), vanityTitle: vanityTitle, getExpertByLegacyFreelancerIdDocument: getExpertByLegacyFreelancerIdDocument }),
222
+ react_1.default.createElement(NetworkSection_1.default, { handleScrollToBottom: isInternal && handleScrollToBottom ? handleScrollToBottom : () => { }, preferenceTasks: preferenceTasks, isWhiteLabel: isWhiteLabel, detailsSectionCompleted: detailsSectionCompleted, clientReferencesSectionCompleted: clientReferencesSectionCompleted, infoColor: infoColor, leftSideStatus: leftSideStatus, rightSideStatus: rightSideStatus, isInternal: isInternal, paroTenure: paroTenure, getExpertVanityTitles: getExpertVanityTitles, updateExpert: updateExpert, expertId: expertId, legacyFreelancerId: Number(legacyFreelancerId), vanityTitle: vanityTitle, getExpertByLegacyFreelancerIdDocument: getExpertByLegacyFreelancerIdDocument, escalationDisputeStatistics: escalationDisputeStatistics, paroAppUrl: paroAppUrl }),
223
223
  react_1.default.createElement(core_1.Divider, { orientation: isSmallScreen ? 'horizontal' : 'vertical' })),
224
224
  react_1.default.createElement(core_1.Grid, { item: true, container: true, direction: 'column', justify: 'space-between', xs: 12, md: true, style: { flex: '1', width: 'auto' } },
225
225
  react_1.default.createElement(EarningsSection_1.default, { expertServiceLinesPlus: expertServiceLinesPlus, firmTags: firmTags, haveATeamProp: haveATeamProp, expertLevels: expertLevels, currentMonthGoalHours: currentMonthGoalHours, expertIRPRRatio: expertIRPRRatio, winRate: winRate, expertIRPRRatioPrev: expertIRPRRatioPrev, winRatePrev: winRatePrev, earnings: earnings, upsell: upsell, crossSell: crossSell, lifetimeIRPR: lifetimeIRPR, lifetimeWinRate: lifetimeWinRate, hasCompletedProjects: (_k = expertMetricsData === null || expertMetricsData === void 0 ? void 0 : expertMetricsData.getExpertMetrics) === null || _k === void 0 ? void 0 : _k.lastProjectCompleted, lifetimeFSV: lifetimeFSV }),
@@ -20,5 +20,5 @@ export type ExpertStatusData = {
20
20
  hasValidInsurance: boolean;
21
21
  insuranceExpiryDate: Date;
22
22
  };
23
- declare const ExpertStatusCalculator: (statusData: ExpertStatusData, setLeftSideStatus: (leftSideStatus: string) => void, setRightSideStatus: (rightSideStatus: string) => void, setInfoColor: ({ leftSideStatus, rightSideStatus, Matching, FaF, JobBoard, Available }: any) => void, expertMetricsData: any, earningsData: any, applicationStatus: any, setTriggerNewStatus: any) => void;
23
+ declare const ExpertStatusCalculator: (statusData: ExpertStatusData, setLeftSideStatus: (leftSideStatus: string) => void, setRightSideStatus: (rightSideStatus: string) => void, setInfoColor: ({ leftSideStatus, rightSideStatus, Matching, FaF, JobBoard, Available }: any) => void, expertMetricsData: any, earningsData: any, applicationStatus: any, setTriggerNewStatus: any, escalationDisputeStatistics: any) => void;
24
24
  export default ExpertStatusCalculator;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("../shared/utils");
4
+ const AccountSuspensionBanner_1 = require("../Escalations/AccountSuspensionBanner");
4
5
  const isDespiseExpert = (earningsToShow, lastPitchDate, lastLoginDate, applicationStatus) => {
5
6
  // Expert is in Despise Status IF:
6
7
  // Active Expert who has no logins, no pitches, no earnings in the last 30 days
@@ -11,18 +12,28 @@ const isDespiseExpert = (earningsToShow, lastPitchDate, lastLoginDate, applicati
11
12
  const earnedInLast2Months = earningsToShow.filter((earning) => earning.earnings_type === 'actual' && (earning.month === formattedPreviousMonthDate || earning.month === formattedCurrentMonthDate));
12
13
  return (0, utils_1.isOlderThan30Days)(lastPitchDate) && (0, utils_1.isOlderThan30Days)(lastLoginDate) && earnedInLast2Months.length === 0 && applicationStatus === 'ACTIVE';
13
14
  };
14
- const ExpertStatusCalculator = (statusData, setLeftSideStatus, setRightSideStatus, setInfoColor, expertMetricsData, earningsData, applicationStatus, setTriggerNewStatus) => {
15
+ const ExpertStatusCalculator = (statusData, setLeftSideStatus, setRightSideStatus, setInfoColor, expertMetricsData, earningsData, applicationStatus, setTriggerNewStatus, escalationDisputeStatistics) => {
16
+ var _a, _b;
15
17
  const suspensionStatus = (statusData.suspensionEndDate && statusData.suspensionEndDate !== "")
16
18
  ? `! Suspended till ${statusData.suspensionEndDate}, see notes.`
17
19
  : '! Suspended, see notes.';
20
+ const suspensionLevel = (_b = (_a = AccountSuspensionBanner_1.suspensionLevels.find((obj) => obj.value === escalationDisputeStatistics.suspensionLevel)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : "Low";
21
+ const startDate = escalationDisputeStatistics.suspensionStartDate ? new Date(escalationDisputeStatistics.suspensionStartDate).toLocaleDateString() : '';
22
+ const endDate = escalationDisputeStatistics.suspensionEndDate ? new Date(escalationDisputeStatistics.suspensionEndDate).toLocaleDateString() : '';
18
23
  if (statusData.churnedPermanently) {
19
24
  const formattedDate = new Date(statusData.churnedDate).toLocaleDateString();
20
25
  setLeftSideStatus('This Expert has been churned from the Network and cannot take on new projects.');
21
26
  setRightSideStatus(`! Churned ${formattedDate} - Not eligible for rehire. See notes.`);
22
27
  }
23
28
  else if (statusData.suspended) {
24
- setLeftSideStatus('This Expert is currently suspended and is unable to take on new projects.');
25
- setRightSideStatus(`${suspensionStatus}`);
29
+ if (suspensionLevel !== "Low" && startDate && endDate) { // suspension due to escalations
30
+ setLeftSideStatus(`The Expert is on ${suspensionLevel} severity level for Escalations.`);
31
+ setRightSideStatus(`This Expert has been suspended due to severity strikes on escalations and was suspended on ${startDate} and will come off suspension on ${endDate} due.`);
32
+ }
33
+ else { // suspension due to other reasons
34
+ setLeftSideStatus('This Expert is currently suspended and is unable to take on new projects.');
35
+ setRightSideStatus(`${suspensionStatus}`);
36
+ }
26
37
  }
27
38
  else if (statusData.churned) {
28
39
  const formattedDate = new Date(statusData.churnedDate).toLocaleDateString();
@@ -15,6 +15,8 @@ interface NetworkSectionProps {
15
15
  expertId: string;
16
16
  vanityTitle: string;
17
17
  getExpertByLegacyFreelancerIdDocument: any;
18
+ escalationDisputeStatistics: any;
19
+ paroAppUrl: string;
18
20
  }
19
- declare const NetworkSection: ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, detailsSectionCompleted, clientReferencesSectionCompleted, infoColor, leftSideStatus, rightSideStatus, isInternal, paroTenure, getExpertVanityTitles, updateExpert, expertId, legacyFreelancerId, vanityTitle, getExpertByLegacyFreelancerIdDocument, }: NetworkSectionProps) => JSX.Element;
21
+ declare const NetworkSection: ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, detailsSectionCompleted, clientReferencesSectionCompleted, infoColor, leftSideStatus, rightSideStatus, isInternal, paroTenure, getExpertVanityTitles, updateExpert, expertId, legacyFreelancerId, vanityTitle, getExpertByLegacyFreelancerIdDocument, escalationDisputeStatistics, paroAppUrl, }: NetworkSectionProps) => JSX.Element;
20
22
  export default NetworkSection;
@@ -39,6 +39,10 @@ const ProfileCompletedPercentange_1 = require("../ProfileCompletedPercentange");
39
39
  const icons_1 = require("@material-ui/icons");
40
40
  const ReviewsTab_1 = require("../ReviewsTab/ReviewsTab");
41
41
  const base_ui_1 = require("@paro.io/base-ui");
42
+ const EarningsSection_1 = require("./EarningsSection");
43
+ const base_icons_1 = require("@paro.io/base-icons");
44
+ const EscalationIssueCard_1 = require("../Escalations/EscalationIssueCard");
45
+ const AccountSuspensionBanner_1 = require("../Escalations/AccountSuspensionBanner");
42
46
  const useStyles = (0, styles_1.makeStyles)((theme) => ({
43
47
  textSuccess: {
44
48
  color: '#12756F',
@@ -75,11 +79,32 @@ const ExpertiseTitleModal = ({ openModal, updateTitle, titleOptions, selectedTit
75
79
  react_1.default.createElement(base_ui_1.Button, { label: "UPDATE PROFILE", onClick: handleUpdateExpertTitle, type: "button", isLoading: updateTitle, disabled: selectedTitle === null || (selectedTitle === 'Other' && (customTitle === null || customTitle === '')), color: "primary" }),
76
80
  react_1.default.createElement(base_ui_1.Button, { label: "CANCEL", onClick: handleOnClose, type: "button", disabled: updateTitle, isLoading: updateTitle })))));
77
81
  };
78
- const NetworkSection = ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, detailsSectionCompleted, clientReferencesSectionCompleted, infoColor, leftSideStatus, rightSideStatus, isInternal, paroTenure, getExpertVanityTitles, updateExpert, expertId, legacyFreelancerId, vanityTitle, getExpertByLegacyFreelancerIdDocument, }) => {
82
+ const PriorityLevelModal = ({ openModal, onClose }) => {
83
+ return (react_1.default.createElement(base_ui_1.Modal, { open: openModal, size: "sm", onClose: onClose },
84
+ react_1.default.createElement("div", { className: "border border-1 border-gray-300 p-4 rounded-md gap-y-2" },
85
+ react_1.default.createElement("h4", { className: "font-medium text-gray-900 mb-2" }, "Severity Levels for Issues"),
86
+ react_1.default.createElement("div", { className: "space-y-2 text-sm" },
87
+ react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
88
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Critical" }),
89
+ react_1.default.createElement("span", null, "All deliverables are currently blocked; the project cannot move forward.")),
90
+ react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
91
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "High" }),
92
+ react_1.default.createElement("span", null, "Key deliverables are blocked, preventing meaningful progress.")),
93
+ react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
94
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Medium" }),
95
+ react_1.default.createElement("span", null, "Deliverables are still in progress, but timelines are at risk.")),
96
+ react_1.default.createElement("div", { className: "flex items-center gap-x-2" },
97
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Low" }),
98
+ react_1.default.createElement("span", null, "Minor issue or inconvenience that does not affect overall project flow."))))));
99
+ };
100
+ const NetworkSection = ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, detailsSectionCompleted, clientReferencesSectionCompleted, infoColor, leftSideStatus, rightSideStatus, isInternal, paroTenure, getExpertVanityTitles, updateExpert, expertId, legacyFreelancerId, vanityTitle, getExpertByLegacyFreelancerIdDocument, escalationDisputeStatistics, paroAppUrl, }) => {
101
+ var _a, _b, _c, _d, _e, _f;
79
102
  const [openModal, setOpenModal] = (0, react_1.useState)(false);
80
103
  const [selectedTitle, setSelectedTitle] = (0, react_1.useState)(vanityTitle);
81
104
  const [customTitle, setCustomTitle] = (0, react_1.useState)(null);
82
105
  const [updateTitle, setUpdateTitle] = (0, react_1.useState)(false);
106
+ const [showPriorityLevelModal, setShowPriorityLevelModal] = (0, react_1.useState)(false);
107
+ const suspensionLevel = (_b = (_a = AccountSuspensionBanner_1.suspensionLevels.find((obj) => obj.value === escalationDisputeStatistics.suspensionLevel)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : "Low";
83
108
  const handleUpdateExpertTitle = () => __awaiter(void 0, void 0, void 0, function* () {
84
109
  setUpdateTitle(true);
85
110
  updateExpert({
@@ -129,6 +154,21 @@ const NetworkSection = ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, d
129
154
  react_1.default.createElement(icons_1.Cached, null))),
130
155
  react_1.default.createElement(core_1.Box, { mt: 1, mb: 1, mr: 2 },
131
156
  react_1.default.createElement(core_1.Divider, null))),
157
+ escalationDisputeStatistics &&
158
+ react_1.default.createElement(react_1.default.Fragment, null,
159
+ react_1.default.createElement(EarningsSection_1.EarningsInfo, { label: "# of Escalations in last 3 months", value: (_c = escalationDisputeStatistics.recentResolvedEscalations) !== null && _c !== void 0 ? _c : 0 }),
160
+ react_1.default.createElement(core_1.Box, { mb: 2 },
161
+ react_1.default.createElement(core_1.Divider, null)),
162
+ react_1.default.createElement(EarningsSection_1.EarningsInfo, { label: "Total # of Escalations", value: (_d = escalationDisputeStatistics.totalResolvedEscalations) !== null && _d !== void 0 ? _d : 0 }),
163
+ react_1.default.createElement(core_1.Box, { mb: 2 },
164
+ react_1.default.createElement(core_1.Divider, null)),
165
+ react_1.default.createElement(EarningsSection_1.EarningsInfo, { label: "# of Disputes in last 3 months", value: (_e = escalationDisputeStatistics.recentResolvedDisputes) !== null && _e !== void 0 ? _e : 0 }),
166
+ react_1.default.createElement(core_1.Box, { mb: 2 },
167
+ react_1.default.createElement(core_1.Divider, null)),
168
+ react_1.default.createElement(EarningsSection_1.EarningsInfo, { label: "Total # of Disputes", value: (_f = escalationDisputeStatistics.totalResolvedDisputes) !== null && _f !== void 0 ? _f : 0 }),
169
+ react_1.default.createElement(core_1.Box, { mb: 0.5 },
170
+ react_1.default.createElement(core_1.Divider, null)),
171
+ !isInternal && react_1.default.createElement("a", { href: `${paroAppUrl}/engagement-support`, className: "text-xs underline text-[#1878BD] cursor-pointer block text-right mb-2", target: "_blank", rel: "noopener noreferrer" }, "See more Disputes & Escalations")),
132
172
  react_1.default.createElement(core_1.Grid, { style: { marginRight: '8px', marginLeft: '2px' } },
133
173
  react_1.default.createElement(core_1.Box, { mb: 1 },
134
174
  react_1.default.createElement("b", null, "Network Availability :")),
@@ -148,9 +188,15 @@ const NetworkSection = ({ handleScrollToBottom, preferenceTasks, isWhiteLabel, d
148
188
  react_1.default.createElement(core_1.Box, null,
149
189
  react_1.default.createElement("b", null, "Reason: "),
150
190
  react_1.default.createElement("ul", null,
151
- react_1.default.createElement("li", null, leftSideStatus),
191
+ react_1.default.createElement("li", null,
192
+ leftSideStatus,
193
+ " ",
194
+ suspensionLevel !== "Low" && react_1.default.createElement(core_1.IconButton, { "aria-label": "Show priority levels", onClick: () => { setShowPriorityLevelModal(true); } },
195
+ react_1.default.createElement(base_icons_1.IconInfoCircle, { size: "sm", className: "block text-right" }))),
152
196
  react_1.default.createElement("li", null, rightSideStatus)))),
153
197
  openModal &&
154
- react_1.default.createElement(ExpertiseTitleModal, { openModal: openModal, updateTitle: updateTitle, titleOptions: [...getExpertVanityTitles], selectedTitle: selectedTitle, customTitle: customTitle, setCustomTitle: setCustomTitle, handleChangeTitle: (event) => { setSelectedTitle(event.target.value); }, handleOnClose: () => setOpenModal(false), handleUpdateExpertTitle: handleUpdateExpertTitle })));
198
+ react_1.default.createElement(ExpertiseTitleModal, { openModal: openModal, updateTitle: updateTitle, titleOptions: [...getExpertVanityTitles], selectedTitle: selectedTitle, customTitle: customTitle, setCustomTitle: setCustomTitle, handleChangeTitle: (event) => { setSelectedTitle(event.target.value); }, handleOnClose: () => setOpenModal(false), handleUpdateExpertTitle: handleUpdateExpertTitle }),
199
+ showPriorityLevelModal &&
200
+ react_1.default.createElement(PriorityLevelModal, { openModal: showPriorityLevelModal, onClose: () => setShowPriorityLevelModal(false) })));
155
201
  };
156
202
  exports.default = NetworkSection;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paro.io/expert-shared-components",
3
- "version": "1.13.8",
3
+ "version": "1.13.10",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {