wealth-alpha-chat-widget 1.0.1 → 1.0.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.
- package/dist/index.cjs +184 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +103 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.mjs +185 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/docs/BACKEND_CHAT_WIDGET.md +0 -357
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/session.ts","../src/api/chatApi.ts","../src/hooks/useAuth.ts","../src/hooks/useChat.ts","../src/hooks/useChip.ts","../src/hooks/useSession.ts","../src/styles/chat.module.css","../src/components/AuthGate.tsx","../src/components/Chip.tsx","../src/components/ChipRow.tsx","../src/utils/markdown.ts","../src/components/MessageBubble.tsx","../src/components/TypingIndicator.tsx","../src/components/ChatBody.tsx","../src/utils/time.ts","../src/components/ChatHeader.tsx","../src/components/ChatInput.tsx","../src/components/FloatingButton.tsx","../src/components/WealthChat.tsx"],"names":["fallback","useRef","useEffect","useCallback","useState","root","floatingButton","positionRight","positionLeft","widget","header","headerTitle","headerMeta","headerActions","iconButton","body","bubble","markdown","bubbleBot","bubbleUser","chipRow","chip","chipActive","chipDisabled","typing","typingDot","input","inputBox","sendButton","authGate","authGateIcon","authGateTitle","authGateText","authGateButton","authGateDisclaimer","authGateDisclaimerTitle","errorBanner","jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { Message, WACSession } from \"../types\";\n\nexport const SESSION_KEY = \"wac_session\";\nexport const DEFAULT_SESSION_TTL_SECONDS = 1800;\nexport const MAX_HISTORY = 100;\n\n// Fallback localStorage keys checked in order when wac_session is empty.\n// Host apps that already store a JWT under one of these keys get auth for free.\nconst FALLBACK_TOKEN_KEYS = [\"token\", \"access_token\", \"auth_token\", \"jwt\"];\n\nconst isBrowser = (): boolean =>\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\";\n\nfunction base64UrlDecode(input: string): string {\n const base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = base64 + \"===\".slice((base64.length + 3) % 4);\n return atob(padded);\n}\n\nfunction decodeJwt(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3 || !parts[1]) return null;\n return JSON.parse(base64UrlDecode(parts[1])) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction jwtExpiresAt(token: string): number | null {\n const payload = decodeJwt(token);\n const exp = payload?.[\"exp\"];\n if (typeof exp !== \"number\") return null;\n return exp * 1000;\n}\n\nfunction jwtUserId(token: string): string {\n const payload = decodeJwt(token);\n if (!payload) return \"\";\n const id = payload[\"id\"] ?? payload[\"sub\"] ?? payload[\"user_id\"];\n return id != null ? String(id) : \"\";\n}\n\nfunction readFallbackToken(): { token: string; key: string } | null {\n if (!isBrowser()) return null;\n for (const key of FALLBACK_TOKEN_KEYS) {\n const value = window.localStorage.getItem(key);\n if (value && value.length > 20) return { token: value, key };\n }\n return null;\n}\n\nconst generateId = (prefix: string): string => {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `${prefix}_${crypto.randomUUID()}`;\n }\n return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n};\n\nexport function newSessionId(): string {\n return generateId(\"ses\");\n}\n\nexport function newMessageId(): string {\n return generateId(\"msg\");\n}\n\nexport function readSession(): WACSession | null {\n if (!isBrowser()) return null;\n try {\n const raw = window.localStorage.getItem(SESSION_KEY);\n if (raw) {\n const session = JSON.parse(raw) as WACSession;\n const valid =\n session &&\n typeof session.token === \"string\" &&\n session.token.length > 0 &&\n typeof session.expiresAt === \"number\" &&\n Date.now() < session.expiresAt;\n if (valid) {\n const fallback = readFallbackToken();\n // If this session was adopted from a fallback key but that key is now gone,\n // the host app has logged out — drop the cached session.\n if (!fallback && session.bootSource === \"fallback\") {\n clearSession();\n return null;\n }\n // If the host app's raw token has rotated (re-login), prefer that one.\n if (fallback && fallback.token !== session.token) {\n return adoptFallbackToken(fallback.token, session);\n }\n return session;\n }\n // Stale wac_session — drop it and try fallback below.\n clearSession();\n }\n } catch {\n clearSession();\n }\n\n const fallback = readFallbackToken();\n if (!fallback) return null;\n return adoptFallbackToken(fallback.token, null);\n}\n\nfunction adoptFallbackToken(token: string, prior: WACSession | null): WACSession | null {\n const jwtExp = jwtExpiresAt(token);\n const now = Date.now();\n const expiresAt = jwtExp ?? now + DEFAULT_SESSION_TTL_SECONDS * 1000;\n if (now >= expiresAt) return null;\n const session: WACSession = {\n token,\n userId: jwtUserId(token) || prior?.userId || \"\",\n sessionId: prior?.sessionId ?? newSessionId(),\n expiresAt,\n lastActive: now,\n history: prior?.history ?? [],\n bootSource: \"fallback\",\n };\n if (isBrowser()) {\n try {\n window.localStorage.setItem(SESSION_KEY, JSON.stringify(session));\n } catch {\n /* ignore quota */\n }\n }\n return session;\n}\n\nexport function writeSession(\n data: Partial<WACSession>,\n ttlSeconds: number = DEFAULT_SESSION_TTL_SECONDS,\n): WACSession | null {\n if (!isBrowser()) return null;\n const now = Date.now();\n const existing = readSession();\n const base: WACSession =\n existing ??\n {\n token: \"\",\n userId: \"\",\n sessionId: newSessionId(),\n expiresAt: now + ttlSeconds * 1000,\n lastActive: now,\n history: [],\n };\n\n const merged: WACSession = {\n ...base,\n ...data,\n sessionId: data.sessionId ?? base.sessionId ?? newSessionId(),\n lastActive: now,\n expiresAt: now + ttlSeconds * 1000,\n history: trimHistory(data.history ?? base.history),\n };\n\n try {\n window.localStorage.setItem(SESSION_KEY, JSON.stringify(merged));\n return merged;\n } catch {\n return null;\n }\n}\n\nexport function clearSession(): void {\n if (!isBrowser()) return;\n try {\n window.localStorage.removeItem(SESSION_KEY);\n } catch {\n /* ignore */\n }\n}\n\nexport function trimHistory(history: Message[] | undefined): Message[] {\n if (!Array.isArray(history)) return [];\n if (history.length <= MAX_HISTORY) return history;\n return history.slice(history.length - MAX_HISTORY);\n}\n\nexport function touchSession(\n ttlSeconds: number = DEFAULT_SESSION_TTL_SECONDS,\n): WACSession | null {\n const current = readSession();\n if (!current) return null;\n return writeSession({}, ttlSeconds);\n}\n","import type { BotResponse, Chip, Message, WACUser } from \"../types\";\nimport { clearSession, newMessageId, readSession } from \"../utils/session\";\n\nconst DEFAULT_TIMEOUT_MS = 20000;\nconst DEFAULT_RETRIES = 2;\nconst RETRY_BASE_DELAY_MS = 400;\n\nexport class ApiError extends Error {\n status: number;\n requestId: string;\n constructor(message: string, status: number, requestId: string) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.requestId = requestId;\n }\n}\n\nexport class AuthExpiredError extends ApiError {\n constructor(requestId: string) {\n super(\"Session expired or invalid\", 401, requestId);\n this.name = \"AuthExpiredError\";\n }\n}\n\ninterface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n signal?: AbortSignal;\n timeoutMs?: number;\n retries?: number;\n auth?: boolean;\n}\n\nconst generateRequestId = (): string => {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n};\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\nconst joinUrl = (base: string, path: string): string => {\n const trimmedBase = base.replace(/\\/+$/, \"\");\n const trimmedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${trimmedBase}${trimmedPath}`;\n};\n\nasync function request<T>(\n apiBase: string,\n path: string,\n opts: RequestOptions = {},\n): Promise<T> {\n const {\n method = \"GET\",\n body,\n signal,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n retries = DEFAULT_RETRIES,\n auth = true,\n } = opts;\n\n const url = /^https?:\\/\\//i.test(path) ? path : joinUrl(apiBase, path);\n const requestId = generateRequestId();\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n const onUserAbort = () => controller.abort();\n if (signal) {\n if (signal.aborted) {\n clearTimeout(timeoutId);\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n signal.addEventListener(\"abort\", onUserAbort, { once: true });\n }\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Request-Id\": requestId,\n };\n if (auth) {\n const session = readSession();\n if (session?.token) headers[\"Authorization\"] = `Bearer ${session.token}`;\n }\n\n const res = await fetch(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n credentials: \"same-origin\",\n });\n\n if (res.status === 401 || res.status === 403) {\n clearSession();\n throw new AuthExpiredError(requestId);\n }\n\n if (res.status >= 500 && attempt < retries) {\n lastError = new ApiError(`Server error ${res.status}`, res.status, requestId);\n throw lastError;\n }\n\n if (!res.ok) {\n let detail = res.statusText;\n try {\n const errBody = (await res.json()) as { message?: string; detail?: string };\n detail = errBody.message ?? errBody.detail ?? detail;\n } catch {\n /* ignore body parse */\n }\n throw new ApiError(detail || `HTTP ${res.status}`, res.status, requestId);\n }\n\n if (res.status === 204) return undefined as T;\n return (await res.json()) as T;\n } catch (err) {\n const error = err as Error;\n const isAbort = error.name === \"AbortError\";\n const isAuth = error instanceof AuthExpiredError;\n const isRetryable =\n !isAuth &&\n !signal?.aborted &&\n (isAbort || error instanceof TypeError || (error as ApiError).status >= 500);\n\n if (isAuth || !isRetryable || attempt === retries) {\n throw error;\n }\n lastError = error;\n await sleep(RETRY_BASE_DELAY_MS * Math.pow(2, attempt));\n } finally {\n clearTimeout(timeoutId);\n if (signal) signal.removeEventListener(\"abort\", onUserAbort);\n }\n }\n\n throw lastError ?? new Error(\"Request failed\");\n}\n\nexport async function checkAuth(\n apiBase: string,\n authCheck: string,\n signal?: AbortSignal,\n): Promise<WACUser> {\n return request<WACUser>(apiBase, authCheck, {\n method: \"GET\",\n signal,\n retries: 1,\n });\n}\n\nexport async function sendChip(\n apiBase: string,\n chip: Chip,\n sessionId: string,\n signal?: AbortSignal,\n): Promise<BotResponse> {\n const path = chip.apiPath ?? `/chip/${chip.id}`;\n return request<BotResponse>(apiBase, path, {\n method: \"POST\",\n body: { chipId: chip.id, sessionId },\n signal,\n });\n}\n\nexport async function sendMessage(\n apiBase: string,\n message: string,\n sessionId: string,\n context: Message[],\n signal?: AbortSignal,\n): Promise<BotResponse> {\n return request<BotResponse>(apiBase, \"/message\", {\n method: \"POST\",\n body: { message, sessionId, context },\n signal,\n });\n}\n\nexport async function logout(apiBase: string, signal?: AbortSignal): Promise<void> {\n try {\n await request<void>(apiBase, \"/auth/logout\", {\n method: \"POST\",\n signal,\n retries: 0,\n });\n } finally {\n clearSession();\n }\n}\n\nexport { generateRequestId };\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { AuthExpiredError, checkAuth } from \"../api/chatApi\";\nimport type { WACUser } from \"../types\";\nimport { clearSession, readSession } from \"../utils/session\";\n\ninterface UseAuthOptions {\n apiBase: string;\n authCheck: string;\n enabled?: boolean;\n onError?: (err: Error) => void;\n}\n\ninterface UseAuthReturn {\n isLoggedIn: boolean;\n user: WACUser | null;\n loading: boolean;\n error: Error | null;\n refresh: () => void;\n}\n\nexport function useAuth(opts: UseAuthOptions): UseAuthReturn {\n const { apiBase, authCheck, enabled = true, onError } = opts;\n const [user, setUser] = useState<WACUser | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<Error | null>(null);\n const [tick, setTick] = useState(0);\n const onErrorRef = useRef(onError);\n\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n\n const session = readSession();\n if (!session?.token) {\n setUser(null);\n setLoading(false);\n return;\n }\n\n const controller = new AbortController();\n setLoading(true);\n setError(null);\n\n checkAuth(apiBase, authCheck, controller.signal)\n .then((u) => {\n setUser(u);\n setError(null);\n })\n .catch((err: Error) => {\n if (err.name === \"AbortError\") return;\n if (err instanceof AuthExpiredError) {\n clearSession();\n setUser(null);\n } else {\n setError(err);\n onErrorRef.current?.(err);\n }\n })\n .finally(() => {\n if (!controller.signal.aborted) setLoading(false);\n });\n\n return () => controller.abort();\n }, [apiBase, authCheck, enabled, tick]);\n\n const refresh = useCallback(() => setTick((t) => t + 1), []);\n\n return {\n isLoggedIn: user !== null,\n user,\n loading,\n error,\n refresh,\n };\n}\n","import { useCallback, useEffect, useReducer, useRef } from \"react\";\nimport { AuthExpiredError, sendMessage as apiSendMessage } from \"../api/chatApi\";\nimport type { BotResponse, ChatState, Message } from \"../types\";\nimport { MAX_HISTORY, newMessageId } from \"../utils/session\";\n\ntype ChatAction =\n | { type: \"ADD_MESSAGE\"; payload: Message }\n | { type: \"SET_TYPING\"; payload: boolean }\n | { type: \"SET_STATUS\"; payload: ChatState[\"status\"] }\n | { type: \"SET_ERROR\"; payload: string | null }\n | { type: \"DEACTIVATE_CHIPS\"; payload: { exceptId?: string } }\n | { type: \"LOAD_HISTORY\"; payload: Message[] }\n | { type: \"CLEAR\" };\n\nconst initialState: ChatState = {\n messages: [],\n isTyping: false,\n status: \"idle\",\n error: null,\n};\n\nfunction reducer(state: ChatState, action: ChatAction): ChatState {\n switch (action.type) {\n case \"ADD_MESSAGE\": {\n const next = [...state.messages, action.payload];\n const trimmed = next.length > MAX_HISTORY ? next.slice(next.length - MAX_HISTORY) : next;\n return { ...state, messages: trimmed };\n }\n case \"SET_TYPING\":\n return { ...state, isTyping: action.payload };\n case \"SET_STATUS\":\n return { ...state, status: action.payload };\n case \"SET_ERROR\":\n return { ...state, error: action.payload };\n case \"DEACTIVATE_CHIPS\":\n return {\n ...state,\n messages: state.messages.map((m) =>\n m.id === action.payload.exceptId ? m : { ...m, chipsActive: false },\n ),\n };\n case \"LOAD_HISTORY\":\n return { ...state, messages: action.payload };\n case \"CLEAR\":\n return initialState;\n default:\n return state;\n }\n}\n\ninterface UseChatOptions {\n apiBase: string;\n sessionId: string | null;\n initialMessages?: Message[];\n onHistoryChange?: (history: Message[]) => void;\n onError?: (err: Error) => void;\n onAuthExpired?: () => void;\n}\n\ninterface UseChatReturn {\n state: ChatState;\n sendText: (text: string) => Promise<void>;\n appendBotResponse: (resp: BotResponse) => void;\n appendUserMessage: (content: string) => Message;\n deactivatePriorChips: (keepId?: string) => void;\n setTyping: (value: boolean) => void;\n clear: () => void;\n loadHistory: (history: Message[]) => void;\n}\n\nexport function useChat(opts: UseChatOptions): UseChatReturn {\n const { apiBase, sessionId, initialMessages, onHistoryChange, onError, onAuthExpired } = opts;\n const [state, dispatch] = useReducer(reducer, initialState);\n const abortRef = useRef<AbortController | null>(null);\n const onHistoryChangeRef = useRef(onHistoryChange);\n const onErrorRef = useRef(onError);\n const onAuthExpiredRef = useRef(onAuthExpired);\n\n useEffect(() => {\n onHistoryChangeRef.current = onHistoryChange;\n onErrorRef.current = onError;\n onAuthExpiredRef.current = onAuthExpired;\n }, [onHistoryChange, onError, onAuthExpired]);\n\n useEffect(() => {\n if (initialMessages && initialMessages.length > 0) {\n dispatch({ type: \"LOAD_HISTORY\", payload: initialMessages });\n }\n }, []);\n\n useEffect(() => {\n onHistoryChangeRef.current?.(state.messages);\n }, [state.messages]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const appendUserMessage = useCallback((content: string): Message => {\n const msg: Message = {\n id: newMessageId(),\n role: \"user\",\n content,\n timestamp: Date.now(),\n };\n dispatch({ type: \"ADD_MESSAGE\", payload: msg });\n return msg;\n }, []);\n\n const appendBotResponse = useCallback((resp: BotResponse) => {\n const botMsg: Message = {\n id: newMessageId(),\n role: \"bot\",\n content: resp.message,\n chips: resp.chips ?? [],\n chipsActive: (resp.chips ?? []).length > 0,\n timestamp: Date.now(),\n };\n dispatch({ type: \"ADD_MESSAGE\", payload: botMsg });\n }, []);\n\n const deactivatePriorChips = useCallback((keepId?: string) => {\n dispatch({ type: \"DEACTIVATE_CHIPS\", payload: { exceptId: keepId } });\n }, []);\n\n const sendText = useCallback(\n async (text: string) => {\n const trimmed = text.trim();\n if (!trimmed || !sessionId) return;\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n deactivatePriorChips();\n appendUserMessage(trimmed);\n dispatch({ type: \"SET_TYPING\", payload: true });\n dispatch({ type: \"SET_STATUS\", payload: \"sending\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const context = state.messages.slice(-20);\n const resp = await apiSendMessage(apiBase, trimmed, sessionId, context, controller.signal);\n appendBotResponse(resp);\n dispatch({ type: \"SET_STATUS\", payload: \"idle\" });\n } catch (err) {\n const error = err as Error;\n if (error.name === \"AbortError\") return;\n if (error instanceof AuthExpiredError) {\n onAuthExpiredRef.current?.();\n } else {\n onErrorRef.current?.(error);\n dispatch({ type: \"SET_ERROR\", payload: error.message });\n }\n dispatch({ type: \"SET_STATUS\", payload: \"error\" });\n } finally {\n dispatch({ type: \"SET_TYPING\", payload: false });\n }\n },\n [apiBase, sessionId, state.messages, appendUserMessage, appendBotResponse, deactivatePriorChips],\n );\n\n const clear = useCallback(() => {\n abortRef.current?.abort();\n dispatch({ type: \"CLEAR\" });\n }, []);\n\n const loadHistory = useCallback((history: Message[]) => {\n dispatch({ type: \"LOAD_HISTORY\", payload: history });\n }, []);\n\n /** Toggle the typing dots externally — used by WealthChat around chip clicks. */\n const setTyping = useCallback((value: boolean) => {\n dispatch({ type: \"SET_TYPING\", payload: value });\n }, []);\n\n return {\n state,\n sendText,\n appendBotResponse,\n appendUserMessage,\n deactivatePriorChips,\n clear,\n loadHistory,\n setTyping,\n };\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { AuthExpiredError, sendChip } from \"../api/chatApi\";\nimport type { BotResponse, Chip } from \"../types\";\n\ninterface UseChipOptions {\n apiBase: string;\n sessionId: string | null;\n onAuthExpired?: () => void;\n onError?: (err: Error) => void;\n}\n\ninterface UseChipReturn {\n callChip: (chip: Chip) => Promise<BotResponse | null>;\n}\n\nexport function useChip(opts: UseChipOptions): UseChipReturn {\n const { apiBase, sessionId, onAuthExpired, onError } = opts;\n const abortRef = useRef<AbortController | null>(null);\n const onAuthExpiredRef = useRef(onAuthExpired);\n const onErrorRef = useRef(onError);\n\n useEffect(() => {\n onAuthExpiredRef.current = onAuthExpired;\n onErrorRef.current = onError;\n }, [onAuthExpired, onError]);\n\n useEffect(() => {\n return () => abortRef.current?.abort();\n }, []);\n\n const callChip = useCallback(\n async (chip: Chip): Promise<BotResponse | null> => {\n if (!sessionId) return null;\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n return await sendChip(apiBase, chip, sessionId, controller.signal);\n } catch (err) {\n const error = err as Error;\n if (error.name === \"AbortError\") return null;\n if (error instanceof AuthExpiredError) {\n onAuthExpiredRef.current?.();\n } else {\n onErrorRef.current?.(error);\n }\n return null;\n }\n },\n [apiBase, sessionId],\n );\n\n return { callChip };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { Message, WACSession } from \"../types\";\nimport {\n DEFAULT_SESSION_TTL_SECONDS,\n clearSession,\n newSessionId,\n readSession,\n touchSession,\n writeSession,\n} from \"../utils/session\";\n\ninterface UseSessionOptions {\n ttlSeconds?: number;\n onExpire?: () => void;\n}\n\ninterface UseSessionReturn {\n session: WACSession | null;\n remainingMs: number;\n setToken: (token: string, userId: string) => void;\n setHistory: (history: Message[]) => void;\n touch: () => void;\n clear: () => void;\n}\n\nexport function useSession(opts: UseSessionOptions = {}): UseSessionReturn {\n const { ttlSeconds = DEFAULT_SESSION_TTL_SECONDS, onExpire } = opts;\n const [session, setSession] = useState<WACSession | null>(null);\n const [remainingMs, setRemainingMs] = useState(0);\n const expiredRef = useRef(false);\n const onExpireRef = useRef(onExpire);\n\n useEffect(() => {\n onExpireRef.current = onExpire;\n }, [onExpire]);\n\n useEffect(() => {\n const current = readSession();\n setSession(current);\n setRemainingMs(current ? current.expiresAt - Date.now() : 0);\n }, []);\n\n useEffect(() => {\n if (!session) return;\n const interval = window.setInterval(() => {\n const current = readSession();\n if (!current) {\n if (!expiredRef.current) {\n expiredRef.current = true;\n onExpireRef.current?.();\n }\n setSession(null);\n setRemainingMs(0);\n return;\n }\n setRemainingMs(current.expiresAt - Date.now());\n }, 15000);\n return () => window.clearInterval(interval);\n }, [session]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onStorage = (e: StorageEvent) => {\n if (e.key && e.key !== \"wac_session\") return;\n const current = readSession();\n setSession(current);\n setRemainingMs(current ? current.expiresAt - Date.now() : 0);\n };\n window.addEventListener(\"storage\", onStorage);\n return () => window.removeEventListener(\"storage\", onStorage);\n }, []);\n\n const setToken = useCallback(\n (token: string, userId: string) => {\n expiredRef.current = false;\n const updated = writeSession(\n {\n token,\n userId,\n sessionId: readSession()?.sessionId ?? newSessionId(),\n history: readSession()?.history ?? [],\n },\n ttlSeconds,\n );\n setSession(updated);\n setRemainingMs(updated ? updated.expiresAt - Date.now() : 0);\n },\n [ttlSeconds],\n );\n\n const setHistory = useCallback(\n (history: Message[]) => {\n const updated = writeSession({ history }, ttlSeconds);\n if (updated) {\n setSession(updated);\n setRemainingMs(updated.expiresAt - Date.now());\n }\n },\n [ttlSeconds],\n );\n\n const touch = useCallback(() => {\n const updated = touchSession(ttlSeconds);\n if (updated) {\n setSession(updated);\n setRemainingMs(updated.expiresAt - Date.now());\n }\n }, [ttlSeconds]);\n\n const clear = useCallback(() => {\n clearSession();\n setSession(null);\n setRemainingMs(0);\n expiredRef.current = true;\n }, []);\n\n return { session, remainingMs, setToken, setHistory, touch, clear };\n}\n",".root {\n --wac-brand: #1a2d5a;\n --wac-brand-contrast: #ffffff;\n --wac-bg: #ffffff;\n --wac-fg: #1f2937;\n --wac-muted: #6b7280;\n --wac-border: #e5e7eb;\n --wac-bot-bg: #f3f4f6;\n --wac-user-bg: var(--wac-brand);\n --wac-chip-bg: #eef2ff;\n --wac-chip-fg: #1e293b;\n --wac-chip-active-bg: var(--wac-brand);\n --wac-chip-active-fg: #ffffff;\n --wac-radius: 14px;\n --wac-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n color: var(--wac-fg);\n box-sizing: border-box;\n}\n\n.root *,\n.root *::before,\n.root *::after {\n box-sizing: inherit;\n}\n\n.floatingButton {\n position: fixed;\n bottom: 24px;\n z-index: 2147483646;\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border: none;\n cursor: pointer;\n box-shadow: var(--wac-shadow);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 26px;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.floatingButton:hover {\n transform: translateY(-2px);\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.22);\n}\n\n.positionRight {\n right: 24px;\n}\n\n.positionLeft {\n left: 24px;\n}\n\n.widget {\n position: fixed;\n bottom: 24px;\n z-index: 2147483647;\n width: 420px;\n max-width: calc(100vw - 24px);\n height: min(760px, calc(100vh - 48px));\n background: var(--wac-bg);\n color: var(--wac-fg);\n border-radius: var(--wac-radius);\n box-shadow: var(--wac-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--wac-border);\n}\n\n@media (max-width: 640px) {\n .widget {\n width: calc(100vw - 12px);\n height: calc(100vh - 24px);\n bottom: 12px;\n }\n .positionRight,\n .positionLeft {\n right: 6px;\n left: auto;\n }\n .floatingButton {\n width: 56px;\n height: 56px;\n bottom: 16px;\n }\n}\n\n.header {\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n padding: 14px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.headerTitle {\n font-weight: 600;\n font-size: 15px;\n line-height: 1.2;\n}\n\n.headerMeta {\n font-size: 11px;\n opacity: 0.85;\n margin-top: 2px;\n}\n\n.headerActions {\n display: flex;\n gap: 4px;\n align-items: center;\n}\n\n.iconButton {\n background: transparent;\n color: inherit;\n border: none;\n cursor: pointer;\n font-size: 18px;\n padding: 4px 8px;\n border-radius: 6px;\n line-height: 1;\n}\n\n.iconButton:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.body {\n flex: 1;\n overflow-y: auto;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n background: #fafafa;\n scroll-behavior: smooth;\n}\n\n.body::-webkit-scrollbar {\n width: 6px;\n}\n\n.body::-webkit-scrollbar-thumb {\n background: #d1d5db;\n border-radius: 3px;\n}\n\n.bubble {\n max-width: 80%;\n padding: 10px 14px;\n border-radius: 12px;\n font-size: 14px;\n line-height: 1.45;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n/* markdown-it output inside a bot bubble.\n markdown-it (breaks: true) emits a <br> for every \\n in the source,\n so we MUST NOT also apply white-space: pre-wrap here — otherwise every\n newline gets rendered twice (once via <br>, once via the literal \\n in\n CSS) and the bubble looks double-spaced. */\n.markdown {\n white-space: normal;\n}\n.markdown p {\n margin: 0 0 6px 0;\n}\n.markdown p:last-child {\n margin-bottom: 0;\n}\n.markdown br {\n /* Make consecutive <br>s collapse a bit — keeps line rhythm tight. */\n line-height: 1.4;\n}\n.markdown strong {\n font-weight: 700;\n color: var(--wac-fg);\n letter-spacing: 0.2px;\n}\n.markdown em {\n font-style: italic;\n color: var(--wac-muted);\n}\n.markdown ul,\n.markdown ol {\n margin: 4px 0 6px 0;\n padding-left: 22px;\n}\n.markdown li {\n margin: 1px 0;\n}\n.markdown a {\n color: var(--wac-brand);\n text-decoration: underline;\n}\n.markdown code {\n background: rgba(0, 0, 0, 0.06);\n padding: 1px 4px;\n border-radius: 4px;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 12.5px;\n}\n.markdown h1,\n.markdown h2,\n.markdown h3 {\n margin: 6px 0 2px 0;\n font-size: 14px;\n font-weight: 700;\n}\n\n.bubbleBot {\n align-self: flex-start;\n background: var(--wac-bot-bg);\n color: var(--wac-fg);\n border-bottom-left-radius: 4px;\n}\n\n.bubbleUser {\n align-self: flex-end;\n background: var(--wac-user-bg);\n color: var(--wac-brand-contrast);\n border-bottom-right-radius: 4px;\n}\n\n.bubbleMeta {\n font-size: 10px;\n color: var(--wac-muted);\n margin-top: 4px;\n text-align: right;\n}\n\n.chipRow {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.chip {\n padding: 7px 12px;\n background: var(--wac-chip-bg);\n color: var(--wac-chip-fg);\n border: 1px solid transparent;\n border-radius: 999px;\n font-size: 13px;\n cursor: pointer;\n transition: background 0.15s ease, transform 0.15s ease;\n font-family: inherit;\n}\n\n.chip:hover:not(:disabled) {\n background: #dbeafe;\n transform: translateY(-1px);\n}\n\n.chipActive {\n background: var(--wac-chip-active-bg);\n color: var(--wac-chip-active-fg);\n}\n\n.chipDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.typing {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n padding: 10px 14px;\n background: var(--wac-bot-bg);\n border-radius: 12px;\n border-bottom-left-radius: 4px;\n}\n\n.typingDot {\n width: 7px;\n height: 7px;\n background: var(--wac-muted);\n border-radius: 50%;\n animation: wacBlink 1.2s infinite ease-in-out both;\n}\n\n.typingDot:nth-child(2) {\n animation-delay: 0.18s;\n}\n.typingDot:nth-child(3) {\n animation-delay: 0.36s;\n}\n\n@keyframes wacBlink {\n 0%, 80%, 100% { opacity: 0.3; transform: scale(0.85); }\n 40% { opacity: 1; transform: scale(1); }\n}\n\n.input {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px solid var(--wac-border);\n background: var(--wac-bg);\n}\n\n.inputBox {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--wac-border);\n border-radius: 999px;\n font-size: 14px;\n outline: none;\n font-family: inherit;\n background: #f9fafb;\n color: var(--wac-fg);\n}\n\n.inputBox:focus {\n border-color: var(--wac-brand);\n background: var(--wac-bg);\n}\n\n.inputBox:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sendButton {\n padding: 0 16px;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border: none;\n border-radius: 999px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n font-family: inherit;\n}\n\n.sendButton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.authGate {\n margin: auto;\n text-align: center;\n padding: 32px 24px;\n max-width: 280px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: center;\n}\n\n.authGateIcon {\n font-size: 36px;\n}\n\n.authGateTitle {\n font-size: 16px;\n font-weight: 600;\n}\n\n.authGateText {\n font-size: 13px;\n color: var(--wac-muted);\n line-height: 1.5;\n}\n\n.authGateButton {\n margin-top: 8px;\n padding: 10px 20px;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border: none;\n border-radius: 999px;\n cursor: pointer;\n font-weight: 600;\n font-size: 14px;\n font-family: inherit;\n}\n\n.authGateDisclaimer {\n margin-top: 16px;\n padding-top: 12px;\n border-top: 1px dashed var(--wac-border);\n font-size: 11px;\n color: var(--wac-muted);\n line-height: 1.5;\n text-align: left;\n width: 100%;\n}\n\n.authGateDisclaimerTitle {\n font-weight: 700;\n letter-spacing: 0.6px;\n font-size: 10px;\n margin-bottom: 4px;\n color: var(--wac-fg);\n}\n\n.errorBanner {\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #991b1b;\n padding: 8px 12px;\n font-size: 12px;\n border-radius: 8px;\n margin: 0 14px 8px;\n}\n","import styles from \"../styles/chat.module.css\";\n\ninterface AuthGateProps {\n brandName: string;\n loginUrl: string;\n onLoginClick?: () => void;\n}\n\nexport function AuthGate({ brandName, loginUrl, onLoginClick }: AuthGateProps) {\n const handleClick = () => {\n if (onLoginClick) {\n onLoginClick();\n return;\n }\n if (typeof window !== \"undefined\") {\n window.location.href = loginUrl;\n }\n };\n\n return (\n <div className={styles.authGate}>\n <div className={styles.authGateIcon} aria-hidden=\"true\">🔒</div>\n <div className={styles.authGateTitle}>Login required</div>\n <div className={styles.authGateText}>\n To access {brandName}, please sign in first.\n </div>\n <button type=\"button\" className={styles.authGateButton} onClick={handleClick}>\n Sign in / Register →\n </button>\n <div className={styles.authGateDisclaimer}>\n <div className={styles.authGateDisclaimerTitle}>DISCLAIMER</div>\n <div>• AI-assisted analysis for educational purposes only.</div>\n <div>• Not financial advice. Markets involve risk.</div>\n <div>• Consult a SEBI-registered advisor before investing.</div>\n </div>\n </div>\n );\n}\n","import type { Chip as ChipType } from \"../types\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChipProps {\n chip: ChipType;\n disabled?: boolean;\n active?: boolean;\n onClick: (chip: ChipType) => void;\n}\n\nexport function Chip({ chip, disabled, active, onClick }: ChipProps) {\n const classes = [\n styles.chip,\n active ? styles.chipActive : \"\",\n disabled ? styles.chipDisabled : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n type=\"button\"\n className={classes}\n disabled={disabled}\n onClick={() => !disabled && onClick(chip)}\n >\n {chip.icon ? <span aria-hidden=\"true\">{chip.icon}</span> : null}\n <span>{chip.label}</span>\n </button>\n );\n}\n","import type { Chip as ChipType } from \"../types\";\nimport { Chip } from \"./Chip\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChipRowProps {\n chips: ChipType[];\n disabled?: boolean;\n onClick: (chip: ChipType) => void;\n}\n\nexport function ChipRow({ chips, disabled, onClick }: ChipRowProps) {\n if (!chips || chips.length === 0) return null;\n return (\n <div className={styles.chipRow}>\n {chips.map((c) => (\n <Chip key={c.id} chip={c} disabled={disabled} onClick={onClick} />\n ))}\n </div>\n );\n}\n","import DOMPurify from \"isomorphic-dompurify\";\n\n/**\n * Backend (chat_widget.py + chat_template_dispatch.py) returns Telegram-HTML in\n * BotResponse.message — e.g. `<b>Heading</b><br>Body<br><i>Note</i>`.\n *\n * We sanitize with DOMPurify against a tight allow-list and feed straight into\n * the bubble via dangerouslySetInnerHTML. This matches the exact look of the\n * Telegram bot for every response template.\n *\n * Markdown-it is intentionally NOT used here anymore — the backend handles all\n * formatting via the shared Telegram templates.\n */\n\nconst ALLOWED_TAGS = [\n \"b\", \"strong\",\n \"i\", \"em\",\n \"u\", \"ins\",\n \"s\", \"strike\", \"del\",\n \"br\",\n \"p\",\n \"code\", \"pre\",\n \"a\",\n \"ul\", \"ol\", \"li\",\n \"blockquote\",\n \"span\",\n];\n\nconst ALLOWED_ATTR = [\"href\", \"target\", \"rel\", \"class\"];\n\nconst SANITIZE_CFG = {\n ALLOWED_TAGS,\n ALLOWED_ATTR,\n // Block javascript: / data: hrefs by stripping URI schemes other than http(s) / mailto\n ALLOW_UNKNOWN_PROTOCOLS: false,\n ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto):|[^a-z]|[a-z+.-]+(?:[^a-z+.\\-:]|$))/i,\n};\n\n/**\n * Convert Telegram-style markdown shortcuts to HTML so chip prompts written\n * with `*bold*` / `_italic_` in Python source render the same way as the\n * template HTML output. Also handles the *standard* markdown that\n * AI-generated text (e.g. the sector-news `ai_verdict`) commonly emits.\n *\n * ## Heading → <b>Heading</b> (line-start ATX header, 1–6 #)\n * **text** → <b>text</b> (double asterisk, standard-bold)\n * __text__ → <b>text</b> (double underscore, standard-bold)\n * *text* → <b>text</b> (single asterisk, Telegram-bold)\n * _text_ → <i>text</i> (single underscore, italic)\n *\n * Order matters: double markers are converted before single ones so a `**`\n * pair isn't half-consumed by the single-asterisk rule. The single-marker\n * rules use lookbehind/ahead so they don't touch already-converted `<b>`\n * spans or dangling markers inside HTML attribute values.\n */\nfunction inlineMarkdownToHtml(text: string): string {\n return text\n // ATX headers at the start of a line → bold (verdict gap, no real <h*> here)\n .replace(/^[ \\t]*#{1,6}[ \\t]+(.+?)[ \\t]*$/gm, \"<b>$1</b>\")\n // Standard double-marker bold first, so the single-marker rules skip them.\n .replace(/\\*\\*([^\\n<>]+?)\\*\\*/g, \"<b>$1</b>\")\n .replace(/__([^\\n<>]+?)__/g, \"<b>$1</b>\")\n // Telegram single-asterisk bold / single-underscore italic.\n .replace(/(?<!\\*)\\*([^\\n*<>]+?)\\*(?!\\*)/g, \"<b>$1</b>\")\n .replace(/(?<![_a-zA-Z0-9])_([^\\n_<>]+?)_(?![_a-zA-Z0-9])/g, \"<i>$1</i>\");\n}\n\n/**\n * Render a Telegram-HTML or markdown-flavoured string from the backend as\n * sanitized HTML suitable for dangerouslySetInnerHTML.\n *\n * Pipeline:\n * 1. `*bold*` / `_italic_` markdown shortcuts → `<b>` / `<i>`\n * 2. Single `\\n` → `<br>`, `\\n\\n` → paragraph break (visual gap)\n * 3. DOMPurify sanitization against a tight allow-list\n */\nexport function renderMarkdown(text: string): string {\n if (!text) return \"\";\n\n const inlined = inlineMarkdownToHtml(text);\n\n // Split on blank lines into paragraphs, then within each paragraph turn \\n into <br>.\n const paragraphs = inlined\n .split(/\\n{2,}/)\n .map((para) => para.replace(/\\n/g, \"<br>\"))\n .filter((p) => p.length > 0);\n\n const html = paragraphs.length > 1\n ? paragraphs.map((p) => `<p>${p}</p>`).join(\"\")\n : paragraphs[0] ?? \"\";\n\n return DOMPurify.sanitize(html, SANITIZE_CFG);\n}\n","import type { Chip as ChipType, Message } from \"../types\";\nimport { ChipRow } from \"./ChipRow\";\nimport { renderMarkdown } from \"../utils/markdown\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface MessageBubbleProps {\n message: Message;\n onChipClick: (chip: ChipType) => void;\n}\n\nexport function MessageBubble({ message, onChipClick }: MessageBubbleProps) {\n const isBot = message.role === \"bot\";\n const bubbleClass = isBot\n ? `${styles.bubble} ${styles.bubbleBot}`\n : `${styles.bubble} ${styles.bubbleUser}`;\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n <div className={bubbleClass}>\n {isBot ? (\n <div\n className={styles.markdown}\n dangerouslySetInnerHTML={{ __html: renderMarkdown(message.content) }}\n />\n ) : (\n message.content\n )}\n </div>\n {isBot && message.chips && message.chips.length > 0 ? (\n <ChipRow\n chips={message.chips}\n disabled={!message.chipsActive}\n onClick={onChipClick}\n />\n ) : null}\n </div>\n );\n}\n","import styles from \"../styles/chat.module.css\";\n\nexport function TypingIndicator() {\n return (\n <div className={styles.typing} aria-live=\"polite\" aria-label=\"Assistant is typing\">\n <span className={styles.typingDot} />\n <span className={styles.typingDot} />\n <span className={styles.typingDot} />\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport type { Chip as ChipType, Message } from \"../types\";\nimport { AuthGate } from \"./AuthGate\";\nimport { MessageBubble } from \"./MessageBubble\";\nimport { TypingIndicator } from \"./TypingIndicator\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChatBodyProps {\n isLoggedIn: boolean;\n loading: boolean;\n messages: Message[];\n isTyping: boolean;\n brandName: string;\n loginUrl: string;\n error: string | null;\n onChipClick: (chip: ChipType) => void;\n onLoginClick?: () => void;\n}\n\nexport function ChatBody({\n isLoggedIn,\n loading,\n messages,\n isTyping,\n brandName,\n loginUrl,\n error,\n onChipClick,\n onLoginClick,\n}: ChatBodyProps) {\n const endRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n endRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages.length, isTyping]);\n\n if (loading) {\n return (\n <div className={styles.body}>\n <TypingIndicator />\n </div>\n );\n }\n\n if (!isLoggedIn) {\n return (\n <div className={styles.body}>\n <AuthGate\n brandName={brandName}\n loginUrl={loginUrl}\n onLoginClick={onLoginClick}\n />\n </div>\n );\n }\n\n return (\n <div className={styles.body}>\n {messages.map((m) => (\n <MessageBubble key={m.id} message={m} onChipClick={onChipClick} />\n ))}\n {isTyping ? <TypingIndicator /> : null}\n {error ? <div className={styles.errorBanner}>{error}</div> : null}\n <div ref={endRef} />\n </div>\n );\n}\n","export function formatCountdown(remainingMs: number): string {\n if (remainingMs <= 0) return \"expired\";\n const totalSeconds = Math.floor(remainingMs / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) return `${hours}h ${minutes}m left`;\n if (minutes > 0) return `${minutes}m ${seconds}s left`;\n return `${seconds}s left`;\n}\n\nexport function formatRelativeTime(ts: number, now: number = Date.now()): string {\n const diff = Math.max(0, now - ts);\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import styles from \"../styles/chat.module.css\";\nimport { formatCountdown } from \"../utils/time\";\n\ninterface ChatHeaderProps {\n brandName: string;\n remainingMs: number;\n showCountdown: boolean;\n onClose: () => void;\n onClear?: () => void;\n}\n\nexport function ChatHeader({\n brandName,\n remainingMs,\n showCountdown,\n onClose,\n onClear,\n}: ChatHeaderProps) {\n return (\n <div className={styles.header}>\n <div>\n <div className={styles.headerTitle}>{brandName}</div>\n {showCountdown && remainingMs > 0 ? (\n <div className={styles.headerMeta}>Session: {formatCountdown(remainingMs)}</div>\n ) : null}\n </div>\n <div className={styles.headerActions}>\n {onClear ? (\n <button\n type=\"button\"\n className={styles.iconButton}\n onClick={onClear}\n aria-label=\"Clear conversation\"\n title=\"Clear conversation\"\n >\n ↺\n </button>\n ) : null}\n <button\n type=\"button\"\n className={styles.iconButton}\n onClick={onClose}\n aria-label=\"Close chat\"\n title=\"Close\"\n >\n ✕\n </button>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChatInputProps {\n disabled?: boolean;\n placeholder?: string;\n onSend: (text: string) => void;\n}\n\nexport function ChatInput({ disabled, placeholder, onSend }: ChatInputProps) {\n const [value, setValue] = useState(\"\");\n\n const submit = () => {\n const trimmed = value.trim();\n if (!trimmed || disabled) return;\n onSend(trimmed);\n setValue(\"\");\n };\n\n return (\n <div className={styles.input}>\n <input\n type=\"text\"\n className={styles.inputBox}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n submit();\n }\n }}\n disabled={disabled}\n placeholder={placeholder ?? \"Type a message…\"}\n aria-label=\"Message input\"\n />\n <button\n type=\"button\"\n className={styles.sendButton}\n onClick={submit}\n disabled={disabled || value.trim().length === 0}\n >\n Send\n </button>\n </div>\n );\n}\n","import type { ChatPosition } from \"../types\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface FloatingButtonProps {\n position: ChatPosition;\n onClick: () => void;\n brandColor?: string;\n}\n\nexport function FloatingButton({ position, onClick, brandColor }: FloatingButtonProps) {\n const posClass = position === \"bottom-left\" ? styles.positionLeft : styles.positionRight;\n return (\n <button\n type=\"button\"\n className={`${styles.floatingButton} ${posClass}`}\n onClick={onClick}\n aria-label=\"Open chat\"\n style={brandColor ? { background: brandColor } : undefined}\n >\n 💬\n </button>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useAuth } from \"../hooks/useAuth\";\nimport { useChat } from \"../hooks/useChat\";\nimport { useChip } from \"../hooks/useChip\";\nimport { useSession } from \"../hooks/useSession\";\nimport type { Chip, Message, WealthChatProps } from \"../types\";\nimport { DEFAULT_SESSION_TTL_SECONDS } from \"../utils/session\";\nimport { ChatBody } from \"./ChatBody\";\nimport { ChatHeader } from \"./ChatHeader\";\nimport { ChatInput } from \"./ChatInput\";\nimport { FloatingButton } from \"./FloatingButton\";\nimport styles from \"../styles/chat.module.css\";\n\nconst DEFAULT_BRAND_NAME = \"Wealth Alpha AI\";\nconst DEFAULT_BRAND_COLOR = \"#1a2d5a\";\nconst DEFAULT_AUTH_CHECK = \"/me\";\n\nconst DISCLAIMER_BLOCK =\n \"DISCLAIMER:\\n\" +\n \"• AI-assisted analysis for educational purposes only.\\n\" +\n \"• Not financial advice. Markets involve risk.\\n\" +\n \"• Consult a SEBI-registered advisor before investing.\";\n\nconst CTA_LINE =\n \"Select a quick command below — or type your query to ask our AI Research Analyst directly.\";\n\nfunction buildWelcome(name: string | undefined, plan: string | undefined): string {\n const greeting = name\n ? `Welcome back, ${name}! You have ${plan ? plan : \"Premium\"} access.`\n : `Welcome! You have ${plan ? plan : \"Premium\"} access.`;\n return `${greeting}\\n\\n${DISCLAIMER_BLOCK}\\n\\n${CTA_LINE}`;\n}\n\nexport function WealthChat(props: WealthChatProps) {\n const {\n apiBase,\n authCheck = DEFAULT_AUTH_CHECK,\n loginUrl,\n sessionTTL = DEFAULT_SESSION_TTL_SECONDS,\n welcomeMessage,\n brandName = DEFAULT_BRAND_NAME,\n brandColor = DEFAULT_BRAND_COLOR,\n position = \"bottom-right\",\n defaultOpen = false,\n showCountdown = true,\n onLogin,\n onLogout,\n onSessionExpire,\n onError,\n } = props;\n\n const [mounted, setMounted] = useState(false);\n const [open, setOpen] = useState(defaultOpen);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n const {\n session,\n remainingMs,\n setHistory,\n touch,\n clear: clearSessionState,\n } = useSession({\n ttlSeconds: sessionTTL,\n onExpire: onSessionExpire,\n });\n\n const { isLoggedIn, user, loading: authLoading } = useAuth({\n apiBase,\n authCheck,\n enabled: mounted && open,\n onError,\n });\n\n const handleAuthExpired = useCallback(() => {\n clearSessionState();\n onSessionExpire?.();\n }, [clearSessionState, onSessionExpire]);\n\n const handleHistoryChange = useCallback(\n (history: Message[]) => {\n if (!session) return;\n setHistory(history);\n },\n [session, setHistory],\n );\n\n const {\n state: chatState,\n sendText,\n appendBotResponse,\n appendUserMessage,\n deactivatePriorChips,\n setTyping,\n loadHistory,\n clear: clearChat,\n } = useChat({\n apiBase,\n sessionId: session?.sessionId ?? null,\n initialMessages: session?.history,\n onHistoryChange: handleHistoryChange,\n onAuthExpired: handleAuthExpired,\n onError,\n });\n\n const { callChip } = useChip({\n apiBase,\n sessionId: session?.sessionId ?? null,\n onAuthExpired: handleAuthExpired,\n onError,\n });\n\n const welcomeShownRef = useMemo(() => ({ shown: false }), []);\n\n useEffect(() => {\n if (!isLoggedIn || !open) return;\n if (chatState.messages.length > 0) return;\n if (welcomeShownRef.shown) return;\n welcomeShownRef.shown = true;\n const messageText =\n welcomeMessage ??\n user?.welcomeMessage ??\n buildWelcome(user?.name, user?.plan);\n appendBotResponse({\n message: messageText,\n chips: user?.rootChips ?? [],\n sessionId: session?.sessionId ?? \"\",\n endOfFlow: false,\n });\n onLogin?.();\n }, [isLoggedIn, open, chatState.messages.length, welcomeMessage, session, user, appendBotResponse, onLogin, welcomeShownRef]);\n\n const handleChipClick = useCallback(\n async (chip: Chip) => {\n touch();\n deactivatePriorChips();\n appendUserMessage(chip.label);\n setTyping(true);\n try {\n const resp = await callChip(chip);\n if (resp) appendBotResponse(resp);\n } finally {\n setTyping(false);\n }\n },\n [touch, deactivatePriorChips, appendUserMessage, callChip, setTyping, appendBotResponse],\n );\n\n const handleSend = useCallback(\n (text: string) => {\n touch();\n void sendText(text);\n },\n [touch, sendText],\n );\n\n const handleClose = useCallback(() => setOpen(false), []);\n\n const handleClear = useCallback(() => {\n clearChat();\n welcomeShownRef.shown = false;\n setHistory([]);\n }, [clearChat, setHistory, welcomeShownRef]);\n\n const handleLoginClick = useCallback(() => {\n if (typeof window !== \"undefined\") {\n window.location.href = loginUrl;\n }\n }, [loginUrl]);\n\n if (!mounted) return null;\n\n const rootStyle = {\n [\"--wac-brand\" as string]: brandColor,\n } as React.CSSProperties;\n\n return (\n <div className={styles.root} style={rootStyle}>\n {!open ? (\n <FloatingButton position={position} onClick={() => setOpen(true)} brandColor={brandColor} />\n ) : null}\n {open ? (\n <div\n className={`${styles.widget} ${position === \"bottom-left\" ? styles.positionLeft : styles.positionRight}`}\n >\n <ChatHeader\n brandName={brandName}\n remainingMs={remainingMs}\n showCountdown={showCountdown && isLoggedIn}\n onClose={handleClose}\n onClear={isLoggedIn ? handleClear : undefined}\n />\n <ChatBody\n isLoggedIn={isLoggedIn}\n loading={authLoading}\n messages={chatState.messages}\n isTyping={chatState.isTyping}\n brandName={brandName}\n loginUrl={loginUrl}\n error={chatState.error}\n onChipClick={handleChipClick}\n onLoginClick={handleLoginClick}\n />\n {isLoggedIn ? (\n <ChatInput\n disabled={chatState.isTyping}\n onSend={handleSend}\n placeholder=\"Type a message…\"\n />\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/session.ts","../src/api/chatApi.ts","../src/hooks/useAuth.ts","../src/hooks/useChat.ts","../src/hooks/useChip.ts","../src/hooks/useSession.ts","../src/styles/chat.module.css","../src/components/AuthGate.tsx","../src/components/Chip.tsx","../src/components/ChipRow.tsx","../src/utils/markdown.ts","../src/components/MessageBubble.tsx","../src/components/TypingIndicator.tsx","../src/components/ChatBody.tsx","../src/utils/time.ts","../src/components/ChatHeader.tsx","../src/components/ChatInput.tsx","../src/components/FloatingButton.tsx","../src/components/WealthChat.tsx"],"names":["fallback","useRef","useEffect","useCallback","useState","root","floatingButton","positionRight","positionLeft","widget","popupBubbleLeft","popupBubbleRight","header","headerTitle","headerMeta","headerActions","iconButton","body","bubble","markdown","bubbleBot","bubbleUser","chipRow","chip","chipActive","chipDisabled","typing","typingDot","input","inputBox","sendButton","hiddenFileInput","authGate","authGateIcon","authGateTitle","authGateText","authGateButton","authGateDisclaimer","authGateDisclaimerTitle","errorBanner","popupBubble","popupDismiss","jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { Message, WACSession } from \"../types\";\n\nexport const SESSION_KEY = \"wac_session\";\nexport const DEFAULT_SESSION_TTL_SECONDS = 1800;\nexport const MAX_HISTORY = 100;\n\n// Fallback localStorage keys checked in order when wac_session is empty.\n// Host apps that already store a JWT under one of these keys get auth for free.\nconst FALLBACK_TOKEN_KEYS = [\"token\", \"access_token\", \"auth_token\", \"jwt\"];\n\nconst isBrowser = (): boolean =>\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\";\n\nfunction base64UrlDecode(input: string): string {\n const base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = base64 + \"===\".slice((base64.length + 3) % 4);\n return atob(padded);\n}\n\nfunction decodeJwt(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split(\".\");\n if (parts.length !== 3 || !parts[1]) return null;\n return JSON.parse(base64UrlDecode(parts[1])) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction jwtExpiresAt(token: string): number | null {\n const payload = decodeJwt(token);\n const exp = payload?.[\"exp\"];\n if (typeof exp !== \"number\") return null;\n return exp * 1000;\n}\n\nfunction jwtUserId(token: string): string {\n const payload = decodeJwt(token);\n if (!payload) return \"\";\n const id = payload[\"id\"] ?? payload[\"sub\"] ?? payload[\"user_id\"];\n return id != null ? String(id) : \"\";\n}\n\nfunction readFallbackToken(): { token: string; key: string } | null {\n if (!isBrowser()) return null;\n for (const key of FALLBACK_TOKEN_KEYS) {\n const value = window.localStorage.getItem(key);\n if (value && value.length > 20) return { token: value, key };\n }\n return null;\n}\n\nconst generateId = (prefix: string): string => {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `${prefix}_${crypto.randomUUID()}`;\n }\n return `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n};\n\nexport function newSessionId(): string {\n return generateId(\"ses\");\n}\n\nexport function newMessageId(): string {\n return generateId(\"msg\");\n}\n\nexport function readSession(): WACSession | null {\n if (!isBrowser()) return null;\n try {\n const raw = window.localStorage.getItem(SESSION_KEY);\n if (raw) {\n const session = JSON.parse(raw) as WACSession;\n const valid =\n session &&\n typeof session.token === \"string\" &&\n session.token.length > 0 &&\n typeof session.expiresAt === \"number\" &&\n Date.now() < session.expiresAt;\n if (valid) {\n const fallback = readFallbackToken();\n // If this session was adopted from a fallback key but that key is now gone,\n // the host app has logged out — drop the cached session.\n if (!fallback && session.bootSource === \"fallback\") {\n clearSession();\n return null;\n }\n // If the host app's raw token has rotated (re-login), prefer that one.\n if (fallback && fallback.token !== session.token) {\n return adoptFallbackToken(fallback.token, session);\n }\n return session;\n }\n // Stale wac_session — drop it and try fallback below.\n clearSession();\n }\n } catch {\n clearSession();\n }\n\n const fallback = readFallbackToken();\n if (!fallback) return null;\n return adoptFallbackToken(fallback.token, null);\n}\n\nfunction adoptFallbackToken(token: string, prior: WACSession | null): WACSession | null {\n const jwtExp = jwtExpiresAt(token);\n const now = Date.now();\n const expiresAt = jwtExp ?? now + DEFAULT_SESSION_TTL_SECONDS * 1000;\n if (now >= expiresAt) return null;\n const session: WACSession = {\n token,\n userId: jwtUserId(token) || prior?.userId || \"\",\n sessionId: prior?.sessionId ?? newSessionId(),\n expiresAt,\n lastActive: now,\n history: prior?.history ?? [],\n bootSource: \"fallback\",\n };\n if (isBrowser()) {\n try {\n window.localStorage.setItem(SESSION_KEY, JSON.stringify(session));\n } catch {\n /* ignore quota */\n }\n }\n return session;\n}\n\nexport function writeSession(\n data: Partial<WACSession>,\n ttlSeconds: number = DEFAULT_SESSION_TTL_SECONDS,\n): WACSession | null {\n if (!isBrowser()) return null;\n const now = Date.now();\n const existing = readSession();\n const base: WACSession =\n existing ??\n {\n token: \"\",\n userId: \"\",\n sessionId: newSessionId(),\n expiresAt: now + ttlSeconds * 1000,\n lastActive: now,\n history: [],\n };\n\n const merged: WACSession = {\n ...base,\n ...data,\n sessionId: data.sessionId ?? base.sessionId ?? newSessionId(),\n lastActive: now,\n expiresAt: now + ttlSeconds * 1000,\n history: trimHistory(data.history ?? base.history),\n };\n\n try {\n window.localStorage.setItem(SESSION_KEY, JSON.stringify(merged));\n return merged;\n } catch {\n return null;\n }\n}\n\nexport function clearSession(): void {\n if (!isBrowser()) return;\n try {\n window.localStorage.removeItem(SESSION_KEY);\n } catch {\n /* ignore */\n }\n}\n\nexport function trimHistory(history: Message[] | undefined): Message[] {\n if (!Array.isArray(history)) return [];\n if (history.length <= MAX_HISTORY) return history;\n return history.slice(history.length - MAX_HISTORY);\n}\n\nexport function touchSession(\n ttlSeconds: number = DEFAULT_SESSION_TTL_SECONDS,\n): WACSession | null {\n const current = readSession();\n if (!current) return null;\n return writeSession({}, ttlSeconds);\n}\n","import type { BotResponse, Chip, Message, WACUser } from \"../types\";\nimport { clearSession, newMessageId, readSession } from \"../utils/session\";\n\nconst DEFAULT_TIMEOUT_MS = 20000;\nconst DEFAULT_RETRIES = 2;\nconst RETRY_BASE_DELAY_MS = 400;\n\nexport class ApiError extends Error {\n status: number;\n requestId: string;\n constructor(message: string, status: number, requestId: string) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.requestId = requestId;\n }\n}\n\nexport class AuthExpiredError extends ApiError {\n constructor(requestId: string) {\n super(\"Session expired or invalid\", 401, requestId);\n this.name = \"AuthExpiredError\";\n }\n}\n\ninterface RequestOptions {\n method?: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n signal?: AbortSignal;\n timeoutMs?: number;\n retries?: number;\n auth?: boolean;\n}\n\nconst generateRequestId = (): string => {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n};\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\nconst joinUrl = (base: string, path: string): string => {\n const trimmedBase = base.replace(/\\/+$/, \"\");\n const trimmedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${trimmedBase}${trimmedPath}`;\n};\n\nasync function request<T>(\n apiBase: string,\n path: string,\n opts: RequestOptions = {},\n): Promise<T> {\n const {\n method = \"GET\",\n body,\n signal,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n retries = DEFAULT_RETRIES,\n auth = true,\n } = opts;\n\n const url = /^https?:\\/\\//i.test(path) ? path : joinUrl(apiBase, path);\n const requestId = generateRequestId();\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n const onUserAbort = () => controller.abort();\n if (signal) {\n if (signal.aborted) {\n clearTimeout(timeoutId);\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n signal.addEventListener(\"abort\", onUserAbort, { once: true });\n }\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Request-Id\": requestId,\n };\n if (auth) {\n const session = readSession();\n if (session?.token) headers[\"Authorization\"] = `Bearer ${session.token}`;\n }\n\n const res = await fetch(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n credentials: \"same-origin\",\n });\n\n if (res.status === 401 || res.status === 403) {\n clearSession();\n throw new AuthExpiredError(requestId);\n }\n\n if (res.status >= 500 && attempt < retries) {\n lastError = new ApiError(`Server error ${res.status}`, res.status, requestId);\n throw lastError;\n }\n\n if (!res.ok) {\n let detail = res.statusText;\n try {\n const errBody = (await res.json()) as { message?: string; detail?: string };\n detail = errBody.message ?? errBody.detail ?? detail;\n } catch {\n /* ignore body parse */\n }\n throw new ApiError(detail || `HTTP ${res.status}`, res.status, requestId);\n }\n\n if (res.status === 204) return undefined as T;\n return (await res.json()) as T;\n } catch (err) {\n const error = err as Error;\n const isAbort = error.name === \"AbortError\";\n const isAuth = error instanceof AuthExpiredError;\n const isRetryable =\n !isAuth &&\n !signal?.aborted &&\n (isAbort || error instanceof TypeError || (error as ApiError).status >= 500);\n\n if (isAuth || !isRetryable || attempt === retries) {\n throw error;\n }\n lastError = error;\n await sleep(RETRY_BASE_DELAY_MS * Math.pow(2, attempt));\n } finally {\n clearTimeout(timeoutId);\n if (signal) signal.removeEventListener(\"abort\", onUserAbort);\n }\n }\n\n throw lastError ?? new Error(\"Request failed\");\n}\n\nexport async function checkAuth(\n apiBase: string,\n authCheck: string,\n signal?: AbortSignal,\n): Promise<WACUser> {\n return request<WACUser>(apiBase, authCheck, {\n method: \"GET\",\n signal,\n retries: 1,\n });\n}\n\nexport async function sendChip(\n apiBase: string,\n chip: Chip,\n sessionId: string,\n signal?: AbortSignal,\n): Promise<BotResponse> {\n const path = chip.apiPath ?? `/chip/${chip.id}`;\n return request<BotResponse>(apiBase, path, {\n method: \"POST\",\n body: { chipId: chip.id, sessionId },\n signal,\n });\n}\n\nexport async function sendMessage(\n apiBase: string,\n message: string,\n sessionId: string,\n context: Message[],\n signal?: AbortSignal,\n): Promise<BotResponse> {\n return request<BotResponse>(apiBase, \"/message\", {\n method: \"POST\",\n body: { message, sessionId, context },\n signal,\n });\n}\n\nexport async function uploadPortfolioCsv(\n apiBase: string,\n file: File,\n sessionId: string,\n signal?: AbortSignal,\n): Promise<BotResponse> {\n const url = joinUrl(apiBase, \"/upload-portfolio-csv\");\n const requestId = generateRequestId();\n const session = readSession();\n const form = new FormData();\n form.append(\"sessionId\", sessionId);\n form.append(\"file\", file, file.name);\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 60000);\n if (signal) {\n if (signal.aborted) {\n clearTimeout(timeoutId);\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n signal.addEventListener(\"abort\", () => controller.abort(), { once: true });\n }\n\n try {\n const headers: Record<string, string> = { \"X-Request-Id\": requestId };\n if (session?.token) headers[\"Authorization\"] = `Bearer ${session.token}`;\n\n const res = await fetch(url, {\n method: \"POST\",\n headers,\n body: form,\n signal: controller.signal,\n credentials: \"same-origin\",\n });\n\n if (res.status === 401 || res.status === 403) {\n clearSession();\n throw new AuthExpiredError(requestId);\n }\n if (!res.ok) {\n let detail = res.statusText;\n try {\n const errBody = (await res.json()) as { message?: string; detail?: string };\n detail = errBody.message ?? errBody.detail ?? detail;\n } catch {\n /* ignore */\n }\n throw new ApiError(detail || `HTTP ${res.status}`, res.status, requestId);\n }\n return (await res.json()) as BotResponse;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\nexport async function logout(apiBase: string, signal?: AbortSignal): Promise<void> {\n try {\n await request<void>(apiBase, \"/auth/logout\", {\n method: \"POST\",\n signal,\n retries: 0,\n });\n } finally {\n clearSession();\n }\n}\n\nexport { generateRequestId };\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { AuthExpiredError, checkAuth } from \"../api/chatApi\";\nimport type { WACUser } from \"../types\";\nimport { clearSession, readSession } from \"../utils/session\";\n\ninterface UseAuthOptions {\n apiBase: string;\n authCheck: string;\n enabled?: boolean;\n onError?: (err: Error) => void;\n}\n\ninterface UseAuthReturn {\n isLoggedIn: boolean;\n user: WACUser | null;\n loading: boolean;\n error: Error | null;\n refresh: () => void;\n}\n\nexport function useAuth(opts: UseAuthOptions): UseAuthReturn {\n const { apiBase, authCheck, enabled = true, onError } = opts;\n const [user, setUser] = useState<WACUser | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<Error | null>(null);\n const [tick, setTick] = useState(0);\n const onErrorRef = useRef(onError);\n\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n\n const session = readSession();\n if (!session?.token) {\n setUser(null);\n setLoading(false);\n return;\n }\n\n const controller = new AbortController();\n setLoading(true);\n setError(null);\n\n checkAuth(apiBase, authCheck, controller.signal)\n .then((u) => {\n setUser(u);\n setError(null);\n })\n .catch((err: Error) => {\n if (err.name === \"AbortError\") return;\n if (err instanceof AuthExpiredError) {\n clearSession();\n setUser(null);\n } else {\n setError(err);\n onErrorRef.current?.(err);\n }\n })\n .finally(() => {\n if (!controller.signal.aborted) setLoading(false);\n });\n\n return () => controller.abort();\n }, [apiBase, authCheck, enabled, tick]);\n\n const refresh = useCallback(() => setTick((t) => t + 1), []);\n\n return {\n isLoggedIn: user !== null,\n user,\n loading,\n error,\n refresh,\n };\n}\n","import { useCallback, useEffect, useReducer, useRef } from \"react\";\nimport {\n AuthExpiredError,\n sendMessage as apiSendMessage,\n uploadPortfolioCsv as apiUploadPortfolioCsv,\n} from \"../api/chatApi\";\nimport type { BotResponse, ChatState, Message } from \"../types\";\nimport { MAX_HISTORY, newMessageId } from \"../utils/session\";\n\ntype ChatAction =\n | { type: \"ADD_MESSAGE\"; payload: Message }\n | { type: \"SET_TYPING\"; payload: boolean }\n | { type: \"SET_STATUS\"; payload: ChatState[\"status\"] }\n | { type: \"SET_ERROR\"; payload: string | null }\n | { type: \"DEACTIVATE_CHIPS\"; payload: { exceptId?: string } }\n | { type: \"LOAD_HISTORY\"; payload: Message[] }\n | { type: \"CLEAR\" };\n\nconst initialState: ChatState = {\n messages: [],\n isTyping: false,\n status: \"idle\",\n error: null,\n};\n\nfunction reducer(state: ChatState, action: ChatAction): ChatState {\n switch (action.type) {\n case \"ADD_MESSAGE\": {\n const next = [...state.messages, action.payload];\n const trimmed = next.length > MAX_HISTORY ? next.slice(next.length - MAX_HISTORY) : next;\n return { ...state, messages: trimmed };\n }\n case \"SET_TYPING\":\n return { ...state, isTyping: action.payload };\n case \"SET_STATUS\":\n return { ...state, status: action.payload };\n case \"SET_ERROR\":\n return { ...state, error: action.payload };\n case \"DEACTIVATE_CHIPS\":\n return {\n ...state,\n messages: state.messages.map((m) =>\n m.id === action.payload.exceptId ? m : { ...m, chipsActive: false },\n ),\n };\n case \"LOAD_HISTORY\":\n return { ...state, messages: action.payload };\n case \"CLEAR\":\n return initialState;\n default:\n return state;\n }\n}\n\ninterface UseChatOptions {\n apiBase: string;\n sessionId: string | null;\n initialMessages?: Message[];\n onHistoryChange?: (history: Message[]) => void;\n onError?: (err: Error) => void;\n onAuthExpired?: () => void;\n}\n\ninterface UseChatReturn {\n state: ChatState;\n sendText: (text: string) => Promise<void>;\n uploadCsv: (file: File) => Promise<void>;\n appendBotResponse: (resp: BotResponse) => void;\n appendUserMessage: (content: string) => Message;\n deactivatePriorChips: (keepId?: string) => void;\n setTyping: (value: boolean) => void;\n clear: () => void;\n loadHistory: (history: Message[]) => void;\n}\n\nexport function useChat(opts: UseChatOptions): UseChatReturn {\n const { apiBase, sessionId, initialMessages, onHistoryChange, onError, onAuthExpired } = opts;\n const [state, dispatch] = useReducer(reducer, initialState);\n const abortRef = useRef<AbortController | null>(null);\n const onHistoryChangeRef = useRef(onHistoryChange);\n const onErrorRef = useRef(onError);\n const onAuthExpiredRef = useRef(onAuthExpired);\n\n useEffect(() => {\n onHistoryChangeRef.current = onHistoryChange;\n onErrorRef.current = onError;\n onAuthExpiredRef.current = onAuthExpired;\n }, [onHistoryChange, onError, onAuthExpired]);\n\n useEffect(() => {\n if (initialMessages && initialMessages.length > 0) {\n dispatch({ type: \"LOAD_HISTORY\", payload: initialMessages });\n }\n }, []);\n\n useEffect(() => {\n onHistoryChangeRef.current?.(state.messages);\n }, [state.messages]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const appendUserMessage = useCallback((content: string): Message => {\n const msg: Message = {\n id: newMessageId(),\n role: \"user\",\n content,\n timestamp: Date.now(),\n };\n dispatch({ type: \"ADD_MESSAGE\", payload: msg });\n return msg;\n }, []);\n\n const appendBotResponse = useCallback((resp: BotResponse) => {\n const botMsg: Message = {\n id: newMessageId(),\n role: \"bot\",\n content: resp.message,\n chips: resp.chips ?? [],\n chipsActive: (resp.chips ?? []).length > 0,\n timestamp: Date.now(),\n };\n dispatch({ type: \"ADD_MESSAGE\", payload: botMsg });\n }, []);\n\n const deactivatePriorChips = useCallback((keepId?: string) => {\n dispatch({ type: \"DEACTIVATE_CHIPS\", payload: { exceptId: keepId } });\n }, []);\n\n const uploadCsv = useCallback(\n async (file: File) => {\n if (!sessionId) return;\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n deactivatePriorChips();\n appendUserMessage(`Uploaded ${file.name}`);\n dispatch({ type: \"SET_TYPING\", payload: true });\n dispatch({ type: \"SET_STATUS\", payload: \"sending\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const resp = await apiUploadPortfolioCsv(apiBase, file, sessionId, controller.signal);\n appendBotResponse(resp);\n dispatch({ type: \"SET_STATUS\", payload: \"idle\" });\n } catch (err) {\n const error = err as Error;\n if (error.name === \"AbortError\") return;\n if (error instanceof AuthExpiredError) {\n onAuthExpiredRef.current?.();\n } else {\n onErrorRef.current?.(error);\n dispatch({ type: \"SET_ERROR\", payload: error.message });\n }\n dispatch({ type: \"SET_STATUS\", payload: \"error\" });\n } finally {\n dispatch({ type: \"SET_TYPING\", payload: false });\n }\n },\n [apiBase, sessionId, appendUserMessage, appendBotResponse, deactivatePriorChips],\n );\n\n const sendText = useCallback(\n async (text: string) => {\n const trimmed = text.trim();\n if (!trimmed || !sessionId) return;\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n deactivatePriorChips();\n appendUserMessage(trimmed);\n dispatch({ type: \"SET_TYPING\", payload: true });\n dispatch({ type: \"SET_STATUS\", payload: \"sending\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const context = state.messages.slice(-20);\n const resp = await apiSendMessage(apiBase, trimmed, sessionId, context, controller.signal);\n appendBotResponse(resp);\n dispatch({ type: \"SET_STATUS\", payload: \"idle\" });\n } catch (err) {\n const error = err as Error;\n if (error.name === \"AbortError\") return;\n if (error instanceof AuthExpiredError) {\n onAuthExpiredRef.current?.();\n } else {\n onErrorRef.current?.(error);\n dispatch({ type: \"SET_ERROR\", payload: error.message });\n }\n dispatch({ type: \"SET_STATUS\", payload: \"error\" });\n } finally {\n dispatch({ type: \"SET_TYPING\", payload: false });\n }\n },\n [apiBase, sessionId, state.messages, appendUserMessage, appendBotResponse, deactivatePriorChips],\n );\n\n const clear = useCallback(() => {\n abortRef.current?.abort();\n dispatch({ type: \"CLEAR\" });\n }, []);\n\n const loadHistory = useCallback((history: Message[]) => {\n dispatch({ type: \"LOAD_HISTORY\", payload: history });\n }, []);\n\n /** Toggle the typing dots externally — used by WealthChat around chip clicks. */\n const setTyping = useCallback((value: boolean) => {\n dispatch({ type: \"SET_TYPING\", payload: value });\n }, []);\n\n return {\n state,\n sendText,\n uploadCsv,\n appendBotResponse,\n appendUserMessage,\n deactivatePriorChips,\n clear,\n loadHistory,\n setTyping,\n };\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { AuthExpiredError, sendChip } from \"../api/chatApi\";\nimport type { BotResponse, Chip } from \"../types\";\n\ninterface UseChipOptions {\n apiBase: string;\n sessionId: string | null;\n onAuthExpired?: () => void;\n onError?: (err: Error) => void;\n}\n\ninterface UseChipReturn {\n callChip: (chip: Chip) => Promise<BotResponse | null>;\n}\n\nexport function useChip(opts: UseChipOptions): UseChipReturn {\n const { apiBase, sessionId, onAuthExpired, onError } = opts;\n const abortRef = useRef<AbortController | null>(null);\n const onAuthExpiredRef = useRef(onAuthExpired);\n const onErrorRef = useRef(onError);\n\n useEffect(() => {\n onAuthExpiredRef.current = onAuthExpired;\n onErrorRef.current = onError;\n }, [onAuthExpired, onError]);\n\n useEffect(() => {\n return () => abortRef.current?.abort();\n }, []);\n\n const callChip = useCallback(\n async (chip: Chip): Promise<BotResponse | null> => {\n if (!sessionId) return null;\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n return await sendChip(apiBase, chip, sessionId, controller.signal);\n } catch (err) {\n const error = err as Error;\n if (error.name === \"AbortError\") return null;\n if (error instanceof AuthExpiredError) {\n onAuthExpiredRef.current?.();\n } else {\n onErrorRef.current?.(error);\n }\n return null;\n }\n },\n [apiBase, sessionId],\n );\n\n return { callChip };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { Message, WACSession } from \"../types\";\nimport {\n DEFAULT_SESSION_TTL_SECONDS,\n clearSession,\n newSessionId,\n readSession,\n touchSession,\n writeSession,\n} from \"../utils/session\";\n\ninterface UseSessionOptions {\n ttlSeconds?: number;\n onExpire?: () => void;\n}\n\ninterface UseSessionReturn {\n session: WACSession | null;\n remainingMs: number;\n setToken: (token: string, userId: string) => void;\n setHistory: (history: Message[]) => void;\n touch: () => void;\n clear: () => void;\n}\n\nexport function useSession(opts: UseSessionOptions = {}): UseSessionReturn {\n const { ttlSeconds = DEFAULT_SESSION_TTL_SECONDS, onExpire } = opts;\n const [session, setSession] = useState<WACSession | null>(null);\n const [remainingMs, setRemainingMs] = useState(0);\n const expiredRef = useRef(false);\n const onExpireRef = useRef(onExpire);\n\n useEffect(() => {\n onExpireRef.current = onExpire;\n }, [onExpire]);\n\n useEffect(() => {\n const current = readSession();\n setSession(current);\n setRemainingMs(current ? current.expiresAt - Date.now() : 0);\n }, []);\n\n useEffect(() => {\n if (!session) return;\n const interval = window.setInterval(() => {\n const current = readSession();\n if (!current) {\n if (!expiredRef.current) {\n expiredRef.current = true;\n onExpireRef.current?.();\n }\n setSession(null);\n setRemainingMs(0);\n return;\n }\n setRemainingMs(current.expiresAt - Date.now());\n }, 15000);\n return () => window.clearInterval(interval);\n }, [session]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onStorage = (e: StorageEvent) => {\n if (e.key && e.key !== \"wac_session\") return;\n const current = readSession();\n setSession(current);\n setRemainingMs(current ? current.expiresAt - Date.now() : 0);\n };\n window.addEventListener(\"storage\", onStorage);\n return () => window.removeEventListener(\"storage\", onStorage);\n }, []);\n\n const setToken = useCallback(\n (token: string, userId: string) => {\n expiredRef.current = false;\n const updated = writeSession(\n {\n token,\n userId,\n sessionId: readSession()?.sessionId ?? newSessionId(),\n history: readSession()?.history ?? [],\n },\n ttlSeconds,\n );\n setSession(updated);\n setRemainingMs(updated ? updated.expiresAt - Date.now() : 0);\n },\n [ttlSeconds],\n );\n\n const setHistory = useCallback(\n (history: Message[]) => {\n const updated = writeSession({ history }, ttlSeconds);\n if (updated) {\n setSession(updated);\n setRemainingMs(updated.expiresAt - Date.now());\n }\n },\n [ttlSeconds],\n );\n\n const touch = useCallback(() => {\n const updated = touchSession(ttlSeconds);\n if (updated) {\n setSession(updated);\n setRemainingMs(updated.expiresAt - Date.now());\n }\n }, [ttlSeconds]);\n\n const clear = useCallback(() => {\n clearSession();\n setSession(null);\n setRemainingMs(0);\n expiredRef.current = true;\n }, []);\n\n return { session, remainingMs, setToken, setHistory, touch, clear };\n}\n",".root {\n --wac-brand: #1a2d5a;\n --wac-brand-contrast: #ffffff;\n --wac-bg: #ffffff;\n --wac-fg: #1f2937;\n --wac-muted: #6b7280;\n --wac-border: #e5e7eb;\n --wac-bot-bg: #f3f4f6;\n --wac-user-bg: var(--wac-brand);\n --wac-chip-bg: #eef2ff;\n --wac-chip-fg: #1e293b;\n --wac-chip-active-bg: var(--wac-brand);\n --wac-chip-active-fg: #ffffff;\n --wac-radius: 14px;\n --wac-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n color: var(--wac-fg);\n box-sizing: border-box;\n}\n\n.root *,\n.root *::before,\n.root *::after {\n box-sizing: inherit;\n}\n\n.floatingButton {\n position: fixed;\n bottom: 24px;\n z-index: 2147483646;\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border: none;\n cursor: pointer;\n box-shadow: var(--wac-shadow);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 26px;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n}\n\n.floatingButton:hover {\n transform: translateY(-2px);\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.22);\n}\n\n.positionRight {\n right: 24px;\n}\n\n.positionLeft {\n left: 24px;\n}\n\n.widget {\n position: fixed;\n bottom: 24px;\n z-index: 2147483647;\n width: 420px;\n max-width: calc(100vw - 24px);\n height: min(760px, calc(100vh - 48px));\n background: var(--wac-bg);\n color: var(--wac-fg);\n border-radius: var(--wac-radius);\n box-shadow: var(--wac-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--wac-border);\n}\n\n@media (max-width: 640px) {\n .widget {\n width: calc(100vw - 12px);\n height: calc(100vh - 24px);\n bottom: 12px;\n }\n .positionRight,\n .positionLeft {\n right: 6px;\n left: auto;\n }\n .floatingButton {\n width: 56px;\n height: 56px;\n bottom: 16px;\n }\n /* Both positions collapse to right: 6px on mobile, so sync popup */\n .popupBubbleLeft,\n .popupBubbleRight {\n right: 72px;\n left: auto;\n bottom: 16px;\n max-width: calc(100vw - 84px);\n }\n}\n\n.header {\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n padding: 14px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.headerTitle {\n font-weight: 600;\n font-size: 15px;\n line-height: 1.2;\n}\n\n.headerMeta {\n font-size: 11px;\n opacity: 0.85;\n margin-top: 2px;\n}\n\n.headerActions {\n display: flex;\n gap: 4px;\n align-items: center;\n}\n\n.iconButton {\n background: transparent;\n color: inherit;\n border: none;\n cursor: pointer;\n font-size: 18px;\n padding: 4px 8px;\n border-radius: 6px;\n line-height: 1;\n}\n\n.iconButton:hover {\n background: rgba(255, 255, 255, 0.15);\n}\n\n.body {\n flex: 1;\n overflow-y: auto;\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n background: #fafafa;\n scroll-behavior: smooth;\n}\n\n.body::-webkit-scrollbar {\n width: 6px;\n}\n\n.body::-webkit-scrollbar-thumb {\n background: #d1d5db;\n border-radius: 3px;\n}\n\n.bubble {\n max-width: 80%;\n padding: 10px 14px;\n border-radius: 12px;\n font-size: 14px;\n line-height: 1.45;\n word-wrap: break-word;\n white-space: pre-wrap;\n}\n\n/* markdown-it output inside a bot bubble.\n markdown-it (breaks: true) emits a <br> for every \\n in the source,\n so we MUST NOT also apply white-space: pre-wrap here — otherwise every\n newline gets rendered twice (once via <br>, once via the literal \\n in\n CSS) and the bubble looks double-spaced. */\n.markdown {\n white-space: normal;\n}\n.markdown p {\n margin: 0 0 6px 0;\n}\n.markdown p:last-child {\n margin-bottom: 0;\n}\n.markdown br {\n /* Make consecutive <br>s collapse a bit — keeps line rhythm tight. */\n line-height: 1.4;\n}\n.markdown strong {\n font-weight: 700;\n color: var(--wac-fg);\n letter-spacing: 0.2px;\n}\n.markdown em {\n font-style: italic;\n color: var(--wac-muted);\n}\n.markdown ul,\n.markdown ol {\n margin: 4px 0 6px 0;\n padding-left: 22px;\n}\n.markdown li {\n margin: 1px 0;\n}\n.markdown a {\n color: var(--wac-brand);\n text-decoration: underline;\n}\n.markdown code {\n background: rgba(0, 0, 0, 0.06);\n padding: 1px 4px;\n border-radius: 4px;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 12.5px;\n}\n.markdown h1,\n.markdown h2,\n.markdown h3 {\n margin: 6px 0 2px 0;\n font-size: 14px;\n font-weight: 700;\n}\n\n.bubbleBot {\n align-self: flex-start;\n background: var(--wac-bot-bg);\n color: var(--wac-fg);\n border-bottom-left-radius: 4px;\n}\n\n.bubbleUser {\n align-self: flex-end;\n background: var(--wac-user-bg);\n color: var(--wac-brand-contrast);\n border-bottom-right-radius: 4px;\n}\n\n.bubbleMeta {\n font-size: 10px;\n color: var(--wac-muted);\n margin-top: 4px;\n text-align: right;\n}\n\n.chipRow {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.chip {\n padding: 7px 12px;\n background: var(--wac-chip-bg);\n color: var(--wac-chip-fg);\n border: 1px solid transparent;\n border-radius: 999px;\n font-size: 13px;\n cursor: pointer;\n transition: background 0.15s ease, transform 0.15s ease;\n font-family: inherit;\n}\n\n.chip:hover:not(:disabled) {\n background: #dbeafe;\n transform: translateY(-1px);\n}\n\n.chipActive {\n background: var(--wac-chip-active-bg);\n color: var(--wac-chip-active-fg);\n}\n\n.chipDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.typing {\n align-self: flex-start;\n display: inline-flex;\n gap: 4px;\n padding: 10px 14px;\n background: var(--wac-bot-bg);\n border-radius: 12px;\n border-bottom-left-radius: 4px;\n}\n\n.typingDot {\n width: 7px;\n height: 7px;\n background: var(--wac-muted);\n border-radius: 50%;\n animation: wacBlink 1.2s infinite ease-in-out both;\n}\n\n.typingDot:nth-child(2) {\n animation-delay: 0.18s;\n}\n.typingDot:nth-child(3) {\n animation-delay: 0.36s;\n}\n\n@keyframes wacBlink {\n 0%, 80%, 100% { opacity: 0.3; transform: scale(0.85); }\n 40% { opacity: 1; transform: scale(1); }\n}\n\n.input {\n display: flex;\n gap: 8px;\n padding: 10px 12px;\n border-top: 1px solid var(--wac-border);\n background: var(--wac-bg);\n}\n\n.inputBox {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--wac-border);\n border-radius: 999px;\n font-size: 14px;\n outline: none;\n font-family: inherit;\n background: #f9fafb;\n color: var(--wac-fg);\n}\n\n.inputBox:focus {\n border-color: var(--wac-brand);\n background: var(--wac-bg);\n}\n\n.inputBox:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sendButton {\n padding: 0 16px;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border: none;\n border-radius: 999px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n font-family: inherit;\n}\n\n.sendButton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.hiddenFileInput {\n position: absolute;\n width: 0;\n height: 0;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n}\n\n.csvButton {\n flex-shrink: 0;\n padding: 0 12px;\n background: var(--wac-chip-bg);\n color: var(--wac-chip-fg);\n border: 1px solid var(--wac-border);\n border-radius: 999px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n white-space: nowrap;\n}\n\n.csvButton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.authGate {\n margin: auto;\n text-align: center;\n padding: 32px 24px;\n max-width: 280px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: center;\n}\n\n.authGateIcon {\n font-size: 36px;\n}\n\n.authGateTitle {\n font-size: 16px;\n font-weight: 600;\n}\n\n.authGateText {\n font-size: 13px;\n color: var(--wac-muted);\n line-height: 1.5;\n}\n\n.authGateButton {\n margin-top: 8px;\n padding: 10px 20px;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border: none;\n border-radius: 999px;\n cursor: pointer;\n font-weight: 600;\n font-size: 14px;\n font-family: inherit;\n}\n\n.authGateDisclaimer {\n margin-top: 16px;\n padding-top: 12px;\n border-top: 1px dashed var(--wac-border);\n font-size: 11px;\n color: var(--wac-muted);\n line-height: 1.5;\n text-align: left;\n width: 100%;\n}\n\n.authGateDisclaimerTitle {\n font-weight: 700;\n letter-spacing: 0.6px;\n font-size: 10px;\n margin-bottom: 4px;\n color: var(--wac-fg);\n}\n\n.errorBanner {\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #991b1b;\n padding: 8px 12px;\n font-size: 12px;\n border-radius: 8px;\n margin: 0 14px 8px;\n}\n\n/* ── Greeting popup bubble ─────────────────────────────────────── */\n\n.popupBubble {\n position: fixed;\n bottom: 24px;\n z-index: 2147483646;\n background: var(--wac-brand);\n color: var(--wac-brand-contrast);\n border-radius: 12px;\n padding: 12px 36px 12px 14px;\n font-size: 13px;\n line-height: 1.45;\n box-shadow: var(--wac-shadow);\n border: none;\n max-width: 240px;\n animation: wacPopIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n/* Shared arrow base — direction is set per-position class below */\n.popupBubble::after {\n content: '';\n position: absolute;\n width: 12px;\n height: 12px;\n background: var(--wac-brand);\n}\n\n/* Popup to the LEFT of a right-positioned button — arrow points right */\n.popupBubbleRight {\n right: 94px;\n}\n\n.popupBubbleRight::after {\n right: -7px;\n top: 50%;\n border-top: 1px solid var(--wac-brand);\n border-right: 1px solid var(--wac-brand);\n transform: translateY(-50%) rotate(45deg);\n}\n\n/* Popup to the RIGHT of a left-positioned button — arrow points left */\n.popupBubbleLeft {\n left: 94px;\n}\n\n.popupBubbleLeft::after {\n left: -7px;\n top: 50%;\n border-bottom: 1px solid var(--wac-brand);\n border-left: 1px solid var(--wac-brand);\n transform: translateY(-50%) rotate(45deg);\n}\n\n.popupDismiss {\n position: absolute;\n top: 8px;\n right: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--wac-brand-contrast);\n line-height: 1;\n padding: 2px 4px;\n border-radius: 4px;\n font-family: inherit;\n opacity: 0.75;\n}\n\n.popupDismiss:hover {\n background: rgba(255, 255, 255, 0.15);\n opacity: 1;\n}\n\n@keyframes wacPopIn {\n 0% { opacity: 0; transform: scale(0.85) translateY(8px); }\n 100% { opacity: 1; transform: scale(1) translateY(0); }\n}\n","import styles from \"../styles/chat.module.css\";\n\ninterface AuthGateProps {\n brandName: string;\n loginUrl: string;\n onLoginClick?: () => void;\n}\n\nexport function AuthGate({ brandName, loginUrl, onLoginClick }: AuthGateProps) {\n const handleClick = () => {\n if (onLoginClick) {\n onLoginClick();\n return;\n }\n if (typeof window !== \"undefined\") {\n window.location.href = loginUrl;\n }\n };\n\n return (\n <div className={styles.authGate}>\n <div className={styles.authGateIcon} aria-hidden=\"true\">🔒</div>\n <div className={styles.authGateTitle}>Login required</div>\n <div className={styles.authGateText}>\n To access {brandName}, please sign in first.\n </div>\n <button type=\"button\" className={styles.authGateButton} onClick={handleClick}>\n Sign in / Register →\n </button>\n <div className={styles.authGateDisclaimer}>\n <div className={styles.authGateDisclaimerTitle}>DISCLAIMER</div>\n <div>• AI-assisted analysis for educational purposes only.</div>\n <div>• Not financial advice. Markets involve risk.</div>\n <div>• Consult a SEBI-registered advisor before investing.</div>\n </div>\n </div>\n );\n}\n","import type { Chip as ChipType } from \"../types\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChipProps {\n chip: ChipType;\n disabled?: boolean;\n active?: boolean;\n onClick: (chip: ChipType) => void;\n}\n\nexport function Chip({ chip, disabled, active, onClick }: ChipProps) {\n const classes = [\n styles.chip,\n active ? styles.chipActive : \"\",\n disabled ? styles.chipDisabled : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n type=\"button\"\n className={classes}\n disabled={disabled}\n onClick={() => !disabled && onClick(chip)}\n >\n {chip.icon ? <span aria-hidden=\"true\">{chip.icon}</span> : null}\n <span>{chip.label}</span>\n </button>\n );\n}\n","import type { Chip as ChipType } from \"../types\";\nimport { Chip } from \"./Chip\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChipRowProps {\n chips: ChipType[];\n disabled?: boolean;\n onClick: (chip: ChipType) => void;\n}\n\nexport function ChipRow({ chips, disabled, onClick }: ChipRowProps) {\n if (!chips || chips.length === 0) return null;\n return (\n <div className={styles.chipRow}>\n {chips.map((c) => (\n <Chip key={c.id} chip={c} disabled={disabled} onClick={onClick} />\n ))}\n </div>\n );\n}\n","import DOMPurify from \"isomorphic-dompurify\";\n\n/**\n * Backend (chat_widget.py + chat_template_dispatch.py) returns Telegram-HTML in\n * BotResponse.message — e.g. `<b>Heading</b><br>Body<br><i>Note</i>`.\n *\n * We sanitize with DOMPurify against a tight allow-list and feed straight into\n * the bubble via dangerouslySetInnerHTML. This matches the exact look of the\n * Telegram bot for every response template.\n *\n * Markdown-it is intentionally NOT used here anymore — the backend handles all\n * formatting via the shared Telegram templates.\n */\n\nconst ALLOWED_TAGS = [\n \"b\", \"strong\",\n \"i\", \"em\",\n \"u\", \"ins\",\n \"s\", \"strike\", \"del\",\n \"br\",\n \"p\",\n \"code\", \"pre\",\n \"a\",\n \"ul\", \"ol\", \"li\",\n \"blockquote\",\n \"span\",\n];\n\nconst ALLOWED_ATTR = [\"href\", \"target\", \"rel\", \"class\"];\n\nconst SANITIZE_CFG = {\n ALLOWED_TAGS,\n ALLOWED_ATTR,\n // Block javascript: / data: hrefs by stripping URI schemes other than http(s) / mailto\n ALLOW_UNKNOWN_PROTOCOLS: false,\n ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto):|[^a-z]|[a-z+.-]+(?:[^a-z+.\\-:]|$))/i,\n};\n\n/**\n * Convert Telegram-style markdown shortcuts to HTML so chip prompts written\n * with `*bold*` / `_italic_` in Python source render the same way as the\n * template HTML output. Also handles the *standard* markdown that\n * AI-generated text (e.g. the sector-news `ai_verdict`) commonly emits.\n *\n * ## Heading → <b>Heading</b> (line-start ATX header, 1–6 #)\n * **text** → <b>text</b> (double asterisk, standard-bold)\n * __text__ → <b>text</b> (double underscore, standard-bold)\n * *text* → <b>text</b> (single asterisk, Telegram-bold)\n * _text_ → <i>text</i> (single underscore, italic)\n *\n * Order matters: double markers are converted before single ones so a `**`\n * pair isn't half-consumed by the single-asterisk rule. The single-marker\n * rules use lookbehind/ahead so they don't touch already-converted `<b>`\n * spans or dangling markers inside HTML attribute values.\n */\nfunction inlineMarkdownToHtml(text: string): string {\n return text\n // ATX headers at the start of a line → bold (verdict gap, no real <h*> here)\n .replace(/^[ \\t]*#{1,6}[ \\t]+(.+?)[ \\t]*$/gm, \"<b>$1</b>\")\n // Standard double-marker bold first, so the single-marker rules skip them.\n .replace(/\\*\\*([^\\n<>]+?)\\*\\*/g, \"<b>$1</b>\")\n .replace(/__([^\\n<>]+?)__/g, \"<b>$1</b>\")\n // Telegram single-asterisk bold / single-underscore italic.\n .replace(/(?<!\\*)\\*([^\\n*<>]+?)\\*(?!\\*)/g, \"<b>$1</b>\")\n .replace(/(?<![_a-zA-Z0-9])_([^\\n_<>]+?)_(?![_a-zA-Z0-9])/g, \"<i>$1</i>\");\n}\n\n/**\n * Render a Telegram-HTML or markdown-flavoured string from the backend as\n * sanitized HTML suitable for dangerouslySetInnerHTML.\n *\n * Pipeline:\n * 1. `*bold*` / `_italic_` markdown shortcuts → `<b>` / `<i>`\n * 2. Single `\\n` → `<br>`, `\\n\\n` → paragraph break (visual gap)\n * 3. DOMPurify sanitization against a tight allow-list\n */\nexport function renderMarkdown(text: string): string {\n if (!text) return \"\";\n\n const inlined = inlineMarkdownToHtml(text);\n\n // Split on blank lines into paragraphs, then within each paragraph turn \\n into <br>.\n const paragraphs = inlined\n .split(/\\n{2,}/)\n .map((para) => para.replace(/\\n/g, \"<br>\"))\n .filter((p) => p.length > 0);\n\n const html = paragraphs.length > 1\n ? paragraphs.map((p) => `<p>${p}</p>`).join(\"\")\n : paragraphs[0] ?? \"\";\n\n return DOMPurify.sanitize(html, SANITIZE_CFG);\n}\n","import type { Chip as ChipType, Message } from \"../types\";\nimport { ChipRow } from \"./ChipRow\";\nimport { renderMarkdown } from \"../utils/markdown\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface MessageBubbleProps {\n message: Message;\n onChipClick: (chip: ChipType) => void;\n}\n\nexport function MessageBubble({ message, onChipClick }: MessageBubbleProps) {\n const isBot = message.role === \"bot\";\n const bubbleClass = isBot\n ? `${styles.bubble} ${styles.bubbleBot}`\n : `${styles.bubble} ${styles.bubbleUser}`;\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n <div className={bubbleClass}>\n {isBot ? (\n <div\n className={styles.markdown}\n dangerouslySetInnerHTML={{ __html: renderMarkdown(message.content) }}\n />\n ) : (\n message.content\n )}\n </div>\n {isBot && message.chips && message.chips.length > 0 ? (\n <ChipRow\n chips={message.chips}\n disabled={!message.chipsActive}\n onClick={onChipClick}\n />\n ) : null}\n </div>\n );\n}\n","import styles from \"../styles/chat.module.css\";\n\nexport function TypingIndicator() {\n return (\n <div className={styles.typing} aria-live=\"polite\" aria-label=\"Assistant is typing\">\n <span className={styles.typingDot} />\n <span className={styles.typingDot} />\n <span className={styles.typingDot} />\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport type { Chip as ChipType, Message } from \"../types\";\nimport { AuthGate } from \"./AuthGate\";\nimport { MessageBubble } from \"./MessageBubble\";\nimport { TypingIndicator } from \"./TypingIndicator\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChatBodyProps {\n isLoggedIn: boolean;\n loading: boolean;\n messages: Message[];\n isTyping: boolean;\n brandName: string;\n loginUrl: string;\n error: string | null;\n onChipClick: (chip: ChipType) => void;\n onLoginClick?: () => void;\n}\n\nexport function ChatBody({\n isLoggedIn,\n loading,\n messages,\n isTyping,\n brandName,\n loginUrl,\n error,\n onChipClick,\n onLoginClick,\n}: ChatBodyProps) {\n const endRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n endRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages.length, isTyping]);\n\n if (loading) {\n return (\n <div className={styles.body}>\n <TypingIndicator />\n </div>\n );\n }\n\n if (!isLoggedIn) {\n return (\n <div className={styles.body}>\n <AuthGate\n brandName={brandName}\n loginUrl={loginUrl}\n onLoginClick={onLoginClick}\n />\n </div>\n );\n }\n\n return (\n <div className={styles.body}>\n {messages.map((m) => (\n <MessageBubble key={m.id} message={m} onChipClick={onChipClick} />\n ))}\n {isTyping ? <TypingIndicator /> : null}\n {error ? <div className={styles.errorBanner}>{error}</div> : null}\n <div ref={endRef} />\n </div>\n );\n}\n","export function formatCountdown(remainingMs: number): string {\n if (remainingMs <= 0) return \"expired\";\n const totalSeconds = Math.floor(remainingMs / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n\n if (hours > 0) return `${hours}h ${minutes}m left`;\n if (minutes > 0) return `${minutes}m ${seconds}s left`;\n return `${seconds}s left`;\n}\n\nexport function formatRelativeTime(ts: number, now: number = Date.now()): string {\n const diff = Math.max(0, now - ts);\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n","import styles from \"../styles/chat.module.css\";\nimport { formatCountdown } from \"../utils/time\";\n\ninterface ChatHeaderProps {\n brandName: string;\n remainingMs: number;\n showCountdown: boolean;\n onClose: () => void;\n onClear?: () => void;\n}\n\nexport function ChatHeader({\n brandName,\n remainingMs,\n showCountdown,\n onClose,\n onClear,\n}: ChatHeaderProps) {\n return (\n <div className={styles.header}>\n <div>\n <div className={styles.headerTitle}>{brandName}</div>\n {showCountdown && remainingMs > 0 ? (\n <div className={styles.headerMeta}>Session: {formatCountdown(remainingMs)}</div>\n ) : null}\n </div>\n <div className={styles.headerActions}>\n {onClear ? (\n <button\n type=\"button\"\n className={styles.iconButton}\n onClick={onClear}\n aria-label=\"Clear conversation\"\n title=\"Clear conversation\"\n >\n ↺\n </button>\n ) : null}\n <button\n type=\"button\"\n className={styles.iconButton}\n onClick={onClose}\n aria-label=\"Close chat\"\n title=\"Close\"\n >\n ✕\n </button>\n </div>\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface ChatInputProps {\n disabled?: boolean;\n placeholder?: string;\n onSend: (text: string) => void;\n}\n\nexport function ChatInput({ disabled, placeholder, onSend }: ChatInputProps) {\n const [value, setValue] = useState(\"\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!disabled) {\n inputRef.current?.focus();\n }\n }, [disabled]);\n\n const submit = () => {\n const trimmed = value.trim();\n if (!trimmed || disabled) return;\n onSend(trimmed);\n setValue(\"\");\n inputRef.current?.focus();\n };\n\n return (\n <div className={styles.input}>\n <input\n ref={inputRef}\n type=\"text\"\n className={styles.inputBox}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n submit();\n }\n }}\n disabled={disabled}\n placeholder={placeholder ?? \"Type a message…\"}\n aria-label=\"Message input\"\n />\n <button\n type=\"button\"\n className={styles.sendButton}\n onClick={submit}\n disabled={disabled || value.trim().length === 0}\n >\n Send\n </button>\n </div>\n );\n}\n","import type { ChatPosition } from \"../types\";\nimport styles from \"../styles/chat.module.css\";\n\ninterface FloatingButtonProps {\n position: ChatPosition;\n onClick: () => void;\n brandColor?: string;\n showPopup?: boolean;\n popupMessage?: string;\n onPopupDismiss?: () => void;\n}\n\nexport function FloatingButton({ position, onClick, brandColor, showPopup, popupMessage, onPopupDismiss }: FloatingButtonProps) {\n const posClass = position === \"bottom-left\" ? styles.positionLeft : styles.positionRight;\n const popupPosClass = position === \"bottom-left\" ? styles.popupBubbleLeft : styles.popupBubbleRight;\n return (\n <>\n {showPopup && popupMessage ? (\n <div\n className={`${styles.popupBubble} ${popupPosClass}`}\n role=\"status\"\n aria-live=\"polite\"\n >\n {popupMessage}\n <button\n type=\"button\"\n className={styles.popupDismiss}\n onClick={onPopupDismiss}\n aria-label=\"Dismiss greeting\"\n >\n ✕\n </button>\n </div>\n ) : null}\n <button\n type=\"button\"\n className={`${styles.floatingButton} ${posClass}`}\n onClick={onClick}\n aria-label=\"Open chat\"\n style={brandColor ? { background: brandColor } : undefined}\n >\n 💬\n </button>\n </>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAuth } from \"../hooks/useAuth\";\nimport { useChat } from \"../hooks/useChat\";\nimport { useChip } from \"../hooks/useChip\";\nimport { useSession } from \"../hooks/useSession\";\nimport type { Chip, Message, WealthChatProps } from \"../types\";\nimport { DEFAULT_SESSION_TTL_SECONDS } from \"../utils/session\";\nimport { ChatBody } from \"./ChatBody\";\nimport { ChatHeader } from \"./ChatHeader\";\nimport { ChatInput } from \"./ChatInput\";\nimport { FloatingButton } from \"./FloatingButton\";\nimport styles from \"../styles/chat.module.css\";\n\nconst DEFAULT_BRAND_NAME = \"Wealth Alpha AI\";\nconst DEFAULT_BRAND_COLOR = \"#1a2d5a\";\nconst DEFAULT_AUTH_CHECK = \"/me\";\nconst DEFAULT_GREETING = \"Hi! I'm your Wealth Alpha AI assistant. How can I help you?\";\n\nconst DISCLAIMER_BLOCK =\n \"DISCLAIMER:\\n\" +\n \"• AI-assisted analysis for educational purposes only.\\n\" +\n \"• Not financial advice. Markets involve risk.\\n\" +\n \"• Consult a SEBI-registered advisor before investing.\";\n\nconst CTA_LINE =\n \"Select a quick command below — or type your query to ask our AI Research Analyst directly.\";\n\n/** Opens file picker in-widget; must match backend PORTFOLIO_CSV_PICK_CHIP.id */\nconst PORTFOLIO_CSV_CHIP_ID = \"__portfolio_csv_upload\";\n\nfunction buildWelcome(name: string | undefined, plan: string | undefined): string {\n const greeting = name\n ? `Welcome back, ${name}! You have ${plan ? plan : \"Premium\"} access.`\n : `Welcome! You have ${plan ? plan : \"Premium\"} access.`;\n return `${greeting}\\n\\n${DISCLAIMER_BLOCK}\\n\\n${CTA_LINE}`;\n}\n\nexport function WealthChat(props: WealthChatProps) {\n const {\n apiBase,\n authCheck = DEFAULT_AUTH_CHECK,\n loginUrl,\n sessionTTL = DEFAULT_SESSION_TTL_SECONDS,\n welcomeMessage,\n brandName = DEFAULT_BRAND_NAME,\n brandColor = DEFAULT_BRAND_COLOR,\n position = \"bottom-right\",\n defaultOpen = false,\n showCountdown = true,\n greetingMessage = DEFAULT_GREETING,\n onLogin,\n onLogout,\n onSessionExpire,\n onError,\n } = props;\n\n const [mounted, setMounted] = useState(false);\n const [open, setOpen] = useState(defaultOpen);\n const [showPopup, setShowPopup] = useState(false);\n const popupShownRef = useRef(defaultOpen);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (!mounted || open || popupShownRef.current) return;\n const timer = setTimeout(() => {\n setShowPopup(true);\n popupShownRef.current = true;\n }, 1000);\n return () => clearTimeout(timer);\n }, [mounted, open]);\n\n const {\n session,\n remainingMs,\n setHistory,\n touch,\n clear: clearSessionState,\n } = useSession({\n ttlSeconds: sessionTTL,\n onExpire: onSessionExpire,\n });\n\n const { isLoggedIn, user, loading: authLoading } = useAuth({\n apiBase,\n authCheck,\n enabled: mounted && open,\n onError,\n });\n\n const handleAuthExpired = useCallback(() => {\n clearSessionState();\n onSessionExpire?.();\n }, [clearSessionState, onSessionExpire]);\n\n const handleHistoryChange = useCallback(\n (history: Message[]) => {\n if (!session) return;\n setHistory(history);\n },\n [session, setHistory],\n );\n\n const csvFileRef = useRef<HTMLInputElement>(null);\n\n const {\n state: chatState,\n sendText,\n uploadCsv,\n appendBotResponse,\n appendUserMessage,\n deactivatePriorChips,\n setTyping,\n loadHistory,\n clear: clearChat,\n } = useChat({\n apiBase,\n sessionId: session?.sessionId ?? null,\n initialMessages: session?.history,\n onHistoryChange: handleHistoryChange,\n onAuthExpired: handleAuthExpired,\n onError,\n });\n\n const { callChip } = useChip({\n apiBase,\n sessionId: session?.sessionId ?? null,\n onAuthExpired: handleAuthExpired,\n onError,\n });\n\n const welcomeShownRef = useMemo(() => ({ shown: false }), []);\n\n useEffect(() => {\n if (!isLoggedIn || !open) return;\n if (chatState.messages.length > 0) return;\n if (welcomeShownRef.shown) return;\n welcomeShownRef.shown = true;\n const messageText =\n welcomeMessage ??\n user?.welcomeMessage ??\n buildWelcome(user?.name, user?.plan);\n appendBotResponse({\n message: messageText,\n chips: user?.rootChips ?? [],\n sessionId: session?.sessionId ?? \"\",\n endOfFlow: false,\n });\n onLogin?.();\n }, [isLoggedIn, open, chatState.messages.length, welcomeMessage, session, user, appendBotResponse, onLogin, welcomeShownRef]);\n\n const handleChipClick = useCallback(\n async (chip: Chip) => {\n touch();\n deactivatePriorChips();\n\n if (chip.id === PORTFOLIO_CSV_CHIP_ID) {\n appendUserMessage(chip.label);\n csvFileRef.current?.click();\n return;\n }\n\n appendUserMessage(chip.label);\n setTyping(true);\n try {\n const resp = await callChip(chip);\n if (resp) appendBotResponse(resp);\n } finally {\n setTyping(false);\n }\n },\n [touch, deactivatePriorChips, appendUserMessage, callChip, setTyping, appendBotResponse],\n );\n\n const handleCsvFileSelected = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n e.target.value = \"\";\n if (file) {\n touch();\n void uploadCsv(file);\n }\n },\n [touch, uploadCsv],\n );\n\n const handleSend = useCallback(\n (text: string) => {\n touch();\n void sendText(text);\n },\n [touch, sendText],\n );\n\n const handleFloatingButtonClick = useCallback(() => {\n setOpen(true);\n setShowPopup(false);\n }, []);\n\n const handleClose = useCallback(() => setOpen(false), []);\n\n const handleClear = useCallback(() => {\n clearChat();\n welcomeShownRef.shown = false;\n setHistory([]);\n }, [clearChat, setHistory, welcomeShownRef]);\n\n const handleLoginClick = useCallback(() => {\n if (typeof window !== \"undefined\") {\n window.location.href = loginUrl;\n }\n }, [loginUrl]);\n\n if (!mounted) return null;\n\n const rootStyle = {\n [\"--wac-brand\" as string]: brandColor,\n } as React.CSSProperties;\n\n return (\n <div className={styles.root} style={rootStyle}>\n {!open ? (\n <FloatingButton\n position={position}\n onClick={handleFloatingButtonClick}\n brandColor={brandColor}\n showPopup={showPopup}\n popupMessage={greetingMessage}\n onPopupDismiss={() => setShowPopup(false)}\n />\n ) : null}\n {open ? (\n <div\n className={`${styles.widget} ${position === \"bottom-left\" ? styles.positionLeft : styles.positionRight}`}\n >\n <ChatHeader\n brandName={brandName}\n remainingMs={remainingMs}\n showCountdown={showCountdown && isLoggedIn}\n onClose={handleClose}\n onClear={isLoggedIn ? handleClear : undefined}\n />\n <ChatBody\n isLoggedIn={isLoggedIn}\n loading={authLoading}\n messages={chatState.messages}\n isTyping={chatState.isTyping}\n brandName={brandName}\n loginUrl={loginUrl}\n error={chatState.error}\n onChipClick={handleChipClick}\n onLoginClick={handleLoginClick}\n />\n <input\n ref={csvFileRef}\n type=\"file\"\n accept=\".csv,text/csv\"\n className={styles.hiddenFileInput}\n onChange={handleCsvFileSelected}\n aria-hidden\n tabIndex={-1}\n />\n {isLoggedIn ? (\n <ChatInput\n disabled={chatState.isTyping}\n onSend={handleSend}\n placeholder=\"Type a message…\"\n />\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n"]}
|