diff --git a/lib/public/assets/icons/whatsapp.svg b/lib/public/assets/icons/whatsapp.svg new file mode 100644 index 00000000..70e0037e --- /dev/null +++ b/lib/public/assets/icons/whatsapp.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/lib/public/js/components/agents-tab/create-channel-modal.js b/lib/public/js/components/agents-tab/create-channel-modal.js index 52e4e029..191c251d 100644 --- a/lib/public/js/components/agents-tab/create-channel-modal.js +++ b/lib/public/js/components/agents-tab/create-channel-modal.js @@ -18,6 +18,7 @@ const kChannelEnvKeys = { telegram: "TELEGRAM_BOT_TOKEN", discord: "DISCORD_BOT_TOKEN", slack: "SLACK_BOT_TOKEN", + whatsapp: "WHATSAPP_OWNER_NUMBER", }; const kChannelExtraEnvKeys = { @@ -229,8 +230,10 @@ export const CreateChannelModal = ({ } setName(providerLabel); }, [provider, providerHasAccounts, nameEditedManually, isEditMode]); + const normalizedProvider = String(provider || "").trim(); const isSingleAccountProvider = isSingleAccountChannelProvider(provider); - const needsAppToken = String(provider || "").trim() === "slack"; + const needsAppToken = normalizedProvider === "slack"; + const isWhatsApp = normalizedProvider === "whatsapp"; const accountId = useMemo(() => { if (isEditMode) { @@ -419,20 +422,34 @@ export const CreateChannelModal = ({ diff --git a/lib/public/js/components/channel-login-modal.js b/lib/public/js/components/channel-login-modal.js new file mode 100644 index 00000000..e59a074e --- /dev/null +++ b/lib/public/js/components/channel-login-modal.js @@ -0,0 +1,82 @@ +import { h } from "https://esm.sh/preact"; +import htm from "https://esm.sh/htm"; +import { ActionButton } from "./action-button.js"; +import { CloseIcon } from "./icons.js"; +import { ModalShell } from "./modal-shell.js"; +import { PageHeader } from "./page-header.js"; + +const html = htm.bind(h); + +export const ChannelLoginModal = ({ + visible = false, + loading = false, + title = "Link Channel", + output = "", + error = "", + runDisabled = false, + runLabel = "Generate QR", + runLoadingLabel = "Running...", + closeLabel = "Close", + onRun = async () => {}, + onClose = () => {}, +}) => { + if (!visible) return null; + const hasOutput = !!String(output || "").trim(); + const hasError = !!String(error || "").trim(); + const displayOutput = hasOutput + ? String(output) + : hasError + ? String(error) + : "No output yet. Generate QR to start login."; + return html` + <${ModalShell} + visible=${visible} + onClose=${onClose} + panelClassName="bg-modal border border-border rounded-xl p-6 max-w-2xl w-full space-y-4" + > + <${PageHeader} + title=${title} + actions=${html` + + `} + /> +
+

+ Click "Generate QR" to run channel login and capture terminal output. +

+