@paro.io/expert-shared-components 1.11.2 → 1.11.4

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 (76) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +2 -2
  3. package/lib/components/ClientReferencesSection/DeleteButton.js +11 -11
  4. package/lib/components/ClientReferencesSection/ParoError.js +10 -10
  5. package/lib/components/ClientReferencesSection/TagsSection.js +2 -2
  6. package/lib/components/ClientReferencesSection/styles/BrandedTypography.js +2 -2
  7. package/lib/components/ClientReferencesSection/styles/Buttons.js +15 -15
  8. package/lib/components/ClientReferencesSection/styles/Name.js +5 -5
  9. package/lib/components/ClientReferencesSection/styles/NullContentConditionalColor.js +4 -4
  10. package/lib/components/ClientReferencesSection/styles/SectionBody.js +11 -11
  11. package/lib/components/ClientReferencesSection/styles/SectionTitle.js +6 -6
  12. package/lib/components/ClientReferencesSection/styles/Tags.js +2 -2
  13. package/lib/components/DiscussionThread/DiscussionThread.d.ts +2 -2
  14. package/lib/components/DiscussionThread/DiscussionThread.js +64 -41
  15. package/lib/components/DocumentCenter/DocumentTable.d.ts +15 -15
  16. package/lib/components/DocumentCenter/DocumentTable.js +350 -350
  17. package/lib/components/DocumentCenter/UploadFilesButton.d.ts +6 -6
  18. package/lib/components/DocumentCenter/UploadFilesButton.js +29 -29
  19. package/lib/components/EarningsTracker/ActiveProjectCard.d.ts +52 -52
  20. package/lib/components/EarningsTracker/ActiveProjectCard.js +161 -161
  21. package/lib/components/EarningsTracker/CenterCardUI.d.ts +13 -13
  22. package/lib/components/EarningsTracker/CenterCardUI.js +134 -134
  23. package/lib/components/EarningsTracker/EarningsTracker.d.ts +52 -52
  24. package/lib/components/EarningsTracker/EarningsTracker.js +508 -508
  25. package/lib/components/EarningsTracker/EditDateModal.d.ts +22 -22
  26. package/lib/components/EarningsTracker/EditDateModal.js +149 -149
  27. package/lib/components/EarningsTracker/EmailModal.d.ts +14 -14
  28. package/lib/components/EarningsTracker/EmailModal.js +79 -79
  29. package/lib/components/EarningsTracker/EndProjectModal.d.ts +56 -56
  30. package/lib/components/EarningsTracker/EndProjectModal.js +221 -221
  31. package/lib/components/EarningsTracker/LeftCardUI.d.ts +18 -18
  32. package/lib/components/EarningsTracker/LeftCardUI.js +189 -189
  33. package/lib/components/EarningsTracker/LogTimeModalAuthenticated.d.ts +52 -52
  34. package/lib/components/EarningsTracker/LogTimeModalAuthenticated.js +358 -358
  35. package/lib/components/EarningsTracker/ProgressBar.d.ts +4 -4
  36. package/lib/components/EarningsTracker/ProgressBar.js +66 -66
  37. package/lib/components/EarningsTracker/ReviewRequestModal.d.ts +17 -17
  38. package/lib/components/EarningsTracker/ReviewRequestModal.js +135 -135
  39. package/lib/components/EarningsTracker/RightCardUI.d.ts +46 -46
  40. package/lib/components/EarningsTracker/RightCardUI.js +231 -231
  41. package/lib/components/EarningsTracker/index.d.ts +1 -1
  42. package/lib/components/EarningsTracker/index.js +5 -5
  43. package/lib/components/ExpertProfileHeader/ActionButtonSection.js +6 -6
  44. package/lib/components/ExpertProfileHeader/ProfileSection.js +7 -7
  45. package/lib/components/Invoices/DecisionSection.d.ts +7 -0
  46. package/lib/components/Invoices/DecisionSection.js +95 -0
  47. package/lib/components/Invoices/DiscussionSection.d.ts +19 -0
  48. package/lib/components/Invoices/DiscussionSection.js +163 -0
  49. package/lib/components/Invoices/DisputeProjectCard.d.ts +20 -0
  50. package/lib/components/Invoices/DisputeProjectCard.js +79 -0
  51. package/lib/components/Invoices/DisputeSection.d.ts +7 -0
  52. package/lib/components/Invoices/DisputeSection.js +94 -0
  53. package/lib/components/Invoices/InvoiceCard.d.ts +8 -3
  54. package/lib/components/Invoices/InvoiceCard.js +18 -204
  55. package/lib/components/Invoices/InvoiceDetails.d.ts +5 -0
  56. package/lib/components/Invoices/InvoiceDetails.js +34 -0
  57. package/lib/components/Invoices/InvoiceHeader.d.ts +5 -0
  58. package/lib/components/Invoices/InvoiceHeader.js +29 -0
  59. package/lib/components/OrganizationChart/OrganizationChart.d.ts +15 -15
  60. package/lib/components/OrganizationChart/OrganizationChart.js +312 -312
  61. package/lib/components/OrganizationChart/PersonCard.js +5 -5
  62. package/lib/components/OrganizationChart/utils.js +79 -79
  63. package/lib/components/ProjectCard/ProgressBar.js +4 -4
  64. package/lib/components/ProjectCard/ReviewRequestModal.js +5 -5
  65. package/lib/components/Reviews/Pagination.js +6 -6
  66. package/lib/components/ReviewsTab/RatingHeader.js +6 -6
  67. package/lib/components/ReviewsTab/expert-shared-components.code-workspace +20 -20
  68. package/lib/components/ReviewsTab/reviewRequestModal.js +5 -5
  69. package/lib/components/shared/Image.js +13 -13
  70. package/lib/components/shared/ProfileTextField.d.ts +18 -18
  71. package/lib/components/shared/ProfileTextField.js +16 -16
  72. package/lib/components/shared/StyledActionButtons.d.ts +7 -7
  73. package/lib/components/shared/StyledActionButtons.js +15 -15
  74. package/lib/components/shared/ToastNotification.d.ts +10 -10
  75. package/lib/components/shared/ToastNotification.js +63 -63
  76. package/package.json +61 -61
