@paro.io/expert-shared-components 1.11.1 → 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
|
|
43
|
+
const didMountRef = (0, react_1.useRef)(false);
|
|
34
44
|
// Auto scroll to bottom when messages change
|
|
35
45
|
(0, react_1.useEffect)(() => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
52
|
+
didMountRef.current = true;
|
|
48
53
|
}
|
|
49
|
-
};
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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,29 +110,28 @@ 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
|
|
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
|
-
|
|
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" },
|
|
101
|
-
|
|
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')))),
|
|
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
|
|
104
127
|
? 'bg-[#dbefef] rounded-br-none'
|
|
105
128
|
: 'bg-[#f9d8a7] border rounded-bl-none'}` }, message.messageText),
|
|
106
|
-
react_1.default.createElement("div", { className: "text-xs text-gray-500 mt-1" }, formatTime(timestamp)))
|
|
107
|
-
isCurrentUser && (react_1.default.createElement("div", { className: "flex-shrink-0 ml-2" }, (currentUser === null || currentUser === void 0 ? void 0 : currentUser.avatar) ? (react_1.default.createElement("img", { src: currentUser.avatar, alt: currentUser.name, className: "h-8 w-8 rounded-full" })) : (react_1.default.createElement("div", { className: "h-8 w-8 rounded-full bg-blue-400 flex items-center justify-center text-white text-xs font-medium" }, getInitials((currentUser === null || currentUser === void 0 ? void 0 : currentUser.name) || 'You')))))));
|
|
129
|
+
react_1.default.createElement("div", { className: "text-xs text-gray-500 mt-1" }, formatTime(timestamp)))));
|
|
108
130
|
}),
|
|
109
|
-
react_1.default.createElement("div", { ref: threadsEndRef })),
|
|
131
|
+
react_1.default.createElement("div", { ref: threadsEndRef })) : react_1.default.createElement(react_1.default.Fragment, null),
|
|
110
132
|
react_1.default.createElement("div", { className: "py-3" },
|
|
111
133
|
react_1.default.createElement("div", { className: "flex items-center" },
|
|
112
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 }),
|
|
113
|
-
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" })))));
|
|
114
136
|
};
|
|
115
137
|
exports.DiscussionThread = DiscussionThread;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
clientInvoice
|
|
1
|
+
interface InvoiceCardProps {
|
|
2
|
+
clientInvoice?: any;
|
|
3
3
|
createDisputeChatMessage: any;
|
|
4
4
|
user: any;
|
|
5
|
-
|
|
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 [
|
|
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,107 +148,116 @@ const InvoiceCard = ({ clientInvoice, createDisputeChatMessage, user }) => {
|
|
|
127
148
|
fileInputRef.current.value = '';
|
|
128
149
|
}
|
|
129
150
|
};
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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,
|
|
159
216
|
headCells.map((headcell) => {
|
|
160
217
|
return react_1.default.createElement(core_1.TableCell, { key: headcell.id, className: classes.tableCell }, headcell.label);
|
|
161
218
|
}),
|
|
162
|
-
react_1.default.createElement(core_1.TableCell, { className: classes.tableCell }))),
|
|
163
|
-
projects.map((row) =>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeType),
|
|
167
|
-
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.hours),
|
|
168
|
-
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeAmount),
|
|
169
|
-
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeReasonCode),
|
|
170
|
-
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell },
|
|
171
|
-
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)))),
|
|
172
|
-
expandRow &&
|
|
219
|
+
react_1.default.createElement(core_1.TableCell, { className: classes.tableCell }))), projects === null || projects === void 0 ? void 0 :
|
|
220
|
+
projects.map((row) => {
|
|
221
|
+
var _a;
|
|
222
|
+
return (react_1.default.createElement(react_1.default.Fragment, { key: row.projectId },
|
|
173
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"),
|
|
225
|
+
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeType),
|
|
226
|
+
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeHours),
|
|
227
|
+
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeAmount),
|
|
228
|
+
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell }, row.disputeReasonCode),
|
|
229
|
+
react_1.default.createElement(core_1.TableCell, { align: "left", className: classes.tableCell },
|
|
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}` },
|
|
174
232
|
react_1.default.createElement(core_1.TableCell, { colSpan: headCells.length + 1, style: { paddingBottom: 0, paddingTop: 0 } },
|
|
175
|
-
react_1.default.createElement(core_1.Collapse, { in:
|
|
233
|
+
react_1.default.createElement(core_1.Collapse, { in: true, timeout: "auto", unmountOnExit: true },
|
|
176
234
|
react_1.default.createElement(react_1.default.Fragment, null,
|
|
177
|
-
react_1.default.createElement(base_ui_1.Card, { className:
|
|
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" },
|
|
178
236
|
react_1.default.createElement("b", { className: "mb-2 flex flex-row justify-start items-center" },
|
|
179
237
|
"Explanation:",
|
|
180
238
|
editingRowId === row.projectId ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
181
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" }),
|
|
182
|
-
react_1.default.createElement(base_ui_2.Button, { label: "Save", size: "md", color: "success", className: "ml-2 mt-1", onClick: () => {
|
|
183
|
-
setProjects((prev) => prev.map((p) => p.projectId === row.projectId
|
|
184
|
-
? Object.assign(Object.assign({}, p), { clientExplanation: editedExplanation }) : p));
|
|
185
|
-
setEditingRowId(null);
|
|
186
|
-
} }))) : (react_1.default.createElement(base_ui_2.Button, { label: "Edit", iconLeft: react_1.default.createElement(base_icons_1.IconPencil, { size: 'sm' }), onClick: () => {
|
|
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: () => {
|
|
187
241
|
setEditedExplanation(row.clientExplanation);
|
|
188
242
|
setEditingRowId(row.projectId);
|
|
189
243
|
}, size: "sm", color: "info", className: "ml-6" }))),
|
|
190
244
|
react_1.default.createElement("p", null, row.clientExplanation),
|
|
191
245
|
react_1.default.createElement("b", { className: "flex flex-row flex-wrap justify-start items-center mt-2" },
|
|
192
246
|
"Supporting Documents:",
|
|
193
|
-
react_1.default.createElement("input", { id: "upload-file", type: "file", multiple: true, accept: ".pdf,.doc,.docx", style: { display: 'none' }, ref: fileInputRef, onChange: handleUpload }),
|
|
194
|
-
react_1.default.createElement(base_ui_2.Button, { label: "Add File", iconLeft: react_1.default.createElement(base_icons_1.IconPlus, { size:
|
|
195
|
-
row.clientDocumentLinks
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
react_1.default.createElement("div", { className: "flex flex-row w-[80%] justify-start" },
|
|
209
|
-
react_1.default.createElement("div", { className: "flex justify-center items-center bg-[#26A69A] h-12 w-12 rounded-full text-2xl text-white" }, "PS"),
|
|
210
|
-
react_1.default.createElement("div", { className: "flex flex-col items-start ml-4" },
|
|
211
|
-
react_1.default.createElement("b", null,
|
|
212
|
-
"Paro Support: ",
|
|
213
|
-
react_1.default.createElement("span", null, "Apr 3, 2025")),
|
|
214
|
-
" ",
|
|
215
|
-
react_1.default.createElement("p", null, "We've received your dispute and are reviewing the timesheet discrepancies."),
|
|
216
|
-
react_1.default.createElement("p", null, "We'll follow up with the expert and update you by Apr 5."),
|
|
217
|
-
react_1.default.createElement("p", null, obj.paroSupport)))
|
|
218
|
-
:
|
|
219
|
-
react_1.default.createElement("div", { className: "flex flex-row-reverse w-[85%] justify-items-end items-center ml-auto my-1" },
|
|
220
|
-
react_1.default.createElement("div", { className: "flex justify-center items-center bg-[#4cbaff] h-12 w-12 rounded-full text-2xl text-white ml-4" }, "A"),
|
|
221
|
-
react_1.default.createElement("p", null, obj.you));
|
|
222
|
-
})),
|
|
223
|
-
react_1.default.createElement("div", { className: "flex flex-row w-[95%] m-2 ml-4 justify-start" },
|
|
224
|
-
react_1.default.createElement(DiscussionThread_1.DiscussionThread, { currentUser: user, initialThreads: clientInvoice.chatMessages, createDisputeChatMessage: createDisputeChatMessage }),
|
|
225
|
-
react_1.default.createElement(base_ui_2.Input, { label: "", type: "text", className: "w-[60vw] mx-4 overflow-ellipsis", value: discussion, onChange: (e) => setDiscussion(e.target.value), placeholder: "Type your reply here..." }),
|
|
226
|
-
react_1.default.createElement(base_ui_2.Button, { label: "Save", size: "md", color: "success", className: "ml-2 mt-1 w-full", disabled: !discussion, onClick: () => {
|
|
227
|
-
setProjects((prev) => prev.map((p) => p.projectId === row.projectId
|
|
228
|
-
? Object.assign(Object.assign({}, p), { discussion: [...p.discussion, { you: discussion }] }) : p));
|
|
229
|
-
setEditingRowId(null);
|
|
230
|
-
setDiscussion('');
|
|
231
|
-
} })))))))))))));
|
|
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 })))));
|
|
232
262
|
};
|
|
233
263
|
exports.InvoiceCard = InvoiceCard;
|