@mailoo/chat 0.0.0-stage → 1.32.2

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.
Files changed (58) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +150 -2
  3. package/dist/chat-message-Dw6tKBEb.d.cts +10 -0
  4. package/dist/chat-message-Dw6tKBEb.d.ts +10 -0
  5. package/dist/chunk-2Y37RYEL.js +141 -0
  6. package/dist/chunk-2Y37RYEL.js.map +1 -0
  7. package/dist/chunk-4TNHJERE.js +19 -0
  8. package/dist/chunk-4TNHJERE.js.map +1 -0
  9. package/dist/chunk-77E6HUHY.js +41 -0
  10. package/dist/chunk-77E6HUHY.js.map +1 -0
  11. package/dist/chunk-AU6EFFLV.js +431 -0
  12. package/dist/chunk-AU6EFFLV.js.map +1 -0
  13. package/dist/chunk-QZ7HWQDO.js +839 -0
  14. package/dist/chunk-QZ7HWQDO.js.map +1 -0
  15. package/dist/client/index.cjs +1658 -0
  16. package/dist/client/index.cjs.map +1 -0
  17. package/dist/client/index.d.cts +33 -0
  18. package/dist/client/index.d.ts +33 -0
  19. package/dist/client/index.js +597 -0
  20. package/dist/client/index.js.map +1 -0
  21. package/dist/hooks/index.cjs +751 -0
  22. package/dist/hooks/index.cjs.map +1 -0
  23. package/dist/hooks/index.d.cts +79 -0
  24. package/dist/hooks/index.d.ts +79 -0
  25. package/dist/hooks/index.js +32 -0
  26. package/dist/hooks/index.js.map +1 -0
  27. package/dist/index.cjs +213 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +53 -0
  30. package/dist/index.d.ts +53 -0
  31. package/dist/index.js +27 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/mailoo-site-chat-widget-C7B797Lu.d.ts +130 -0
  34. package/dist/mailoo-site-chat-widget-h_cBqsJw.d.cts +130 -0
  35. package/dist/routes/index.cjs +204 -0
  36. package/dist/routes/index.cjs.map +1 -0
  37. package/dist/routes/index.d.cts +30 -0
  38. package/dist/routes/index.d.ts +30 -0
  39. package/dist/routes/index.js +174 -0
  40. package/dist/routes/index.js.map +1 -0
  41. package/dist/shared-glVmghqk.d.cts +40 -0
  42. package/dist/shared-glVmghqk.d.ts +40 -0
  43. package/dist/styles/widget.css +122 -0
  44. package/dist/welcome-presets/index.cjs +479 -0
  45. package/dist/welcome-presets/index.cjs.map +1 -0
  46. package/dist/welcome-presets/index.d.cts +53 -0
  47. package/dist/welcome-presets/index.d.ts +53 -0
  48. package/dist/welcome-presets/index.js +38 -0
  49. package/dist/welcome-presets/index.js.map +1 -0
  50. package/dist/welcome-presets/parse.cjs +44 -0
  51. package/dist/welcome-presets/parse.cjs.map +1 -0
  52. package/dist/welcome-presets/parse.d.cts +11 -0
  53. package/dist/welcome-presets/parse.d.ts +11 -0
  54. package/dist/welcome-presets/parse.js +9 -0
  55. package/dist/welcome-presets/parse.js.map +1 -0
  56. package/dist/widget-config-B5Tf7gqn.d.cts +32 -0
  57. package/dist/widget-config-B5Tf7gqn.d.ts +32 -0
  58. package/package.json +85 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/index.ts","../../src/components/mailoo-site-chat-widget.tsx","../../src/hooks/index.ts","../../src/lib/chat-message.ts","../../src/hooks/shared.ts","../../src/hooks/use-mailoo-chat-session.ts","../../src/lib/guest-copy.ts","../../src/lib/visitor-ws-url.ts","../../src/lib/widget-config.ts","../../src/components/mailoo-chat-unavailable-panel.tsx","../../src/components/mailoo-site-chat-shell.tsx","../../src/welcome-presets/shared.tsx","../../src/welcome-presets/assistant.tsx","../../src/welcome-presets/team.tsx","../../src/welcome-presets/preset-context.tsx","../../src/welcome-presets/preset-switcher.tsx","../../src/welcome-presets/index.ts"],"sourcesContent":["'use client'\n\nexport {\n MailooSiteChatWidget,\n type MailooChatWidgetProps,\n type MailooChatUiLabels,\n type MailooChatMessage,\n type MailooChatWelcomeRenderArgs,\n type MailooChatWidgetConfig,\n type MailooChatLauncherPosition,\n type MailooChatUnavailableAction,\n type MailooChatUnavailableRenderArgs,\n type MailooChatFault,\n} from '../components/mailoo-site-chat-widget.js'\nexport {\n MailooChatUnavailablePanel,\n} from '../components/mailoo-chat-unavailable-panel.js'\nexport {\n MailooSiteChatShell,\n openMailooSiteChat,\n MAILOO_SITE_CHAT_OPEN_EVENT,\n type MailooSiteChatShellConfig,\n type MailooSiteChatShellProps,\n} from '../components/mailoo-site-chat-shell.js'\n","'use client'\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport {\n ChatBubbleLeftRightIcon,\n ChevronLeftIcon,\n ChevronUpIcon,\n InformationCircleIcon,\n XMarkIcon,\n} from '@heroicons/react/24/outline'\nimport {\n useMailooChatSession,\n type MailooChatFault,\n} from '../hooks/index.js'\nimport {\n defaultChatUiLabels,\n type MailooChatUiLabels,\n} from '../lib/guest-copy.js'\nimport {\n chatWidgetCssVariables,\n mailooChatLauncherRootClassNames,\n resolveMailooChatLauncherPosition,\n type MailooChatLauncherPosition,\n type MailooChatWidgetConfig,\n} from '../lib/widget-config.js'\nimport {\n MailooChatUnavailablePanel,\n type MailooChatUnavailableAction,\n type MailooChatUnavailableRenderArgs,\n} from './mailoo-chat-unavailable-panel.js'\n\nexport type { MailooChatMessage } from '../lib/chat-message.js'\nexport type { MailooChatUiLabels }\nexport type { MailooChatWidgetConfig, MailooChatLauncherPosition }\nexport type {\n MailooChatUnavailableAction,\n MailooChatUnavailableRenderArgs,\n}\nexport type { MailooChatFault }\n\nexport type MailooChatWidgetProps = {\n apiOrigin: string\n projectUid: string\n integrationId: string\n welcomeMessage: string\n locale: string\n isAuthenticated: boolean\n widgetConfig?: MailooChatWidgetConfig | null\n className?: string\n panelClassName?: string\n launcherClassName?: string\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n title?: string\n launcherLabel?: string\n labels?: Partial<MailooChatUiLabels>\n submitEndpoint?: string\n messagesEndpoint?: string\n pollIntervalMs?: number\n enablePolling?: boolean\n enableWebSocket?: boolean\n position?: MailooChatLauncherPosition\n zIndex?: number\n onSessionCreated?: (sessionPublicId: string) => void\n onMessageSent?: (content: string) => void\n onError?: (error: string) => void\n onFault?: (fault: MailooChatFault) => void\n /** Integrator-chosen contact/link when chat is rate-limited or unavailable. */\n unavailableAction?: MailooChatUnavailableAction\n renderLauncher?: (args: { open: boolean; toggle: () => void }) => ReactNode\n renderHeader?: (args: { welcomeMessage: string; title: string }) => ReactNode\n renderEmpty?: (args: { isAuthenticated: boolean }) => ReactNode\n renderWelcome?: (args: MailooChatWelcomeRenderArgs) => ReactNode\n /** Replace the built-in unavailable panel; package still classifies the fault. */\n renderUnavailable?: (args: MailooChatUnavailableRenderArgs) => ReactNode\n}\n\nexport type MailooChatWelcomeRenderArgs = {\n widgetConfig: MailooChatWidgetConfig | null | undefined\n welcomeMessage: string\n title: string\n locale: string\n labels: MailooChatUiLabels\n brandBtnClass: string\n brandStyle?: React.CSSProperties\n topics: MailooChatWidgetConfig['topics']\n selectedTopicId: string | null\n setSelectedTopicId: (id: string | null) => void\n /** When false, identity comes from session / saved guest profile — no email form. */\n needsGuestFields: boolean\n isAuthenticated: boolean\n guestEmail: string\n setGuestEmail: (value: string) => void\n guestName: string\n setGuestName: (value: string) => void\n error: string | null\n /** Continue from welcome: validates guest email when needed, then enters composer. */\n confirmGuestContact: (invalidEmailMessage?: string) => boolean\n}\n\nexport function MailooSiteChatWidget(props: MailooChatWidgetProps) {\n const {\n apiOrigin,\n projectUid,\n integrationId,\n welcomeMessage,\n locale,\n isAuthenticated,\n widgetConfig,\n className,\n panelClassName,\n launcherClassName,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n title: titleProp,\n launcherLabel,\n labels: labelsProp,\n submitEndpoint,\n messagesEndpoint,\n pollIntervalMs,\n enablePolling,\n enableWebSocket,\n position: positionProp,\n zIndex,\n onSessionCreated,\n onMessageSent,\n onError,\n onFault,\n unavailableAction,\n renderLauncher,\n renderHeader,\n renderEmpty,\n renderWelcome,\n renderUnavailable,\n } = props\n\n const t: MailooChatUiLabels = {\n ...defaultChatUiLabels(locale),\n ...labelsProp,\n }\n const title = titleProp ?? t.title\n\n const isControlled = openProp !== undefined\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen)\n const open = isControlled ? openProp : uncontrolledOpen\n const setOpen = (next: boolean) => {\n onOpenChange?.(next)\n if (!isControlled) setUncontrolledOpen(next)\n }\n\n const [input, setInput] = useState('')\n const [threadHintExpanded, setThreadHintExpanded] = useState(false)\n const [selectedTopicId, setSelectedTopicId] = useState<string | null>(null)\n /** Welcome dismissed via Continue; independent of auth / guestContactOk. */\n const [welcomeDone, setWelcomeDone] = useState(false)\n const messagesScrollRef = useRef<HTMLDivElement | null>(null)\n /** When true, new messages pin the pane to the bottom. Cleared when user scrolls up. */\n const stickToBottomRef = useRef(true)\n const SCROLL_NEAR_BOTTOM_PX = 80\n\n const brandStyle = chatWidgetCssVariables(widgetConfig ?? undefined)\n const brandBtn =\n 'rounded bg-[var(--mailoo-chat-brand,#2563eb)] text-[var(--mailoo-chat-brand-on,#ffffff)] hover:opacity-90'\n const headerTitle = widgetConfig?.welcomeTitle ?? title\n const headerTagline = widgetConfig?.welcomeTagline ?? welcomeMessage\n const topics = widgetConfig?.topics ?? []\n const anyOperatorOnline = (widgetConfig?.operators ?? []).some(\n (op) => op.online\n )\n\n const session = useMailooChatSession({\n apiOrigin,\n projectUid,\n integrationId,\n isAuthenticated,\n submitEndpoint,\n messagesEndpoint,\n pollIntervalMs,\n enablePolling,\n enableWebSocket,\n enabled: open,\n onSessionCreated,\n onMessageSent,\n onError,\n onFault,\n })\n\n const {\n messages,\n sending,\n error,\n fault,\n retryAfterFault,\n guestEmail,\n guestName,\n setGuestEmail,\n setGuestName,\n guestContactOk,\n guestProfileHydrated,\n confirmGuestContact,\n resetGuestContact,\n canCompose,\n sendMessage,\n } = session\n\n const onMessagesScroll = useCallback(() => {\n const el = messagesScrollRef.current\n if (!el) return\n const distanceFromBottom =\n el.scrollHeight - el.scrollTop - el.clientHeight\n stickToBottomRef.current = distanceFromBottom <= SCROLL_NEAR_BOTTOM_PX\n }, [])\n\n useEffect(() => {\n if (!stickToBottomRef.current) return\n const el = messagesScrollRef.current\n if (!el) return\n el.scrollTop = el.scrollHeight\n }, [messages])\n\n const send = async () => {\n const text = input.trim()\n if (!text || sending) return\n stickToBottomRef.current = true\n const ok = await sendMessage(text, {\n invalidEmailMessage: t.emailInvalid,\n topicId: selectedTopicId ?? undefined,\n })\n if (ok) setInput('')\n }\n\n const toggle = () => setOpen(!open)\n const position = resolveMailooChatLauncherPosition(\n positionProp,\n widgetConfig\n )\n\n const needsGuestFields = !isAuthenticated && !guestContactOk\n const showUnavailable = fault != null\n const showEntry =\n !showUnavailable &&\n guestProfileHydrated &&\n messages.length === 0 &&\n !welcomeDone\n const showWelcomeSkin = showEntry && renderWelcome != null\n const showBuiltinEntry = showEntry && renderWelcome == null\n const showComposer =\n !showUnavailable &&\n (welcomeDone || messages.length > 0) &&\n canCompose\n const showDefaultHeader = !showWelcomeSkin || showUnavailable\n\n const unavailableArgs: MailooChatUnavailableRenderArgs | null = fault\n ? {\n fault,\n labels: t,\n retry: retryAfterFault,\n unavailableAction,\n brandBtnClass: brandBtn,\n }\n : null\n\n const enterFromWelcome = (invalidEmailMessage?: string): boolean => {\n if (isAuthenticated || guestContactOk) {\n setWelcomeDone(true)\n return true\n }\n const ok = confirmGuestContact(invalidEmailMessage)\n if (ok) setWelcomeDone(true)\n return ok\n }\n\n const onResetGuestContact = () => {\n setWelcomeDone(false)\n resetGuestContact()\n }\n\n const backToTopics = () => {\n setWelcomeDone(false)\n setThreadHintExpanded(false)\n }\n\n const canReturnToTopics = welcomeDone && !showUnavailable\n\n const welcomeArgs: MailooChatWelcomeRenderArgs = {\n widgetConfig,\n welcomeMessage: headerTagline,\n title: headerTitle,\n locale,\n labels: t,\n brandBtnClass: brandBtn,\n brandStyle,\n topics,\n selectedTopicId,\n setSelectedTopicId,\n needsGuestFields,\n isAuthenticated,\n guestEmail,\n setGuestEmail,\n guestName,\n setGuestName,\n error,\n confirmGuestContact: enterFromWelcome,\n }\n\n const rootClass = [\n mailooChatLauncherRootClassNames(position),\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n className={rootClass}\n data-clarity-mask=\"true\"\n style={{\n ...brandStyle,\n ...(zIndex != null ? { zIndex } : {}),\n }}\n >\n {open && (\n <div\n className={`mailoo-chat-panel ${panelClassName ?? ''}`}\n style={brandStyle}\n >\n {showDefaultHeader &&\n (renderHeader ? (\n renderHeader({\n welcomeMessage: headerTagline,\n title: headerTitle,\n })\n ) : (\n <div className=\"flex items-start gap-1 border-b border-gray-200 px-2 py-2 dark:border-gray-700\">\n {canReturnToTopics ? (\n <button\n type=\"button\"\n onClick={backToTopics}\n className=\"mt-0.5 shrink-0 rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-800 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-100\"\n aria-label={t.backToTopics}\n title={t.backToTopics}\n >\n <ChevronLeftIcon className=\"h-5 w-5\" aria-hidden />\n </button>\n ) : null}\n <div className=\"min-w-0 flex-1 px-1\">\n <p className=\"text-sm font-medium text-gray-900 dark:text-white\">\n {headerTitle}\n </p>\n <p className=\"text-xs text-gray-500 dark:text-gray-400\">\n {headerTagline}\n </p>\n </div>\n </div>\n ))}\n\n {!isAuthenticated && !guestProfileHydrated && !showUnavailable && (\n <p className=\"border-b border-gray-200 p-3 text-sm text-gray-500 dark:border-gray-700 dark:text-gray-400\">\n {t.loadingProfile}\n </p>\n )}\n\n {showUnavailable && unavailableArgs ? (\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n {messages.length > 0 ? (\n <div className=\"min-h-0 max-h-[40%] space-y-2 overflow-y-auto border-b border-gray-200 p-3 text-sm dark:border-gray-700\">\n {messages.map((m) => (\n <div\n key={m.id}\n className={\n m.messageType === 'OUTBOUND'\n ? 'mailoo-chat-bubble--outbound ml-6 rounded-md p-2'\n : 'mailoo-chat-bubble--inbound mr-6 rounded-md p-2'\n }\n >\n <p className=\"whitespace-pre-wrap text-gray-900 dark:text-gray-100\">\n {m.content}\n </p>\n </div>\n ))}\n </div>\n ) : null}\n {renderUnavailable\n ? renderUnavailable(unavailableArgs)\n : MailooChatUnavailablePanel(unavailableArgs)}\n </div>\n ) : null}\n\n {showWelcomeSkin && (\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n {renderWelcome(welcomeArgs)}\n </div>\n )}\n\n {showBuiltinEntry && (\n <div className=\"space-y-3 border-b border-gray-200 p-3 text-sm dark:border-gray-700\">\n {topics.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {topics.map((topic) =>\n topic.action === 'external_url' && topic.externalUrl ? (\n <a\n key={topic.id}\n href={topic.externalUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`px-2 py-1 text-xs font-medium ${brandBtn}`}\n >\n {topic.label}\n </a>\n ) : (\n <button\n key={topic.id}\n type=\"button\"\n onClick={() =>\n setSelectedTopicId((prev) =>\n prev === topic.id ? null : topic.id\n )\n }\n className={`px-2 py-1 text-xs font-medium ${\n selectedTopicId === topic.id\n ? brandBtn\n : 'rounded border border-gray-300 text-gray-700 dark:border-gray-600 dark:text-gray-200'\n }`}\n >\n {topic.label}\n </button>\n )\n )}\n </div>\n )}\n {needsGuestFields && (\n <>\n <p className=\"text-gray-700 dark:text-gray-300\">{t.intro}</p>\n <div>\n <label\n htmlFor=\"mailoo-chat-guest-email\"\n className=\"mb-1 block text-xs font-medium text-gray-600 dark:text-gray-400\"\n >\n {t.emailLabel}\n </label>\n <input\n id=\"mailoo-chat-guest-email\"\n type=\"email\"\n autoComplete=\"email\"\n value={guestEmail}\n onChange={(e) => setGuestEmail(e.target.value)}\n placeholder={t.emailPlaceholder}\n className=\"w-full rounded border border-gray-300 bg-white px-2 py-1.5 text-sm dark:border-gray-600 dark:bg-gray-800\"\n />\n </div>\n <div>\n <label\n htmlFor=\"mailoo-chat-guest-name\"\n className=\"mb-1 block text-xs font-medium text-gray-600 dark:text-gray-400\"\n >\n {t.nameLabel}\n </label>\n <input\n id=\"mailoo-chat-guest-name\"\n type=\"text\"\n autoComplete=\"name\"\n value={guestName}\n onChange={(e) => setGuestName(e.target.value)}\n placeholder={t.namePlaceholder}\n className=\"w-full rounded border border-gray-300 bg-white px-2 py-1.5 text-sm dark:border-gray-600 dark:bg-gray-800\"\n />\n </div>\n {error && (\n <p className=\"text-xs text-red-600 dark:text-red-400\">\n {error}\n </p>\n )}\n </>\n )}\n <button\n type=\"button\"\n onClick={() => enterFromWelcome(t.emailInvalid)}\n className={`w-full py-2 text-sm font-medium ${brandBtn}`}\n >\n {t.continueCta}\n </button>\n </div>\n )}\n\n {showComposer && (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n {!isAuthenticated && (\n <>\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-gray-100 px-3 py-1.5 text-[11px] text-gray-500 dark:border-gray-800 dark:text-gray-400\">\n <span className=\"truncate\">{guestEmail}</span>\n <button\n type=\"button\"\n onClick={() => onResetGuestContact()}\n className=\"shrink-0 text-[var(--mailoo-chat-brand,#2563eb)] hover:underline\"\n >\n {t.changeContact}\n </button>\n </div>\n {threadHintExpanded && (\n <div className=\"shrink-0 border-b border-gray-100 px-3 py-2 dark:border-gray-800\">\n <div className=\"flex items-start gap-2\">\n <p className=\"min-w-0 flex-1 text-[11px] leading-snug text-gray-500 dark:text-gray-400\">\n {t.threadHint}\n </p>\n <button\n type=\"button\"\n onClick={() => setThreadHintExpanded(false)}\n className=\"shrink-0 rounded p-0.5 text-gray-400 hover:bg-gray-100 hover:text-gray-600 dark:hover:bg-gray-700 dark:hover:text-gray-300\"\n aria-label={t.threadHintCollapse}\n title={t.threadHintCollapse}\n >\n <ChevronUpIcon className=\"h-4 w-4\" aria-hidden />\n </button>\n </div>\n </div>\n )}\n </>\n )}\n <div className=\"relative min-h-0 w-full min-w-0 flex-1\">\n {!isAuthenticated && !threadHintExpanded && (\n <button\n type=\"button\"\n onClick={() => setThreadHintExpanded(true)}\n className=\"absolute right-3 top-2 z-20 rounded-full bg-white/95 p-1 shadow-md ring-1 ring-gray-200/80 hover:bg-gray-50 dark:bg-gray-800/95 dark:ring-gray-600 dark:hover:bg-gray-700\"\n aria-expanded={false}\n aria-label={t.threadHintIconLabel}\n title={t.threadHintIconLabel}\n >\n <InformationCircleIcon\n className=\"h-5 w-5 text-gray-600 dark:text-gray-300\"\n aria-hidden\n />\n </button>\n )}\n <div\n ref={messagesScrollRef}\n onScroll={onMessagesScroll}\n className={`h-full min-h-0 space-y-2 overflow-y-auto p-3 text-sm ${\n !isAuthenticated && !threadHintExpanded ? 'pr-12 pt-2' : ''\n }`}\n >\n {messages.length === 0 &&\n (renderEmpty ? (\n renderEmpty({ isAuthenticated })\n ) : (\n <p className=\"text-gray-500 dark:text-gray-400\">\n {isAuthenticated\n ? t.emptyThreadAuthenticated\n : t.emptyThreadGuest}\n </p>\n ))}\n {messages.map((m) => (\n <div\n key={m.id}\n className={\n m.messageType === 'OUTBOUND'\n ? 'mailoo-chat-bubble--outbound ml-6 rounded-md p-2'\n : 'mailoo-chat-bubble--inbound mr-6 rounded-md p-2'\n }\n >\n <p className=\"whitespace-pre-wrap text-gray-900 dark:text-gray-100\">\n {m.content}\n </p>\n <p className=\"mt-1 text-[10px] text-gray-400\">\n {new Date(m.createdAt).toLocaleString()}\n </p>\n </div>\n ))}\n </div>\n </div>\n {error && guestContactOk && (\n <p className=\"px-3 text-xs text-red-600 dark:text-red-400\">\n {error}\n </p>\n )}\n {widgetConfig?.privacyPolicyUrl && (\n <p className=\"px-3 pb-1 text-[10px] text-gray-500 dark:text-gray-400\">\n <a\n href={widgetConfig.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline hover:text-gray-700 dark:hover:text-gray-300\"\n >\n Privacy\n </a>\n </p>\n )}\n <div className=\"flex shrink-0 gap-2 border-t border-gray-200 p-2 dark:border-gray-700\">\n <input\n type=\"text\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') void send()\n }}\n placeholder={t.composerPlaceholder}\n className=\"min-w-0 flex-1 rounded border border-gray-300 bg-white px-2 py-1.5 text-sm dark:border-gray-600 dark:bg-gray-800\"\n />\n <button\n type=\"button\"\n onClick={() => void send()}\n disabled={sending}\n className={`px-3 py-1.5 text-sm font-medium disabled:opacity-50 ${brandBtn}`}\n >\n {t.send}\n </button>\n </div>\n </div>\n )}\n </div>\n )}\n {renderLauncher ? (\n renderLauncher({ open, toggle })\n ) : (\n <button\n type=\"button\"\n onClick={toggle}\n className={`mailoo-chat-launcher ${launcherClassName ?? ''}`}\n aria-label={\n open ? t.launcherClose : (launcherLabel ?? t.launcherOpen)\n }\n >\n {open ? (\n <XMarkIcon className=\"mailoo-chat-launcher__icon\" aria-hidden />\n ) : (\n <ChatBubbleLeftRightIcon\n className=\"mailoo-chat-launcher__icon\"\n aria-hidden\n />\n )}\n {!open && anyOperatorOnline ? (\n <span className=\"mailoo-chat-launcher__online\" aria-hidden />\n ) : null}\n </button>\n )}\n </div>\n )\n}\n","'use client'\n\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n parseChatMessages,\n type MailooChatMessage,\n} from '../lib/chat-message.js'\nimport {\n DEFAULT_CHAT_MESSAGES_ENDPOINT,\n DEFAULT_CHAT_STATUS_ENDPOINT,\n DEFAULT_CHAT_SUBMIT_ENDPOINT,\n messageFromPayload,\n type MailooChatStatus,\n type MailooChatSubmitResult,\n} from './shared.js'\n\nexport type { MailooChatMessage }\nexport {\n classifyChatFault,\n DEFAULT_CHAT_GUEST_PROFILE_KEY,\n DEFAULT_CHAT_MESSAGES_ENDPOINT,\n DEFAULT_CHAT_POLL_INTERVAL_MS,\n DEFAULT_CHAT_SESSION_STORAGE_KEY,\n DEFAULT_CHAT_STATUS_ENDPOINT,\n DEFAULT_CHAT_SUBMIT_ENDPOINT,\n isChatSessionNotFound,\n messageFromPayload,\n type MailooChatConnectionState,\n type MailooChatFault,\n type MailooChatFaultKind,\n type MailooChatStatus,\n type MailooChatSubmitResult,\n} from './shared.js'\nexport {\n useMailooChatSession,\n type UseMailooChatSessionOptions,\n} from './use-mailoo-chat-session.js'\n\nexport function useMailooChatSubmit(options?: { endpoint?: string }) {\n const endpoint = options?.endpoint ?? DEFAULT_CHAT_SUBMIT_ENDPOINT\n const [pending, setPending] = useState(false)\n\n const submit = useCallback(\n async (body: Record<string, unknown>): Promise<MailooChatSubmitResult> => {\n setPending(true)\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n return {\n ok: false,\n status: res.status,\n message: messageFromPayload(data, 'Send failed'),\n }\n }\n return { ok: true, status: res.status, data }\n } catch {\n return { ok: false, status: 0, message: 'Network error' }\n } finally {\n setPending(false)\n }\n },\n [endpoint]\n )\n\n return { submit, pending }\n}\n\nexport function useMailooChatMessages(options?: { endpoint?: string }) {\n const endpoint = options?.endpoint ?? DEFAULT_CHAT_MESSAGES_ENDPOINT\n const [pending, setPending] = useState(false)\n\n const refresh = useCallback(\n async (\n sessionPublicId: string,\n since?: string\n ): Promise<MailooChatSubmitResult & { messages?: MailooChatMessage[] }> => {\n setPending(true)\n try {\n const params = new URLSearchParams({ sessionPublicId })\n if (since) params.set('since', since)\n const res = await fetch(`${endpoint}?${params.toString()}`)\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n return {\n ok: false,\n status: res.status,\n message: messageFromPayload(data, 'Fetch failed'),\n }\n }\n const rows = Array.isArray((data as { data?: unknown[] }).data)\n ? (data as { data: unknown[] }).data\n : []\n return {\n ok: true,\n status: res.status,\n data,\n messages: parseChatMessages(rows),\n }\n } catch {\n return { ok: false, status: 0, message: 'Network error' }\n } finally {\n setPending(false)\n }\n },\n [endpoint]\n )\n\n return { refresh, pending }\n}\n\nexport function useMailooChatStatus(options?: {\n endpoint?: string\n enabled?: boolean\n}) {\n const endpoint = options?.endpoint ?? DEFAULT_CHAT_STATUS_ENDPOINT\n const enabled = options?.enabled ?? true\n const [status, setStatus] = useState<MailooChatStatus | null>(null)\n const [pending, setPending] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async () => {\n setPending(true)\n setError(null)\n try {\n const res = await fetch(endpoint)\n const data = (await res\n .json()\n .catch(() => ({}))) as Partial<MailooChatStatus> & {\n message?: string\n error?: string\n }\n if (!res.ok) {\n setError(messageFromPayload(data, 'Status fetch failed'))\n return null\n }\n if (\n typeof data.status !== 'string' ||\n typeof data.name !== 'string' ||\n typeof data.type !== 'string' ||\n typeof data.lastActivity !== 'string'\n ) {\n setError('Invalid status payload')\n return null\n }\n const parsed: MailooChatStatus = {\n status: data.status,\n name: data.name,\n type: data.type,\n lastActivity: data.lastActivity,\n }\n setStatus(parsed)\n return parsed\n } catch {\n setError('Network error')\n return null\n } finally {\n setPending(false)\n }\n }, [endpoint])\n\n useEffect(() => {\n if (!enabled) return\n void refresh()\n }, [enabled, refresh])\n\n return { status, pending, error, refresh }\n}\n","export type MailooChatMessage = {\n id: string\n messageType: string\n content: string\n senderEmail?: string | null\n senderName?: string | null\n createdAt: string\n}\n\nexport function parseChatMessages(rows: unknown[]): MailooChatMessage[] {\n const parsed: MailooChatMessage[] = []\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue\n const r = row as Record<string, unknown>\n if (typeof r.id !== 'string' || typeof r.content !== 'string') continue\n parsed.push({\n id: r.id,\n messageType:\n typeof r.messageType === 'string' ? r.messageType : 'INBOUND',\n content: r.content,\n senderEmail: typeof r.senderEmail === 'string' ? r.senderEmail : null,\n senderName: typeof r.senderName === 'string' ? r.senderName : null,\n createdAt:\n typeof r.createdAt === 'string'\n ? r.createdAt\n : new Date().toISOString(),\n })\n }\n return parsed\n}\n\nfunction messagesEqual(\n a: MailooChatMessage[],\n b: MailooChatMessage[]\n): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n const x = a[i]\n const y = b[i]\n if (\n x.id !== y.id ||\n x.content !== y.content ||\n x.messageType !== y.messageType ||\n x.createdAt !== y.createdAt ||\n x.senderEmail !== y.senderEmail ||\n x.senderName !== y.senderName\n ) {\n return false\n }\n }\n return true\n}\n\nexport function mergeChatMessages(\n prev: MailooChatMessage[],\n incoming: MailooChatMessage[]\n): MailooChatMessage[] {\n if (incoming.length === 0) return prev\n\n const byId = new Map<string, MailooChatMessage>()\n for (const m of prev) byId.set(m.id, m)\n for (const m of incoming) byId.set(m.id, m)\n const next = Array.from(byId.values()).sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n )\n return messagesEqual(prev, next) ? prev : next\n}\n\nexport function latestMessageCreatedAt(\n messages: MailooChatMessage[]\n): string | undefined {\n if (messages.length === 0) return undefined\n let latest = messages[0].createdAt\n for (const m of messages) {\n if (new Date(m.createdAt).getTime() > new Date(latest).getTime()) {\n latest = m.createdAt\n }\n }\n return latest\n}\n","export const DEFAULT_CHAT_SUBMIT_ENDPOINT = '/api/v1/webhooks/chat/submit'\nexport const DEFAULT_CHAT_MESSAGES_ENDPOINT = '/api/v1/webhooks/chat/messages'\nexport const DEFAULT_CHAT_STATUS_ENDPOINT = '/api/v1/webhooks/chat/status'\nexport const DEFAULT_CHAT_SESSION_STORAGE_KEY =\n 'mailoo_site_chat_session_public_id'\nexport const DEFAULT_CHAT_GUEST_PROFILE_KEY = 'mailoo_site_chat_guest_profile'\nexport const DEFAULT_CHAT_POLL_INTERVAL_MS = 5000\n\nexport type MailooChatConnectionState =\n 'idle' | 'connecting' | 'open' | 'closed'\n\nexport type MailooChatFaultKind = 'rate_limited' | 'unavailable'\n\n/** Classified chat transport/service fault (not validation or session lifecycle). */\nexport type MailooChatFault = {\n kind: MailooChatFaultKind\n status: number\n message: string\n}\n\nexport type MailooChatSubmitResult =\n | { ok: true; status: number; data: unknown }\n | { ok: false; status: number; message: string }\n\nexport type MailooChatStatus = {\n status: string\n name: string\n type: string\n lastActivity: string\n}\n\nexport function messageFromPayload(data: unknown, fallback: string): string {\n if (!data || typeof data !== 'object') return fallback\n const d = data as { message?: unknown; error?: unknown }\n if (typeof d.message === 'string') return d.message\n if (typeof d.error === 'string') return d.error\n return fallback\n}\n\n/**\n * Classify HTTP/network failures that should show the unavailable panel.\n * Status-based only (no English string parsing). Returns null for validation,\n * 4xx client errors other than 429, and session-not-found (handled separately).\n */\nexport function classifyChatFault(\n status: number,\n payload: unknown,\n fallbackMessage = 'Request failed'\n): MailooChatFault | null {\n if (status === 429) {\n return {\n kind: 'rate_limited',\n status,\n message: messageFromPayload(payload, fallbackMessage),\n }\n }\n // Network failure (fetch throw mapped to 0) or gateway / service errors\n if (status === 0 || status === 502 || status === 503 || status >= 500) {\n return {\n kind: 'unavailable',\n status,\n message: messageFromPayload(payload, fallbackMessage),\n }\n }\n return null\n}\n\n/** Upstream 404 after DB reset / expired sessionStorage id. */\nexport function isChatSessionNotFound(\n status: number,\n data: unknown\n): boolean {\n if (status !== 404) return false\n const text = messageFromPayload(data, '').toLowerCase()\n return text.includes('chat session not found')\n}\n\nexport function persistSessionPublicId(\n id: string,\n storageKey: string,\n ctx: {\n sessionPublicIdRef: { current: string | null }\n setSessionPublicId: (id: string) => void\n onCreated?: (sessionPublicId: string) => void\n }\n) {\n const created = !ctx.sessionPublicIdRef.current\n ctx.setSessionPublicId(id)\n ctx.sessionPublicIdRef.current = id\n try {\n sessionStorage.setItem(storageKey, id)\n } catch {\n /* ignore */\n }\n if (created) ctx.onCreated?.(id)\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n latestMessageCreatedAt,\n mergeChatMessages,\n parseChatMessages,\n type MailooChatMessage,\n} from '../lib/chat-message.js'\nimport { isValidEmail } from '../lib/guest-copy.js'\nimport { buildVisitorWsUrl } from '../lib/visitor-ws-url.js'\nimport {\n classifyChatFault,\n DEFAULT_CHAT_GUEST_PROFILE_KEY,\n DEFAULT_CHAT_MESSAGES_ENDPOINT,\n DEFAULT_CHAT_POLL_INTERVAL_MS,\n DEFAULT_CHAT_SESSION_STORAGE_KEY,\n DEFAULT_CHAT_SUBMIT_ENDPOINT,\n isChatSessionNotFound,\n messageFromPayload,\n persistSessionPublicId,\n type MailooChatConnectionState,\n type MailooChatFault,\n} from './shared.js'\n\nexport type UseMailooChatSessionOptions = {\n apiOrigin: string\n projectUid: string\n integrationId: string\n isAuthenticated: boolean\n submitEndpoint?: string\n messagesEndpoint?: string\n storageKey?: string\n guestProfileKey?: string\n pollIntervalMs?: number\n enableRealtime?: boolean\n enablePolling?: boolean\n enableWebSocket?: boolean\n enabled?: boolean\n onSessionCreated?: (sessionPublicId: string) => void\n onMessageSent?: (content: string) => void\n onError?: (error: string) => void\n onFault?: (fault: MailooChatFault) => void\n}\n\nexport function useMailooChatSession(options: UseMailooChatSessionOptions) {\n const {\n apiOrigin,\n projectUid,\n integrationId,\n isAuthenticated,\n submitEndpoint = DEFAULT_CHAT_SUBMIT_ENDPOINT,\n messagesEndpoint = DEFAULT_CHAT_MESSAGES_ENDPOINT,\n storageKey = DEFAULT_CHAT_SESSION_STORAGE_KEY,\n guestProfileKey = DEFAULT_CHAT_GUEST_PROFILE_KEY,\n pollIntervalMs = DEFAULT_CHAT_POLL_INTERVAL_MS,\n enableRealtime = true,\n enablePolling = true,\n enableWebSocket = true,\n enabled = true,\n onSessionCreated,\n onMessageSent,\n onError,\n onFault,\n } = options\n\n const [sessionPublicId, setSessionPublicId] = useState<string | null>(null)\n const [messages, setMessages] = useState<MailooChatMessage[]>([])\n const [sending, setSending] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [fault, setFault] = useState<MailooChatFault | null>(null)\n const [connectionState, setConnectionState] =\n useState<MailooChatConnectionState>('idle')\n\n const [guestEmail, setGuestEmail] = useState('')\n const [guestName, setGuestName] = useState('')\n const [guestContactOk, setGuestContactOk] = useState(isAuthenticated)\n const [guestProfileHydrated, setGuestProfileHydrated] = useState(false)\n\n const wsRef = useRef<WebSocket | null>(null)\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)\n const sessionPublicIdRef = useRef<string | null>(null)\n const sinceRef = useRef<string | undefined>(undefined)\n const faultRef = useRef<MailooChatFault | null>(null)\n const onSessionCreatedRef = useRef(onSessionCreated)\n const onMessageSentRef = useRef(onMessageSent)\n const onErrorRef = useRef(onError)\n const onFaultRef = useRef(onFault)\n\n sessionPublicIdRef.current = sessionPublicId\n faultRef.current = fault\n onSessionCreatedRef.current = onSessionCreated\n onMessageSentRef.current = onMessageSent\n onErrorRef.current = onError\n onFaultRef.current = onFault\n\n const clearFault = useCallback(() => {\n faultRef.current = null\n setFault(null)\n }, [])\n\n const reportFault = useCallback((next: MailooChatFault) => {\n faultRef.current = next\n setFault(next)\n setError(null)\n onFaultRef.current?.(next)\n onErrorRef.current?.(next.message)\n }, [])\n\n const reportError = useCallback((message: string | null) => {\n setError(message)\n if (message) {\n clearFault()\n onErrorRef.current?.(message)\n }\n }, [clearFault])\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n const existing = sessionStorage.getItem(storageKey)\n if (existing) setSessionPublicId(existing)\n }, [storageKey])\n\n useEffect(() => {\n if (typeof window === 'undefined' || isAuthenticated) {\n setGuestProfileHydrated(true)\n return\n }\n try {\n const raw = sessionStorage.getItem(guestProfileKey)\n if (raw) {\n const j = JSON.parse(raw) as { email?: unknown; name?: unknown }\n const em =\n typeof j.email === 'string' ? j.email.trim().toLowerCase() : ''\n if (em && isValidEmail(em)) {\n setGuestEmail(em)\n setGuestName(typeof j.name === 'string' ? j.name.trim() : '')\n setGuestContactOk(true)\n }\n }\n } catch {\n /* ignore */\n }\n setGuestProfileHydrated(true)\n }, [isAuthenticated, guestProfileKey])\n\n useEffect(() => {\n if (isAuthenticated) {\n setGuestContactOk(true)\n }\n }, [isAuthenticated])\n\n const persistGuestProfile = useCallback(\n (email: string, name: string) => {\n try {\n sessionStorage.setItem(\n guestProfileKey,\n JSON.stringify({\n email: email.trim().toLowerCase(),\n name: name.trim(),\n })\n )\n } catch {\n /* ignore */\n }\n },\n [guestProfileKey]\n )\n\n const confirmGuestContact = useCallback(\n (invalidEmailMessage?: string): boolean => {\n reportError(null)\n if (isAuthenticated) {\n setGuestContactOk(true)\n return true\n }\n if (!isValidEmail(guestEmail)) {\n reportError(\n invalidEmailMessage ?? 'Please enter a valid email address.'\n )\n return false\n }\n persistGuestProfile(guestEmail, guestName)\n setGuestContactOk(true)\n return true\n },\n [\n isAuthenticated,\n guestEmail,\n guestName,\n persistGuestProfile,\n reportError,\n ]\n )\n\n const resetGuestContact = useCallback(() => {\n setGuestContactOk(false)\n reportError(null)\n }, [reportError])\n\n const mergeIncoming = useCallback((rows: unknown[]) => {\n const parsed = parseChatMessages(rows)\n setMessages((prev) => {\n const next = mergeChatMessages(prev, parsed)\n sinceRef.current = latestMessageCreatedAt(next)\n return next\n })\n }, [])\n\n const mergeMessage = useCallback((message: MailooChatMessage) => {\n setMessages((prev) => {\n const next = mergeChatMessages(prev, [message])\n sinceRef.current = latestMessageCreatedAt(next)\n return next\n })\n }, [])\n\n const clearSession = useCallback(() => {\n try {\n sessionStorage.removeItem(storageKey)\n } catch {\n /* ignore */\n }\n setSessionPublicId(null)\n sessionPublicIdRef.current = null\n setMessages([])\n sinceRef.current = undefined\n }, [storageKey])\n\n const stopRealtime = useCallback(() => {\n if (pollRef.current) {\n clearInterval(pollRef.current)\n pollRef.current = null\n }\n wsRef.current?.close()\n wsRef.current = null\n setConnectionState('closed')\n }, [])\n\n const refreshMessages = useCallback(\n async (sid?: string, opts?: { full?: boolean }) => {\n const id = sid ?? sessionPublicIdRef.current\n if (!id) return\n if (faultRef.current) return\n const params = new URLSearchParams({ sessionPublicId: id })\n if (!opts?.full && sinceRef.current) {\n params.set('since', sinceRef.current)\n }\n let res: Response\n try {\n res = await fetch(`${messagesEndpoint}?${params.toString()}`)\n } catch {\n const next = classifyChatFault(0, null, 'Network error')\n if (next) {\n reportFault(next)\n stopRealtime()\n }\n return\n }\n const data = (await res.json().catch(() => ({}))) as {\n data?: unknown[]\n message?: unknown\n error?: unknown\n }\n if (!res.ok) {\n if (isChatSessionNotFound(res.status, data)) {\n clearSession()\n reportError(null)\n return\n }\n const classified = classifyChatFault(\n res.status,\n data,\n 'Failed to load messages'\n )\n if (classified) {\n reportFault(classified)\n stopRealtime()\n return\n }\n reportError(messageFromPayload(data, 'Failed to load messages'))\n return\n }\n if (Array.isArray(data.data)) {\n mergeIncoming(data.data)\n }\n },\n [\n messagesEndpoint,\n mergeIncoming,\n clearSession,\n reportError,\n reportFault,\n stopRealtime,\n ]\n )\n\n useEffect(() => {\n const realtimeOn =\n enabled && enableRealtime && guestContactOk && !fault\n if (!realtimeOn || !sessionPublicId) {\n return\n }\n\n const connectWs = () => {\n if (!enableWebSocket || !apiOrigin || !projectUid || !integrationId) {\n return\n }\n try {\n const url = buildVisitorWsUrl(\n apiOrigin,\n projectUid,\n integrationId,\n sessionPublicId\n )\n setConnectionState('connecting')\n const ws = new WebSocket(url)\n wsRef.current = ws\n ws.onopen = () => setConnectionState('open')\n ws.onmessage = (ev) => {\n try {\n const msg = JSON.parse(ev.data as string) as {\n type?: string\n payload?: {\n messageId?: unknown\n content?: unknown\n messageType?: unknown\n senderEmail?: unknown\n senderName?: unknown\n createdAt?: unknown\n }\n }\n if (msg.type !== 'chat.message') return\n const p = msg.payload\n if (\n p &&\n typeof p.messageId === 'string' &&\n typeof p.content === 'string'\n ) {\n mergeMessage({\n id: p.messageId,\n content: p.content,\n messageType:\n typeof p.messageType === 'string'\n ? p.messageType\n : 'OUTBOUND',\n senderEmail:\n typeof p.senderEmail === 'string' ? p.senderEmail : null,\n senderName:\n typeof p.senderName === 'string' ? p.senderName : null,\n createdAt:\n typeof p.createdAt === 'string'\n ? p.createdAt\n : new Date().toISOString(),\n })\n }\n void refreshMessages(sessionPublicId)\n } catch {\n /* ignore */\n }\n }\n ws.onclose = () => {\n wsRef.current = null\n setConnectionState('closed')\n }\n } catch {\n setConnectionState('closed')\n }\n }\n\n connectWs()\n void refreshMessages(sessionPublicId, { full: true })\n\n if (enablePolling) {\n pollRef.current = setInterval(() => {\n void refreshMessages(sessionPublicId)\n }, pollIntervalMs)\n }\n\n return () => {\n if (pollRef.current) clearInterval(pollRef.current)\n pollRef.current = null\n wsRef.current?.close()\n wsRef.current = null\n setConnectionState('idle')\n }\n }, [\n enabled,\n enableRealtime,\n enablePolling,\n enableWebSocket,\n guestContactOk,\n fault,\n sessionPublicId,\n apiOrigin,\n projectUid,\n integrationId,\n pollIntervalMs,\n refreshMessages,\n mergeMessage,\n ])\n\n const sendMessage = useCallback(\n async (\n content: string,\n opts?: {\n pageUrl?: string\n invalidEmailMessage?: string\n topicId?: string\n }\n ): Promise<boolean> => {\n const text = content.trim()\n if (!text || sending) return false\n if (faultRef.current) return false\n if (!isAuthenticated && !isValidEmail(guestEmail)) {\n reportError(\n opts?.invalidEmailMessage ?? 'Please enter a valid email address.'\n )\n return false\n }\n setSending(true)\n reportError(null)\n clearFault()\n try {\n const buildBody = (includeSession: boolean) => {\n const body: Record<string, string> = { content: text }\n const pageUrl =\n opts?.pageUrl ??\n (typeof window !== 'undefined' ? window.location.href : undefined)\n if (pageUrl) body.pageUrl = pageUrl\n const sid = includeSession ? sessionPublicIdRef.current : null\n if (sid) body.sessionPublicId = sid\n else if (opts?.topicId?.trim()) {\n body.topicId = opts.topicId.trim()\n }\n if (!isAuthenticated) {\n body.senderEmail = guestEmail.trim().toLowerCase()\n if (guestName.trim()) body.senderName = guestName.trim()\n }\n return body\n }\n\n const post = async (includeSession: boolean) => {\n let res: Response\n try {\n res = await fetch(submitEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(buildBody(includeSession)),\n })\n } catch {\n return {\n res: null as Response | null,\n data: {} as {\n sessionPublicId?: string\n messageId?: string\n message?: unknown\n error?: unknown\n },\n networkError: true as const,\n }\n }\n const data = (await res.json().catch(() => ({}))) as {\n sessionPublicId?: string\n messageId?: string\n message?: unknown\n error?: unknown\n }\n return { res, data, networkError: false as const }\n }\n\n let result = await post(true)\n if (result.networkError) {\n const next = classifyChatFault(0, null, 'Network error')\n if (next) {\n reportFault(next)\n stopRealtime()\n }\n return false\n }\n let { res, data } = result\n if (!res) return false\n if (!res.ok && isChatSessionNotFound(res.status, data)) {\n clearSession()\n result = await post(false)\n if (result.networkError) {\n const next = classifyChatFault(0, null, 'Network error')\n if (next) {\n reportFault(next)\n stopRealtime()\n }\n return false\n }\n ;({ res, data } = result)\n if (!res) return false\n }\n if (!res.ok) {\n const classified = classifyChatFault(\n res.status,\n data,\n 'Send failed'\n )\n if (classified) {\n reportFault(classified)\n stopRealtime()\n return false\n }\n reportError(messageFromPayload(data, 'Send failed'))\n return false\n }\n if (data.sessionPublicId) {\n persistSessionPublicId(data.sessionPublicId, storageKey, {\n sessionPublicIdRef,\n setSessionPublicId,\n onCreated: onSessionCreatedRef.current,\n })\n }\n if (!isAuthenticated) {\n persistGuestProfile(guestEmail, guestName)\n }\n if (typeof data.messageId === 'string' && data.messageId) {\n mergeMessage({\n id: data.messageId,\n content: text,\n messageType: 'INBOUND',\n senderEmail: isAuthenticated\n ? null\n : guestEmail.trim().toLowerCase(),\n senderName: isAuthenticated\n ? null\n : guestName.trim() || null,\n createdAt: new Date().toISOString(),\n })\n }\n const nextSid = data.sessionPublicId ?? sessionPublicIdRef.current\n if (nextSid) {\n await refreshMessages(nextSid, { full: true })\n }\n onMessageSentRef.current?.(text)\n return true\n } catch (e) {\n reportError(e instanceof Error ? e.message : 'Send failed')\n return false\n } finally {\n setSending(false)\n }\n },\n [\n sending,\n isAuthenticated,\n guestEmail,\n guestName,\n submitEndpoint,\n storageKey,\n persistGuestProfile,\n mergeMessage,\n refreshMessages,\n clearSession,\n reportError,\n reportFault,\n clearFault,\n stopRealtime,\n ]\n )\n\n const retryAfterFault = useCallback(() => {\n clearFault()\n reportError(null)\n }, [clearFault, reportError])\n\n const canCompose = isAuthenticated || (guestProfileHydrated && guestContactOk)\n\n return {\n sessionPublicId,\n messages,\n sending,\n error,\n fault,\n setError: reportError,\n clearFault,\n retryAfterFault,\n connectionState,\n guestEmail,\n guestName,\n setGuestEmail,\n setGuestName,\n guestContactOk,\n guestProfileHydrated,\n confirmGuestContact,\n resetGuestContact,\n canCompose,\n sendMessage,\n refreshMessages,\n clearSession,\n }\n}\n","export type GuestUiCopy = {\n intro: string\n emailLabel: string\n nameLabel: string\n emailPlaceholder: string\n namePlaceholder: string\n continueCta: string\n changeContact: string\n backToTopics: string\n emailInvalid: string\n threadHint: string\n threadHintIconLabel: string\n threadHintCollapse: string\n emptyThreadGuest: string\n loadingProfile: string\n}\n\nexport type MailooChatUnavailableCopy = {\n rateLimitedTitle: string\n rateLimitedBody: string\n unavailableTitle: string\n unavailableBody: string\n retryCta: string\n contactCta: string\n}\n\nexport type MailooChatUiLabels = GuestUiCopy &\n MailooChatUnavailableCopy & {\n title: string\n launcherOpen: string\n launcherClose: string\n send: string\n composerPlaceholder: string\n emptyThreadAuthenticated: string\n }\n\nexport function isValidEmail(s: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(s.trim())\n}\n\nfunction unavailableCopy(locale: string): MailooChatUnavailableCopy {\n switch (locale) {\n case 'ru':\n return {\n rateLimitedTitle: 'Чат временно недоступен',\n rateLimitedBody:\n 'Слишком много запросов. Подождите немного и попробуйте снова или свяжитесь с нами другим способом.',\n unavailableTitle: 'Чат временно недоступен',\n unavailableBody:\n 'Не удалось связаться с чатом. Попробуйте ещё раз или напишите нам другим способом.',\n retryCta: 'Повторить',\n contactCta: 'Связаться с нами',\n }\n case 'de':\n return {\n rateLimitedTitle: 'Chat vorübergehend nicht verfügbar',\n rateLimitedBody:\n 'Zu viele Anfragen. Bitte warten Sie kurz und versuchen Sie es erneut, oder kontaktieren Sie uns auf anderem Wege.',\n unavailableTitle: 'Chat vorübergehend nicht verfügbar',\n unavailableBody:\n 'Der Chat ist gerade nicht erreichbar. Bitte versuchen Sie es erneut oder kontaktieren Sie uns auf anderem Wege.',\n retryCta: 'Erneut versuchen',\n contactCta: 'Kontakt aufnehmen',\n }\n case 'es':\n return {\n rateLimitedTitle: 'Chat temporalmente no disponible',\n rateLimitedBody:\n 'Hay demasiadas solicitudes. Espera un momento e inténtalo de nuevo, o contáctanos de otra forma.',\n unavailableTitle: 'Chat temporalmente no disponible',\n unavailableBody:\n 'No pudimos conectar con el chat. Inténtalo de nuevo o contáctanos de otra forma.',\n retryCta: 'Reintentar',\n contactCta: 'Contactarnos',\n }\n default:\n return {\n rateLimitedTitle: 'Chat temporarily unavailable',\n rateLimitedBody:\n 'Too many requests right now. Please wait a moment and try again, or reach us another way.',\n unavailableTitle: 'Chat temporarily unavailable',\n unavailableBody:\n 'We could not reach chat right now. Please try again, or contact us another way.',\n retryCta: 'Try again',\n contactCta: 'Contact us',\n }\n }\n}\n\nexport function guestCopy(locale: string): GuestUiCopy {\n switch (locale) {\n case 'ru':\n return {\n intro:\n 'Чтобы мы могли с вами связаться, укажите адрес электронной почты (обязательно) и при желании — имя.',\n emailLabel: 'Электронная почта',\n nameLabel: 'Имя',\n emailPlaceholder: 'you@example.com',\n namePlaceholder: 'Необязательно',\n continueCta: 'Продолжить',\n changeContact: 'Изменить контакты',\n backToTopics: 'К списку тем',\n emailInvalid: 'Пожалуйста, введите корректный адрес электронной почты.',\n threadHint:\n 'Переписка отображается ниже. Мы продублируем переписку на указанный email в случае обрыва связи.',\n threadHintIconLabel: 'Подсказка: переписка и дублирование на email',\n threadHintCollapse: 'Свернуть',\n emptyThreadGuest: 'Напишите первое сообщение в поле ниже.',\n loadingProfile: 'Загрузка…',\n }\n case 'de':\n return {\n intro:\n 'Damit wir antworten können, geben Sie bitte Ihre E-Mail-Adresse an (Pflichtfeld) und optional Ihren Namen.',\n emailLabel: 'E-Mail',\n nameLabel: 'Name',\n emailPlaceholder: 'you@example.com',\n namePlaceholder: 'Optional',\n continueCta: 'Weiter',\n changeContact: 'Kontakt ändern',\n backToTopics: 'Zurück zu den Themen',\n emailInvalid: 'Bitte geben Sie eine gültige E-Mail-Adresse ein.',\n threadHint:\n 'Der Chatverlauf erscheint unten. Wir antworten per E-Mail.',\n threadHintIconLabel: 'Hinweis zu Chat und E-Mail',\n threadHintCollapse: 'Einklappen',\n emptyThreadGuest: 'Schreiben Sie Ihre erste Nachricht unten.',\n loadingProfile: 'Wird geladen…',\n }\n case 'es':\n return {\n intro:\n 'Para poder responderte, indica tu correo electrónico (obligatorio) y, si quieres, tu nombre.',\n emailLabel: 'Correo electrónico',\n nameLabel: 'Nombre',\n emailPlaceholder: 'tu@ejemplo.com',\n namePlaceholder: 'Opcional',\n continueCta: 'Continuar',\n changeContact: 'Cambiar datos',\n backToTopics: 'Volver a los temas',\n emailInvalid: 'Introduce un correo electrónico válido.',\n threadHint: 'Los mensajes aparecen abajo. Te responderemos por correo.',\n threadHintIconLabel: 'Aviso sobre el chat y el correo',\n threadHintCollapse: 'Ocultar',\n emptyThreadGuest: 'Escribe tu primer mensaje abajo.',\n loadingProfile: 'Cargando…',\n }\n default:\n return {\n intro:\n 'So we can reach you, please enter your email address (required) and your name if you’d like (optional).',\n emailLabel: 'Email',\n nameLabel: 'Name',\n emailPlaceholder: 'you@example.com',\n namePlaceholder: 'Optional',\n continueCta: 'Continue',\n changeContact: 'Change contact details',\n backToTopics: 'Back to topics',\n emailInvalid: 'Please enter a valid email address.',\n threadHint:\n 'Your conversation appears below. We’ll reply to your email.',\n threadHintIconLabel: 'Note about chat and email',\n threadHintCollapse: 'Collapse',\n emptyThreadGuest: 'Write your first message in the box below.',\n loadingProfile: 'Loading…',\n }\n }\n}\n\nexport function defaultChatUiLabels(locale: string): MailooChatUiLabels {\n return {\n ...guestCopy(locale),\n ...unavailableCopy(locale),\n title: 'Chat',\n launcherOpen: 'Open chat',\n launcherClose: 'Close chat',\n send: 'Send',\n composerPlaceholder: 'Type a message…',\n emptyThreadAuthenticated: 'Say hello to start a conversation.',\n }\n}\n","export function buildVisitorWsUrl(\n apiOrigin: string,\n projectUid: string,\n integrationId: string,\n sessionPublicId: string\n): string {\n const u = new URL(apiOrigin)\n const wsProto = u.protocol === 'https:' ? 'wss:' : 'ws:'\n const qs = new URLSearchParams({\n projectUid,\n integrationId,\n sessionPublicId,\n })\n return `${wsProto}//${u.host}/api/v1/chat/visitor-ws?${qs.toString()}`\n}\n","import type { CSSProperties } from 'react'\n\nexport type MailooChatWidgetTopic = {\n id: string\n label: string\n action: 'start_chat' | 'external_url'\n externalUrl?: string\n}\n\nexport type MailooChatWidgetOperator = {\n userId: string\n name: string | null\n image: string | null\n online: boolean\n}\n\nexport const MAILOO_CHAT_LAUNCHER_POSITIONS = [\n 'bottom-right',\n 'bottom-left',\n 'top-right',\n 'top-left',\n 'middle-right',\n 'middle-left',\n] as const\n\nexport type MailooChatLauncherPosition =\n (typeof MAILOO_CHAT_LAUNCHER_POSITIONS)[number]\n\nexport type MailooChatWidgetConfig = {\n brandPrimary?: string\n brandOnPrimary?: string\n welcomeTitle?: string\n welcomeTagline?: string\n privacyPolicyUrl?: string\n position?: MailooChatLauncherPosition\n topics: MailooChatWidgetTopic[]\n operators: MailooChatWidgetOperator[]\n}\n\nexport function isMailooChatLauncherPosition(\n value: unknown\n): value is MailooChatLauncherPosition {\n return (\n typeof value === 'string' &&\n (MAILOO_CHAT_LAUNCHER_POSITIONS as readonly string[]).includes(value)\n )\n}\n\nexport function resolveMailooChatLauncherPosition(\n prop: MailooChatLauncherPosition | undefined,\n config: Pick<MailooChatWidgetConfig, 'position'> | null | undefined\n): MailooChatLauncherPosition {\n if (prop) return prop\n if (config?.position && isMailooChatLauncherPosition(config.position)) {\n return config.position\n }\n return 'bottom-right'\n}\n\nexport function mailooChatLauncherRootClassNames(\n position: MailooChatLauncherPosition\n): string {\n const parts = ['mailoo-chat-root']\n if (position.endsWith('-left')) parts.push('mailoo-chat-root--left')\n if (position.startsWith('top-')) parts.push('mailoo-chat-root--top')\n if (position.startsWith('middle-')) parts.push('mailoo-chat-root--middle')\n return parts.join(' ')\n}\n\nexport function chatWidgetCssVariables(\n config: Pick<\n MailooChatWidgetConfig,\n 'brandPrimary' | 'brandOnPrimary'\n > | null | undefined\n): CSSProperties {\n return {\n ['--mailoo-chat-brand' as string]: config?.brandPrimary ?? '#2563EB',\n ['--mailoo-chat-brand-on' as string]: config?.brandOnPrimary ?? '#FFFFFF',\n }\n}\n","'use client'\n\nimport type { ReactNode } from 'react'\nimport type { MailooChatFault } from '../hooks/shared.js'\nimport type { MailooChatUiLabels } from '../lib/guest-copy.js'\n\nexport type MailooChatUnavailableAction =\n | { type: 'link'; href: string; label: string }\n | { type: 'mailto'; email: string; label?: string }\n\nexport type MailooChatUnavailableRenderArgs = {\n fault: MailooChatFault\n labels: MailooChatUiLabels\n retry: () => void\n unavailableAction?: MailooChatUnavailableAction\n brandBtnClass: string\n}\n\nfunction actionHref(action: MailooChatUnavailableAction): string {\n if (action.type === 'mailto') {\n return `mailto:${action.email.trim()}`\n }\n return action.href\n}\n\nfunction actionLabel(\n action: MailooChatUnavailableAction,\n labels: MailooChatUiLabels\n): string {\n if (action.type === 'mailto') {\n return action.label?.trim() || labels.contactCta\n }\n return action.label\n}\n\n/**\n * Built-in panel when chat hits rate limit or service/network unavailability.\n * Integrators may replace this via `renderUnavailable`.\n */\nexport function MailooChatUnavailablePanel({\n fault,\n labels,\n retry,\n unavailableAction,\n brandBtnClass,\n}: MailooChatUnavailableRenderArgs): ReactNode {\n const isRateLimited = fault.kind === 'rate_limited'\n const title = isRateLimited\n ? labels.rateLimitedTitle\n : labels.unavailableTitle\n const body = isRateLimited\n ? labels.rateLimitedBody\n : labels.unavailableBody\n\n return (\n <div\n className=\"flex min-h-0 flex-1 flex-col justify-center gap-3 p-4 text-sm\"\n role=\"alert\"\n >\n <div className=\"space-y-1\">\n <p className=\"font-medium text-gray-900 dark:text-white\">{title}</p>\n <p className=\"text-xs leading-snug text-gray-600 dark:text-gray-300\">\n {body}\n </p>\n </div>\n <div className=\"flex flex-col gap-2\">\n <button\n type=\"button\"\n onClick={retry}\n className={`w-full py-2 text-sm font-medium ${brandBtnClass}`}\n >\n {labels.retryCta}\n </button>\n {unavailableAction ? (\n <a\n href={actionHref(unavailableAction)}\n {...(unavailableAction.type === 'link'\n ? { target: '_blank', rel: 'noopener noreferrer' }\n : {})}\n className=\"w-full rounded border border-gray-300 py-2 text-center text-sm font-medium text-gray-800 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-100 dark:hover:bg-gray-800\"\n >\n {actionLabel(unavailableAction, labels)}\n </a>\n ) : null}\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'\nimport type { MailooChatHostConfig } from '../config.js'\nimport type { MailooChatFault } from '../hooks/shared.js'\nimport {\n MailooSiteChatWidget,\n type MailooChatUnavailableAction,\n type MailooChatUnavailableRenderArgs,\n} from './mailoo-site-chat-widget.js'\nimport {\n createMailooChatWelcomePresetRenderer,\n mailooChatWelcomePresetPanelClassName,\n useOptionalMailooChatWelcomePreset,\n} from '../welcome-presets/index.js'\n\n/** Dispatched by Support Live Chat (and other CTAs) to open the floating widget. */\nexport const MAILOO_SITE_CHAT_OPEN_EVENT = 'mailoo-site-chat:open'\n\nexport type MailooSiteChatShellConfig = MailooChatHostConfig\n\nexport type MailooSiteChatShellProps = {\n chat: MailooSiteChatShellConfig\n unavailableAction?: MailooChatUnavailableAction\n renderUnavailable?: (args: MailooChatUnavailableRenderArgs) => ReactNode\n onError?: (error: string) => void\n onFault?: (fault: MailooChatFault) => void\n}\n\n/**\n * Default floating site chat host. Always passes `widgetConfig` from\n * {@link resolveMailooChatHostConfig}. Open state is controlled here; CTAs call\n * {@link openMailooSiteChat}. When wrapped in\n * {@link MailooChatWelcomePresetProvider}, uses the active welcome preset.\n * Pass `unavailableAction` / `renderUnavailable` so rate-limit and service\n * faults show a contact path chosen by the integrator.\n */\nexport function MailooSiteChatShell({\n chat,\n unavailableAction,\n renderUnavailable,\n onError,\n onFault,\n}: Readonly<MailooSiteChatShellProps>) {\n const welcomePreset = useOptionalMailooChatWelcomePreset()\n const [open, setOpen] = useState(false)\n const openChat = useCallback(() => setOpen(true), [])\n\n useEffect(() => {\n const onOpen = () => openChat()\n window.addEventListener(MAILOO_SITE_CHAT_OPEN_EVENT, onOpen)\n return () => {\n window.removeEventListener(MAILOO_SITE_CHAT_OPEN_EVENT, onOpen)\n }\n }, [openChat])\n\n const renderWelcome = useMemo(\n () =>\n welcomePreset\n ? createMailooChatWelcomePresetRenderer(welcomePreset.preset)\n : undefined,\n [welcomePreset]\n )\n\n const panelClassName = welcomePreset\n ? mailooChatWelcomePresetPanelClassName(welcomePreset.preset)\n : undefined\n\n return (\n <MailooSiteChatWidget\n apiOrigin={chat.apiOrigin}\n projectUid={chat.projectUid}\n integrationId={chat.integrationId}\n welcomeMessage={chat.welcomeMessage}\n locale={chat.locale}\n isAuthenticated={chat.isAuthenticated}\n widgetConfig={chat.widgetConfig}\n open={open}\n onOpenChange={setOpen}\n renderWelcome={renderWelcome}\n panelClassName={panelClassName}\n unavailableAction={unavailableAction}\n renderUnavailable={renderUnavailable}\n onError={onError}\n onFault={onFault}\n />\n )\n}\n\n/** Open the site chat widget (works from any client component on the page). */\nexport function openMailooSiteChat(): void {\n window.dispatchEvent(new Event(MAILOO_SITE_CHAT_OPEN_EVENT))\n}\n","'use client'\n\nimport { useId } from 'react'\nimport type { MailooChatWelcomeRenderArgs } from '../components/mailoo-site-chat-widget.js'\n\nexport function operatorInitials(name: string | null): string {\n const base = (name ?? '?').trim()\n const parts = base.split(/\\s+/).filter(Boolean)\n if (parts.length >= 2) {\n return `${parts[0]![0] ?? ''}${parts[1]![0] ?? ''}`.toUpperCase()\n }\n return base.slice(0, 2).toUpperCase()\n}\n\nexport function GuestContactFields({\n args,\n compact = false,\n}: {\n args: MailooChatWelcomeRenderArgs\n compact?: boolean\n}) {\n const id = useId()\n const emailId = `${id}-guest-email`\n const nameId = `${id}-guest-name`\n const {\n labels,\n guestEmail,\n setGuestEmail,\n guestName,\n setGuestName,\n error,\n needsGuestFields,\n } = args\n\n if (!needsGuestFields) return null\n\n return (\n <div className={compact ? 'space-y-2' : 'space-y-3'}>\n <div>\n <label\n htmlFor={emailId}\n className=\"mb-1 block text-xs font-medium text-gray-600 dark:text-gray-400\"\n >\n {labels.emailLabel}\n </label>\n <input\n id={emailId}\n type=\"email\"\n autoComplete=\"email\"\n value={guestEmail}\n onChange={(e) => setGuestEmail(e.target.value)}\n placeholder={labels.emailPlaceholder}\n className=\"w-full rounded border border-gray-300 bg-white px-2 py-1.5 text-sm dark:border-gray-600 dark:bg-gray-800\"\n />\n </div>\n <div>\n <label\n htmlFor={nameId}\n className=\"mb-1 block text-xs font-medium text-gray-600 dark:text-gray-400\"\n >\n {labels.nameLabel}\n </label>\n <input\n id={nameId}\n type=\"text\"\n autoComplete=\"name\"\n value={guestName}\n onChange={(e) => setGuestName(e.target.value)}\n placeholder={labels.namePlaceholder}\n className=\"w-full rounded border border-gray-300 bg-white px-2 py-1.5 text-sm dark:border-gray-600 dark:bg-gray-800\"\n />\n </div>\n {error && (\n <p className=\"text-xs text-red-600 dark:text-red-400\">{error}</p>\n )}\n </div>\n )\n}\n\nexport function PrivacyFooter({\n privacyPolicyUrl,\n className = '',\n}: {\n privacyPolicyUrl?: string\n className?: string\n}) {\n if (!privacyPolicyUrl) return null\n return (\n <p\n className={`text-center text-[10px] leading-snug text-gray-500 dark:text-gray-400 ${className}`}\n >\n By continuing, you agree to our{' '}\n <a\n href={privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline hover:text-gray-700 dark:hover:text-gray-300\"\n >\n privacy policy\n </a>\n .\n </p>\n )\n}\n","'use client'\n\nimport type { MailooChatWelcomeRenderArgs } from '../components/mailoo-site-chat-widget.js'\nimport { GuestContactFields, PrivacyFooter } from './shared.js'\n\n/** Assistant welcome: persona hero, intro bubble, topic chips. */\nexport function AssistantWelcomePreset(args: MailooChatWelcomeRenderArgs) {\n const {\n widgetConfig,\n title,\n welcomeMessage,\n brandBtnClass,\n brandStyle,\n topics,\n selectedTopicId,\n setSelectedTopicId,\n labels,\n needsGuestFields,\n confirmGuestContact,\n } = args\n\n const personaName = widgetConfig?.welcomeTitle?.trim() || title\n const heroLine = widgetConfig?.welcomeTagline?.trim() || welcomeMessage\n const headerBg =\n 'bg-[var(--mailoo-chat-brand,#5b21b6)] text-[var(--mailoo-chat-brand-on,#ffffff)]'\n\n return (\n <div\n className=\"flex min-h-0 flex-1 flex-col overflow-hidden\"\n style={brandStyle}\n >\n <div className={`shrink-0 px-4 pb-3 pt-5 ${headerBg}`}>\n <div className=\"mb-3 flex items-center gap-3\">\n <span className=\"flex h-12 w-12 items-center justify-center rounded-full bg-white/20 text-lg font-bold\">\n {personaName.slice(0, 1).toUpperCase()}\n </span>\n <div>\n <p className=\"text-xs uppercase tracking-wide opacity-80\">\n Assistant\n </p>\n <h2 className=\"text-base font-semibold\">{personaName}</h2>\n </div>\n </div>\n <div className=\"rounded-2xl rounded-tl-sm bg-white/15 px-3 py-2.5 text-sm leading-relaxed\">\n {heroLine}\n </div>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto bg-white px-4 py-4 text-gray-900 dark:bg-gray-950 dark:text-gray-100\">\n {topics.length > 0 && (\n <div className=\"mb-4 flex flex-wrap gap-2\">\n {topics.map((topic) =>\n topic.action === 'external_url' && topic.externalUrl ? (\n <a\n key={topic.id}\n href={topic.externalUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`rounded-full px-4 py-2 text-xs font-semibold ${brandBtnClass}`}\n >\n {topic.label}\n </a>\n ) : (\n <button\n key={topic.id}\n type=\"button\"\n onClick={() =>\n setSelectedTopicId(\n selectedTopicId === topic.id ? null : topic.id\n )\n }\n className={`rounded-full px-4 py-2 text-xs font-semibold ${\n selectedTopicId === topic.id\n ? brandBtnClass\n : 'border border-gray-300 text-gray-700 dark:border-gray-600 dark:text-gray-200'\n }`}\n >\n {topic.label}\n </button>\n )\n )}\n </div>\n )}\n\n {needsGuestFields && (\n <p className=\"mb-3 text-sm text-gray-600 dark:text-gray-300\">\n {labels.intro}\n </p>\n )}\n <GuestContactFields args={args} compact />\n\n <button\n type=\"button\"\n onClick={() => confirmGuestContact(labels.emailInvalid)}\n className={`mt-4 w-full py-2.5 text-sm font-semibold ${brandBtnClass}`}\n >\n {labels.continueCta}\n </button>\n\n <PrivacyFooter\n privacyPolicyUrl={widgetConfig?.privacyPolicyUrl}\n className=\"mt-4 text-gray-500 dark:text-gray-400\"\n />\n </div>\n </div>\n )\n}\n","'use client'\n\nimport type { MailooChatWelcomeRenderArgs } from '../components/mailoo-site-chat-widget.js'\nimport {\n GuestContactFields,\n operatorInitials,\n PrivacyFooter,\n} from './shared.js'\n\n/** Team roster welcome: brand header, operator avatars, topic grid, privacy. */\nexport function TeamWelcomePreset(args: MailooChatWelcomeRenderArgs) {\n const {\n widgetConfig,\n title,\n welcomeMessage,\n brandBtnClass,\n brandStyle,\n topics,\n selectedTopicId,\n setSelectedTopicId,\n labels,\n needsGuestFields,\n confirmGuestContact,\n } = args\n\n const operators = widgetConfig?.operators ?? []\n const headerBg =\n 'bg-[var(--mailoo-chat-brand,#5b21b6)] text-[var(--mailoo-chat-brand-on,#ffffff)]'\n\n return (\n <div\n className=\"flex min-h-0 flex-1 flex-col overflow-hidden\"\n style={brandStyle}\n >\n <div className={`shrink-0 px-4 pb-4 pt-5 ${headerBg}`}>\n {operators.length > 0 && (\n <div className=\"mb-3 flex -space-x-2\">\n {operators.slice(0, 5).map((op) => (\n <div key={op.userId} className=\"relative\">\n {op.image ? (\n <img\n src={op.image}\n alt=\"\"\n className=\"h-9 w-9 rounded-full border-2 border-white/30 object-cover\"\n />\n ) : (\n <span className=\"flex h-9 w-9 items-center justify-center rounded-full border-2 border-white/30 bg-white/20 text-xs font-semibold\">\n {operatorInitials(op.name)}\n </span>\n )}\n {op.online && (\n <span\n className=\"absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-[var(--mailoo-chat-brand,#5b21b6)] bg-emerald-400\"\n aria-hidden\n />\n )}\n </div>\n ))}\n </div>\n )}\n <h2 className=\"text-lg font-semibold leading-tight\">{title}</h2>\n <p className=\"mt-1 text-sm opacity-90\">{welcomeMessage}</p>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto bg-white p-4 dark:bg-gray-900\">\n {topics.length > 0 && (\n <div className=\"mb-4 grid grid-cols-2 gap-2\">\n {topics.map((topic) =>\n topic.action === 'external_url' && topic.externalUrl ? (\n <a\n key={topic.id}\n href={topic.externalUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"rounded-lg border border-gray-200 px-3 py-2.5 text-center text-xs font-medium text-gray-800 hover:border-[var(--mailoo-chat-brand,#5b21b6)] dark:border-gray-600 dark:text-gray-100\"\n >\n {topic.label}\n </a>\n ) : (\n <button\n key={topic.id}\n type=\"button\"\n onClick={() =>\n setSelectedTopicId(\n selectedTopicId === topic.id ? null : topic.id\n )\n }\n className={`rounded-lg border px-3 py-2.5 text-center text-xs font-medium ${\n selectedTopicId === topic.id\n ? `${brandBtnClass} border-transparent`\n : 'border-gray-200 text-gray-800 hover:border-[var(--mailoo-chat-brand,#5b21b6)] dark:border-gray-600 dark:text-gray-100'\n }`}\n >\n {topic.label}\n </button>\n )\n )}\n </div>\n )}\n\n {needsGuestFields && (\n <p className=\"mb-3 text-sm text-gray-600 dark:text-gray-300\">\n {labels.intro}\n </p>\n )}\n <GuestContactFields args={args} compact />\n\n <button\n type=\"button\"\n onClick={() => confirmGuestContact(labels.emailInvalid)}\n className={`mt-4 w-full py-2.5 text-sm font-semibold ${brandBtnClass}`}\n >\n {labels.continueCta}\n </button>\n\n <PrivacyFooter\n privacyPolicyUrl={widgetConfig?.privacyPolicyUrl}\n className=\"mt-4\"\n />\n </div>\n </div>\n )\n}\n","'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from 'react'\nimport type { MailooChatWelcomePresetId } from './types.js'\nimport { normalizeLegacyWelcomePresetId } from './types.js'\n\nconst DEFAULT_STORAGE_KEY = 'mailoo-chat-welcome-preset'\n\ntype MailooChatWelcomePresetContextValue = {\n preset: MailooChatWelcomePresetId\n setPreset: (preset: MailooChatWelcomePresetId) => void\n}\n\nconst MailooChatWelcomePresetContext =\n createContext<MailooChatWelcomePresetContextValue | null>(null)\n\nexport function MailooChatWelcomePresetProvider({\n children,\n defaultPreset = 'builtin',\n storageKey = DEFAULT_STORAGE_KEY,\n}: {\n children: ReactNode\n defaultPreset?: MailooChatWelcomePresetId\n storageKey?: string\n}) {\n const [preset, setPresetState] =\n useState<MailooChatWelcomePresetId>(defaultPreset)\n\n useEffect(() => {\n try {\n const stored = localStorage.getItem(storageKey)\n if (!stored) return\n const normalized = normalizeLegacyWelcomePresetId(stored)\n if (normalized) {\n setPresetState(normalized)\n }\n } catch {\n /* ignore */\n }\n }, [storageKey])\n\n const setPreset = useCallback(\n (next: MailooChatWelcomePresetId) => {\n setPresetState(next)\n try {\n localStorage.setItem(storageKey, next)\n } catch {\n /* ignore */\n }\n },\n [storageKey]\n )\n\n const value = useMemo(() => ({ preset, setPreset }), [preset, setPreset])\n\n return (\n <MailooChatWelcomePresetContext.Provider value={value}>\n {children}\n </MailooChatWelcomePresetContext.Provider>\n )\n}\n\nexport function useMailooChatWelcomePreset(): MailooChatWelcomePresetContextValue {\n const ctx = useContext(MailooChatWelcomePresetContext)\n if (!ctx) {\n throw new Error(\n 'useMailooChatWelcomePreset must be used within MailooChatWelcomePresetProvider'\n )\n }\n return ctx\n}\n\n/** Returns null when no {@link MailooChatWelcomePresetProvider} is present. */\nexport function useOptionalMailooChatWelcomePreset(): MailooChatWelcomePresetContextValue | null {\n return useContext(MailooChatWelcomePresetContext)\n}\n","'use client'\n\nimport { MAILOO_CHAT_WELCOME_PRESET_OPTIONS } from './preset-options.js'\nimport { useMailooChatWelcomePreset } from './preset-context.js'\nimport type {\n MailooChatWelcomePresetId,\n MailooChatWelcomePresetOption,\n} from './types.js'\n\nexport type MailooChatWelcomePresetSwitcherProps = {\n title?: string\n description?: string\n className?: string\n optionClassName?: (active: boolean) => string\n}\n\nexport function MailooChatWelcomePresetSwitcher({\n title = 'Welcome preset',\n description = 'Preview optional welcome layouts via renderWelcome on MailooSiteChatWidget.',\n className = '',\n optionClassName,\n}: MailooChatWelcomePresetSwitcherProps) {\n const { preset, setPreset } = useMailooChatWelcomePreset()\n\n const defaultOptionClass = (active: boolean) =>\n [\n 'rounded-lg border p-3 text-left transition-colors',\n active\n ? 'border-blue-600 bg-blue-50 ring-1 ring-blue-600 dark:border-blue-400 dark:bg-blue-950/40 dark:ring-blue-400'\n : 'border-gray-200 hover:border-blue-400/50 dark:border-gray-700',\n ].join(' ')\n\n const resolveOptionClass = optionClassName ?? defaultOptionClass\n\n return (\n <div className={className}>\n <h2 className=\"text-sm font-semibold text-gray-900 dark:text-white\">\n {title}\n </h2>\n {description ? (\n <p className=\"mt-1 text-sm text-gray-600 dark:text-gray-400\">\n {description}\n </p>\n ) : null}\n <div className=\"mt-4 grid gap-3 sm:grid-cols-3\">\n {MAILOO_CHAT_WELCOME_PRESET_OPTIONS.map(\n (option: MailooChatWelcomePresetOption) => {\n const active = preset === option.id\n return (\n <button\n key={option.id}\n type=\"button\"\n onClick={() => setPreset(option.id as MailooChatWelcomePresetId)}\n className={resolveOptionClass(active)}\n >\n <span className=\"block text-sm font-medium text-gray-900 dark:text-white\">\n {option.label}\n </span>\n <span className=\"mt-1 block text-xs text-gray-600 dark:text-gray-400\">\n {option.description}\n </span>\n </button>\n )\n }\n )}\n </div>\n </div>\n )\n}\n","'use client'\n\nimport type { ReactNode } from 'react'\nimport type { MailooChatWelcomeRenderArgs } from '../components/mailoo-site-chat-widget.js'\nimport { AssistantWelcomePreset } from './assistant.js'\nimport { TeamWelcomePreset } from './team.js'\nimport {\n parseMailooChatWelcomePreset,\n type MailooChatWelcomePresetId,\n type MailooChatWelcomePresetOption,\n} from './types.js'\nimport { MAILOO_CHAT_WELCOME_PRESET_OPTIONS } from './preset-options.js'\n\nexport {\n MailooChatWelcomePresetProvider,\n useMailooChatWelcomePreset,\n useOptionalMailooChatWelcomePreset,\n} from './preset-context.js'\nexport { AssistantWelcomePreset } from './assistant.js'\nexport { TeamWelcomePreset } from './team.js'\nexport {\n GuestContactFields,\n operatorInitials,\n PrivacyFooter,\n} from './shared.js'\nexport {\n normalizeLegacyWelcomePresetId,\n parseMailooChatWelcomePreset,\n type MailooChatWelcomePresetId,\n type MailooChatWelcomePresetOption,\n} from './types.js'\nexport { MAILOO_CHAT_WELCOME_PRESET_OPTIONS } from './preset-options.js'\n\nexport function renderMailooChatWelcomePreset(\n preset: MailooChatWelcomePresetId,\n args: MailooChatWelcomeRenderArgs\n): ReactNode {\n if (preset === 'team') return TeamWelcomePreset(args)\n if (preset === 'assistant') return AssistantWelcomePreset(args)\n return null\n}\n\n/** Returns `renderWelcome` callback for MailooSiteChatWidget, or undefined for built-in. */\nexport function createMailooChatWelcomePresetRenderer(\n preset: MailooChatWelcomePresetId\n): ((args: MailooChatWelcomeRenderArgs) => ReactNode) | undefined {\n if (preset === 'builtin') return undefined\n return (args) => renderMailooChatWelcomePreset(preset, args)\n}\n\nexport function mailooChatWelcomePresetPanelClassName(\n preset: MailooChatWelcomePresetId\n): string | undefined {\n if (preset === 'team' || preset === 'assistant') {\n return 'border-0 shadow-2xl'\n }\n return undefined\n}\n\nexport { MailooChatWelcomePresetSwitcher } from './preset-switcher.js'\nexport type { MailooChatWelcomePresetSwitcherProps } from './preset-switcher.js'\n"],"mappings":"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","names":["import_react","import_react","res","data","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
@@ -0,0 +1,33 @@
1
+ import { M as MailooChatUnavailableAction, a as MailooChatUnavailableRenderArgs } from '../mailoo-site-chat-widget-h_cBqsJw.cjs';
2
+ export { d as MailooChatUiLabels, f as MailooChatUnavailablePanel, e as MailooChatWelcomeRenderArgs, c as MailooChatWidgetProps, b as MailooSiteChatWidget } from '../mailoo-site-chat-widget-h_cBqsJw.cjs';
3
+ import * as react from 'react';
4
+ import { ReactNode } from 'react';
5
+ import { MailooChatHostConfig } from '../index.cjs';
6
+ import { M as MailooChatFault } from '../shared-glVmghqk.cjs';
7
+ export { M as MailooChatMessage } from '../chat-message-Dw6tKBEb.cjs';
8
+ export { a as MailooChatLauncherPosition, M as MailooChatWidgetConfig } from '../widget-config-B5Tf7gqn.cjs';
9
+ import '@mailoo/next-core';
10
+
11
+ /** Dispatched by Support Live Chat (and other CTAs) to open the floating widget. */
12
+ declare const MAILOO_SITE_CHAT_OPEN_EVENT = "mailoo-site-chat:open";
13
+ type MailooSiteChatShellConfig = MailooChatHostConfig;
14
+ type MailooSiteChatShellProps = {
15
+ chat: MailooSiteChatShellConfig;
16
+ unavailableAction?: MailooChatUnavailableAction;
17
+ renderUnavailable?: (args: MailooChatUnavailableRenderArgs) => ReactNode;
18
+ onError?: (error: string) => void;
19
+ onFault?: (fault: MailooChatFault) => void;
20
+ };
21
+ /**
22
+ * Default floating site chat host. Always passes `widgetConfig` from
23
+ * {@link resolveMailooChatHostConfig}. Open state is controlled here; CTAs call
24
+ * {@link openMailooSiteChat}. When wrapped in
25
+ * {@link MailooChatWelcomePresetProvider}, uses the active welcome preset.
26
+ * Pass `unavailableAction` / `renderUnavailable` so rate-limit and service
27
+ * faults show a contact path chosen by the integrator.
28
+ */
29
+ declare function MailooSiteChatShell({ chat, unavailableAction, renderUnavailable, onError, onFault, }: Readonly<MailooSiteChatShellProps>): react.JSX.Element;
30
+ /** Open the site chat widget (works from any client component on the page). */
31
+ declare function openMailooSiteChat(): void;
32
+
33
+ export { MAILOO_SITE_CHAT_OPEN_EVENT, MailooChatFault, MailooChatUnavailableAction, MailooChatUnavailableRenderArgs, MailooSiteChatShell, type MailooSiteChatShellConfig, type MailooSiteChatShellProps, openMailooSiteChat };
@@ -0,0 +1,33 @@
1
+ import { M as MailooChatUnavailableAction, a as MailooChatUnavailableRenderArgs } from '../mailoo-site-chat-widget-C7B797Lu.js';
2
+ export { d as MailooChatUiLabels, f as MailooChatUnavailablePanel, e as MailooChatWelcomeRenderArgs, c as MailooChatWidgetProps, b as MailooSiteChatWidget } from '../mailoo-site-chat-widget-C7B797Lu.js';
3
+ import * as react from 'react';
4
+ import { ReactNode } from 'react';
5
+ import { MailooChatHostConfig } from '../index.js';
6
+ import { M as MailooChatFault } from '../shared-glVmghqk.js';
7
+ export { M as MailooChatMessage } from '../chat-message-Dw6tKBEb.js';
8
+ export { a as MailooChatLauncherPosition, M as MailooChatWidgetConfig } from '../widget-config-B5Tf7gqn.js';
9
+ import '@mailoo/next-core';
10
+
11
+ /** Dispatched by Support Live Chat (and other CTAs) to open the floating widget. */
12
+ declare const MAILOO_SITE_CHAT_OPEN_EVENT = "mailoo-site-chat:open";
13
+ type MailooSiteChatShellConfig = MailooChatHostConfig;
14
+ type MailooSiteChatShellProps = {
15
+ chat: MailooSiteChatShellConfig;
16
+ unavailableAction?: MailooChatUnavailableAction;
17
+ renderUnavailable?: (args: MailooChatUnavailableRenderArgs) => ReactNode;
18
+ onError?: (error: string) => void;
19
+ onFault?: (fault: MailooChatFault) => void;
20
+ };
21
+ /**
22
+ * Default floating site chat host. Always passes `widgetConfig` from
23
+ * {@link resolveMailooChatHostConfig}. Open state is controlled here; CTAs call
24
+ * {@link openMailooSiteChat}. When wrapped in
25
+ * {@link MailooChatWelcomePresetProvider}, uses the active welcome preset.
26
+ * Pass `unavailableAction` / `renderUnavailable` so rate-limit and service
27
+ * faults show a contact path chosen by the integrator.
28
+ */
29
+ declare function MailooSiteChatShell({ chat, unavailableAction, renderUnavailable, onError, onFault, }: Readonly<MailooSiteChatShellProps>): react.JSX.Element;
30
+ /** Open the site chat widget (works from any client component on the page). */
31
+ declare function openMailooSiteChat(): void;
32
+
33
+ export { MAILOO_SITE_CHAT_OPEN_EVENT, MailooChatFault, MailooChatUnavailableAction, MailooChatUnavailableRenderArgs, MailooSiteChatShell, type MailooSiteChatShellConfig, type MailooSiteChatShellProps, openMailooSiteChat };