@@ -0,0 +1,95 @@
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
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.DecisionSection = void 0;
39
+ const react_1 = __importStar(require("react"));
40
+ const base_ui_1 = require("@paro.io/base-ui");
41
+ const react_hot_toast_1 = __importDefault(require("react-hot-toast"));
42
+ const RESOLUTION_OPTIONS = [
43
+ { value: 'Resolved', label: 'Approve Dispute' },
44
+ { value: 'Resolved', label: 'Decline Dispute' },
45
+ { value: 'Resolved', label: 'Partial Approval' },
46
+ ];
47
+ const DecisionSection = ({ dispute, onUpdateDispute, }) => {
48
+ const [resolution, setResolution] = (0, react_1.useState)('');
49
+ const [amount, setAmount] = (0, react_1.useState)('');
50
+ const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false);
51
+ const handleSubmit = () => __awaiter(void 0, void 0, void 0, function* () {
52
+ if (!resolution)
53
+ return;
54
+ setIsSubmitting(true);
55
+ try {
56
+ yield onUpdateDispute({
57
+ variables: {
58
+ input: {
59
+ disputeId: dispute.disputeId,
60
+ status: resolution,
61
+ approvedAmount: amount ? parseFloat(amount) : undefined,
62
+ },
63
+ },
64
+ });
65
+ react_hot_toast_1.default.success('Thank you for resolving the dispute');
66
+ }
67
+ catch (error) {
68
+ console.error('Failed to update dispute:', error);
69
+ react_hot_toast_1.default.error('Failed to update dispute');
70
+ }
71
+ finally {
72
+ setIsSubmitting(false);
73
+ }
74
+ });
75
+ return (react_1.default.createElement("div", { className: "space-y-6" },
76
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
77
+ react_1.default.createElement("div", { className: "text-lg font-bold text-[#333333]" }, "Make Decision")),
78
+ react_1.default.createElement("div", { className: "p-6 space-y-6", style: { backgroundColor: '#F8F9FA' } },
79
+ react_1.default.createElement("div", { className: "grid grid-cols-2 gap-6" },
80
+ react_1.default.createElement("div", null,
81
+ react_1.default.createElement("label", { className: "block text-sm text-[#666666] font-bold mb-2" }, "Resolution:"),
82
+ react_1.default.createElement("div", { className: "w-full" },
83
+ react_1.default.createElement("select", { value: resolution, onChange: (e) => setResolution(e.target.value), className: "w-full px-3 py-2 border border-[#CCCCCC] rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#248384] bg-white" },
84
+ react_1.default.createElement("option", { value: "" }, "Select Resolution"),
85
+ RESOLUTION_OPTIONS.map((option) => (react_1.default.createElement("option", { key: option.value, value: option.value }, option.label)))))),
86
+ resolution === 'PARTIAL' && (react_1.default.createElement("div", null,
87
+ react_1.default.createElement("label", { className: "block text-sm text-[#666666] font-bold mb-2" }, "Approved Amount:"),
88
+ react_1.default.createElement("div", { className: "relative" },
89
+ react_1.default.createElement("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-[#333333]" }, "$"),
90
+ react_1.default.createElement("input", { type: "number", value: amount, onChange: (e) => setAmount(e.target.value), className: "w-full pl-8 pr-3 py-2 border border-[#CCCCCC] rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#248384]", placeholder: "Enter amount" }))))),
91
+ react_1.default.createElement("div", { className: "flex justify-end space-x-4" },
92
+ react_1.default.createElement(base_ui_1.Button, { label: "Decline Dispute", color: "error", onClick: () => setResolution('DECLINED'), disabled: isSubmitting, size: "md" }),
93
+ react_1.default.createElement(base_ui_1.Button, { label: "Approve & Resolve", color: "primary", onClick: handleSubmit, isLoading: isSubmitting, disabled: !resolution || (resolution === 'PARTIAL' && !amount), size: "md" })))));
94
+ };
95
+ exports.DecisionSection = DecisionSection;
@@ -0,0 +1,19 @@
1
+ interface Message {
2
+ id: string;
3
+ sender: {
4
+ firstName: string;
5
+ lastName: string;
6
+ role: string;
7
+ userTypeId: number;
8
+ };
9
+ messageText: string;
10
+ createdAt: string;
11
+ }
12
+ interface DiscussionSectionProps {
13
+ disputeId: string;
14
+ currentUser: any;
15
+ messages: Message[];
16
+ onCreateMessage: (variables: any) => Promise<any>;
17
+ }
18
+ export declare const DiscussionSection: ({ disputeId, currentUser, messages, onCreateMessage, }: DiscussionSectionProps) => JSX.Element;
19
+ export {};
@@ -0,0 +1,163 @@
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
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.DiscussionSection = void 0;
39
+ const react_1 = __importStar(require("react"));
40
+ const base_ui_1 = require("@paro.io/base-ui");
41
+ const dayjs_1 = __importDefault(require("dayjs"));
42
+ const DiscussionSection = ({ disputeId, currentUser, messages, onCreateMessage, }) => {
43
+ var _a;
44
+ const [newMessage, setNewMessage] = (0, react_1.useState)('');
45
+ const [visibility, setVisibility] = (0, react_1.useState)('ALL');
46
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
47
+ // Get the sequence of unique userTypeIds to determine alignment
48
+ const userSequence = (0, react_1.useMemo)(() => {
49
+ const uniqueUsers = Array.from(new Set(messages.map(m => m.sender.userTypeId)));
50
+ return uniqueUsers;
51
+ }, [messages]);
52
+ const handleSendMessage = () => __awaiter(void 0, void 0, void 0, function* () {
53
+ var _a;
54
+ if (!newMessage.trim())
55
+ return;
56
+ try {
57
+ setIsLoading(true);
58
+ yield onCreateMessage({
59
+ variables: {
60
+ input: {
61
+ disputeId,
62
+ messageText: newMessage,
63
+ visibility,
64
+ senderId: (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.app_metadata) === null || _a === void 0 ? void 0 : _a.userId,
65
+ },
66
+ },
67
+ });
68
+ setNewMessage('');
69
+ setIsLoading(false);
70
+ }
71
+ catch (error) {
72
+ console.error('Failed to send message:', error);
73
+ }
74
+ });
75
+ const getSenderInitial = (sender) => {
76
+ if (sender.userTypeId === 3)
77
+ return 'C';
78
+ if (sender.userTypeId === 1)
79
+ return 'E';
80
+ return 'P';
81
+ };
82
+ const getSenderTextColor = (userTypeId) => {
83
+ switch (userTypeId) {
84
+ case 1:
85
+ return '#195C5C';
86
+ case 2:
87
+ return '#2196F3';
88
+ case 3:
89
+ return '#643E0C';
90
+ default:
91
+ return '#333333';
92
+ }
93
+ };
94
+ const getSenderBackgroundColor = (userTypeId) => {
95
+ switch (userTypeId) {
96
+ case 1:
97
+ return '#D9EFEF';
98
+ case 2:
99
+ return '#E4F0FF';
100
+ case 3:
101
+ return '#FDD7A5';
102
+ default:
103
+ return '#F8F9FA';
104
+ }
105
+ };
106
+ const getMessageAlignment = (userTypeId) => {
107
+ // First user in sequence is left-aligned, second is right-aligned
108
+ const userIndex = userSequence.indexOf(userTypeId);
109
+ return userIndex === 0 ? 'mr-auto' : 'ml-auto';
110
+ };
111
+ const getMessageOrder = (userTypeId) => {
112
+ // First user in sequence shows avatar on left, second on right
113
+ const userIndex = userSequence.indexOf(userTypeId);
114
+ return userIndex === 0 ? 'flex-row' : 'flex-row-reverse';
115
+ };
116
+ const getHeaderAlignment = (userTypeId) => {
117
+ // First user in sequence aligns text left, second aligns right
118
+ const userIndex = userSequence.indexOf(userTypeId);
119
+ return userIndex === 0 ? 'justify-start' : 'justify-end';
120
+ };
121
+ return (react_1.default.createElement("div", { className: "space-y-6" },
122
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
123
+ react_1.default.createElement("div", { className: "text-lg font-bold text-[#333333]" }, "Discussion Thread")),
124
+ react_1.default.createElement("div", { className: "rounded" },
125
+ react_1.default.createElement("div", { className: "space-y-6" }, messages.map((message) => (react_1.default.createElement("div", { key: message.id, className: `flex ${getMessageAlignment(message.sender.userTypeId)}` },
126
+ react_1.default.createElement("div", { className: `flex space-x-4 ${getMessageOrder(message.sender.userTypeId)} ${getMessageAlignment(message.sender.userTypeId)}` },
127
+ react_1.default.createElement("div", { style: {
128
+ backgroundColor: getSenderBackgroundColor(message.sender.userTypeId),
129
+ color: getSenderTextColor(message.sender.userTypeId)
130
+ }, className: "w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0" },
131
+ react_1.default.createElement("span", { className: "text-sm font-bold" }, getSenderInitial(message.sender))),
132
+ react_1.default.createElement("div", { className: "flex-1" },
133
+ react_1.default.createElement("div", { className: `flex items-center ${getHeaderAlignment(message.sender.userTypeId)} space-x-2` },
134
+ react_1.default.createElement("span", { className: "text-sm font-bold text-[#333333]" },
135
+ message.sender.firstName,
136
+ " ",
137
+ message.sender.lastName),
138
+ react_1.default.createElement("span", { className: "text-xs text-[#666666]" }, (0, dayjs_1.default)(message.createdAt).format('MMM D, YYYY • h:mm A'))),
139
+ react_1.default.createElement("div", { style: { backgroundColor: getSenderBackgroundColor(message.sender.userTypeId) }, className: "mt-1 p-3 rounded-lg" },
140
+ react_1.default.createElement("p", { className: `text-sm ${getHeaderAlignment(message.sender.userTypeId)}`, style: { color: getSenderTextColor(message.sender.userTypeId) } }, message.messageText)))))))),
141
+ react_1.default.createElement("div", { className: "space-y-4 p-6 space-y-6 rounded mt-4", style: { backgroundColor: '#F5F7F9' } },
142
+ react_1.default.createElement("div", null,
143
+ react_1.default.createElement("div", { className: "font-bold text-[#333333] mb-2" }, "Add Comment"),
144
+ react_1.default.createElement("textarea", { value: newMessage, onChange: (e) => setNewMessage(e.target.value), placeholder: "Type your comment here...", className: "w-full h-24 p-3 border border-[#CCCCCC] rounded-lg text-sm resize-none focus:outline-none focus:ring-2 focus:ring-[#248384]" })),
145
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
146
+ react_1.default.createElement("div", { className: "flex items-center space-x-4" }, ((_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.app_metadata) === null || _a === void 0 ? void 0 : _a.userTypeId) === 1 && (react_1.default.createElement(react_1.default.Fragment, null,
147
+ react_1.default.createElement("span", { className: "text-sm text-[#666666]" }, "Visible to:"),
148
+ react_1.default.createElement("div", { className: "flex items-center space-x-2" },
149
+ react_1.default.createElement("label", { className: "flex items-center space-x-2 cursor-pointer" },
150
+ react_1.default.createElement("input", { type: "radio", checked: visibility === 'EXPERT_INTERNAL_ONLY', onChange: () => setVisibility('EXPERT_INTERNAL_ONLY'), className: "form-radio text-[#248384]" }),
151
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, "Expert Only")),
152
+ react_1.default.createElement("label", { className: "flex items-center space-x-2 cursor-pointer" },
153
+ react_1.default.createElement("input", { type: "radio", checked: visibility === 'CLIENT_INTERNAL_ONLY', onChange: () => setVisibility('CLIENT_INTERNAL_ONLY'), className: "form-radio text-[#248384]" }),
154
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, "Client Only")),
155
+ react_1.default.createElement("label", { className: "flex items-center space-x-2 cursor-pointer" },
156
+ react_1.default.createElement("input", { type: "radio", checked: visibility === 'INTERNAL_ONLY', onChange: () => setVisibility('INTERNAL_ONLY'), className: "form-radio text-[#248384]" }),
157
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, "Internal Only")),
158
+ react_1.default.createElement("label", { className: "flex items-center space-x-2 cursor-pointer" },
159
+ react_1.default.createElement("input", { type: "radio", checked: visibility === 'ALL', onChange: () => setVisibility('ALL'), className: "form-radio text-[#248384]" }),
160
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, "All")))))),
161
+ react_1.default.createElement(base_ui_1.Button, { label: "Reply", color: "primary", isLoading: isLoading, onClick: handleSendMessage, disabled: !newMessage.trim() }))))));
162
+ };
163
+ exports.DiscussionSection = DiscussionSection;
@@ -0,0 +1,20 @@
1
+ interface DisputeProjectCardProps {
2
+ project: {
3
+ project: {
4
+ name: string;
5
+ };
6
+ disputeAmount: number;
7
+ disputeHours: number;
8
+ disputeType: string;
9
+ disputeReasonCode: string;
10
+ resolutionMode?: 'Direct' | 'Mediated' | 'Escalated';
11
+ resolutionType?: 'Upheld' | 'Reduced' | 'FutureCredit' | 'Canceled';
12
+ };
13
+ client: {
14
+ name: string;
15
+ };
16
+ disputeDate: string;
17
+ disputeUpdatedDate: string;
18
+ }
19
+ export declare const DisputeProjectCard: ({ project, client, disputeDate, disputeUpdatedDate }: DisputeProjectCardProps) => JSX.Element;
20
+ export {};
@@ -0,0 +1,79 @@
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.DisputeProjectCard = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const base_ui_1 = require("@paro.io/base-ui");
9
+ const dayjs_1 = __importDefault(require("dayjs"));
10
+ const DisputeProjectCard = ({ project, client, disputeDate, disputeUpdatedDate }) => {
11
+ var _a, _b;
12
+ const getResolutionModeColor = (mode) => {
13
+ switch (mode) {
14
+ case 'Direct':
15
+ return 'success';
16
+ case 'Mediated':
17
+ return 'warning';
18
+ case 'Escalated':
19
+ return 'danger';
20
+ default:
21
+ return 'default';
22
+ }
23
+ };
24
+ const getResolutionTypeColor = (type) => {
25
+ switch (type) {
26
+ case 'Upheld':
27
+ return 'success';
28
+ case 'Reduced':
29
+ return 'warning';
30
+ case 'FutureCredit':
31
+ return 'info';
32
+ case 'Canceled':
33
+ return 'danger';
34
+ default:
35
+ return 'default';
36
+ }
37
+ };
38
+ return (react_1.default.createElement("div", { className: "bg-white rounded-lg shadow-sm border border-[#E5E7EB] p-6 space-y-4" },
39
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
40
+ react_1.default.createElement("div", { className: "flex items-center space-x-2" },
41
+ project.resolutionMode && (react_1.default.createElement("div", null,
42
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Resolution Mode: "),
43
+ react_1.default.createElement(base_ui_1.Tag, { label: project.resolutionMode, variant: "subtle", color: getResolutionModeColor(project.resolutionMode) }))),
44
+ project.resolutionType && (react_1.default.createElement("div", null,
45
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Resolution Type: "),
46
+ react_1.default.createElement(base_ui_1.Tag, { label: project.resolutionType, variant: "subtle", color: getResolutionTypeColor(project.resolutionType) }))))),
47
+ react_1.default.createElement("div", { className: "grid grid-cols-2 gap-6" },
48
+ react_1.default.createElement("div", { className: "space-y-4" },
49
+ react_1.default.createElement("div", null,
50
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Client: "),
51
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, client === null || client === void 0 ? void 0 : client.name)),
52
+ react_1.default.createElement("div", null,
53
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Project: "),
54
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, (_a = project === null || project === void 0 ? void 0 : project.project) === null || _a === void 0 ? void 0 : _a.name)),
55
+ react_1.default.createElement("div", null,
56
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Type: "),
57
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, project === null || project === void 0 ? void 0 : project.disputeType)),
58
+ react_1.default.createElement("div", null,
59
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Hours Disputed: "),
60
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, project === null || project === void 0 ? void 0 :
61
+ project.disputeHours,
62
+ " hours"))),
63
+ react_1.default.createElement("div", { className: "space-y-4" },
64
+ react_1.default.createElement("div", null,
65
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Amount: "),
66
+ react_1.default.createElement("span", { className: "text-sm text-[#F44336] font-bold" },
67
+ "$", (_b = project === null || project === void 0 ? void 0 : project.disputeAmount) === null || _b === void 0 ? void 0 :
68
+ _b.toLocaleString())),
69
+ react_1.default.createElement("div", null,
70
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Submitted: "),
71
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, (0, dayjs_1.default)(disputeDate).format('MMM D, YYYY'))),
72
+ react_1.default.createElement("div", null,
73
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Last Updated: "),
74
+ react_1.default.createElement("span", { className: "text-sm text-[#333333]" }, (0, dayjs_1.default)(disputeUpdatedDate).format('MMM D, YYYY'))),
75
+ react_1.default.createElement("div", null,
76
+ react_1.default.createElement("span", { className: "text-sm text-[#666666] font-bold" }, "Days Left: "),
77
+ react_1.default.createElement("span", { className: "text-sm text-[#F44336] font-bold" }, "5 days left to resolve"))))));
78
+ };
79
+ exports.DisputeProjectCard = DisputeProjectCard;
@@ -0,0 +1,7 @@
1
+ interface DisputeSectionProps {
2
+ dispute: any;
3
+ onUpdateDispute: (variables: any) => Promise<any>;
4
+ onRefetch: () => Promise<void>;
5
+ }
6
+ export declare const DisputeSection: ({ dispute, onUpdateDispute, onRefetch, }: DisputeSectionProps) => JSX.Element;
7
+ export {};
@@ -0,0 +1,94 @@
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.DisputeSection = void 0;
27
+ const react_1 = __importStar(require("react"));
28
+ const base_ui_1 = require("@paro.io/base-ui");
29
+ const base_icons_1 = require("@paro.io/base-icons");
30
+ const ACCEPTED_FILE_TYPES = [
31
+ 'application/pdf',
32
+ 'application/msword',
33
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
34
+ 'image/jpeg',
35
+ 'image/png',
36
+ 'text/csv',
37
+ ];
38
+ const DisputeSection = ({ dispute, onUpdateDispute, onRefetch, }) => {
39
+ var _a, _b, _c;
40
+ const [files, setFiles] = (0, react_1.useState)((dispute === null || dispute === void 0 ? void 0 : dispute.clientDocumentLinks) || []);
41
+ const fileInputRef = (0, react_1.useRef)(null);
42
+ const validateFileUpload = (file) => {
43
+ return ACCEPTED_FILE_TYPES.includes(file.type);
44
+ };
45
+ const handleUpload = (event) => {
46
+ const selectedFiles = event.target.files;
47
+ if (!selectedFiles)
48
+ return;
49
+ const validFiles = Array.from(selectedFiles)
50
+ .filter(file => validateFileUpload(file))
51
+ .map(file => file.name);
52
+ if (validFiles.length === 0)
53
+ return;
54
+ setFiles(prev => [...prev, ...validFiles]);
55
+ if (fileInputRef.current) {
56
+ fileInputRef.current.value = '';
57
+ }
58
+ };
59
+ const handleRemoveFile = (fileName) => {
60
+ setFiles(prev => prev.filter(f => f !== fileName));
61
+ };
62
+ const disputeProject = (_a = dispute === null || dispute === void 0 ? void 0 : dispute.disputeProjects) === null || _a === void 0 ? void 0 : _a[0];
63
+ return (react_1.default.createElement("div", { className: "grid grid-cols-2 gap-6" },
64
+ react_1.default.createElement("div", { className: "space-y-4" },
65
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
66
+ react_1.default.createElement("div", { className: "text-lg font-bold text-[#333333]" }, "Client Dispute")),
67
+ react_1.default.createElement("div", { className: "p-6 space-y-4 rounded", style: { backgroundColor: '#D9EFEF', minHeight: '230px' } },
68
+ react_1.default.createElement("div", { className: "py-1 text-[#195C5C] font-bold inline-block mb-2" },
69
+ "Reason: ", disputeProject === null || disputeProject === void 0 ? void 0 :
70
+ disputeProject.disputeReasonCode),
71
+ react_1.default.createElement("div", null,
72
+ react_1.default.createElement("div", { className: "text-sm font-bold text-[#333333] mb-2" }, "Client Explanation:"),
73
+ react_1.default.createElement("p", { className: "text-sm text-[#333333]" }, disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.clientExplanation)),
74
+ react_1.default.createElement("div", null,
75
+ react_1.default.createElement("div", { className: "text-sm font-bold text-[#333333] mb-2" }, "Supporting Documents:"),
76
+ react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
77
+ react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: true, accept: ACCEPTED_FILE_TYPES.join(','), className: "hidden", onChange: handleUpload }),
78
+ react_1.default.createElement(base_ui_1.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]" }), (_b = disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.clientDocumentLinks) === null || _b === void 0 ? void 0 :
79
+ _b.map((file, index) => (react_1.default.createElement(base_ui_1.Tag, { key: index, label: file, variant: "subtle", color: "success", iconRight: react_1.default.createElement(base_icons_1.IconXCircle, null), onClick: () => handleRemoveFile(file) }))))))),
80
+ react_1.default.createElement("div", { className: "space-y-4" },
81
+ react_1.default.createElement("div", { className: "flex items-center justify-between" },
82
+ react_1.default.createElement("div", { className: "text-lg font-bold text-[#333333]" }, "Expert Rebuttal")),
83
+ react_1.default.createElement("div", { className: "p-6 space-y-4 rounded", style: { backgroundColor: '#FDD7A5', minHeight: '230px' } },
84
+ react_1.default.createElement("div", null,
85
+ react_1.default.createElement("div", { className: "text-sm font-bold text-[#333333] mb-2" }, "Expert Explanation:"),
86
+ react_1.default.createElement("p", { className: "text-sm text-[#333333]" }, disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.expertExplanation)),
87
+ react_1.default.createElement("div", null,
88
+ react_1.default.createElement("div", { className: "text-sm font-bold text-[#333333] mb-2" }, "Supporting Documents:"),
89
+ react_1.default.createElement("div", { className: "flex flex-wrap gap-2" },
90
+ react_1.default.createElement("input", { ref: fileInputRef, type: "file", multiple: true, accept: ACCEPTED_FILE_TYPES.join(','), className: "hidden", onChange: handleUpload }),
91
+ react_1.default.createElement(base_ui_1.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: "sm" }), onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, size: "sm", color: "info", className: "bg-white border border-[#248384] text-[#248384]" }), (_c = disputeProject === null || disputeProject === void 0 ? void 0 : disputeProject.expertDocumentLinks) === null || _c === void 0 ? void 0 :
92
+ _c.map((file, index) => (react_1.default.createElement(base_ui_1.Tag, { key: index, label: file, variant: "subtle", color: "success", iconRight: react_1.default.createElement(base_icons_1.IconXCircle, null), onClick: () => handleRemoveFile(file) })))))))));
93
+ };
94
+ exports.DisputeSection = DisputeSection;
@@ -1,5 +1,10 @@
1
- export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user }: {
2
- clientInvoice: any;
1
+ interface InvoiceCardProps {
2
+ clientInvoice?: any;
3
3
  createDisputeChatMessage: any;
4
4
  user: any;
5
- }) => JSX.Element;
5
+ chatMessages: any[];
6
+ updateClientInvoiceMutation: any;
7
+ refetchInvoiceDisputes: any;
8
+ }
9
+ export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceMutation, refetchInvoiceDisputes, }: InvoiceCardProps) => JSX.Element;
10
+ export {};