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

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.
@@ -8,7 +8,6 @@ interface ChatMessages {
8
8
  firstName: string;
9
9
  lastName: string;
10
10
  userTypeId: number;
11
- avatar: string | null;
12
11
  };
13
12
  messageText: string;
14
13
  visibility: "ALL" | "INTERNAL_ONLY" | "CLIENT_INTERNAL_ONLY" | "EXPERT_INTERNAL_ONLY";
@@ -20,6 +19,7 @@ interface DiscussionThreadProps {
20
19
  currentUser: any;
21
20
  initialThreads: ChatMessages[] | [];
22
21
  createDisputeChatMessage: any;
22
+ disputeId: number;
23
23
  }
24
- export declare const DiscussionThread: ({ currentUser, initialThreads, createDisputeChatMessage, }: DiscussionThreadProps) => React.JSX.Element;
24
+ export declare const DiscussionThread: ({ currentUser, initialThreads, createDisputeChatMessage, disputeId, }: DiscussionThreadProps) => React.JSX.Element;
25
25
  export {};
@@ -22,52 +22,75 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
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
+ };
25
34
  Object.defineProperty(exports, "__esModule", { value: true });
26
35
  exports.DiscussionThread = void 0;
27
36
  const react_1 = __importStar(require("react"));
28
37
  const base_ui_1 = require("@paro.io/base-ui");
