@adatechnology/conversations-ui 0.1.0-rc.23 → 0.1.0-rc.25
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/flows/index.d.ts +128 -2
- package/dist/flows/index.js +1085 -6
- package/dist/index.d.ts +255 -9
- package/dist/index.js +1309 -325
- package/dist/preview/index.d.ts +2 -2
- package/dist/styles.css +117 -0
- package/dist/{types-C6A_9edv.d.ts → types-BfINicc-.d.ts} +36 -1
- package/package.json +2 -2
- package/src/documents/DocumentsWorkspace.tsx +489 -0
- package/src/documents/index.ts +8 -0
- package/src/documents/labels.ts +88 -0
- package/src/flows/FlowNodeCard.tsx +12 -3
- package/src/flows/FlowNodePanel.tsx +15 -2
- package/src/flows/FlowsWorkspace.tsx +1252 -0
- package/src/flows/index.ts +3 -1
- package/src/flows/labels.ts +132 -0
- package/src/hooks/useUrlFilterState.ts +107 -0
- package/src/index.ts +30 -0
- package/src/listing/index.tsx +198 -0
- package/src/providers/types.ts +36 -1
- package/src/settings/MessagesWorkspace.tsx +465 -0
- package/src/settings/WhatsAppTemplatesSettings.tsx +7 -1
- package/src/styles.css +108 -0
- package/src/workspace/ConversationPane.tsx +119 -4
- package/src/workspace/ConversationsWorkspace.tsx +33 -1
- package/src/workspace/labels.ts +5 -0
package/dist/index.js
CHANGED
|
@@ -1547,6 +1547,599 @@ function isWindowBlocking(window2) {
|
|
|
1547
1547
|
return window2 === CONVERSATION_WINDOW.EXPIRED;
|
|
1548
1548
|
}
|
|
1549
1549
|
|
|
1550
|
+
// src/documents/DocumentsWorkspace.tsx
|
|
1551
|
+
import { useEffect as useEffect6, useMemo as useMemo2, useState as useState10 } from "react";
|
|
1552
|
+
import { Download, Eye, MessageSquare, Trash2, X as X2 } from "lucide-react";
|
|
1553
|
+
|
|
1554
|
+
// src/listing/index.tsx
|
|
1555
|
+
import { useState as useState8 } from "react";
|
|
1556
|
+
import { ArrowDown, ArrowUp, ArrowUpDown, ChevronDown as ChevronDown2, X } from "lucide-react";
|
|
1557
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1558
|
+
function SortableHead({ label, field, activeField, direction, onSort, className }) {
|
|
1559
|
+
const isActive = activeField === field;
|
|
1560
|
+
const Icon = !isActive ? ArrowUpDown : direction === "asc" ? ArrowUp : ArrowDown;
|
|
1561
|
+
return /* @__PURE__ */ jsx15("th", { scope: "col", className: cn("px-3 py-2 text-left text-xs font-medium", className), children: /* @__PURE__ */ jsxs13(
|
|
1562
|
+
"button",
|
|
1563
|
+
{
|
|
1564
|
+
type: "button",
|
|
1565
|
+
onClick: () => onSort(field),
|
|
1566
|
+
"aria-label": label,
|
|
1567
|
+
className: "inline-flex items-center gap-1 hover:text-gray-900 dark:hover:text-gray-100",
|
|
1568
|
+
children: [
|
|
1569
|
+
label,
|
|
1570
|
+
/* @__PURE__ */ jsx15(Icon, { size: 12, className: isActive ? "" : "opacity-40", "aria-hidden": "true" })
|
|
1571
|
+
]
|
|
1572
|
+
}
|
|
1573
|
+
) });
|
|
1574
|
+
}
|
|
1575
|
+
function MultiSelectFilter({ label, options, selected, onChange, className }) {
|
|
1576
|
+
const [open, setOpen] = useState8(false);
|
|
1577
|
+
function toggle(value) {
|
|
1578
|
+
onChange(selected.includes(value) ? selected.filter((item) => item !== value) : [...selected, value]);
|
|
1579
|
+
}
|
|
1580
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("relative", className), children: [
|
|
1581
|
+
/* @__PURE__ */ jsxs13(
|
|
1582
|
+
"button",
|
|
1583
|
+
{
|
|
1584
|
+
type: "button",
|
|
1585
|
+
onClick: () => setOpen((current) => !current),
|
|
1586
|
+
className: "cv-header-action inline-flex items-center gap-1",
|
|
1587
|
+
children: [
|
|
1588
|
+
label,
|
|
1589
|
+
selected.length > 0 ? /* @__PURE__ */ jsx15("span", { className: "cv-filter-count", children: selected.length }) : null,
|
|
1590
|
+
/* @__PURE__ */ jsx15(ChevronDown2, { size: 12, className: open ? "rotate-180 transition-transform" : "transition-transform", "aria-hidden": "true" })
|
|
1591
|
+
]
|
|
1592
|
+
}
|
|
1593
|
+
),
|
|
1594
|
+
open ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
1595
|
+
/* @__PURE__ */ jsx15("div", { className: "fixed inset-0 z-10", onClick: () => setOpen(false) }),
|
|
1596
|
+
/* @__PURE__ */ jsx15("div", { className: "cv-filter-menu", children: options.map((option) => /* @__PURE__ */ jsxs13("label", { className: "cv-filter-option", children: [
|
|
1597
|
+
/* @__PURE__ */ jsx15(
|
|
1598
|
+
"input",
|
|
1599
|
+
{
|
|
1600
|
+
type: "checkbox",
|
|
1601
|
+
checked: selected.includes(option.value),
|
|
1602
|
+
onChange: () => toggle(option.value),
|
|
1603
|
+
className: "cursor-pointer rounded border-gray-300 text-blue-600 dark:border-gray-600"
|
|
1604
|
+
}
|
|
1605
|
+
),
|
|
1606
|
+
option.label
|
|
1607
|
+
] }, option.value)) })
|
|
1608
|
+
] }) : null
|
|
1609
|
+
] });
|
|
1610
|
+
}
|
|
1611
|
+
function BulkActionBar({ selectedCount, selectedLabel, clearLabel, onClear, children }) {
|
|
1612
|
+
if (selectedCount === 0) return null;
|
|
1613
|
+
return /* @__PURE__ */ jsxs13("div", { className: "cv-bulk-bar", role: "toolbar", "aria-label": selectedLabel(selectedCount), children: [
|
|
1614
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs font-medium", children: selectedLabel(selectedCount) }),
|
|
1615
|
+
children,
|
|
1616
|
+
/* @__PURE__ */ jsxs13("button", { type: "button", onClick: onClear, className: "cv-header-action ml-auto inline-flex items-center gap-1", children: [
|
|
1617
|
+
/* @__PURE__ */ jsx15(X, { size: 12, "aria-hidden": "true" }),
|
|
1618
|
+
clearLabel
|
|
1619
|
+
] })
|
|
1620
|
+
] });
|
|
1621
|
+
}
|
|
1622
|
+
function ListingPagination({
|
|
1623
|
+
page,
|
|
1624
|
+
total,
|
|
1625
|
+
perPage,
|
|
1626
|
+
perPageOptions,
|
|
1627
|
+
onPageChange,
|
|
1628
|
+
onPerPageChange,
|
|
1629
|
+
labels
|
|
1630
|
+
}) {
|
|
1631
|
+
const lastPage = Math.max(1, Math.ceil(total / perPage));
|
|
1632
|
+
return /* @__PURE__ */ jsxs13("div", { className: "cv-listing-pagination", children: [
|
|
1633
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400", children: [
|
|
1634
|
+
onPerPageChange && perPageOptions ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
1635
|
+
/* @__PURE__ */ jsx15("span", { children: labels.show }),
|
|
1636
|
+
/* @__PURE__ */ jsx15(
|
|
1637
|
+
"select",
|
|
1638
|
+
{
|
|
1639
|
+
value: perPage,
|
|
1640
|
+
onChange: (event) => onPerPageChange(Number(event.target.value)),
|
|
1641
|
+
"aria-label": labels.perPage,
|
|
1642
|
+
className: "cv-listing-perpage",
|
|
1643
|
+
children: perPageOptions.map((option) => /* @__PURE__ */ jsx15("option", { value: option, children: option }, option))
|
|
1644
|
+
}
|
|
1645
|
+
),
|
|
1646
|
+
/* @__PURE__ */ jsx15("span", { children: labels.perPage })
|
|
1647
|
+
] }) : null,
|
|
1648
|
+
/* @__PURE__ */ jsx15("span", { className: "ml-1", children: labels.total(total) })
|
|
1649
|
+
] }),
|
|
1650
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
1651
|
+
/* @__PURE__ */ jsx15(
|
|
1652
|
+
"button",
|
|
1653
|
+
{
|
|
1654
|
+
type: "button",
|
|
1655
|
+
onClick: () => onPageChange(page - 1),
|
|
1656
|
+
disabled: page <= 1,
|
|
1657
|
+
"aria-label": labels.previous,
|
|
1658
|
+
className: "cv-header-icon disabled:opacity-40",
|
|
1659
|
+
children: "\u2039"
|
|
1660
|
+
}
|
|
1661
|
+
),
|
|
1662
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs text-gray-500", children: labels.page(page, lastPage) }),
|
|
1663
|
+
/* @__PURE__ */ jsx15(
|
|
1664
|
+
"button",
|
|
1665
|
+
{
|
|
1666
|
+
type: "button",
|
|
1667
|
+
onClick: () => onPageChange(page + 1),
|
|
1668
|
+
disabled: page >= lastPage,
|
|
1669
|
+
"aria-label": labels.next,
|
|
1670
|
+
className: "cv-header-icon disabled:opacity-40",
|
|
1671
|
+
children: "\u203A"
|
|
1672
|
+
}
|
|
1673
|
+
)
|
|
1674
|
+
] })
|
|
1675
|
+
] });
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
// src/hooks/useUrlFilterState.ts
|
|
1679
|
+
import { useCallback as useCallback4, useEffect as useEffect5, useState as useState9 } from "react";
|
|
1680
|
+
var LIST_SEPARATOR = ",";
|
|
1681
|
+
function readParams() {
|
|
1682
|
+
if (typeof window === "undefined") return new URLSearchParams();
|
|
1683
|
+
return new URLSearchParams(window.location.search);
|
|
1684
|
+
}
|
|
1685
|
+
function writeParam(key, value) {
|
|
1686
|
+
if (typeof window === "undefined") return;
|
|
1687
|
+
const params = readParams();
|
|
1688
|
+
if (value === void 0 || value === "") params.delete(key);
|
|
1689
|
+
else params.set(key, value);
|
|
1690
|
+
const query = params.toString();
|
|
1691
|
+
window.history.replaceState(null, "", query ? `${window.location.pathname}?${query}` : window.location.pathname);
|
|
1692
|
+
}
|
|
1693
|
+
function useUrlStringState(key, initial, { enabled = true } = {}) {
|
|
1694
|
+
const [value, setValue] = useState9(() => enabled ? readParams().get(key) ?? initial : initial);
|
|
1695
|
+
const update = useCallback4(
|
|
1696
|
+
(next) => {
|
|
1697
|
+
setValue(next);
|
|
1698
|
+
if (enabled) writeParam(key, next === initial ? void 0 : next);
|
|
1699
|
+
},
|
|
1700
|
+
[enabled, key, initial]
|
|
1701
|
+
);
|
|
1702
|
+
return [value, update];
|
|
1703
|
+
}
|
|
1704
|
+
function useUrlNumberState(key, initial, { enabled = true } = {}) {
|
|
1705
|
+
const [value, setValue] = useState9(() => {
|
|
1706
|
+
if (!enabled) return initial;
|
|
1707
|
+
const raw = Number(readParams().get(key));
|
|
1708
|
+
return Number.isFinite(raw) && raw > 0 ? raw : initial;
|
|
1709
|
+
});
|
|
1710
|
+
const update = useCallback4(
|
|
1711
|
+
(next) => {
|
|
1712
|
+
setValue(next);
|
|
1713
|
+
if (enabled) writeParam(key, next === initial ? void 0 : String(next));
|
|
1714
|
+
},
|
|
1715
|
+
[enabled, key, initial]
|
|
1716
|
+
);
|
|
1717
|
+
return [value, update];
|
|
1718
|
+
}
|
|
1719
|
+
function useUrlArrayState(key, { enabled = true } = {}) {
|
|
1720
|
+
const [value, setValue] = useState9(() => {
|
|
1721
|
+
if (!enabled) return [];
|
|
1722
|
+
const raw = readParams().get(key);
|
|
1723
|
+
return raw ? raw.split(LIST_SEPARATOR).filter(Boolean) : [];
|
|
1724
|
+
});
|
|
1725
|
+
const update = useCallback4(
|
|
1726
|
+
(next) => {
|
|
1727
|
+
setValue(next);
|
|
1728
|
+
if (enabled) writeParam(key, next.length > 0 ? next.join(LIST_SEPARATOR) : void 0);
|
|
1729
|
+
},
|
|
1730
|
+
[enabled, key]
|
|
1731
|
+
);
|
|
1732
|
+
return [value, update];
|
|
1733
|
+
}
|
|
1734
|
+
function useDebouncedValue(value, delayMs = 300) {
|
|
1735
|
+
const [debounced, setDebounced] = useState9(value);
|
|
1736
|
+
useEffect5(() => {
|
|
1737
|
+
const timer = setTimeout(() => setDebounced(value), delayMs);
|
|
1738
|
+
return () => clearTimeout(timer);
|
|
1739
|
+
}, [value, delayMs]);
|
|
1740
|
+
return debounced;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// src/documents/labels.ts
|
|
1744
|
+
var DEFAULT_DOCUMENTS_WORKSPACE_LABELS = {
|
|
1745
|
+
title: "Documentos",
|
|
1746
|
+
subtitle: (total) => `${total} arquivo${total === 1 ? "" : "s"} trocado${total === 1 ? "" : "s"}`,
|
|
1747
|
+
searchPlaceholder: "Buscar por nome do arquivo ou telefone",
|
|
1748
|
+
empty: "Nenhum arquivo trocado ainda.",
|
|
1749
|
+
noResults: "Nenhum arquivo encontrado para os filtros aplicados.",
|
|
1750
|
+
loading: "Carregando arquivos\u2026",
|
|
1751
|
+
failure: "N\xE3o foi poss\xEDvel carregar os arquivos.",
|
|
1752
|
+
view: "Visualizar",
|
|
1753
|
+
download: "Baixar",
|
|
1754
|
+
remove: "Excluir",
|
|
1755
|
+
removeConfirm: (filename) => `Excluir "${filename}"?`,
|
|
1756
|
+
openConversation: "Abrir conversa",
|
|
1757
|
+
sourceFilter: "Origem",
|
|
1758
|
+
categoryFilter: "Tipo",
|
|
1759
|
+
startDate: "De",
|
|
1760
|
+
endDate: "At\xE9",
|
|
1761
|
+
clearFilters: "Limpar filtros",
|
|
1762
|
+
selectAllPage: "Selecionar todos desta p\xE1gina",
|
|
1763
|
+
selectRow: "Selecionar arquivo",
|
|
1764
|
+
bulkSelected: (count) => `${count} selecionado${count === 1 ? "" : "s"}`,
|
|
1765
|
+
bulkClear: "Limpar sele\xE7\xE3o",
|
|
1766
|
+
bulkDownloadZip: "Baixar em zip",
|
|
1767
|
+
bulkRemove: (count) => `Excluir ${count}`,
|
|
1768
|
+
bulkRemoveConfirm: (count) => `Excluir ${count} arquivo${count === 1 ? "" : "s"}?`,
|
|
1769
|
+
columnFilename: "Arquivo",
|
|
1770
|
+
columnContact: "Contato",
|
|
1771
|
+
columnType: "Tipo",
|
|
1772
|
+
columnSize: "Tamanho",
|
|
1773
|
+
columnSource: "Origem",
|
|
1774
|
+
columnDate: "Recebido em",
|
|
1775
|
+
columnActions: "A\xE7\xF5es",
|
|
1776
|
+
sourceLabels: { customer: "Cliente", agent: "Atendente", bot: "Bot" },
|
|
1777
|
+
categoryLabels: { document: "Documento", image: "Imagem", audio: "\xC1udio", video: "V\xEDdeo" },
|
|
1778
|
+
show: "Mostrar",
|
|
1779
|
+
perPage: "por p\xE1gina",
|
|
1780
|
+
total: (count) => `${count} no total`,
|
|
1781
|
+
page: (current, last) => `${current} / ${last}`,
|
|
1782
|
+
previousPage: "P\xE1gina anterior",
|
|
1783
|
+
nextPage: "Pr\xF3xima p\xE1gina"
|
|
1784
|
+
};
|
|
1785
|
+
|
|
1786
|
+
// src/documents/DocumentsWorkspace.tsx
|
|
1787
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1788
|
+
var DEFAULT_PER_PAGE = 20;
|
|
1789
|
+
var DEFAULT_PER_PAGE_OPTIONS = [10, 20, 50, 100];
|
|
1790
|
+
var DEFAULT_SORT_FIELD = "linkedAt";
|
|
1791
|
+
function DocumentsWorkspace({
|
|
1792
|
+
perPage: initialPerPage = DEFAULT_PER_PAGE,
|
|
1793
|
+
perPageOptions = DEFAULT_PER_PAGE_OPTIONS,
|
|
1794
|
+
onOpenConversation,
|
|
1795
|
+
sources,
|
|
1796
|
+
categories,
|
|
1797
|
+
dateFilter = true,
|
|
1798
|
+
renderFilters,
|
|
1799
|
+
labels: labelsOverride,
|
|
1800
|
+
className,
|
|
1801
|
+
classNames,
|
|
1802
|
+
syncUrl = true
|
|
1803
|
+
}) {
|
|
1804
|
+
const labels = { ...DEFAULT_DOCUMENTS_WORKSPACE_LABELS, ...labelsOverride };
|
|
1805
|
+
const context = useConversations();
|
|
1806
|
+
const urlOptions = { enabled: syncUrl };
|
|
1807
|
+
const [search, setSearch] = useUrlStringState("search", "", urlOptions);
|
|
1808
|
+
const [source, setSource] = useUrlArrayState("source", urlOptions);
|
|
1809
|
+
const [category, setCategory] = useUrlArrayState("fileCategory", urlOptions);
|
|
1810
|
+
const [startDate, setStartDate] = useUrlStringState("startDate", "", urlOptions);
|
|
1811
|
+
const [endDate, setEndDate] = useUrlStringState("endDate", "", urlOptions);
|
|
1812
|
+
const [sortField, setSortField] = useUrlStringState("sortField", DEFAULT_SORT_FIELD, urlOptions);
|
|
1813
|
+
const [sortDirection, setSortDirection] = useUrlStringState("sortDirection", "desc", urlOptions);
|
|
1814
|
+
const [page, setPage] = useUrlNumberState("page", 1, urlOptions);
|
|
1815
|
+
const [perPage, setPerPage] = useUrlNumberState("limit", initialPerPage, urlOptions);
|
|
1816
|
+
const [extra, setExtra] = useState10({});
|
|
1817
|
+
const [documents, setDocuments] = useState10([]);
|
|
1818
|
+
const [total, setTotal] = useState10(0);
|
|
1819
|
+
const [loading, setLoading] = useState10(false);
|
|
1820
|
+
const [failed, setFailed] = useState10(false);
|
|
1821
|
+
const [selectedIds, setSelectedIds] = useState10(/* @__PURE__ */ new Set());
|
|
1822
|
+
const [reloadToken, setReloadToken] = useState10(0);
|
|
1823
|
+
const [busy, setBusy] = useState10(false);
|
|
1824
|
+
const debouncedSearch = useDebouncedValue(search);
|
|
1825
|
+
const fetchAll = context?.api.getAllDocuments;
|
|
1826
|
+
const removeDocument = context?.api.deleteDocument;
|
|
1827
|
+
const downloadArchive = context?.api.downloadDocumentsArchiveByIds;
|
|
1828
|
+
const extraKey = JSON.stringify(extra);
|
|
1829
|
+
const sourceOptions = useMemo2(
|
|
1830
|
+
() => sources ?? Object.entries(labels.sourceLabels).map(([value, label]) => ({ value, label })),
|
|
1831
|
+
[sources, labels.sourceLabels]
|
|
1832
|
+
);
|
|
1833
|
+
const categoryOptions = useMemo2(
|
|
1834
|
+
() => categories ?? Object.entries(labels.categoryLabels).map(([value, label]) => ({ value, label })),
|
|
1835
|
+
[categories, labels.categoryLabels]
|
|
1836
|
+
);
|
|
1837
|
+
const hasFilters = debouncedSearch !== "" || source.length > 0 || category.length > 0 || startDate !== "" || endDate !== "" || Object.keys(extra).length > 0;
|
|
1838
|
+
useEffect6(() => {
|
|
1839
|
+
if (!fetchAll) return;
|
|
1840
|
+
let active = true;
|
|
1841
|
+
setLoading(true);
|
|
1842
|
+
setFailed(false);
|
|
1843
|
+
void fetchAll({
|
|
1844
|
+
search: debouncedSearch || void 0,
|
|
1845
|
+
page,
|
|
1846
|
+
limit: perPage,
|
|
1847
|
+
sortField,
|
|
1848
|
+
sortDirection: sortDirection === "asc" ? "asc" : "desc",
|
|
1849
|
+
...source.length > 0 ? { source: source.join(",") } : {},
|
|
1850
|
+
...category.length > 0 ? { fileCategory: category.join(",") } : {},
|
|
1851
|
+
...startDate ? { startDate } : {},
|
|
1852
|
+
...endDate ? { endDate } : {},
|
|
1853
|
+
...Object.keys(extra).length > 0 ? { extra } : {}
|
|
1854
|
+
}).then((result) => {
|
|
1855
|
+
if (!active) return;
|
|
1856
|
+
setDocuments(result.documents);
|
|
1857
|
+
setTotal(result.total);
|
|
1858
|
+
}).catch(() => {
|
|
1859
|
+
if (active) setFailed(true);
|
|
1860
|
+
}).finally(() => {
|
|
1861
|
+
if (active) setLoading(false);
|
|
1862
|
+
});
|
|
1863
|
+
return () => {
|
|
1864
|
+
active = false;
|
|
1865
|
+
};
|
|
1866
|
+
}, [fetchAll, debouncedSearch, source, category, startDate, endDate, sortField, sortDirection, page, perPage, extraKey, reloadToken]);
|
|
1867
|
+
useEffect6(() => {
|
|
1868
|
+
setPage(1);
|
|
1869
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
1870
|
+
}, [debouncedSearch, source, category, startDate, endDate, perPage, extraKey]);
|
|
1871
|
+
function toggleSort(field) {
|
|
1872
|
+
if (sortField === field) setSortDirection(sortDirection === "asc" ? "desc" : "asc");
|
|
1873
|
+
else {
|
|
1874
|
+
setSortField(field);
|
|
1875
|
+
setSortDirection("asc");
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
function toggleRow(id) {
|
|
1879
|
+
const next = new Set(selectedIds);
|
|
1880
|
+
if (next.has(id)) next.delete(id);
|
|
1881
|
+
else next.add(id);
|
|
1882
|
+
setSelectedIds(next);
|
|
1883
|
+
}
|
|
1884
|
+
const isAllSelected = documents.length > 0 && documents.every((document2) => selectedIds.has(document2.id));
|
|
1885
|
+
function toggleAll() {
|
|
1886
|
+
setSelectedIds(isAllSelected ? /* @__PURE__ */ new Set() : new Set(documents.map((document2) => document2.id)));
|
|
1887
|
+
}
|
|
1888
|
+
function clearFilters() {
|
|
1889
|
+
setSearch("");
|
|
1890
|
+
setSource([]);
|
|
1891
|
+
setCategory([]);
|
|
1892
|
+
setStartDate("");
|
|
1893
|
+
setEndDate("");
|
|
1894
|
+
setExtra({});
|
|
1895
|
+
}
|
|
1896
|
+
async function handleOpen(uploadId, disposition) {
|
|
1897
|
+
const url = await context?.api.getDocumentUrl(uploadId, disposition);
|
|
1898
|
+
if (url) window.open(url, "_blank", "noopener,noreferrer");
|
|
1899
|
+
}
|
|
1900
|
+
async function handleRemove(ids) {
|
|
1901
|
+
if (!removeDocument) return;
|
|
1902
|
+
setBusy(true);
|
|
1903
|
+
try {
|
|
1904
|
+
await Promise.all(ids.map((id) => removeDocument(id)));
|
|
1905
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
1906
|
+
setReloadToken((token) => token + 1);
|
|
1907
|
+
} finally {
|
|
1908
|
+
setBusy(false);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
async function handleDownloadArchive() {
|
|
1912
|
+
if (!downloadArchive) return;
|
|
1913
|
+
setBusy(true);
|
|
1914
|
+
try {
|
|
1915
|
+
const blob = await downloadArchive(Array.from(selectedIds));
|
|
1916
|
+
const url = URL.createObjectURL(blob);
|
|
1917
|
+
const anchor = document.createElement("a");
|
|
1918
|
+
anchor.href = url;
|
|
1919
|
+
anchor.download = "documentos.zip";
|
|
1920
|
+
anchor.click();
|
|
1921
|
+
URL.revokeObjectURL(url);
|
|
1922
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
1923
|
+
} finally {
|
|
1924
|
+
setBusy(false);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
if (!fetchAll) return null;
|
|
1928
|
+
const direction = sortDirection === "asc" ? "asc" : "desc";
|
|
1929
|
+
const canSelect = Boolean(removeDocument ?? downloadArchive);
|
|
1930
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("space-y-4", classNames?.root, className), children: [
|
|
1931
|
+
/* @__PURE__ */ jsxs14("header", { className: cn("space-y-0.5", classNames?.header), children: [
|
|
1932
|
+
/* @__PURE__ */ jsx16("h2", { className: "text-lg font-semibold", children: labels.title }),
|
|
1933
|
+
/* @__PURE__ */ jsx16("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: labels.subtitle(total) })
|
|
1934
|
+
] }),
|
|
1935
|
+
/* @__PURE__ */ jsxs14("div", { className: cn("flex flex-wrap items-center gap-2", classNames?.filters), children: [
|
|
1936
|
+
/* @__PURE__ */ jsx16(
|
|
1937
|
+
"input",
|
|
1938
|
+
{
|
|
1939
|
+
type: "search",
|
|
1940
|
+
value: search,
|
|
1941
|
+
onChange: (event) => setSearch(event.target.value),
|
|
1942
|
+
placeholder: labels.searchPlaceholder,
|
|
1943
|
+
"aria-label": labels.searchPlaceholder,
|
|
1944
|
+
className: "w-full rounded-md border px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900 sm:w-64"
|
|
1945
|
+
}
|
|
1946
|
+
),
|
|
1947
|
+
/* @__PURE__ */ jsx16(MultiSelectFilter, { label: labels.sourceFilter, options: sourceOptions, selected: source, onChange: setSource }),
|
|
1948
|
+
categoryOptions.length > 0 ? /* @__PURE__ */ jsx16(
|
|
1949
|
+
MultiSelectFilter,
|
|
1950
|
+
{
|
|
1951
|
+
label: labels.categoryFilter,
|
|
1952
|
+
options: categoryOptions,
|
|
1953
|
+
selected: category,
|
|
1954
|
+
onChange: setCategory
|
|
1955
|
+
}
|
|
1956
|
+
) : null,
|
|
1957
|
+
dateFilter ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
1958
|
+
/* @__PURE__ */ jsx16(
|
|
1959
|
+
"input",
|
|
1960
|
+
{
|
|
1961
|
+
type: "date",
|
|
1962
|
+
value: startDate,
|
|
1963
|
+
onChange: (event) => setStartDate(event.target.value),
|
|
1964
|
+
"aria-label": labels.startDate,
|
|
1965
|
+
className: "rounded-md border px-2 py-2 text-xs dark:border-gray-700 dark:bg-gray-900"
|
|
1966
|
+
}
|
|
1967
|
+
),
|
|
1968
|
+
/* @__PURE__ */ jsx16(
|
|
1969
|
+
"input",
|
|
1970
|
+
{
|
|
1971
|
+
type: "date",
|
|
1972
|
+
value: endDate,
|
|
1973
|
+
onChange: (event) => setEndDate(event.target.value),
|
|
1974
|
+
"aria-label": labels.endDate,
|
|
1975
|
+
className: "rounded-md border px-2 py-2 text-xs dark:border-gray-700 dark:bg-gray-900"
|
|
1976
|
+
}
|
|
1977
|
+
)
|
|
1978
|
+
] }) : null,
|
|
1979
|
+
renderFilters?.({ extra, setExtra }),
|
|
1980
|
+
hasFilters ? /* @__PURE__ */ jsxs14("button", { type: "button", onClick: clearFilters, className: "cv-header-action inline-flex items-center gap-1", children: [
|
|
1981
|
+
/* @__PURE__ */ jsx16(X2, { size: 12, "aria-hidden": "true" }),
|
|
1982
|
+
labels.clearFilters
|
|
1983
|
+
] }) : null
|
|
1984
|
+
] }),
|
|
1985
|
+
canSelect ? /* @__PURE__ */ jsxs14(
|
|
1986
|
+
BulkActionBar,
|
|
1987
|
+
{
|
|
1988
|
+
selectedCount: selectedIds.size,
|
|
1989
|
+
selectedLabel: labels.bulkSelected,
|
|
1990
|
+
clearLabel: labels.bulkClear,
|
|
1991
|
+
onClear: () => setSelectedIds(/* @__PURE__ */ new Set()),
|
|
1992
|
+
children: [
|
|
1993
|
+
downloadArchive ? /* @__PURE__ */ jsxs14(
|
|
1994
|
+
"button",
|
|
1995
|
+
{
|
|
1996
|
+
type: "button",
|
|
1997
|
+
onClick: () => void handleDownloadArchive(),
|
|
1998
|
+
disabled: busy,
|
|
1999
|
+
className: "cv-header-action inline-flex items-center gap-1 disabled:opacity-40",
|
|
2000
|
+
children: [
|
|
2001
|
+
/* @__PURE__ */ jsx16(Download, { size: 12, "aria-hidden": "true" }),
|
|
2002
|
+
labels.bulkDownloadZip
|
|
2003
|
+
]
|
|
2004
|
+
}
|
|
2005
|
+
) : null,
|
|
2006
|
+
removeDocument ? /* @__PURE__ */ jsxs14(
|
|
2007
|
+
"button",
|
|
2008
|
+
{
|
|
2009
|
+
type: "button",
|
|
2010
|
+
onClick: () => {
|
|
2011
|
+
if (window.confirm(labels.bulkRemoveConfirm(selectedIds.size))) void handleRemove(Array.from(selectedIds));
|
|
2012
|
+
},
|
|
2013
|
+
disabled: busy,
|
|
2014
|
+
className: "cv-header-action cv-header-action--danger inline-flex items-center gap-1 disabled:opacity-40",
|
|
2015
|
+
children: [
|
|
2016
|
+
/* @__PURE__ */ jsx16(Trash2, { size: 12, "aria-hidden": "true" }),
|
|
2017
|
+
labels.bulkRemove(selectedIds.size)
|
|
2018
|
+
]
|
|
2019
|
+
}
|
|
2020
|
+
) : null
|
|
2021
|
+
]
|
|
2022
|
+
}
|
|
2023
|
+
) : null,
|
|
2024
|
+
loading ? /* @__PURE__ */ jsx16("p", { className: cn("text-sm text-gray-500", classNames?.status), children: labels.loading }) : null,
|
|
2025
|
+
failed ? /* @__PURE__ */ jsx16("p", { role: "alert", className: cn("text-sm text-red-600 dark:text-red-400", classNames?.status), children: labels.failure }) : null,
|
|
2026
|
+
/* @__PURE__ */ jsxs14("div", { className: cn("overflow-x-auto rounded-xl border dark:border-gray-700", classNames?.table), children: [
|
|
2027
|
+
/* @__PURE__ */ jsxs14("table", { className: "w-full text-sm", children: [
|
|
2028
|
+
/* @__PURE__ */ jsx16("thead", { className: "border-b text-gray-500 dark:border-gray-700 dark:text-gray-400", children: /* @__PURE__ */ jsxs14("tr", { children: [
|
|
2029
|
+
canSelect ? /* @__PURE__ */ jsx16("th", { scope: "col", className: "w-10 px-3 py-2", children: /* @__PURE__ */ jsx16(
|
|
2030
|
+
"input",
|
|
2031
|
+
{
|
|
2032
|
+
type: "checkbox",
|
|
2033
|
+
checked: isAllSelected,
|
|
2034
|
+
onChange: toggleAll,
|
|
2035
|
+
"aria-label": labels.selectAllPage,
|
|
2036
|
+
className: "cursor-pointer rounded border-gray-300 text-blue-600 dark:border-gray-600"
|
|
2037
|
+
}
|
|
2038
|
+
) }) : null,
|
|
2039
|
+
/* @__PURE__ */ jsx16(SortableHead, { label: labels.columnFilename, field: "filename", activeField: sortField, direction, onSort: toggleSort }),
|
|
2040
|
+
/* @__PURE__ */ jsx16(SortableHead, { label: labels.columnContact, field: "conversationId", activeField: sortField, direction, onSort: toggleSort, className: "hidden sm:table-cell" }),
|
|
2041
|
+
/* @__PURE__ */ jsx16(SortableHead, { label: labels.columnType, field: "mimeType", activeField: sortField, direction, onSort: toggleSort, className: "hidden md:table-cell" }),
|
|
2042
|
+
/* @__PURE__ */ jsx16(SortableHead, { label: labels.columnSize, field: "sizeBytes", activeField: sortField, direction, onSort: toggleSort, className: "hidden lg:table-cell" }),
|
|
2043
|
+
/* @__PURE__ */ jsx16(SortableHead, { label: labels.columnSource, field: "source", activeField: sortField, direction, onSort: toggleSort, className: "hidden lg:table-cell" }),
|
|
2044
|
+
/* @__PURE__ */ jsx16(SortableHead, { label: labels.columnDate, field: "linkedAt", activeField: sortField, direction, onSort: toggleSort, className: "hidden xl:table-cell" }),
|
|
2045
|
+
/* @__PURE__ */ jsx16("th", { scope: "col", className: "px-3 py-2 text-left text-xs font-medium", children: labels.columnActions })
|
|
2046
|
+
] }) }),
|
|
2047
|
+
/* @__PURE__ */ jsx16("tbody", { children: documents.map((document2) => /* @__PURE__ */ jsxs14("tr", { className: cn("border-b last:border-0 dark:border-gray-800", classNames?.row), children: [
|
|
2048
|
+
canSelect ? /* @__PURE__ */ jsx16("td", { className: "w-10 px-3 py-2", children: /* @__PURE__ */ jsx16(
|
|
2049
|
+
"input",
|
|
2050
|
+
{
|
|
2051
|
+
type: "checkbox",
|
|
2052
|
+
checked: selectedIds.has(document2.id),
|
|
2053
|
+
onChange: () => toggleRow(document2.id),
|
|
2054
|
+
"aria-label": `${labels.selectRow}: ${document2.filename}`,
|
|
2055
|
+
className: "cursor-pointer rounded border-gray-300 text-blue-600 dark:border-gray-600"
|
|
2056
|
+
}
|
|
2057
|
+
) }) : null,
|
|
2058
|
+
/* @__PURE__ */ jsx16("td", { className: "max-w-xs px-3 py-2", children: /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2059
|
+
/* @__PURE__ */ jsx16(FileIcon, { filename: document2.filename, mimeType: document2.mimeType }),
|
|
2060
|
+
/* @__PURE__ */ jsx16("span", { className: "truncate font-medium", title: document2.filename, children: document2.filename })
|
|
2061
|
+
] }) }),
|
|
2062
|
+
/* @__PURE__ */ jsx16("td", { className: "hidden px-3 py-2 sm:table-cell", children: onOpenConversation ? /* @__PURE__ */ jsxs14(
|
|
2063
|
+
"button",
|
|
2064
|
+
{
|
|
2065
|
+
type: "button",
|
|
2066
|
+
onClick: () => onOpenConversation(document2.conversationId),
|
|
2067
|
+
title: labels.openConversation,
|
|
2068
|
+
className: "cv-header-action inline-flex items-center gap-1",
|
|
2069
|
+
children: [
|
|
2070
|
+
/* @__PURE__ */ jsx16(MessageSquare, { size: 12, "aria-hidden": "true" }),
|
|
2071
|
+
document2.contactName ?? formatPhone(document2.conversationId)
|
|
2072
|
+
]
|
|
2073
|
+
}
|
|
2074
|
+
) : /* @__PURE__ */ jsx16("span", { className: "text-xs text-gray-500", children: document2.contactName ?? formatPhone(document2.conversationId) }) }),
|
|
2075
|
+
/* @__PURE__ */ jsx16("td", { className: "hidden px-3 py-2 font-mono text-xs md:table-cell", children: document2.mimeType }),
|
|
2076
|
+
/* @__PURE__ */ jsx16("td", { className: "hidden px-3 py-2 text-xs lg:table-cell", children: formatFileSize(document2.sizeBytes) }),
|
|
2077
|
+
/* @__PURE__ */ jsx16("td", { className: "hidden px-3 py-2 text-xs lg:table-cell", children: labels.sourceLabels[document2.source] ?? document2.source }),
|
|
2078
|
+
/* @__PURE__ */ jsx16("td", { className: "hidden px-3 py-2 text-xs xl:table-cell", children: formatDateTime(document2.linkedAt) }),
|
|
2079
|
+
/* @__PURE__ */ jsx16("td", { className: "px-3 py-2", children: /* @__PURE__ */ jsxs14("div", { className: "flex gap-1", children: [
|
|
2080
|
+
/* @__PURE__ */ jsx16(
|
|
2081
|
+
"button",
|
|
2082
|
+
{
|
|
2083
|
+
type: "button",
|
|
2084
|
+
onClick: () => void handleOpen(document2.id, "inline"),
|
|
2085
|
+
title: labels.view,
|
|
2086
|
+
"aria-label": `${labels.view}: ${document2.filename}`,
|
|
2087
|
+
className: "cv-header-icon",
|
|
2088
|
+
children: /* @__PURE__ */ jsx16(Eye, { size: 14 })
|
|
2089
|
+
}
|
|
2090
|
+
),
|
|
2091
|
+
/* @__PURE__ */ jsx16(
|
|
2092
|
+
"button",
|
|
2093
|
+
{
|
|
2094
|
+
type: "button",
|
|
2095
|
+
onClick: () => void handleOpen(document2.id, "attachment"),
|
|
2096
|
+
title: labels.download,
|
|
2097
|
+
"aria-label": `${labels.download}: ${document2.filename}`,
|
|
2098
|
+
className: "cv-header-icon",
|
|
2099
|
+
children: /* @__PURE__ */ jsx16(Download, { size: 14 })
|
|
2100
|
+
}
|
|
2101
|
+
),
|
|
2102
|
+
removeDocument ? /* @__PURE__ */ jsx16(
|
|
2103
|
+
"button",
|
|
2104
|
+
{
|
|
2105
|
+
type: "button",
|
|
2106
|
+
onClick: () => {
|
|
2107
|
+
if (window.confirm(labels.removeConfirm(document2.filename))) void handleRemove([document2.id]);
|
|
2108
|
+
},
|
|
2109
|
+
disabled: busy,
|
|
2110
|
+
title: labels.remove,
|
|
2111
|
+
"aria-label": `${labels.remove}: ${document2.filename}`,
|
|
2112
|
+
className: "cv-header-icon disabled:opacity-40",
|
|
2113
|
+
children: /* @__PURE__ */ jsx16(Trash2, { size: 14, className: "text-red-500" })
|
|
2114
|
+
}
|
|
2115
|
+
) : null
|
|
2116
|
+
] }) })
|
|
2117
|
+
] }, `${document2.conversationId}:${document2.id}`)) })
|
|
2118
|
+
] }),
|
|
2119
|
+
!loading && documents.length === 0 ? /* @__PURE__ */ jsx16("p", { className: cn("py-8 text-center text-sm text-gray-400", classNames?.status), children: hasFilters ? labels.noResults : labels.empty }) : null
|
|
2120
|
+
] }),
|
|
2121
|
+
/* @__PURE__ */ jsx16(
|
|
2122
|
+
ListingPagination,
|
|
2123
|
+
{
|
|
2124
|
+
page,
|
|
2125
|
+
total,
|
|
2126
|
+
perPage,
|
|
2127
|
+
perPageOptions,
|
|
2128
|
+
onPageChange: setPage,
|
|
2129
|
+
onPerPageChange: setPerPage,
|
|
2130
|
+
labels: {
|
|
2131
|
+
show: labels.show,
|
|
2132
|
+
perPage: labels.perPage,
|
|
2133
|
+
total: labels.total,
|
|
2134
|
+
page: labels.page,
|
|
2135
|
+
previous: labels.previousPage,
|
|
2136
|
+
next: labels.nextPage
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
)
|
|
2140
|
+
] });
|
|
2141
|
+
}
|
|
2142
|
+
|
|
1550
2143
|
// src/conversationTranscript.ts
|
|
1551
2144
|
var SENDER_LABEL = {
|
|
1552
2145
|
customer: "Cliente",
|
|
@@ -1591,7 +2184,7 @@ function downloadTextFile(filename, content) {
|
|
|
1591
2184
|
}
|
|
1592
2185
|
|
|
1593
2186
|
// src/useWaitingNotifications.ts
|
|
1594
|
-
import { useState as
|
|
2187
|
+
import { useState as useState11, useEffect as useEffect7, useRef as useRef4, useCallback as useCallback5 } from "react";
|
|
1595
2188
|
var DEFAULT_POLL_INTERVAL_MS = 1e4;
|
|
1596
2189
|
var DEFAULT_LIMIT = 50;
|
|
1597
2190
|
var DEFAULT_LABELS = {
|
|
@@ -1600,7 +2193,7 @@ var DEFAULT_LABELS = {
|
|
|
1600
2193
|
};
|
|
1601
2194
|
function useWaitingNotifications(params) {
|
|
1602
2195
|
const conversationsContext = useConversations();
|
|
1603
|
-
const [conversations, setConversations] =
|
|
2196
|
+
const [conversations, setConversations] = useState11([]);
|
|
1604
2197
|
const previousUnreadMap = useRef4(/* @__PURE__ */ new Map());
|
|
1605
2198
|
const notifiedIds = useRef4(/* @__PURE__ */ new Set());
|
|
1606
2199
|
const isPollingRef = useRef4(false);
|
|
@@ -1610,7 +2203,7 @@ function useWaitingNotifications(params) {
|
|
|
1610
2203
|
const listParams = params?.params;
|
|
1611
2204
|
const labelTitle = params?.labels?.title ?? DEFAULT_LABELS.title;
|
|
1612
2205
|
const labelBody = params?.labels?.body ?? DEFAULT_LABELS.body;
|
|
1613
|
-
const refresh =
|
|
2206
|
+
const refresh = useCallback5(async () => {
|
|
1614
2207
|
if (!conversationsContext || isPollingRef.current) return;
|
|
1615
2208
|
isPollingRef.current = true;
|
|
1616
2209
|
try {
|
|
@@ -1635,7 +2228,7 @@ function useWaitingNotifications(params) {
|
|
|
1635
2228
|
isPollingRef.current = false;
|
|
1636
2229
|
}
|
|
1637
2230
|
}, [conversationsContext, listParams, icon, labelTitle, labelBody]);
|
|
1638
|
-
|
|
2231
|
+
useEffect7(() => {
|
|
1639
2232
|
if (!isEnabled) return;
|
|
1640
2233
|
if (typeof window !== "undefined" && "Notification" in window && Notification.permission === "default") {
|
|
1641
2234
|
Notification.requestPermission();
|
|
@@ -1649,8 +2242,8 @@ function useWaitingNotifications(params) {
|
|
|
1649
2242
|
}
|
|
1650
2243
|
|
|
1651
2244
|
// src/settings/WhatsAppTemplateSettingsForm.tsx
|
|
1652
|
-
import { Plus, RefreshCw, Save, Trash2 } from "lucide-react";
|
|
1653
|
-
import { jsx as
|
|
2245
|
+
import { Plus, RefreshCw, Save, Trash2 as Trash22 } from "lucide-react";
|
|
2246
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1654
2247
|
var DEFAULT_LABELS2 = {
|
|
1655
2248
|
sectionTitle: "WhatsApp",
|
|
1656
2249
|
sectionDescription: "Template usado para reabrir a janela de 24h com o cliente.",
|
|
@@ -1709,16 +2302,16 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1709
2302
|
}
|
|
1710
2303
|
onVariablesChange([...variables, token]);
|
|
1711
2304
|
}
|
|
1712
|
-
return /* @__PURE__ */
|
|
1713
|
-
/* @__PURE__ */
|
|
1714
|
-
/* @__PURE__ */
|
|
1715
|
-
/* @__PURE__ */
|
|
2305
|
+
return /* @__PURE__ */ jsxs15("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
2306
|
+
/* @__PURE__ */ jsxs15("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: [
|
|
2307
|
+
/* @__PURE__ */ jsx17("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.sectionTitle }),
|
|
2308
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.sectionDescription })
|
|
1716
2309
|
] }),
|
|
1717
|
-
/* @__PURE__ */
|
|
1718
|
-
/* @__PURE__ */
|
|
1719
|
-
/* @__PURE__ */
|
|
1720
|
-
/* @__PURE__ */
|
|
1721
|
-
/* @__PURE__ */
|
|
2310
|
+
/* @__PURE__ */ jsxs15("form", { onSubmit: onSave, className: "p-6 space-y-4", children: [
|
|
2311
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
2312
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
2313
|
+
/* @__PURE__ */ jsx17("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.templateLabel }),
|
|
2314
|
+
/* @__PURE__ */ jsxs15(
|
|
1722
2315
|
"button",
|
|
1723
2316
|
{
|
|
1724
2317
|
type: "button",
|
|
@@ -1726,31 +2319,31 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1726
2319
|
disabled: loadingTemplates,
|
|
1727
2320
|
className: "flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:underline disabled:opacity-50",
|
|
1728
2321
|
children: [
|
|
1729
|
-
/* @__PURE__ */
|
|
2322
|
+
/* @__PURE__ */ jsx17(RefreshCw, { size: 11, className: loadingTemplates ? "animate-spin" : "" }),
|
|
1730
2323
|
labels.refreshList
|
|
1731
2324
|
]
|
|
1732
2325
|
}
|
|
1733
2326
|
)
|
|
1734
2327
|
] }),
|
|
1735
|
-
templatesError && /* @__PURE__ */
|
|
2328
|
+
templatesError && /* @__PURE__ */ jsxs15("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: [
|
|
1736
2329
|
labels.errorLoading,
|
|
1737
|
-
/* @__PURE__ */
|
|
1738
|
-
/* @__PURE__ */
|
|
2330
|
+
/* @__PURE__ */ jsx17("br", {}),
|
|
2331
|
+
/* @__PURE__ */ jsxs15("span", { className: "text-gray-500 dark:text-gray-400 mt-0.5 block", children: [
|
|
1739
2332
|
labels.currentNameSaved,
|
|
1740
2333
|
" ",
|
|
1741
|
-
/* @__PURE__ */
|
|
2334
|
+
/* @__PURE__ */ jsx17("strong", { children: selectedTemplateName || "\u2014" })
|
|
1742
2335
|
] })
|
|
1743
2336
|
] }),
|
|
1744
|
-
loadingTemplates && /* @__PURE__ */
|
|
1745
|
-
!loadingTemplates && !templatesError && /* @__PURE__ */
|
|
2337
|
+
loadingTemplates && /* @__PURE__ */ jsx17("div", { className: "h-10 rounded-xl bg-gray-100 dark:bg-gray-700 animate-pulse" }),
|
|
2338
|
+
!loadingTemplates && !templatesError && /* @__PURE__ */ jsxs15(
|
|
1746
2339
|
"select",
|
|
1747
2340
|
{
|
|
1748
2341
|
value: selectedTemplateName,
|
|
1749
2342
|
onChange: (e) => handleSelect(e.target.value),
|
|
1750
2343
|
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",
|
|
1751
2344
|
children: [
|
|
1752
|
-
/* @__PURE__ */
|
|
1753
|
-
templates.map((template) => /* @__PURE__ */
|
|
2345
|
+
/* @__PURE__ */ jsx17("option", { value: "", children: labels.selectPlaceholder }),
|
|
2346
|
+
templates.map((template) => /* @__PURE__ */ jsxs15("option", { value: template.name, disabled: template.status !== "APPROVED", children: [
|
|
1754
2347
|
template.displayName,
|
|
1755
2348
|
" \xB7 ",
|
|
1756
2349
|
template.shortId,
|
|
@@ -1762,27 +2355,27 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1762
2355
|
]
|
|
1763
2356
|
}
|
|
1764
2357
|
),
|
|
1765
|
-
selected?.bodyText && /* @__PURE__ */
|
|
2358
|
+
selected?.bodyText && /* @__PURE__ */ jsx17("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 })
|
|
1766
2359
|
] }),
|
|
1767
|
-
/* @__PURE__ */
|
|
1768
|
-
/* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
1770
|
-
/* @__PURE__ */
|
|
2360
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
2361
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
2362
|
+
/* @__PURE__ */ jsx17("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.variablesLabel }),
|
|
2363
|
+
/* @__PURE__ */ jsxs15(
|
|
1771
2364
|
"button",
|
|
1772
2365
|
{
|
|
1773
2366
|
type: "button",
|
|
1774
2367
|
onClick: () => onVariablesChange([...variables, ""]),
|
|
1775
2368
|
className: "flex items-center gap-1 text-xs text-blue-600 dark:text-blue-400 hover:underline",
|
|
1776
2369
|
children: [
|
|
1777
|
-
/* @__PURE__ */
|
|
2370
|
+
/* @__PURE__ */ jsx17(Plus, { size: 12 }),
|
|
1778
2371
|
labels.addVariable
|
|
1779
2372
|
]
|
|
1780
2373
|
}
|
|
1781
2374
|
)
|
|
1782
2375
|
] }),
|
|
1783
|
-
availableVariables.length > 0 && /* @__PURE__ */
|
|
1784
|
-
/* @__PURE__ */
|
|
1785
|
-
/* @__PURE__ */
|
|
2376
|
+
availableVariables.length > 0 && /* @__PURE__ */ jsxs15("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: [
|
|
2377
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs font-medium text-gray-600 dark:text-gray-300 mb-1.5", children: labels.variablesAvailableTitle }),
|
|
2378
|
+
/* @__PURE__ */ jsx17("div", { className: "flex flex-wrap gap-1.5", children: availableVariables.map((available) => /* @__PURE__ */ jsxs15(
|
|
1786
2379
|
"button",
|
|
1787
2380
|
{
|
|
1788
2381
|
type: "button",
|
|
@@ -1790,8 +2383,8 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1790
2383
|
title: `Inserir ${available.token}`,
|
|
1791
2384
|
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",
|
|
1792
2385
|
children: [
|
|
1793
|
-
/* @__PURE__ */
|
|
1794
|
-
/* @__PURE__ */
|
|
2386
|
+
/* @__PURE__ */ jsx17("code", { className: "text-blue-600 dark:text-blue-300", children: available.token }),
|
|
2387
|
+
/* @__PURE__ */ jsxs15("span", { className: "text-gray-400 dark:text-gray-500", children: [
|
|
1795
2388
|
"\xB7 ",
|
|
1796
2389
|
available.label
|
|
1797
2390
|
] })
|
|
@@ -1799,13 +2392,13 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1799
2392
|
},
|
|
1800
2393
|
available.token
|
|
1801
2394
|
)) }),
|
|
1802
|
-
/* @__PURE__ */
|
|
2395
|
+
/* @__PURE__ */ jsx17("p", { className: "mt-1.5 text-[11px] text-gray-400 dark:text-gray-500", children: labels.variablesAvailableHint })
|
|
1803
2396
|
] }),
|
|
1804
|
-
/* @__PURE__ */
|
|
1805
|
-
variables.length === 0 && /* @__PURE__ */
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */
|
|
1808
|
-
/* @__PURE__ */
|
|
2397
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-gray-400 dark:text-gray-500 mb-2", children: labels.variablesMappingHint }),
|
|
2398
|
+
variables.length === 0 && /* @__PURE__ */ jsx17("p", { className: "text-xs text-gray-400 dark:text-gray-500 italic", children: labels.noVariables }),
|
|
2399
|
+
/* @__PURE__ */ jsx17("div", { className: "space-y-2", children: variables.map((variable, index) => /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
2400
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs text-gray-400 dark:text-gray-500 w-6 text-right flex-shrink-0", children: `{{${index + 1}}}` }),
|
|
2401
|
+
/* @__PURE__ */ jsx17(
|
|
1809
2402
|
"input",
|
|
1810
2403
|
{
|
|
1811
2404
|
type: "text",
|
|
@@ -1815,27 +2408,27 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1815
2408
|
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"
|
|
1816
2409
|
}
|
|
1817
2410
|
),
|
|
1818
|
-
/* @__PURE__ */
|
|
2411
|
+
/* @__PURE__ */ jsx17(
|
|
1819
2412
|
"button",
|
|
1820
2413
|
{
|
|
1821
2414
|
type: "button",
|
|
1822
2415
|
onClick: () => removeVariable(index),
|
|
1823
2416
|
className: "text-gray-400 hover:text-red-500 dark:hover:text-red-400 transition-colors flex-shrink-0",
|
|
1824
2417
|
title: labels.removeVariable,
|
|
1825
|
-
children: /* @__PURE__ */
|
|
2418
|
+
children: /* @__PURE__ */ jsx17(Trash22, { size: 14 })
|
|
1826
2419
|
}
|
|
1827
2420
|
)
|
|
1828
2421
|
] }, index)) })
|
|
1829
2422
|
] }),
|
|
1830
|
-
saveSuccess && /* @__PURE__ */
|
|
1831
|
-
/* @__PURE__ */
|
|
2423
|
+
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 }),
|
|
2424
|
+
/* @__PURE__ */ jsx17("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs15(
|
|
1832
2425
|
"button",
|
|
1833
2426
|
{
|
|
1834
2427
|
type: "submit",
|
|
1835
2428
|
disabled: saving || !selectedTemplateName.trim(),
|
|
1836
2429
|
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",
|
|
1837
2430
|
children: [
|
|
1838
|
-
saving ? /* @__PURE__ */
|
|
2431
|
+
saving ? /* @__PURE__ */ jsx17("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx17(Save, { size: 14 }),
|
|
1839
2432
|
saving ? labels.saving : labels.save
|
|
1840
2433
|
]
|
|
1841
2434
|
}
|
|
@@ -1846,7 +2439,7 @@ function WhatsAppTemplateSettingsForm({
|
|
|
1846
2439
|
|
|
1847
2440
|
// src/settings/WhatsAppCreateTemplateForm.tsx
|
|
1848
2441
|
import { SendHorizonal as SendHorizonal2 } from "lucide-react";
|
|
1849
|
-
import { jsx as
|
|
2442
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1850
2443
|
var DEFAULT_LABELS3 = {
|
|
1851
2444
|
sectionTitle: "Criar novo template",
|
|
1852
2445
|
sectionDescription: "Envia um template para aprova\xE7\xE3o da Meta.",
|
|
@@ -1903,16 +2496,16 @@ function WhatsAppCreateTemplateForm({
|
|
|
1903
2496
|
function set(key, next) {
|
|
1904
2497
|
onChange({ ...value, [key]: next });
|
|
1905
2498
|
}
|
|
1906
|
-
return /* @__PURE__ */
|
|
1907
|
-
/* @__PURE__ */
|
|
1908
|
-
/* @__PURE__ */
|
|
1909
|
-
/* @__PURE__ */
|
|
2499
|
+
return /* @__PURE__ */ jsxs16("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
2500
|
+
/* @__PURE__ */ jsxs16("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: [
|
|
2501
|
+
/* @__PURE__ */ jsx18("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.sectionTitle }),
|
|
2502
|
+
/* @__PURE__ */ jsx18("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.sectionDescription })
|
|
1910
2503
|
] }),
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
/* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
1914
|
-
/* @__PURE__ */
|
|
1915
|
-
/* @__PURE__ */
|
|
2504
|
+
/* @__PURE__ */ jsxs16("form", { onSubmit, className: "p-6 space-y-4", children: [
|
|
2505
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2506
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.nameLabel }),
|
|
2507
|
+
/* @__PURE__ */ jsx18("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.nameHint }),
|
|
2508
|
+
/* @__PURE__ */ jsx18(
|
|
1916
2509
|
"input",
|
|
1917
2510
|
{
|
|
1918
2511
|
type: "text",
|
|
@@ -1924,56 +2517,56 @@ function WhatsAppCreateTemplateForm({
|
|
|
1924
2517
|
}
|
|
1925
2518
|
)
|
|
1926
2519
|
] }),
|
|
1927
|
-
/* @__PURE__ */
|
|
1928
|
-
/* @__PURE__ */
|
|
1929
|
-
/* @__PURE__ */
|
|
1930
|
-
/* @__PURE__ */
|
|
2520
|
+
/* @__PURE__ */ jsxs16("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
2521
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2522
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.categoryLabel }),
|
|
2523
|
+
/* @__PURE__ */ jsxs16(
|
|
1931
2524
|
"select",
|
|
1932
2525
|
{
|
|
1933
2526
|
value: value.category,
|
|
1934
2527
|
onChange: (e) => set("category", e.target.value),
|
|
1935
2528
|
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",
|
|
1936
2529
|
children: [
|
|
1937
|
-
/* @__PURE__ */
|
|
1938
|
-
/* @__PURE__ */
|
|
2530
|
+
/* @__PURE__ */ jsx18("option", { value: "UTILITY", children: "UTILITY (Transacional)" }),
|
|
2531
|
+
/* @__PURE__ */ jsx18("option", { value: "MARKETING", children: "MARKETING (Promocional)" })
|
|
1939
2532
|
]
|
|
1940
2533
|
}
|
|
1941
2534
|
)
|
|
1942
2535
|
] }),
|
|
1943
|
-
/* @__PURE__ */
|
|
1944
|
-
/* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
2536
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2537
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.languageLabel }),
|
|
2538
|
+
/* @__PURE__ */ jsxs16(
|
|
1946
2539
|
"select",
|
|
1947
2540
|
{
|
|
1948
2541
|
value: value.language,
|
|
1949
2542
|
onChange: (e) => set("language", e.target.value),
|
|
1950
2543
|
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",
|
|
1951
2544
|
children: [
|
|
1952
|
-
/* @__PURE__ */
|
|
1953
|
-
/* @__PURE__ */
|
|
1954
|
-
/* @__PURE__ */
|
|
2545
|
+
/* @__PURE__ */ jsx18("option", { value: "pt_BR", children: "Portugu\xEAs (Brasil)" }),
|
|
2546
|
+
/* @__PURE__ */ jsx18("option", { value: "en_US", children: "Ingl\xEAs (EUA)" }),
|
|
2547
|
+
/* @__PURE__ */ jsx18("option", { value: "es_ES", children: "Espanhol" })
|
|
1955
2548
|
]
|
|
1956
2549
|
}
|
|
1957
2550
|
)
|
|
1958
2551
|
] })
|
|
1959
2552
|
] }),
|
|
1960
|
-
/* @__PURE__ */
|
|
1961
|
-
/* @__PURE__ */
|
|
1962
|
-
/* @__PURE__ */
|
|
1963
|
-
/* @__PURE__ */
|
|
1964
|
-
/* @__PURE__ */
|
|
2553
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2554
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.headerLabel }),
|
|
2555
|
+
/* @__PURE__ */ jsx18("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.headerHint }),
|
|
2556
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex gap-2", children: [
|
|
2557
|
+
/* @__PURE__ */ jsxs16(
|
|
1965
2558
|
"select",
|
|
1966
2559
|
{
|
|
1967
2560
|
value: value.headerType,
|
|
1968
2561
|
onChange: (e) => set("headerType", e.target.value),
|
|
1969
2562
|
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",
|
|
1970
2563
|
children: [
|
|
1971
|
-
/* @__PURE__ */
|
|
1972
|
-
/* @__PURE__ */
|
|
2564
|
+
/* @__PURE__ */ jsx18("option", { value: "NONE", children: labels.headerNone }),
|
|
2565
|
+
/* @__PURE__ */ jsx18("option", { value: "TEXT", children: labels.headerText })
|
|
1973
2566
|
]
|
|
1974
2567
|
}
|
|
1975
2568
|
),
|
|
1976
|
-
value.headerType === "TEXT" && /* @__PURE__ */
|
|
2569
|
+
value.headerType === "TEXT" && /* @__PURE__ */ jsx18(
|
|
1977
2570
|
"input",
|
|
1978
2571
|
{
|
|
1979
2572
|
type: "text",
|
|
@@ -1986,10 +2579,10 @@ function WhatsAppCreateTemplateForm({
|
|
|
1986
2579
|
)
|
|
1987
2580
|
] })
|
|
1988
2581
|
] }),
|
|
1989
|
-
/* @__PURE__ */
|
|
1990
|
-
/* @__PURE__ */
|
|
1991
|
-
/* @__PURE__ */
|
|
1992
|
-
/* @__PURE__ */
|
|
2582
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2583
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.bodyLabel }),
|
|
2584
|
+
/* @__PURE__ */ jsx18("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.bodyHint }),
|
|
2585
|
+
/* @__PURE__ */ jsx18(
|
|
1993
2586
|
"textarea",
|
|
1994
2587
|
{
|
|
1995
2588
|
value: value.bodyText,
|
|
@@ -2000,26 +2593,26 @@ function WhatsAppCreateTemplateForm({
|
|
|
2000
2593
|
required: true
|
|
2001
2594
|
}
|
|
2002
2595
|
),
|
|
2003
|
-
detectedVariables.length > 0 && /* @__PURE__ */
|
|
2004
|
-
/* @__PURE__ */
|
|
2005
|
-
/* @__PURE__ */
|
|
2006
|
-
/* @__PURE__ */
|
|
2007
|
-
/* @__PURE__ */
|
|
2596
|
+
detectedVariables.length > 0 && /* @__PURE__ */ jsxs16("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: [
|
|
2597
|
+
/* @__PURE__ */ jsx18("p", { className: "font-medium text-gray-500 dark:text-gray-400 mb-1.5 uppercase tracking-wide text-xs", children: labels.detectedVariables }),
|
|
2598
|
+
/* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-2", children: detectedVariables.map((num) => /* @__PURE__ */ jsxs16("span", { className: "inline-flex items-center gap-1 text-xs", children: [
|
|
2599
|
+
/* @__PURE__ */ jsx18("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}}}` }),
|
|
2600
|
+
/* @__PURE__ */ jsxs16("span", { className: "text-gray-400 dark:text-gray-500", children: [
|
|
2008
2601
|
"= ",
|
|
2009
2602
|
variableExamples[Number(num) - 1] ?? labels.variableLabel(Number(num))
|
|
2010
2603
|
] })
|
|
2011
2604
|
] }, num)) }),
|
|
2012
|
-
/* @__PURE__ */
|
|
2605
|
+
/* @__PURE__ */ jsxs16("p", { className: "text-gray-400 dark:text-gray-500 mt-1.5 text-xs", children: [
|
|
2013
2606
|
labels.configureHintPrefix,
|
|
2014
|
-
/* @__PURE__ */
|
|
2607
|
+
/* @__PURE__ */ jsx18("strong", { children: labels.configureHintLink }),
|
|
2015
2608
|
labels.configureHintSuffix
|
|
2016
2609
|
] })
|
|
2017
2610
|
] })
|
|
2018
2611
|
] }),
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
2022
|
-
/* @__PURE__ */
|
|
2612
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2613
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.footerLabel }),
|
|
2614
|
+
/* @__PURE__ */ jsx18("p", { className: "text-xs text-gray-400 mb-1.5", children: labels.footerHint }),
|
|
2615
|
+
/* @__PURE__ */ jsx18(
|
|
2023
2616
|
"input",
|
|
2024
2617
|
{
|
|
2025
2618
|
type: "text",
|
|
@@ -2031,48 +2624,48 @@ function WhatsAppCreateTemplateForm({
|
|
|
2031
2624
|
}
|
|
2032
2625
|
)
|
|
2033
2626
|
] }),
|
|
2034
|
-
/* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2036
|
-
/* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2038
|
-
/* @__PURE__ */
|
|
2039
|
-
/* @__PURE__ */
|
|
2040
|
-
/* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2627
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2628
|
+
/* @__PURE__ */ jsx18("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block", children: labels.previewLabel }),
|
|
2629
|
+
/* @__PURE__ */ jsxs16("div", { className: "rounded-2xl bg-[#e5ddd5] dark:bg-[#1a1a2e] border border-gray-300 dark:border-gray-600 overflow-hidden shadow-inner", children: [
|
|
2630
|
+
/* @__PURE__ */ jsxs16("div", { className: "bg-[#075e54] px-4 py-2.5 flex items-center gap-2", children: [
|
|
2631
|
+
/* @__PURE__ */ jsx18("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() }),
|
|
2632
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2633
|
+
/* @__PURE__ */ jsx18("p", { className: "text-white text-xs font-semibold leading-tight", children: previewCompanyName }),
|
|
2634
|
+
/* @__PURE__ */ jsx18("p", { className: "text-white/60 text-xs", children: labels.previewOnline })
|
|
2042
2635
|
] })
|
|
2043
2636
|
] }),
|
|
2044
|
-
/* @__PURE__ */
|
|
2045
|
-
/* @__PURE__ */
|
|
2046
|
-
/* @__PURE__ */
|
|
2047
|
-
/* @__PURE__ */
|
|
2637
|
+
/* @__PURE__ */ jsxs16("div", { className: "px-3 py-4 space-y-3", style: { minHeight: "120px" }, children: [
|
|
2638
|
+
/* @__PURE__ */ jsx18("div", { className: "flex justify-start", style: { maxWidth: "85%" }, children: /* @__PURE__ */ jsxs16("div", { className: "bg-white dark:bg-gray-700 rounded-lg rounded-tl-none px-3 py-2 shadow-sm", children: [
|
|
2639
|
+
/* @__PURE__ */ jsx18("p", { className: "text-gray-500 dark:text-gray-400 leading-tight text-sm", children: labels.previewDescription }),
|
|
2640
|
+
/* @__PURE__ */ jsx18("p", { className: "text-gray-400 dark:text-gray-500 mt-1 text-right text-[9px]", children: "12:00" })
|
|
2048
2641
|
] }) }),
|
|
2049
|
-
/* @__PURE__ */
|
|
2050
|
-
value.headerType === "TEXT" && value.headerText && /* @__PURE__ */
|
|
2051
|
-
/* @__PURE__ */
|
|
2052
|
-
value.footerText && /* @__PURE__ */
|
|
2053
|
-
/* @__PURE__ */
|
|
2642
|
+
/* @__PURE__ */ jsx18("div", { className: "flex justify-end ml-auto", style: { maxWidth: "85%" }, children: /* @__PURE__ */ jsxs16("div", { className: "bg-[#dcf8c6] dark:bg-[#1b5e20] rounded-lg rounded-tr-none px-3 py-2 shadow-sm", children: [
|
|
2643
|
+
value.headerType === "TEXT" && value.headerText && /* @__PURE__ */ jsx18("p", { className: "text-xs font-bold text-gray-700 dark:text-gray-200 mb-1", children: fillPreviewTokens(value.headerText) || labels.previewHeaderFallback }),
|
|
2644
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sm text-gray-800 dark:text-gray-100 leading-relaxed", children: value.bodyText ? fillPreviewTokens(value.bodyText) : /* @__PURE__ */ jsx18("span", { className: "text-gray-400 italic", children: labels.previewBodyPlaceholder }) }),
|
|
2645
|
+
value.footerText && /* @__PURE__ */ jsx18("p", { className: "text-gray-400 dark:text-gray-400 mt-1 text-xs", children: value.footerText }),
|
|
2646
|
+
/* @__PURE__ */ jsx18("p", { className: "text-gray-400 dark:text-gray-400 mt-1 text-right text-[9px]", children: "12:01 \u2713" })
|
|
2054
2647
|
] }) })
|
|
2055
2648
|
] })
|
|
2056
2649
|
] })
|
|
2057
2650
|
] }),
|
|
2058
|
-
result && /* @__PURE__ */
|
|
2651
|
+
result && /* @__PURE__ */ jsxs16(
|
|
2059
2652
|
"div",
|
|
2060
2653
|
{
|
|
2061
2654
|
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"}`,
|
|
2062
2655
|
children: [
|
|
2063
2656
|
result.message,
|
|
2064
|
-
result.ok && result.status && /* @__PURE__ */
|
|
2657
|
+
result.ok && result.status && /* @__PURE__ */ jsx18("p", { className: "text-xs mt-1 opacity-75", children: labels.successStatus(result.status) })
|
|
2065
2658
|
]
|
|
2066
2659
|
}
|
|
2067
2660
|
),
|
|
2068
|
-
/* @__PURE__ */
|
|
2661
|
+
/* @__PURE__ */ jsx18("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs16(
|
|
2069
2662
|
"button",
|
|
2070
2663
|
{
|
|
2071
2664
|
type: "submit",
|
|
2072
2665
|
disabled: submitting || !value.name || !value.bodyText,
|
|
2073
2666
|
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",
|
|
2074
2667
|
children: [
|
|
2075
|
-
submitting ? /* @__PURE__ */
|
|
2668
|
+
submitting ? /* @__PURE__ */ jsx18("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx18(SendHorizonal2, { size: 14 }),
|
|
2076
2669
|
submitting ? labels.sending : labels.sendForApproval
|
|
2077
2670
|
]
|
|
2078
2671
|
}
|
|
@@ -2083,7 +2676,7 @@ function WhatsAppCreateTemplateForm({
|
|
|
2083
2676
|
|
|
2084
2677
|
// src/settings/WelcomeFarewellForm.tsx
|
|
2085
2678
|
import { LogOut, Mail, Save as Save2 } from "lucide-react";
|
|
2086
|
-
import { jsx as
|
|
2679
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2087
2680
|
var DEFAULT_LABELS4 = {
|
|
2088
2681
|
sectionTitle: "Boas-vindas e encerramento",
|
|
2089
2682
|
welcomeMessage: "Mensagem de boas-vindas",
|
|
@@ -2111,15 +2704,15 @@ function WelcomeFarewellForm({
|
|
|
2111
2704
|
labels: labelsOverride
|
|
2112
2705
|
}) {
|
|
2113
2706
|
const labels = { ...DEFAULT_LABELS4, ...labelsOverride };
|
|
2114
|
-
return /* @__PURE__ */
|
|
2115
|
-
/* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2117
|
-
/* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
2119
|
-
/* @__PURE__ */
|
|
2707
|
+
return /* @__PURE__ */ jsxs17("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
2708
|
+
/* @__PURE__ */ jsx19("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: /* @__PURE__ */ jsx19("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: labels.sectionTitle }) }),
|
|
2709
|
+
/* @__PURE__ */ jsxs17("form", { onSubmit: onSave, className: "p-6 space-y-5", children: [
|
|
2710
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
2711
|
+
/* @__PURE__ */ jsxs17("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5 flex items-center gap-1.5", children: [
|
|
2712
|
+
/* @__PURE__ */ jsx19(Mail, { size: 13, className: "text-blue-600 dark:text-blue-400" }),
|
|
2120
2713
|
labels.welcomeMessage
|
|
2121
2714
|
] }),
|
|
2122
|
-
/* @__PURE__ */
|
|
2715
|
+
/* @__PURE__ */ jsx19(
|
|
2123
2716
|
WhatsAppMessageEditor,
|
|
2124
2717
|
{
|
|
2125
2718
|
value: welcomeMessage,
|
|
@@ -2128,14 +2721,14 @@ function WelcomeFarewellForm({
|
|
|
2128
2721
|
placeholders: welcomePlaceholders
|
|
2129
2722
|
}
|
|
2130
2723
|
),
|
|
2131
|
-
/* @__PURE__ */
|
|
2724
|
+
/* @__PURE__ */ jsx19("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: labels.welcomeMessageHint })
|
|
2132
2725
|
] }),
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2726
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
2727
|
+
/* @__PURE__ */ jsxs17("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5 flex items-center gap-1.5", children: [
|
|
2728
|
+
/* @__PURE__ */ jsx19(LogOut, { size: 13, className: "text-blue-600 dark:text-blue-400" }),
|
|
2136
2729
|
labels.farewellMessage
|
|
2137
2730
|
] }),
|
|
2138
|
-
/* @__PURE__ */
|
|
2731
|
+
/* @__PURE__ */ jsx19(
|
|
2139
2732
|
WhatsAppMessageEditor,
|
|
2140
2733
|
{
|
|
2141
2734
|
value: farewellMessage,
|
|
@@ -2144,17 +2737,17 @@ function WelcomeFarewellForm({
|
|
|
2144
2737
|
placeholders: farewellPlaceholders
|
|
2145
2738
|
}
|
|
2146
2739
|
),
|
|
2147
|
-
/* @__PURE__ */
|
|
2740
|
+
/* @__PURE__ */ jsx19("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: labels.farewellMessageHint })
|
|
2148
2741
|
] }),
|
|
2149
|
-
saveSuccess && /* @__PURE__ */
|
|
2150
|
-
/* @__PURE__ */
|
|
2742
|
+
saveSuccess && /* @__PURE__ */ jsx19("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 }),
|
|
2743
|
+
/* @__PURE__ */ jsx19("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs17(
|
|
2151
2744
|
"button",
|
|
2152
2745
|
{
|
|
2153
2746
|
type: "submit",
|
|
2154
2747
|
disabled: saving,
|
|
2155
2748
|
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",
|
|
2156
2749
|
children: [
|
|
2157
|
-
saving ? /* @__PURE__ */
|
|
2750
|
+
saving ? /* @__PURE__ */ jsx19("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx19(Save2, { size: 14 }),
|
|
2158
2751
|
saving ? labels.saving : labels.save
|
|
2159
2752
|
]
|
|
2160
2753
|
}
|
|
@@ -2165,7 +2758,7 @@ function WelcomeFarewellForm({
|
|
|
2165
2758
|
|
|
2166
2759
|
// src/settings/TranscriptionSettingsForm.tsx
|
|
2167
2760
|
import { AudioLines, Save as Save3 } from "lucide-react";
|
|
2168
|
-
import { jsx as
|
|
2761
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2169
2762
|
var DEFAULT_LABELS5 = {
|
|
2170
2763
|
sectionTitle: "Transcri\xE7\xE3o de \xE1udio",
|
|
2171
2764
|
enabled: "Transcrever notas de voz",
|
|
@@ -2192,15 +2785,15 @@ function TranscriptionSettingsForm({
|
|
|
2192
2785
|
labels: labelsOverride
|
|
2193
2786
|
}) {
|
|
2194
2787
|
const labels = { ...DEFAULT_LABELS5, ...labelsOverride };
|
|
2195
|
-
return /* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2788
|
+
return /* @__PURE__ */ jsxs18("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
2789
|
+
/* @__PURE__ */ jsx20("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: /* @__PURE__ */ jsxs18("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-1.5", children: [
|
|
2790
|
+
/* @__PURE__ */ jsx20(AudioLines, { size: 14, className: "text-blue-600 dark:text-blue-400" }),
|
|
2198
2791
|
labels.sectionTitle
|
|
2199
2792
|
] }) }),
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
!isAvailable && /* @__PURE__ */
|
|
2202
|
-
/* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2793
|
+
/* @__PURE__ */ jsxs18("form", { onSubmit: onSave, className: "p-6 space-y-5", children: [
|
|
2794
|
+
!isAvailable && /* @__PURE__ */ jsx20("div", { className: "bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800 rounded-xl px-4 py-3 text-sm text-amber-800 dark:text-amber-300", children: labels.unavailable }),
|
|
2795
|
+
/* @__PURE__ */ jsxs18("label", { className: "flex items-start gap-3 cursor-pointer", children: [
|
|
2796
|
+
/* @__PURE__ */ jsx20(
|
|
2204
2797
|
"input",
|
|
2205
2798
|
{
|
|
2206
2799
|
type: "checkbox",
|
|
@@ -2210,14 +2803,14 @@ function TranscriptionSettingsForm({
|
|
|
2210
2803
|
className: "mt-0.5 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 disabled:opacity-50"
|
|
2211
2804
|
}
|
|
2212
2805
|
),
|
|
2213
|
-
/* @__PURE__ */
|
|
2214
|
-
/* @__PURE__ */
|
|
2215
|
-
/* @__PURE__ */
|
|
2806
|
+
/* @__PURE__ */ jsxs18("span", { children: [
|
|
2807
|
+
/* @__PURE__ */ jsx20("span", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: labels.enabled }),
|
|
2808
|
+
/* @__PURE__ */ jsx20("span", { className: "block text-xs text-gray-500 dark:text-gray-400", children: labels.enabledHint })
|
|
2216
2809
|
] })
|
|
2217
2810
|
] }),
|
|
2218
|
-
enabled && /* @__PURE__ */
|
|
2219
|
-
/* @__PURE__ */
|
|
2220
|
-
/* @__PURE__ */
|
|
2811
|
+
enabled && /* @__PURE__ */ jsxs18("fieldset", { disabled: !isAvailable, className: "space-y-2.5", children: [
|
|
2812
|
+
/* @__PURE__ */ jsx20("legend", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: labels.modeTitle }),
|
|
2813
|
+
/* @__PURE__ */ jsx20(
|
|
2221
2814
|
ModeOption,
|
|
2222
2815
|
{
|
|
2223
2816
|
value: "onDemand",
|
|
@@ -2227,7 +2820,7 @@ function TranscriptionSettingsForm({
|
|
|
2227
2820
|
hint: labels.modeOnDemandHint
|
|
2228
2821
|
}
|
|
2229
2822
|
),
|
|
2230
|
-
/* @__PURE__ */
|
|
2823
|
+
/* @__PURE__ */ jsx20(
|
|
2231
2824
|
ModeOption,
|
|
2232
2825
|
{
|
|
2233
2826
|
value: "auto",
|
|
@@ -2238,15 +2831,15 @@ function TranscriptionSettingsForm({
|
|
|
2238
2831
|
}
|
|
2239
2832
|
)
|
|
2240
2833
|
] }),
|
|
2241
|
-
saveSuccess && /* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2834
|
+
saveSuccess && /* @__PURE__ */ jsx20("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 }),
|
|
2835
|
+
/* @__PURE__ */ jsx20("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs18(
|
|
2243
2836
|
"button",
|
|
2244
2837
|
{
|
|
2245
2838
|
type: "submit",
|
|
2246
2839
|
disabled: saving || !isAvailable,
|
|
2247
2840
|
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",
|
|
2248
2841
|
children: [
|
|
2249
|
-
saving ? /* @__PURE__ */
|
|
2842
|
+
saving ? /* @__PURE__ */ jsx20("span", { className: "w-4 h-4 border-2 border-white/40 border-t-white rounded-full animate-spin" }) : /* @__PURE__ */ jsx20(Save3, { size: 14 }),
|
|
2250
2843
|
saving ? labels.saving : labels.save
|
|
2251
2844
|
]
|
|
2252
2845
|
}
|
|
@@ -2262,12 +2855,12 @@ function ModeOption({
|
|
|
2262
2855
|
hint
|
|
2263
2856
|
}) {
|
|
2264
2857
|
const isSelected = current === value;
|
|
2265
|
-
return /* @__PURE__ */
|
|
2858
|
+
return /* @__PURE__ */ jsxs18(
|
|
2266
2859
|
"label",
|
|
2267
2860
|
{
|
|
2268
2861
|
className: `flex items-start gap-3 cursor-pointer rounded-xl border px-4 py-3 transition-colors ${isSelected ? "border-blue-500 bg-blue-50 dark:border-blue-500 dark:bg-blue-950/30" : "border-gray-200 hover:border-gray-300 dark:border-gray-700 dark:hover:border-gray-600"}`,
|
|
2269
2862
|
children: [
|
|
2270
|
-
/* @__PURE__ */
|
|
2863
|
+
/* @__PURE__ */ jsx20(
|
|
2271
2864
|
"input",
|
|
2272
2865
|
{
|
|
2273
2866
|
type: "radio",
|
|
@@ -2278,9 +2871,9 @@ function ModeOption({
|
|
|
2278
2871
|
className: "mt-0.5 h-4 w-4 border-gray-300 text-blue-600 focus:ring-blue-500"
|
|
2279
2872
|
}
|
|
2280
2873
|
),
|
|
2281
|
-
/* @__PURE__ */
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
/* @__PURE__ */
|
|
2874
|
+
/* @__PURE__ */ jsxs18("span", { children: [
|
|
2875
|
+
/* @__PURE__ */ jsx20("span", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: title }),
|
|
2876
|
+
/* @__PURE__ */ jsx20("span", { className: "block text-xs text-gray-500 dark:text-gray-400", children: hint })
|
|
2284
2877
|
] })
|
|
2285
2878
|
]
|
|
2286
2879
|
}
|
|
@@ -2288,8 +2881,8 @@ function ModeOption({
|
|
|
2288
2881
|
}
|
|
2289
2882
|
|
|
2290
2883
|
// src/settings/WhatsAppTemplatesSettings.tsx
|
|
2291
|
-
import { useState as
|
|
2292
|
-
import { jsx as
|
|
2884
|
+
import { useState as useState12 } from "react";
|
|
2885
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2293
2886
|
var TEMPLATE_SETTINGS_TAB = {
|
|
2294
2887
|
SELECT: "select",
|
|
2295
2888
|
CREATE: "create"
|
|
@@ -2300,14 +2893,15 @@ var DEFAULT_TEMPLATES_SETTINGS_LABELS = {
|
|
|
2300
2893
|
};
|
|
2301
2894
|
function WhatsAppTemplatesSettings({
|
|
2302
2895
|
labels: labelsOverride,
|
|
2896
|
+
settingsLabels,
|
|
2303
2897
|
create,
|
|
2304
2898
|
...settingsProps
|
|
2305
2899
|
}) {
|
|
2306
2900
|
const labels = { ...DEFAULT_TEMPLATES_SETTINGS_LABELS, ...labelsOverride };
|
|
2307
|
-
const [tab, setTab] =
|
|
2308
|
-
return /* @__PURE__ */
|
|
2309
|
-
/* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2901
|
+
const [tab, setTab] = useState12(TEMPLATE_SETTINGS_TAB.SELECT);
|
|
2902
|
+
return /* @__PURE__ */ jsxs19("div", { className: "space-y-4", children: [
|
|
2903
|
+
/* @__PURE__ */ jsxs19("nav", { className: "flex gap-1 border-b", role: "tablist", children: [
|
|
2904
|
+
/* @__PURE__ */ jsx21(
|
|
2311
2905
|
"button",
|
|
2312
2906
|
{
|
|
2313
2907
|
type: "button",
|
|
@@ -2318,7 +2912,7 @@ function WhatsAppTemplatesSettings({
|
|
|
2318
2912
|
children: labels.selectTab
|
|
2319
2913
|
}
|
|
2320
2914
|
),
|
|
2321
|
-
create ? /* @__PURE__ */
|
|
2915
|
+
create ? /* @__PURE__ */ jsx21(
|
|
2322
2916
|
"button",
|
|
2323
2917
|
{
|
|
2324
2918
|
type: "button",
|
|
@@ -2330,13 +2924,13 @@ function WhatsAppTemplatesSettings({
|
|
|
2330
2924
|
}
|
|
2331
2925
|
) : null
|
|
2332
2926
|
] }),
|
|
2333
|
-
tab === TEMPLATE_SETTINGS_TAB.SELECT ? /* @__PURE__ */
|
|
2927
|
+
tab === TEMPLATE_SETTINGS_TAB.SELECT ? /* @__PURE__ */ jsx21(WhatsAppTemplateSettingsForm, { ...settingsProps, ...settingsLabels ? { labels: settingsLabels } : {} }) : create ? /* @__PURE__ */ jsx21(WhatsAppCreateTemplateForm, { ...create }) : null
|
|
2334
2928
|
] });
|
|
2335
2929
|
}
|
|
2336
2930
|
|
|
2337
2931
|
// src/settings/TopicsForm.tsx
|
|
2338
2932
|
import { Megaphone, Save as Save4 } from "lucide-react";
|
|
2339
|
-
import { jsx as
|
|
2933
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2340
2934
|
var DEFAULT_LABELS6 = {
|
|
2341
2935
|
sectionTitle: "T\xF3picos intermedi\xE1rios",
|
|
2342
2936
|
sectionDescription: "Mensagens autom\xE1ticas para assuntos espec\xEDficos, disparadas quando o cliente demonstra interesse.",
|
|
@@ -2354,19 +2948,19 @@ function TopicsForm({
|
|
|
2354
2948
|
labels: labelsOverride
|
|
2355
2949
|
}) {
|
|
2356
2950
|
const labels = { ...DEFAULT_LABELS6, ...labelsOverride };
|
|
2357
|
-
return /* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2951
|
+
return /* @__PURE__ */ jsxs20("section", { className: "bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden", children: [
|
|
2952
|
+
/* @__PURE__ */ jsxs20("div", { className: "px-6 py-4 border-b border-gray-100 dark:border-gray-700", children: [
|
|
2953
|
+
/* @__PURE__ */ jsxs20("h2", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2", children: [
|
|
2954
|
+
/* @__PURE__ */ jsx22(Megaphone, { size: 16, className: "text-orange-600 dark:text-orange-400" }),
|
|
2361
2955
|
labels.sectionTitle
|
|
2362
2956
|
] }),
|
|
2363
|
-
/* @__PURE__ */
|
|
2957
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: labels.sectionDescription })
|
|
2364
2958
|
] }),
|
|
2365
|
-
/* @__PURE__ */
|
|
2366
|
-
topics.map((topic) => /* @__PURE__ */
|
|
2367
|
-
/* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
/* @__PURE__ */
|
|
2959
|
+
/* @__PURE__ */ jsxs20("form", { onSubmit: onSave, className: "p-6 space-y-6", children: [
|
|
2960
|
+
topics.map((topic) => /* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
|
|
2961
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-start gap-4", children: [
|
|
2962
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1", children: /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: topic.label }) }),
|
|
2963
|
+
/* @__PURE__ */ jsx22(
|
|
2370
2964
|
"button",
|
|
2371
2965
|
{
|
|
2372
2966
|
type: "button",
|
|
@@ -2374,7 +2968,7 @@ function TopicsForm({
|
|
|
2374
2968
|
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"}`,
|
|
2375
2969
|
role: "switch",
|
|
2376
2970
|
"aria-checked": topic.enabled,
|
|
2377
|
-
children: /* @__PURE__ */
|
|
2971
|
+
children: /* @__PURE__ */ jsx22(
|
|
2378
2972
|
"span",
|
|
2379
2973
|
{
|
|
2380
2974
|
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"}`
|
|
@@ -2383,7 +2977,7 @@ function TopicsForm({
|
|
|
2383
2977
|
}
|
|
2384
2978
|
)
|
|
2385
2979
|
] }),
|
|
2386
|
-
/* @__PURE__ */
|
|
2980
|
+
/* @__PURE__ */ jsx22(
|
|
2387
2981
|
"textarea",
|
|
2388
2982
|
{
|
|
2389
2983
|
value: topic.message,
|
|
@@ -2395,27 +2989,330 @@ function TopicsForm({
|
|
|
2395
2989
|
}
|
|
2396
2990
|
)
|
|
2397
2991
|
] }, topic.key)),
|
|
2398
|
-
/* @__PURE__ */
|
|
2399
|
-
/* @__PURE__ */
|
|
2992
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3", children: [
|
|
2993
|
+
/* @__PURE__ */ jsxs20(
|
|
2400
2994
|
"button",
|
|
2401
2995
|
{
|
|
2402
2996
|
type: "submit",
|
|
2403
2997
|
disabled: saving,
|
|
2404
2998
|
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",
|
|
2405
2999
|
children: [
|
|
2406
|
-
/* @__PURE__ */
|
|
3000
|
+
/* @__PURE__ */ jsx22(Save4, { size: 14 }),
|
|
2407
3001
|
labels.saveButton
|
|
2408
3002
|
]
|
|
2409
3003
|
}
|
|
2410
3004
|
),
|
|
2411
|
-
saveSuccess && /* @__PURE__ */
|
|
3005
|
+
saveSuccess && /* @__PURE__ */ jsx22("span", { className: "text-sm text-green-600 dark:text-green-400", children: labels.saveSuccess })
|
|
2412
3006
|
] })
|
|
2413
3007
|
] })
|
|
2414
3008
|
] });
|
|
2415
3009
|
}
|
|
2416
3010
|
|
|
3011
|
+
// src/settings/MessagesWorkspace.tsx
|
|
3012
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useState as useState13 } from "react";
|
|
3013
|
+
import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3014
|
+
var DEFAULT_LABELS7 = {
|
|
3015
|
+
title: "Mensagens",
|
|
3016
|
+
subtitle: "Mensagens do bot e templates do WhatsApp.",
|
|
3017
|
+
loading: "Carregando configura\xE7\xF5es\u2026",
|
|
3018
|
+
loadError: "N\xE3o foi poss\xEDvel carregar as configura\xE7\xF5es de mensagens.",
|
|
3019
|
+
tabBot: "Mensagens do Bot",
|
|
3020
|
+
tabTemplates: "Templates WhatsApp",
|
|
3021
|
+
tabTranscription: "Transcri\xE7\xE3o de \xE1udio",
|
|
3022
|
+
welcomeFarewell: {},
|
|
3023
|
+
topics: {},
|
|
3024
|
+
templates: {},
|
|
3025
|
+
templateSettings: {},
|
|
3026
|
+
createTemplate: {},
|
|
3027
|
+
transcription: {}
|
|
3028
|
+
};
|
|
3029
|
+
var MESSAGES_TAB = {
|
|
3030
|
+
BOT: "bot",
|
|
3031
|
+
TEMPLATES: "templates",
|
|
3032
|
+
TRANSCRIPTION: "transcription"
|
|
3033
|
+
};
|
|
3034
|
+
var EMPTY_MESSAGES = { welcomeMessage: "", farewellMessage: "" };
|
|
3035
|
+
var EMPTY_TEMPLATE_SETTINGS = {
|
|
3036
|
+
templateName: "",
|
|
3037
|
+
templateLanguage: "pt_BR",
|
|
3038
|
+
variables: []
|
|
3039
|
+
};
|
|
3040
|
+
var EMPTY_CREATE_TEMPLATE = {
|
|
3041
|
+
name: "",
|
|
3042
|
+
category: "UTILITY",
|
|
3043
|
+
language: "pt_BR",
|
|
3044
|
+
headerType: "NONE",
|
|
3045
|
+
headerText: "",
|
|
3046
|
+
bodyText: "",
|
|
3047
|
+
footerText: ""
|
|
3048
|
+
};
|
|
3049
|
+
var UNDECIDED_TRANSCRIPTION = {
|
|
3050
|
+
enabled: false,
|
|
3051
|
+
mode: "onDemand",
|
|
3052
|
+
available: false
|
|
3053
|
+
};
|
|
3054
|
+
var SAVE_FEEDBACK_MS = 3e3;
|
|
3055
|
+
function MessagesWorkspace({
|
|
3056
|
+
api,
|
|
3057
|
+
labels: labelsOverride,
|
|
3058
|
+
welcomePlaceholders,
|
|
3059
|
+
farewellPlaceholders,
|
|
3060
|
+
availableVariables,
|
|
3061
|
+
renderTemplatesNotice,
|
|
3062
|
+
className
|
|
3063
|
+
}) {
|
|
3064
|
+
const labels = { ...DEFAULT_LABELS7, ...labelsOverride };
|
|
3065
|
+
const hasTopics = Boolean(api.getTopics && api.saveTopics);
|
|
3066
|
+
const hasTemplates = Boolean(api.getTemplateSettings && api.saveTemplateSettings);
|
|
3067
|
+
const hasTranscription = Boolean(api.getTranscription && api.saveTranscription);
|
|
3068
|
+
const [tab, setTab] = useState13(MESSAGES_TAB.BOT);
|
|
3069
|
+
const [loadState, setLoadState] = useState13("loading");
|
|
3070
|
+
const [messages, setMessages] = useState13(EMPTY_MESSAGES);
|
|
3071
|
+
const [savingMessages, setSavingMessages] = useState13(false);
|
|
3072
|
+
const [messagesSaved, setMessagesSaved] = useState13(false);
|
|
3073
|
+
const [topics, setTopics] = useState13([]);
|
|
3074
|
+
const [savingTopics, setSavingTopics] = useState13(false);
|
|
3075
|
+
const [topicsSaved, setTopicsSaved] = useState13(false);
|
|
3076
|
+
const [templateSettings, setTemplateSettings] = useState13(EMPTY_TEMPLATE_SETTINGS);
|
|
3077
|
+
const [templates, setTemplates] = useState13([]);
|
|
3078
|
+
const [loadingTemplates, setLoadingTemplates] = useState13(false);
|
|
3079
|
+
const [templatesError, setTemplatesError] = useState13(false);
|
|
3080
|
+
const [savingTemplate, setSavingTemplate] = useState13(false);
|
|
3081
|
+
const [templateSaved, setTemplateSaved] = useState13(false);
|
|
3082
|
+
const [createTemplate, setCreateTemplate] = useState13(EMPTY_CREATE_TEMPLATE);
|
|
3083
|
+
const [creatingTemplate, setCreatingTemplate] = useState13(false);
|
|
3084
|
+
const [createResult, setCreateResult] = useState13(null);
|
|
3085
|
+
const [transcription, setTranscription] = useState13(UNDECIDED_TRANSCRIPTION);
|
|
3086
|
+
const [savingTranscription, setSavingTranscription] = useState13(false);
|
|
3087
|
+
const [transcriptionSaved, setTranscriptionSaved] = useState13(false);
|
|
3088
|
+
const reloadTemplates = useCallback6(async () => {
|
|
3089
|
+
if (!api.listTemplates) return;
|
|
3090
|
+
setLoadingTemplates(true);
|
|
3091
|
+
setTemplatesError(false);
|
|
3092
|
+
try {
|
|
3093
|
+
setTemplates(await api.listTemplates());
|
|
3094
|
+
} catch {
|
|
3095
|
+
setTemplatesError(true);
|
|
3096
|
+
} finally {
|
|
3097
|
+
setLoadingTemplates(false);
|
|
3098
|
+
}
|
|
3099
|
+
}, [api]);
|
|
3100
|
+
useEffect8(() => {
|
|
3101
|
+
let active = true;
|
|
3102
|
+
async function load() {
|
|
3103
|
+
try {
|
|
3104
|
+
const [loadedMessages, loadedTopics, loadedTemplateSettings, loadedTranscription] = await Promise.all([
|
|
3105
|
+
api.getMessages(),
|
|
3106
|
+
api.getTopics?.(),
|
|
3107
|
+
api.getTemplateSettings?.(),
|
|
3108
|
+
api.getTranscription?.()
|
|
3109
|
+
]);
|
|
3110
|
+
if (!active) return;
|
|
3111
|
+
setMessages(loadedMessages);
|
|
3112
|
+
if (loadedTopics) setTopics(loadedTopics);
|
|
3113
|
+
if (loadedTemplateSettings) setTemplateSettings(loadedTemplateSettings);
|
|
3114
|
+
if (loadedTranscription) setTranscription(loadedTranscription);
|
|
3115
|
+
setLoadState("ready");
|
|
3116
|
+
} catch {
|
|
3117
|
+
if (active) setLoadState("error");
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
void load();
|
|
3121
|
+
return () => {
|
|
3122
|
+
active = false;
|
|
3123
|
+
};
|
|
3124
|
+
}, [api]);
|
|
3125
|
+
useEffect8(() => {
|
|
3126
|
+
void reloadTemplates();
|
|
3127
|
+
}, [reloadTemplates]);
|
|
3128
|
+
function flash(setter) {
|
|
3129
|
+
setter(true);
|
|
3130
|
+
setTimeout(() => setter(false), SAVE_FEEDBACK_MS);
|
|
3131
|
+
}
|
|
3132
|
+
async function handleSaveMessages(event) {
|
|
3133
|
+
event.preventDefault();
|
|
3134
|
+
setSavingMessages(true);
|
|
3135
|
+
try {
|
|
3136
|
+
await api.saveMessages(messages);
|
|
3137
|
+
flash(setMessagesSaved);
|
|
3138
|
+
} finally {
|
|
3139
|
+
setSavingMessages(false);
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
async function handleSaveTopics(event) {
|
|
3143
|
+
event.preventDefault();
|
|
3144
|
+
if (!api.saveTopics) return;
|
|
3145
|
+
setSavingTopics(true);
|
|
3146
|
+
try {
|
|
3147
|
+
await api.saveTopics(topics);
|
|
3148
|
+
flash(setTopicsSaved);
|
|
3149
|
+
} finally {
|
|
3150
|
+
setSavingTopics(false);
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
async function handleSaveTemplate(event) {
|
|
3154
|
+
event.preventDefault();
|
|
3155
|
+
if (!api.saveTemplateSettings) return;
|
|
3156
|
+
setSavingTemplate(true);
|
|
3157
|
+
try {
|
|
3158
|
+
await api.saveTemplateSettings(templateSettings);
|
|
3159
|
+
flash(setTemplateSaved);
|
|
3160
|
+
} finally {
|
|
3161
|
+
setSavingTemplate(false);
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
async function handleCreateTemplate(event) {
|
|
3165
|
+
event.preventDefault();
|
|
3166
|
+
if (!api.createTemplate) return;
|
|
3167
|
+
setCreatingTemplate(true);
|
|
3168
|
+
setCreateResult(null);
|
|
3169
|
+
try {
|
|
3170
|
+
const result = await api.createTemplate(createTemplate);
|
|
3171
|
+
setCreateResult(result);
|
|
3172
|
+
if (result.ok) {
|
|
3173
|
+
setCreateTemplate(EMPTY_CREATE_TEMPLATE);
|
|
3174
|
+
void reloadTemplates();
|
|
3175
|
+
}
|
|
3176
|
+
} catch (error) {
|
|
3177
|
+
setCreateResult({ ok: false, message: error instanceof Error ? error.message : "" });
|
|
3178
|
+
} finally {
|
|
3179
|
+
setCreatingTemplate(false);
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
async function handleSaveTranscription(event) {
|
|
3183
|
+
event.preventDefault();
|
|
3184
|
+
if (!api.saveTranscription) return;
|
|
3185
|
+
setSavingTranscription(true);
|
|
3186
|
+
try {
|
|
3187
|
+
await api.saveTranscription({ enabled: transcription.enabled, mode: transcription.mode });
|
|
3188
|
+
flash(setTranscriptionSaved);
|
|
3189
|
+
} finally {
|
|
3190
|
+
setSavingTranscription(false);
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
function handleSelectTemplate(name, template) {
|
|
3194
|
+
setTemplateSettings((previous) => {
|
|
3195
|
+
if (!template) return { ...previous, templateName: name };
|
|
3196
|
+
const shouldSeedVariables = template.variableCount > 0 && previous.variables.length === 0;
|
|
3197
|
+
return {
|
|
3198
|
+
templateName: name,
|
|
3199
|
+
templateLanguage: template.language,
|
|
3200
|
+
variables: shouldSeedVariables ? Array.from({ length: template.variableCount }, () => "") : previous.variables
|
|
3201
|
+
};
|
|
3202
|
+
});
|
|
3203
|
+
}
|
|
3204
|
+
if (loadState === "loading") {
|
|
3205
|
+
return /* @__PURE__ */ jsx23("p", { className: "p-6 text-sm text-gray-500 dark:text-gray-400", children: labels.loading });
|
|
3206
|
+
}
|
|
3207
|
+
if (loadState === "error") {
|
|
3208
|
+
return /* @__PURE__ */ jsx23("p", { role: "alert", className: "p-6 text-sm text-red-600 dark:text-red-400", children: labels.loadError });
|
|
3209
|
+
}
|
|
3210
|
+
const tabs = [
|
|
3211
|
+
{ id: MESSAGES_TAB.BOT, label: labels.tabBot },
|
|
3212
|
+
...hasTemplates ? [{ id: MESSAGES_TAB.TEMPLATES, label: labels.tabTemplates }] : [],
|
|
3213
|
+
...hasTranscription ? [{ id: MESSAGES_TAB.TRANSCRIPTION, label: labels.tabTranscription }] : []
|
|
3214
|
+
];
|
|
3215
|
+
return /* @__PURE__ */ jsxs21("div", { className: `space-y-6 p-4 lg:p-0 ${className ?? ""}`, children: [
|
|
3216
|
+
/* @__PURE__ */ jsxs21("header", { children: [
|
|
3217
|
+
/* @__PURE__ */ jsx23("h1", { className: "text-xl font-semibold text-gray-900 dark:text-gray-100", children: labels.title }),
|
|
3218
|
+
/* @__PURE__ */ jsx23("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: labels.subtitle })
|
|
3219
|
+
] }),
|
|
3220
|
+
tabs.length > 1 ? /* @__PURE__ */ jsx23("nav", { className: "flex gap-1 border-b border-gray-200 dark:border-gray-700", role: "tablist", children: tabs.map((item) => /* @__PURE__ */ jsx23(
|
|
3221
|
+
"button",
|
|
3222
|
+
{
|
|
3223
|
+
type: "button",
|
|
3224
|
+
role: "tab",
|
|
3225
|
+
"aria-selected": tab === item.id,
|
|
3226
|
+
onClick: () => setTab(item.id),
|
|
3227
|
+
className: `-mb-px border-b-2 px-4 py-2.5 text-sm font-medium transition-colors ${tab === item.id ? "border-blue-600 text-blue-700 dark:border-blue-400 dark:text-blue-400" : "border-transparent text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200"}`,
|
|
3228
|
+
children: item.label
|
|
3229
|
+
},
|
|
3230
|
+
item.id
|
|
3231
|
+
)) }) : null,
|
|
3232
|
+
tab === MESSAGES_TAB.BOT ? /* @__PURE__ */ jsxs21("div", { className: "space-y-8", children: [
|
|
3233
|
+
/* @__PURE__ */ jsx23(
|
|
3234
|
+
WelcomeFarewellForm,
|
|
3235
|
+
{
|
|
3236
|
+
welcomeMessage: messages.welcomeMessage,
|
|
3237
|
+
onWelcomeMessageChange: (welcomeMessage) => setMessages((previous) => ({ ...previous, welcomeMessage })),
|
|
3238
|
+
farewellMessage: messages.farewellMessage,
|
|
3239
|
+
onFarewellMessageChange: (farewellMessage) => setMessages((previous) => ({ ...previous, farewellMessage })),
|
|
3240
|
+
onSave: handleSaveMessages,
|
|
3241
|
+
saving: savingMessages,
|
|
3242
|
+
saveSuccess: messagesSaved,
|
|
3243
|
+
labels: labels.welcomeFarewell,
|
|
3244
|
+
...welcomePlaceholders ? { welcomePlaceholders } : {},
|
|
3245
|
+
...farewellPlaceholders ? { farewellPlaceholders } : {}
|
|
3246
|
+
}
|
|
3247
|
+
),
|
|
3248
|
+
hasTopics ? /* @__PURE__ */ jsx23(
|
|
3249
|
+
TopicsForm,
|
|
3250
|
+
{
|
|
3251
|
+
topics,
|
|
3252
|
+
onToggle: (key) => setTopics(
|
|
3253
|
+
(previous) => previous.map((topic) => topic.key === key ? { ...topic, enabled: !topic.enabled } : topic)
|
|
3254
|
+
),
|
|
3255
|
+
onMessageChange: (key, message) => setTopics(
|
|
3256
|
+
(previous) => previous.map((topic) => topic.key === key ? { ...topic, message } : topic)
|
|
3257
|
+
),
|
|
3258
|
+
onSave: handleSaveTopics,
|
|
3259
|
+
saving: savingTopics,
|
|
3260
|
+
saveSuccess: topicsSaved,
|
|
3261
|
+
labels: labels.topics
|
|
3262
|
+
}
|
|
3263
|
+
) : null
|
|
3264
|
+
] }) : null,
|
|
3265
|
+
tab === MESSAGES_TAB.TEMPLATES ? /* @__PURE__ */ jsxs21("div", { className: "space-y-4", children: [
|
|
3266
|
+
renderTemplatesNotice?.(),
|
|
3267
|
+
/* @__PURE__ */ jsx23(
|
|
3268
|
+
WhatsAppTemplatesSettings,
|
|
3269
|
+
{
|
|
3270
|
+
templates,
|
|
3271
|
+
loadingTemplates,
|
|
3272
|
+
templatesError,
|
|
3273
|
+
selectedTemplateName: templateSettings.templateName,
|
|
3274
|
+
onSelectTemplate: handleSelectTemplate,
|
|
3275
|
+
variables: templateSettings.variables,
|
|
3276
|
+
onVariablesChange: (variables) => setTemplateSettings((previous) => ({ ...previous, variables })),
|
|
3277
|
+
onSave: handleSaveTemplate,
|
|
3278
|
+
saving: savingTemplate,
|
|
3279
|
+
saveSuccess: templateSaved,
|
|
3280
|
+
labels: labels.templates,
|
|
3281
|
+
settingsLabels: labels.templateSettings,
|
|
3282
|
+
...api.listTemplates ? { onRefreshTemplates: () => void reloadTemplates() } : {},
|
|
3283
|
+
...availableVariables ? { availableVariables } : {},
|
|
3284
|
+
...api.createTemplate ? {
|
|
3285
|
+
create: {
|
|
3286
|
+
value: createTemplate,
|
|
3287
|
+
onChange: setCreateTemplate,
|
|
3288
|
+
onSubmit: handleCreateTemplate,
|
|
3289
|
+
submitting: creatingTemplate,
|
|
3290
|
+
result: createResult,
|
|
3291
|
+
labels: labels.createTemplate
|
|
3292
|
+
}
|
|
3293
|
+
} : {}
|
|
3294
|
+
}
|
|
3295
|
+
)
|
|
3296
|
+
] }) : null,
|
|
3297
|
+
tab === MESSAGES_TAB.TRANSCRIPTION ? /* @__PURE__ */ jsx23(
|
|
3298
|
+
TranscriptionSettingsForm,
|
|
3299
|
+
{
|
|
3300
|
+
enabled: transcription.enabled,
|
|
3301
|
+
onEnabledChange: (enabled) => setTranscription((previous) => ({ ...previous, enabled })),
|
|
3302
|
+
mode: transcription.mode,
|
|
3303
|
+
onModeChange: (mode) => setTranscription((previous) => ({ ...previous, mode })),
|
|
3304
|
+
onSave: handleSaveTranscription,
|
|
3305
|
+
isAvailable: transcription.available,
|
|
3306
|
+
saving: savingTranscription,
|
|
3307
|
+
saveSuccess: transcriptionSaved,
|
|
3308
|
+
labels: labels.transcription
|
|
3309
|
+
}
|
|
3310
|
+
) : null
|
|
3311
|
+
] });
|
|
3312
|
+
}
|
|
3313
|
+
|
|
2417
3314
|
// src/hooks/useConversationMessages.ts
|
|
2418
|
-
import { useCallback as
|
|
3315
|
+
import { useCallback as useCallback7 } from "react";
|
|
2419
3316
|
function useConversationMessages(conversationId, params) {
|
|
2420
3317
|
const context = useConversations();
|
|
2421
3318
|
if (!context) {
|
|
@@ -2426,7 +3323,7 @@ function useConversationMessages(conversationId, params) {
|
|
|
2426
3323
|
() => api.fetchMessages(conversationId, params),
|
|
2427
3324
|
[conversationId, params?.limit, params?.before]
|
|
2428
3325
|
);
|
|
2429
|
-
const sendMessage =
|
|
3326
|
+
const sendMessage = useCallback7(
|
|
2430
3327
|
async (text) => {
|
|
2431
3328
|
const message = await api.sendMessage(conversationId, text);
|
|
2432
3329
|
await refetch();
|
|
@@ -2434,7 +3331,7 @@ function useConversationMessages(conversationId, params) {
|
|
|
2434
3331
|
},
|
|
2435
3332
|
[api, conversationId, refetch]
|
|
2436
3333
|
);
|
|
2437
|
-
const sendMedia =
|
|
3334
|
+
const sendMedia = useCallback7(
|
|
2438
3335
|
async (mediaData) => {
|
|
2439
3336
|
const message = await api.sendMedia(conversationId, mediaData);
|
|
2440
3337
|
await refetch();
|
|
@@ -2442,19 +3339,19 @@ function useConversationMessages(conversationId, params) {
|
|
|
2442
3339
|
},
|
|
2443
3340
|
[api, conversationId, refetch]
|
|
2444
3341
|
);
|
|
2445
|
-
const sendTemplate =
|
|
3342
|
+
const sendTemplate = useCallback7(
|
|
2446
3343
|
async (templateData) => {
|
|
2447
3344
|
await api.sendTemplate(conversationId, templateData);
|
|
2448
3345
|
await refetch();
|
|
2449
3346
|
},
|
|
2450
3347
|
[api, conversationId, refetch]
|
|
2451
3348
|
);
|
|
2452
|
-
const markRead =
|
|
3349
|
+
const markRead = useCallback7(() => api.markRead(conversationId), [api, conversationId]);
|
|
2453
3350
|
return { messages: data ?? [], loading, error, refetch, sendMessage, sendMedia, sendTemplate, markRead };
|
|
2454
3351
|
}
|
|
2455
3352
|
|
|
2456
3353
|
// src/hooks/useScrollToLatestMessage.ts
|
|
2457
|
-
import { useCallback as
|
|
3354
|
+
import { useCallback as useCallback8, useLayoutEffect, useRef as useRef5, useState as useState14 } from "react";
|
|
2458
3355
|
var NEAR_BOTTOM_THRESHOLD_PX = 120;
|
|
2459
3356
|
var SCROLL_BEHAVIOR = "auto";
|
|
2460
3357
|
function useScrollToLatestMessage({
|
|
@@ -2462,14 +3359,14 @@ function useScrollToLatestMessage({
|
|
|
2462
3359
|
messageCount
|
|
2463
3360
|
}) {
|
|
2464
3361
|
const containerRef = useRef5(null);
|
|
2465
|
-
const [isAwayFromBottom, setIsAwayFromBottom] =
|
|
3362
|
+
const [isAwayFromBottom, setIsAwayFromBottom] = useState14(false);
|
|
2466
3363
|
const isAwayFromBottomRef = useRef5(false);
|
|
2467
|
-
const scrollToBottom =
|
|
3364
|
+
const scrollToBottom = useCallback8((behavior = SCROLL_BEHAVIOR) => {
|
|
2468
3365
|
const container = containerRef.current;
|
|
2469
3366
|
if (!container) return;
|
|
2470
3367
|
container.scrollTo({ top: container.scrollHeight, behavior });
|
|
2471
3368
|
}, []);
|
|
2472
|
-
const handleScroll =
|
|
3369
|
+
const handleScroll = useCallback8((event) => {
|
|
2473
3370
|
const target = event.currentTarget;
|
|
2474
3371
|
const distanceFromBottom = target.scrollHeight - target.scrollTop - target.clientHeight;
|
|
2475
3372
|
const away = distanceFromBottom > NEAR_BOTTOM_THRESHOLD_PX;
|
|
@@ -2523,12 +3420,12 @@ function useConversationContext(conversationId) {
|
|
|
2523
3420
|
}
|
|
2524
3421
|
|
|
2525
3422
|
// src/hooks/useConversationRealtime.ts
|
|
2526
|
-
import { useEffect as
|
|
3423
|
+
import { useEffect as useEffect9, useRef as useRef6 } from "react";
|
|
2527
3424
|
function useConversationRealtime(conversationId, onEvent) {
|
|
2528
3425
|
const context = useConversations();
|
|
2529
3426
|
const onEventRef = useRef6(onEvent);
|
|
2530
3427
|
onEventRef.current = onEvent;
|
|
2531
|
-
|
|
3428
|
+
useEffect9(() => {
|
|
2532
3429
|
if (!context || !conversationId) return;
|
|
2533
3430
|
const source = context.sse.connectConversationStream(conversationId);
|
|
2534
3431
|
const handler = (event) => onEventRef.current(event);
|
|
@@ -2543,7 +3440,7 @@ function useGlobalRealtime(onEvent) {
|
|
|
2543
3440
|
const context = useConversations();
|
|
2544
3441
|
const onEventRef = useRef6(onEvent);
|
|
2545
3442
|
onEventRef.current = onEvent;
|
|
2546
|
-
|
|
3443
|
+
useEffect9(() => {
|
|
2547
3444
|
if (!context) return;
|
|
2548
3445
|
const source = context.sse.connectGlobalStream();
|
|
2549
3446
|
const handler = (event) => onEventRef.current(event);
|
|
@@ -2556,14 +3453,14 @@ function useGlobalRealtime(onEvent) {
|
|
|
2556
3453
|
}
|
|
2557
3454
|
|
|
2558
3455
|
// src/hooks/useConversationActions.ts
|
|
2559
|
-
import { useMemo as
|
|
3456
|
+
import { useMemo as useMemo3 } from "react";
|
|
2560
3457
|
function useConversationActions(conversationId) {
|
|
2561
3458
|
const context = useConversations();
|
|
2562
3459
|
if (!context) {
|
|
2563
3460
|
throw new Error("useConversationActions requires an ancestor <ConversationsProvider>");
|
|
2564
3461
|
}
|
|
2565
3462
|
const { api } = context;
|
|
2566
|
-
return
|
|
3463
|
+
return useMemo3(
|
|
2567
3464
|
() => ({
|
|
2568
3465
|
takeover: api.takeover ? () => api.takeover(conversationId) : void 0,
|
|
2569
3466
|
release: api.release ? () => api.release(conversationId) : void 0,
|
|
@@ -2578,7 +3475,7 @@ function useInboxActions() {
|
|
|
2578
3475
|
throw new Error("useInboxActions requires an ancestor <ConversationsProvider>");
|
|
2579
3476
|
}
|
|
2580
3477
|
const { api } = context;
|
|
2581
|
-
return
|
|
3478
|
+
return useMemo3(
|
|
2582
3479
|
() => ({
|
|
2583
3480
|
markAllRead: api.markAllRead ? () => api.markAllRead() : void 0,
|
|
2584
3481
|
listTemplates: api.listTemplates ? () => api.listTemplates() : void 0
|
|
@@ -2588,11 +3485,11 @@ function useInboxActions() {
|
|
|
2588
3485
|
}
|
|
2589
3486
|
|
|
2590
3487
|
// src/workspace/ConversationsWorkspace.tsx
|
|
2591
|
-
import { useEffect as
|
|
3488
|
+
import { useEffect as useEffect13, useMemo as useMemo6, useState as useState18 } from "react";
|
|
2592
3489
|
|
|
2593
3490
|
// src/workspace/BulkTemplateModal.tsx
|
|
2594
|
-
import { useEffect as
|
|
2595
|
-
import { jsx as
|
|
3491
|
+
import { useEffect as useEffect10, useMemo as useMemo4, useState as useState15 } from "react";
|
|
3492
|
+
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2596
3493
|
function BulkTemplateModal({
|
|
2597
3494
|
labels,
|
|
2598
3495
|
expiredCount,
|
|
@@ -2605,10 +3502,10 @@ function BulkTemplateModal({
|
|
|
2605
3502
|
throw new Error("BulkTemplateModal requires an ancestor <ConversationsProvider>");
|
|
2606
3503
|
}
|
|
2607
3504
|
const { api } = context;
|
|
2608
|
-
const [templates, setTemplates] =
|
|
2609
|
-
const [search, setSearch] =
|
|
2610
|
-
const [selected, setSelected] =
|
|
2611
|
-
|
|
3505
|
+
const [templates, setTemplates] = useState15([]);
|
|
3506
|
+
const [search, setSearch] = useState15("");
|
|
3507
|
+
const [selected, setSelected] = useState15("");
|
|
3508
|
+
useEffect10(() => {
|
|
2612
3509
|
let active = true;
|
|
2613
3510
|
void api.listTemplates?.().then((loaded) => {
|
|
2614
3511
|
if (active) setTemplates(loaded);
|
|
@@ -2618,20 +3515,20 @@ function BulkTemplateModal({
|
|
|
2618
3515
|
active = false;
|
|
2619
3516
|
};
|
|
2620
3517
|
}, [api]);
|
|
2621
|
-
const filtered =
|
|
3518
|
+
const filtered = useMemo4(() => {
|
|
2622
3519
|
const term = search.trim().toLowerCase();
|
|
2623
3520
|
if (!term) return templates;
|
|
2624
3521
|
return templates.filter((template) => template.name.toLowerCase().includes(term));
|
|
2625
3522
|
}, [templates, search]);
|
|
2626
|
-
return /* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2628
|
-
/* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
3523
|
+
return /* @__PURE__ */ jsx24("div", { className: "cv-workspace-modal", role: "dialog", "aria-modal": "true", "aria-label": labels.templateModalTitle, children: /* @__PURE__ */ jsxs22("div", { className: "cv-workspace-modal__box", children: [
|
|
3524
|
+
/* @__PURE__ */ jsxs22("header", { className: "cv-workspace-modal__header", children: [
|
|
3525
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
3526
|
+
/* @__PURE__ */ jsx24("h3", { children: labels.templateModalTitle }),
|
|
3527
|
+
/* @__PURE__ */ jsx24("p", { children: labels.templateModalAvailable(templates.length) })
|
|
2631
3528
|
] }),
|
|
2632
|
-
/* @__PURE__ */
|
|
3529
|
+
/* @__PURE__ */ jsx24("button", { type: "button", onClick: onClose, "aria-label": labels.templateModalCancel, children: "\u2715" })
|
|
2633
3530
|
] }),
|
|
2634
|
-
/* @__PURE__ */
|
|
3531
|
+
/* @__PURE__ */ jsx24("div", { className: "cv-workspace-modal__search", children: /* @__PURE__ */ jsx24(
|
|
2635
3532
|
"input",
|
|
2636
3533
|
{
|
|
2637
3534
|
type: "search",
|
|
@@ -2641,9 +3538,9 @@ function BulkTemplateModal({
|
|
|
2641
3538
|
autoFocus: true
|
|
2642
3539
|
}
|
|
2643
3540
|
) }),
|
|
2644
|
-
/* @__PURE__ */
|
|
2645
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
2646
|
-
filtered.map((template) => /* @__PURE__ */
|
|
3541
|
+
/* @__PURE__ */ jsxs22("div", { className: "cv-workspace-modal__list", children: [
|
|
3542
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx24("p", { className: "cv-workspace-empty", children: labels.templateModalEmpty }) : null,
|
|
3543
|
+
filtered.map((template) => /* @__PURE__ */ jsxs22(
|
|
2647
3544
|
"button",
|
|
2648
3545
|
{
|
|
2649
3546
|
type: "button",
|
|
@@ -2651,8 +3548,8 @@ function BulkTemplateModal({
|
|
|
2651
3548
|
"aria-pressed": template.name === selected,
|
|
2652
3549
|
className: `cv-workspace-modal__item${template.name === selected ? " cv-workspace-modal__item--on" : ""}`,
|
|
2653
3550
|
children: [
|
|
2654
|
-
/* @__PURE__ */
|
|
2655
|
-
/* @__PURE__ */
|
|
3551
|
+
/* @__PURE__ */ jsx24("span", { className: "cv-workspace-modal__item-name", children: template.name }),
|
|
3552
|
+
/* @__PURE__ */ jsxs22("span", { className: "cv-workspace-modal__item-meta", children: [
|
|
2656
3553
|
template.language,
|
|
2657
3554
|
template.category ? ` \xB7 ${template.category.toLowerCase()}` : ""
|
|
2658
3555
|
] })
|
|
@@ -2661,10 +3558,10 @@ function BulkTemplateModal({
|
|
|
2661
3558
|
template.name
|
|
2662
3559
|
))
|
|
2663
3560
|
] }),
|
|
2664
|
-
expiredCount === 0 ? /* @__PURE__ */
|
|
2665
|
-
/* @__PURE__ */
|
|
2666
|
-
/* @__PURE__ */
|
|
2667
|
-
/* @__PURE__ */
|
|
3561
|
+
expiredCount === 0 ? /* @__PURE__ */ jsx24("p", { className: "cv-workspace-modal__warning", children: labels.templateModalNoneExpired }) : null,
|
|
3562
|
+
/* @__PURE__ */ jsxs22("footer", { className: "cv-workspace-modal__footer", children: [
|
|
3563
|
+
/* @__PURE__ */ jsx24("button", { type: "button", onClick: onClose, children: labels.templateModalCancel }),
|
|
3564
|
+
/* @__PURE__ */ jsx24(
|
|
2668
3565
|
"button",
|
|
2669
3566
|
{
|
|
2670
3567
|
type: "button",
|
|
@@ -2678,8 +3575,8 @@ function BulkTemplateModal({
|
|
|
2678
3575
|
}
|
|
2679
3576
|
|
|
2680
3577
|
// src/workspace/ConversationPane.tsx
|
|
2681
|
-
import { useEffect as
|
|
2682
|
-
import { jsx as
|
|
3578
|
+
import { useEffect as useEffect11, useState as useState16 } from "react";
|
|
3579
|
+
import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2683
3580
|
function ConversationPane({
|
|
2684
3581
|
conversation,
|
|
2685
3582
|
now,
|
|
@@ -2699,7 +3596,11 @@ function ConversationPane({
|
|
|
2699
3596
|
messageSelection,
|
|
2700
3597
|
initialComposerText,
|
|
2701
3598
|
renderAboveTranscript,
|
|
2702
|
-
onAttach
|
|
3599
|
+
onAttach,
|
|
3600
|
+
composer = "simple",
|
|
3601
|
+
composerVariablesFor,
|
|
3602
|
+
onSendAttachments,
|
|
3603
|
+
onRecordAudio
|
|
2703
3604
|
}) {
|
|
2704
3605
|
const context = useConversations();
|
|
2705
3606
|
if (!context) {
|
|
@@ -2708,13 +3609,15 @@ function ConversationPane({
|
|
|
2708
3609
|
const { api } = context;
|
|
2709
3610
|
const { messages, refetch } = useConversationMessages(conversation.id);
|
|
2710
3611
|
const { context: conversationContext } = useConversationContext(conversation.id);
|
|
2711
|
-
const [documentsOpen, setDocumentsOpen] =
|
|
2712
|
-
const [sendFailure, setSendFailure] =
|
|
2713
|
-
const [selectedMessageIds, setSelectedMessageIds] =
|
|
2714
|
-
const [draft, setDraft] =
|
|
2715
|
-
|
|
3612
|
+
const [documentsOpen, setDocumentsOpen] = useState16(false);
|
|
3613
|
+
const [sendFailure, setSendFailure] = useState16(void 0);
|
|
3614
|
+
const [selectedMessageIds, setSelectedMessageIds] = useState16(/* @__PURE__ */ new Set());
|
|
3615
|
+
const [draft, setDraft] = useState16(initialComposerText ?? "");
|
|
3616
|
+
const [queuedFiles, setQueuedFiles] = useState16([]);
|
|
3617
|
+
useEffect11(() => {
|
|
2716
3618
|
setSelectedMessageIds(/* @__PURE__ */ new Set());
|
|
2717
3619
|
setDraft(initialComposerText ?? "");
|
|
3620
|
+
setQueuedFiles([]);
|
|
2718
3621
|
}, [conversation.id, initialComposerText]);
|
|
2719
3622
|
function toggleMessageSelected(messageId) {
|
|
2720
3623
|
setSelectedMessageIds((current) => {
|
|
@@ -2750,6 +3653,19 @@ function ConversationPane({
|
|
|
2750
3653
|
async function handleSend(text) {
|
|
2751
3654
|
await runSend(() => api.sendMessage(conversation.id, text), labels.sendFailure);
|
|
2752
3655
|
}
|
|
3656
|
+
async function handleRichSend() {
|
|
3657
|
+
if (onSendAttachments && queuedFiles.length > 0) {
|
|
3658
|
+
const files = queuedFiles;
|
|
3659
|
+
const caption = draft;
|
|
3660
|
+
await runSend(() => onSendAttachments(files, caption), labels.attachFailure);
|
|
3661
|
+
setQueuedFiles([]);
|
|
3662
|
+
setDraft("");
|
|
3663
|
+
return;
|
|
3664
|
+
}
|
|
3665
|
+
if (!draft.trim()) return;
|
|
3666
|
+
await handleSend(draft);
|
|
3667
|
+
setDraft("");
|
|
3668
|
+
}
|
|
2753
3669
|
async function handleAttach(file) {
|
|
2754
3670
|
if (!onAttach) return;
|
|
2755
3671
|
await runSend(() => onAttach(file), labels.attachFailure);
|
|
@@ -2765,9 +3681,15 @@ function ConversationPane({
|
|
|
2765
3681
|
);
|
|
2766
3682
|
}
|
|
2767
3683
|
const contextEntries = contextEntriesOf?.(conversationContext);
|
|
3684
|
+
const composerVariables = composerVariablesFor?.(conversation, conversationContext);
|
|
3685
|
+
const richQuickReplies = quickReplies?.map((reply) => ({
|
|
3686
|
+
id: reply.key,
|
|
3687
|
+
label: reply.label,
|
|
3688
|
+
text: typeof reply.text === "string" ? applyQuickReplyVariables(reply.text, quickReplyVariablesFor?.(conversation, conversationContext) ?? {}) : reply.text(quickReplyVariablesFor?.(conversation, conversationContext) ?? {})
|
|
3689
|
+
}));
|
|
2768
3690
|
const botOwnsConversation = Boolean(requireTakeoverToReply) && conversation.mode !== "human";
|
|
2769
|
-
return /* @__PURE__ */
|
|
2770
|
-
/* @__PURE__ */
|
|
3691
|
+
return /* @__PURE__ */ jsxs23("div", { className: "cv-workspace-pane", children: [
|
|
3692
|
+
/* @__PURE__ */ jsx25(
|
|
2771
3693
|
ConversationHeader,
|
|
2772
3694
|
{
|
|
2773
3695
|
conversation,
|
|
@@ -2782,10 +3704,10 @@ function ConversationPane({
|
|
|
2782
3704
|
...extraUtilities ? { extraUtilities } : {}
|
|
2783
3705
|
}
|
|
2784
3706
|
),
|
|
2785
|
-
contextEntries && contextEntries.length > 0 || flowLabel ? /* @__PURE__ */
|
|
2786
|
-
/* @__PURE__ */
|
|
2787
|
-
renderAboveTranscript?.(conversation),
|
|
2788
|
-
/* @__PURE__ */
|
|
3707
|
+
contextEntries && contextEntries.length > 0 || flowLabel ? /* @__PURE__ */ jsx25(ConversationContextPanel, { entries: contextEntries ?? [], ...flowLabel ? { flowLabel } : {} }) : null,
|
|
3708
|
+
/* @__PURE__ */ jsx25(ConversationDocumentsPanel, { conversationId: conversation.id, open: documentsOpen }),
|
|
3709
|
+
renderAboveTranscript?.(conversation, conversationContext),
|
|
3710
|
+
/* @__PURE__ */ jsx25(
|
|
2789
3711
|
ConversationWallpaper,
|
|
2790
3712
|
{
|
|
2791
3713
|
ref: scroll.containerRef,
|
|
@@ -2794,9 +3716,9 @@ function ConversationPane({
|
|
|
2794
3716
|
children: messages.map((message, index) => {
|
|
2795
3717
|
const previous = index > 0 ? messages[index - 1] : void 0;
|
|
2796
3718
|
const startsNewDay = !previous || new Date(message.timestamp).toDateString() !== new Date(previous.timestamp).toDateString();
|
|
2797
|
-
return /* @__PURE__ */
|
|
2798
|
-
startsNewDay ? /* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
3719
|
+
return /* @__PURE__ */ jsxs23("div", { children: [
|
|
3720
|
+
startsNewDay ? /* @__PURE__ */ jsx25(DateDivider, { iso: message.timestamp }) : null,
|
|
3721
|
+
/* @__PURE__ */ jsx25(
|
|
2800
3722
|
MessageBubble,
|
|
2801
3723
|
{
|
|
2802
3724
|
message,
|
|
@@ -2813,15 +3735,15 @@ function ConversationPane({
|
|
|
2813
3735
|
})
|
|
2814
3736
|
}
|
|
2815
3737
|
),
|
|
2816
|
-
messageSelection && selectedMessageIds.size > 0 ? /* @__PURE__ */
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
/* @__PURE__ */
|
|
2819
|
-
/* @__PURE__ */
|
|
2820
|
-
/* @__PURE__ */
|
|
3738
|
+
messageSelection && selectedMessageIds.size > 0 ? /* @__PURE__ */ jsxs23("div", { className: "cv-workspace-selection", children: [
|
|
3739
|
+
/* @__PURE__ */ jsx25("span", { children: labels.messagesSelected(selectedMessageIds.size) }),
|
|
3740
|
+
/* @__PURE__ */ jsxs23("div", { className: "cv-workspace-selection__actions", children: [
|
|
3741
|
+
/* @__PURE__ */ jsx25("button", { type: "button", onClick: () => setSelectedMessageIds(/* @__PURE__ */ new Set()), children: labels.bulkClear }),
|
|
3742
|
+
/* @__PURE__ */ jsx25("button", { type: "button", onClick: copySelectedMessages, children: labels.copySelected })
|
|
2821
3743
|
] })
|
|
2822
3744
|
] }) : null,
|
|
2823
|
-
sendFailure ? /* @__PURE__ */
|
|
2824
|
-
blocked ? /* @__PURE__ */
|
|
3745
|
+
sendFailure ? /* @__PURE__ */ jsx25("p", { role: "alert", className: "cv-workspace-alert", children: sendFailure }) : null,
|
|
3746
|
+
blocked ? /* @__PURE__ */ jsx25(
|
|
2825
3747
|
WindowExpiredNotice,
|
|
2826
3748
|
{
|
|
2827
3749
|
disabled: busy,
|
|
@@ -2829,8 +3751,47 @@ function ConversationPane({
|
|
|
2829
3751
|
}
|
|
2830
3752
|
) : botOwnsConversation ? (
|
|
2831
3753
|
// Responder com a conversa no bot atropelaria o fluxo automático no meio de uma pergunta.
|
|
2832
|
-
/* @__PURE__ */
|
|
2833
|
-
) : /* @__PURE__ */
|
|
3754
|
+
/* @__PURE__ */ jsx25("p", { className: "cv-workspace-notice", children: labels.takeoverToReply })
|
|
3755
|
+
) : composer === "rich" ? /* @__PURE__ */ jsx25(
|
|
3756
|
+
RichMessageComposer,
|
|
3757
|
+
{
|
|
3758
|
+
value: draft,
|
|
3759
|
+
onChange: setDraft,
|
|
3760
|
+
onSend: () => void handleRichSend(),
|
|
3761
|
+
...onSendAttachments ? { onAttachFiles: (files) => setQueuedFiles((current) => [...current, ...Array.from(files)]) } : onAttach ? {
|
|
3762
|
+
onAttachFiles: (files) => {
|
|
3763
|
+
for (const file of Array.from(files)) void handleAttach(file);
|
|
3764
|
+
}
|
|
3765
|
+
} : {},
|
|
3766
|
+
placeholder: labels.composerPlaceholder,
|
|
3767
|
+
isSending: busy,
|
|
3768
|
+
...onRecordAudio ? {
|
|
3769
|
+
idleAction: /* @__PURE__ */ jsx25(
|
|
3770
|
+
AudioRecorderButton,
|
|
3771
|
+
{
|
|
3772
|
+
onRecorded: (file) => void runSend(() => onRecordAudio(file), labels.recordFailure),
|
|
3773
|
+
onFailure: (failureMessage) => setSendFailure(failureMessage)
|
|
3774
|
+
}
|
|
3775
|
+
)
|
|
3776
|
+
} : {},
|
|
3777
|
+
...queuedFiles.length > 0 ? {
|
|
3778
|
+
attachmentsPreview: /* @__PURE__ */ jsx25("ul", { className: "cv-workspace-attachments", children: queuedFiles.map((file, index) => /* @__PURE__ */ jsxs23("li", { children: [
|
|
3779
|
+
/* @__PURE__ */ jsx25("span", { children: file.name }),
|
|
3780
|
+
/* @__PURE__ */ jsx25(
|
|
3781
|
+
"button",
|
|
3782
|
+
{
|
|
3783
|
+
type: "button",
|
|
3784
|
+
"aria-label": labels.attachmentRemove,
|
|
3785
|
+
onClick: () => setQueuedFiles((current) => current.filter((_, position) => position !== index)),
|
|
3786
|
+
children: "\u2715"
|
|
3787
|
+
}
|
|
3788
|
+
)
|
|
3789
|
+
] }, `${file.name}-${index}`)) })
|
|
3790
|
+
} : {},
|
|
3791
|
+
...richQuickReplies ? { quickReplies: [...richQuickReplies] } : {},
|
|
3792
|
+
...composerVariables ? { variables: [...composerVariables] } : {}
|
|
3793
|
+
}
|
|
3794
|
+
) : /* @__PURE__ */ jsx25(
|
|
2834
3795
|
MessageComposer,
|
|
2835
3796
|
{
|
|
2836
3797
|
value: draft,
|
|
@@ -2846,7 +3807,7 @@ function ConversationPane({
|
|
|
2846
3807
|
}
|
|
2847
3808
|
|
|
2848
3809
|
// src/workspace/ConversationsInboxList.tsx
|
|
2849
|
-
import { jsx as
|
|
3810
|
+
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2850
3811
|
function ConversationsInboxList({
|
|
2851
3812
|
inbox,
|
|
2852
3813
|
labels,
|
|
@@ -2857,13 +3818,13 @@ function ConversationsInboxList({
|
|
|
2857
3818
|
onSendTemplateToSelected
|
|
2858
3819
|
}) {
|
|
2859
3820
|
const hasSelection = inbox.selectedIds.size > 0;
|
|
2860
|
-
return /* @__PURE__ */
|
|
2861
|
-
hasSelection ? /* @__PURE__ */
|
|
2862
|
-
/* @__PURE__ */
|
|
2863
|
-
/* @__PURE__ */
|
|
2864
|
-
/* @__PURE__ */
|
|
2865
|
-
onSendTemplateToSelected ? /* @__PURE__ */
|
|
2866
|
-
inbox.canFinalize ? /* @__PURE__ */
|
|
3821
|
+
return /* @__PURE__ */ jsxs24("aside", { className, children: [
|
|
3822
|
+
hasSelection ? /* @__PURE__ */ jsxs24("div", { className: "cv-workspace-bulk", children: [
|
|
3823
|
+
/* @__PURE__ */ jsx26("span", { className: "cv-workspace-bulk__count", children: labels.bulkSelected(inbox.selectedIds.size) }),
|
|
3824
|
+
/* @__PURE__ */ jsxs24("div", { className: "cv-workspace-bulk__actions", children: [
|
|
3825
|
+
/* @__PURE__ */ jsx26("button", { type: "button", onClick: inbox.clearBulkSelection, children: labels.bulkClear }),
|
|
3826
|
+
onSendTemplateToSelected ? /* @__PURE__ */ jsx26("button", { type: "button", onClick: onSendTemplateToSelected, disabled: inbox.busy, children: labels.bulkTemplate }) : null,
|
|
3827
|
+
inbox.canFinalize ? /* @__PURE__ */ jsx26(
|
|
2867
3828
|
"button",
|
|
2868
3829
|
{
|
|
2869
3830
|
type: "button",
|
|
@@ -2879,8 +3840,8 @@ function ConversationsInboxList({
|
|
|
2879
3840
|
renderBulkActions?.(inbox)
|
|
2880
3841
|
] })
|
|
2881
3842
|
] }) : null,
|
|
2882
|
-
/* @__PURE__ */
|
|
2883
|
-
/* @__PURE__ */
|
|
3843
|
+
/* @__PURE__ */ jsxs24("div", { className: "cv-workspace-filters", children: [
|
|
3844
|
+
/* @__PURE__ */ jsx26(
|
|
2884
3845
|
"input",
|
|
2885
3846
|
{
|
|
2886
3847
|
type: "search",
|
|
@@ -2890,9 +3851,9 @@ function ConversationsInboxList({
|
|
|
2890
3851
|
className: "cv-workspace-search"
|
|
2891
3852
|
}
|
|
2892
3853
|
),
|
|
2893
|
-
/* @__PURE__ */
|
|
2894
|
-
/* @__PURE__ */
|
|
2895
|
-
WINDOW_FILTERS.map((filter) => /* @__PURE__ */
|
|
3854
|
+
/* @__PURE__ */ jsxs24("div", { className: "cv-workspace-chips", children: [
|
|
3855
|
+
/* @__PURE__ */ jsx26("span", { className: "cv-workspace-chips__legend", children: labels.windowLegend }),
|
|
3856
|
+
WINDOW_FILTERS.map((filter) => /* @__PURE__ */ jsxs24(
|
|
2896
3857
|
"button",
|
|
2897
3858
|
{
|
|
2898
3859
|
type: "button",
|
|
@@ -2900,16 +3861,16 @@ function ConversationsInboxList({
|
|
|
2900
3861
|
"aria-pressed": inbox.windowFilter === filter.value,
|
|
2901
3862
|
className: `cv-workspace-chip${inbox.windowFilter === filter.value ? " cv-workspace-chip--on" : ""}`,
|
|
2902
3863
|
children: [
|
|
2903
|
-
filter.dotClass ? /* @__PURE__ */
|
|
3864
|
+
filter.dotClass ? /* @__PURE__ */ jsx26("span", { className: `cv-workspace-dot ${filter.dotClass}` }) : null,
|
|
2904
3865
|
filter.label
|
|
2905
3866
|
]
|
|
2906
3867
|
},
|
|
2907
3868
|
filter.value
|
|
2908
3869
|
))
|
|
2909
3870
|
] }),
|
|
2910
|
-
inbox.channelFilters.length > 0 ? /* @__PURE__ */
|
|
2911
|
-
/* @__PURE__ */
|
|
2912
|
-
inbox.channelFilters.map((filter) => /* @__PURE__ */
|
|
3871
|
+
inbox.channelFilters.length > 0 ? /* @__PURE__ */ jsxs24("div", { className: "cv-workspace-chips", children: [
|
|
3872
|
+
/* @__PURE__ */ jsx26("span", { className: "cv-workspace-chips__legend", children: labels.channelLegend }),
|
|
3873
|
+
inbox.channelFilters.map((filter) => /* @__PURE__ */ jsxs24(
|
|
2913
3874
|
"button",
|
|
2914
3875
|
{
|
|
2915
3876
|
type: "button",
|
|
@@ -2917,7 +3878,7 @@ function ConversationsInboxList({
|
|
|
2917
3878
|
"aria-pressed": inbox.channelFilter === filter.value,
|
|
2918
3879
|
className: `cv-workspace-chip${inbox.channelFilter === filter.value ? " cv-workspace-chip--on" : ""}`,
|
|
2919
3880
|
children: [
|
|
2920
|
-
filter.value === CHANNEL_FILTER_ALL ? null : /* @__PURE__ */
|
|
3881
|
+
filter.value === CHANNEL_FILTER_ALL ? null : /* @__PURE__ */ jsx26(ChannelIcon, { channel: filter.value }),
|
|
2921
3882
|
filter.label
|
|
2922
3883
|
]
|
|
2923
3884
|
},
|
|
@@ -2925,14 +3886,14 @@ function ConversationsInboxList({
|
|
|
2925
3886
|
))
|
|
2926
3887
|
] }) : null,
|
|
2927
3888
|
renderFilters?.(inbox),
|
|
2928
|
-
/* @__PURE__ */
|
|
2929
|
-
/* @__PURE__ */
|
|
3889
|
+
/* @__PURE__ */ jsxs24("label", { className: "cv-workspace-selectall", children: [
|
|
3890
|
+
/* @__PURE__ */ jsx26("input", { type: "checkbox", checked: inbox.allOnPageSelected, onChange: inbox.toggleSelectAllOnPage }),
|
|
2930
3891
|
labels.selectAll
|
|
2931
3892
|
] })
|
|
2932
3893
|
] }),
|
|
2933
|
-
/* @__PURE__ */
|
|
3894
|
+
/* @__PURE__ */ jsxs24("div", { className: "cv-workspace-rows", children: [
|
|
2934
3895
|
inbox.pageConversations.map(
|
|
2935
|
-
(conversation) => renderRow ? /* @__PURE__ */
|
|
3896
|
+
(conversation) => renderRow ? /* @__PURE__ */ jsx26("div", { children: renderRow(conversation) }, conversation.id) : /* @__PURE__ */ jsx26(
|
|
2936
3897
|
ConversationRow,
|
|
2937
3898
|
{
|
|
2938
3899
|
conversation,
|
|
@@ -2947,13 +3908,13 @@ function ConversationsInboxList({
|
|
|
2947
3908
|
conversation.id
|
|
2948
3909
|
)
|
|
2949
3910
|
),
|
|
2950
|
-
!inbox.loading && inbox.filteredCount === 0 ? /* @__PURE__ */
|
|
3911
|
+
!inbox.loading && inbox.filteredCount === 0 ? /* @__PURE__ */ jsx26("p", { className: "cv-workspace-empty", children: labels.emptyList }) : null
|
|
2951
3912
|
] }),
|
|
2952
|
-
/* @__PURE__ */
|
|
2953
|
-
/* @__PURE__ */
|
|
2954
|
-
/* @__PURE__ */
|
|
2955
|
-
/* @__PURE__ */
|
|
2956
|
-
/* @__PURE__ */
|
|
3913
|
+
/* @__PURE__ */ jsxs24("div", { className: "cv-workspace-pager", children: [
|
|
3914
|
+
/* @__PURE__ */ jsx26("span", { children: labels.rangeOf(inbox.firstOnPage, inbox.lastOnPage, inbox.filteredCount) }),
|
|
3915
|
+
/* @__PURE__ */ jsxs24("div", { className: "cv-workspace-pager__buttons", children: [
|
|
3916
|
+
/* @__PURE__ */ jsx26("button", { type: "button", onClick: () => inbox.goToPage(1), disabled: inbox.page === 1, "aria-label": "Primeira p\xE1gina", children: "\xAB" }),
|
|
3917
|
+
/* @__PURE__ */ jsx26(
|
|
2957
3918
|
"button",
|
|
2958
3919
|
{
|
|
2959
3920
|
type: "button",
|
|
@@ -2963,8 +3924,8 @@ function ConversationsInboxList({
|
|
|
2963
3924
|
children: "\u2039"
|
|
2964
3925
|
}
|
|
2965
3926
|
),
|
|
2966
|
-
/* @__PURE__ */
|
|
2967
|
-
/* @__PURE__ */
|
|
3927
|
+
/* @__PURE__ */ jsx26("span", { children: labels.pageOf(inbox.page, inbox.pageCount) }),
|
|
3928
|
+
/* @__PURE__ */ jsx26(
|
|
2968
3929
|
"button",
|
|
2969
3930
|
{
|
|
2970
3931
|
type: "button",
|
|
@@ -2974,7 +3935,7 @@ function ConversationsInboxList({
|
|
|
2974
3935
|
children: "\u203A"
|
|
2975
3936
|
}
|
|
2976
3937
|
),
|
|
2977
|
-
/* @__PURE__ */
|
|
3938
|
+
/* @__PURE__ */ jsx26(
|
|
2978
3939
|
"button",
|
|
2979
3940
|
{
|
|
2980
3941
|
type: "button",
|
|
@@ -3021,6 +3982,8 @@ var DEFAULT_CONVERSATIONS_WORKSPACE_LABELS = {
|
|
|
3021
3982
|
copySelected: "Copiar",
|
|
3022
3983
|
composerPlaceholder: "Responder como atendente\u2026",
|
|
3023
3984
|
attachFailure: "Falha ao enviar o arquivo.",
|
|
3985
|
+
attachmentRemove: "Remover anexo",
|
|
3986
|
+
recordFailure: "Falha ao gravar o \xE1udio.",
|
|
3024
3987
|
sendFailure: "Falha ao enviar a mensagem.",
|
|
3025
3988
|
takeoverToReply: "Assuma o atendimento para responder diretamente ao cliente.",
|
|
3026
3989
|
signIn: "Entrar no painel",
|
|
@@ -3029,7 +3992,7 @@ var DEFAULT_CONVERSATIONS_WORKSPACE_LABELS = {
|
|
|
3029
3992
|
};
|
|
3030
3993
|
|
|
3031
3994
|
// src/workspace/useConversationsInbox.ts
|
|
3032
|
-
import { useCallback as
|
|
3995
|
+
import { useCallback as useCallback9, useEffect as useEffect12, useMemo as useMemo5, useRef as useRef7, useState as useState17 } from "react";
|
|
3033
3996
|
var CONVERSATIONS_PER_PAGE = 50;
|
|
3034
3997
|
function defaultDescribeFailure(error) {
|
|
3035
3998
|
const status = error.status;
|
|
@@ -3047,14 +4010,14 @@ function useConversationsInbox(params = {}) {
|
|
|
3047
4010
|
const perPage = params.perPage ?? CONVERSATIONS_PER_PAGE;
|
|
3048
4011
|
const markReadOnOpen = params.markReadOnOpen ?? true;
|
|
3049
4012
|
const describeFailure = params.describeFailure ?? defaultDescribeFailure;
|
|
3050
|
-
const [waitingOnly, setWaitingOnly] =
|
|
3051
|
-
const [windowFilter, setWindowFilter] =
|
|
3052
|
-
const [channelFilter, setChannelFilter] =
|
|
3053
|
-
const [search, setSearch] =
|
|
3054
|
-
const [page, setPage] =
|
|
3055
|
-
const [selectedId, setSelectedId] =
|
|
3056
|
-
const [selectedIds, setSelectedIds] =
|
|
3057
|
-
const [busy, setBusy] =
|
|
4013
|
+
const [waitingOnly, setWaitingOnly] = useState17(false);
|
|
4014
|
+
const [windowFilter, setWindowFilter] = useState17(CONVERSATION_WINDOW.ALL);
|
|
4015
|
+
const [channelFilter, setChannelFilter] = useState17(CHANNEL_FILTER_ALL);
|
|
4016
|
+
const [search, setSearch] = useState17("");
|
|
4017
|
+
const [page, setPage] = useState17(1);
|
|
4018
|
+
const [selectedId, setSelectedId] = useState17(void 0);
|
|
4019
|
+
const [selectedIds, setSelectedIds] = useState17(/* @__PURE__ */ new Set());
|
|
4020
|
+
const [busy, setBusy] = useState17(false);
|
|
3058
4021
|
const { conversations, total, loading, error, refetch } = useConversationList({
|
|
3059
4022
|
...waitingOnly ? { waitingHuman: true } : {},
|
|
3060
4023
|
...search ? { search } : {},
|
|
@@ -3062,12 +4025,12 @@ function useConversationsInbox(params = {}) {
|
|
|
3062
4025
|
...params.serverPaginated ? { page, limit: perPage } : {}
|
|
3063
4026
|
});
|
|
3064
4027
|
useGlobalRealtime(
|
|
3065
|
-
|
|
4028
|
+
useCallback9(() => {
|
|
3066
4029
|
void refetch();
|
|
3067
4030
|
}, [refetch])
|
|
3068
4031
|
);
|
|
3069
|
-
const now =
|
|
3070
|
-
const filtered =
|
|
4032
|
+
const now = useMemo5(() => Date.now(), [conversations]);
|
|
4033
|
+
const filtered = useMemo5(
|
|
3071
4034
|
() => conversations.filter(
|
|
3072
4035
|
(conversation) => channelFilter === CHANNEL_FILTER_ALL || (conversation.channel ?? DEFAULT_CONVERSATION_CHANNEL) === channelFilter
|
|
3073
4036
|
).filter(
|
|
@@ -3079,16 +4042,16 @@ function useConversationsInbox(params = {}) {
|
|
|
3079
4042
|
const pageCount = Math.max(1, Math.ceil(totalForPaging / perPage));
|
|
3080
4043
|
const currentPage = Math.min(page, pageCount);
|
|
3081
4044
|
const pageConversations = params.serverPaginated ? filtered : filtered.slice((currentPage - 1) * perPage, currentPage * perPage);
|
|
3082
|
-
|
|
4045
|
+
useEffect12(() => {
|
|
3083
4046
|
setPage(1);
|
|
3084
4047
|
}, [search, waitingOnly, windowFilter, channelFilter]);
|
|
3085
|
-
|
|
4048
|
+
useEffect12(() => {
|
|
3086
4049
|
if (selectedId && !conversations.some((conversation) => conversation.id === selectedId)) {
|
|
3087
4050
|
setSelectedId(void 0);
|
|
3088
4051
|
}
|
|
3089
4052
|
}, [conversations, selectedId]);
|
|
3090
4053
|
const lastMarkReadAttempt = useRef7(void 0);
|
|
3091
|
-
|
|
4054
|
+
useEffect12(() => {
|
|
3092
4055
|
if (!markReadOnOpen || !selectedId) return;
|
|
3093
4056
|
const opened = conversations.find((conversation) => conversation.id === selectedId);
|
|
3094
4057
|
if (!opened || opened.unread === 0) return;
|
|
@@ -3098,7 +4061,7 @@ function useConversationsInbox(params = {}) {
|
|
|
3098
4061
|
void api.markRead(selectedId).then(() => refetch()).catch(() => {
|
|
3099
4062
|
});
|
|
3100
4063
|
}, [markReadOnOpen, selectedId, conversations, refetch, api]);
|
|
3101
|
-
const toggleSelected =
|
|
4064
|
+
const toggleSelected = useCallback9((conversationId) => {
|
|
3102
4065
|
setSelectedIds((current) => {
|
|
3103
4066
|
const next = new Set(current);
|
|
3104
4067
|
if (next.has(conversationId)) next.delete(conversationId);
|
|
@@ -3108,7 +4071,7 @@ function useConversationsInbox(params = {}) {
|
|
|
3108
4071
|
}, []);
|
|
3109
4072
|
const pageIds = pageConversations.map((conversation) => conversation.id);
|
|
3110
4073
|
const allOnPageSelected = pageIds.length > 0 && pageIds.every((id) => selectedIds.has(id));
|
|
3111
|
-
const toggleSelectAllOnPage =
|
|
4074
|
+
const toggleSelectAllOnPage = useCallback9(() => {
|
|
3112
4075
|
setSelectedIds((current) => {
|
|
3113
4076
|
const next = new Set(current);
|
|
3114
4077
|
if (allOnPageSelected) pageIds.forEach((id) => next.delete(id));
|
|
@@ -3116,7 +4079,7 @@ function useConversationsInbox(params = {}) {
|
|
|
3116
4079
|
return next;
|
|
3117
4080
|
});
|
|
3118
4081
|
}, [allOnPageSelected, pageIds]);
|
|
3119
|
-
const runOnSelection =
|
|
4082
|
+
const runOnSelection = useCallback9(
|
|
3120
4083
|
async (action) => {
|
|
3121
4084
|
setBusy(true);
|
|
3122
4085
|
try {
|
|
@@ -3129,7 +4092,7 @@ function useConversationsInbox(params = {}) {
|
|
|
3129
4092
|
},
|
|
3130
4093
|
[selectedIds, refetch]
|
|
3131
4094
|
);
|
|
3132
|
-
const runConversationAction =
|
|
4095
|
+
const runConversationAction = useCallback9(
|
|
3133
4096
|
async (action, conversationId) => {
|
|
3134
4097
|
if (!action) return;
|
|
3135
4098
|
setBusy(true);
|
|
@@ -3208,7 +4171,7 @@ function useConversationsInbox(params = {}) {
|
|
|
3208
4171
|
}
|
|
3209
4172
|
|
|
3210
4173
|
// src/workspace/ConversationsWorkspace.tsx
|
|
3211
|
-
import { Fragment as
|
|
4174
|
+
import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3212
4175
|
function ConversationsWorkspace({
|
|
3213
4176
|
labels: labelsOverride,
|
|
3214
4177
|
filters,
|
|
@@ -3225,6 +4188,10 @@ function ConversationsWorkspace({
|
|
|
3225
4188
|
requireTakeoverToReply,
|
|
3226
4189
|
messageSelection,
|
|
3227
4190
|
initialComposerText,
|
|
4191
|
+
composer,
|
|
4192
|
+
composerVariablesFor,
|
|
4193
|
+
onSendAttachments,
|
|
4194
|
+
onRecordAudio,
|
|
3228
4195
|
contextEntriesOf,
|
|
3229
4196
|
onAttach,
|
|
3230
4197
|
extraUtilitiesFor,
|
|
@@ -3244,10 +4211,10 @@ function ConversationsWorkspace({
|
|
|
3244
4211
|
...markReadOnOpen === void 0 ? {} : { markReadOnOpen },
|
|
3245
4212
|
...serverPaginated ? { serverPaginated } : {}
|
|
3246
4213
|
});
|
|
3247
|
-
const [simulatorOpen, setSimulatorOpen] =
|
|
3248
|
-
const [templateModalOpen, setTemplateModalOpen] =
|
|
3249
|
-
const [openedFromLink, setOpenedFromLink] =
|
|
3250
|
-
|
|
4214
|
+
const [simulatorOpen, setSimulatorOpen] = useState18(false);
|
|
4215
|
+
const [templateModalOpen, setTemplateModalOpen] = useState18(false);
|
|
4216
|
+
const [openedFromLink, setOpenedFromLink] = useState18(void 0);
|
|
4217
|
+
useEffect13(() => {
|
|
3251
4218
|
const link = initialConversationId ?? initialWhatsappNumber;
|
|
3252
4219
|
if (!link || openedFromLink === link) return;
|
|
3253
4220
|
const target = inbox.conversations.find(
|
|
@@ -3260,7 +4227,7 @@ function ConversationsWorkspace({
|
|
|
3260
4227
|
const selected = inbox.selectedConversation;
|
|
3261
4228
|
const simulatorEnabled = Boolean(simulator && (simulator.enabled ?? true));
|
|
3262
4229
|
const showSimulator = simulatorEnabled && simulatorOpen && Boolean(selected);
|
|
3263
|
-
const paneUtilities =
|
|
4230
|
+
const paneUtilities = useMemo6(() => {
|
|
3264
4231
|
if (!selected) return void 0;
|
|
3265
4232
|
const fromProduct = extraUtilitiesFor?.(selected) ?? [];
|
|
3266
4233
|
if (!simulatorEnabled) return fromProduct;
|
|
@@ -3275,39 +4242,39 @@ function ConversationsWorkspace({
|
|
|
3275
4242
|
}
|
|
3276
4243
|
];
|
|
3277
4244
|
}, [selected, extraUtilitiesFor, simulatorEnabled, simulator, simulatorOpen]);
|
|
3278
|
-
return /* @__PURE__ */
|
|
3279
|
-
/* @__PURE__ */
|
|
3280
|
-
/* @__PURE__ */
|
|
3281
|
-
/* @__PURE__ */
|
|
3282
|
-
/* @__PURE__ */
|
|
3283
|
-
/* @__PURE__ */
|
|
4245
|
+
return /* @__PURE__ */ jsxs25("div", { className: `cv-workspace${className ? ` ${className}` : ""}`, children: [
|
|
4246
|
+
/* @__PURE__ */ jsxs25("header", { className: "cv-workspace-header", children: [
|
|
4247
|
+
/* @__PURE__ */ jsxs25("div", { className: "cv-workspace-header__titles", children: [
|
|
4248
|
+
/* @__PURE__ */ jsx27("h1", { children: labels.title }),
|
|
4249
|
+
/* @__PURE__ */ jsxs25("p", { children: [
|
|
4250
|
+
/* @__PURE__ */ jsxs25("span", { title: labels.conversations, children: [
|
|
3284
4251
|
"\u{1F4AC} ",
|
|
3285
4252
|
inbox.totalCount,
|
|
3286
|
-
/* @__PURE__ */
|
|
4253
|
+
/* @__PURE__ */ jsxs25("span", { className: "cv-only-wide", children: [
|
|
3287
4254
|
" ",
|
|
3288
4255
|
labels.conversations
|
|
3289
4256
|
] })
|
|
3290
4257
|
] }),
|
|
3291
|
-
/* @__PURE__ */
|
|
4258
|
+
/* @__PURE__ */ jsxs25("span", { title: labels.waiting, className: "cv-workspace-header__waiting", children: [
|
|
3292
4259
|
"\u23F3 ",
|
|
3293
4260
|
inbox.waitingCount,
|
|
3294
|
-
/* @__PURE__ */
|
|
4261
|
+
/* @__PURE__ */ jsxs25("span", { className: "cv-only-wide", children: [
|
|
3295
4262
|
" ",
|
|
3296
4263
|
labels.waiting
|
|
3297
4264
|
] })
|
|
3298
4265
|
] }),
|
|
3299
|
-
/* @__PURE__ */
|
|
4266
|
+
/* @__PURE__ */ jsxs25("span", { title: labels.unread, children: [
|
|
3300
4267
|
"\u2709\uFE0F ",
|
|
3301
4268
|
inbox.unreadCount,
|
|
3302
|
-
/* @__PURE__ */
|
|
4269
|
+
/* @__PURE__ */ jsxs25("span", { className: "cv-only-wide", children: [
|
|
3303
4270
|
" ",
|
|
3304
4271
|
labels.unread
|
|
3305
4272
|
] })
|
|
3306
4273
|
] })
|
|
3307
4274
|
] })
|
|
3308
4275
|
] }),
|
|
3309
|
-
/* @__PURE__ */
|
|
3310
|
-
/* @__PURE__ */
|
|
4276
|
+
/* @__PURE__ */ jsxs25("div", { className: "cv-workspace-header__actions", children: [
|
|
4277
|
+
/* @__PURE__ */ jsxs25(
|
|
3311
4278
|
"button",
|
|
3312
4279
|
{
|
|
3313
4280
|
type: "button",
|
|
@@ -3317,14 +4284,14 @@ function ConversationsWorkspace({
|
|
|
3317
4284
|
className: inbox.waitingOnly ? "cv-workspace-toggle cv-workspace-toggle--on" : "cv-workspace-toggle",
|
|
3318
4285
|
children: [
|
|
3319
4286
|
"\u23F3",
|
|
3320
|
-
/* @__PURE__ */
|
|
4287
|
+
/* @__PURE__ */ jsxs25("span", { className: "cv-only-wide", children: [
|
|
3321
4288
|
" ",
|
|
3322
4289
|
labels.waitingOnly
|
|
3323
4290
|
] })
|
|
3324
4291
|
]
|
|
3325
4292
|
}
|
|
3326
4293
|
),
|
|
3327
|
-
/* @__PURE__ */
|
|
4294
|
+
/* @__PURE__ */ jsxs25(
|
|
3328
4295
|
"button",
|
|
3329
4296
|
{
|
|
3330
4297
|
type: "button",
|
|
@@ -3335,7 +4302,7 @@ function ConversationsWorkspace({
|
|
|
3335
4302
|
className: "cv-workspace-toggle",
|
|
3336
4303
|
children: [
|
|
3337
4304
|
"\u2713",
|
|
3338
|
-
/* @__PURE__ */
|
|
4305
|
+
/* @__PURE__ */ jsxs25("span", { className: "cv-only-wide", children: [
|
|
3339
4306
|
" ",
|
|
3340
4307
|
labels.markSelectedAsRead
|
|
3341
4308
|
] }),
|
|
@@ -3343,7 +4310,7 @@ function ConversationsWorkspace({
|
|
|
3343
4310
|
]
|
|
3344
4311
|
}
|
|
3345
4312
|
),
|
|
3346
|
-
inbox.canMarkAllRead && inbox.unreadCount > 0 ? /* @__PURE__ */
|
|
4313
|
+
inbox.canMarkAllRead && inbox.unreadCount > 0 ? /* @__PURE__ */ jsxs25(
|
|
3347
4314
|
"button",
|
|
3348
4315
|
{
|
|
3349
4316
|
type: "button",
|
|
@@ -3353,7 +4320,7 @@ function ConversationsWorkspace({
|
|
|
3353
4320
|
className: "cv-workspace-toggle",
|
|
3354
4321
|
children: [
|
|
3355
4322
|
"\u2713\u2713",
|
|
3356
|
-
/* @__PURE__ */
|
|
4323
|
+
/* @__PURE__ */ jsxs25("span", { className: "cv-only-wide", children: [
|
|
3357
4324
|
" ",
|
|
3358
4325
|
labels.markAllAsRead
|
|
3359
4326
|
] })
|
|
@@ -3363,20 +4330,20 @@ function ConversationsWorkspace({
|
|
|
3363
4330
|
renderHeaderActions?.(inbox)
|
|
3364
4331
|
] })
|
|
3365
4332
|
] }),
|
|
3366
|
-
inbox.loadFailure ? /* @__PURE__ */
|
|
4333
|
+
inbox.loadFailure ? /* @__PURE__ */ jsxs25("p", { role: "alert", className: "cv-workspace-failure", children: [
|
|
3367
4334
|
inbox.loadFailure,
|
|
3368
|
-
signInHref ? /* @__PURE__ */
|
|
4335
|
+
signInHref ? /* @__PURE__ */ jsxs25(Fragment6, { children: [
|
|
3369
4336
|
" ",
|
|
3370
|
-
/* @__PURE__ */
|
|
4337
|
+
/* @__PURE__ */ jsx27("a", { href: signInHref, className: "cv-workspace-failure__link", children: labels.signIn })
|
|
3371
4338
|
] }) : null
|
|
3372
4339
|
] }) : null,
|
|
3373
|
-
/* @__PURE__ */
|
|
4340
|
+
/* @__PURE__ */ jsxs25(
|
|
3374
4341
|
"div",
|
|
3375
4342
|
{
|
|
3376
4343
|
className: `cv-workspace-grid${showSimulator ? " cv-workspace-grid--with-simulator" : ""}`,
|
|
3377
4344
|
"data-detail": selected ? "open" : "closed",
|
|
3378
4345
|
children: [
|
|
3379
|
-
/* @__PURE__ */
|
|
4346
|
+
/* @__PURE__ */ jsx27(
|
|
3380
4347
|
ConversationsInboxList,
|
|
3381
4348
|
{
|
|
3382
4349
|
inbox,
|
|
@@ -3388,7 +4355,7 @@ function ConversationsWorkspace({
|
|
|
3388
4355
|
...onSendTemplateToSelected ? { onSendTemplateToSelected: () => onSendTemplateToSelected(inbox) } : inbox.canListTemplates ? { onSendTemplateToSelected: () => setTemplateModalOpen(true) } : {}
|
|
3389
4356
|
}
|
|
3390
4357
|
),
|
|
3391
|
-
/* @__PURE__ */
|
|
4358
|
+
/* @__PURE__ */ jsx27("section", { className: "cv-workspace-detail", children: selected ? /* @__PURE__ */ jsx27(
|
|
3392
4359
|
ConversationPane,
|
|
3393
4360
|
{
|
|
3394
4361
|
conversation: selected,
|
|
@@ -3403,6 +4370,12 @@ function ConversationsWorkspace({
|
|
|
3403
4370
|
...requireTakeoverToReply ? { requireTakeoverToReply } : {},
|
|
3404
4371
|
...messageSelection ? { messageSelection } : {},
|
|
3405
4372
|
...initialComposerText ? { initialComposerText } : {},
|
|
4373
|
+
...composer ? { composer } : {},
|
|
4374
|
+
...composerVariablesFor ? { composerVariablesFor } : {},
|
|
4375
|
+
...onSendAttachments ? {
|
|
4376
|
+
onSendAttachments: (files, caption) => onSendAttachments(selected, files, caption)
|
|
4377
|
+
} : {},
|
|
4378
|
+
...onRecordAudio ? { onRecordAudio: (file) => onRecordAudio(selected, file) } : {},
|
|
3406
4379
|
onBack: inbox.clearSelection,
|
|
3407
4380
|
...paneUtilities ? { extraUtilities: paneUtilities } : {},
|
|
3408
4381
|
...contextEntriesOf ? { contextEntriesOf } : {},
|
|
@@ -3411,16 +4384,16 @@ function ConversationsWorkspace({
|
|
|
3411
4384
|
...renderAboveTranscript ? { renderAboveTranscript } : {},
|
|
3412
4385
|
...onAttach ? { onAttach: (file) => onAttach(selected, file) } : {}
|
|
3413
4386
|
}
|
|
3414
|
-
) : /* @__PURE__ */
|
|
4387
|
+
) : /* @__PURE__ */ jsx27("p", { className: "cv-workspace-empty", children: labels.emptyDetail }) }),
|
|
3415
4388
|
showSimulator && selected ? (
|
|
3416
4389
|
// `min-height:0` junto do `min-width:0`: sem isso a linha do grid cresce com o conteúdo do
|
|
3417
4390
|
// painel, o scroll interno nunca ativa e quem rola passa a ser a página inteira.
|
|
3418
|
-
/* @__PURE__ */
|
|
4391
|
+
/* @__PURE__ */ jsx27("div", { className: "cv-workspace-simulator", children: simulator?.render({ conversationId: selected.id, close: () => setSimulatorOpen(false) }) })
|
|
3419
4392
|
) : null
|
|
3420
4393
|
]
|
|
3421
4394
|
}
|
|
3422
4395
|
),
|
|
3423
|
-
templateModalOpen ? /* @__PURE__ */
|
|
4396
|
+
templateModalOpen ? /* @__PURE__ */ jsx27(
|
|
3424
4397
|
BulkTemplateModal,
|
|
3425
4398
|
{
|
|
3426
4399
|
labels,
|
|
@@ -3439,6 +4412,7 @@ export {
|
|
|
3439
4412
|
AudioRecorderButton,
|
|
3440
4413
|
AudioTranscription,
|
|
3441
4414
|
Avatar,
|
|
4415
|
+
BulkActionBar,
|
|
3442
4416
|
CHANNEL_BRAND_COLOR,
|
|
3443
4417
|
CHANNEL_CAPABILITIES,
|
|
3444
4418
|
CHANNEL_FILTER_ALL,
|
|
@@ -3467,6 +4441,7 @@ export {
|
|
|
3467
4441
|
DEFAULT_CONVERSATION_HEADER_LABELS,
|
|
3468
4442
|
DEFAULT_CONVERSATION_LIST_ITEM_LABELS,
|
|
3469
4443
|
DEFAULT_DOCUMENTS_LIBRARY_LABELS,
|
|
4444
|
+
DEFAULT_DOCUMENTS_WORKSPACE_LABELS,
|
|
3470
4445
|
DEFAULT_EMOJI_PICKER_LABELS,
|
|
3471
4446
|
DEFAULT_INTERACTIVE_MESSAGE_LABELS,
|
|
3472
4447
|
DEFAULT_LIGHTBOX_LABELS,
|
|
@@ -3479,23 +4454,28 @@ export {
|
|
|
3479
4454
|
DOCUMENT_SOURCE_FILTER,
|
|
3480
4455
|
DateDivider,
|
|
3481
4456
|
DocumentsLibrary,
|
|
4457
|
+
DocumentsWorkspace,
|
|
3482
4458
|
EMOJI_CATEGORIES,
|
|
3483
4459
|
EmojiPicker,
|
|
3484
4460
|
FileIcon,
|
|
3485
4461
|
HANDLE_KIND,
|
|
3486
4462
|
InteractiveMessage,
|
|
3487
4463
|
Lightbox,
|
|
4464
|
+
ListingPagination,
|
|
3488
4465
|
MediaRenderer,
|
|
3489
4466
|
MessageBubble,
|
|
3490
4467
|
MessageComposer,
|
|
3491
4468
|
MessageTail,
|
|
3492
4469
|
MessageText,
|
|
3493
4470
|
MessageTimestamp,
|
|
4471
|
+
MessagesWorkspace,
|
|
4472
|
+
MultiSelectFilter,
|
|
3494
4473
|
NARROW_MAX_WIDTH_PX,
|
|
3495
4474
|
REOPEN_MECHANISM,
|
|
3496
4475
|
RICH_COMPOSER_ACTION,
|
|
3497
4476
|
RichMessageComposer,
|
|
3498
4477
|
SimpleEmojiPicker,
|
|
4478
|
+
SortableHead,
|
|
3499
4479
|
StatusTicks,
|
|
3500
4480
|
TEMPLATE_SETTINGS_TAB,
|
|
3501
4481
|
ToastProvider,
|
|
@@ -3540,12 +4520,16 @@ export {
|
|
|
3540
4520
|
useConversations,
|
|
3541
4521
|
useConversationsInbox,
|
|
3542
4522
|
useDarkMode,
|
|
4523
|
+
useDebouncedValue,
|
|
3543
4524
|
useGlobalRealtime,
|
|
3544
4525
|
useInboxActions,
|
|
3545
4526
|
useIsDarkTheme,
|
|
3546
4527
|
useIsNarrow,
|
|
3547
4528
|
useScrollToLatestMessage,
|
|
3548
4529
|
useToast,
|
|
4530
|
+
useUrlArrayState,
|
|
4531
|
+
useUrlNumberState,
|
|
4532
|
+
useUrlStringState,
|
|
3549
4533
|
useWaitingNotifications,
|
|
3550
4534
|
waToHTML,
|
|
3551
4535
|
waToHTMLInline,
|