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

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.
Files changed (31) hide show
  1. package/lib/components/Escalations/AccountSuspensionModal.js +25 -49
  2. package/lib/components/Escalations/EscalationChat.js +10 -12
  3. package/lib/components/Escalations/EscalationIssueCard.d.ts +1 -0
  4. package/lib/components/Escalations/EscalationIssueCard.js +39 -4
  5. package/lib/components/Escalations/EscalationRespondForm.js +11 -13
  6. package/lib/components/Escalations/EscalationSubmitForm.js +15 -20
  7. package/lib/components/Escalations/EscalationTabsContent.d.ts +2 -1
  8. package/lib/components/Escalations/EscalationTabsContent.js +6 -2
  9. package/lib/components/Escalations/Escalations.d.ts +2 -1
  10. package/lib/components/Escalations/Escalations.js +22 -9
  11. package/lib/components/Escalations/MarkResolvedModal.d.ts +2 -1
  12. package/lib/components/Escalations/MarkResolvedModal.js +10 -9
  13. package/lib/components/ProjectIntelligence/EngagementHeader/index.d.ts +18 -0
  14. package/lib/components/ProjectIntelligence/EngagementHeader/index.js +47 -0
  15. package/lib/components/ProjectIntelligence/FocusAreas/index.d.ts +18 -0
  16. package/lib/components/ProjectIntelligence/FocusAreas/index.js +156 -0
  17. package/lib/components/ProjectIntelligence/KeyMetrics/index.d.ts +12 -0
  18. package/lib/components/ProjectIntelligence/KeyMetrics/index.js +148 -0
  19. package/lib/components/ProjectIntelligence/MissingInformation/index.d.ts +24 -0
  20. package/lib/components/ProjectIntelligence/MissingInformation/index.js +218 -0
  21. package/lib/components/ProjectIntelligence/ProgressTracker/index.d.ts +8 -0
  22. package/lib/components/ProjectIntelligence/ProgressTracker/index.js +21 -0
  23. package/lib/components/ProjectIntelligence/ProjectHealth/index.d.ts +25 -0
  24. package/lib/components/ProjectIntelligence/ProjectHealth/index.js +42 -0
  25. package/lib/components/ProjectIntelligence/TeamSection/index.d.ts +25 -0
  26. package/lib/components/ProjectIntelligence/TeamSection/index.js +41 -0
  27. package/lib/components/ProjectIntelligence/index.d.ts +17 -0
  28. package/lib/components/ProjectIntelligence/index.js +146 -0
  29. package/lib/index.d.ts +1 -0
  30. package/lib/index.js +3 -1
  31. package/package.json +1 -1
@@ -37,7 +37,7 @@ const base_icons_1 = require("@paro.io/base-icons");
37
37
  const base_ui_1 = require("@paro.io/base-ui");
38
38
  const core_1 = require("@material-ui/core");
39
39
  const utils_1 = require("../shared/utils");
40
- const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProjectEscalation, userId, }) => {
40
+ const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProjectEscalation, userId, refetchEscalationDisputeStatistics, }) => {
41
41
  const [resolutionText, setResolutionText] = (0, react_1.useState)(null);
42
42
  const [submitting, setSubmitting] = (0, react_1.useState)(false);
43
43
  const [expertResponsibility, setExpertResponsibility] = (0, react_1.useState)('');
@@ -53,7 +53,9 @@ const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProj
53
53
  statusChangedBy: userId,
54
54
  isExpertAtFault: expertResponsibility === 'atFault' ? true : false,
55
55
  }
56
- }
56
+ },
57
+ }).then(() => {
58
+ refetchEscalationDisputeStatistics && refetchEscalationDisputeStatistics();
57
59
  });
58
60
  (0, utils_1.showToast)("success", "Issue marked as resolved. You can now find it in the `Resolved` section");
59
61
  }
@@ -80,23 +82,22 @@ const MarkResolvedModal = ({ escalationId, expertName, open, onClose, updateProj
80
82
  react_1.default.createElement("div", { className: "mt-6 mb-4" },
81
83
  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."),
82
84
  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
85
  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
+ react_1.default.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-1" },
86
87
  "Expert Responsibility ",
87
88
  react_1.default.createElement("span", { className: "text-sm text-red-800" }, "*")),
88
89
  react_1.default.createElement("div", null,
89
- react_1.default.createElement("label", null,
90
+ react_1.default.createElement("label", { className: "flex items-center space-x-2" },
90
91
  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("span", null, "Expert is at fault for this issue"))),
92
93
  react_1.default.createElement("div", null,
93
- react_1.default.createElement("label", null,
94
+ react_1.default.createElement("label", { className: "flex items-center space-x-2" },
94
95
  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"))),
96
+ react_1.default.createElement("span", null, "Expert is NOT at fault for this issue")))),
96
97
  react_1.default.createElement("div", { className: "flex items-center justify-between" },
97
98
  react_1.default.createElement("div", { className: "flex space-x-2" },
98
99
  react_1.default.createElement(base_ui_1.Button, { label: "Cancel", onClick: onClose, disabled: submitting })),
99
100
  react_1.default.createElement("div", { className: "flex space-x-2" },
100
- react_1.default.createElement(base_ui_1.Button, { label: "Submit", color: "primary", onClick: handleSubmit, isLoading: submitting, disabled: expertResponsibility === '' }))))));
101
+ react_1.default.createElement(base_ui_1.Button, { label: "Submit", color: "primary", onClick: handleSubmit, isLoading: submitting, disabled: expertResponsibility === '' || !resolutionText || resolutionText.trim() === '' }))))));
101
102
  };