29
- const DiscussionThread = ({ currentUser, initialThreads, createDisputeChatMessage, }) => {
38
+ const DiscussionThread = ({ currentUser, initialThreads, createDisputeChatMessage, disputeId, }) => {
30
39
  const [messages, setMessages] = (0, react_1.useState)(initialThreads);
40
+ const [sending, setSending] = (0, react_1.useState)(false);
31
41
  const [comment, setComment] = (0, react_1.useState)("");
32
42
  const threadsEndRef = (0, react_1.useRef)(null);
33
- const [invalid, setInvalid] = (0, react_1.useState)(false);
43
+ const didMountRef = (0, react_1.useRef)(false);
34
44
  // Auto scroll to bottom when messages change
35
45
  (0, react_1.useEffect)(() => {
36
- var _a;
37
- (_a = threadsEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
38
- }, [messages]);
39
- const handleSend = () => {
40
- setInvalid(false);
41
- if (comment) {
42
- createDisputeChatMessage();
43
- handleSendMessage();
44
- setComment("");
46
+ if (didMountRef.current) {
47
+ if (threadsEndRef.current) {
48
+ threadsEndRef.current.scrollIntoView({ behavior: "smooth" });
49
+ }
45
50
  }
46
51
  else {
47
- setInvalid(true);
52
+ didMountRef.current = true;
48
53
  }
49
- };
50
- const handleSendMessage = () => {
51
- const newMsg = {
52
- messageId: 0, // update required
53
- disputeId: messages[0].disputeId,
54
- sender: {
55
- id: currentUser.id,
56
- email: currentUser.email,
57
- firstName: currentUser.name.split(' ')[0] || '',
58
- lastName: currentUser.name.split(' ')[1] || '',
59
- userTypeId: currentUser.userTypeId,
60
- avatar: currentUser.avatar,
61
- },
62
- messageText: comment,
63
- visibility: "ALL",
64
- createdAt: new Date().toISOString(),
65
- updatedAt: new Date().toISOString(),
66
- isDeleted: false,
67
- };
68
- setMessages([...messages, newMsg]);
69
- setComment("");
70
- };
54
+ }, [messages]);
55
+ const handleSend = () => __awaiter(void 0, void 0, void 0, function* () {
56
+ setSending(true);
57
+ try {
58
+ if (comment) {
59
+ const chatInput = {
60
+ disputeId: disputeId,
61
+ messageText: comment,
62
+ senderId: currentUser === null || currentUser === void 0 ? void 0 : currentUser.userId,
63
+ visibility: "ALL"
64
+ };
65
+ yield createDisputeChatMessage({
66
+ variables: {
67
+ input: chatInput
68
+ }
69
+ }).then((res) => {
70
+ const newMsg = {
71
+ messageId: res.data.createDisputeChatMessage.messageId,
72
+ disputeId: res.data.createDisputeChatMessage.disputeId,
73
+ sender: res.data.createDisputeChatMessage.sender,
74
+ messageText: res.data.createDisputeChatMessage.messageText,
75
+ visibility: res.data.createDisputeChatMessage.visibility,
76
+ createdAt: res.data.createDisputeChatMessage.createdAt,
77
+ updatedAt: res.data.createDisputeChatMessage.updatedAt,
78
+ isDeleted: res.data.createDisputeChatMessage.isDeleted,
79
+ };
80
+ setMessages([...messages, newMsg]);
81
+ setComment("");
82
+ }).catch((error) => {
83
+ console.error("Error creating dispute chat message:", error);
84
+ });
85
+ }
86
+ }
87
+ catch (error) {
88
+ console.error("Error sending message:", error);
89
+ }
90
+ finally {
91
+ setSending(false);
92
+ }
93
+ });
71
94
  const handleKeyPress = (e) => {
72
95
  if (e.key === "Enter" && !e.shiftKey) {
73
96
  e.preventDefault();
@@ -87,17 +110,17 @@ const DiscussionThread = ({ currentUser, initialThreads, createDisputeChatMessag
87
110
  .toUpperCase()
88
111
  .substring(0, 2);
89
112
  };
90
- return (react_1.default.createElement("div", { className: "flex flex-col w-full rounded-lg bg-white px-4 h-auto" },
113
+ return (react_1.default.createElement("div", { className: "flex flex-col w-full rounded-lg bg-white h-auto" },
91
114
  react_1.default.createElement("div", { className: `py-3 flex items-center` },
92
115
  react_1.default.createElement("div", { className: "font-semibold text-gray-800 capitalize" }, "Discussion Thread")),
93
- react_1.default.createElement("div", { className: "flex-1 max-h-[30vh] overflow-y-auto border rounded-md p-2" },
116
+ messages.length ? react_1.default.createElement("div", { className: "flex-1 max-h-[30vh] overflow-y-auto border rounded-md p-2" },
94
117
  messages.map((message) => {
95
- var _a;
96
- const isCurrentUser = currentUser.id === message.sender.id;
118
+ const isCurrentUser = currentUser.userId === message.sender.id;
97
119
  const userName = message.sender.firstName + message.sender.lastName;
98
120
  const timestamp = message.updatedAt ? message.updatedAt : message.createdAt;
99
121
  return (react_1.default.createElement("div", { key: message.messageId, className: `flex mb-4 ${isCurrentUser ? 'justify-end' : 'justify-start'}` },
100
- !isCurrentUser && (react_1.default.createElement("div", { className: "flex-shrink-0 mr-2" }, ((_a = message.sender) === null || _a === void 0 ? void 0 : _a.avatar) ? (react_1.default.createElement("img", { src: message.sender.avatar, alt: userName, className: "h-8 w-8 rounded-full" })) : (react_1.default.createElement("div", { className: "h-8 w-8 rounded-full bg-gray-400 flex items-center justify-center text-white text-xs font-medium bg-[#5f4508]" }, getInitials(userName || 'User'))))),
122
+ !isCurrentUser && (react_1.default.createElement("div", { className: "flex-shrink-0 mr-2" },
123
+ react_1.default.createElement("div", { className: "h-8 w-8 rounded-full bg-gray-400 flex items-center justify-center text-white text-xs font-medium bg-[#5f4508]" }, getInitials(userName || 'User')))),
101
124
  react_1.default.createElement("div", { className: `ml-1 min-w-min max-w-[75%] break-words` },
102
125
  !isCurrentUser && (react_1.default.createElement("div", { className: "text-xs text-gray-500 font-medium mb-1" }, userName || 'Unknown User')),
103
126
  react_1.default.createElement("div", { className: `px-4 py-2 rounded-lg ${isCurrentUser
@@ -105,10 +128,10 @@ const DiscussionThread = ({ currentUser, initialThreads, createDisputeChatMessag
105
128
  : 'bg-[#f9d8a7] border rounded-bl-none'}` }, message.messageText),
106
129
  react_1.default.createElement("div", { className: "text-xs text-gray-500 mt-1" }, formatTime(timestamp)))));
107
130
  }),
108
- react_1.default.createElement("div", { ref: threadsEndRef })),
131
+ react_1.default.createElement("div", { ref: threadsEndRef })) : react_1.default.createElement(react_1.default.Fragment, null),
109
132
  react_1.default.createElement("div", { className: "py-3" },
110
133
  react_1.default.createElement("div", { className: "flex items-center" },
111
134
  react_1.default.createElement("textarea", { value: comment, onChange: (e) => setComment(e.target.value), onKeyDown: handleKeyPress, placeholder: "Type your message here...", className: "flex-1 border rounded-lg px-3 py-2 resize-none focus:outline-none focus:ring-2 focus:ring-blue-500", rows: 1 }),
112
- react_1.default.createElement(base_ui_1.Button, { label: "Send", onClick: handleSend, disabled: !comment.trim(), color: "primary", className: "ml-2 px-4 py-2" })))));
135
+ react_1.default.createElement(base_ui_1.Button, { label: "Send", onClick: handleSend, disabled: !comment.trim(), isLoading: sending, color: "primary", className: "ml-2 px-4 py-2" })))));
113
136
  };
114
137
  exports.DiscussionThread = DiscussionThread;
@@ -1,5 +1,9 @@
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
+ }
8
+ export declare const InvoiceCard: ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceMutation }: InvoiceCardProps) => JSX.Element;
9
+ export {};
@@ -22,6 +22,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
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
+ };
25
37
  Object.defineProperty(exports, "__esModule", { value: true });
