@adatechnology/conversations-ui 0.1.0-rc.10 → 0.1.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-FWNAWAJP.js → chunk-3RKFU46R.js} +35 -0
- package/dist/index.d.ts +103 -2
- package/dist/index.js +694 -435
- package/dist/preview/index.d.ts +12 -1
- package/dist/preview/index.js +21 -6
- package/package.json +1 -1
- package/src/MessageComposer.tsx +73 -0
- package/src/RichMessageComposer.test.tsx +83 -0
- package/src/RichMessageComposer.tsx +379 -0
- package/src/index.ts +11 -0
- package/src/preview/AudioRecorderButton.tsx +33 -3
- package/src/preview/ConversationPreview.tsx +8 -1
- package/src/quickReply.test.ts +58 -0
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
MessageBubble,
|
|
24
24
|
MessageComposer,
|
|
25
25
|
StatusTicks,
|
|
26
|
+
applyQuickReplyVariables,
|
|
26
27
|
cn,
|
|
27
28
|
conversationsOf,
|
|
28
29
|
createMediaUrlResolver,
|
|
@@ -33,13 +34,14 @@ import {
|
|
|
33
34
|
isSameDay,
|
|
34
35
|
phoneCountryFlag,
|
|
35
36
|
phoneInitials,
|
|
37
|
+
resolveQuickReply,
|
|
36
38
|
searchEmojis,
|
|
37
39
|
totalOf,
|
|
38
40
|
useAsyncResource,
|
|
39
41
|
useConversationDocuments,
|
|
40
42
|
useConversationLocales,
|
|
41
43
|
useConversations
|
|
42
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-3RKFU46R.js";
|
|
43
45
|
import {
|
|
44
46
|
htmlToWA,
|
|
45
47
|
parseWhatsAppFormatting,
|
|
@@ -49,128 +51,14 @@ import {
|
|
|
49
51
|
waToHTMLInline
|
|
50
52
|
} from "./chunk-2AYDBWNE.js";
|
|
51
53
|
|
|
52
|
-
// src/
|
|
53
|
-
import { useRef } from "react";
|
|
54
|
-
import { Bold, Italic, Strikethrough } from "lucide-react";
|
|
55
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
56
|
-
var DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS = {
|
|
57
|
-
bold: "Negrito",
|
|
58
|
-
boldHint: "Negrito (*texto*)",
|
|
59
|
-
italic: "It\xE1lico",
|
|
60
|
-
italicHint: "It\xE1lico (_texto_)",
|
|
61
|
-
strikethrough: "Tachado",
|
|
62
|
-
strikethroughHint: "Tachado (~texto~)",
|
|
63
|
-
insertPlaceholder: (token) => `Inserir ${token}`
|
|
64
|
-
};
|
|
65
|
-
var INLINE_TOKEN = /(\*[^*\n]+\*|_[^_\n]+_|~[^~\n]+~|`[^`\n]+`|\{[a-zA-Z_]+\})/g;
|
|
66
|
-
function renderLine(line, lineKey) {
|
|
67
|
-
const nodes = [];
|
|
68
|
-
let lastIndex = 0;
|
|
69
|
-
let match;
|
|
70
|
-
let tokenIndex = 0;
|
|
71
|
-
INLINE_TOKEN.lastIndex = 0;
|
|
72
|
-
while ((match = INLINE_TOKEN.exec(line)) !== null) {
|
|
73
|
-
if (match.index > lastIndex) nodes.push(line.slice(lastIndex, match.index));
|
|
74
|
-
const token = match[0];
|
|
75
|
-
const key = `${lineKey}-${tokenIndex++}`;
|
|
76
|
-
if (token.startsWith("*")) nodes.push(/* @__PURE__ */ jsx("strong", { children: token.slice(1, -1) }, key));
|
|
77
|
-
else if (token.startsWith("_")) nodes.push(/* @__PURE__ */ jsx("em", { children: token.slice(1, -1) }, key));
|
|
78
|
-
else if (token.startsWith("~")) nodes.push(/* @__PURE__ */ jsx("s", { children: token.slice(1, -1) }, key));
|
|
79
|
-
else if (token.startsWith("`")) nodes.push(/* @__PURE__ */ jsx("code", { className: "font-mono text-[0.85em]", children: token.slice(1, -1) }, key));
|
|
80
|
-
else nodes.push(/* @__PURE__ */ jsx("span", { className: "rounded bg-blue-100 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300 px-1", children: token }, key));
|
|
81
|
-
lastIndex = INLINE_TOKEN.lastIndex;
|
|
82
|
-
}
|
|
83
|
-
if (lastIndex < line.length) nodes.push(line.slice(lastIndex));
|
|
84
|
-
return nodes;
|
|
85
|
-
}
|
|
86
|
-
function renderWhatsApp(text) {
|
|
87
|
-
const lines = text.split("\n");
|
|
88
|
-
return lines.map((line, index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
89
|
-
renderLine(line, `ln-${index}`),
|
|
90
|
-
index < lines.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
|
|
91
|
-
] }, `ln-${index}`));
|
|
92
|
-
}
|
|
93
|
-
function WhatsAppMessageEditor({
|
|
94
|
-
value,
|
|
95
|
-
onChange,
|
|
96
|
-
placeholder,
|
|
97
|
-
placeholders = [],
|
|
98
|
-
rows = 4,
|
|
99
|
-
previewLabel = "Pr\xE9via (como aparece no WhatsApp)",
|
|
100
|
-
emptyPreviewText = "Sua mensagem aparecer\xE1 aqui\u2026",
|
|
101
|
-
labels
|
|
102
|
-
}) {
|
|
103
|
-
const editorLabels = { ...DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, ...labels };
|
|
104
|
-
const textareaRef = useRef(null);
|
|
105
|
-
function wrapSelection(marker) {
|
|
106
|
-
const textarea = textareaRef.current;
|
|
107
|
-
if (!textarea) return;
|
|
108
|
-
const start = textarea.selectionStart;
|
|
109
|
-
const end = textarea.selectionEnd;
|
|
110
|
-
const selected = value.slice(start, end) || "texto";
|
|
111
|
-
const next = value.slice(0, start) + marker + selected + marker + value.slice(end);
|
|
112
|
-
onChange(next);
|
|
113
|
-
requestAnimationFrame(() => {
|
|
114
|
-
textarea.focus();
|
|
115
|
-
textarea.setSelectionRange(start + marker.length, start + marker.length + selected.length);
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
function insertAtCursor(snippet) {
|
|
119
|
-
const textarea = textareaRef.current;
|
|
120
|
-
if (!textarea) return;
|
|
121
|
-
const start = textarea.selectionStart;
|
|
122
|
-
const end = textarea.selectionEnd;
|
|
123
|
-
const next = value.slice(0, start) + snippet + value.slice(end);
|
|
124
|
-
onChange(next);
|
|
125
|
-
requestAnimationFrame(() => {
|
|
126
|
-
textarea.focus();
|
|
127
|
-
const caret = start + snippet.length;
|
|
128
|
-
textarea.setSelectionRange(caret, caret);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
const toolbarButtonClass = "inline-flex items-center justify-center h-8 w-8 rounded-lg border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors";
|
|
132
|
-
return /* @__PURE__ */ jsxs("div", { children: [
|
|
133
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5 mb-2", children: [
|
|
134
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => wrapSelection("*"), className: toolbarButtonClass, title: editorLabels.boldHint, "aria-label": editorLabels.bold, children: /* @__PURE__ */ jsx(Bold, { size: 15 }) }),
|
|
135
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => wrapSelection("_"), className: toolbarButtonClass, title: editorLabels.italicHint, "aria-label": editorLabels.italic, children: /* @__PURE__ */ jsx(Italic, { size: 15 }) }),
|
|
136
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => wrapSelection("~"), className: toolbarButtonClass, title: editorLabels.strikethroughHint, "aria-label": editorLabels.strikethrough, children: /* @__PURE__ */ jsx(Strikethrough, { size: 15 }) }),
|
|
137
|
-
placeholders.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
-
/* @__PURE__ */ jsx("span", { className: "mx-1 h-5 w-px bg-gray-200 dark:bg-gray-600" }),
|
|
139
|
-
placeholders.map((token) => /* @__PURE__ */ jsx(
|
|
140
|
-
"button",
|
|
141
|
-
{
|
|
142
|
-
type: "button",
|
|
143
|
-
onClick: () => insertAtCursor(token),
|
|
144
|
-
className: "inline-flex items-center h-8 px-2 rounded-lg border border-gray-200 dark:border-gray-600 text-xs text-blue-600 dark:text-blue-300 hover:bg-blue-50 dark:hover:bg-blue-900/40 transition-colors",
|
|
145
|
-
title: editorLabels.insertPlaceholder(token),
|
|
146
|
-
children: token
|
|
147
|
-
},
|
|
148
|
-
token
|
|
149
|
-
))
|
|
150
|
-
] })
|
|
151
|
-
] }),
|
|
152
|
-
/* @__PURE__ */ jsx(
|
|
153
|
-
"textarea",
|
|
154
|
-
{
|
|
155
|
-
ref: textareaRef,
|
|
156
|
-
value,
|
|
157
|
-
onChange: (event) => onChange(event.target.value),
|
|
158
|
-
placeholder,
|
|
159
|
-
rows,
|
|
160
|
-
className: "w-full border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition-all placeholder:text-gray-400 dark:placeholder:text-gray-500 resize-y"
|
|
161
|
-
}
|
|
162
|
-
),
|
|
163
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-2", children: [
|
|
164
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-1", children: previewLabel }),
|
|
165
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-xl bg-[#e5ded8] dark:bg-gray-900 p-3", children: /* @__PURE__ */ jsx("div", { className: "inline-block max-w-full rounded-lg rounded-tl-none bg-white dark:bg-gray-800 shadow-sm px-3 py-2 text-sm text-gray-800 dark:text-gray-100 whitespace-pre-wrap break-words", children: value.trim() ? renderWhatsApp(value) : /* @__PURE__ */ jsx("span", { className: "text-gray-400 dark:text-gray-500", children: emptyPreviewText }) }) })
|
|
166
|
-
] })
|
|
167
|
-
] });
|
|
168
|
-
}
|
|
54
|
+
// src/RichMessageComposer.tsx
|
|
55
|
+
import { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef as useRef2, useState as useState2 } from "react";
|
|
56
|
+
import { Bold, Italic, Strikethrough, Code, Paperclip, SendHorizonal, Braces } from "lucide-react";
|
|
169
57
|
|
|
170
58
|
// src/SimpleEmojiPicker.tsx
|
|
171
|
-
import { useEffect, useRef
|
|
59
|
+
import { useEffect, useRef, useState } from "react";
|
|
172
60
|
import { Smile } from "lucide-react";
|
|
173
|
-
import { jsx
|
|
61
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
174
62
|
var EMOJIS = [
|
|
175
63
|
"\u{1F600}",
|
|
176
64
|
"\u{1F602}",
|
|
@@ -255,7 +143,7 @@ var EMOJIS = [
|
|
|
255
143
|
];
|
|
256
144
|
function SimpleEmojiPicker({ onSelect, label = "Emojis", pickerWidth = "280px", pickerMaxHeight = "220px" }) {
|
|
257
145
|
const [open, setOpen] = useState(false);
|
|
258
|
-
const containerRef =
|
|
146
|
+
const containerRef = useRef(null);
|
|
259
147
|
useEffect(() => {
|
|
260
148
|
if (!open) return;
|
|
261
149
|
const handleClickOutside = (e) => {
|
|
@@ -266,23 +154,23 @@ function SimpleEmojiPicker({ onSelect, label = "Emojis", pickerWidth = "280px",
|
|
|
266
154
|
document.addEventListener("mousedown", handleClickOutside);
|
|
267
155
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
268
156
|
}, [open]);
|
|
269
|
-
return /* @__PURE__ */
|
|
270
|
-
/* @__PURE__ */
|
|
157
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative flex-shrink-0", children: [
|
|
158
|
+
/* @__PURE__ */ jsx(
|
|
271
159
|
"button",
|
|
272
160
|
{
|
|
273
161
|
type: "button",
|
|
274
162
|
onClick: () => setOpen((v) => !v),
|
|
275
163
|
className: "w-7 h-7 flex items-center justify-center rounded-lg text-gray-400 dark:text-gray-500 hover:text-teal-600 dark:hover:text-teal-400 hover:bg-teal-50 dark:hover:bg-teal-900/30 transition-colors",
|
|
276
164
|
title: label,
|
|
277
|
-
children: /* @__PURE__ */
|
|
165
|
+
children: /* @__PURE__ */ jsx(Smile, { size: 15 })
|
|
278
166
|
}
|
|
279
167
|
),
|
|
280
|
-
open && /* @__PURE__ */
|
|
168
|
+
open && /* @__PURE__ */ jsx("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-xl shadow-xl p-2 z-50", children: /* @__PURE__ */ jsx(
|
|
281
169
|
"div",
|
|
282
170
|
{
|
|
283
171
|
className: "grid grid-cols-10 gap-0.5 overflow-y-auto",
|
|
284
172
|
style: { width: pickerWidth, maxHeight: pickerMaxHeight },
|
|
285
|
-
children: EMOJIS.map((emoji) => /* @__PURE__ */
|
|
173
|
+
children: EMOJIS.map((emoji) => /* @__PURE__ */ jsx(
|
|
286
174
|
"button",
|
|
287
175
|
{
|
|
288
176
|
type: "button",
|
|
@@ -300,8 +188,374 @@ function SimpleEmojiPicker({ onSelect, label = "Emojis", pickerWidth = "280px",
|
|
|
300
188
|
] });
|
|
301
189
|
}
|
|
302
190
|
|
|
191
|
+
// src/RichMessageComposer.tsx
|
|
192
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
193
|
+
var RICH_COMPOSER_ACTION = {
|
|
194
|
+
BOLD: "bold",
|
|
195
|
+
ITALIC: "italic",
|
|
196
|
+
STRIKETHROUGH: "strikethrough",
|
|
197
|
+
MONOSPACE: "monospace",
|
|
198
|
+
EMOJI: "emoji",
|
|
199
|
+
ATTACH: "attach",
|
|
200
|
+
VARIABLES: "variables"
|
|
201
|
+
};
|
|
202
|
+
var DEFAULT_RICH_COMPOSER_TOOLTIPS = {
|
|
203
|
+
bold: "Negrito",
|
|
204
|
+
italic: "It\xE1lico",
|
|
205
|
+
strikethrough: "Tachado",
|
|
206
|
+
monospace: "Monoespa\xE7ado",
|
|
207
|
+
emoji: "Emojis",
|
|
208
|
+
attach: "Anexar arquivo",
|
|
209
|
+
send: "Enviar",
|
|
210
|
+
variables: "Vari\xE1veis dispon\xEDveis"
|
|
211
|
+
};
|
|
212
|
+
var FORMATTING_ELEMENT = {
|
|
213
|
+
bold: "strong",
|
|
214
|
+
italic: "em",
|
|
215
|
+
strikethrough: "del",
|
|
216
|
+
monospace: "code"
|
|
217
|
+
};
|
|
218
|
+
var MONOSPACE_CLASS = "bg-black/5 dark:bg-white/10 rounded px-0.5 font-mono text-sm";
|
|
219
|
+
var RichMessageComposer = forwardRef(function RichMessageComposer2({
|
|
220
|
+
value,
|
|
221
|
+
onChange,
|
|
222
|
+
onSend,
|
|
223
|
+
onAttachFiles,
|
|
224
|
+
quickReplies,
|
|
225
|
+
variables,
|
|
226
|
+
toolbar,
|
|
227
|
+
tooltips,
|
|
228
|
+
placeholder,
|
|
229
|
+
disabled = false,
|
|
230
|
+
isSending = false,
|
|
231
|
+
idleAction,
|
|
232
|
+
attachmentsPreview,
|
|
233
|
+
acceptedFileTypes = DEFAULT_ACCEPTED_FILE_TYPES,
|
|
234
|
+
className
|
|
235
|
+
}, ref) {
|
|
236
|
+
const editorRef = useRef2(null);
|
|
237
|
+
const fileInputRef = useRef2(null);
|
|
238
|
+
const variablesRef = useRef2(null);
|
|
239
|
+
const [isVariablesOpen, setIsVariablesOpen] = useState2(false);
|
|
240
|
+
useEffect2(() => {
|
|
241
|
+
if (!isVariablesOpen) return;
|
|
242
|
+
const closeOnOutsideClick = (event) => {
|
|
243
|
+
if (!variablesRef.current?.contains(event.target)) setIsVariablesOpen(false);
|
|
244
|
+
};
|
|
245
|
+
document.addEventListener("mousedown", closeOnOutsideClick);
|
|
246
|
+
return () => document.removeEventListener("mousedown", closeOnOutsideClick);
|
|
247
|
+
}, [isVariablesOpen]);
|
|
248
|
+
const tooltipOf = (action) => tooltips?.[action] ?? DEFAULT_RICH_COMPOSER_TOOLTIPS[action];
|
|
249
|
+
const shows = (action) => toolbar?.[action] !== false;
|
|
250
|
+
const replaceContent = useCallback((text) => {
|
|
251
|
+
const editor = editorRef.current;
|
|
252
|
+
if (!editor) return;
|
|
253
|
+
editor.innerHTML = waToHTML(text);
|
|
254
|
+
onChange(htmlToWA(editor.innerHTML));
|
|
255
|
+
editor.focus();
|
|
256
|
+
}, [onChange]);
|
|
257
|
+
useImperativeHandle(ref, () => ({
|
|
258
|
+
setContent: replaceContent,
|
|
259
|
+
clear: () => {
|
|
260
|
+
const editor = editorRef.current;
|
|
261
|
+
if (!editor) return;
|
|
262
|
+
editor.innerHTML = "";
|
|
263
|
+
onChange("");
|
|
264
|
+
},
|
|
265
|
+
focus: () => editorRef.current?.focus()
|
|
266
|
+
}), [onChange, replaceContent]);
|
|
267
|
+
const currentRange = useCallback(() => {
|
|
268
|
+
const editor = editorRef.current;
|
|
269
|
+
if (!editor) return void 0;
|
|
270
|
+
editor.focus();
|
|
271
|
+
const selection = window.getSelection();
|
|
272
|
+
if (!selection?.rangeCount || !editor.contains(selection.anchorNode)) return void 0;
|
|
273
|
+
return selection.getRangeAt(0);
|
|
274
|
+
}, []);
|
|
275
|
+
const commitRange = useCallback((range, node) => {
|
|
276
|
+
const selection = window.getSelection();
|
|
277
|
+
range.setStartAfter(node);
|
|
278
|
+
range.collapse(true);
|
|
279
|
+
selection?.removeAllRanges();
|
|
280
|
+
selection?.addRange(range);
|
|
281
|
+
onChange(htmlToWA(editorRef.current?.innerHTML ?? ""));
|
|
282
|
+
}, [onChange]);
|
|
283
|
+
const insertAtCursor = useCallback((fragment) => {
|
|
284
|
+
const range = currentRange();
|
|
285
|
+
if (!range) return;
|
|
286
|
+
range.deleteContents();
|
|
287
|
+
const textNode = document.createTextNode(fragment);
|
|
288
|
+
range.insertNode(textNode);
|
|
289
|
+
commitRange(range, textNode);
|
|
290
|
+
}, [commitRange, currentRange]);
|
|
291
|
+
const wrapSelection = useCallback((action) => {
|
|
292
|
+
const range = currentRange();
|
|
293
|
+
const selectedText = range?.toString();
|
|
294
|
+
if (!range || !selectedText) return;
|
|
295
|
+
range.deleteContents();
|
|
296
|
+
const wrapper = document.createElement(FORMATTING_ELEMENT[action]);
|
|
297
|
+
if (action === "monospace") wrapper.className = MONOSPACE_CLASS;
|
|
298
|
+
wrapper.textContent = selectedText;
|
|
299
|
+
range.insertNode(wrapper);
|
|
300
|
+
commitRange(range, wrapper);
|
|
301
|
+
}, [commitRange, currentRange]);
|
|
302
|
+
const handleInput = useCallback((event) => {
|
|
303
|
+
onChange(htmlToWA(event.currentTarget.innerHTML));
|
|
304
|
+
}, [onChange]);
|
|
305
|
+
const handleKeyDown = useCallback((event) => {
|
|
306
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
if (!disabled) onSend();
|
|
309
|
+
}
|
|
310
|
+
}, [disabled, onSend]);
|
|
311
|
+
const handleFileChange = useCallback((event) => {
|
|
312
|
+
if (event.target.files?.length) onAttachFiles?.(event.target.files);
|
|
313
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
314
|
+
}, [onAttachFiles]);
|
|
315
|
+
const canSend = value.trim().length > 0;
|
|
316
|
+
return /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col", className), children: [
|
|
317
|
+
attachmentsPreview,
|
|
318
|
+
quickReplies?.length ? (
|
|
319
|
+
/* Uma linha rolável no celular, quebrando em várias no desktop: empilhar os chips no
|
|
320
|
+
celular come a altura da conversa, que é o que o operador precisa ver. */
|
|
321
|
+
/* @__PURE__ */ jsx2("div", { className: "mb-2 flex flex-nowrap gap-1 overflow-x-auto sm:flex-wrap sm:overflow-x-visible [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: quickReplies.map((quickReply) => /* @__PURE__ */ jsx2(
|
|
322
|
+
"button",
|
|
323
|
+
{
|
|
324
|
+
type: "button",
|
|
325
|
+
title: quickReply.tooltip,
|
|
326
|
+
onClick: () => replaceContent(quickReply.text),
|
|
327
|
+
className: "whitespace-nowrap rounded-full border border-gray-200 bg-white px-2 py-1 text-xs text-gray-600 transition-colors hover:border-teal-200 hover:bg-teal-50 hover:text-teal-700 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:border-teal-800 dark:hover:bg-teal-950/40 dark:hover:text-teal-400",
|
|
328
|
+
children: quickReply.label
|
|
329
|
+
},
|
|
330
|
+
quickReply.id
|
|
331
|
+
)) })
|
|
332
|
+
) : null,
|
|
333
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex flex-wrap items-end gap-2", children: [
|
|
334
|
+
/* @__PURE__ */ jsx2("div", { className: "mb-0.5 hidden items-center gap-0.5 sm:flex", children: [
|
|
335
|
+
[RICH_COMPOSER_ACTION.BOLD, Bold],
|
|
336
|
+
[RICH_COMPOSER_ACTION.ITALIC, Italic],
|
|
337
|
+
[RICH_COMPOSER_ACTION.STRIKETHROUGH, Strikethrough],
|
|
338
|
+
[RICH_COMPOSER_ACTION.MONOSPACE, Code]
|
|
339
|
+
].filter(([action]) => shows(action)).map(([action, Icon]) => /* @__PURE__ */ jsx2(
|
|
340
|
+
"button",
|
|
341
|
+
{
|
|
342
|
+
type: "button",
|
|
343
|
+
onClick: () => wrapSelection(action),
|
|
344
|
+
title: tooltipOf(action),
|
|
345
|
+
"aria-label": tooltipOf(action),
|
|
346
|
+
className: "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-teal-50 hover:text-teal-600 dark:text-gray-500 dark:hover:bg-teal-900/30 dark:hover:text-teal-400",
|
|
347
|
+
children: /* @__PURE__ */ jsx2(Icon, { size: 15 })
|
|
348
|
+
},
|
|
349
|
+
action
|
|
350
|
+
)) }),
|
|
351
|
+
shows(RICH_COMPOSER_ACTION.EMOJI) ? /* @__PURE__ */ jsx2(SimpleEmojiPicker, { onSelect: insertAtCursor, label: tooltipOf("emoji") }) : null,
|
|
352
|
+
variables?.length && shows(RICH_COMPOSER_ACTION.VARIABLES) ? /* @__PURE__ */ jsxs2("div", { ref: variablesRef, className: "relative", children: [
|
|
353
|
+
/* @__PURE__ */ jsx2(
|
|
354
|
+
"button",
|
|
355
|
+
{
|
|
356
|
+
type: "button",
|
|
357
|
+
onClick: () => setIsVariablesOpen((open) => !open),
|
|
358
|
+
title: tooltipOf("variables"),
|
|
359
|
+
"aria-label": tooltipOf("variables"),
|
|
360
|
+
"aria-expanded": isVariablesOpen,
|
|
361
|
+
className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full text-gray-400 transition-colors hover:bg-teal-50 hover:text-teal-600 dark:text-gray-500 dark:hover:bg-teal-900/30 dark:hover:text-teal-400",
|
|
362
|
+
children: /* @__PURE__ */ jsx2(Braces, { size: 18 })
|
|
363
|
+
}
|
|
364
|
+
),
|
|
365
|
+
isVariablesOpen ? /* @__PURE__ */ jsx2("div", { className: "absolute bottom-full left-0 z-20 mb-2 max-h-56 w-64 overflow-y-auto rounded-xl border border-gray-200 bg-white py-1 shadow-lg dark:border-gray-700 dark:bg-gray-800", children: variables.map((variable) => /* @__PURE__ */ jsxs2(
|
|
366
|
+
"button",
|
|
367
|
+
{
|
|
368
|
+
type: "button",
|
|
369
|
+
title: variable.tooltip ?? variable.value,
|
|
370
|
+
onClick: () => {
|
|
371
|
+
insertAtCursor(variable.value);
|
|
372
|
+
setIsVariablesOpen(false);
|
|
373
|
+
},
|
|
374
|
+
className: "flex w-full flex-col items-start px-3 py-1.5 text-left hover:bg-teal-50 dark:hover:bg-teal-950/40",
|
|
375
|
+
children: [
|
|
376
|
+
/* @__PURE__ */ jsx2("span", { className: "text-sm text-gray-800 dark:text-gray-100", children: variable.label }),
|
|
377
|
+
/* @__PURE__ */ jsx2("span", { className: "font-mono text-xs text-gray-400 dark:text-gray-500", children: variable.value })
|
|
378
|
+
]
|
|
379
|
+
},
|
|
380
|
+
variable.id
|
|
381
|
+
)) }) : null
|
|
382
|
+
] }) : null,
|
|
383
|
+
onAttachFiles && shows(RICH_COMPOSER_ACTION.ATTACH) ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
384
|
+
/* @__PURE__ */ jsx2(
|
|
385
|
+
"input",
|
|
386
|
+
{
|
|
387
|
+
ref: fileInputRef,
|
|
388
|
+
type: "file",
|
|
389
|
+
multiple: true,
|
|
390
|
+
accept: acceptedFileTypes,
|
|
391
|
+
onChange: handleFileChange,
|
|
392
|
+
className: "hidden"
|
|
393
|
+
}
|
|
394
|
+
),
|
|
395
|
+
/* @__PURE__ */ jsx2(
|
|
396
|
+
"button",
|
|
397
|
+
{
|
|
398
|
+
type: "button",
|
|
399
|
+
onClick: () => fileInputRef.current?.click(),
|
|
400
|
+
title: tooltipOf("attach"),
|
|
401
|
+
"aria-label": tooltipOf("attach"),
|
|
402
|
+
className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full text-gray-400 transition-colors hover:bg-teal-50 hover:text-teal-600 dark:text-gray-500 dark:hover:bg-teal-900/30 dark:hover:text-teal-400",
|
|
403
|
+
children: /* @__PURE__ */ jsx2(Paperclip, { size: 18 })
|
|
404
|
+
}
|
|
405
|
+
)
|
|
406
|
+
] }) : null,
|
|
407
|
+
/* @__PURE__ */ jsx2(
|
|
408
|
+
"div",
|
|
409
|
+
{
|
|
410
|
+
ref: editorRef,
|
|
411
|
+
contentEditable: !disabled,
|
|
412
|
+
suppressContentEditableWarning: true,
|
|
413
|
+
role: "textbox",
|
|
414
|
+
"aria-multiline": "true",
|
|
415
|
+
"aria-label": placeholder,
|
|
416
|
+
"data-placeholder": placeholder,
|
|
417
|
+
onInput: handleInput,
|
|
418
|
+
onKeyDown: handleKeyDown,
|
|
419
|
+
style: { minHeight: "36px", maxHeight: "120px" },
|
|
420
|
+
className: "flex-1 min-w-[180px] overflow-y-auto rounded-2xl border border-gray-200 bg-gray-50 px-4 py-2 text-sm text-gray-800 transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-teal-300 dark:border-gray-700 dark:bg-gray-700 dark:text-gray-100 empty:before:content-[attr(data-placeholder)] empty:before:text-gray-400 dark:empty:before:text-gray-500 before:pointer-events-none [&_strong]:font-semibold [&_em]:italic [&_del]:line-through [&_code]:rounded [&_code]:bg-black/5 [&_code]:px-0.5 [&_code]:font-mono [&_code]:text-sm dark:[&_code]:bg-white/10"
|
|
421
|
+
}
|
|
422
|
+
),
|
|
423
|
+
!canSend && idleAction ? /* @__PURE__ */ jsx2("div", { className: "flex-shrink-0", children: idleAction }) : /* @__PURE__ */ jsx2(
|
|
424
|
+
"button",
|
|
425
|
+
{
|
|
426
|
+
type: "button",
|
|
427
|
+
onClick: onSend,
|
|
428
|
+
disabled: disabled || isSending || !canSend,
|
|
429
|
+
title: tooltipOf("send"),
|
|
430
|
+
"aria-label": tooltipOf("send"),
|
|
431
|
+
className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-teal-600 text-white transition-colors hover:bg-teal-700 disabled:cursor-not-allowed disabled:opacity-40",
|
|
432
|
+
children: isSending ? /* @__PURE__ */ jsx2("span", { className: "text-xs", children: "\u23F3" }) : /* @__PURE__ */ jsx2(SendHorizonal, { size: 16 })
|
|
433
|
+
}
|
|
434
|
+
)
|
|
435
|
+
] })
|
|
436
|
+
] });
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// src/WhatsAppMessageEditor.tsx
|
|
440
|
+
import { useRef as useRef3 } from "react";
|
|
441
|
+
import { Bold as Bold2, Italic as Italic2, Strikethrough as Strikethrough2 } from "lucide-react";
|
|
442
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
443
|
+
var DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS = {
|
|
444
|
+
bold: "Negrito",
|
|
445
|
+
boldHint: "Negrito (*texto*)",
|
|
446
|
+
italic: "It\xE1lico",
|
|
447
|
+
italicHint: "It\xE1lico (_texto_)",
|
|
448
|
+
strikethrough: "Tachado",
|
|
449
|
+
strikethroughHint: "Tachado (~texto~)",
|
|
450
|
+
insertPlaceholder: (token) => `Inserir ${token}`
|
|
451
|
+
};
|
|
452
|
+
var INLINE_TOKEN = /(\*[^*\n]+\*|_[^_\n]+_|~[^~\n]+~|`[^`\n]+`|\{[a-zA-Z_]+\})/g;
|
|
453
|
+
function renderLine(line, lineKey) {
|
|
454
|
+
const nodes = [];
|
|
455
|
+
let lastIndex = 0;
|
|
456
|
+
let match;
|
|
457
|
+
let tokenIndex = 0;
|
|
458
|
+
INLINE_TOKEN.lastIndex = 0;
|
|
459
|
+
while ((match = INLINE_TOKEN.exec(line)) !== null) {
|
|
460
|
+
if (match.index > lastIndex) nodes.push(line.slice(lastIndex, match.index));
|
|
461
|
+
const token = match[0];
|
|
462
|
+
const key = `${lineKey}-${tokenIndex++}`;
|
|
463
|
+
if (token.startsWith("*")) nodes.push(/* @__PURE__ */ jsx3("strong", { children: token.slice(1, -1) }, key));
|
|
464
|
+
else if (token.startsWith("_")) nodes.push(/* @__PURE__ */ jsx3("em", { children: token.slice(1, -1) }, key));
|
|
465
|
+
else if (token.startsWith("~")) nodes.push(/* @__PURE__ */ jsx3("s", { children: token.slice(1, -1) }, key));
|
|
466
|
+
else if (token.startsWith("`")) nodes.push(/* @__PURE__ */ jsx3("code", { className: "font-mono text-[0.85em]", children: token.slice(1, -1) }, key));
|
|
467
|
+
else nodes.push(/* @__PURE__ */ jsx3("span", { className: "rounded bg-blue-100 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300 px-1", children: token }, key));
|
|
468
|
+
lastIndex = INLINE_TOKEN.lastIndex;
|
|
469
|
+
}
|
|
470
|
+
if (lastIndex < line.length) nodes.push(line.slice(lastIndex));
|
|
471
|
+
return nodes;
|
|
472
|
+
}
|
|
473
|
+
function renderWhatsApp(text) {
|
|
474
|
+
const lines = text.split("\n");
|
|
475
|
+
return lines.map((line, index) => /* @__PURE__ */ jsxs3("span", { children: [
|
|
476
|
+
renderLine(line, `ln-${index}`),
|
|
477
|
+
index < lines.length - 1 ? /* @__PURE__ */ jsx3("br", {}) : null
|
|
478
|
+
] }, `ln-${index}`));
|
|
479
|
+
}
|
|
480
|
+
function WhatsAppMessageEditor({
|
|
481
|
+
value,
|
|
482
|
+
onChange,
|
|
483
|
+
placeholder,
|
|
484
|
+
placeholders = [],
|
|
485
|
+
rows = 4,
|
|
486
|
+
previewLabel = "Pr\xE9via (como aparece no WhatsApp)",
|
|
487
|
+
emptyPreviewText = "Sua mensagem aparecer\xE1 aqui\u2026",
|
|
488
|
+
labels
|
|
489
|
+
}) {
|
|
490
|
+
const editorLabels = { ...DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, ...labels };
|
|
491
|
+
const textareaRef = useRef3(null);
|
|
492
|
+
function wrapSelection(marker) {
|
|
493
|
+
const textarea = textareaRef.current;
|
|
494
|
+
if (!textarea) return;
|
|
495
|
+
const start = textarea.selectionStart;
|
|
496
|
+
const end = textarea.selectionEnd;
|
|
497
|
+
const selected = value.slice(start, end) || "texto";
|
|
498
|
+
const next = value.slice(0, start) + marker + selected + marker + value.slice(end);
|
|
499
|
+
onChange(next);
|
|
500
|
+
requestAnimationFrame(() => {
|
|
501
|
+
textarea.focus();
|
|
502
|
+
textarea.setSelectionRange(start + marker.length, start + marker.length + selected.length);
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
function insertAtCursor(snippet) {
|
|
506
|
+
const textarea = textareaRef.current;
|
|
507
|
+
if (!textarea) return;
|
|
508
|
+
const start = textarea.selectionStart;
|
|
509
|
+
const end = textarea.selectionEnd;
|
|
510
|
+
const next = value.slice(0, start) + snippet + value.slice(end);
|
|
511
|
+
onChange(next);
|
|
512
|
+
requestAnimationFrame(() => {
|
|
513
|
+
textarea.focus();
|
|
514
|
+
const caret = start + snippet.length;
|
|
515
|
+
textarea.setSelectionRange(caret, caret);
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
const toolbarButtonClass = "inline-flex items-center justify-center h-8 w-8 rounded-lg border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors";
|
|
519
|
+
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
520
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-1.5 mb-2", children: [
|
|
521
|
+
/* @__PURE__ */ jsx3("button", { type: "button", onClick: () => wrapSelection("*"), className: toolbarButtonClass, title: editorLabels.boldHint, "aria-label": editorLabels.bold, children: /* @__PURE__ */ jsx3(Bold2, { size: 15 }) }),
|
|
522
|
+
/* @__PURE__ */ jsx3("button", { type: "button", onClick: () => wrapSelection("_"), className: toolbarButtonClass, title: editorLabels.italicHint, "aria-label": editorLabels.italic, children: /* @__PURE__ */ jsx3(Italic2, { size: 15 }) }),
|
|
523
|
+
/* @__PURE__ */ jsx3("button", { type: "button", onClick: () => wrapSelection("~"), className: toolbarButtonClass, title: editorLabels.strikethroughHint, "aria-label": editorLabels.strikethrough, children: /* @__PURE__ */ jsx3(Strikethrough2, { size: 15 }) }),
|
|
524
|
+
placeholders.length > 0 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
525
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-1 h-5 w-px bg-gray-200 dark:bg-gray-600" }),
|
|
526
|
+
placeholders.map((token) => /* @__PURE__ */ jsx3(
|
|
527
|
+
"button",
|
|
528
|
+
{
|
|
529
|
+
type: "button",
|
|
530
|
+
onClick: () => insertAtCursor(token),
|
|
531
|
+
className: "inline-flex items-center h-8 px-2 rounded-lg border border-gray-200 dark:border-gray-600 text-xs text-blue-600 dark:text-blue-300 hover:bg-blue-50 dark:hover:bg-blue-900/40 transition-colors",
|
|
532
|
+
title: editorLabels.insertPlaceholder(token),
|
|
533
|
+
children: token
|
|
534
|
+
},
|
|
535
|
+
token
|
|
536
|
+
))
|
|
537
|
+
] })
|
|
538
|
+
] }),
|
|
539
|
+
/* @__PURE__ */ jsx3(
|
|
540
|
+
"textarea",
|
|
541
|
+
{
|
|
542
|
+
ref: textareaRef,
|
|
543
|
+
value,
|
|
544
|
+
onChange: (event) => onChange(event.target.value),
|
|
545
|
+
placeholder,
|
|
546
|
+
rows,
|
|
547
|
+
className: "w-full border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition-all placeholder:text-gray-400 dark:placeholder:text-gray-500 resize-y"
|
|
548
|
+
}
|
|
549
|
+
),
|
|
550
|
+
/* @__PURE__ */ jsxs3("div", { className: "mt-2", children: [
|
|
551
|
+
/* @__PURE__ */ jsx3("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-1", children: previewLabel }),
|
|
552
|
+
/* @__PURE__ */ jsx3("div", { className: "rounded-xl bg-[#e5ded8] dark:bg-gray-900 p-3", children: /* @__PURE__ */ jsx3("div", { className: "inline-block max-w-full rounded-lg rounded-tl-none bg-white dark:bg-gray-800 shadow-sm px-3 py-2 text-sm text-gray-800 dark:text-gray-100 whitespace-pre-wrap break-words", children: value.trim() ? renderWhatsApp(value) : /* @__PURE__ */ jsx3("span", { className: "text-gray-400 dark:text-gray-500", children: emptyPreviewText }) }) })
|
|
553
|
+
] })
|
|
554
|
+
] });
|
|
555
|
+
}
|
|
556
|
+
|
|
303
557
|
// src/Avatar.tsx
|
|
304
|
-
import { jsx as
|
|
558
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
305
559
|
var DEFAULT_AVATAR_LABELS = {
|
|
306
560
|
unnamedContact: "Contato sem nome"
|
|
307
561
|
};
|
|
@@ -334,7 +588,7 @@ function Avatar({ name, avatarUrl, size = "md", className = "", labels }) {
|
|
|
334
588
|
const sizeClass = sizeClasses[size];
|
|
335
589
|
const unnamedContactLabel = labels?.unnamedContact ?? DEFAULT_AVATAR_LABELS.unnamedContact;
|
|
336
590
|
if (avatarUrl) {
|
|
337
|
-
return /* @__PURE__ */
|
|
591
|
+
return /* @__PURE__ */ jsx4(
|
|
338
592
|
"img",
|
|
339
593
|
{
|
|
340
594
|
src: avatarUrl,
|
|
@@ -345,17 +599,17 @@ function Avatar({ name, avatarUrl, size = "md", className = "", labels }) {
|
|
|
345
599
|
}
|
|
346
600
|
const bgColor = getBgColor(name);
|
|
347
601
|
if (!name) {
|
|
348
|
-
return /* @__PURE__ */
|
|
602
|
+
return /* @__PURE__ */ jsx4(
|
|
349
603
|
"div",
|
|
350
604
|
{
|
|
351
605
|
className: `${sizeClass} ${bgColor} rounded-full flex items-center justify-center text-white flex-shrink-0 ${className}`,
|
|
352
606
|
role: "img",
|
|
353
607
|
"aria-label": unnamedContactLabel,
|
|
354
|
-
children: /* @__PURE__ */
|
|
608
|
+
children: /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 24 24", fill: "currentColor", className: "h-[60%] w-[60%]", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm0 2c-4.42 0-8 2.24-8 5v1h16v-1c0-2.76-3.58-5-8-5Z" }) })
|
|
355
609
|
}
|
|
356
610
|
);
|
|
357
611
|
}
|
|
358
|
-
return /* @__PURE__ */
|
|
612
|
+
return /* @__PURE__ */ jsx4(
|
|
359
613
|
"div",
|
|
360
614
|
{
|
|
361
615
|
className: `${sizeClass} ${bgColor} rounded-full flex items-center justify-center text-white font-semibold flex-shrink-0 ${className}`,
|
|
@@ -448,7 +702,7 @@ function contactFlag(params) {
|
|
|
448
702
|
}
|
|
449
703
|
|
|
450
704
|
// src/ConversationListItem.tsx
|
|
451
|
-
import { jsx as
|
|
705
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
452
706
|
var DEFAULT_CONVERSATION_LIST_ITEM_LABELS = {
|
|
453
707
|
expiredWindow: "Janela expirada",
|
|
454
708
|
warningWindow: "Janela pr\xF3xima do fim"
|
|
@@ -531,7 +785,7 @@ var ConversationListItem = ({
|
|
|
531
785
|
onClick?.();
|
|
532
786
|
onSelect?.(conversation.id);
|
|
533
787
|
};
|
|
534
|
-
return /* @__PURE__ */
|
|
788
|
+
return /* @__PURE__ */ jsxs4(
|
|
535
789
|
"button",
|
|
536
790
|
{
|
|
537
791
|
onClick: handleClick,
|
|
@@ -540,34 +794,34 @@ var ConversationListItem = ({
|
|
|
540
794
|
backgroundColor: isActive && highlightActive ? "#f0f2f5" : "transparent"
|
|
541
795
|
},
|
|
542
796
|
children: [
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
545
|
-
conversation.waitingHuman && /* @__PURE__ */
|
|
797
|
+
/* @__PURE__ */ jsxs4("div", { className: "relative flex-shrink-0", children: [
|
|
798
|
+
/* @__PURE__ */ jsx5(Avatar, { name: conversation.clientName, size: "lg" }),
|
|
799
|
+
conversation.waitingHuman && /* @__PURE__ */ jsx5("div", { className: "absolute -bottom-0.5 -right-0.5 w-3.5 h-3.5 bg-amber-400 rounded-full border-2 border-white" })
|
|
546
800
|
] }),
|
|
547
|
-
/* @__PURE__ */
|
|
548
|
-
/* @__PURE__ */
|
|
549
|
-
/* @__PURE__ */
|
|
550
|
-
!conversation.clientName && flag ? /* @__PURE__ */
|
|
551
|
-
/* @__PURE__ */
|
|
552
|
-
windowStatus && windowStatus.label === "expired" && /* @__PURE__ */
|
|
553
|
-
windowStatus && windowStatus.label === "warning" && /* @__PURE__ */
|
|
801
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex-1 min-w-0", children: [
|
|
802
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-2", children: [
|
|
803
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
804
|
+
!conversation.clientName && flag ? /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: flag }) : null,
|
|
805
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[16px] text-[#111b21] truncate", children: name }),
|
|
806
|
+
windowStatus && windowStatus.label === "expired" && /* @__PURE__ */ jsx5("span", { className: "w-2 h-2 rounded-full bg-red-500 flex-shrink-0", title: expiredWindowLabel }),
|
|
807
|
+
windowStatus && windowStatus.label === "warning" && /* @__PURE__ */ jsx5("span", { className: "w-2 h-2 rounded-full bg-orange-500 flex-shrink-0", title: warningWindowLabel })
|
|
554
808
|
] }),
|
|
555
|
-
timestamp && /* @__PURE__ */
|
|
809
|
+
timestamp && /* @__PURE__ */ jsx5("span", { className: "text-xs text-[#667781] flex-shrink-0", children: timestamp })
|
|
556
810
|
] }),
|
|
557
|
-
conversation.clientName ? /* @__PURE__ */
|
|
558
|
-
flag ? /* @__PURE__ */
|
|
559
|
-
/* @__PURE__ */
|
|
811
|
+
conversation.clientName ? /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1 text-xs text-[#667781]", children: [
|
|
812
|
+
flag ? /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: flag }) : null,
|
|
813
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: displayHandle })
|
|
560
814
|
] }) : null,
|
|
561
|
-
/* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
563
|
-
preview.icon && /* @__PURE__ */
|
|
815
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between mt-0.5", children: [
|
|
816
|
+
/* @__PURE__ */ jsxs4("span", { className: "text-sm text-[#667781] truncate max-w-[180px]", children: [
|
|
817
|
+
preview.icon && /* @__PURE__ */ jsx5("span", { className: "mr-1", children: preview.icon }),
|
|
564
818
|
preview.preview || "Sem mensagens"
|
|
565
819
|
] }),
|
|
566
|
-
conversation.unread > 0 && /* @__PURE__ */
|
|
820
|
+
conversation.unread > 0 && /* @__PURE__ */ jsx5("span", { className: "bg-[#25d366] text-white text-xs font-semibold rounded-full min-w-[20px] h-5 px-1.5 flex items-center justify-center flex-shrink-0 ml-2", children: conversation.unread > 99 ? "99+" : conversation.unread })
|
|
567
821
|
] }),
|
|
568
|
-
/* @__PURE__ */
|
|
569
|
-
conversation.mode === "human" && /* @__PURE__ */
|
|
570
|
-
conversation.mode === "bot" && conversation.waitingHuman && /* @__PURE__ */
|
|
822
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5 mt-1", children: [
|
|
823
|
+
conversation.mode === "human" && /* @__PURE__ */ jsx5("span", { className: "text-[10px] px-1.5 py-0.5 rounded font-medium bg-purple-100 text-purple-700", children: "Humano" }),
|
|
824
|
+
conversation.mode === "bot" && conversation.waitingHuman && /* @__PURE__ */ jsx5("span", { className: "text-[10px] px-1.5 py-0.5 rounded font-medium bg-amber-100 text-amber-700", children: "Aguardando" })
|
|
571
825
|
] })
|
|
572
826
|
] })
|
|
573
827
|
]
|
|
@@ -576,8 +830,8 @@ var ConversationListItem = ({
|
|
|
576
830
|
};
|
|
577
831
|
|
|
578
832
|
// src/Toast.tsx
|
|
579
|
-
import { createContext, useContext, useState as
|
|
580
|
-
import { jsx as
|
|
833
|
+
import { createContext, useContext, useState as useState3, useCallback as useCallback2, useEffect as useEffect3 } from "react";
|
|
834
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
581
835
|
var ToastContext = createContext(null);
|
|
582
836
|
var nextId = 0;
|
|
583
837
|
var singletonShow = null;
|
|
@@ -594,34 +848,34 @@ var typeStyles = {
|
|
|
594
848
|
info: "bg-blue-600"
|
|
595
849
|
};
|
|
596
850
|
var typeIcons = {
|
|
597
|
-
success: /* @__PURE__ */
|
|
598
|
-
error: /* @__PURE__ */
|
|
599
|
-
/* @__PURE__ */
|
|
600
|
-
/* @__PURE__ */
|
|
851
|
+
success: /* @__PURE__ */ jsx6("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx6("polyline", { points: "20 6 9 17 4 12" }) }),
|
|
852
|
+
error: /* @__PURE__ */ jsxs5("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
853
|
+
/* @__PURE__ */ jsx6("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
854
|
+
/* @__PURE__ */ jsx6("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
601
855
|
] }),
|
|
602
|
-
info: /* @__PURE__ */
|
|
603
|
-
/* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
856
|
+
info: /* @__PURE__ */ jsxs5("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
857
|
+
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "10" }),
|
|
858
|
+
/* @__PURE__ */ jsx6("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
859
|
+
/* @__PURE__ */ jsx6("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
606
860
|
] })
|
|
607
861
|
};
|
|
608
862
|
function ToastItemComponent({ item, onRemove }) {
|
|
609
|
-
const [exiting, setExiting] =
|
|
610
|
-
|
|
863
|
+
const [exiting, setExiting] = useState3(false);
|
|
864
|
+
useEffect3(() => {
|
|
611
865
|
const timer = setTimeout(() => {
|
|
612
866
|
setExiting(true);
|
|
613
867
|
setTimeout(() => onRemove(item.id), 300);
|
|
614
868
|
}, 5e3);
|
|
615
869
|
return () => clearTimeout(timer);
|
|
616
870
|
}, [item.id, onRemove]);
|
|
617
|
-
return /* @__PURE__ */
|
|
871
|
+
return /* @__PURE__ */ jsxs5(
|
|
618
872
|
"div",
|
|
619
873
|
{
|
|
620
874
|
className: `flex items-center gap-2 px-4 py-3 rounded-lg shadow-lg text-white text-sm min-w-[280px] max-w-[400px] ${typeStyles[item.type]} ${exiting ? "animate-slide-out" : "animate-slide-in"}`,
|
|
621
875
|
children: [
|
|
622
|
-
/* @__PURE__ */
|
|
623
|
-
/* @__PURE__ */
|
|
624
|
-
/* @__PURE__ */
|
|
876
|
+
/* @__PURE__ */ jsx6("span", { className: "flex-shrink-0", children: typeIcons[item.type] }),
|
|
877
|
+
/* @__PURE__ */ jsx6("span", { className: "flex-1", children: item.message }),
|
|
878
|
+
/* @__PURE__ */ jsx6(
|
|
625
879
|
"button",
|
|
626
880
|
{
|
|
627
881
|
onClick: () => {
|
|
@@ -629,9 +883,9 @@ function ToastItemComponent({ item, onRemove }) {
|
|
|
629
883
|
setTimeout(() => onRemove(item.id), 300);
|
|
630
884
|
},
|
|
631
885
|
className: "flex-shrink-0 opacity-70 hover:opacity-100 transition-opacity",
|
|
632
|
-
children: /* @__PURE__ */
|
|
633
|
-
/* @__PURE__ */
|
|
634
|
-
/* @__PURE__ */
|
|
886
|
+
children: /* @__PURE__ */ jsxs5("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
887
|
+
/* @__PURE__ */ jsx6("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
888
|
+
/* @__PURE__ */ jsx6("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
635
889
|
] })
|
|
636
890
|
}
|
|
637
891
|
)
|
|
@@ -640,24 +894,24 @@ function ToastItemComponent({ item, onRemove }) {
|
|
|
640
894
|
);
|
|
641
895
|
}
|
|
642
896
|
function ToastProvider({ children }) {
|
|
643
|
-
const [items, setItems] =
|
|
644
|
-
const show =
|
|
897
|
+
const [items, setItems] = useState3([]);
|
|
898
|
+
const show = useCallback2((type, message) => {
|
|
645
899
|
const id = ++nextId;
|
|
646
900
|
setItems((prev) => [...prev, { id, type, message }]);
|
|
647
901
|
}, []);
|
|
648
|
-
const remove =
|
|
902
|
+
const remove = useCallback2((id) => {
|
|
649
903
|
setItems((prev) => prev.filter((item) => item.id !== id));
|
|
650
904
|
}, []);
|
|
651
|
-
|
|
905
|
+
useEffect3(() => {
|
|
652
906
|
singletonShow = show;
|
|
653
907
|
return () => {
|
|
654
908
|
singletonShow = null;
|
|
655
909
|
};
|
|
656
910
|
}, [show]);
|
|
657
|
-
return /* @__PURE__ */
|
|
911
|
+
return /* @__PURE__ */ jsxs5(ToastContext.Provider, { value: { show }, children: [
|
|
658
912
|
children,
|
|
659
|
-
/* @__PURE__ */
|
|
660
|
-
/* @__PURE__ */
|
|
913
|
+
/* @__PURE__ */ jsx6("div", { className: "fixed top-4 right-4 z-[100] flex flex-col gap-2", children: items.map((item) => /* @__PURE__ */ jsx6(ToastItemComponent, { item, onRemove: remove }, item.id)) }),
|
|
914
|
+
/* @__PURE__ */ jsx6("style", { children: `
|
|
661
915
|
@keyframes slide-in {
|
|
662
916
|
from { transform: translateX(100%); opacity: 0; }
|
|
663
917
|
to { transform: translateX(0); opacity: 1; }
|
|
@@ -680,11 +934,11 @@ function useToast() {
|
|
|
680
934
|
}
|
|
681
935
|
|
|
682
936
|
// src/MessageText.tsx
|
|
683
|
-
import { useCallback as
|
|
684
|
-
import { jsx as
|
|
937
|
+
import { useCallback as useCallback3, useState as useState4 } from "react";
|
|
938
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
685
939
|
function MessageText({ message }) {
|
|
686
|
-
const [copied, setCopied] =
|
|
687
|
-
const handleCopy =
|
|
940
|
+
const [copied, setCopied] = useState4(false);
|
|
941
|
+
const handleCopy = useCallback3(async () => {
|
|
688
942
|
if (!message.content) return;
|
|
689
943
|
try {
|
|
690
944
|
await navigator.clipboard.writeText(message.content);
|
|
@@ -694,35 +948,35 @@ function MessageText({ message }) {
|
|
|
694
948
|
}
|
|
695
949
|
}, [message.content]);
|
|
696
950
|
if (message.type === "template")
|
|
697
|
-
return /* @__PURE__ */
|
|
698
|
-
return /* @__PURE__ */
|
|
951
|
+
return /* @__PURE__ */ jsx7("p", { className: "text-sm italic text-[#667781]", children: message.content ?? "Template message" });
|
|
952
|
+
return /* @__PURE__ */ jsxs6(
|
|
699
953
|
"div",
|
|
700
954
|
{
|
|
701
955
|
onClick: handleCopy,
|
|
702
956
|
className: "text-[14.2px] leading-[19px] whitespace-pre-wrap break-words select-all [&_strong]:font-bold [&_em]:italic [&_del]:line-through",
|
|
703
957
|
children: [
|
|
704
|
-
/* @__PURE__ */
|
|
705
|
-
copied && /* @__PURE__ */
|
|
958
|
+
/* @__PURE__ */ jsx7("span", { children: parseWhatsAppFormatting(message.content ?? "") }),
|
|
959
|
+
copied && /* @__PURE__ */ jsx7("span", { className: "absolute top-0 right-0 -translate-y-full bg-[#3b4a54] text-white text-[11px] px-1.5 py-0.5 rounded shadow-lg", children: "Copiado!" })
|
|
706
960
|
]
|
|
707
961
|
}
|
|
708
962
|
);
|
|
709
963
|
}
|
|
710
964
|
|
|
711
965
|
// src/MessageTimestamp.tsx
|
|
712
|
-
import { jsx as
|
|
966
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
713
967
|
function MessageTimestamp({ timestamp, status, isOutbound }) {
|
|
714
|
-
return /* @__PURE__ */
|
|
715
|
-
/* @__PURE__ */
|
|
716
|
-
isOutbound && status && /* @__PURE__ */
|
|
968
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-end gap-[3px]", children: [
|
|
969
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[11px] text-[#667781] leading-[15px] select-none", children: timestamp }),
|
|
970
|
+
isOutbound && status && /* @__PURE__ */ jsx8("span", { className: "flex items-center -mr-[2px]", children: /* @__PURE__ */ jsx8(StatusTicks, { status }) })
|
|
717
971
|
] });
|
|
718
972
|
}
|
|
719
973
|
|
|
720
974
|
// src/MessageTail.tsx
|
|
721
|
-
import { jsx as
|
|
975
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
722
976
|
function MessageTail({ isOutbound }) {
|
|
723
977
|
if (isOutbound)
|
|
724
|
-
return /* @__PURE__ */
|
|
725
|
-
return /* @__PURE__ */
|
|
978
|
+
return /* @__PURE__ */ jsx9("svg", { className: "absolute top-0 -right-[5px] w-[5px] h-[11px]", viewBox: "0 0 5 11", fill: "#d9fdd3", children: /* @__PURE__ */ jsx9("path", { d: "M5 0H0v11c1.5-2 4.5-2 5-4V0z" }) });
|
|
979
|
+
return /* @__PURE__ */ jsx9("svg", { className: "absolute top-0 -left-[5px] w-[5px] h-[11px]", viewBox: "0 0 5 11", fill: "white", children: /* @__PURE__ */ jsx9("path", { d: "M0 0h5v11C3.5 9 .5 9 0 7V0z" }) });
|
|
726
980
|
}
|
|
727
981
|
|
|
728
982
|
// src/conversationWindow.ts
|
|
@@ -767,7 +1021,7 @@ function formatStalledFor(lastAt, now) {
|
|
|
767
1021
|
}
|
|
768
1022
|
|
|
769
1023
|
// src/ChannelIcon.tsx
|
|
770
|
-
import { Fragment as
|
|
1024
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
771
1025
|
var CHANNEL_BRAND_COLOR = {
|
|
772
1026
|
[CONVERSATION_CHANNEL.WHATSAPP]: "#25D366",
|
|
773
1027
|
[CONVERSATION_CHANNEL.MESSENGER]: "#0084FF",
|
|
@@ -777,9 +1031,9 @@ var CHANNEL_BRAND_COLOR = {
|
|
|
777
1031
|
function Glyph({ channel }) {
|
|
778
1032
|
const color = CHANNEL_BRAND_COLOR[channel];
|
|
779
1033
|
if (channel === CONVERSATION_CHANNEL.WHATSAPP) {
|
|
780
|
-
return /* @__PURE__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
1034
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1035
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "11", fill: color }),
|
|
1036
|
+
/* @__PURE__ */ jsx10(
|
|
783
1037
|
"path",
|
|
784
1038
|
{
|
|
785
1039
|
d: "M8.6 7.2c.3-.1.7 0 .9.3l1 1.6c.2.3.1.7-.1.9l-.7.7c.6 1.3 1.6 2.3 2.9 2.9l.7-.7c.2-.2.6-.3.9-.1l1.6 1c.3.2.4.6.3.9-.4 1-1.4 1.6-2.4 1.4-3-.5-5.4-2.9-5.9-5.9-.2-1 .4-2 1.4-2.4Z",
|
|
@@ -789,28 +1043,28 @@ function Glyph({ channel }) {
|
|
|
789
1043
|
] });
|
|
790
1044
|
}
|
|
791
1045
|
if (channel === CONVERSATION_CHANNEL.MESSENGER) {
|
|
792
|
-
return /* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
794
|
-
/* @__PURE__ */
|
|
1046
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1047
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "11", fill: color }),
|
|
1048
|
+
/* @__PURE__ */ jsx10("path", { d: "M6.5 15.5 11 10.8l2.4 2.4L17.5 9l-4.6 4.9-2.4-2.4-4 4Z", fill: "#fff", stroke: "#fff", strokeWidth: "1.4", strokeLinejoin: "round" })
|
|
795
1049
|
] });
|
|
796
1050
|
}
|
|
797
1051
|
if (channel === CONVERSATION_CHANNEL.INSTAGRAM) {
|
|
798
|
-
return /* @__PURE__ */
|
|
799
|
-
/* @__PURE__ */
|
|
800
|
-
/* @__PURE__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
/* @__PURE__ */
|
|
1052
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1053
|
+
/* @__PURE__ */ jsx10("rect", { x: "2", y: "2", width: "20", height: "20", rx: "6", fill: color }),
|
|
1054
|
+
/* @__PURE__ */ jsx10("rect", { x: "6.5", y: "6.5", width: "11", height: "11", rx: "3.5", fill: "none", stroke: "#fff", strokeWidth: "1.6" }),
|
|
1055
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "2.6", fill: "none", stroke: "#fff", strokeWidth: "1.6" }),
|
|
1056
|
+
/* @__PURE__ */ jsx10("circle", { cx: "16.4", cy: "7.6", r: "1", fill: "#fff" })
|
|
803
1057
|
] });
|
|
804
1058
|
}
|
|
805
|
-
return /* @__PURE__ */
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
/* @__PURE__ */
|
|
1059
|
+
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1060
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "11", fill: color }),
|
|
1061
|
+
/* @__PURE__ */ jsx10("path", { d: "M6.5 8.5h11v7h-5.5L8.5 18v-2.5h-2v-7Z", fill: "#fff" })
|
|
808
1062
|
] });
|
|
809
1063
|
}
|
|
810
1064
|
function ChannelIcon({ channel, size = 14, className = "" }) {
|
|
811
1065
|
const resolved = channel ?? CONVERSATION_CHANNEL.WHATSAPP;
|
|
812
1066
|
const { label } = capabilitiesOf(resolved);
|
|
813
|
-
return /* @__PURE__ */
|
|
1067
|
+
return /* @__PURE__ */ jsx10(
|
|
814
1068
|
"svg",
|
|
815
1069
|
{
|
|
816
1070
|
viewBox: "0 0 24 24",
|
|
@@ -819,13 +1073,13 @@ function ChannelIcon({ channel, size = 14, className = "" }) {
|
|
|
819
1073
|
className: `inline-block shrink-0 ${className}`.trim(),
|
|
820
1074
|
role: "img",
|
|
821
1075
|
"aria-label": label,
|
|
822
|
-
children: /* @__PURE__ */
|
|
1076
|
+
children: /* @__PURE__ */ jsx10(Glyph, { channel: resolved })
|
|
823
1077
|
}
|
|
824
1078
|
);
|
|
825
1079
|
}
|
|
826
1080
|
|
|
827
1081
|
// src/ConversationRow.tsx
|
|
828
|
-
import { jsx as
|
|
1082
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
829
1083
|
var WINDOW_TITLE = {
|
|
830
1084
|
[CONVERSATION_WINDOW.ALL]: "",
|
|
831
1085
|
[CONVERSATION_WINDOW.FRESH]: "Janela de 24h aberta (menos de 12h)",
|
|
@@ -858,8 +1112,8 @@ function ConversationRow({
|
|
|
858
1112
|
const stalledMs = now - new Date(conversation.lastAt).getTime();
|
|
859
1113
|
const isStalled = stalledMs > STALLED_THRESHOLD_MS;
|
|
860
1114
|
const isWaiting = conversation.mode === "bot" && conversation.waitingHuman;
|
|
861
|
-
return /* @__PURE__ */
|
|
862
|
-
/* @__PURE__ */
|
|
1115
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("cv-row flex border-b", active && "cv-row--active", classNames?.root, className), children: [
|
|
1116
|
+
/* @__PURE__ */ jsx11(
|
|
863
1117
|
"span",
|
|
864
1118
|
{
|
|
865
1119
|
className: cn("w-1 shrink-0", WINDOW_BAR_CLASS[window2], classNames?.windowBar),
|
|
@@ -867,9 +1121,9 @@ function ConversationRow({
|
|
|
867
1121
|
"aria-label": WINDOW_TITLE[window2]
|
|
868
1122
|
}
|
|
869
1123
|
),
|
|
870
|
-
/* @__PURE__ */
|
|
871
|
-
/* @__PURE__ */
|
|
872
|
-
/* @__PURE__ */
|
|
1124
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
|
|
1125
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-2 px-2 pt-2", children: [
|
|
1126
|
+
/* @__PURE__ */ jsx11(
|
|
873
1127
|
"input",
|
|
874
1128
|
{
|
|
875
1129
|
type: "checkbox",
|
|
@@ -879,7 +1133,7 @@ function ConversationRow({
|
|
|
879
1133
|
className: "mt-3"
|
|
880
1134
|
}
|
|
881
1135
|
),
|
|
882
|
-
/* @__PURE__ */
|
|
1136
|
+
/* @__PURE__ */ jsx11("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx11(
|
|
883
1137
|
ConversationListItem,
|
|
884
1138
|
{
|
|
885
1139
|
conversation,
|
|
@@ -890,28 +1144,28 @@ function ConversationRow({
|
|
|
890
1144
|
}
|
|
891
1145
|
) })
|
|
892
1146
|
] }),
|
|
893
|
-
/* @__PURE__ */
|
|
894
|
-
/* @__PURE__ */
|
|
895
|
-
/* @__PURE__ */
|
|
1147
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1.5 px-4 pb-2 pl-8", children: [
|
|
1148
|
+
/* @__PURE__ */ jsxs9("span", { className: "cv-pill", children: [
|
|
1149
|
+
/* @__PURE__ */ jsx11(ChannelIcon, { channel: conversation.channel }),
|
|
896
1150
|
" ",
|
|
897
1151
|
capabilities.label
|
|
898
1152
|
] }),
|
|
899
|
-
conversation.mode === "human" ? /* @__PURE__ */
|
|
900
|
-
isWaiting ? /* @__PURE__ */
|
|
901
|
-
!isWaiting && conversation.mode === "bot" ? /* @__PURE__ */
|
|
902
|
-
isStalled ? /* @__PURE__ */
|
|
1153
|
+
conversation.mode === "human" ? /* @__PURE__ */ jsx11("span", { className: "cv-pill cv-pill--success", children: "\u{1F9D1}\u200D\u{1F4BC} em atendimento" }) : null,
|
|
1154
|
+
isWaiting ? /* @__PURE__ */ jsx11("span", { className: "cv-pill cv-pill--warning", children: "\u23F3 aguardando atendimento" }) : null,
|
|
1155
|
+
!isWaiting && conversation.mode === "bot" ? /* @__PURE__ */ jsx11("span", { className: "cv-pill", children: "\u{1F916} bot ativo" }) : null,
|
|
1156
|
+
isStalled ? /* @__PURE__ */ jsxs9("span", { className: "cv-pill cv-pill--danger", children: [
|
|
903
1157
|
"\u23F1\uFE0F parada h\xE1 ",
|
|
904
1158
|
formatStalledFor(conversation.lastAt, now)
|
|
905
1159
|
] }) : null,
|
|
906
|
-
isWaiting ? /* @__PURE__ */
|
|
1160
|
+
isWaiting ? /* @__PURE__ */ jsx11("button", { type: "button", onClick: onTakeover, disabled: busy, className: "cv-header-action", children: "\u25B6\uFE0F Continuar Atendimento" }) : null
|
|
907
1161
|
] })
|
|
908
1162
|
] })
|
|
909
1163
|
] });
|
|
910
1164
|
}
|
|
911
1165
|
|
|
912
1166
|
// src/ConversationHeader.tsx
|
|
913
|
-
import { useState as
|
|
914
|
-
import { jsx as
|
|
1167
|
+
import { useState as useState5 } from "react";
|
|
1168
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
915
1169
|
var DEFAULT_CONVERSATION_HEADER_LABELS = {
|
|
916
1170
|
botMode: "\u{1F916} atendimento autom\xE1tico",
|
|
917
1171
|
humanMode: "\u{1F9D1}\u200D\u{1F4BC} atendimento humano",
|
|
@@ -944,7 +1198,7 @@ function ConversationHeader({
|
|
|
944
1198
|
const displayHandle = formatContactHandle({ handle, channel: conversation.channel });
|
|
945
1199
|
const flag = contactFlag({ handle, channel: conversation.channel });
|
|
946
1200
|
const capabilities = capabilitiesOf(conversation.channel);
|
|
947
|
-
const [menuOpen, setMenuOpen] =
|
|
1201
|
+
const [menuOpen, setMenuOpen] = useState5(false);
|
|
948
1202
|
const utilities = [
|
|
949
1203
|
onOpenDocuments ? { key: "documents", icon: "\u{1F4C4}", label: labels.documents, run: onOpenDocuments, active: documentsOpen } : void 0,
|
|
950
1204
|
onDownload ? { key: "download", icon: "\u2B07\uFE0F", label: labels.download, run: onDownload, active: false } : void 0,
|
|
@@ -966,7 +1220,7 @@ function ConversationHeader({
|
|
|
966
1220
|
})),
|
|
967
1221
|
...actions
|
|
968
1222
|
];
|
|
969
|
-
return /* @__PURE__ */
|
|
1223
|
+
return /* @__PURE__ */ jsxs10(
|
|
970
1224
|
"header",
|
|
971
1225
|
{
|
|
972
1226
|
className: cn(
|
|
@@ -975,26 +1229,26 @@ function ConversationHeader({
|
|
|
975
1229
|
className
|
|
976
1230
|
),
|
|
977
1231
|
children: [
|
|
978
|
-
/* @__PURE__ */
|
|
979
|
-
onBack ? /* @__PURE__ */
|
|
980
|
-
/* @__PURE__ */
|
|
981
|
-
/* @__PURE__ */
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
1232
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("flex min-w-0 flex-1 items-center gap-3", classNames?.identity), children: [
|
|
1233
|
+
onBack ? /* @__PURE__ */ jsx12("button", { type: "button", onClick: onBack, className: "cv-back cv-touch", "aria-label": labels.back, title: labels.back, children: "\u2190" }) : null,
|
|
1234
|
+
/* @__PURE__ */ jsx12(Avatar, { name: conversation.clientName, size: "md" }),
|
|
1235
|
+
/* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
|
|
1236
|
+
/* @__PURE__ */ jsx12("p", { className: cn("truncate font-medium", classNames?.name), children: conversation.clientName ?? displayHandle }),
|
|
1237
|
+
/* @__PURE__ */ jsxs10("p", { className: cn("truncate text-xs text-gray-500", classNames?.meta), children: [
|
|
984
1238
|
flag ? `${flag} ` : "",
|
|
985
1239
|
displayHandle,
|
|
986
|
-
/* @__PURE__ */
|
|
987
|
-
/* @__PURE__ */
|
|
988
|
-
/* @__PURE__ */
|
|
1240
|
+
/* @__PURE__ */ jsxs10("span", { className: "ml-2 inline-flex items-center gap-1", children: [
|
|
1241
|
+
/* @__PURE__ */ jsx12(ChannelIcon, { channel: conversation.channel }),
|
|
1242
|
+
/* @__PURE__ */ jsx12("span", { className: "cv-only-wide", children: capabilities.label })
|
|
989
1243
|
] }),
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
/* @__PURE__ */
|
|
1244
|
+
/* @__PURE__ */ jsx12("span", { className: "ml-2 cv-only-wide", children: isHuman ? labels.humanMode : labels.botMode }),
|
|
1245
|
+
/* @__PURE__ */ jsx12("span", { className: "ml-1 cv-only-narrow", title: isHuman ? labels.humanMode : labels.botMode, children: isHuman ? "\u{1F9D1}\u200D\u{1F4BC}" : "\u{1F916}" })
|
|
992
1246
|
] })
|
|
993
1247
|
] })
|
|
994
1248
|
] }),
|
|
995
|
-
/* @__PURE__ */
|
|
996
|
-
/* @__PURE__ */
|
|
997
|
-
utilities.map((utility) => /* @__PURE__ */
|
|
1249
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("flex shrink-0 items-center gap-2", classNames?.actions), children: [
|
|
1250
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("hidden items-center gap-2 lg:flex", classNames?.desktopActions), children: [
|
|
1251
|
+
utilities.map((utility) => /* @__PURE__ */ jsx12(
|
|
998
1252
|
"button",
|
|
999
1253
|
{
|
|
1000
1254
|
type: "button",
|
|
@@ -1008,7 +1262,7 @@ function ConversationHeader({
|
|
|
1008
1262
|
},
|
|
1009
1263
|
utility.key
|
|
1010
1264
|
)),
|
|
1011
|
-
actions.map((action) => /* @__PURE__ */
|
|
1265
|
+
actions.map((action) => /* @__PURE__ */ jsx12(
|
|
1012
1266
|
"button",
|
|
1013
1267
|
{
|
|
1014
1268
|
type: "button",
|
|
@@ -1020,8 +1274,8 @@ function ConversationHeader({
|
|
|
1020
1274
|
action.key
|
|
1021
1275
|
))
|
|
1022
1276
|
] }),
|
|
1023
|
-
menuItems.length > 0 ? /* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1277
|
+
menuItems.length > 0 ? /* @__PURE__ */ jsxs10("div", { className: cn("cv-menu lg:hidden", classNames?.mobileMenu), children: [
|
|
1278
|
+
/* @__PURE__ */ jsx12(
|
|
1025
1279
|
"button",
|
|
1026
1280
|
{
|
|
1027
1281
|
type: "button",
|
|
@@ -1033,7 +1287,7 @@ function ConversationHeader({
|
|
|
1033
1287
|
children: "\u22EE"
|
|
1034
1288
|
}
|
|
1035
1289
|
),
|
|
1036
|
-
menuOpen ? /* @__PURE__ */
|
|
1290
|
+
menuOpen ? /* @__PURE__ */ jsx12("div", { className: "cv-menu-panel", role: "menu", children: menuItems.map((item) => /* @__PURE__ */ jsx12(
|
|
1037
1291
|
"button",
|
|
1038
1292
|
{
|
|
1039
1293
|
type: "button",
|
|
@@ -1056,16 +1310,16 @@ function ConversationHeader({
|
|
|
1056
1310
|
}
|
|
1057
1311
|
|
|
1058
1312
|
// src/ConversationContextPanel.tsx
|
|
1059
|
-
import { useState as
|
|
1313
|
+
import { useState as useState7 } from "react";
|
|
1060
1314
|
|
|
1061
1315
|
// src/useIsNarrow.ts
|
|
1062
|
-
import { useEffect as
|
|
1316
|
+
import { useEffect as useEffect4, useState as useState6 } from "react";
|
|
1063
1317
|
var NARROW_MAX_WIDTH_PX = 1023;
|
|
1064
1318
|
function useIsNarrow() {
|
|
1065
|
-
const [isNarrow, setIsNarrow] =
|
|
1319
|
+
const [isNarrow, setIsNarrow] = useState6(
|
|
1066
1320
|
() => typeof window !== "undefined" && window.matchMedia(`(max-width: ${NARROW_MAX_WIDTH_PX}px)`).matches
|
|
1067
1321
|
);
|
|
1068
|
-
|
|
1322
|
+
useEffect4(() => {
|
|
1069
1323
|
const query = window.matchMedia(`(max-width: ${NARROW_MAX_WIDTH_PX}px)`);
|
|
1070
1324
|
const handleChange = (event) => setIsNarrow(event.matches);
|
|
1071
1325
|
query.addEventListener("change", handleChange);
|
|
@@ -1076,7 +1330,7 @@ function useIsNarrow() {
|
|
|
1076
1330
|
}
|
|
1077
1331
|
|
|
1078
1332
|
// src/ConversationContextPanel.tsx
|
|
1079
|
-
import { jsx as
|
|
1333
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1080
1334
|
var DEFAULT_CONVERSATION_CONTEXT_LABELS = {
|
|
1081
1335
|
title: "\u{1F4CB} Suas Sele\xE7\xF5es",
|
|
1082
1336
|
empty: "Nada coletado ainda nesta conversa."
|
|
@@ -1090,10 +1344,10 @@ function ConversationContextPanel({
|
|
|
1090
1344
|
const labels = { ...DEFAULT_CONVERSATION_CONTEXT_LABELS, ...labelsOverride };
|
|
1091
1345
|
const filled = entries.filter((entry) => Boolean(entry.value));
|
|
1092
1346
|
const isNarrow = useIsNarrow();
|
|
1093
|
-
const [manualOpen, setManualOpen] =
|
|
1347
|
+
const [manualOpen, setManualOpen] = useState7(void 0);
|
|
1094
1348
|
const open = manualOpen ?? (!isNarrow && filled.length > 0);
|
|
1095
|
-
return /* @__PURE__ */
|
|
1096
|
-
/* @__PURE__ */
|
|
1349
|
+
return /* @__PURE__ */ jsxs11("section", { className: cn("border-b", classNames?.root, className), children: [
|
|
1350
|
+
/* @__PURE__ */ jsxs11(
|
|
1097
1351
|
"button",
|
|
1098
1352
|
{
|
|
1099
1353
|
type: "button",
|
|
@@ -1101,9 +1355,9 @@ function ConversationContextPanel({
|
|
|
1101
1355
|
"aria-expanded": open,
|
|
1102
1356
|
className: cn("flex w-full items-center gap-2 px-4 py-3 text-left text-sm font-medium", classNames?.toggle),
|
|
1103
1357
|
children: [
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1358
|
+
/* @__PURE__ */ jsx13("span", { "aria-hidden": true, className: "text-xs", children: open ? "\u25BE" : "\u25B8" }),
|
|
1359
|
+
/* @__PURE__ */ jsx13("span", { children: labels.title }),
|
|
1360
|
+
/* @__PURE__ */ jsxs11("span", { className: cn("rounded-full bg-gray-200 px-2 text-xs dark:bg-gray-700", classNames?.counter), children: [
|
|
1107
1361
|
filled.length,
|
|
1108
1362
|
"/",
|
|
1109
1363
|
entries.length
|
|
@@ -1111,12 +1365,12 @@ function ConversationContextPanel({
|
|
|
1111
1365
|
]
|
|
1112
1366
|
}
|
|
1113
1367
|
),
|
|
1114
|
-
open ? /* @__PURE__ */
|
|
1115
|
-
/* @__PURE__ */
|
|
1368
|
+
open ? /* @__PURE__ */ jsx13("div", { className: cn("px-4 pb-3", classNames?.body), children: entries.length === 0 ? /* @__PURE__ */ jsx13("p", { className: "text-xs text-gray-500", children: labels.empty }) : /* @__PURE__ */ jsx13("dl", { className: "grid grid-cols-2 gap-2 text-xs", children: entries.map((entry) => /* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
|
|
1369
|
+
/* @__PURE__ */ jsxs11("dt", { className: "truncate text-gray-500", children: [
|
|
1116
1370
|
entry.icon ? `${entry.icon} ` : "",
|
|
1117
1371
|
entry.label
|
|
1118
1372
|
] }),
|
|
1119
|
-
/* @__PURE__ */
|
|
1373
|
+
/* @__PURE__ */ jsx13("dd", { className: "truncate font-medium", children: entry.value ? /* @__PURE__ */ jsxs11("span", { className: "text-green-700 dark:text-green-400", children: [
|
|
1120
1374
|
"\u2713 ",
|
|
1121
1375
|
entry.value
|
|
1122
1376
|
] }) : "\u2014" })
|
|
@@ -1125,7 +1379,7 @@ function ConversationContextPanel({
|
|
|
1125
1379
|
}
|
|
1126
1380
|
|
|
1127
1381
|
// src/WindowExpiredNotice.tsx
|
|
1128
|
-
import { jsx as
|
|
1382
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1129
1383
|
var DEFAULT_WINDOW_EXPIRED_LABELS = {
|
|
1130
1384
|
title: "\u23F0 Janela de 24h expirada \u2014 o WhatsApp n\xE3o aceita mensagens livres.",
|
|
1131
1385
|
description: "Envie uma mensagem de template para reabrir a conversa com o cliente.",
|
|
@@ -1138,10 +1392,10 @@ function WindowExpiredNotice({
|
|
|
1138
1392
|
className
|
|
1139
1393
|
}) {
|
|
1140
1394
|
const labels = { ...DEFAULT_WINDOW_EXPIRED_LABELS, ...labelsOverride };
|
|
1141
|
-
return /* @__PURE__ */
|
|
1142
|
-
/* @__PURE__ */
|
|
1143
|
-
/* @__PURE__ */
|
|
1144
|
-
onSendTemplate ? /* @__PURE__ */
|
|
1395
|
+
return /* @__PURE__ */ jsxs12("div", { role: "status", className: cn("border-t bg-yellow-50 px-4 py-3 text-sm dark:bg-yellow-950", className), children: [
|
|
1396
|
+
/* @__PURE__ */ jsx14("p", { className: "font-medium text-yellow-900 dark:text-yellow-200", children: labels.title }),
|
|
1397
|
+
/* @__PURE__ */ jsx14("p", { className: "text-yellow-800 dark:text-yellow-300", children: labels.description }),
|
|
1398
|
+
onSendTemplate ? /* @__PURE__ */ jsx14("button", { type: "button", onClick: onSendTemplate, disabled, className: "cv-header-action mt-2", children: labels.sendTemplate }) : null
|
|
1145
1399
|
] });
|
|
1146
1400
|
}
|
|
1147
1401
|
function isWindowBlocking(window2) {
|
|
@@ -1184,7 +1438,7 @@ function downloadTextFile(filename, content) {
|
|
|
1184
1438
|
}
|
|
1185
1439
|
|
|
1186
1440
|
// src/useWaitingNotifications.ts
|
|
1187
|
-
import { useState as
|
|
1441
|
+
import { useState as useState8, useEffect as useEffect5, useRef as useRef4, useCallback as useCallback4 } from "react";
|
|
1188
1442
|
var DEFAULT_POLL_INTERVAL_MS = 1e4;
|
|
1189
1443
|
var DEFAULT_LIMIT = 50;
|
|
1190
1444
|
var DEFAULT_LABELS = {
|
|
@@ -1193,17 +1447,17 @@ var DEFAULT_LABELS = {
|
|
|
1193
1447
|
};
|
|
1194
1448
|
function useWaitingNotifications(params) {
|
|
1195
1449
|
const conversationsContext = useConversations();
|
|
1196
|
-
const [conversations, setConversations] =
|
|
1197
|
-
const previousUnreadMap =
|
|
1198
|
-
const notifiedIds =
|
|
1199
|
-
const isPollingRef =
|
|
1450
|
+
const [conversations, setConversations] = useState8([]);
|
|
1451
|
+
const previousUnreadMap = useRef4(/* @__PURE__ */ new Map());
|
|
1452
|
+
const notifiedIds = useRef4(/* @__PURE__ */ new Set());
|
|
1453
|
+
const isPollingRef = useRef4(false);
|
|
1200
1454
|
const isEnabled = params?.enabled ?? true;
|
|
1201
1455
|
const intervalMs = params?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
1202
1456
|
const icon = params?.icon;
|
|
1203
1457
|
const listParams = params?.params;
|
|
1204
1458
|
const labelTitle = params?.labels?.title ?? DEFAULT_LABELS.title;
|
|
1205
1459
|
const labelBody = params?.labels?.body ?? DEFAULT_LABELS.body;
|
|
1206
|
-
const refresh =
|
|
1460
|
+
const refresh = useCallback4(async () => {
|
|
1207
1461
|
if (!conversationsContext || isPollingRef.current) return;
|
|
1208
1462
|
isPollingRef.current = true;
|
|
1209
1463
|
try {
|
|
@@ -1228,7 +1482,7 @@ function useWaitingNotifications(params) {
|
|
|
1228
1482
|
isPollingRef.current = false;
|
|
1229
1483
|
}
|
|
1230
1484
|
}, [conversationsContext, listParams, icon, labelTitle, labelBody]);
|
|
1231
|
-
|
|
1485
|
+
useEffect5(() => {
|
|
1232
1486
|
if (!isEnabled) return;
|
|
1233
1487
|
if (typeof window !== "undefined" && "Notification" in window && Notification.permission === "default") {
|
|
1234
1488
|
Notification.requestPermission();
|
|
@@ -1243,7 +1497,7 @@ function useWaitingNotifications(params) {
|
|
|
1243
1497
|
|
|
1244
1498
|
// src/settings/WhatsAppTemplateSettingsForm.tsx
|
|
1245
1499
|
import { Plus, RefreshCw, Save, Trash2 } from "lucide-react";
|
|
1246
|
-
import { jsx as
|
|
1500
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1247
1501
|
var DEFAULT_LABELS2 = {
|
|
1248
1502
|
sectionTitle: "WhatsApp",
|
|
1249
1503
|
sectionDescription: "Template usado para reabrir a janela de 24h com o cliente.",
|
|
@@ -1302,16 +1556,16 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1302
1556
|
}
|
|
1303
1557
|
onVariablesChange([...variables, token]);
|
|
1304
1558
|
}
|
|
1305
|
-
return /* @__PURE__ */
|
|
1306
|
-
/* @__PURE__ */
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1559
|
+
return /* @__PURE__ */ jsxs13("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
1560
|
+
/* @__PURE__ */ jsxs13("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: [
|
|
1561
|
+
/* @__PURE__ */ jsx15("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.sectionTitle }),
|
|
1562
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.sectionDescription })
|
|
1309
1563
|
] }),
|
|
1310
|
-
/* @__PURE__ */
|
|
1311
|
-
/* @__PURE__ */
|
|
1312
|
-
/* @__PURE__ */
|
|
1313
|
-
/* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1564
|
+
/* @__PURE__ */ jsxs13("form", { onSubmit: onSave, className: "p-6 space-y-4", children: [
|
|
1565
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
1566
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
1567
|
+
/* @__PURE__ */ jsx15("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.templateLabel }),
|
|
1568
|
+
/* @__PURE__ */ jsxs13(
|
|
1315
1569
|
"button",
|
|
1316
1570
|
{
|
|
1317
1571
|
type: "button",
|
|
@@ -1319,31 +1573,31 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1319
1573
|
disabled: loadingTemplates,
|
|
1320
1574
|
className: "flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:underline disabled:opacity-50",
|
|
1321
1575
|
children: [
|
|
1322
|
-
/* @__PURE__ */
|
|
1576
|
+
/* @__PURE__ */ jsx15(RefreshCw, { size: 11, className: loadingTemplates ? "animate-spin" : "" }),
|
|
1323
1577
|
labels.refreshList
|
|
1324
1578
|
]
|
|
1325
1579
|
}
|
|
1326
1580
|
)
|
|
1327
1581
|
] }),
|
|
1328
|
-
templatesError && /* @__PURE__ */
|
|
1582
|
+
templatesError && /* @__PURE__ */ jsxs13("div", { className: "mb-2 rounded-lg bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800 px-3 py-2 text-xs text-amber-700 dark:text-amber-400", children: [
|
|
1329
1583
|
labels.errorLoading,
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
/* @__PURE__ */
|
|
1584
|
+
/* @__PURE__ */ jsx15("br", {}),
|
|
1585
|
+
/* @__PURE__ */ jsxs13("span", { className: "text-gray-500 dark:text-gray-400 mt-0.5 block", children: [
|
|
1332
1586
|
labels.currentNameSaved,
|
|
1333
1587
|
" ",
|
|
1334
|
-
/* @__PURE__ */
|
|
1588
|
+
/* @__PURE__ */ jsx15("strong", { children: selectedTemplateName || "\u2014" })
|
|
1335
1589
|
] })
|
|
1336
1590
|
] }),
|
|
1337
|
-
loadingTemplates && /* @__PURE__ */
|
|
1338
|
-
!loadingTemplates && !templatesError && /* @__PURE__ */
|
|
1591
|
+
loadingTemplates && /* @__PURE__ */ jsx15("div", { className: "h-10 rounded-xl bg-gray-100 dark:bg-gray-700 animate-pulse" }),
|
|
1592
|
+
!loadingTemplates && !templatesError && /* @__PURE__ */ jsxs13(
|
|
1339
1593
|
"select",
|
|
1340
1594
|
{
|
|
1341
1595
|
value: selectedTemplateName,
|
|
1342
1596
|
onChange: (e) => handleSelect(e.target.value),
|
|
1343
1597
|
className: "w-full border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition-all",
|
|
1344
1598
|
children: [
|
|
1345
|
-
/* @__PURE__ */
|
|
1346
|
-
templates.map((template) => /* @__PURE__ */
|
|
1599
|
+
/* @__PURE__ */ jsx15("option", { value: "", children: labels.selectPlaceholder }),
|
|
1600
|
+
templates.map((template) => /* @__PURE__ */ jsxs13("option", { value: template.name, disabled: template.status !== "APPROVED", children: [
|
|
1347
1601
|
template.displayName,
|
|
1348
1602
|
" \xB7 ",
|
|
1349
1603
|
template.shortId,
|
|
@@ -1355,27 +1609,27 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1355
1609
|
]
|
|
1356
1610
|
}
|
|
1357
1611
|
),
|
|
1358
|
-
selected?.bodyText && /* @__PURE__ */
|
|
1612
|
+
selected?.bodyText && /* @__PURE__ */ jsx15("div", { className: "mt-2 rounded-lg bg-gray-50 dark:bg-gray-700/50 border border-gray-200 dark:border-gray-600 px-3 py-2 text-xs text-gray-600 dark:text-gray-300 whitespace-pre-wrap", children: selected.bodyText })
|
|
1359
1613
|
] }),
|
|
1360
|
-
/* @__PURE__ */
|
|
1361
|
-
/* @__PURE__ */
|
|
1362
|
-
/* @__PURE__ */
|
|
1363
|
-
/* @__PURE__ */
|
|
1614
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
1615
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
1616
|
+
/* @__PURE__ */ jsx15("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.variablesLabel }),
|
|
1617
|
+
/* @__PURE__ */ jsxs13(
|
|
1364
1618
|
"button",
|
|
1365
1619
|
{
|
|
1366
1620
|
type: "button",
|
|
1367
1621
|
onClick: () => onVariablesChange([...variables, ""]),
|
|
1368
1622
|
className: "flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:underline",
|
|
1369
1623
|
children: [
|
|
1370
|
-
/* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ jsx15(Plus, { size: 12 }),
|
|
1371
1625
|
labels.addVariable
|
|
1372
1626
|
]
|
|
1373
1627
|
}
|
|
1374
1628
|
)
|
|
1375
1629
|
] }),
|
|
1376
|
-
availableVariables.length > 0 && /* @__PURE__ */
|
|
1377
|
-
/* @__PURE__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1630
|
+
availableVariables.length > 0 && /* @__PURE__ */ jsxs13("div", { className: "mb-3 rounded-lg border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700/40 p-2.5", children: [
|
|
1631
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs font-medium text-gray-600 dark:text-gray-300 mb-1.5", children: labels.variablesAvailableTitle }),
|
|
1632
|
+
/* @__PURE__ */ jsx15("div", { className: "flex flex-wrap gap-1.5", children: availableVariables.map((available) => /* @__PURE__ */ jsxs13(
|
|
1379
1633
|
"button",
|
|
1380
1634
|
{
|
|
1381
1635
|
type: "button",
|
|
@@ -1383,8 +1637,8 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1383
1637
|
title: `Inserir ${available.token}`,
|
|
1384
1638
|
className: "inline-flex items-center gap-1 rounded-md border border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-800 px-2 py-1 text-xs hover:border-blue-400 dark:hover:border-blue-500 transition-colors",
|
|
1385
1639
|
children: [
|
|
1386
|
-
/* @__PURE__ */
|
|
1387
|
-
/* @__PURE__ */
|
|
1640
|
+
/* @__PURE__ */ jsx15("code", { className: "text-blue-600 dark:text-blue-300", children: available.token }),
|
|
1641
|
+
/* @__PURE__ */ jsxs13("span", { className: "text-gray-400 dark:text-gray-500", children: [
|
|
1388
1642
|
"\xB7 ",
|
|
1389
1643
|
available.label
|
|
1390
1644
|
] })
|
|
@@ -1392,13 +1646,13 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1392
1646
|
},
|
|
1393
1647
|
available.token
|
|
1394
1648
|
)) }),
|
|
1395
|
-
/* @__PURE__ */
|
|
1649
|
+
/* @__PURE__ */ jsx15("p", { className: "mt-1.5 text-[11px] text-gray-400 dark:text-gray-500", children: labels.variablesAvailableHint })
|
|
1396
1650
|
] }),
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
variables.length === 0 && /* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1651
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-gray-400 dark:text-gray-500 mb-2", children: labels.variablesMappingHint }),
|
|
1652
|
+
variables.length === 0 && /* @__PURE__ */ jsx15("p", { className: "text-xs text-gray-400 dark:text-gray-500 italic", children: labels.noVariables }),
|
|
1653
|
+
/* @__PURE__ */ jsx15("div", { className: "space-y-2", children: variables.map((variable, index) => /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
1654
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs text-gray-400 dark:text-gray-500 w-6 text-right flex-shrink-0", children: `{{${index + 1}}}` }),
|
|
1655
|
+
/* @__PURE__ */ jsx15(
|
|
1402
1656
|
"input",
|
|
1403
1657
|
{
|
|
1404
1658
|
type: "text",
|
|
@@ -1408,27 +1662,27 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1408
1662
|
className: "flex-1 border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition-all placeholder:text-gray-400 dark:placeholder:text-gray-500"
|
|
1409
1663
|
}
|
|
1410
1664
|
),
|
|
1411
|
-
/* @__PURE__ */
|
|
1665
|
+
/* @__PURE__ */ jsx15(
|
|
1412
1666
|
"button",
|
|
1413
1667
|
{
|
|
1414
1668
|
type: "button",
|
|
1415
1669
|
onClick: () => removeVariable(index),
|
|
1416
1670
|
className: "text-gray-400 hover:text-red-500 dark:hover:text-red-400 transition-colors flex-shrink-0",
|
|
1417
1671
|
title: labels.removeVariable,
|
|
1418
|
-
children: /* @__PURE__ */
|
|
1672
|
+
children: /* @__PURE__ */ jsx15(Trash2, { size: 14 })
|
|
1419
1673
|
}
|
|
1420
1674
|
)
|
|
1421
1675
|
] }, index)) })
|
|
1422
1676
|
] }),
|
|
1423
|
-
saveSuccess && /* @__PURE__ */
|
|
1424
|
-
/* @__PURE__ */
|
|
1677
|
+
saveSuccess && /* @__PURE__ */ jsx15("div", { className: "bg-green-50 dark:bg-green-950/40 border border-green-200 dark:border-green-800 rounded-xl px-4 py-3 text-sm text-green-700 dark:text-green-400", children: labels.saveSuccess }),
|
|
1678
|
+
/* @__PURE__ */ jsx15("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs13(
|
|
1425
1679
|
"button",
|
|
1426
1680
|
{
|
|
1427
1681
|
type: "submit",
|
|
1428
1682
|
disabled: saving || !selectedTemplateName.trim(),
|
|
1429
1683
|
className: "flex items-center gap-2 bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white font-semibold px-5 py-2.5 rounded-xl transition-colors text-sm",
|
|
1430
1684
|
children: [
|
|
1431
|
-
saving ? /* @__PURE__ */
|
|
1685
|
+
saving ? /* @__PURE__ */ jsx15("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx15(Save, { size: 14 }),
|
|
1432
1686
|
saving ? labels.saving : labels.save
|
|
1433
1687
|
]
|
|
1434
1688
|
}
|
|
@@ -1438,8 +1692,8 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1438
1692
|
}
|
|
1439
1693
|
|
|
1440
1694
|
// src/settings/WhatsAppCreateTemplateForm.tsx
|
|
1441
|
-
import { SendHorizonal } from "lucide-react";
|
|
1442
|
-
import { jsx as
|
|
1695
|
+
import { SendHorizonal as SendHorizonal2 } from "lucide-react";
|
|
1696
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1443
1697
|
var DEFAULT_LABELS3 = {
|
|
1444
1698
|
sectionTitle: "Criar novo template",
|
|
1445
1699
|
sectionDescription: "Envia um template para aprova\xE7\xE3o da Meta.",
|
|
@@ -1496,16 +1750,16 @@ function WhatsAppCreateTemplateForm({
|
|
|
1496
1750
|
function set(key, next) {
|
|
1497
1751
|
onChange({ ...value, [key]: next });
|
|
1498
1752
|
}
|
|
1499
|
-
return /* @__PURE__ */
|
|
1500
|
-
/* @__PURE__ */
|
|
1501
|
-
/* @__PURE__ */
|
|
1502
|
-
/* @__PURE__ */
|
|
1753
|
+
return /* @__PURE__ */ jsxs14("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
1754
|
+
/* @__PURE__ */ jsxs14("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: [
|
|
1755
|
+
/* @__PURE__ */ jsx16("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.sectionTitle }),
|
|
1756
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.sectionDescription })
|
|
1503
1757
|
] }),
|
|
1504
|
-
/* @__PURE__ */
|
|
1505
|
-
/* @__PURE__ */
|
|
1506
|
-
/* @__PURE__ */
|
|
1507
|
-
/* @__PURE__ */
|
|
1508
|
-
/* @__PURE__ */
|
|
1758
|
+
/* @__PURE__ */ jsxs14("form", { onSubmit, className: "p-6 space-y-4", children: [
|
|
1759
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1760
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.nameLabel }),
|
|
1761
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.nameHint }),
|
|
1762
|
+
/* @__PURE__ */ jsx16(
|
|
1509
1763
|
"input",
|
|
1510
1764
|
{
|
|
1511
1765
|
type: "text",
|
|
@@ -1517,56 +1771,56 @@ function WhatsAppCreateTemplateForm({
|
|
|
1517
1771
|
}
|
|
1518
1772
|
)
|
|
1519
1773
|
] }),
|
|
1520
|
-
/* @__PURE__ */
|
|
1521
|
-
/* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
1523
|
-
/* @__PURE__ */
|
|
1774
|
+
/* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
1775
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1776
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.categoryLabel }),
|
|
1777
|
+
/* @__PURE__ */ jsxs14(
|
|
1524
1778
|
"select",
|
|
1525
1779
|
{
|
|
1526
1780
|
value: value.category,
|
|
1527
1781
|
onChange: (e) => set("category", e.target.value),
|
|
1528
1782
|
className: "w-full border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition-all",
|
|
1529
1783
|
children: [
|
|
1530
|
-
/* @__PURE__ */
|
|
1531
|
-
/* @__PURE__ */
|
|
1784
|
+
/* @__PURE__ */ jsx16("option", { value: "UTILITY", children: "UTILITY (Transacional)" }),
|
|
1785
|
+
/* @__PURE__ */ jsx16("option", { value: "MARKETING", children: "MARKETING (Promocional)" })
|
|
1532
1786
|
]
|
|
1533
1787
|
}
|
|
1534
1788
|
)
|
|
1535
1789
|
] }),
|
|
1536
|
-
/* @__PURE__ */
|
|
1537
|
-
/* @__PURE__ */
|
|
1538
|
-
/* @__PURE__ */
|
|
1790
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1791
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.languageLabel }),
|
|
1792
|
+
/* @__PURE__ */ jsxs14(
|
|
1539
1793
|
"select",
|
|
1540
1794
|
{
|
|
1541
1795
|
value: value.language,
|
|
1542
1796
|
onChange: (e) => set("language", e.target.value),
|
|
1543
1797
|
className: "w-full border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent transition-all",
|
|
1544
1798
|
children: [
|
|
1545
|
-
/* @__PURE__ */
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
/* @__PURE__ */
|
|
1799
|
+
/* @__PURE__ */ jsx16("option", { value: "pt_BR", children: "Portugu\xEAs (Brasil)" }),
|
|
1800
|
+
/* @__PURE__ */ jsx16("option", { value: "en_US", children: "Ingl\xEAs (EUA)" }),
|
|
1801
|
+
/* @__PURE__ */ jsx16("option", { value: "es_ES", children: "Espanhol" })
|
|
1548
1802
|
]
|
|
1549
1803
|
}
|
|
1550
1804
|
)
|
|
1551
1805
|
] })
|
|
1552
1806
|
] }),
|
|
1553
|
-
/* @__PURE__ */
|
|
1554
|
-
/* @__PURE__ */
|
|
1555
|
-
/* @__PURE__ */
|
|
1556
|
-
/* @__PURE__ */
|
|
1557
|
-
/* @__PURE__ */
|
|
1807
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1808
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.headerLabel }),
|
|
1809
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.headerHint }),
|
|
1810
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
|
|
1811
|
+
/* @__PURE__ */ jsxs14(
|
|
1558
1812
|
"select",
|
|
1559
1813
|
{
|
|
1560
1814
|
value: value.headerType,
|
|
1561
1815
|
onChange: (e) => set("headerType", e.target.value),
|
|
1562
1816
|
className: "border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 rounded-xl px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 transition-all",
|
|
1563
1817
|
children: [
|
|
1564
|
-
/* @__PURE__ */
|
|
1565
|
-
/* @__PURE__ */
|
|
1818
|
+
/* @__PURE__ */ jsx16("option", { value: "NONE", children: labels.headerNone }),
|
|
1819
|
+
/* @__PURE__ */ jsx16("option", { value: "TEXT", children: labels.headerText })
|
|
1566
1820
|
]
|
|
1567
1821
|
}
|
|
1568
1822
|
),
|
|
1569
|
-
value.headerType === "TEXT" && /* @__PURE__ */
|
|
1823
|
+
value.headerType === "TEXT" && /* @__PURE__ */ jsx16(
|
|
1570
1824
|
"input",
|
|
1571
1825
|
{
|
|
1572
1826
|
type: "text",
|
|
@@ -1579,10 +1833,10 @@ function WhatsAppCreateTemplateForm({
|
|
|
1579
1833
|
)
|
|
1580
1834
|
] })
|
|
1581
1835
|
] }),
|
|
1582
|
-
/* @__PURE__ */
|
|
1583
|
-
/* @__PURE__ */
|
|
1584
|
-
/* @__PURE__ */
|
|
1585
|
-
/* @__PURE__ */
|
|
1836
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1837
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.bodyLabel }),
|
|
1838
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.bodyHint }),
|
|
1839
|
+
/* @__PURE__ */ jsx16(
|
|
1586
1840
|
"textarea",
|
|
1587
1841
|
{
|
|
1588
1842
|
value: value.bodyText,
|
|
@@ -1593,26 +1847,26 @@ function WhatsAppCreateTemplateForm({
|
|
|
1593
1847
|
required: true
|
|
1594
1848
|
}
|
|
1595
1849
|
),
|
|
1596
|
-
detectedVariables.length > 0 && /* @__PURE__ */
|
|
1597
|
-
/* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
/* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
1850
|
+
detectedVariables.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "mt-2 rounded-lg bg-gray-50 dark:bg-gray-700/50 border border-gray-200 dark:border-gray-600 px-3 py-2", children: [
|
|
1851
|
+
/* @__PURE__ */ jsx16("p", { className: "font-medium text-gray-500 dark:text-gray-400 mb-1.5 uppercase tracking-wide text-xs", children: labels.detectedVariables }),
|
|
1852
|
+
/* @__PURE__ */ jsx16("div", { className: "flex flex-wrap gap-2", children: detectedVariables.map((num) => /* @__PURE__ */ jsxs14("span", { className: "inline-flex items-center gap-1 text-xs", children: [
|
|
1853
|
+
/* @__PURE__ */ jsx16("code", { className: "bg-blue-100 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300 px-1.5 py-0.5 rounded font-mono", children: `{{${num}}}` }),
|
|
1854
|
+
/* @__PURE__ */ jsxs14("span", { className: "text-gray-400 dark:text-gray-500", children: [
|
|
1601
1855
|
"= ",
|
|
1602
1856
|
variableExamples[Number(num) - 1] ?? labels.variableLabel(Number(num))
|
|
1603
1857
|
] })
|
|
1604
1858
|
] }, num)) }),
|
|
1605
|
-
/* @__PURE__ */
|
|
1859
|
+
/* @__PURE__ */ jsxs14("p", { className: "text-gray-400 dark:text-gray-500 mt-1.5 text-xs", children: [
|
|
1606
1860
|
labels.configureHintPrefix,
|
|
1607
|
-
/* @__PURE__ */
|
|
1861
|
+
/* @__PURE__ */ jsx16("strong", { children: labels.configureHintLink }),
|
|
1608
1862
|
labels.configureHintSuffix
|
|
1609
1863
|
] })
|
|
1610
1864
|
] })
|
|
1611
1865
|
] }),
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
/* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
/* @__PURE__ */
|
|
1866
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1867
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.footerLabel }),
|
|
1868
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.footerHint }),
|
|
1869
|
+
/* @__PURE__ */ jsx16(
|
|
1616
1870
|
"input",
|
|
1617
1871
|
{
|
|
1618
1872
|
type: "text",
|
|
@@ -1624,48 +1878,48 @@ function WhatsAppCreateTemplateForm({
|
|
|
1624
1878
|
}
|
|
1625
1879
|
)
|
|
1626
1880
|
] }),
|
|
1627
|
-
/* @__PURE__ */
|
|
1628
|
-
/* @__PURE__ */
|
|
1629
|
-
/* @__PURE__ */
|
|
1630
|
-
/* @__PURE__ */
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
/* @__PURE__ */
|
|
1633
|
-
/* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
1881
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1882
|
+
/* @__PURE__ */ jsx16("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block", children: labels.previewLabel }),
|
|
1883
|
+
/* @__PURE__ */ jsxs14("div", { className: "rounded-2xl bg-[#e5ddd5] dark:bg-[#1a1a2e] border border-gray-300 dark:border-gray-600 overflow-hidden shadow-inner", children: [
|
|
1884
|
+
/* @__PURE__ */ jsxs14("div", { className: "bg-[#075e54] px-4 py-2.5 flex items-center gap-2", children: [
|
|
1885
|
+
/* @__PURE__ */ jsx16("div", { className: "w-8 h-8 rounded-full bg-white/20 flex items-center justify-center text-white text-xs font-bold", children: previewCompanyName.slice(0, 2).toUpperCase() }),
|
|
1886
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
1887
|
+
/* @__PURE__ */ jsx16("p", { className: "text-white text-xs font-semibold leading-tight", children: previewCompanyName }),
|
|
1888
|
+
/* @__PURE__ */ jsx16("p", { className: "text-white/60 text-xs", children: labels.previewOnline })
|
|
1635
1889
|
] })
|
|
1636
1890
|
] }),
|
|
1637
|
-
/* @__PURE__ */
|
|
1638
|
-
/* @__PURE__ */
|
|
1639
|
-
/* @__PURE__ */
|
|
1640
|
-
/* @__PURE__ */
|
|
1891
|
+
/* @__PURE__ */ jsxs14("div", { className: "px-3 py-4 space-y-3", style: { minHeight: "120px" }, children: [
|
|
1892
|
+
/* @__PURE__ */ jsx16("div", { className: "flex justify-start", style: { maxWidth: "85%" }, children: /* @__PURE__ */ jsxs14("div", { className: "bg-white dark:bg-gray-700 rounded-lg rounded-tl-none px-3 py-2 shadow-sm", children: [
|
|
1893
|
+
/* @__PURE__ */ jsx16("p", { className: "text-gray-500 dark:text-gray-400 leading-tight text-sm", children: labels.previewDescription }),
|
|
1894
|
+
/* @__PURE__ */ jsx16("p", { className: "text-gray-400 dark:text-gray-500 mt-1 text-right text-[9px]", children: "12:00" })
|
|
1641
1895
|
] }) }),
|
|
1642
|
-
/* @__PURE__ */
|
|
1643
|
-
value.headerType === "TEXT" && value.headerText && /* @__PURE__ */
|
|
1644
|
-
/* @__PURE__ */
|
|
1645
|
-
value.footerText && /* @__PURE__ */
|
|
1646
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsx16("div", { className: "flex justify-end ml-auto", style: { maxWidth: "85%" }, children: /* @__PURE__ */ jsxs14("div", { className: "bg-[#dcf8c6] dark:bg-[#1b5e20] rounded-lg rounded-tr-none px-3 py-2 shadow-sm", children: [
|
|
1897
|
+
value.headerType === "TEXT" && value.headerText && /* @__PURE__ */ jsx16("p", { className: "text-xs font-bold text-gray-700 dark:text-gray-200 mb-1", children: fillPreviewTokens(value.headerText) || labels.previewHeaderFallback }),
|
|
1898
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm text-gray-800 dark:text-gray-100 leading-relaxed", children: value.bodyText ? fillPreviewTokens(value.bodyText) : /* @__PURE__ */ jsx16("span", { className: "text-gray-400 italic", children: labels.previewBodyPlaceholder }) }),
|
|
1899
|
+
value.footerText && /* @__PURE__ */ jsx16("p", { className: "text-gray-400 dark:text-gray-400 mt-1 text-xs", children: value.footerText }),
|
|
1900
|
+
/* @__PURE__ */ jsx16("p", { className: "text-gray-400 dark:text-gray-400 mt-1 text-right text-[9px]", children: "12:01 \u2713" })
|
|
1647
1901
|
] }) })
|
|
1648
1902
|
] })
|
|
1649
1903
|
] })
|
|
1650
1904
|
] }),
|
|
1651
|
-
result && /* @__PURE__ */
|
|
1905
|
+
result && /* @__PURE__ */ jsxs14(
|
|
1652
1906
|
"div",
|
|
1653
1907
|
{
|
|
1654
1908
|
className: `rounded-xl px-4 py-3 text-sm ${result.ok ? "bg-green-50 dark:bg-green-950/40 border border-green-200 dark:border-green-800 text-green-700 dark:text-green-400" : "bg-red-50 dark:bg-red-950/40 border border-red-200 dark:border-red-800 text-red-700 dark:text-red-400"}`,
|
|
1655
1909
|
children: [
|
|
1656
1910
|
result.message,
|
|
1657
|
-
result.ok && result.status && /* @__PURE__ */
|
|
1911
|
+
result.ok && result.status && /* @__PURE__ */ jsx16("p", { className: "text-xs mt-1 opacity-75", children: labels.successStatus(result.status) })
|
|
1658
1912
|
]
|
|
1659
1913
|
}
|
|
1660
1914
|
),
|
|
1661
|
-
/* @__PURE__ */
|
|
1915
|
+
/* @__PURE__ */ jsx16("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs14(
|
|
1662
1916
|
"button",
|
|
1663
1917
|
{
|
|
1664
1918
|
type: "submit",
|
|
1665
1919
|
disabled: submitting || !value.name || !value.bodyText,
|
|
1666
1920
|
className: "flex items-center gap-2 bg-emerald-600 hover:bg-emerald-700 disabled:bg-emerald-400 text-white font-semibold px-5 py-2.5 rounded-xl transition-colors text-sm",
|
|
1667
1921
|
children: [
|
|
1668
|
-
submitting ? /* @__PURE__ */
|
|
1922
|
+
submitting ? /* @__PURE__ */ jsx16("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx16(SendHorizonal2, { size: 14 }),
|
|
1669
1923
|
submitting ? labels.sending : labels.sendForApproval
|
|
1670
1924
|
]
|
|
1671
1925
|
}
|
|
@@ -1676,7 +1930,7 @@ function WhatsAppCreateTemplateForm({
|
|
|
1676
1930
|
|
|
1677
1931
|
// src/settings/WelcomeFarewellForm.tsx
|
|
1678
1932
|
import { LogOut, Mail, Save as Save2 } from "lucide-react";
|
|
1679
|
-
import { jsx as
|
|
1933
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1680
1934
|
var DEFAULT_LABELS4 = {
|
|
1681
1935
|
sectionTitle: "Boas-vindas e encerramento",
|
|
1682
1936
|
welcomeMessage: "Mensagem de boas-vindas",
|
|
@@ -1704,15 +1958,15 @@ function WelcomeFarewellForm({
|
|
|
1704
1958
|
labels: labelsOverride
|
|
1705
1959
|
}) {
|
|
1706
1960
|
const labels = { ...DEFAULT_LABELS4, ...labelsOverride };
|
|
1707
|
-
return /* @__PURE__ */
|
|
1708
|
-
/* @__PURE__ */
|
|
1709
|
-
/* @__PURE__ */
|
|
1710
|
-
/* @__PURE__ */
|
|
1711
|
-
/* @__PURE__ */
|
|
1712
|
-
/* @__PURE__ */
|
|
1961
|
+
return /* @__PURE__ */ jsxs15("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
1962
|
+
/* @__PURE__ */ jsx17("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: /* @__PURE__ */ jsx17("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.sectionTitle }) }),
|
|
1963
|
+
/* @__PURE__ */ jsxs15("form", { onSubmit: onSave, className: "p-6 space-y-5", children: [
|
|
1964
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
1965
|
+
/* @__PURE__ */ jsxs15("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5 flex items-center gap-1.5", children: [
|
|
1966
|
+
/* @__PURE__ */ jsx17(Mail, { size: 13, className: "text-blue-600 dark:text-blue-400" }),
|
|
1713
1967
|
labels.welcomeMessage
|
|
1714
1968
|
] }),
|
|
1715
|
-
/* @__PURE__ */
|
|
1969
|
+
/* @__PURE__ */ jsx17(
|
|
1716
1970
|
WhatsAppMessageEditor,
|
|
1717
1971
|
{
|
|
1718
1972
|
value: welcomeMessage,
|
|
@@ -1721,14 +1975,14 @@ function WelcomeFarewellForm({
|
|
|
1721
1975
|
placeholders: welcomePlaceholders
|
|
1722
1976
|
}
|
|
1723
1977
|
),
|
|
1724
|
-
/* @__PURE__ */
|
|
1978
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: labels.welcomeMessageHint })
|
|
1725
1979
|
] }),
|
|
1726
|
-
/* @__PURE__ */
|
|
1727
|
-
/* @__PURE__ */
|
|
1728
|
-
/* @__PURE__ */
|
|
1980
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
1981
|
+
/* @__PURE__ */ jsxs15("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5 flex items-center gap-1.5", children: [
|
|
1982
|
+
/* @__PURE__ */ jsx17(LogOut, { size: 13, className: "text-blue-600 dark:text-blue-400" }),
|
|
1729
1983
|
labels.farewellMessage
|
|
1730
1984
|
] }),
|
|
1731
|
-
/* @__PURE__ */
|
|
1985
|
+
/* @__PURE__ */ jsx17(
|
|
1732
1986
|
WhatsAppMessageEditor,
|
|
1733
1987
|
{
|
|
1734
1988
|
value: farewellMessage,
|
|
@@ -1737,17 +1991,17 @@ function WelcomeFarewellForm({
|
|
|
1737
1991
|
placeholders: farewellPlaceholders
|
|
1738
1992
|
}
|
|
1739
1993
|
),
|
|
1740
|
-
/* @__PURE__ */
|
|
1994
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: labels.farewellMessageHint })
|
|
1741
1995
|
] }),
|
|
1742
|
-
saveSuccess && /* @__PURE__ */
|
|
1743
|
-
/* @__PURE__ */
|
|
1996
|
+
saveSuccess && /* @__PURE__ */ jsx17("div", { className: "bg-green-50 dark:bg-green-950/40 border border-green-200 dark:border-green-800 rounded-xl px-4 py-3 text-sm text-green-700 dark:text-green-400", children: labels.saveSuccess }),
|
|
1997
|
+
/* @__PURE__ */ jsx17("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs15(
|
|
1744
1998
|
"button",
|
|
1745
1999
|
{
|
|
1746
2000
|
type: "submit",
|
|
1747
2001
|
disabled: saving,
|
|
1748
2002
|
className: "flex items-center gap-2 bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white font-semibold px-5 py-2.5 rounded-xl transition-colors text-sm",
|
|
1749
2003
|
children: [
|
|
1750
|
-
saving ? /* @__PURE__ */
|
|
2004
|
+
saving ? /* @__PURE__ */ jsx17("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx17(Save2, { size: 14 }),
|
|
1751
2005
|
saving ? labels.saving : labels.save
|
|
1752
2006
|
]
|
|
1753
2007
|
}
|
|
@@ -1757,8 +2011,8 @@ function WelcomeFarewellForm({
|
|
|
1757
2011
|
}
|
|
1758
2012
|
|
|
1759
2013
|
// src/settings/WhatsAppTemplatesSettings.tsx
|
|
1760
|
-
import { useState as
|
|
1761
|
-
import { jsx as
|
|
2014
|
+
import { useState as useState9 } from "react";
|
|
2015
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1762
2016
|
var TEMPLATE_SETTINGS_TAB = {
|
|
1763
2017
|
SELECT: "select",
|
|
1764
2018
|
CREATE: "create"
|
|
@@ -1773,10 +2027,10 @@ function WhatsAppTemplatesSettings({
|
|
|
1773
2027
|
...settingsProps
|
|
1774
2028
|
}) {
|
|
1775
2029
|
const labels = { ...DEFAULT_TEMPLATES_SETTINGS_LABELS, ...labelsOverride };
|
|
1776
|
-
const [tab, setTab] =
|
|
1777
|
-
return /* @__PURE__ */
|
|
1778
|
-
/* @__PURE__ */
|
|
1779
|
-
/* @__PURE__ */
|
|
2030
|
+
const [tab, setTab] = useState9(TEMPLATE_SETTINGS_TAB.SELECT);
|
|
2031
|
+
return /* @__PURE__ */ jsxs16("div", { className: "space-y-4", children: [
|
|
2032
|
+
/* @__PURE__ */ jsxs16("nav", { className: "flex gap-1 border-b", role: "tablist", children: [
|
|
2033
|
+
/* @__PURE__ */ jsx18(
|
|
1780
2034
|
"button",
|
|
1781
2035
|
{
|
|
1782
2036
|
type: "button",
|
|
@@ -1787,7 +2041,7 @@ function WhatsAppTemplatesSettings({
|
|
|
1787
2041
|
children: labels.selectTab
|
|
1788
2042
|
}
|
|
1789
2043
|
),
|
|
1790
|
-
create ? /* @__PURE__ */
|
|
2044
|
+
create ? /* @__PURE__ */ jsx18(
|
|
1791
2045
|
"button",
|
|
1792
2046
|
{
|
|
1793
2047
|
type: "button",
|
|
@@ -1799,13 +2053,13 @@ function WhatsAppTemplatesSettings({
|
|
|
1799
2053
|
}
|
|
1800
2054
|
) : null
|
|
1801
2055
|
] }),
|
|
1802
|
-
tab === TEMPLATE_SETTINGS_TAB.SELECT ? /* @__PURE__ */
|
|
2056
|
+
tab === TEMPLATE_SETTINGS_TAB.SELECT ? /* @__PURE__ */ jsx18(WhatsAppTemplateSettingsForm, { ...settingsProps }) : create ? /* @__PURE__ */ jsx18(WhatsAppCreateTemplateForm, { ...create }) : null
|
|
1803
2057
|
] });
|
|
1804
2058
|
}
|
|
1805
2059
|
|
|
1806
2060
|
// src/settings/TopicsForm.tsx
|
|
1807
2061
|
import { Megaphone, Save as Save3 } from "lucide-react";
|
|
1808
|
-
import { jsx as
|
|
2062
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1809
2063
|
var DEFAULT_LABELS5 = {
|
|
1810
2064
|
sectionTitle: "T\xF3picos intermedi\xE1rios",
|
|
1811
2065
|
sectionDescription: "Mensagens autom\xE1ticas para assuntos espec\xEDficos, disparadas quando o cliente demonstra interesse.",
|
|
@@ -1823,19 +2077,19 @@ function TopicsForm({
|
|
|
1823
2077
|
labels: labelsOverride
|
|
1824
2078
|
}) {
|
|
1825
2079
|
const labels = { ...DEFAULT_LABELS5, ...labelsOverride };
|
|
1826
|
-
return /* @__PURE__ */
|
|
1827
|
-
/* @__PURE__ */
|
|
1828
|
-
/* @__PURE__ */
|
|
1829
|
-
/* @__PURE__ */
|
|
2080
|
+
return /* @__PURE__ */ jsxs17("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
2081
|
+
/* @__PURE__ */ jsxs17("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: [
|
|
2082
|
+
/* @__PURE__ */ jsxs17("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2", children: [
|
|
2083
|
+
/* @__PURE__ */ jsx19(Megaphone, { size: 16, className: "text-orange-600 dark:text-orange-400" }),
|
|
1830
2084
|
labels.sectionTitle
|
|
1831
2085
|
] }),
|
|
1832
|
-
/* @__PURE__ */
|
|
2086
|
+
/* @__PURE__ */ jsx19("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.sectionDescription })
|
|
1833
2087
|
] }),
|
|
1834
|
-
/* @__PURE__ */
|
|
1835
|
-
topics.map((topic) => /* @__PURE__ */
|
|
1836
|
-
/* @__PURE__ */
|
|
1837
|
-
/* @__PURE__ */
|
|
1838
|
-
/* @__PURE__ */
|
|
2088
|
+
/* @__PURE__ */ jsxs17("form", { onSubmit: onSave, className: "p-6 space-y-6", children: [
|
|
2089
|
+
topics.map((topic) => /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
|
|
2090
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-4", children: [
|
|
2091
|
+
/* @__PURE__ */ jsx19("div", { className: "flex-1", children: /* @__PURE__ */ jsx19("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: topic.label }) }),
|
|
2092
|
+
/* @__PURE__ */ jsx19(
|
|
1839
2093
|
"button",
|
|
1840
2094
|
{
|
|
1841
2095
|
type: "button",
|
|
@@ -1843,7 +2097,7 @@ function TopicsForm({
|
|
|
1843
2097
|
className: `relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${topic.enabled ? "bg-blue-600 dark:bg-blue-500" : "bg-gray-200 dark:bg-gray-700"}`,
|
|
1844
2098
|
role: "switch",
|
|
1845
2099
|
"aria-checked": topic.enabled,
|
|
1846
|
-
children: /* @__PURE__ */
|
|
2100
|
+
children: /* @__PURE__ */ jsx19(
|
|
1847
2101
|
"span",
|
|
1848
2102
|
{
|
|
1849
2103
|
className: `pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out ${topic.enabled ? "translate-x-5" : "translate-x-0"}`
|
|
@@ -1852,7 +2106,7 @@ function TopicsForm({
|
|
|
1852
2106
|
}
|
|
1853
2107
|
)
|
|
1854
2108
|
] }),
|
|
1855
|
-
/* @__PURE__ */
|
|
2109
|
+
/* @__PURE__ */ jsx19(
|
|
1856
2110
|
"textarea",
|
|
1857
2111
|
{
|
|
1858
2112
|
value: topic.message,
|
|
@@ -1864,27 +2118,27 @@ function TopicsForm({
|
|
|
1864
2118
|
}
|
|
1865
2119
|
)
|
|
1866
2120
|
] }, topic.key)),
|
|
1867
|
-
/* @__PURE__ */
|
|
1868
|
-
/* @__PURE__ */
|
|
2121
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3", children: [
|
|
2122
|
+
/* @__PURE__ */ jsxs17(
|
|
1869
2123
|
"button",
|
|
1870
2124
|
{
|
|
1871
2125
|
type: "submit",
|
|
1872
2126
|
disabled: saving,
|
|
1873
2127
|
className: "inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50",
|
|
1874
2128
|
children: [
|
|
1875
|
-
/* @__PURE__ */
|
|
2129
|
+
/* @__PURE__ */ jsx19(Save3, { size: 14 }),
|
|
1876
2130
|
labels.saveButton
|
|
1877
2131
|
]
|
|
1878
2132
|
}
|
|
1879
2133
|
),
|
|
1880
|
-
saveSuccess && /* @__PURE__ */
|
|
2134
|
+
saveSuccess && /* @__PURE__ */ jsx19("span", { className: "text-sm text-green-600 dark:text-green-400", children: labels.saveSuccess })
|
|
1881
2135
|
] })
|
|
1882
2136
|
] })
|
|
1883
2137
|
] });
|
|
1884
2138
|
}
|
|
1885
2139
|
|
|
1886
2140
|
// src/hooks/useConversationMessages.ts
|
|
1887
|
-
import { useCallback as
|
|
2141
|
+
import { useCallback as useCallback5 } from "react";
|
|
1888
2142
|
function useConversationMessages(conversationId, params) {
|
|
1889
2143
|
const context = useConversations();
|
|
1890
2144
|
if (!context) {
|
|
@@ -1895,7 +2149,7 @@ function useConversationMessages(conversationId, params) {
|
|
|
1895
2149
|
() => api.fetchMessages(conversationId, params),
|
|
1896
2150
|
[conversationId, params?.limit, params?.before]
|
|
1897
2151
|
);
|
|
1898
|
-
const sendMessage =
|
|
2152
|
+
const sendMessage = useCallback5(
|
|
1899
2153
|
async (text) => {
|
|
1900
2154
|
const message = await api.sendMessage(conversationId, text);
|
|
1901
2155
|
await refetch();
|
|
@@ -1903,7 +2157,7 @@ function useConversationMessages(conversationId, params) {
|
|
|
1903
2157
|
},
|
|
1904
2158
|
[api, conversationId, refetch]
|
|
1905
2159
|
);
|
|
1906
|
-
const sendMedia =
|
|
2160
|
+
const sendMedia = useCallback5(
|
|
1907
2161
|
async (mediaData) => {
|
|
1908
2162
|
const message = await api.sendMedia(conversationId, mediaData);
|
|
1909
2163
|
await refetch();
|
|
@@ -1911,14 +2165,14 @@ function useConversationMessages(conversationId, params) {
|
|
|
1911
2165
|
},
|
|
1912
2166
|
[api, conversationId, refetch]
|
|
1913
2167
|
);
|
|
1914
|
-
const sendTemplate =
|
|
2168
|
+
const sendTemplate = useCallback5(
|
|
1915
2169
|
async (templateData) => {
|
|
1916
2170
|
await api.sendTemplate(conversationId, templateData);
|
|
1917
2171
|
await refetch();
|
|
1918
2172
|
},
|
|
1919
2173
|
[api, conversationId, refetch]
|
|
1920
2174
|
);
|
|
1921
|
-
const markRead =
|
|
2175
|
+
const markRead = useCallback5(() => api.markRead(conversationId), [api, conversationId]);
|
|
1922
2176
|
return { messages: data ?? [], loading, error, refetch, sendMessage, sendMedia, sendTemplate, markRead };
|
|
1923
2177
|
}
|
|
1924
2178
|
|
|
@@ -1952,12 +2206,12 @@ function useConversationContext(conversationId) {
|
|
|
1952
2206
|
}
|
|
1953
2207
|
|
|
1954
2208
|
// src/hooks/useConversationRealtime.ts
|
|
1955
|
-
import { useEffect as
|
|
2209
|
+
import { useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
1956
2210
|
function useConversationRealtime(conversationId, onEvent) {
|
|
1957
2211
|
const context = useConversations();
|
|
1958
|
-
const onEventRef =
|
|
2212
|
+
const onEventRef = useRef5(onEvent);
|
|
1959
2213
|
onEventRef.current = onEvent;
|
|
1960
|
-
|
|
2214
|
+
useEffect6(() => {
|
|
1961
2215
|
if (!context || !conversationId) return;
|
|
1962
2216
|
const source = context.sse.connectConversationStream(conversationId);
|
|
1963
2217
|
const handler = (event) => onEventRef.current(event);
|
|
@@ -1970,9 +2224,9 @@ function useConversationRealtime(conversationId, onEvent) {
|
|
|
1970
2224
|
}
|
|
1971
2225
|
function useGlobalRealtime(onEvent) {
|
|
1972
2226
|
const context = useConversations();
|
|
1973
|
-
const onEventRef =
|
|
2227
|
+
const onEventRef = useRef5(onEvent);
|
|
1974
2228
|
onEventRef.current = onEvent;
|
|
1975
|
-
|
|
2229
|
+
useEffect6(() => {
|
|
1976
2230
|
if (!context) return;
|
|
1977
2231
|
const source = context.sse.connectGlobalStream();
|
|
1978
2232
|
const handler = (event) => onEventRef.current(event);
|
|
@@ -2044,6 +2298,7 @@ export {
|
|
|
2044
2298
|
DEFAULT_INTERACTIVE_MESSAGE_LABELS,
|
|
2045
2299
|
DEFAULT_LIGHTBOX_LABELS,
|
|
2046
2300
|
DEFAULT_MESSAGE_COMPOSER_LABELS,
|
|
2301
|
+
DEFAULT_RICH_COMPOSER_TOOLTIPS,
|
|
2047
2302
|
DEFAULT_TEMPLATES_SETTINGS_LABELS,
|
|
2048
2303
|
DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS,
|
|
2049
2304
|
DEFAULT_WINDOW_EXPIRED_LABELS,
|
|
@@ -2064,6 +2319,8 @@ export {
|
|
|
2064
2319
|
MessageTimestamp,
|
|
2065
2320
|
NARROW_MAX_WIDTH_PX,
|
|
2066
2321
|
REOPEN_MECHANISM,
|
|
2322
|
+
RICH_COMPOSER_ACTION,
|
|
2323
|
+
RichMessageComposer,
|
|
2067
2324
|
SimpleEmojiPicker,
|
|
2068
2325
|
StatusTicks,
|
|
2069
2326
|
TEMPLATE_SETTINGS_TAB,
|
|
@@ -2076,6 +2333,7 @@ export {
|
|
|
2076
2333
|
WhatsAppTemplateSettingsForm,
|
|
2077
2334
|
WhatsAppTemplatesSettings,
|
|
2078
2335
|
WindowExpiredNotice,
|
|
2336
|
+
applyQuickReplyVariables,
|
|
2079
2337
|
buildTranscriptFilename,
|
|
2080
2338
|
buildTranscriptText,
|
|
2081
2339
|
capabilitiesOf,
|
|
@@ -2094,6 +2352,7 @@ export {
|
|
|
2094
2352
|
isWindowBlocking,
|
|
2095
2353
|
parseWhatsAppFormatting,
|
|
2096
2354
|
phoneInitials,
|
|
2355
|
+
resolveQuickReply,
|
|
2097
2356
|
searchEmojis,
|
|
2098
2357
|
toast,
|
|
2099
2358
|
useConversationActions,
|