102
103
  exports.default = MarkResolvedModal;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ interface ClientTab {
3
+ id: string;
4
+ label: string;
5
+ clientId: string;
6
+ }
7
+ interface EngagementHeaderProps {
8
+ clientName: string;
9
+ expertName: string;
10
+ expertTitle: string;
11
+ startDate: string;
12
+ status: 'Discovery' | 'Kickoff_Complete' | 'In_Progress' | 'Completed' | 'Paused' | 'Cancelled';
13
+ clientTabs: ClientTab[];
14
+ selectedClientId: string | null;
15
+ onClientChange: (opportunityId: string) => void;
16
+ }
17
+ export declare const EngagementHeader: React.FC<EngagementHeaderProps>;
18
+ export {};
@@ -0,0 +1,47 @@
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
+ exports.EngagementHeader = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const date_fns_1 = require("date-fns");
9
+ const base_ui_1 = require("@paro.io/base-ui");
10
+ const EscalationIssueCard_1 = require("../../Escalations/EscalationIssueCard");
11
+ const STATUS_COLORS = {
12
+ Discovery: 'warning',
13
+ Kickoff_Complete: 'success',
14
+ In_Progress: 'info',
15
+ Completed: 'neutral',
16
+ Paused: 'warning',
17
+ Cancelled: 'danger',
18
+ };
19
+ const STATUS_LABELS = {
20
+ Discovery: 'DISCOVERY',
21
+ Kickoff_Complete: 'KICKOFF COMPLETE',
22
+ In_Progress: 'IN PROGRESS',
23
+ Completed: 'COMPLETED',
24
+ Paused: 'PAUSED',
25
+ Cancelled: 'CANCELLED',
26
+ };
27
+ const EngagementHeader = ({ clientName, expertName, expertTitle, startDate, status, clientTabs, selectedClientId, onClientChange }) => {
28
+ const formattedDate = startDate ? (0, date_fns_1.format)(new Date(startDate), 'MMMM dd, yyyy') : (0, date_fns_1.format)(new Date(), 'MMMM dd, yyyy');
29
+ return (react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200" },
30
+ react_1.default.createElement("div", { className: "px-6 pt-4" },
31
+ react_1.default.createElement("p", { className: "text-sm font-medium text-gray-700 mb-3" }, "Select Client:"),
32
+ react_1.default.createElement("div", { className: "flex flex-wrap gap-2 mb-4" }, clientTabs.map((client) => (react_1.default.createElement(base_ui_1.Button, { key: client.id, label: client.label, onClick: () => onClientChange(client.id), color: "primary" })))),
33
+ react_1.default.createElement("hr", { className: "border-gray-200" })),
34
+ react_1.default.createElement("div", { className: "px-6 py-4" },
35
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
36
+ react_1.default.createElement("div", null,
37
+ react_1.default.createElement("h1", { className: "text-2xl font-bold text-gray-900 mb-1" },
38
+ clientName,
39
+ " \u00D7 ",
40
+ expertName),
41
+ react_1.default.createElement("p", { className: "text-gray-600" },
42
+ expertTitle,
43
+ " \u2022 Started ",
44
+ formattedDate)),
45
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: STATUS_LABELS[status] === 'GOOD' ? 'On track' : STATUS_LABELS[status] === 'ATTENTION_NEEDED' ? 'Needs attention' : 'Critical', customColor: `bg-${STATUS_COLORS[status]} border-${STATUS_COLORS[status]}` })))));
46
+ };
47
+ exports.EngagementHeader = EngagementHeader;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ interface FocusArea {
3
+ id: string;
4
+ title: string;
5
+ description: string;
6
+ status: 'CONFIRMED' | 'IN_PROGRESS' | 'COMPLETED' | 'AT_RISK';
7
+ dueDate: string;
8
+ priority: 'HIGH' | 'MEDIUM' | 'LOW';
9
+ }
10
+ interface FocusAreasProps {
11
+ focusAreas: FocusArea[];
12
+ onEditFocusAreas: () => void;
13
+ updateOpportunityFocusArea: any;
14
+ GetOpportunityInsightsDocument: any;
15
+ opportunityId: string;
16
+ }
17
+ export declare const FocusAreas: React.FC<FocusAreasProps>;
18
+ export {};
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.FocusAreas = void 0;
27
+ const react_1 = __importStar(require("react"));
28
+ const date_fns_1 = require("date-fns");
29
+ const utils_1 = require("../../shared/utils");
30
+ const core_1 = require("@material-ui/core");
31
+ const base_icons_1 = require("@paro.io/base-icons");
32
+ const base_ui_1 = require("@paro.io/base-ui");
33
+ const EscalationIssueCard_1 = require("../../Escalations/EscalationIssueCard");
34
+ const TeamSection_1 = require("../TeamSection");
35
+ const STATUS_COLORS = {
36
+ CONFIRMED: "success",
37
+ IN_PROGRESS: "info",
38
+ COMPLETED: "neutral",
39
+ AT_RISK: "warning",
40
+ };
41
+ const STATUS_ICONS = {
42
+ CONFIRMED: react_1.default.createElement(base_icons_1.IconCheck, { size: "sm" }),
43
+ IN_PROGRESS: react_1.default.createElement(base_icons_1.IconDotsHorizontal, { size: "sm" }),
44
+ COMPLETED: react_1.default.createElement(base_icons_1.IconCheck, { size: "sm" }),
45
+ AT_RISK: react_1.default.createElement(base_icons_1.IconExclamation, { size: "sm" }),
46
+ };
47
+ const PRIORITY_COLORS = {
48
+ HIGH: 'danger',
49
+ MEDIUM: 'warning',
50
+ LOW: 'info',
51
+ };
52
+ // Modal Component
53
+ const EditFocusAreaModal = ({ isOpen, focusArea, onClose, onSave, updateOpportunityFocusArea, GetOpportunityInsightsDocument, opportunityId, }) => {
54
+ const [title, setTitle] = (0, react_1.useState)((focusArea === null || focusArea === void 0 ? void 0 : focusArea.title) || '');
55
+ const [description, setDescription] = (0, react_1.useState)((focusArea === null || focusArea === void 0 ? void 0 : focusArea.description) || '');
56
+ react_1.default.useEffect(() => {
57
+ setTitle((focusArea === null || focusArea === void 0 ? void 0 : focusArea.title) || '');
58
+ setDescription((focusArea === null || focusArea === void 0 ? void 0 : focusArea.description) || '');
59
+ }, [focusArea]);
60
+ const handleSave = () => {
61
+ if (focusArea) {
62
+ try {
63
+ updateOpportunityFocusArea({
64
+ variables: {
65
+ opportunityId: `0063l00000nqlm2AAA`,
66
+ input: {
67
+ id: focusArea.id,
68
+ title,
69
+ description
70
+ }
71
+ },
72
+ refetchQueries: [
73
+ { query: GetOpportunityInsightsDocument, variables: { opportunityId } }
74
+ ]
75
+ });
76
+ (0, utils_1.showToast)('success', 'Focus area updated successfully');
77
+ }
78
+ catch (error) {
79
+ console.error('Error updating focus area:', error);
80
+ (0, utils_1.showToast)('warning', 'Error updating focus area. Please try again.');
81
+ }
82
+ onClose();
83
+ }
84
+ };
85
+ const handleCancel = () => {
86
+ setTitle((focusArea === null || focusArea === void 0 ? void 0 : focusArea.title) || '');
87
+ setDescription((focusArea === null || focusArea === void 0 ? void 0 : focusArea.description) || '');
88
+ onClose();
89
+ };
90
+ if (!isOpen || !focusArea)
91
+ return null;
92
+ return (react_1.default.createElement(core_1.Dialog, { open: isOpen, onClose: onClose, fullWidth: true },
93
+ react_1.default.createElement(core_1.DialogTitle, null,
94
+ 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" },
95
+ "Edit Focus Area",
96
+ react_1.default.createElement(core_1.IconButton, { onClick: onClose },
97
+ react_1.default.createElement(base_icons_1.IconX, null)))),
98
+ react_1.default.createElement(core_1.DialogContent, null,
99
+ react_1.default.createElement("div", { className: "space-y-4 mt-4" },
100
+ react_1.default.createElement("div", null,
101
+ react_1.default.createElement("label", { htmlFor: "title", className: "block text-sm font-medium text-gray-700 mb-2" }, "Title"),
102
+ react_1.default.createElement("textarea", { id: "title", value: title, onChange: (e) => setTitle(e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", placeholder: "Enter focus area title..." })),
103
+ react_1.default.createElement("div", null,
104
+ react_1.default.createElement("label", { htmlFor: "description", className: "block text-sm font-medium text-gray-700 mb-2" }, "Description"),
105
+ react_1.default.createElement("textarea", { id: "description", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", placeholder: "Enter focus area description..." }))),
106
+ react_1.default.createElement("div", { className: "px-6 py-4 flex justify-end space-x-3" },
107
+ react_1.default.createElement(base_ui_1.Button, { label: "cancel", onClick: handleCancel }),
108
+ react_1.default.createElement(base_ui_1.Button, { label: "save", onClick: handleSave, color: "primary" })))));
109
+ };
110
+ const FocusAreas = ({ focusAreas, onEditFocusAreas, updateOpportunityFocusArea, GetOpportunityInsightsDocument, opportunityId, }) => {
111
+ const [editingFocusArea, setEditingFocusArea] = (0, react_1.useState)(null);
112
+ const [isModalOpen, setIsModalOpen] = (0, react_1.useState)(false);
113
+ const [localFocusAreas, setLocalFocusAreas] = (0, react_1.useState)(focusAreas || []);
114
+ react_1.default.useEffect(() => {
115
+ setLocalFocusAreas(focusAreas);
116
+ }, [focusAreas]);
117
+ const handleEditClick = (focusArea) => {
118
+ setEditingFocusArea(focusArea);
119
+ setIsModalOpen(true);
120
+ };
121
+ const handleCloseModal = () => {
122
+ setIsModalOpen(false);
123
+ setEditingFocusArea(null);
124
+ };
125
+ const handleSaveFocusArea = (id, newTitle, newDescription) => {
126
+ setLocalFocusAreas(prev => prev.map(area => area.id === id
127
+ ? Object.assign(Object.assign({}, area), { title: newTitle, description: newDescription }) : area));
128
+ // Here you would typically call an API to update the focus area
129
+ console.log('Saving focus area:', id, newTitle, newDescription);
130
+ };
131
+ return (react_1.default.createElement(react_1.default.Fragment, null,
132
+ react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200" },
133
+ react_1.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200" },
134
+ react_1.default.createElement(TeamSection_1.Heading, { icon: react_1.default.createElement(base_icons_1.IconTarget, { size: "sm", className: "mr-4" }), headerText: "Focus Areas" }),
135
+ react_1.default.createElement("p", { className: "text-sm text-gray-600 mt-1" }, "Time-sensitive tasks that need attention today/this week")),
136
+ react_1.default.createElement("div", { className: "p-6" },
137
+ react_1.default.createElement("div", { className: "space-y-4" }, localFocusAreas.map((area, index) => (react_1.default.createElement("div", { key: area.id, className: "flex items-start space-x-4 p-4 border border-gray-200 rounded-lg hover:shadow-sm transition-shadow" },
138
+ react_1.default.createElement("div", { className: "flex-1 min-w-0" },
139
+ react_1.default.createElement("div", { className: "flex items-center justify-between mb-1" },
140
+ react_1.default.createElement("div", { className: "flex items-center space-x-2" },
141
+ react_1.default.createElement("div", { className: "text-sm font-bold" }, area.title),
142
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: area.status.replace('_', ' '), iconLeft: STATUS_ICONS[area.status], customColor: `bg-${STATUS_COLORS[area.status]} border-${STATUS_COLORS[area.status]}` })),
143
+ react_1.default.createElement(base_ui_1.Button, { label: "Edit focus area", iconLeft: react_1.default.createElement(base_icons_1.IconPencil, { size: "sm" }), onClick: () => handleEditClick(area), color: "success", size: 'sm' })),
144
+ react_1.default.createElement("p", { className: "text-sm text-gray-600 mb-2" }, area.description),
145
+ react_1.default.createElement("div", { className: "flex items-center text-sm font-medium space-x-2" },
146
+ react_1.default.createElement("span", null, (0, date_fns_1.format)(new Date(area.dueDate), 'MMM dd, yyyy')),
147
+ react_1.default.createElement("span", null, "\u2022"),
148
+ react_1.default.createElement("span", { className: `text-${PRIORITY_COLORS[area.priority]}` },
149
+ area.priority,
150
+ " Priority"),
151
+ area.status === 'IN_PROGRESS' && (react_1.default.createElement(react_1.default.Fragment, null,
152
+ react_1.default.createElement("span", null, "\u2022"),
153
+ react_1.default.createElement("span", { className: "text-info" }, "In progress"))))))))))),
154
+ react_1.default.createElement(EditFocusAreaModal, { isOpen: isModalOpen, focusArea: editingFocusArea, onClose: handleCloseModal, onSave: handleSaveFocusArea, updateOpportunityFocusArea: updateOpportunityFocusArea, GetOpportunityInsightsDocument: GetOpportunityInsightsDocument, opportunityId: opportunityId })));
155
+ };
156
+ exports.FocusAreas = FocusAreas;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ interface KeyMetricsData {
3
+ targetAchievements: number;
4
+ hourlyRate: number;
5
+ daysSinceGoal: number;
6
+ totalContractLength: number;
7
+ }
8
+ interface KeyMetricsProps {
9
+ metrics: KeyMetricsData;
10
+ }
11
+ export declare const KeyMetrics: React.FC<KeyMetricsProps>;
12
+ export {};
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.KeyMetrics = void 0;
27
+ const react_1 = __importStar(require("react"));
28
+ const EscalationIssueCard_1 = require("../../Escalations/EscalationIssueCard");
29
+ const base_icons_1 = require("@paro.io/base-icons");
30
+ const TeamSection_1 = require("../TeamSection");
31
+ // Edit Metrics Modal Component
32
+ const EditMetricsModal = ({ isOpen, metrics, onClose, onSave }) => {
33
+ const [formData, setFormData] = (0, react_1.useState)(metrics);
34
+ react_1.default.useEffect(() => {
35
+ setFormData(metrics);
36
+ }, [metrics]);
37
+ const handleSave = () => {
38
+ onSave(formData);
39
+ onClose();
40
+ };
41
+ const handleCancel = () => {
42
+ setFormData(metrics);
43
+ onClose();
44
+ };
45
+ const handleInputChange = (field, value) => {
46
+ const numericValue = parseFloat(value) || 0;
47
+ setFormData(prev => (Object.assign(Object.assign({}, prev), { [field]: numericValue })));
48
+ };
49
+ if (!isOpen)
50
+ return null;
51
+ return (react_1.default.createElement("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" },
52
+ react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-md mx-4" },
53
+ react_1.default.createElement("div", { className: "px-6 py-4 border-b border-gray-200" },
54
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
55
+ react_1.default.createElement("h2", { className: "text-lg font-semibold text-gray-900" }, "Edit Engagement Metrics"),
56
+ react_1.default.createElement("button", { onClick: onClose, className: "text-gray-400 hover:text-gray-600 transition-colors" },
57
+ react_1.default.createElement("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
58
+ react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }))))),
59
+ react_1.default.createElement("div", { className: "px-6 py-4 space-y-4" },
60
+ react_1.default.createElement("div", null,
61
+ react_1.default.createElement("label", { htmlFor: "targetAchievements", className: "block text-sm font-medium text-gray-700 mb-1" }, "Target Hours/Month"),
62
+ react_1.default.createElement("input", { id: "targetAchievements", type: "number", value: formData.targetAchievements, onChange: (e) => handleInputChange('targetAchievements', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm", placeholder: "Enter target hours per month" })),
63
+ react_1.default.createElement("div", null,
64
+ react_1.default.createElement("label", { htmlFor: "hourlyRate", className: "block text-sm font-medium text-gray-700 mb-1" }, "Hourly Rate ($)"),
65
+ react_1.default.createElement("input", { id: "hourlyRate", type: "number", step: "0.01", value: formData.hourlyRate, onChange: (e) => handleInputChange('hourlyRate', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm", placeholder: "Enter hourly rate" })),
66
+ react_1.default.createElement("div", null,
67
+ react_1.default.createElement("label", { htmlFor: "daysSinceGoal", className: "block text-sm font-medium text-gray-700 mb-1" }, "Day Close Goal"),
68
+ react_1.default.createElement("input", { id: "daysSinceGoal", type: "number", value: formData.daysSinceGoal, onChange: (e) => handleInputChange('daysSinceGoal', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm", placeholder: "Enter day close goal" })),
69
+ react_1.default.createElement("div", null,
70
+ react_1.default.createElement("label", { htmlFor: "totalContractLength", className: "block text-sm font-medium text-gray-700 mb-1" }, "Total Contract Length (months)"),
71
+ react_1.default.createElement("input", { id: "totalContractLength", type: "number", value: formData.totalContractLength, onChange: (e) => handleInputChange('totalContractLength', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm", placeholder: "Enter contract length in months" }))),
72
+ react_1.default.createElement("div", { className: "px-6 py-4 border-t border-gray-200 flex justify-end space-x-3" },
73
+ react_1.default.createElement("button", { onClick: handleCancel, className: "px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 transition-colors" }, "Cancel"),
74
+ react_1.default.createElement("button", { onClick: handleSave, className: "px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors" }, "Save Changes")))));
75
+ };
76
+ const KeyMetrics = ({ metrics }) => {
77
+ const [isModalOpen, setIsModalOpen] = (0, react_1.useState)(false);
78
+ const [localMetrics, setLocalMetrics] = (0, react_1.useState)(metrics);
79
+ react_1.default.useEffect(() => {
80
+ setLocalMetrics(metrics);
81
+ }, [metrics]);
82
+ const handleOpenModal = () => {
83
+ setIsModalOpen(true);
84
+ };
85
+ const handleCloseModal = () => {
86
+ setIsModalOpen(false);
87
+ };
88
+ const handleSaveMetrics = (newMetrics) => {
89
+ setLocalMetrics(newMetrics);
90
+ // Here you would typically call an API to update the metrics
91
+ console.log('Saving metrics:', newMetrics);
92
+ };
93
+ return (react_1.default.createElement("div", { className: "flex flex-col space-y-4" },
94
+ react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-6" },
95
+ react_1.default.createElement(TeamSection_1.Heading, { icon: react_1.default.createElement(base_icons_1.IconViewGrid, { size: "sm", className: "mr-4" }), headerText: "Engagement Metrics" }),
96
+ react_1.default.createElement("div", { className: "grid grid-cols-2 gap-4 mt-2" },
97
+ react_1.default.createElement("div", { className: "text-center" },
98
+ react_1.default.createElement("div", { className: "text-2xl font-bold text-gray-900" }, localMetrics.targetAchievements),
99
+ react_1.default.createElement("div", { className: "text-sm text-gray-600" }, "Target Hours/Month")),
100
+ react_1.default.createElement("div", { className: "text-center" },
101
+ react_1.default.createElement("div", { className: "text-2xl font-bold text-gray-900" },
102
+ "$",
103
+ localMetrics.hourlyRate),
104
+ react_1.default.createElement("div", { className: "text-sm text-gray-600" }, "Hourly Rate")),
105
+ react_1.default.createElement("div", { className: "text-center" },
106
+ react_1.default.createElement("div", { className: "text-2xl font-bold text-gray-900" },
107
+ localMetrics.daysSinceGoal,
108
+ "-5"),
109
+ react_1.default.createElement("div", { className: "text-sm text-gray-600" }, "Day Close Goal")),
110
+ react_1.default.createElement("div", { className: "text-center" },
111
+ react_1.default.createElement("div", { className: "text-2xl font-bold text-gray-900" }, localMetrics.totalContractLength),
112
+ react_1.default.createElement("div", { className: "text-sm text-gray-600" }, "Total Contract Length")))),
113
+ react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-4" },
114
+ react_1.default.createElement(TeamSection_1.Heading, { icon: react_1.default.createElement(base_icons_1.IconChat, { size: "sm", className: "mr-4" }), headerText: "Communication" }),
115
+ react_1.default.createElement("div", { className: "space-y-2 text-sm text-gray-600 mt-2" },
116
+ react_1.default.createElement("div", { className: "flex justify-between" },
117
+ react_1.default.createElement("span", null, "Daily"),
118
+ react_1.default.createElement("span", { className: "font-medium" }, "Microsoft Teams")),
119
+ react_1.default.createElement("div", { className: "flex justify-between" },
120
+ react_1.default.createElement("span", null, "Formal"),
121
+ react_1.default.createElement("span", { className: "font-medium" }, "Email")),
122
+ react_1.default.createElement("div", { className: "flex justify-between" },
123
+ react_1.default.createElement("span", null, "Weekly"),
124
+ react_1.default.createElement("span", { className: "font-medium" }, "Mondays 11 AM EST")),
125
+ react_1.default.createElement("div", { className: "flex justify-between" },
126
+ react_1.default.createElement("span", null, "Languages"),
127
+ react_1.default.createElement("span", { className: "font-medium" }, "English & Spanish")))),
128
+ react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-gray-200 p-4" },
129
+ react_1.default.createElement(TeamSection_1.Heading, { icon: react_1.default.createElement(base_icons_1.IconChartBar, { size: "sm", className: "mr-4" }), headerText: "Business Context" }),
130
+ react_1.default.createElement("div", { className: "space-y-2 text-sm text-gray-600 mt-2" },
131
+ react_1.default.createElement("div", { className: "flex justify-between" },
132
+ react_1.default.createElement("span", null, "Industry:"),
133
+ react_1.default.createElement("span", { className: "font-medium" }, "NetSuite software development")),
134
+ react_1.default.createElement("div", { className: "flex justify-between" },
135
+ react_1.default.createElement("span", null, "Structure:"),
136
+ react_1.default.createElement("span", { className: "font-medium" }, "US clients, Colombian delivery team")),
137
+ react_1.default.createElement("div", { className: "flex justify-between" },
138
+ react_1.default.createElement("span", null, "Challenge:"),
139
+ react_1.default.createElement("span", { className: "font-medium" }, "Manual consolidation processes")),
140
+ react_1.default.createElement("div", { className: "flex justify-between" },
141
+ react_1.default.createElement("span", null, "Opportunity:"),
142
+ react_1.default.createElement("span", { className: "font-medium" }, "NetSuite automation & efficiency"))),
143
+ react_1.default.createElement("div", { className: "flex items-center space-x-2 mt-4" },
144
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "NetSuite", customColor: `bg-info border-info` }),
145
+ react_1.default.createElement(EscalationIssueCard_1.CustomTag, { label: "Bilingual Team", customColor: `bg-success border-success` }))),
146
+ react_1.default.createElement(EditMetricsModal, { isOpen: isModalOpen, metrics: localMetrics, onClose: handleCloseModal, onSave: handleSaveMetrics })));
147
+ };
148
+ exports.KeyMetrics = KeyMetrics;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ interface MissingInfoItem {
3
+ id: string;
4
+ title: string;
5
+ description: string;
6
+ priority: 'HIGH' | 'MEDIUM' | 'LOW';
7
+ category: string;
8
+ status?: string;
9
+ clientResponse?: string;
10
+ }
11
+ interface MissingInformationProps {
12
+ items: MissingInfoItem[];
13
+ className?: string;
14
+ opportunityId: string;
15
+ GetOpportunityInsightsDocument: any;
16
+ updateOpportunityMissingInformation: any;
17
+ documentCenterController: {
18
+ openDocumentCenter: ((open: boolean) => void) | null;
19
+ } | null;
20
+ isInternal: boolean;
21
+ handleRouteToDocuments?: () => void;
22
+ }
23
+ export declare const MissingInformation: React.FC<MissingInformationProps>;
24
+ export {};