26
38
  exports.InvoiceCard = void 0;
27
39
  const react_1 = __importStar(require("react"));
@@ -30,6 +42,8 @@ const base_ui_2 = require("@paro.io/base-ui");
30
42
  const core_1 = require("@material-ui/core");
31
43
  const base_icons_1 = require("@paro.io/base-icons");
32
44
  const DiscussionThread_1 = require("../DiscussionThread");
45
+ const dayjs_1 = __importDefault(require("dayjs"));
46
+ const utils_1 = require("../shared/utils");
33
47
  const useStyles = (0, core_1.makeStyles)((theme) => ({
34
48
  root: {
35
49
  width: "100%",
@@ -80,6 +94,9 @@ const ACCEPTED_FILE_TYPES = [
80
94
  'application/pdf',
81
95
  'application/msword',
82
96
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
97
+ 'image/jpeg',
98
+ 'image/png',
99
+ 'text/csv',
83
100
  ];
84
101
  const validateFileUpload = (file) => {
85
102
  if (!file) {
@@ -88,18 +105,22 @@ const validateFileUpload = (file) => {
88
105
  if (!ACCEPTED_FILE_TYPES.includes(file.type)) {
89
106
  return false;
90
107
  }
91
- if (file.size > 5242880) { //5MB size
92
- return false;
93
- }
94
108
  return true;
95
109
  };
96
- const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user }) => {
110
+ const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user, chatMessages, updateClientInvoiceMutation }) => {
111
+ var _a, _b, _c, _d, _e, _f;
97
112
  const [expandRow, setExpandRow] = (0, react_1.useState)(null);
98
113
  const classes = useStyles();
99
- const [projects, setProjects] = (0, react_1.useState)(clientInvoice.disputeProjects);
114
+ const [projects, setProjects] = (0, react_1.useState)(clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects);
100
115
  const [editingRowId, setEditingRowId] = (0, react_1.useState)(null);
101
116
  const [editedExplanation, setEditedExplanation] = (0, react_1.useState)('');
102
- const [discussion, setDiscussion] = (0, react_1.useState)('');
117
+ const [updatedDispute, setUpdateDispute] = (0, react_1.useState)(false);
118
+ const [updatingDispute, setUpdatingDispute] = (0, react_1.useState)(false);
119
+ (0, react_1.useEffect)(() => {
120
+ if (JSON.stringify(clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeProjects) !== JSON.stringify(projects)) {
121
+ setUpdateDispute(true);
122
+ }
123
+ }, [projects]);
103
124
  const fileInputRef = (0, react_1.useRef)(null);
104
125
  const handleChange = (e, field) => {
105
126
  const updatedProject = field === "clientDocumentLinks" ? projects.map((project) => {
@@ -127,32 +148,68 @@ const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user }) => {
127
148
  fileInputRef.current.value = '';
128
149
  }
129
150
  };
130
- return (react_1.default.createElement(base_ui_1.Card, { className: `mx-2 my-4 md:mx-8 flex md:flex items-center justify-between rounded flex-col` },
131
- react_1.default.createElement("div", { key: clientInvoice.invoice.id, className: "bg-[#0F172A] text-white mb-1 p-4 relative top-0 left-0 w-full rounded flex flex-row justify-evenly" },
151
+ const handleEditExplanation = (projectId) => __awaiter(void 0, void 0, void 0, function* () {
152
+ setProjects((prev) => prev.map((p) => p.projectId === projectId
153
+ ? Object.assign(Object.assign({}, p), { clientExplanation: editedExplanation }) : p));
154
+ setEditingRowId(null);
155
+ });
156
+ const handleSubmitDispute = () => __awaiter(void 0, void 0, void 0, function* () {
157
+ setUpdatingDispute(true);
158
+ try {
159
+ yield updateClientInvoiceMutation({
160
+ variables: {
161
+ input: {
162
+ disputeId: projects[0].id,
163
+ projectDisputes: projects.map((project) => ({
164
+ projectId: project.projectId,
165
+ disputeReasonCode: project.disputeReasonCode,
166
+ disputeType: project.disputeType,
167
+ disputeHours: project.disputeHours,
168
+ disputeAmount: project.disputeAmount,
169
+ clientExplanation: project.clientExplanation,
170
+ clientDocumentLinks: project.clientDocumentLinks,
171
+ })),
172
+ }
173
+ }
174
+ }).then(() => {
175
+ (0, utils_1.showToast)('success', 'Dispute updation successfull!');
176
+ });
177
+ }
178
+ catch (error) {
179
+ console.error("Failed to update dispute", error);
180
+ (0, utils_1.showToast)('warning', 'Failed to update dispute');
181
+ }
182
+ finally {
183
+ setUpdatingDispute(false);
184
+ setUpdateDispute(false);
185
+ }
186
+ });
187
+ return (react_1.default.createElement(base_ui_1.Card, { className: `mx-1 my-4 md:mx-8 flex md:flex items-center justify-between rounded flex-col` },
188
+ react_1.default.createElement("div", { key: (_a = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.invoice) === null || _a === void 0 ? void 0 : _a.id, className: "bg-[#0F172A] text-white mb-1 p-4 relative top-0 left-0 w-full rounded flex flex-row justify-between" },
132
189
  react_1.default.createElement("b", null,
133
- "Dispute Invoice #",
134
- clientInvoice.invoice.id),
190
+ "Dispute Invoice #", (_b = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.invoice) === null || _b === void 0 ? void 0 :
191
+ _b.id),
135
192
  react_1.default.createElement("p", null,
136
- "Disputed: ",
193
+ "Dispute Date: ", clientInvoice === null || clientInvoice === void 0 ? void 0 :
137
194
  clientInvoice.disputeDate),
138
195
  react_1.default.createElement("p", null,
139
- "Invoice Date: ",
140
- clientInvoice.invoice.dateGenerated)),
141
- react_1.default.createElement("div", { className: "flex flex-row justify-start items-center gap-2" },
142
- clientInvoice && // for in progress
143
- react_1.default.createElement(base_ui_1.Tag, { color: "warning", label: "In Progress", variant: "subtle" }),
144
- clientInvoice && // for resolved
145
- react_1.default.createElement(base_ui_1.Tag, { color: "success", label: "Resolved", variant: "subtle" }),
146
- clientInvoice && // for submitted
147
- react_1.default.createElement(base_ui_1.Tag, { color: "danger", label: "Submitted", variant: "subtle" }),
148
- clientInvoice && // for acion taken
149
- react_1.default.createElement(base_ui_1.Tag, { color: "success", label: "Invoice reduced", variant: "subtle" }),
150
- clientInvoice && // for editable upto
151
- react_1.default.createElement(base_ui_1.Tag, { color: "warning", label: "Editable until May 30", variant: "subtle" }),
152
- clientInvoice && // for under review
153
- react_1.default.createElement(base_ui_1.Tag, { color: "info", label: "Under Review", variant: "subtle" }),
154
- react_1.default.createElement("div", { className: "flex ml-2 items-center" }, "Last updated: date")),
196
+ "Invoice Date: ", (_c = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.invoice) === null || _c === void 0 ? void 0 :
197
+ _c.dateGenerated),
198
+ react_1.default.createElement("p", null,
199
+ "Expert Name: ",
200
+ ((_d = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.freelancer) === null || _d === void 0 ? void 0 : _d.firstName) + " " + ((_e = clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.freelancer) === null || _e === void 0 ? void 0 : _e.lastName))),
155
201
  react_1.default.createElement("div", { className: "w-[95%] m-2" },
202
+ react_1.default.createElement("div", { className: "flex flex-row justify-start items-center gap-4 mr-auto mb-2" },
203
+ react_1.default.createElement("div", null,
204
+ (clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.status) === 'InProgress' &&
205
+ react_1.default.createElement(base_ui_1.Tag, { color: "warning", label: "In Progress", variant: "subtle" }),
206
+ (clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.status) === 'Resolved' &&
207
+ react_1.default.createElement(base_ui_1.Tag, { color: "success", label: "Resolved", variant: "subtle" }),
208
+ (clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.status) === 'UnderReview' &&
209
+ react_1.default.createElement(base_ui_1.Tag, { color: "info", label: "Under Review", variant: "subtle" })),
210
+ react_1.default.createElement("div", { className: "flex items-center" },
211
+ "Last updated: ",
212
+ (0, dayjs_1.default)(clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.disputeUpdatedDate).format("YYYY-MM-DD"))),
156
213
  react_1.default.createElement(core_1.Table, { className: classes.table, "aria-labelledby": "tableTitle", size: 'medium', "aria-label": "enhanced table" },
157
214
  react_1.default.createElement(core_1.TableHead, { className: classes.tableHead },
158
215
  react_1.default.createElement(core_1.TableRow, null,
@@ -161,51 +218,46 @@ const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user }) => {
161
218
  }),
162
219
  react_1.default.createElement(core_1.TableCell, { className: classes.tableCell }))), projects === null || projects === void 0 ? void 0 :
163
220
  projects.map((row) => {
164
- var _a, _b;
165
- return (react_1.default.createElement(react_1.default.Fragment, null,
166
- react_1.default.createElement(core_1.TableRow, { key: row.projectId },
167
- react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, (_a = row.project) === null || _a === void 0 ? void 0 : _a.name),
221
+ var _a;
222
+ return (react_1.default.createElement(react_1.default.Fragment, { key: row.projectId },
223
+ react_1.default.createElement(core_1.TableRow, null,
224
+ react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, ((_a = row.project) === null || _a === void 0 ? void 0 : _a.name) || "N/A"),
168
225
  react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeType),
169
- react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.hours),
226
+ react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeHours),
170
227
  react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeAmount),
171
228
  react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeReasonCode),
172
229
  react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell },
173
- react_1.default.createElement(core_1.IconButton, { onClick: () => { setExpandRow(expandRow === row.projectId ? null : row.projectId); } }, expandRow === row.projectId ? react_1.default.createElement(base_icons_1.IconChevronUp, null) : react_1.default.createElement(base_icons_1.IconChevronDown, null)))),
174
- expandRow &&
175
- react_1.default.createElement(core_1.TableRow, null,
176
- react_1.default.createElement(core_1.TableCell, { colSpan: headCells.length + 1, style: { paddingBottom: 0, paddingTop: 0 } },
177
- react_1.default.createElement(core_1.Collapse, { in: expandRow === row.projectId, timeout: "auto", unmountOnExit: true },
178
- react_1.default.createElement(react_1.default.Fragment, null,
179
- react_1.default.createElement(base_ui_1.Card, { className: `bg-[#F8F9FA] m-2 md:mx-8 flex md:flex items-start justify-between rounded flex-col w-[95%] p-6` },
180
- react_1.default.createElement("b", { className: "mb-2 flex flex-row justify-start items-center" },
181
- "Explanation:",
182
- editingRowId === row.projectId ? (react_1.default.createElement(react_1.default.Fragment, null,
183
- react_1.default.createElement(base_ui_2.Input, { label: "", type: "text", className: "w-96 mx-4 overflow-ellipsis", value: editedExplanation, onChange: (e) => setEditedExplanation(e.target.value), placeholder: "Please provide an explanation", isInvalid: !editedExplanation, isInvalidText: "Please provide an explanation" }),
184
- react_1.default.createElement(base_ui_2.Button, { label: "Save", size: "md", color: "success", className: "ml-2 mt-1", onClick: () => {
185
- setProjects((prev) => prev.map((p) => p.projectId === row.projectId
186
- ? Object.assign(Object.assign({}, p), { clientExplanation: editedExplanation }) : p));
187
- setEditingRowId(null);
188
- } }))) : (react_1.default.createElement(base_ui_2.Button, { label: "Edit", iconLeft: react_1.default.createElement(base_icons_1.IconPencil, { size: 'sm' }), onClick: () => {
189
- setEditedExplanation(row.clientExplanation);
190
- setEditingRowId(row.projectId);
191
- }, size: "sm", color: "info", className: "ml-6" }))),
192
- react_1.default.createElement("p", null, row.clientExplanation),
193
- react_1.default.createElement("b", { className: "flex flex-row flex-wrap justify-start items-center mt-2" },
194
- "Supporting Documents:",
195
- react_1.default.createElement("input", { id: "upload-file", type: "file", multiple: true, accept: ".pdf,.doc,.docx", style: { display: 'none' }, ref: fileInputRef, onChange: handleUpload }),
196
- react_1.default.createElement(base_ui_2.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size: 'sm' }), onClick: () => { fileInputRef.current && fileInputRef.current.click(); }, size: 'sm', color: "info", className: "mx-2" }),
197
- row.clientDocumentLinks && ((_b = row.clientDocumentLinks) === null || _b === void 0 ? void 0 : _b.map((f) => {
198
- return react_1.default.createElement("div", { className: "mx-2" },
199
- react_1.default.createElement(base_ui_1.Tag, { variant: "subtle", color: "success", label: f, iconRight: react_1.default.createElement(base_icons_1.IconXCircle, null), onClick: () => {
200
- const updatedFiles = projects.map((p) => {
201
- const updatedFiles = p.files.filter((file) => file !== f);
202
- return Object.assign(Object.assign({}, p), { files: updatedFiles });
203
- });
204
- setProjects(updatedFiles);
205
- } }));
206
- })))),
207
- react_1.default.createElement("div", { className: "flex flex-row w-[95%] m-2 ml-4 justify-start" },
208
- react_1.default.createElement(DiscussionThread_1.DiscussionThread, { key: row.projectId, currentUser: user, initialThreads: clientInvoice.chatMessages, createDisputeChatMessage: createDisputeChatMessage }))))))));
209
- })))));
230
+ react_1.default.createElement(core_1.IconButton, { onClick: () => setExpandRow(expandRow === row.projectId ? null : row.projectId) }, expandRow === row.projectId ? react_1.default.createElement(base_icons_1.IconChevronUp, null) : react_1.default.createElement(base_icons_1.IconChevronDown, null)))),
231
+ expandRow === row.projectId && (react_1.default.createElement(core_1.TableRow, { key: `expanded-${row.projectId}` },
232
+ react_1.default.createElement(core_1.TableCell, { colSpan: headCells.length + 1, style: { paddingBottom: 0, paddingTop: 0 } },
233
+ react_1.default.createElement(core_1.Collapse, { in: true, timeout: "auto", unmountOnExit: true },
234
+ react_1.default.createElement(react_1.default.Fragment, null,
235
+ react_1.default.createElement(base_ui_1.Card, { className: "bg-[#F8F9FA] m-2 flex items-start justify-between rounded flex-col w-full p-6" },
236
+ react_1.default.createElement("b", { className: "mb-2 flex flex-row justify-start items-center" },
237
+ "Explanation:",
238
+ editingRowId === row.projectId ? (react_1.default.createElement(react_1.default.Fragment, null,
239
+ react_1.default.createElement(base_ui_2.Input, { label: "", type: "text", className: "w-96 mx-4 overflow-ellipsis", value: editedExplanation, onChange: (e) => setEditedExplanation(e.target.value), placeholder: "Please provide an explanation", isInvalid: !editedExplanation, isInvalidText: "Please provide an explanation" }),
240
+ react_1.default.createElement(base_ui_2.Button, { label: "Save", size: "md", color: "success", className: "ml-2 mt-1", onClick: () => { handleEditExplanation(row.projectId); } }))) : (react_1.default.createElement(base_ui_2.Button, { label: "Edit", iconLeft: react_1.default.createElement(base_icons_1.IconPencil, { size: "sm" }), onClick: () => {
241
+ setEditedExplanation(row.clientExplanation);
242
+ setEditingRowId(row.projectId);
243
+ }, size: "sm", color: "info", className: "ml-6" }))),
244
+ react_1.default.createElement("p", null, row.clientExplanation),
245
+ react_1.default.createElement("b", { className: "flex flex-row flex-wrap justify-start items-center mt-2" },
246
+ "Supporting Documents:",
247
+ react_1.default.createElement("input", { id: "upload-file", type: "file", multiple: true, accept: ".pdf,.doc,.docx,.jpeg,.png,.gif,.csv", style: { display: 'none' }, ref: fileInputRef, onChange: handleUpload }),
248
+ react_1.default.createElement(base_ui_2.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: "mx-2" }),
249
+ (Array.isArray(row.clientDocumentLinks)
250
+ ? row.clientDocumentLinks
251
+ : []).map((f, index) => (react_1.default.createElement("div", { key: index, className: "mx-2" },
252
+ react_1.default.createElement(base_ui_1.Tag, { variant: "subtle", color: "success", label: f, iconRight: react_1.default.createElement(base_icons_1.IconXCircle, null), onClick: () => {
253
+ const updatedProjects = projects.map((p) => p.projectId === row.projectId
254
+ ? Object.assign(Object.assign({}, p), { clientDocumentLinks: p.clientDocumentLinks.filter((file) => file !== f) }) : p);
255
+ setProjects(updatedProjects);
256
+ } })))))))))))));
257
+ })),
258
+ updatedDispute && react_1.default.createElement("div", { className: "flex justify-end ml-auto mt-2" },
259
+ react_1.default.createElement(base_ui_2.Button, { label: "Update Dispute", color: "primary", isLoading: updatingDispute, onClick: () => handleSubmitDispute() })),
260
+ (clientInvoice === null || clientInvoice === void 0 ? void 0 : clientInvoice.chatEnabled) && react_1.default.createElement("div", { className: "flex flex-row w-full my-2 justify-start" },
261
+ react_1.default.createElement(DiscussionThread_1.DiscussionThread, { disputeId: (_f = projects[0]) === null || _f === void 0 ? void 0 : _f.id, currentUser: user, initialThreads: chatMessages, createDisputeChatMessage: createDisputeChatMessage })))));
210
262
  };
211
263
  exports.InvoiceCard = InvoiceCard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paro.io/expert-shared-components",
3
- "version": "1.11.2",
3
+ "version": "1.11.3",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {