))}
{tableHiddenFieldCount > 0 ? (
@@ -666,11 +666,43 @@ export function FormSubmissionsPanel({ formId, formName, onClose }: Props) {
);
}
-function formatCell(v: unknown): string {
+function formatCell(v: unknown, fieldType?: string): string {
if (v == null) return "—";
if (typeof v === "boolean") return v ? "Yes" : "No";
- if (Array.isArray(v)) return v.join(", ");
+ const sep = fieldType === "rank" ? " → " : ", ";
+ if (Array.isArray(v)) {
+ const joined = v.map((x) => String(x ?? "").trim()).filter(Boolean).join(sep);
+ return joined || "—";
+ }
+ if (typeof v === "object") {
+ const rec = v as Record;
+ if (rec.ranks && typeof rec.ranks === "object" && !Array.isArray(rec.ranks)) {
+ const items: { label: string; rank: number }[] = [];
+ for (const [label, rank] of Object.entries(rec.ranks as Record)) {
+ if (label === "__other__") {
+ const text = String(rec.otherText ?? "").trim();
+ const n = Number(rank);
+ if (text && Number.isFinite(n) && n > 0) items.push({ label: text, rank: n });
+ continue;
+ }
+ const n = Number(rank);
+ if (Number.isFinite(n) && n > 0) items.push({ label: String(label), rank: n });
+ }
+ items.sort((a, b) => a.rank - b.rank);
+ if (items.length) return items.map((i) => i.label).join(sep);
+ }
+ const keys = Object.keys(rec);
+ if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
+ const joined = keys
+ .sort((a, b) => Number(a) - Number(b))
+ .map((k) => String(rec[k] ?? "").trim())
+ .filter(Boolean)
+ .join(sep);
+ return joined || "—";
+ }
+ }
const s = String(v);
+ if (!s || s === "[object Object]") return "—";
if (s.length > 500) return `${s.slice(0, 500)}…`;
return s;
}
diff --git a/src/app/components/whatsapp-chatbot/WhatsAppChatbotsPage.tsx b/src/app/components/whatsapp-chatbot/WhatsAppChatbotsPage.tsx
index 22a25e7e..a8b09de4 100644
--- a/src/app/components/whatsapp-chatbot/WhatsAppChatbotsPage.tsx
+++ b/src/app/components/whatsapp-chatbot/WhatsAppChatbotsPage.tsx
@@ -83,7 +83,7 @@ function buildEmbedSnippet(botId: string, accentColor?: string | null) {
const apiBase = CONCIERGE_API_BASE;
const widgetSrc = apiBase.replace(/\/api\/?$/, "") + "/embed/concierge-widget.js";
const accent = String(accentColor || "").trim() || "rgb(13, 148, 136)";
- return `\n`;
+ return `\n`;
}
export function WhatsAppChatbotsPage() {
@@ -172,6 +172,8 @@ export function WhatsAppChatbotsPage() {
wabaPhoneNumberId: bot.wabaPhoneNumberId,
eventId: nextEventId || undefined,
enabled: Boolean(bot.enabled),
+ voiceEnabled: Boolean(bot.voiceEnabled),
+ videoAvatarEnabled: bot.videoAvatarEnabled !== false,
greeting: bot.greeting,
registration: bot.registration,
knowledge: bot.knowledge
@@ -536,6 +538,29 @@ export function WhatsAppChatbotsPage() {
/>
Enable chatbot
+
+
+
+
+
+
+ Removes all WhatsApp visitors for this desk so the next message from an existing number is treated as
+ new (welcome + drips).
+
+
{!info?.canSendMessages && (
WhatsApp Cloud is not ready to send. Configure WABA ID, token, and phone number ID in Organisation
@@ -222,17 +343,37 @@ export function WhatsAppReceptionTab({
src={`data:image/png;base64,${info.qrPngBase64}`}
style={{ width: 180, height: 180, background: "#fff", borderRadius: 8 }}
/>
-
+
+
+ Logo uses high error correction so the code still scans. Prefer Meta’s brand guidelines for posters.
+