@huskel/sdk 0.4.6 → 0.4.8
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.css +531 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +464 -123
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +464 -125
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts","../src/client.ts","../src/hooks/useHuskel.ts","../src/hooks/useSearch.ts","../src/components/HuskelProvider.tsx","../src/hooks/useIngest.ts","../src/hooks/usePageIngest.ts","../src/hooks/useChat.ts","../src/hooks/useCart.ts","../src/components/SearchBar.tsx","../src/utils/cn.ts","../src/components/Sparkle.tsx","../src/utils/markdown.tsx","../src/components/ChatWidget.tsx","../src/components/AIChatButton.tsx","../src/components/CartBadge.tsx","../src/components/CartDrawer.tsx","../src/components/CheckoutModal.tsx"],"sourcesContent":["import { Product, SearchResponse, IngestResponse, HuskelError } from './types';\r\n\r\nconst MAX_RETRIES = 3;\r\nconst RETRY_DELAYS = [500, 1000, 2000]; // ms\r\n\r\nfunction log(level: 'info' | 'warn' | 'error', msg: string, data?: unknown) {\r\n const prefix = '[Huskel]';\r\n if (level === 'error') console.error(prefix, msg, data ?? '');\r\n else if (level === 'warn') console.warn(prefix, msg, data ?? '');\r\n else console.log(prefix, msg, data ?? '');\r\n}\r\n\r\nasync function sleep(ms: number) {\r\n return new Promise(r => setTimeout(r, ms));\r\n}\r\n\r\nexport class HuskelAPI {\r\n constructor(\r\n private apiUrl: string,\r\n private siteId: string,\r\n private apiToken: string,\r\n private getShopperId?: () => string | undefined,\r\n private getSessionId?: () => string | undefined\r\n ) {}\r\n\r\n private async post<T>(path: string, body: unknown, attempt = 0): Promise<T> {\r\n const url = `${this.apiUrl}${path}`;\r\n\r\n try {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'X-Huskel-Token': this.apiToken,\r\n 'X-Huskel-Site': this.siteId,\r\n };\r\n\r\n const shopperId = this.getShopperId?.();\r\n if (shopperId) {\r\n headers['X-Huskel-Shopper-Id'] = shopperId;\r\n }\r\n\r\n const sessionId = this.getSessionId?.();\r\n if (sessionId) {\r\n headers['X-Huskel-Session-Id'] = sessionId;\r\n }\r\n\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!res.ok) {\r\n const text = await res.text();\r\n let message = text;\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed.error === 'string') {\r\n message = parsed.error;\r\n }\r\n } catch {\r\n // keep original text\r\n }\r\n const err: HuskelError = { status: res.status, message };\r\n\r\n // Don't retry 4xx — developer errors\r\n if (res.status >= 400 && res.status < 500) {\r\n log('error', `${path} failed [${res.status}]`, text);\r\n throw err;\r\n }\r\n\r\n // Retry 5xx\r\n if (attempt < MAX_RETRIES - 1) {\r\n log('warn', `${path} [${res.status}] retrying (${attempt + 1}/${MAX_RETRIES})...`);\r\n await sleep(RETRY_DELAYS[attempt]);\r\n return this.post(path, body, attempt + 1);\r\n }\r\n\r\n log('error', `${path} failed after ${MAX_RETRIES} attempts`, err);\r\n throw err;\r\n }\r\n\r\n return res.json();\r\n } catch (e) {\r\n // Network error (offline, DNS, etc.)\r\n if ((e as HuskelError).status === undefined) {\r\n if (attempt < MAX_RETRIES - 1) {\r\n log('warn', `${path} network error, retrying (${attempt + 1}/${MAX_RETRIES})...`);\r\n await sleep(RETRY_DELAYS[attempt]);\r\n return this.post(path, body, attempt + 1);\r\n }\r\n log('error', `${path} unreachable after ${MAX_RETRIES} attempts`);\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n async ingest(product: Product): Promise<IngestResponse> {\r\n log('info', 'ingesting product', product.name);\r\n return this.post('/ingest', { siteId: this.siteId, product });\r\n }\r\n\r\n async ingestBatch(products: Product[]): Promise<IngestResponse> {\r\n log('info', `ingesting batch of ${products.length} products`);\r\n return this.post('/ingest/batch', { siteId: this.siteId, products });\r\n }\r\n\r\n async search(query: string, limit = 10): Promise<SearchResponse> {\r\n log('info', 'search query', query);\r\n return this.post('/search', { query, siteId: this.siteId, limit });\r\n }\r\n\r\n // Pure vector search — no LLM, instant results. This is what the SearchBar uses.\r\n async searchVector(query: string, limit = 10): Promise<SearchResponse> {\r\n return this.post('/search/vector', { query, siteId: this.siteId, limit });\r\n }\r\n\r\n // Autocomplete — pure in-memory Trie, <1ms, no Upstash call. Only true prefix matches.\r\n async searchAutocomplete(query: string, limit = 8): Promise<SearchResponse> {\r\n return this.post('/search/autocomplete', { query, siteId: this.siteId, limit });\r\n }\r\n\r\n // LLM chat — conversational search with history context.\r\n async chat(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = []): Promise<{ answer: string; sources: any[]; checkout?: import('./types').CartPayload; action?: any }> {\r\n log('info', 'chat query', query);\r\n return this.post('/chat', { query, siteId: this.siteId, history });\r\n }\r\n\r\n // --- Cart System ---\r\n private buildHeaders(): Record<string, string> {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'X-Huskel-Token': this.apiToken,\r\n 'X-Huskel-Site': this.siteId,\r\n };\r\n const shopperId = this.getShopperId?.();\r\n if (shopperId) headers['X-Huskel-Shopper-Id'] = shopperId;\r\n const sessionId = this.getSessionId?.();\r\n if (sessionId) headers['X-Huskel-Session-Id'] = sessionId;\r\n return headers;\r\n }\r\n\r\n async getCart(): Promise<import('./types').CartPayload> {\r\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to fetch cart');\r\n return res.json();\r\n }\r\n\r\n async clearCart(): Promise<import('./types').CartPayload> {\r\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\r\n method: 'DELETE',\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to clear cart');\r\n return res.json();\r\n }\r\n\r\n async checkoutCart(): Promise<import('./types').CartPayload> {\r\n const res = await fetch(`${this.apiUrl}/cart/checkout`, {\r\n method: 'POST',\r\n headers: this.buildHeaders(),\r\n body: JSON.stringify({ siteId: this.siteId })\r\n });\r\n if (!res.ok) throw new Error('Failed to checkout cart');\r\n return res.json();\r\n }\r\n\r\n async getCheckoutConfig(): Promise<any> {\r\n const res = await fetch(`${this.apiUrl}/checkout/config?site_id=${this.siteId}`, {\r\n method: 'GET',\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to fetch checkout config');\r\n return res.json();\r\n }\r\n}\r\n","import { HuskelConfig, Product, RawProductInput } from './types';\r\nimport { HuskelAPI } from './api';\r\n\r\nfunction getEnvVar(key: string): string | undefined {\r\n if (typeof globalThis !== 'undefined') {\r\n const g = globalThis as any;\r\n if (g.process && g.process.env) {\r\n return g.process.env[key];\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction mapRawProduct(input: RawProductInput): Product | null {\r\n const name = input.name || input.title || input.productName || '';\r\n \r\n let price = '';\r\n let priceNumeric: number | undefined = undefined;\r\n\r\n if (input.price !== undefined) {\r\n if (typeof input.price === 'number') {\r\n priceNumeric = input.price;\r\n price = String(input.price);\r\n } else {\r\n price = input.price;\r\n const num = parseFloat(input.price.replace(/[^0-9.]/g, ''));\r\n priceNumeric = isNaN(num) ? undefined : num;\r\n }\r\n }\r\n if (input.priceNumeric !== undefined) {\r\n priceNumeric = input.priceNumeric;\r\n }\r\n\r\n let url = input.url || '';\r\n if (!url && typeof window !== 'undefined') {\r\n url = window.location.href;\r\n }\r\n\r\n let slug = input.slug || input.id || input.productId || '';\r\n if (!slug && url) {\r\n slug = url.split('/').filter(Boolean).pop() || '';\r\n }\r\n if (!slug && name) {\r\n slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');\r\n }\r\n\r\n let images: string[] = [];\r\n if (input.images) {\r\n images = input.images;\r\n } else if (input.image) {\r\n images = [input.image];\r\n } else if (input.thumbnail) {\r\n images = [input.thumbnail];\r\n }\r\n\r\n if (!name) {\r\n console.warn('[Huskel] Validation warning: Product name/title is missing. Skipping:', input);\r\n return null;\r\n }\r\n if (!price) {\r\n console.warn('[Huskel] Validation warning: Product price is missing. Skipping:', input);\r\n return null;\r\n }\r\n if (!url) {\r\n console.warn('[Huskel] Validation warning: Product URL is missing. Skipping:', input);\r\n return null;\r\n }\r\n\r\n return {\r\n name,\r\n price,\r\n url,\r\n brand: input.brand,\r\n description: input.description,\r\n originalPrice: input.originalPrice,\r\n discount: input.discount,\r\n currency: input.currency ?? 'KES',\r\n stock: input.stock,\r\n availability: input.availability,\r\n rating: input.rating,\r\n reviewCount: input.reviewCount,\r\n category: input.category,\r\n subCategory: input.subCategory,\r\n tags: input.tags,\r\n images: images.length > 0 ? images : undefined,\r\n specs: input.specs,\r\n priceNumeric,\r\n slug,\r\n };\r\n}\r\n\r\nfunction generateUUID(): string {\r\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\r\n return crypto.randomUUID();\r\n }\r\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\r\n const r = (Math.random() * 16) | 0;\r\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\r\n return v.toString(16);\r\n });\r\n}\r\n\r\nexport class HuskelClient {\r\n readonly api: HuskelAPI;\r\n private ingestQueue: Product[] = [];\r\n private ingestTimer: ReturnType<typeof setTimeout> | null = null;\r\n private ingestedUrls = new Set<string>();\r\n private onlineHandler: (() => void) | null = null;\r\n private shopperId?: string;\r\n private sessionId: string = '';\r\n public onCheckout?: (cart: import('./types').CartPayload) => void;\r\n\r\n private static INGEST_CACHE_KEY = 'huskel_ingested_v1';\r\n private static INGEST_CACHE_TTL = 24 * 60 * 60 * 1000; // 24h\r\n\r\n private loadIngestedCache() {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n const raw = localStorage.getItem(HuskelClient.INGEST_CACHE_KEY);\r\n if (!raw) return;\r\n const { ts, urls }: { ts: number; urls: string[] } = JSON.parse(raw);\r\n if (Date.now() - ts > HuskelClient.INGEST_CACHE_TTL) {\r\n localStorage.removeItem(HuskelClient.INGEST_CACHE_KEY);\r\n return;\r\n }\r\n this.ingestedUrls = new Set(urls);\r\n } catch { /* ignore */ }\r\n }\r\n\r\n private saveIngestedCache() {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n localStorage.setItem(\r\n HuskelClient.INGEST_CACHE_KEY,\r\n JSON.stringify({ ts: Date.now(), urls: [...this.ingestedUrls] })\r\n );\r\n } catch { /* ignore */ }\r\n }\r\n\r\n constructor(config: HuskelConfig) {\r\n const siteId = config.siteId || getEnvVar('NEXT_PUBLIC_HUSKEL_SITE_ID') || '';\r\n const apiUrl = config.apiUrl || getEnvVar('NEXT_PUBLIC_HUSKEL_API_URL') || '';\r\n const apiToken = config.apiToken || getEnvVar('NEXT_PUBLIC_HUSKEL_API_TOKEN') || '';\r\n\r\n // Runtime validation — fail loudly so misconfiguration is never silent\r\n if (!siteId) console.error('[Huskel] Missing siteId. Set it via <HuskelProvider siteId=\"...\"> or NEXT_PUBLIC_HUSKEL_SITE_ID.');\r\n if (!apiUrl) console.error('[Huskel] Missing apiUrl. Set it via <HuskelProvider apiUrl=\"...\"> or NEXT_PUBLIC_HUSKEL_API_URL.');\r\n if (!apiToken) console.error('[Huskel] Missing apiToken. Set it via <HuskelProvider apiToken=\"...\"> or NEXT_PUBLIC_HUSKEL_API_TOKEN.');\r\n\r\n this.shopperId = config.shopperId;\r\n this.onCheckout = config.onCheckout;\r\n this.initSession();\r\n this.loadIngestedCache();\r\n\r\n this.api = new HuskelAPI(\r\n apiUrl,\r\n siteId,\r\n apiToken,\r\n () => this.getShopperId(),\r\n () => this.sessionId\r\n );\r\n instance = this;\r\n\r\n if (typeof window !== 'undefined') {\r\n this.onlineHandler = () => {\r\n console.log('[Huskel] Connectivity restored, flushing queued ingestions.');\r\n this.flushQueue();\r\n };\r\n window.addEventListener('online', this.onlineHandler);\r\n }\r\n }\r\n\r\n reRegister() {\r\n instance = this;\r\n }\r\n\r\n setShopperId(id: string | undefined) {\r\n this.shopperId = id;\r\n }\r\n\r\n getShopperId(): string | undefined {\r\n return this.shopperId || 'guest_' + this.sessionId;\r\n }\r\n\r\n getSessionId(): string {\r\n return this.sessionId;\r\n }\r\n\r\n private initSession() {\r\n if (typeof window !== 'undefined' && window.sessionStorage) {\r\n try {\r\n let sid = window.sessionStorage.getItem('huskel_session_id');\r\n if (!sid) {\r\n sid = generateUUID();\r\n window.sessionStorage.setItem('huskel_session_id', sid);\r\n }\r\n this.sessionId = sid;\r\n return;\r\n } catch (e) {\r\n // Fallback if sessionStorage is disabled or private mode\r\n }\r\n }\r\n this.sessionId = generateUUID();\r\n }\r\n\r\n destroy() {\r\n if (typeof window !== 'undefined' && this.onlineHandler) {\r\n window.removeEventListener('online', this.onlineHandler);\r\n this.onlineHandler = null;\r\n }\r\n if (this.ingestTimer) {\r\n clearTimeout(this.ingestTimer);\r\n this.ingestTimer = null;\r\n }\r\n if (instance === this) instance = null;\r\n }\r\n\r\n async queueIngest(rawProduct: RawProductInput): Promise<void> {\r\n const product = mapRawProduct(rawProduct);\r\n if (!product) return;\r\n\r\n if (this.ingestedUrls.has(product.url)) {\r\n return; // already indexed in this session or today — skip\r\n }\r\n this.ingestedUrls.add(product.url);\r\n this.saveIngestedCache();\r\n\r\n this.ingestQueue.push(product);\r\n this.scheduleFlush();\r\n }\r\n\r\n async queueIngestBatch(rawProducts: RawProductInput[]): Promise<void> {\r\n rawProducts.forEach(p => {\r\n const product = mapRawProduct(p);\r\n if (!product) return;\r\n\r\n if (this.ingestedUrls.has(product.url)) {\r\n return;\r\n }\r\n this.ingestedUrls.add(product.url);\r\n this.ingestQueue.push(product);\r\n });\r\n\r\n if (this.ingestQueue.length > 0) {\r\n this.saveIngestedCache();\r\n this.scheduleFlush();\r\n }\r\n }\r\n\r\n private scheduleFlush() {\r\n if (this.ingestTimer) return;\r\n this.ingestTimer = setTimeout(() => {\r\n this.flushQueue();\r\n }, 300);\r\n }\r\n\r\n private async flushQueue() {\r\n this.ingestTimer = null;\r\n if (this.ingestQueue.length === 0) return;\r\n\r\n if (typeof navigator !== 'undefined' && !navigator.onLine) {\r\n console.warn('[Huskel] Browser offline. Postponing ingestion.');\r\n return;\r\n }\r\n\r\n const batch = [...this.ingestQueue];\r\n this.ingestQueue = [];\r\n\r\n try {\r\n await this.api.ingestBatch(batch);\r\n } catch (e: any) {\r\n if (e.status && e.status >= 400 && e.status < 500) {\r\n console.error('[Huskel] Ingestion discarded due to client error:', e.message);\r\n return;\r\n }\r\n\r\n // Re-queue and schedule another flush so items are not stuck forever\r\n console.warn('[Huskel] Ingestion failed. Re-queuing to retry.', e);\r\n this.ingestQueue = [...batch, ...this.ingestQueue];\r\n this.scheduleFlush();\r\n }\r\n }\r\n}\r\n\r\nlet instance: HuskelClient | null = null;\r\n\r\nexport function initHuskel(config: HuskelConfig): HuskelClient {\r\n instance = new HuskelClient(config);\r\n return instance;\r\n}\r\n\r\nexport function getHuskelClient(): HuskelClient {\r\n if (!instance) {\r\n const siteId = getEnvVar('NEXT_PUBLIC_HUSKEL_SITE_ID');\r\n const apiUrl = getEnvVar('NEXT_PUBLIC_HUSKEL_API_URL');\r\n const apiToken = getEnvVar('NEXT_PUBLIC_HUSKEL_API_TOKEN');\r\n\r\n if (siteId && apiUrl && apiToken) {\r\n instance = new HuskelClient({ siteId, apiUrl, apiToken });\r\n } else {\r\n throw new Error('[Huskel] Call initHuskel() or set NEXT_PUBLIC_HUSKEL_* environment variables before using the client.');\r\n }\r\n }\r\n return instance;\r\n}\r\n","import { useRef } from 'react';\r\nimport { HuskelConfig } from '../types';\r\nimport { HuskelClient, initHuskel } from '../client';\r\n\r\n/**\r\n * @deprecated Use <HuskelProvider> instead to avoid SSR issues.\r\n */\r\nexport function useHuskel(config: HuskelConfig): HuskelClient {\r\n const clientRef = useRef<HuskelClient | null>(null);\r\n\r\n if (!clientRef.current) {\r\n console.warn('[Huskel] useHuskel() is deprecated. Please wrap your application in <HuskelProvider> instead.');\r\n clientRef.current = initHuskel(config);\r\n }\r\n\r\n return clientRef.current;\r\n}\r\n","import { useState, useCallback, useRef } from 'react';\nimport { SearchResult } from '../types';\nimport { useHuskelContext } from '../components/HuskelProvider';\n\ninterface UseSearchReturn {\n results: SearchResult[];\n loading: boolean;\n error: string | null;\n search: (query: string, limit?: number) => Promise<void>;\n clear: () => void;\n}\n\nexport function useSearch(): UseSearchReturn {\n const client = useHuskelContext();\n const [results, setResults] = useState<SearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n // Generation counter so stale responses from any in-flight requests don't overwrite newer ones\n const genRef = useRef(0);\n\n const search = useCallback(async (query: string, limit = 8) => {\n if (!query.trim()) { setResults([]); setLoading(false); return; }\n const gen = ++genRef.current;\n setLoading(true);\n setError(null);\n try {\n // searchAutocomplete = pure in-memory Trie, <1ms, no Upstash\n const res = await client.api.searchAutocomplete(query, limit);\n if (gen === genRef.current) {\n setResults(res.results ?? []);\n }\n } catch (e: unknown) {\n if (gen === genRef.current) {\n let msg = (e as any)?.message ?? 'Search failed';\n try {\n const parsed = JSON.parse(msg);\n if (parsed && parsed.error) {\n msg = parsed.error;\n }\n } catch {\n // keep original text\n }\n setError(msg);\n }\n } finally {\n if (gen === genRef.current) setLoading(false);\n }\n }, [client]);\n\n const clear = useCallback(() => {\n genRef.current++;\n setResults([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { results, loading, error, search, clear };\n}\n","'use client';\r\n\r\nimport React, { createContext, useContext, useEffect, useRef } from 'react';\r\nimport { HuskelClient, getHuskelClient } from '../client';\r\nimport { HuskelConfig } from '../types';\r\n\r\nexport const HuskelContext = createContext<HuskelClient | null>(null);\r\n\r\ninterface HuskelProviderProps extends HuskelConfig {\r\n children: React.ReactNode;\r\n}\r\n\r\nexport function HuskelProvider({ siteId, apiUrl, apiToken, shopperId, children }: HuskelProviderProps) {\r\n const clientRef = useRef<HuskelClient | null>(null);\r\n\r\n if (!clientRef.current) {\r\n clientRef.current = new HuskelClient({ siteId, apiUrl, apiToken, shopperId });\r\n } else {\r\n clientRef.current.reRegister();\r\n }\r\n\r\n // Update shopperId dynamically when it changes (e.g., shopper logs in/out)\r\n useEffect(() => {\r\n clientRef.current?.setShopperId(shopperId);\r\n }, [shopperId]);\r\n\r\n // Ensure active instance is registered on mount (handles development double-mounts and fast refresh)\r\n useEffect(() => {\r\n clientRef.current?.reRegister();\r\n }, []);\r\n\r\n // Clean up the online listener and timers when the provider unmounts\r\n // (prevents leaks during hot module reload and React StrictMode double-mount)\r\n useEffect(() => {\r\n return () => {\r\n clientRef.current?.destroy();\r\n };\r\n }, []);\r\n\r\n return (\r\n <HuskelContext.Provider value={clientRef.current}>\r\n {children}\r\n </HuskelContext.Provider>\r\n );\r\n}\r\n\r\nexport function useHuskelContext(): HuskelClient {\r\n const context = useContext(HuskelContext);\r\n if (!context) {\r\n return getHuskelClient();\r\n }\r\n return context;\r\n}\r\n\r\n","import { useCallback, useState } from 'react';\r\nimport { RawProductInput } from '../types';\r\nimport { useHuskelContext } from '../components/HuskelProvider';\r\n\r\ninterface UseIngestReturn {\r\n ingest: (product: RawProductInput) => Promise<void>;\r\n ingestBatch: (products: RawProductInput[]) => Promise<void>;\r\n loading: boolean;\r\n error: string | null;\r\n}\r\n\r\nexport function useIngest(): UseIngestReturn {\r\n const client = useHuskelContext();\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const ingest = useCallback(async (product: RawProductInput) => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n await client.queueIngest(product);\r\n } catch (e: unknown) {\r\n setError((e as Error).message ?? 'Ingest failed');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [client]);\r\n\r\n const ingestBatch = useCallback(async (products: RawProductInput[]) => {\r\n if (!products.length) return;\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n await client.queueIngestBatch(products);\r\n } catch (e: unknown) {\r\n setError((e as Error).message ?? 'Batch ingest failed');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [client]);\r\n\r\n return { ingest, ingestBatch, loading, error };\r\n}\r\n","import { useEffect, useRef } from 'react';\nimport { RawProductInput } from '../types';\nimport { getHuskelClient } from '../client';\n\n/**\n * usePageIngest — drop this into any product page component.\n * The moment a customer's browser renders the page, the product is\n * automatically captured and queued for ingestion into the vector index.\n *\n * No configuration needed beyond <HuskelProvider> in your layout.\n *\n * @example\n * // Product detail page — Next.js or React\n * export function ProductPage({ product }) {\n * usePageIngest({\n * name: product.title,\n * price: product.price,\n * url: window.location.href,\n * images: [product.thumbnail],\n * category: product.category,\n * });\n * return <div>...</div>;\n * }\n */\nexport function usePageIngest(product: RawProductInput | null | undefined): void {\n // Use url as the stable key — avoids re-ingesting on unrelated re-renders\n const ingestedRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!product) return;\n\n // Resolve URL — falls back to window.location if not provided\n const url =\n product.url ||\n (typeof window !== 'undefined' ? window.location.href : '');\n\n // Guard: only ingest once per URL per component lifecycle\n if (ingestedRef.current === url) return;\n ingestedRef.current = url;\n\n try {\n getHuskelClient().queueIngest({ ...product, url });\n } catch {\n // Client not initialised — silently skip\n }\n }, [product?.url ?? product?.name]);\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { useHuskelContext } from '../components/HuskelProvider';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatSource {\n id?: string;\n name: string;\n price?: string;\n currency?: string;\n category?: string;\n url?: string;\n image?: string;\n}\n\ninterface UseChatReturn {\n messages: ChatMessage[];\n sources: ChatSource[];\n loading: boolean;\n error: string | null;\n send: (query: string, displayQuery?: string) => Promise<void>;\n reset: () => void;\n}\n\nexport function useChat(): UseChatReturn {\n const client = useHuskelContext();\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [sources, setSources] = useState<ChatSource[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const send = useCallback(async (query: string, displayQuery?: string) => {\n if (!query.trim() || loading) return;\n abortRef.current?.abort();\n abortRef.current = new AbortController();\n const signal = abortRef.current.signal;\n\n // Optimistically add the user message\n const userMsg: ChatMessage = { role: 'user', content: displayQuery ?? query };\n setMessages(prev => [...prev, userMsg]);\n setLoading(true);\n setError(null);\n\n try {\n // Build history from current messages (exclude the one we just added — server will see it as query)\n const history = messages.map(m => ({ role: m.role, content: m.content }));\n const res = await client.api.chat(query, history);\n\n if (signal.aborted) return;\n\n const fullAnswer = res.answer || '';\n const words = fullAnswer.split(/(\\s+)/);\n\n // Initialize empty assistant message\n setMessages(prev => [...prev, { role: 'assistant', content: '' }]);\n\n let currentContent = '';\n for (const word of words) {\n if (signal.aborted) return;\n currentContent += word;\n setMessages(prev => {\n const next = [...prev];\n if (next.length > 0) {\n next[next.length - 1] = { role: 'assistant', content: currentContent };\n }\n return next;\n });\n // 25ms delay per word token to make it read naturally\n await new Promise(resolve => setTimeout(resolve, 25));\n }\n\n if (signal.aborted) return;\n setSources(res.sources ?? []);\n\n if (res.action?.type === 'add_to_cart' || res.checkout) {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('huskel:cart_updated', { detail: res.checkout }));\n }\n }\n if (res.action?.type === 'checkout') {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('huskel:trigger_checkout', { detail: res.checkout }));\n }\n }\n if (res.checkout && client.onCheckout) {\n client.onCheckout(res.checkout);\n }\n } catch (e: any) {\n if (signal.aborted) return;\n let msg = e?.message ?? 'Chat request failed';\n try {\n const parsed = JSON.parse(msg);\n if (parsed && parsed.error) {\n msg = parsed.error;\n }\n } catch {\n // keep original text\n }\n setError(msg);\n // Remove the optimistic user message on failure\n setMessages(prev => prev.slice(0, -1));\n } finally {\n if (!signal.aborted) {\n setLoading(false);\n }\n }\n }, [client, messages, loading]);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setMessages([]);\n setSources([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { messages, sources, loading, error, send, reset };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { useHuskelContext } from '../components/HuskelProvider';\nimport { CartPayload } from '../types';\n\nexport function useCart() {\n const client = useHuskelContext();\n const [cart, setCart] = useState<CartPayload | null>(null);\n const [loading, setLoading] = useState(false);\n\n const shopperId = client.getShopperId();\n\n const fetchCart = useCallback(async () => {\n if (!shopperId) return;\n setLoading(true);\n try {\n const res = await client.api.getCart();\n setCart(res);\n } catch (e) {\n console.error('[Huskel] Failed to fetch cart', e);\n } finally {\n setLoading(false);\n }\n }, [client, shopperId]);\n\n useEffect(() => {\n fetchCart();\n \n const handleCartUpdate = (e: any) => {\n if (e.detail) {\n setCart(e.detail);\n } else {\n fetchCart();\n }\n };\n if (typeof window !== 'undefined') {\n window.addEventListener('huskel:cart_updated', handleCartUpdate as EventListener);\n return () => window.removeEventListener('huskel:cart_updated', handleCartUpdate as EventListener);\n }\n }, [fetchCart, shopperId]);\n\n return { cart, loading, fetchCart };\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { useSearch } from '../hooks/useSearch';\nimport { SearchResult, HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\nimport { useHuskelContext } from './HuskelProvider';\n\nexport interface SearchBarProps {\n placeholder?: string;\n limit?: number;\n /** Debounce in ms — default 300 for smooth type-ahead */\n debounceMs?: number;\n onSelect?: (result: SearchResult) => void;\n className?: string;\n inputClassName?: string;\n dropdownClassName?: string;\n renderResult?: (result: SearchResult) => React.ReactNode;\n theme?: HuskelTheme;\n classNames?: {\n root?: string;\n input?: string;\n dropdown?: string;\n row?: string;\n };\n}\n\n/* SVG search glass — pure inline so no icon dependency */\nconst SearchIcon = () => (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/>\n <line x1=\"13\" y1=\"13\" x2=\"18\" y2=\"18\"/>\n </svg>\n);\n\nexport function SearchBar({\n placeholder = 'Search products…',\n limit = 10,\n debounceMs = 300,\n onSelect,\n className,\n inputClassName,\n dropdownClassName,\n renderResult,\n theme,\n classNames = {},\n}: SearchBarProps) {\n const [query, setQuery] = useState('');\n const [open, setOpen] = useState(false);\n const [isDebouncing, setIsDebouncing] = useState(false);\n const { results, loading, search, clear } = useSearch();\n const client = useHuskelContext();\n const timer = useRef<ReturnType<typeof setTimeout>>();\n const wrap = useRef<HTMLDivElement>(null);\n const ignoreNextQueryChange = useRef(false);\n\n /* Debounce search — but keep stale results visible between calls */\n useEffect(() => {\n if (ignoreNextQueryChange.current) {\n ignoreNextQueryChange.current = false;\n return;\n }\n clearTimeout(timer.current);\n if (!query.trim()) {\n clear();\n setOpen(false);\n setIsDebouncing(false);\n return;\n }\n setOpen(true); // open immediately (stale results show while fetching)\n setIsDebouncing(true);\n timer.current = setTimeout(() => {\n setIsDebouncing(false);\n search(query, limit);\n }, debounceMs);\n return () => clearTimeout(timer.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [query]);\n\n /* Click-outside to close */\n useEffect(() => {\n const h = (e: MouseEvent) => {\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', h);\n return () => document.removeEventListener('mousedown', h);\n }, []);\n\n const handleSelect = (r: SearchResult) => {\n if (query.trim()) {\n client.api.searchVector(query, 1).catch(() => {});\n }\n ignoreNextQueryChange.current = true;\n setOpen(false);\n setQuery(r.product.name);\n onSelect?.(r);\n };\n\n const handleCommitSearch = () => {\n if (!query.trim()) return;\n client.api.searchVector(query, 1).catch(() => {});\n if (results.length > 0) {\n handleSelect(results[0]);\n }\n };\n\n const showDrop = open && query.trim().length > 0;\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div className={cn(\"hsk-sb-wrap\", classNames.root, className)} ref={wrap} style={customStyles}>\n <span className=\"hsk-sb-icon\"><SearchIcon /></span>\n <input\n className={cn(\"hsk-sb-input\", classNames.input, inputClassName)}\n type=\"text\"\n value={query}\n placeholder={placeholder}\n onChange={e => setQuery(e.target.value)}\n onFocus={() => results.length > 0 && query.trim() && setOpen(true)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleCommitSearch();\n }\n }}\n autoComplete=\"off\"\n spellCheck={false}\n />\n {showDrop && (\n <div className={cn(\"hsk-sb-drop\", classNames.dropdown, dropdownClassName)} style={{ position: 'absolute' }}>\n {(loading || isDebouncing) && <div className=\"hsk-sb-loading-bar\" />}\n\n {(loading || isDebouncing) && results.length === 0 ? (\n <>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" />\n <div className=\"hsk-sb-skeleton-text2\" />\n </div>\n </div>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" style={{ width: '45%' }} />\n <div className=\"hsk-sb-skeleton-text2\" style={{ width: '25%' }} />\n </div>\n </div>\n </>\n ) : (\n <>\n {results.length === 0 && !loading && !isDebouncing && (\n <div className=\"hsk-sb-empty\">No results for “{query}”</div>\n )}\n\n {results.map((r, i) => (\n renderResult ? (\n <div\n key={r.id}\n onClick={() => handleSelect(r)}\n className=\"hsk-sb-fade\"\n style={{ animationDelay: `${i * 18}ms` }}\n >\n {renderResult(r)}\n </div>\n ) : (\n <div\n key={r.id}\n className={cn(\"hsk-sb-row hsk-sb-fade\", classNames.row)}\n style={{ animationDelay: `${i * 18}ms` }}\n onClick={() => handleSelect(r)}\n >\n <span className=\"hsk-sb-row-icon\"><SearchIcon /></span>\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-row-title\">{r.product.name}</div>\n {(r.product.category || r.product.brand) && (\n <div className=\"hsk-sb-row-sub\">\n {r.product.category ?? r.product.brand}\n </div>\n )}\n </div>\n </div>\n )\n ))}\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merges Tailwind classes intelligently, allowing overrides.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSearch } from '../hooks/useSearch';\nimport { useChat } from '../hooks/useChat';\nimport { useHuskelContext } from './HuskelProvider';\nimport { renderMarkdown } from '../utils/markdown';\nimport { SearchResult, Product, HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\n\nexport interface SparkleProps {\n productName: string;\n limit?: number;\n onResult?: (results: SearchResult[]) => void;\n /** Override the backdrop colour (any CSS colour/gradient) */\n backdropColor?: string;\n /** Override backdrop blur — e.g. \"8px\" or 8 */\n backdropBlur?: string | number;\n /** Extra classes on the trigger button */\n className?: string;\n /** Called when user clicks a result — return false to prevent default navigation */\n onNavigate?: (result: SearchResult) => boolean | void;\n theme?: HuskelTheme;\n classNames?: {\n button?: string;\n backdrop?: string;\n card?: string;\n item?: string;\n };\n product?: Product;\n}\n\nconst SparkleIcon = ({ className }: { className?: string }) => (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z\"/>\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\n/* ── Modal ────────────────────────────────────────────────────────────────── */\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\n onClose: () => void;\n}\n\nconst getFriendlyError = (err: any) => {\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n if (str.toLowerCase().includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n try {\n const parsed = JSON.parse(str);\n return parsed.error || parsed.message || str;\n } catch {\n return str;\n }\n};\n\nfunction SparkleModal({ \n productName, \n limit, \n backdropColor, \n backdropBlur, \n onClose, \n onNavigate, \n onResult,\n theme,\n classNames = {},\n product: initialProduct,\n}: ModalProps) {\n const client = useHuskelContext();\n const [fetchedProduct, setFetchedProduct] = useState<Product | null>(null);\n const displayProduct = initialProduct || fetchedProduct;\n const { results, loading: searchLoading, search } = useSearch();\n const { messages, sources, loading: chatLoading, error: chatError, send } = useChat();\n const [chatInput, setChatInput] = useState('');\n const chatBottomRef = useRef<HTMLDivElement>(null);\n const chatTextareaRef = useRef<HTMLTextAreaElement>(null);\n\n /* auto-search and product fetching on open */\n useEffect(() => {\n if (!initialProduct && !fetchedProduct) {\n client.api.searchVector(productName, 1)\n .then(res => {\n if (res.results && res.results.length > 0) {\n setFetchedProduct(res.results[0].product);\n }\n })\n .catch(err => console.error('[Huskel] Failed to fetch product details', err));\n }\n search(productName, limit);\n }, [productName, initialProduct, fetchedProduct, client, limit, search]);\n\n /* fire callback */\n useEffect(() => { if (results.length > 0) onResult?.(results); }, [results, onResult]);\n\n /* Escape key */\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, [onClose]);\n\n /* Scroll chat to bottom */\n useEffect(() => {\n chatBottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages, chatLoading]);\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '16px');\n const bg = backdropColor ?? undefined;\n\n const handleNav = (r: SearchResult) => {\n const prevent = onNavigate?.(r);\n if (prevent !== false) {\n onClose();\n if (r.product.url) window.location.href = r.product.url;\n }\n };\n\n const handleSend = async (text?: string) => {\n const q = (text ?? chatInput).trim();\n if (!q || chatLoading) return;\n setChatInput('');\n if (chatTextareaRef.current) {\n chatTextareaRef.current.style.height = 'auto';\n }\n\n if (messages.length === 0 && displayProduct) {\n const contextQuery = `[Context: Shopper is viewing \"${displayProduct.name}\". Price: ${displayProduct.price}. Description: ${displayProduct.description || ''}]\\n\\nQuestion: ${q}`;\n await send(contextQuery, q);\n } else {\n await send(q);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setChatInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\n };\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n const displayMessages = messages.length === 0 && displayProduct\n ? [\n {\n role: 'assistant' as const,\n content: `Hi! I can help you with **${displayProduct.name}**. Ask me about its specifications, features, compare it with other options, or find alternatives!`,\n },\n ]\n : messages;\n\n return (\n <div\n className={cn(\"hsk-sp-backdrop\", classNames.backdrop)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n background: bg ?? undefined,\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen\", classNames.card)} onClick={e => e.stopPropagation()}>\n <div className=\"hsk-sp-header\">\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div className=\"hsk-sp-header-body\">\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\n <div className=\"hsk-sp-header-sub\">Ask questions, compare specs, or check similar products</div>\n </div>\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n\n {searchLoading && <div className=\"hsk-sp-bar\" />}\n\n {/* Split pane body */}\n <div className=\"hsk-sp-body\">\n {/* Left Pane: Product Profile */}\n <div className=\"hsk-sp-details-pane\">\n {displayProduct && (\n <div className=\"hsk-sp-product-profile-container\">\n <div className=\"hsk-sp-product-profile\">\n <div className=\"hsk-sp-details-imgwrap\">\n {displayProduct.images?.[0] ? (\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">🛍</span>\n )}\n </div>\n <div className=\"hsk-sp-details-meta\">\n {displayProduct.brand && <span className=\"hsk-sp-item-brand\">{displayProduct.brand}</span>}\n {displayProduct.category && <span className=\"hsk-sp-item-cat\">{displayProduct.category}</span>}\n <h2 className=\"hsk-sp-details-name\">{displayProduct.name}</h2>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{displayProduct.currency ?? 'KES'}</span>\n <span className=\"hsk-sp-item-price\">{parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}</span>\n {displayProduct.originalPrice && (\n <span className=\"hsk-sp-item-original-price\">\n {parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </span>\n )}\n {displayProduct.discount && (\n <span className=\"hsk-sp-item-discount\">({displayProduct.discount})</span>\n )}\n </div>\n \n <div className=\"hsk-sp-item-meta-badges\">\n {displayProduct.rating && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-rating\">\n ★ {parseFloat(displayProduct.rating.toString()).toFixed(1)} {displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ''}\n </span>\n )}\n {displayProduct.availability && (\n <span className={`hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes('in') ? 'in-stock' : 'out-stock'}`}>\n {displayProduct.availability}\n </span>\n )}\n {displayProduct.stock && !displayProduct.availability && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-stock\">\n Stock: {displayProduct.stock}\n </span>\n )}\n </div>\n </div>\n </div>\n\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\n <div className=\"hsk-sp-specs-horizontal\">\n {Object.entries(displayProduct.specs).map(([key, val]) => (\n <div key={key} className=\"hsk-sp-spec-item-horizontal\">\n <span className=\"hsk-sp-spec-label-horizontal\">{key}:</span>\n <span className=\"hsk-sp-spec-value-horizontal\" title={val}>{val}</span>\n </div>\n ))}\n </div>\n )}\n\n {displayProduct.description && (\n <div className=\"hsk-sp-details-desc\">\n <h4>Description</h4>\n <p>{displayProduct.description}</p>\n </div>\n )}\n </div>\n )}\n\n {/* Similar Products */}\n <div className=\"hsk-sp-similar-section\">\n <h3>Similar Products</h3>\n <div className=\"hsk-sp-results\">\n {(() => {\n const similarProducts = results.filter(\n r => {\n const isSameName = r.product.name.toLowerCase() === displayProduct?.name?.toLowerCase();\n const isSameSlug = r.product.slug && displayProduct?.slug && r.product.slug.toLowerCase() === displayProduct.slug.toLowerCase();\n return !isSameName && !isSameSlug;\n }\n );\n\n if (!searchLoading && similarProducts.length === 0) {\n return <div className=\"hsk-sp-empty\">No similar products found.</div>;\n }\n\n return similarProducts.map((r, i) => {\n const price = parseFloat(r.product.price?.replace(/[^0-9.]/g, '') || '0');\n const currency = r.product.currency ?? 'KES';\n return (\n <div\n key={r.id}\n className={cn(\"hsk-sp-item\", classNames.item)}\n style={{ animationDelay: `${i * 55}ms` }}\n >\n <div className=\"hsk-sp-img-wrap\">\n {r.product.images?.[0] ? (\n <img src={r.product.images[0]} alt={r.product.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">🛍</span>\n )}\n </div>\n <div className=\"hsk-sp-item-body\">\n <div>\n {r.product.category && (\n <div className=\"hsk-sp-item-cat\">{r.product.category}</div>\n )}\n <div className=\"hsk-sp-item-name\" title={r.product.name}>{r.product.name}</div>\n </div>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{currency}</span>\n <span className=\"hsk-sp-item-price\">{price.toLocaleString()}</span>\n </div>\n <div className=\"hsk-sp-actions\">\n <button\n className=\"hsk-sp-action hsk-sp-action-primary\"\n onClick={() => handleNav(r)}\n >\n View\n </button>\n </div>\n </div>\n </div>\n );\n });\n })()}\n </div>\n </div>\n </div>\n\n {/* Right Pane: AI Chat Assistant */}\n <div className=\"hsk-sp-chat-pane\">\n <div className=\"hsk-cb-msgs\">\n {displayMessages.map((msg, idx) => {\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {chatLoading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\n <div ref={chatBottomRef} style={{ height: 1 }} />\n </div>\n\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={chatTextareaRef}\n className=\"hsk-cb-textarea\"\n value={chatInput}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this product, specs, or comparison...\"\n rows={1}\n disabled={chatLoading}\n />\n <button\n className=\"hsk-cb-send\"\n onClick={() => handleSend()}\n disabled={!chatInput.trim() || chatLoading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Huskel AI · instant product knowledge</div>\n </div>\n </div>\n </div>\n\n <div className=\"hsk-sp-footer\">\n <span className=\"hsk-sp-esc\">Esc to close</span>\n </div>\n </div>\n </div>\n );\n}\n\n/* ── Exported component ───────────────────────────────────────────────────── */\nexport function Sparkle({ \n productName, \n limit = 8, \n onResult, \n backdropColor, \n backdropBlur, \n className, \n onNavigate,\n theme,\n classNames = {},\n product,\n}: SparkleProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => { setMounted(true); }, []);\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <>\n <button\n className={cn(\"hsk-sp-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n title=\"Find similar products\"\n aria-label=\"Find similar products\"\n >\n <SparkleIcon />\n </button>\n {open && mounted && createPortal(\n <SparkleModal\n productName={productName}\n limit={limit}\n onResult={onResult}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onNavigate={onNavigate}\n theme={theme}\n classNames={classNames}\n product={product}\n />,\n document.body\n )}\n </>\n );\n}\n","import React from 'react';\n\n// Helper to parse inline styles (bold, links, and inline code) safely into React nodes\nconst parseInline = (text: string, keyPrefix: string): React.ReactNode => {\n // Regex to match markdown links, bold text, and inline code\n const tokenRegex = /(\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+\\*\\*|`[^`]+`)/g;\n const parts = text.split(tokenRegex);\n\n return parts.map((part, index) => {\n if (!part) return null;\n const key = `${keyPrefix}-inline-${index}`;\n\n // Handle Inline Code\n if (part.startsWith('`') && part.endsWith('`')) {\n return (\n <code key={key} className=\"hsk-markdown-code\">\n {part.slice(1, -1)}\n </code>\n );\n }\n\n // Handle Bold\n if (part.startsWith('**') && part.endsWith('**')) {\n return <strong key={key}>{parseInline(part.slice(2, -2), key)}</strong>;\n }\n\n // Handle Links\n const linkMatch = part.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (linkMatch) {\n // Basic sanitization: ensure the URL doesn't contain javascript:\n const url = linkMatch[2];\n const isSafeUrl = /^(https?|mailto|tel):/i.test(url) || url.startsWith('/');\n if (isSafeUrl) {\n return (\n <a key={key} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"hsk-markdown-link\">\n {parseInline(linkMatch[1], key)}\n </a>\n );\n }\n return <span key={key}>{parseInline(linkMatch[1], key)}</span>; // Fallback to plain text if unsafe\n }\n\n // Return standard text\n return part;\n });\n};\n\nexport function renderMarkdown(content: string): React.ReactNode {\n const lines = content.split('\\n');\n const elements: React.ReactNode[] = [];\n \n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n const key = `md-line-${i}`;\n\n // 1. Empty lines (spacing)\n if (!line.trim()) {\n i++;\n continue;\n }\n\n // 2. Headers\n const headerMatch = line.match(/^(#{1,3})\\s+(.*)/);\n if (headerMatch) {\n const level = headerMatch[1].length;\n const Tag = `h${level + 3}` as keyof JSX.IntrinsicElements; // Maps # to h4, ## to h5 to avoid messing up host page hierarchy\n elements.push(<Tag key={key} className={`hsk-markdown-h${level}`}>{parseInline(headerMatch[2], key)}</Tag>);\n i++;\n continue;\n }\n\n // 3. Unordered Lists\n if (line.match(/^[-*]\\s+/)) {\n const listItems: React.ReactNode[] = [];\n while (i < lines.length && lines[i].match(/^[-*]\\s+/)) {\n const itemText = lines[i].replace(/^[-*]\\s+/, '');\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\n i++;\n }\n elements.push(<ul key={`ul-${key}`} className=\"hsk-markdown-list\">{listItems}</ul>);\n continue;\n }\n\n // 4. Tables\n if (line.trim().startsWith('|')) {\n const tableRows: React.ReactNode[] = [];\n let isHeader = true;\n\n while (i < lines.length && lines[i].trim().startsWith('|')) {\n const rowLine = lines[i].trim();\n // Skip markdown table separator (e.g., |---|---|)\n if (rowLine.match(/^\\|[-:| ]+\\|$/)) {\n i++;\n isHeader = false;\n continue;\n }\n\n // Slice to remove outer pipes and map trim to handle empty cells properly\n const cells = rowLine.split('|').slice(1, -1).map(c => c.trim());\n const Tag = isHeader ? 'th' : 'td';\n \n tableRows.push(\n <tr key={`tr-${i}`}>\n {cells.map((cell, cIdx) => (\n <Tag key={`td-${i}-${cIdx}`}>{parseInline(cell, `td-${i}-${cIdx}`)}</Tag>\n ))}\n </tr>\n );\n i++;\n }\n \n elements.push(\n <div key={`table-wrapper-${key}`} className=\"hsk-table-wrapper\">\n <table className=\"hsk-markdown-table\">\n <tbody>{tableRows}</tbody>\n </table>\n </div>\n );\n continue;\n }\n\n // 5. Default Paragraph\n elements.push(\n <p key={key} className=\"hsk-markdown-p\">\n {parseInline(line, key)}\n </p>\n );\n i++;\n }\n\n return <>{elements}</>;\n}\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useChat, ChatMessage, ChatSource } from '../hooks/useChat';\nimport { renderMarkdown } from '../utils/markdown';\nimport { HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\n\n\n\n// Better Prop Interface for SDKs\nexport interface ChatWidgetProps {\n title?: string;\n placeholder?: string;\n emptyStateText?: string;\n emptyStateSuggestions?: string;\n defaultCurrency?: string;\n className?: string;\n \n // Allow overriding styles via standard CSS variables\n theme?: HuskelTheme;\n \n // Allow targeting specific elements with custom classes (e.g. Tailwind)\n classNames?: {\n root?: string;\n header?: string;\n messageBubble?: string;\n input?: string;\n };\n \n onSelectSource?: (source: ChatSource) => void;\n}\n\n// Simple SVG Icons instead of text characters\nconst SparkleIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z\"/>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\nfunction SourceCard({ source, defaultCurrency, onSelect }: { source: ChatSource; defaultCurrency: string; onSelect?: (s: ChatSource) => void }) {\n return (\n <div className=\"hsk-source-card\" onClick={() => onSelect?.(source)}>\n {source.image && <img src={source.image} alt={source.name} className=\"hsk-source-img\" />}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div className=\"hsk-source-name\">{source.name}</div>\n {source.price && (\n <div className=\"hsk-source-price\">{source.currency ?? defaultCurrency} {source.price}</div>\n )}\n </div>\n </div>\n );\n}\n\nexport function ChatWidget({ \n title = 'AI Shopping Assistant',\n placeholder = 'Ask about anything in our store…', \n emptyStateText = 'Ask me anything about our products',\n emptyStateSuggestions = '\"Find me headphones under KSh 5,000\" · \"Gift ideas\"',\n defaultCurrency = 'KES',\n className,\n theme,\n classNames = {},\n onSelectSource \n}: ChatWidgetProps) {\n const { messages, sources, loading, error, send, reset } = useChat();\n const [input, setInput] = useState('');\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages, loading]);\n\n const handleSend = async () => {\n const q = input.trim();\n if (!q || loading) return;\n setInput('');\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n await send(q);\n };\n\n const handleKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = Math.min(t.scrollHeight, 120) + 'px';\n };\n\n // Apply custom CSS variables inline to the root wrapper\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div \n className={cn(\"hsk-chat-widget\", classNames.root, className)} \n style={customStyles}\n >\n <div className={cn(\"hsk-chat-header\", classNames.header)}>\n <span className=\"hsk-chat-header-icon\"><SparkleIcon /></span>\n <span className=\"hsk-chat-title\">{title}</span>\n <span className=\"hsk-chat-badge\">AI</span>\n {messages.length > 0 && (\n <button className=\"hsk-chat-reset\" onClick={reset} style={{ marginLeft: 'auto' }}>Clear</button>\n )}\n </div>\n\n <div className=\"hsk-chat-messages\">\n {messages.length === 0 ? (\n <div className=\"hsk-chat-empty\">\n <div className=\"hsk-chat-empty-icon\"><SparkleIcon /></div>\n <div>{emptyStateText}</div>\n <div className=\"hsk-chat-empty-suggestions\">{emptyStateSuggestions}</div>\n </div>\n ) : (\n messages.map((msg, idx) => (\n <div key={idx}>\n <div className={`hsk-msg-row ${msg.role}`}>\n <div className={cn(\"hsk-msg-avatar\", msg.role === 'assistant' ? 'ai' : 'user')}>\n {msg.role === 'assistant' ? <SparkleIcon /> : 'U'}\n </div>\n <div className={cn(\"hsk-msg-bubble\", msg.role, classNames.messageBubble)}>\n {renderMarkdown(msg.content)}\n </div>\n </div>\n {msg.role === 'assistant' && idx === messages.length - 1 && sources.length > 0 && (\n <div className=\"hsk-sources-container\">\n <div className=\"hsk-sources\">\n {sources.map((src, si) => (\n <SourceCard key={si} source={src} defaultCurrency={defaultCurrency} onSelect={onSelectSource} />\n ))}\n </div>\n </div>\n )}\n </div>\n ))\n )}\n\n {loading && (\n <div className=\"hsk-msg-row\">\n <div className=\"hsk-msg-avatar ai\"><SparkleIcon /></div>\n <div className=\"hsk-typing\">\n <div className=\"hsk-typing-dot\" /><div className=\"hsk-typing-dot\" /><div className=\"hsk-typing-dot\" />\n </div>\n </div>\n )}\n\n {error && (\n <div className=\"hsk-chat-error\">\n {(() => {\n try {\n const parsed = JSON.parse(error);\n return parsed.error || parsed.message || error;\n } catch {\n return error;\n }\n })()}\n </div>\n )}\n <div ref={bottomRef} />\n </div>\n\n <div className=\"hsk-chat-input-area\">\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-chat-input\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKey}\n placeholder={placeholder}\n rows={1}\n disabled={loading}\n />\n <button\n className=\"hsk-chat-send\"\n onClick={handleSend}\n disabled={!input.trim() || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n </div>\n );\n}\n\n","'use client';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useChat, ChatMessage, ChatSource } from '../hooks/useChat';\nimport { renderMarkdown } from '../utils/markdown';\nimport { HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\n\n\nexport interface AIChatButtonProps {\n label?: string;\n title?: string;\n placeholder?: string;\n backdropColor?: string;\n backdropBlur?: string | number;\n className?: string;\n onSelectSource?: (source: ChatSource) => void;\n defaultCurrency?: string;\n chips?: string[];\n theme?: HuskelTheme;\n classNames?: {\n button?: string;\n overlay?: string;\n panel?: string;\n input?: string;\n sendButton?: string;\n };\n}\n\nconst SparkleIcon = ({ className }: { className?: string }) => (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z\"/>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nconst ChevronRightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\"/>\n </svg>\n);\n\nconst DEFAULT_CHIPS = [\n 'Cheapest smartphone',\n 'Smart TV under KSh 20,000',\n 'Noise-cancelling headphones',\n 'Best laptop for students',\n];\n\ninterface SourcesCarouselProps {\n sources: ChatSource[];\n defaultCurrency: string;\n onSelectSource?: (src: ChatSource) => void;\n}\n\nfunction SourcesCarousel({ sources, defaultCurrency, onSelectSource }: SourcesCarouselProps) {\n const railRef = useRef<HTMLDivElement>(null);\n const [showNext, setShowNext] = useState(false);\n\n const measure = useCallback(() => {\n const el = railRef.current;\n if (!el) return;\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;\n setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);\n }, []);\n\n useEffect(() => {\n measure();\n const el = railRef.current;\n if (!el) return;\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n el.addEventListener('scroll', measure, { passive: true });\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\n }, [measure, sources]);\n\n const scrollNext = () => {\n railRef.current?.scrollBy({ left: 170, behavior: 'smooth' });\n };\n\n return (\n <div className=\"hsk-cb-sources-wrap\">\n <div className=\"hsk-cb-sources\" ref={railRef}>\n {sources.map((src, si) => (\n <div\n key={si}\n className=\"hsk-cb-source\"\n style={{ animationDelay: `${si * 50}ms` }}\n onClick={() => onSelectSource?.(src)}\n >\n {src.image ? (\n <div className=\"hsk-cb-src-imgwrap\">\n <img src={src.image} alt={src.name} loading=\"lazy\" />\n </div>\n ) : (\n <div className=\"hsk-cb-src-imgwrap-empty\">\n <SparkleIcon />\n </div>\n )}\n <div className=\"hsk-cb-src-info\">\n <div className=\"hsk-cb-src-name\">{src.name}</div>\n {src.price && (\n <div className=\"hsk-cb-src-price\">\n {src.currency ?? defaultCurrency}{' '}\n {parseFloat(src.price.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n {showNext && (\n <>\n <div\n className=\"hsk-cb-sources-fade\"\n style={{ background: 'linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))' }}\n />\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\n <ChevronRightIcon />\n </button>\n </>\n )}\n </div>\n );\n}\n\ninterface ChatModalProps extends Pick<AIChatButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames'> {\n onClose: () => void;\n}\n\nconst getFriendlyError = (err: any) => {\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n if (str.toLowerCase().includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n try {\n const parsed = JSON.parse(str);\n return parsed.error || parsed.message || str;\n } catch {\n return str;\n }\n};\n\nfunction ChatModal({\n title = 'Shopping Assistant',\n placeholder = 'Ask me anything — gifts, budget, use case…',\n backdropColor,\n backdropBlur,\n onClose,\n onSelectSource,\n defaultCurrency = 'KES',\n chips = DEFAULT_CHIPS,\n theme,\n classNames = {},\n}: ChatModalProps) {\n const { messages, sources, loading, error, send, reset } = useChat();\n const [input, setInput] = useState('');\n const [selectedProduct, setSelectedProduct] = useState<ChatSource | null>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages, loading, selectedProduct]);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, []);\n\n const handleSourceClick = (src: ChatSource) => {\n setSelectedProduct(src);\n onSelectSource?.(src);\n const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ''} — what are its key specs, who is it best for, and is it worth buying?`;\n send(q);\n };\n\n const handleSend = async (text?: string) => {\n const q = (text ?? input).trim();\n if (!q || loading) return;\n setSelectedProduct(null);\n setInput('');\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n await send(q);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\n };\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '20px');\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div\n className={cn(\"hsk-cb-overlay\", classNames.overlay)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n ...(backdropColor ? { background: backdropColor } : {}),\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-cb-panel\", classNames.panel)} onClick={e => e.stopPropagation()}>\n\n {/* Top bar */}\n <div className=\"hsk-cb-topbar\">\n <div className=\"hsk-cb-topbar-left\">\n <span className=\"hsk-cb-topbar-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div>\n <div className=\"hsk-cb-topbar-title\">{title}</div>\n </div>\n </div>\n <div className=\"hsk-cb-topbar-actions\">\n {messages.length > 0 && (\n <button className=\"hsk-cb-topbar-btn\" onClick={reset}>Clear chat</button>\n )}\n <button className=\"hsk-cb-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"hsk-cb-msgs\">\n {messages.length === 0 ? (\n <div className=\"hsk-cb-empty\">\n <div className=\"hsk-cb-empty-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-empty-title\">Find exactly what you need</div>\n <div className=\"hsk-cb-chips\">\n {chips.map(chip => (\n <button\n key={chip}\n className=\"hsk-cb-chip\"\n onClick={() => handleSend(chip)}\n >\n {chip}\n </button>\n ))}\n </div>\n </div>\n ) : (\n messages.map((msg: ChatMessage, idx: number) => {\n const isLast = idx === messages.length - 1;\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n\n {/* Sources as horizontal carousel — only after latest assistant reply */}\n {isLast && sources.length > 0 && (\n <SourcesCarousel\n sources={sources}\n defaultCurrency={defaultCurrency}\n onSelectSource={handleSourceClick}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n })\n )}\n\n {/* Selected product pinned card — shows while LLM fetches details */}\n {selectedProduct && loading && (\n <div\n className=\"hsk-cb-selected-product\"\n onClick={() => selectedProduct.url && window.open(selectedProduct.url, '_blank')}\n >\n {selectedProduct.image && (\n <img className=\"hsk-cb-selected-img\" src={selectedProduct.image} alt={selectedProduct.name} />\n )}\n <div className=\"hsk-cb-selected-info\">\n <div className=\"hsk-cb-selected-name\">{selectedProduct.name}</div>\n {selectedProduct.price && (\n <div className=\"hsk-cb-selected-price\">\n {selectedProduct.currency ?? defaultCurrency} {parseFloat((selectedProduct.price ?? '').replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Typing dots */}\n {loading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {error && <div className=\"hsk-cb-error\">{error}</div>}\n <div ref={bottomRef} style={{ height: 1 }} />\n </div>\n\n {/* Input */}\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-cb-textarea\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n rows={1}\n disabled={loading}\n autoFocus\n />\n <button\n className={cn(\"hsk-cb-send\", classNames.sendButton)}\n onClick={() => handleSend()}\n disabled={!input.trim() || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Huskel AI · searches the whole catalogue in real time</div>\n </div>\n\n </div>\n </div>\n );\n}\n\nexport function AIChatButton({\n label,\n title,\n placeholder,\n backdropColor,\n backdropBlur,\n className,\n onSelectSource,\n defaultCurrency,\n chips,\n theme,\n classNames = {},\n}: AIChatButtonProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => { setMounted(true); }, []);\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <>\n <button\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n aria-label=\"Open AI chat\"\n >\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n {label !== undefined ? label : null}\n </button>\n {open && mounted && createPortal(\n <ChatModal\n title={title}\n placeholder={placeholder}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onSelectSource={onSelectSource}\n defaultCurrency={defaultCurrency}\n chips={chips}\n theme={theme}\n classNames={classNames}\n />,\n document.body\n )}\n </>\n );\n}\n","import React from 'react';\nimport { useCart } from '../hooks/useCart';\nimport { cn } from '../utils/cn';\n\nexport function CartBadge({ className }: { className?: string }) {\n const { cart } = useCart();\n \n if (!cart || cart.item_count === 0) return null;\n \n return (\n <span className={cn(\"hsk-cart-badge\", className)}>\n {cart.item_count}\n </span>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useCart } from '../hooks/useCart';\nimport { useHuskelContext } from './HuskelProvider';\nimport { HuskelTheme } from '../types';\nimport { CheckoutModal } from './CheckoutModal';\nimport { cn } from '../utils/cn';\n\nexport function CartDrawer({ \n trigger, \n className,\n theme \n}: { \n trigger?: React.ReactNode, \n className?: string,\n theme?: 'light' | 'dark' | HuskelTheme \n}) {\n const { cart, loading } = useCart();\n const [open, setOpen] = useState(false);\n const [showCheckout, setShowCheckout] = useState(false);\n const [mounted, setMounted] = useState(false);\n const client = useHuskelContext();\n\n useEffect(() => {\n setMounted(true);\n const handleTriggerCheckout = () => {\n setShowCheckout(true);\n setOpen(false);\n };\n window.addEventListener('huskel:trigger_checkout', handleTriggerCheckout);\n return () => {\n window.removeEventListener('huskel:trigger_checkout', handleTriggerCheckout);\n };\n }, []);\n\n // Block body scroll when drawer is open\n useEffect(() => {\n if (open) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => { document.body.style.overflow = ''; };\n }, [open]);\n\n const handleCheckout = async () => {\n if (!cart || cart.items.length === 0) return;\n setShowCheckout(true);\n };\n\n const isStringTheme = typeof theme === 'string';\n const hskThemeAttr = isStringTheme ? theme : undefined;\n \n const customStyles = (!isStringTheme && theme) ? {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor, '--hsk-primary-color': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties : undefined;\n\n return (\n <>\n <div onClick={() => setOpen(true)} style={{ display: 'inline-block' }}>\n {trigger || (\n <button \n className={cn(\"hsk-cart-trigger\", className)} \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n aria-label=\"Open cart\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"9\" cy=\"21\" r=\"1\"></circle>\n <circle cx=\"20\" cy=\"21\" r=\"1\"></circle>\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"></path>\n </svg>\n {cart && cart.item_count > 0 ? (\n <span className=\"hsk-cart-trigger-badge\">{cart.item_count}</span>\n ) : null}\n </button>\n )}\n </div>\n \n {open && mounted && createPortal(\n <div \n className=\"hsk-cart-backdrop\" \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n onClick={() => setOpen(false)}\n >\n <div \n className=\"hsk-cart-bottom-sheet\" \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"hsk-cart-sheet-handle\" />\n \n <div className=\"hsk-cart-sheet-header\">\n <h2>Your Cart</h2>\n <button onClick={() => setOpen(false)} className=\"hsk-close-btn\">×</button>\n </div>\n \n <div className=\"hsk-cart-sheet-content\">\n {loading && !cart ? (\n <div className=\"hsk-cart-loading\">Loading cart...</div>\n ) : !cart || cart.items.length === 0 ? (\n <div className=\"hsk-cart-empty\">Your cart is empty.</div>\n ) : (\n <ul className=\"hsk-cart-items\">\n {cart.items.map(item => (\n <li key={item.id} className=\"hsk-cart-item\">\n {item.image && <img src={item.image} alt={item.name} className=\"hsk-cart-item-img\" />}\n <div className=\"hsk-cart-item-info\">\n <span className=\"hsk-cart-item-name\">{item.name}</span>\n <span className=\"hsk-cart-item-price\">{item.currency} {item.price_numeric.toLocaleString(undefined, { minimumFractionDigits: 2 })}</span>\n </div>\n <div className=\"hsk-cart-item-qty\">x{item.quantity}</div>\n </li>\n ))}\n </ul>\n )}\n </div>\n \n {cart && cart.items.length > 0 && (\n <div className=\"hsk-cart-sheet-footer\">\n <div className=\"hsk-cart-total\">\n <span>Total</span>\n <span>{cart.currency} {cart.total.toLocaleString(undefined, { minimumFractionDigits: 2 })}</span>\n </div>\n <button onClick={handleCheckout} className=\"hsk-checkout-btn\">\n Checkout securely\n </button>\n </div>\n )}\n </div>\n </div>,\n document.body\n )}\n\n {showCheckout && mounted && (\n <CheckoutModal \n onClose={() => {\n setShowCheckout(false);\n setOpen(false);\n }}\n theme={isStringTheme ? (theme as string) : undefined}\n customStyles={customStyles}\n hskThemeAttr={hskThemeAttr}\n />\n )}\n </>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useCart } from '../hooks/useCart';\nimport { useHuskelContext } from './HuskelProvider';\n\nexport function CheckoutModal({\n onClose,\n theme,\n customStyles,\n hskThemeAttr\n}: {\n onClose: () => void;\n theme?: string;\n customStyles?: React.CSSProperties;\n hskThemeAttr?: string;\n}) {\n const { cart, loading: cartLoading } = useCart();\n const client = useHuskelContext();\n const [config, setConfig] = useState<any>(null);\n const [loading, setLoading] = useState(true);\n const [checkingOut, setCheckingOut] = useState(false);\n const [paymentSuccess, setPaymentSuccess] = useState(false);\n\n useEffect(() => {\n client.api.getCheckoutConfig()\n .then(res => setConfig(res.payment_methods))\n .catch(e => console.error('[Huskel] Failed to fetch checkout config', e))\n .finally(() => setLoading(false));\n }, [client]);\n\n const handlePay = async (method: string) => {\n setCheckingOut(true);\n // Simulate processing payment\n setTimeout(async () => {\n try {\n const payload = await client.api.checkoutCart();\n if (client.onCheckout) {\n client.onCheckout(payload);\n }\n setPaymentSuccess(true);\n setTimeout(() => {\n onClose();\n }, 3000);\n } catch (e) {\n console.error('[Huskel] Checkout failed', e);\n setCheckingOut(false);\n }\n }, 1500);\n };\n\n const hasPaymentMethods = config && Object.values(config).some((m: any) => m.enabled);\n\n return createPortal(\n <div \n className=\"hsk-cart-backdrop\" \n style={{...customStyles, zIndex: 999999}}\n data-hsk-theme={hskThemeAttr}\n onClick={onClose}\n >\n <div \n className=\"hsk-checkout-modal\" \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"hsk-checkout-header\">\n <h2>Secure Checkout</h2>\n <button onClick={onClose} className=\"hsk-close-btn\">×</button>\n </div>\n \n <div className=\"hsk-checkout-content\">\n {paymentSuccess ? (\n <div className=\"hsk-checkout-success\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"hsk-success-icon\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path>\n <polyline points=\"22 4 12 14.01 9 11.01\"></polyline>\n </svg>\n <h3>Payment Successful!</h3>\n <p>Thank you for your order.</p>\n </div>\n ) : (\n <div className=\"hsk-checkout-split\">\n <div className=\"hsk-checkout-summary\">\n <h3>Order Summary</h3>\n {cartLoading || !cart ? (\n <p className=\"hsk-cart-loading\">Loading order...</p>\n ) : (\n <>\n <ul className=\"hsk-checkout-items\">\n {cart.items.map(item => (\n <li key={item.id}>\n <span>{item.quantity}x {item.name}</span>\n <span>{item.currency} {(item.price_numeric * item.quantity).toLocaleString(undefined, { minimumFractionDigits: 2 })}</span>\n </li>\n ))}\n </ul>\n <div className=\"hsk-checkout-total\">\n <span>Total</span>\n <span>{cart.currency} {cart.total.toLocaleString(undefined, { minimumFractionDigits: 2 })}</span>\n </div>\n </>\n )}\n </div>\n <div className=\"hsk-checkout-payment\">\n <h3>Payment Method</h3>\n {loading ? (\n <p className=\"hsk-cart-loading\">Loading secure payment methods...</p>\n ) : !hasPaymentMethods ? (\n <p className=\"hsk-checkout-error\">No payment methods are currently available for this store.</p>\n ) : (\n <div className=\"hsk-payment-options\">\n {config?.mpesa?.enabled && (\n <button onClick={() => handlePay('mpesa')} disabled={checkingOut} className=\"hsk-pay-btn hsk-pay-mpesa\">\n {checkingOut ? 'Processing...' : 'Pay with M-Pesa'}\n </button>\n )}\n {config?.equity?.enabled && (\n <button onClick={() => handlePay('equity')} disabled={checkingOut} className=\"hsk-pay-btn hsk-pay-equity\">\n {checkingOut ? 'Processing...' : 'Pay with Equity Bank'}\n </button>\n )}\n {config?.stripe?.enabled && (\n <button onClick={() => handlePay('stripe')} disabled={checkingOut} className=\"hsk-pay-btn hsk-pay-stripe\">\n {checkingOut ? 'Processing...' : 'Pay with Card (Stripe)'}\n </button>\n )}\n {config?.paypal?.enabled && (\n <button onClick={() => handlePay('paypal')} disabled={checkingOut} className=\"hsk-pay-btn hsk-pay-paypal\">\n {checkingOut ? 'Processing...' : 'Pay with PayPal'}\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n </div>,\n document.body\n );\n}\n"],"mappings":"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","names":["useRef","useRef","useRef","useRef","e","useCallback","useState","useState","useCallback","useEffect","useRef","useRef","useEffect","useState","useCallback","useRef","useState","useRef","useCallback","e","useState","useEffect","useCallback","useState","useCallback","useEffect","useState","useEffect","useRef","jsx","useState","useRef","useEffect","useState","useEffect","useRef","Fragment","jsx","Fragment","jsx","jsxs","useState","useRef","useEffect","_a","_b","_c","useState","useRef","useEffect","jsx","jsxs","SparkleIcon","ArrowUpIcon","useState","useRef","useEffect","useState","useEffect","useRef","useCallback","createPortal","Fragment","jsx","jsxs","SparkleIcon","ArrowUpIcon","CloseIcon","useRef","useState","useCallback","useEffect","useState","useRef","useEffect","_a","jsx","jsxs","SparkleIcon","CloseIcon","ArrowUpIcon","Fragment","createPortal","jsx","useState","useEffect","createPortal","useState","useEffect","createPortal","Fragment","jsx","jsxs","useState","useEffect","createPortal","Fragment","jsx","jsxs","useState","useEffect","createPortal"]}
|
|
1
|
+
{"version":3,"sources":["../src/api.ts","../src/client.ts","../src/hooks/useHuskel.ts","../src/hooks/useSearch.ts","../src/components/HuskelProvider.tsx","../src/hooks/useIngest.ts","../src/hooks/usePageIngest.ts","../src/hooks/useChat.ts","../src/hooks/useCart.ts","../src/hooks/usePaymentPolling.ts","../src/components/SearchBar.tsx","../src/utils/cn.ts","../src/components/Sparkle.tsx","../src/utils/markdown.tsx","../src/components/ChatWidget.tsx","../src/components/AIChatButton.tsx","../src/components/CartBadge.tsx","../src/components/CartDrawer.tsx","../src/components/CheckoutModal.tsx"],"sourcesContent":["import { Product, SearchResponse, IngestResponse, HuskelError } from './types';\r\n\r\nconst MAX_RETRIES = 3;\r\nconst RETRY_DELAYS = [500, 1000, 2000]; // ms\r\n\r\nfunction log(level: 'info' | 'warn' | 'error', msg: string, data?: unknown) {\r\n const prefix = '[Huskel]';\r\n if (level === 'error') console.error(prefix, msg, data ?? '');\r\n else if (level === 'warn') console.warn(prefix, msg, data ?? '');\r\n else console.log(prefix, msg, data ?? '');\r\n}\r\n\r\nasync function sleep(ms: number) {\r\n return new Promise(r => setTimeout(r, ms));\r\n}\r\n\r\nexport class HuskelAPI {\r\n constructor(\r\n private apiUrl: string,\r\n private siteId: string,\r\n private apiToken: string,\r\n private getShopperId?: () => string | undefined,\r\n private getSessionId?: () => string | undefined\r\n ) {}\r\n\r\n private async post<T>(path: string, body: unknown, attempt = 0): Promise<T> {\r\n const url = `${this.apiUrl}${path}`;\r\n\r\n try {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'X-Huskel-Token': this.apiToken,\r\n 'X-Huskel-Site': this.siteId,\r\n };\r\n\r\n const shopperId = this.getShopperId?.();\r\n if (shopperId) {\r\n headers['X-Huskel-Shopper-Id'] = shopperId;\r\n }\r\n\r\n const sessionId = this.getSessionId?.();\r\n if (sessionId) {\r\n headers['X-Huskel-Session-Id'] = sessionId;\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n const phone = localStorage.getItem('huskel_user_phone');\r\n if (phone) {\r\n headers['X-Huskel-Shopper-Phone'] = phone;\r\n }\r\n }\r\n\r\n const res = await fetch(url, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!res.ok) {\r\n const text = await res.text();\r\n let message = text;\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed.error === 'string') {\r\n message = parsed.error;\r\n }\r\n } catch {\r\n // keep original text\r\n }\r\n const err: HuskelError = { status: res.status, message };\r\n\r\n // Don't retry 4xx — developer errors\r\n if (res.status >= 400 && res.status < 500) {\r\n log('error', `${path} failed [${res.status}]`, text);\r\n throw err;\r\n }\r\n\r\n // Retry 5xx\r\n if (attempt < MAX_RETRIES - 1) {\r\n log('warn', `${path} [${res.status}] retrying (${attempt + 1}/${MAX_RETRIES})...`);\r\n await sleep(RETRY_DELAYS[attempt]);\r\n return this.post(path, body, attempt + 1);\r\n }\r\n\r\n log('error', `${path} failed after ${MAX_RETRIES} attempts`, err);\r\n throw err;\r\n }\r\n\r\n return res.json();\r\n } catch (e) {\r\n // Network error (offline, DNS, etc.)\r\n if ((e as HuskelError).status === undefined) {\r\n if (attempt < MAX_RETRIES - 1) {\r\n log('warn', `${path} network error, retrying (${attempt + 1}/${MAX_RETRIES})...`);\r\n await sleep(RETRY_DELAYS[attempt]);\r\n return this.post(path, body, attempt + 1);\r\n }\r\n log('error', `${path} unreachable after ${MAX_RETRIES} attempts`);\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n async ingest(product: Product): Promise<IngestResponse> {\r\n log('info', 'ingesting product', product.name);\r\n return this.post('/ingest', { siteId: this.siteId, product });\r\n }\r\n\r\n async ingestBatch(products: Product[]): Promise<IngestResponse> {\r\n log('info', `ingesting batch of ${products.length} products`);\r\n return this.post('/ingest/batch', { siteId: this.siteId, products });\r\n }\r\n\r\n async search(query: string, limit = 10): Promise<SearchResponse> {\r\n log('info', 'search query', query);\r\n return this.post('/search', { query, siteId: this.siteId, limit });\r\n }\r\n\r\n // Pure vector search — no LLM, instant results. This is what the SearchBar uses.\r\n async searchVector(query: string, limit = 10): Promise<SearchResponse> {\r\n return this.post('/search/vector', { query, siteId: this.siteId, limit });\r\n }\r\n\r\n // Autocomplete — pure in-memory Trie, <1ms, no Upstash call. Only true prefix matches.\r\n async searchAutocomplete(query: string, limit = 8): Promise<SearchResponse> {\r\n return this.post('/search/autocomplete', { query, siteId: this.siteId, limit });\r\n }\r\n\r\n // LLM chat — conversational search with history context.\r\n async chat(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = []): Promise<{ answer: string; sources: any[]; checkout?: import('./types').CartPayload; action?: any }> {\r\n log('info', 'chat query', query);\r\n return this.post('/chat', { query, siteId: this.siteId, history });\r\n }\r\n\r\n // --- Cart System ---\r\n private buildHeaders(): Record<string, string> {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'X-Huskel-Token': this.apiToken,\r\n 'X-Huskel-Site': this.siteId,\r\n };\r\n const shopperId = this.getShopperId?.();\r\n if (shopperId) headers['X-Huskel-Shopper-Id'] = shopperId;\r\n const sessionId = this.getSessionId?.();\r\n if (sessionId) headers['X-Huskel-Session-Id'] = sessionId;\r\n if (typeof window !== 'undefined') {\r\n const phone = localStorage.getItem('huskel_user_phone');\r\n if (phone) {\r\n headers['X-Huskel-Shopper-Phone'] = phone;\r\n }\r\n }\r\n return headers;\r\n }\r\n\r\n async getCart(): Promise<import('./types').CartPayload> {\r\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to fetch cart');\r\n return res.json();\r\n }\r\n\r\n async clearCart(): Promise<import('./types').CartPayload> {\r\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\r\n method: 'DELETE',\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to clear cart');\r\n return res.json();\r\n }\r\n\r\n async checkoutCart(): Promise<import('./types').CartPayload> {\r\n const res = await fetch(`${this.apiUrl}/cart/checkout`, {\r\n method: 'POST',\r\n headers: this.buildHeaders(),\r\n body: JSON.stringify({ siteId: this.siteId })\r\n });\r\n if (!res.ok) throw new Error('Failed to checkout cart');\r\n return res.json();\r\n }\r\n\r\n async getCheckoutConfig(): Promise<any> {\r\n const res = await fetch(`${this.apiUrl}/checkout/config?site_id=${this.siteId}`, {\r\n method: 'GET',\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to fetch checkout config');\r\n return res.json();\r\n }\r\n\r\n async initiatePayment(phoneNumber: string, email?: string, firstName?: string, lastName?: string): Promise<any> {\r\n const res = await fetch(`${this.apiUrl}/payment/initiate`, {\r\n method: 'POST',\r\n headers: this.buildHeaders(),\r\n body: JSON.stringify({\r\n siteId: this.siteId,\r\n phoneNumber,\r\n email,\r\n firstName,\r\n lastName\r\n })\r\n });\r\n if (!res.ok) {\r\n const errText = await res.text();\r\n throw new Error('Failed to initiate payment: ' + errText);\r\n }\r\n return res.json();\r\n }\r\n\r\n async getPaymentStatus(ref: string): Promise<any> {\r\n const res = await fetch(`${this.apiUrl}/payment/status?ref=${ref}`, {\r\n method: 'GET',\r\n headers: this.buildHeaders()\r\n });\r\n if (!res.ok) throw new Error('Failed to get payment status');\r\n return res.json();\r\n }\r\n}\r\n","import { HuskelConfig, Product, RawProductInput } from './types';\r\nimport { HuskelAPI } from './api';\r\n\r\nfunction getEnvVar(key: string): string | undefined {\r\n if (typeof globalThis !== 'undefined') {\r\n const g = globalThis as any;\r\n if (g.process && g.process.env) {\r\n return g.process.env[key];\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction mapRawProduct(input: RawProductInput): Product | null {\r\n const name = input.name || input.title || input.productName || '';\r\n \r\n let price = '';\r\n let priceNumeric: number | undefined = undefined;\r\n\r\n if (input.price !== undefined) {\r\n if (typeof input.price === 'number') {\r\n priceNumeric = input.price;\r\n price = String(input.price);\r\n } else {\r\n price = input.price;\r\n const num = parseFloat(input.price.replace(/[^0-9.]/g, ''));\r\n priceNumeric = isNaN(num) ? undefined : num;\r\n }\r\n }\r\n if (input.priceNumeric !== undefined) {\r\n priceNumeric = input.priceNumeric;\r\n }\r\n\r\n let url = input.url || '';\r\n if (!url && typeof window !== 'undefined') {\r\n url = window.location.href;\r\n }\r\n\r\n let slug = input.slug || input.id || input.productId || '';\r\n if (!slug && url) {\r\n slug = url.split('/').filter(Boolean).pop() || '';\r\n }\r\n if (!slug && name) {\r\n slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');\r\n }\r\n\r\n let images: string[] = [];\r\n if (input.images) {\r\n images = input.images;\r\n } else if (input.image) {\r\n images = [input.image];\r\n } else if (input.thumbnail) {\r\n images = [input.thumbnail];\r\n }\r\n\r\n if (!name) {\r\n console.warn('[Huskel] Validation warning: Product name/title is missing. Skipping:', input);\r\n return null;\r\n }\r\n if (!price) {\r\n console.warn('[Huskel] Validation warning: Product price is missing. Skipping:', input);\r\n return null;\r\n }\r\n if (!url) {\r\n console.warn('[Huskel] Validation warning: Product URL is missing. Skipping:', input);\r\n return null;\r\n }\r\n\r\n return {\r\n name,\r\n price,\r\n url,\r\n brand: input.brand,\r\n description: input.description,\r\n originalPrice: input.originalPrice,\r\n discount: input.discount,\r\n currency: input.currency ?? 'KES',\r\n stock: input.stock,\r\n availability: input.availability,\r\n rating: input.rating,\r\n reviewCount: input.reviewCount,\r\n category: input.category,\r\n subCategory: input.subCategory,\r\n tags: input.tags,\r\n images: images.length > 0 ? images : undefined,\r\n specs: input.specs,\r\n priceNumeric,\r\n slug,\r\n };\r\n}\r\n\r\nfunction generateUUID(): string {\r\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\r\n return crypto.randomUUID();\r\n }\r\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\r\n const r = (Math.random() * 16) | 0;\r\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\r\n return v.toString(16);\r\n });\r\n}\r\n\r\nexport class HuskelClient {\r\n readonly api: HuskelAPI;\r\n private ingestQueue: Product[] = [];\r\n private ingestTimer: ReturnType<typeof setTimeout> | null = null;\r\n private ingestedUrls = new Set<string>();\r\n private onlineHandler: (() => void) | null = null;\r\n private shopperId?: string;\r\n private sessionId: string = '';\r\n public onCheckout?: (cart: import('./types').CartPayload) => void;\r\n\r\n private static INGEST_CACHE_KEY = 'huskel_ingested_v1';\r\n private static INGEST_CACHE_TTL = 24 * 60 * 60 * 1000; // 24h\r\n\r\n private loadIngestedCache() {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n const raw = localStorage.getItem(HuskelClient.INGEST_CACHE_KEY);\r\n if (!raw) return;\r\n const { ts, urls }: { ts: number; urls: string[] } = JSON.parse(raw);\r\n if (Date.now() - ts > HuskelClient.INGEST_CACHE_TTL) {\r\n localStorage.removeItem(HuskelClient.INGEST_CACHE_KEY);\r\n return;\r\n }\r\n this.ingestedUrls = new Set(urls);\r\n } catch { /* ignore */ }\r\n }\r\n\r\n private saveIngestedCache() {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n localStorage.setItem(\r\n HuskelClient.INGEST_CACHE_KEY,\r\n JSON.stringify({ ts: Date.now(), urls: [...this.ingestedUrls] })\r\n );\r\n } catch { /* ignore */ }\r\n }\r\n\r\n constructor(config: HuskelConfig) {\r\n const siteId = config.siteId || getEnvVar('NEXT_PUBLIC_HUSKEL_SITE_ID') || '';\r\n const apiUrl = config.apiUrl || getEnvVar('NEXT_PUBLIC_HUSKEL_API_URL') || '';\r\n const apiToken = config.apiToken || getEnvVar('NEXT_PUBLIC_HUSKEL_API_TOKEN') || '';\r\n\r\n // Runtime validation — fail loudly so misconfiguration is never silent\r\n if (!siteId) console.error('[Huskel] Missing siteId. Set it via <HuskelProvider siteId=\"...\"> or NEXT_PUBLIC_HUSKEL_SITE_ID.');\r\n if (!apiUrl) console.error('[Huskel] Missing apiUrl. Set it via <HuskelProvider apiUrl=\"...\"> or NEXT_PUBLIC_HUSKEL_API_URL.');\r\n if (!apiToken) console.error('[Huskel] Missing apiToken. Set it via <HuskelProvider apiToken=\"...\"> or NEXT_PUBLIC_HUSKEL_API_TOKEN.');\r\n\r\n this.shopperId = config.shopperId;\r\n this.onCheckout = config.onCheckout;\r\n this.initSession();\r\n this.loadIngestedCache();\r\n\r\n this.api = new HuskelAPI(\r\n apiUrl,\r\n siteId,\r\n apiToken,\r\n () => this.getShopperId(),\r\n () => this.sessionId\r\n );\r\n instance = this;\r\n\r\n if (typeof window !== 'undefined') {\r\n this.onlineHandler = () => {\r\n console.log('[Huskel] Connectivity restored, flushing queued ingestions.');\r\n this.flushQueue();\r\n };\r\n window.addEventListener('online', this.onlineHandler);\r\n }\r\n }\r\n\r\n reRegister() {\r\n instance = this;\r\n }\r\n\r\n setShopperId(id: string | undefined) {\r\n this.shopperId = id;\r\n }\r\n\r\n getShopperId(): string | undefined {\r\n return this.shopperId || 'guest_' + this.sessionId;\r\n }\r\n\r\n getSessionId(): string {\r\n return this.sessionId;\r\n }\r\n\r\n private initSession() {\r\n if (typeof window !== 'undefined' && window.sessionStorage) {\r\n try {\r\n let sid = window.sessionStorage.getItem('huskel_session_id');\r\n if (!sid) {\r\n sid = generateUUID();\r\n window.sessionStorage.setItem('huskel_session_id', sid);\r\n }\r\n this.sessionId = sid;\r\n return;\r\n } catch (e) {\r\n // Fallback if sessionStorage is disabled or private mode\r\n }\r\n }\r\n this.sessionId = generateUUID();\r\n }\r\n\r\n destroy() {\r\n if (typeof window !== 'undefined' && this.onlineHandler) {\r\n window.removeEventListener('online', this.onlineHandler);\r\n this.onlineHandler = null;\r\n }\r\n if (this.ingestTimer) {\r\n clearTimeout(this.ingestTimer);\r\n this.ingestTimer = null;\r\n }\r\n if (instance === this) instance = null;\r\n }\r\n\r\n async queueIngest(rawProduct: RawProductInput): Promise<void> {\r\n const product = mapRawProduct(rawProduct);\r\n if (!product) return;\r\n\r\n if (this.ingestedUrls.has(product.url)) {\r\n return; // already indexed in this session or today — skip\r\n }\r\n this.ingestedUrls.add(product.url);\r\n this.saveIngestedCache();\r\n\r\n this.ingestQueue.push(product);\r\n this.scheduleFlush();\r\n }\r\n\r\n async queueIngestBatch(rawProducts: RawProductInput[]): Promise<void> {\r\n rawProducts.forEach(p => {\r\n const product = mapRawProduct(p);\r\n if (!product) return;\r\n\r\n if (this.ingestedUrls.has(product.url)) {\r\n return;\r\n }\r\n this.ingestedUrls.add(product.url);\r\n this.ingestQueue.push(product);\r\n });\r\n\r\n if (this.ingestQueue.length > 0) {\r\n this.saveIngestedCache();\r\n this.scheduleFlush();\r\n }\r\n }\r\n\r\n private scheduleFlush() {\r\n if (this.ingestTimer) return;\r\n this.ingestTimer = setTimeout(() => {\r\n this.flushQueue();\r\n }, 300);\r\n }\r\n\r\n private async flushQueue() {\r\n this.ingestTimer = null;\r\n if (this.ingestQueue.length === 0) return;\r\n\r\n if (typeof navigator !== 'undefined' && !navigator.onLine) {\r\n console.warn('[Huskel] Browser offline. Postponing ingestion.');\r\n return;\r\n }\r\n\r\n const batch = [...this.ingestQueue];\r\n this.ingestQueue = [];\r\n\r\n try {\r\n await this.api.ingestBatch(batch);\r\n } catch (e: any) {\r\n if (e.status && e.status >= 400 && e.status < 500) {\r\n console.error('[Huskel] Ingestion discarded due to client error:', e.message);\r\n return;\r\n }\r\n\r\n // Re-queue and schedule another flush so items are not stuck forever\r\n console.warn('[Huskel] Ingestion failed. Re-queuing to retry.', e);\r\n this.ingestQueue = [...batch, ...this.ingestQueue];\r\n this.scheduleFlush();\r\n }\r\n }\r\n}\r\n\r\nlet instance: HuskelClient | null = null;\r\n\r\nexport function initHuskel(config: HuskelConfig): HuskelClient {\r\n instance = new HuskelClient(config);\r\n return instance;\r\n}\r\n\r\nexport function getHuskelClient(): HuskelClient {\r\n if (!instance) {\r\n const siteId = getEnvVar('NEXT_PUBLIC_HUSKEL_SITE_ID');\r\n const apiUrl = getEnvVar('NEXT_PUBLIC_HUSKEL_API_URL');\r\n const apiToken = getEnvVar('NEXT_PUBLIC_HUSKEL_API_TOKEN');\r\n\r\n if (siteId && apiUrl && apiToken) {\r\n instance = new HuskelClient({ siteId, apiUrl, apiToken });\r\n } else {\r\n throw new Error('[Huskel] Call initHuskel() or set NEXT_PUBLIC_HUSKEL_* environment variables before using the client.');\r\n }\r\n }\r\n return instance;\r\n}\r\n","import { useRef } from 'react';\r\nimport { HuskelConfig } from '../types';\r\nimport { HuskelClient, initHuskel } from '../client';\r\n\r\n/**\r\n * @deprecated Use <HuskelProvider> instead to avoid SSR issues.\r\n */\r\nexport function useHuskel(config: HuskelConfig): HuskelClient {\r\n const clientRef = useRef<HuskelClient | null>(null);\r\n\r\n if (!clientRef.current) {\r\n console.warn('[Huskel] useHuskel() is deprecated. Please wrap your application in <HuskelProvider> instead.');\r\n clientRef.current = initHuskel(config);\r\n }\r\n\r\n return clientRef.current;\r\n}\r\n","import { useState, useCallback, useRef } from 'react';\nimport { SearchResult } from '../types';\nimport { useHuskelContext } from '../components/HuskelProvider';\n\ninterface UseSearchReturn {\n results: SearchResult[];\n loading: boolean;\n error: string | null;\n search: (query: string, limit?: number) => Promise<void>;\n clear: () => void;\n}\n\nexport function useSearch(): UseSearchReturn {\n const client = useHuskelContext();\n const [results, setResults] = useState<SearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n // Generation counter so stale responses from any in-flight requests don't overwrite newer ones\n const genRef = useRef(0);\n\n const search = useCallback(async (query: string, limit = 8) => {\n if (!query.trim()) { setResults([]); setLoading(false); return; }\n const gen = ++genRef.current;\n setLoading(true);\n setError(null);\n try {\n // searchAutocomplete = pure in-memory Trie, <1ms, no Upstash\n const res = await client.api.searchAutocomplete(query, limit);\n if (gen === genRef.current) {\n setResults(res.results ?? []);\n }\n } catch (e: unknown) {\n if (gen === genRef.current) {\n let msg = (e as any)?.message ?? 'Search failed';\n try {\n const parsed = JSON.parse(msg);\n if (parsed && parsed.error) {\n msg = parsed.error;\n }\n } catch {\n // keep original text\n }\n setError(msg);\n }\n } finally {\n if (gen === genRef.current) setLoading(false);\n }\n }, [client]);\n\n const clear = useCallback(() => {\n genRef.current++;\n setResults([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { results, loading, error, search, clear };\n}\n","'use client';\r\n\r\nimport React, { createContext, useContext, useEffect, useRef } from 'react';\r\nimport { HuskelClient, getHuskelClient } from '../client';\r\nimport { HuskelConfig } from '../types';\r\n\r\nexport const HuskelContext = createContext<HuskelClient | null>(null);\r\n\r\ninterface HuskelProviderProps extends HuskelConfig {\r\n children: React.ReactNode;\r\n}\r\n\r\nexport function HuskelProvider({ siteId, apiUrl, apiToken, shopperId, children }: HuskelProviderProps) {\r\n const clientRef = useRef<HuskelClient | null>(null);\r\n\r\n if (!clientRef.current) {\r\n clientRef.current = new HuskelClient({ siteId, apiUrl, apiToken, shopperId });\r\n } else {\r\n clientRef.current.reRegister();\r\n }\r\n\r\n // Update shopperId dynamically when it changes (e.g., shopper logs in/out)\r\n useEffect(() => {\r\n clientRef.current?.setShopperId(shopperId);\r\n }, [shopperId]);\r\n\r\n // Ensure active instance is registered on mount (handles development double-mounts and fast refresh)\r\n useEffect(() => {\r\n clientRef.current?.reRegister();\r\n }, []);\r\n\r\n // Clean up the online listener and timers when the provider unmounts\r\n // (prevents leaks during hot module reload and React StrictMode double-mount)\r\n useEffect(() => {\r\n return () => {\r\n clientRef.current?.destroy();\r\n };\r\n }, []);\r\n\r\n return (\r\n <HuskelContext.Provider value={clientRef.current}>\r\n {children}\r\n </HuskelContext.Provider>\r\n );\r\n}\r\n\r\nexport function useHuskelContext(): HuskelClient {\r\n const context = useContext(HuskelContext);\r\n if (!context) {\r\n return getHuskelClient();\r\n }\r\n return context;\r\n}\r\n\r\n","import { useCallback, useState } from 'react';\r\nimport { RawProductInput } from '../types';\r\nimport { useHuskelContext } from '../components/HuskelProvider';\r\n\r\ninterface UseIngestReturn {\r\n ingest: (product: RawProductInput) => Promise<void>;\r\n ingestBatch: (products: RawProductInput[]) => Promise<void>;\r\n loading: boolean;\r\n error: string | null;\r\n}\r\n\r\nexport function useIngest(): UseIngestReturn {\r\n const client = useHuskelContext();\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const ingest = useCallback(async (product: RawProductInput) => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n await client.queueIngest(product);\r\n } catch (e: unknown) {\r\n setError((e as Error).message ?? 'Ingest failed');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [client]);\r\n\r\n const ingestBatch = useCallback(async (products: RawProductInput[]) => {\r\n if (!products.length) return;\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n await client.queueIngestBatch(products);\r\n } catch (e: unknown) {\r\n setError((e as Error).message ?? 'Batch ingest failed');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [client]);\r\n\r\n return { ingest, ingestBatch, loading, error };\r\n}\r\n","import { useEffect, useRef } from 'react';\nimport { RawProductInput } from '../types';\nimport { getHuskelClient } from '../client';\n\n/**\n * usePageIngest — drop this into any product page component.\n * The moment a customer's browser renders the page, the product is\n * automatically captured and queued for ingestion into the vector index.\n *\n * No configuration needed beyond <HuskelProvider> in your layout.\n *\n * @example\n * // Product detail page — Next.js or React\n * export function ProductPage({ product }) {\n * usePageIngest({\n * name: product.title,\n * price: product.price,\n * url: window.location.href,\n * images: [product.thumbnail],\n * category: product.category,\n * });\n * return <div>...</div>;\n * }\n */\nexport function usePageIngest(product: RawProductInput | null | undefined): void {\n // Use url as the stable key — avoids re-ingesting on unrelated re-renders\n const ingestedRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!product) return;\n\n // Resolve URL — falls back to window.location if not provided\n const url =\n product.url ||\n (typeof window !== 'undefined' ? window.location.href : '');\n\n // Guard: only ingest once per URL per component lifecycle\n if (ingestedRef.current === url) return;\n ingestedRef.current = url;\n\n try {\n getHuskelClient().queueIngest({ ...product, url });\n } catch {\n // Client not initialised — silently skip\n }\n }, [product?.url ?? product?.name]);\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { useHuskelContext } from '../components/HuskelProvider';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatSource {\n id?: string;\n name: string;\n price?: string;\n currency?: string;\n category?: string;\n url?: string;\n image?: string;\n}\n\ninterface UseChatReturn {\n messages: ChatMessage[];\n sources: ChatSource[];\n loading: boolean;\n error: string | null;\n lastAction: any | null;\n send: (query: string, displayQuery?: string) => Promise<void>;\n reset: () => void;\n}\n\nexport function useChat(): UseChatReturn {\n const client = useHuskelContext();\n const [messages, setMessages] = useState<ChatMessage[]>([]);\n const [sources, setSources] = useState<ChatSource[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [lastAction, setLastAction] = useState<any | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const send = useCallback(async (query: string, displayQuery?: string) => {\n if (!query.trim() || loading) return;\n abortRef.current?.abort();\n abortRef.current = new AbortController();\n const signal = abortRef.current.signal;\n\n // Optimistically add the user message\n const userMsg: ChatMessage = { role: 'user', content: displayQuery ?? query };\n setMessages(prev => [...prev, userMsg]);\n setLoading(true);\n setError(null);\n\n try {\n // Build history from current messages (exclude the one we just added — server will see it as query)\n const history = messages.map(m => ({ role: m.role, content: m.content }));\n const res = await client.api.chat(query, history);\n\n if (signal.aborted) return;\n\n const fullAnswer = res.answer || '';\n const words = fullAnswer.split(/(\\s+)/);\n\n // Initialize empty assistant message\n setMessages(prev => [...prev, { role: 'assistant', content: '' }]);\n\n let currentContent = '';\n for (const word of words) {\n if (signal.aborted) return;\n currentContent += word;\n setMessages(prev => {\n const next = [...prev];\n if (next.length > 0) {\n next[next.length - 1] = { role: 'assistant', content: currentContent };\n }\n return next;\n });\n // 25ms delay per word token to make it read naturally\n await new Promise(resolve => setTimeout(resolve, 25));\n }\n\n if (signal.aborted) return;\n setSources(res.sources ?? []);\n if (res.action) setLastAction(res.action);\n\n if (res.action?.type === 'add_to_cart' || res.checkout) {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('huskel:cart_updated', { detail: res.checkout }));\n }\n }\n if (res.action?.type === 'checkout') {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('huskel:trigger_checkout', { detail: res.checkout }));\n }\n }\n if (res.action?.type === 'awaiting_payment') {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('huskel:awaiting_payment', { detail: res.action }));\n }\n }\n if (res.checkout && client.onCheckout) {\n client.onCheckout(res.checkout);\n }\n } catch (e: any) {\n if (signal.aborted) return;\n let msg = e?.message ?? 'Chat request failed';\n try {\n const parsed = JSON.parse(msg);\n if (parsed && parsed.error) {\n msg = parsed.error;\n }\n } catch {\n // keep original text\n }\n setError(msg);\n // Remove the optimistic user message on failure\n setMessages(prev => prev.slice(0, -1));\n } finally {\n if (!signal.aborted) {\n setLoading(false);\n }\n }\n }, [client, messages, loading]);\n\n const reset = useCallback(() => {\n abortRef.current?.abort();\n setMessages([]);\n setSources([]);\n setError(null);\n setLoading(false);\n setLastAction(null);\n }, []);\n\n return { messages, sources, loading, error, lastAction, send, reset };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { useHuskelContext } from '../components/HuskelProvider';\nimport { CartPayload } from '../types';\n\nexport function useCart() {\n const client = useHuskelContext();\n const [cart, setCart] = useState<CartPayload | null>(null);\n const [loading, setLoading] = useState(false);\n\n const shopperId = client.getShopperId();\n\n const fetchCart = useCallback(async () => {\n if (!shopperId) return;\n setLoading(true);\n try {\n const res = await client.api.getCart();\n setCart(res);\n } catch (e) {\n console.error('[Huskel] Failed to fetch cart', e);\n } finally {\n setLoading(false);\n }\n }, [client, shopperId]);\n\n useEffect(() => {\n fetchCart();\n \n const handleCartUpdate = (e: any) => {\n if (e.detail) {\n setCart(e.detail);\n } else {\n fetchCart();\n }\n };\n if (typeof window !== 'undefined') {\n window.addEventListener('huskel:cart_updated', handleCartUpdate as EventListener);\n return () => window.removeEventListener('huskel:cart_updated', handleCartUpdate as EventListener);\n }\n }, [fetchCart, shopperId]);\n\n return { cart, loading, fetchCart };\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { HuskelAPI } from '../api';\n\nexport interface UsePaymentPollingProps {\n client: HuskelAPI;\n merchantReference: string | null;\n onSuccess?: () => void;\n onFailure?: (errorMsg?: string) => void;\n intervalMs?: number;\n timeoutMs?: number;\n}\n\nexport function usePaymentPolling({\n client,\n merchantReference,\n onSuccess,\n onFailure,\n intervalMs = 3000,\n timeoutMs = 300000, // 5 minutes default\n}: UsePaymentPollingProps) {\n const [status, setStatus] = useState<'IDLE' | 'PENDING' | 'COMPLETED' | 'FAILED'>('IDLE');\n const [error, setError] = useState<string | null>(null);\n\n const onSuccessRef = useRef(onSuccess);\n const onFailureRef = useRef(onFailure);\n\n useEffect(() => {\n onSuccessRef.current = onSuccess;\n onFailureRef.current = onFailure;\n }, [onSuccess, onFailure]);\n\n useEffect(() => {\n if (!merchantReference) {\n setStatus('IDLE');\n setError(null);\n return;\n }\n\n setStatus('PENDING');\n setError(null);\n\n const startTime = Date.now();\n let timerId: ReturnType<typeof setTimeout> | null = null;\n\n async function checkStatus() {\n try {\n if (Date.now() - startTime >= timeoutMs) {\n setStatus('FAILED');\n setError('Payment session timed out');\n if (onFailureRef.current) onFailureRef.current('Payment session timed out');\n return;\n }\n\n const res = await client.getPaymentStatus(merchantReference as string);\n \n if (res.status === 'COMPLETED') {\n setStatus('COMPLETED');\n if (onSuccessRef.current) onSuccessRef.current();\n } else if (res.status === 'FAILED') {\n setStatus('FAILED');\n setError('Payment failed');\n if (onFailureRef.current) onFailureRef.current('Payment failed');\n } else {\n // Keep polling\n timerId = setTimeout(checkStatus, intervalMs);\n }\n } catch (err: any) {\n console.error('[Huskel Polling Error]', err);\n // Treat transient network/parsing errors gracefully and retry\n timerId = setTimeout(checkStatus, intervalMs);\n }\n }\n\n // Start polling\n timerId = setTimeout(checkStatus, intervalMs);\n\n return () => {\n if (timerId) {\n clearTimeout(timerId);\n }\n };\n }, [client, merchantReference, intervalMs, timeoutMs]);\n\n return { status, error };\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { useSearch } from '../hooks/useSearch';\nimport { SearchResult, HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\nimport { useHuskelContext } from './HuskelProvider';\n\nexport interface SearchBarProps {\n placeholder?: string;\n limit?: number;\n /** Debounce in ms — default 300 for smooth type-ahead */\n debounceMs?: number;\n onSelect?: (result: SearchResult) => void;\n className?: string;\n inputClassName?: string;\n dropdownClassName?: string;\n renderResult?: (result: SearchResult) => React.ReactNode;\n theme?: HuskelTheme;\n classNames?: {\n root?: string;\n input?: string;\n dropdown?: string;\n row?: string;\n };\n}\n\n/* SVG search glass — pure inline so no icon dependency */\nconst SearchIcon = () => (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"8.5\" cy=\"8.5\" r=\"5.5\"/>\n <line x1=\"13\" y1=\"13\" x2=\"18\" y2=\"18\"/>\n </svg>\n);\n\nexport function SearchBar({\n placeholder = 'Search products…',\n limit = 10,\n debounceMs = 300,\n onSelect,\n className,\n inputClassName,\n dropdownClassName,\n renderResult,\n theme,\n classNames = {},\n}: SearchBarProps) {\n const [query, setQuery] = useState('');\n const [open, setOpen] = useState(false);\n const [isDebouncing, setIsDebouncing] = useState(false);\n const { results, loading, search, clear } = useSearch();\n const client = useHuskelContext();\n const timer = useRef<ReturnType<typeof setTimeout>>();\n const wrap = useRef<HTMLDivElement>(null);\n const ignoreNextQueryChange = useRef(false);\n\n /* Debounce search — but keep stale results visible between calls */\n useEffect(() => {\n if (ignoreNextQueryChange.current) {\n ignoreNextQueryChange.current = false;\n return;\n }\n clearTimeout(timer.current);\n if (!query.trim()) {\n clear();\n setOpen(false);\n setIsDebouncing(false);\n return;\n }\n setOpen(true); // open immediately (stale results show while fetching)\n setIsDebouncing(true);\n timer.current = setTimeout(() => {\n setIsDebouncing(false);\n search(query, limit);\n }, debounceMs);\n return () => clearTimeout(timer.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [query]);\n\n /* Click-outside to close */\n useEffect(() => {\n const h = (e: MouseEvent) => {\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', h);\n return () => document.removeEventListener('mousedown', h);\n }, []);\n\n const handleSelect = (r: SearchResult) => {\n if (query.trim()) {\n client.api.searchVector(query, 1).catch(() => {});\n }\n ignoreNextQueryChange.current = true;\n setOpen(false);\n setQuery(r.product.name);\n onSelect?.(r);\n };\n\n const handleCommitSearch = () => {\n if (!query.trim()) return;\n client.api.searchVector(query, 1).catch(() => {});\n if (results.length > 0) {\n handleSelect(results[0]);\n }\n };\n\n const showDrop = open && query.trim().length > 0;\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div className={cn(\"hsk-sb-wrap\", classNames.root, className)} ref={wrap} style={customStyles}>\n <span className=\"hsk-sb-icon\"><SearchIcon /></span>\n <input\n className={cn(\"hsk-sb-input\", classNames.input, inputClassName)}\n type=\"text\"\n value={query}\n placeholder={placeholder}\n onChange={e => setQuery(e.target.value)}\n onFocus={() => results.length > 0 && query.trim() && setOpen(true)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n handleCommitSearch();\n }\n }}\n autoComplete=\"off\"\n spellCheck={false}\n />\n {showDrop && (\n <div className={cn(\"hsk-sb-drop\", classNames.dropdown, dropdownClassName)} style={{ position: 'absolute' }}>\n {(loading || isDebouncing) && <div className=\"hsk-sb-loading-bar\" />}\n\n {(loading || isDebouncing) && results.length === 0 ? (\n <>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" />\n <div className=\"hsk-sb-skeleton-text2\" />\n </div>\n </div>\n <div className=\"hsk-sb-skeleton-row\">\n <span className=\"hsk-sb-skeleton-icon\" />\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-skeleton-text1\" style={{ width: '45%' }} />\n <div className=\"hsk-sb-skeleton-text2\" style={{ width: '25%' }} />\n </div>\n </div>\n </>\n ) : (\n <>\n {results.length === 0 && !loading && !isDebouncing && (\n <div className=\"hsk-sb-empty\">No results for “{query}”</div>\n )}\n\n {results.map((r, i) => (\n renderResult ? (\n <div\n key={r.id}\n onClick={() => handleSelect(r)}\n className=\"hsk-sb-fade\"\n style={{ animationDelay: `${i * 18}ms` }}\n >\n {renderResult(r)}\n </div>\n ) : (\n <div\n key={r.id}\n className={cn(\"hsk-sb-row hsk-sb-fade\", classNames.row)}\n style={{ animationDelay: `${i * 18}ms` }}\n onClick={() => handleSelect(r)}\n >\n <span className=\"hsk-sb-row-icon\"><SearchIcon /></span>\n <div className=\"hsk-sb-row-body\">\n <div className=\"hsk-sb-row-title\">{r.product.name}</div>\n {(r.product.category || r.product.brand) && (\n <div className=\"hsk-sb-row-sub\">\n {r.product.category ?? r.product.brand}\n </div>\n )}\n </div>\n </div>\n )\n ))}\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merges Tailwind classes intelligently, allowing overrides.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import React, { useState, useEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSearch } from '../hooks/useSearch';\nimport { useChat } from '../hooks/useChat';\nimport { useHuskelContext } from './HuskelProvider';\nimport { renderMarkdown } from '../utils/markdown';\nimport { SearchResult, Product, HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\n\nexport interface SparkleProps {\n productName: string;\n limit?: number;\n onResult?: (results: SearchResult[]) => void;\n /** Override the backdrop colour (any CSS colour/gradient) */\n backdropColor?: string;\n /** Override backdrop blur — e.g. \"8px\" or 8 */\n backdropBlur?: string | number;\n /** Extra classes on the trigger button */\n className?: string;\n /** Called when user clicks a result — return false to prevent default navigation */\n onNavigate?: (result: SearchResult) => boolean | void;\n theme?: HuskelTheme;\n classNames?: {\n button?: string;\n backdrop?: string;\n card?: string;\n item?: string;\n };\n product?: Product;\n}\n\nconst SparkleIcon = ({ className }: { className?: string }) => (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z\"/>\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\n/* ── Modal ────────────────────────────────────────────────────────────────── */\ninterface ModalProps extends Pick<SparkleProps, 'productName' | 'limit' | 'backdropColor' | 'backdropBlur' | 'onNavigate' | 'onResult' | 'theme' | 'classNames' | 'product'> {\n onClose: () => void;\n}\n\nconst getFriendlyError = (err: any) => {\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n if (str.toLowerCase().includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n try {\n const parsed = JSON.parse(str);\n return parsed.error || parsed.message || str;\n } catch {\n return str;\n }\n};\n\nfunction SparkleModal({ \n productName, \n limit, \n backdropColor, \n backdropBlur, \n onClose, \n onNavigate, \n onResult,\n theme,\n classNames = {},\n product: initialProduct,\n}: ModalProps) {\n const client = useHuskelContext();\n const [fetchedProduct, setFetchedProduct] = useState<Product | null>(null);\n const displayProduct = initialProduct || fetchedProduct;\n const { results, loading: searchLoading, search } = useSearch();\n const { messages, sources, loading: chatLoading, error: chatError, send } = useChat();\n const [chatInput, setChatInput] = useState('');\n const chatBottomRef = useRef<HTMLDivElement>(null);\n const chatTextareaRef = useRef<HTMLTextAreaElement>(null);\n\n /* auto-search and product fetching on open */\n useEffect(() => {\n if (!initialProduct && !fetchedProduct) {\n client.api.searchVector(productName, 1)\n .then(res => {\n if (res.results && res.results.length > 0) {\n setFetchedProduct(res.results[0].product);\n }\n })\n .catch(err => console.error('[Huskel] Failed to fetch product details', err));\n }\n search(productName, limit);\n }, [productName, initialProduct, fetchedProduct, client, limit, search]);\n\n /* fire callback */\n useEffect(() => { if (results.length > 0) onResult?.(results); }, [results, onResult]);\n\n /* Escape key */\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, [onClose]);\n\n /* Scroll chat to bottom */\n useEffect(() => {\n chatBottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages, chatLoading]);\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '16px');\n const bg = backdropColor ?? undefined;\n\n const handleNav = (r: SearchResult) => {\n const prevent = onNavigate?.(r);\n if (prevent !== false) {\n onClose();\n if (r.product.url) window.location.href = r.product.url;\n }\n };\n\n const handleSend = async (text?: string) => {\n const q = (text ?? chatInput).trim();\n if (!q || chatLoading) return;\n setChatInput('');\n if (chatTextareaRef.current) {\n chatTextareaRef.current.style.height = 'auto';\n }\n\n if (messages.length === 0 && displayProduct) {\n const contextQuery = `[Context: Shopper is viewing \"${displayProduct.name}\". Price: ${displayProduct.price}. Description: ${displayProduct.description || ''}]\\n\\nQuestion: ${q}`;\n await send(contextQuery, q);\n } else {\n await send(q);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setChatInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\n };\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n const displayMessages = messages.length === 0 && displayProduct\n ? [\n {\n role: 'assistant' as const,\n content: `Hi! I can help you with **${displayProduct.name}**. Ask me about its specifications, features, compare it with other options, or find alternatives!`,\n },\n ]\n : messages;\n\n return (\n <div\n className={cn(\"hsk-sp-backdrop\", classNames.backdrop)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n background: bg ?? undefined,\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-sp-card hsk-sp-fullscreen\", classNames.card)} onClick={e => e.stopPropagation()}>\n <div className=\"hsk-sp-header\">\n <span className=\"hsk-sp-header-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div className=\"hsk-sp-header-body\">\n <div className=\"hsk-sp-header-title\">{displayProduct?.name || productName}</div>\n <div className=\"hsk-sp-header-sub\">Ask questions, compare specs, or check similar products</div>\n </div>\n <button className=\"hsk-sp-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n\n {searchLoading && <div className=\"hsk-sp-bar\" />}\n\n {/* Split pane body */}\n <div className=\"hsk-sp-body\">\n {/* Left Pane: Product Profile */}\n <div className=\"hsk-sp-details-pane\">\n {displayProduct && (\n <div className=\"hsk-sp-product-profile-container\">\n <div className=\"hsk-sp-product-profile\">\n <div className=\"hsk-sp-details-imgwrap\">\n {displayProduct.images?.[0] ? (\n <img src={displayProduct.images[0]} alt={displayProduct.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">🛍</span>\n )}\n </div>\n <div className=\"hsk-sp-details-meta\">\n {displayProduct.brand && <span className=\"hsk-sp-item-brand\">{displayProduct.brand}</span>}\n {displayProduct.category && <span className=\"hsk-sp-item-cat\">{displayProduct.category}</span>}\n <h2 className=\"hsk-sp-details-name\">{displayProduct.name}</h2>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{displayProduct.currency ?? 'KES'}</span>\n <span className=\"hsk-sp-item-price\">{parseFloat(displayProduct.price?.replace(/[^0-9.]/g, '') || '0').toLocaleString()}</span>\n {displayProduct.originalPrice && (\n <span className=\"hsk-sp-item-original-price\">\n {parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </span>\n )}\n {displayProduct.discount && (\n <span className=\"hsk-sp-item-discount\">({displayProduct.discount})</span>\n )}\n </div>\n \n <div className=\"hsk-sp-item-meta-badges\">\n {displayProduct.rating && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-rating\">\n ★ {parseFloat(displayProduct.rating.toString()).toFixed(1)} {displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ''}\n </span>\n )}\n {displayProduct.availability && (\n <span className={`hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes('in') ? 'in-stock' : 'out-stock'}`}>\n {displayProduct.availability}\n </span>\n )}\n {displayProduct.stock && !displayProduct.availability && (\n <span className=\"hsk-sp-meta-badge hsk-sp-meta-badge-stock\">\n Stock: {displayProduct.stock}\n </span>\n )}\n </div>\n </div>\n </div>\n\n {displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && (\n <div className=\"hsk-sp-specs-horizontal\">\n {Object.entries(displayProduct.specs).map(([key, val]) => (\n <div key={key} className=\"hsk-sp-spec-item-horizontal\">\n <span className=\"hsk-sp-spec-label-horizontal\">{key}:</span>\n <span className=\"hsk-sp-spec-value-horizontal\" title={val}>{val}</span>\n </div>\n ))}\n </div>\n )}\n\n {displayProduct.description && (\n <div className=\"hsk-sp-details-desc\">\n <h4>Description</h4>\n <p>{displayProduct.description}</p>\n </div>\n )}\n </div>\n )}\n\n {/* Similar Products */}\n <div className=\"hsk-sp-similar-section\">\n <h3>Similar Products</h3>\n <div className=\"hsk-sp-results\">\n {(() => {\n const similarProducts = results.filter(\n r => {\n const isSameName = r.product.name.toLowerCase() === displayProduct?.name?.toLowerCase();\n const isSameSlug = r.product.slug && displayProduct?.slug && r.product.slug.toLowerCase() === displayProduct.slug.toLowerCase();\n return !isSameName && !isSameSlug;\n }\n );\n\n if (!searchLoading && similarProducts.length === 0) {\n return <div className=\"hsk-sp-empty\">No similar products found.</div>;\n }\n\n return similarProducts.map((r, i) => {\n const price = parseFloat(r.product.price?.replace(/[^0-9.]/g, '') || '0');\n const currency = r.product.currency ?? 'KES';\n return (\n <div\n key={r.id}\n className={cn(\"hsk-sp-item\", classNames.item)}\n style={{ animationDelay: `${i * 55}ms` }}\n >\n <div className=\"hsk-sp-img-wrap\">\n {r.product.images?.[0] ? (\n <img src={r.product.images[0]} alt={r.product.name} />\n ) : (\n <span className=\"hsk-sp-img-placeholder\">🛍</span>\n )}\n </div>\n <div className=\"hsk-sp-item-body\">\n <div>\n {r.product.category && (\n <div className=\"hsk-sp-item-cat\">{r.product.category}</div>\n )}\n <div className=\"hsk-sp-item-name\" title={r.product.name}>{r.product.name}</div>\n </div>\n <div className=\"hsk-sp-item-price-row\">\n <span className=\"hsk-sp-item-currency\">{currency}</span>\n <span className=\"hsk-sp-item-price\">{price.toLocaleString()}</span>\n </div>\n <div className=\"hsk-sp-actions\">\n <button\n className=\"hsk-sp-action hsk-sp-action-primary\"\n onClick={() => handleNav(r)}\n >\n View\n </button>\n </div>\n </div>\n </div>\n );\n });\n })()}\n </div>\n </div>\n </div>\n\n {/* Right Pane: AI Chat Assistant */}\n <div className=\"hsk-sp-chat-pane\">\n <div className=\"hsk-cb-msgs\">\n {displayMessages.map((msg, idx) => {\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n </div>\n </div>\n )}\n </div>\n );\n })}\n\n {chatLoading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {chatError && <div className=\"hsk-cb-error\">{getFriendlyError(chatError)}</div>}\n <div ref={chatBottomRef} style={{ height: 1 }} />\n </div>\n\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={chatTextareaRef}\n className=\"hsk-cb-textarea\"\n value={chatInput}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask about this product, specs, or comparison...\"\n rows={1}\n disabled={chatLoading}\n />\n <button\n className=\"hsk-cb-send\"\n onClick={() => handleSend()}\n disabled={!chatInput.trim() || chatLoading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Huskel AI · instant product knowledge</div>\n </div>\n </div>\n </div>\n\n <div className=\"hsk-sp-footer\">\n <span className=\"hsk-sp-esc\">Esc to close</span>\n </div>\n </div>\n </div>\n );\n}\n\n/* ── Exported component ───────────────────────────────────────────────────── */\nexport function Sparkle({ \n productName, \n limit = 8, \n onResult, \n backdropColor, \n backdropBlur, \n className, \n onNavigate,\n theme,\n classNames = {},\n product,\n}: SparkleProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => { setMounted(true); }, []);\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <>\n <button\n className={cn(\"hsk-sp-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n title=\"Find similar products\"\n aria-label=\"Find similar products\"\n >\n <SparkleIcon />\n </button>\n {open && mounted && createPortal(\n <SparkleModal\n productName={productName}\n limit={limit}\n onResult={onResult}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onNavigate={onNavigate}\n theme={theme}\n classNames={classNames}\n product={product}\n />,\n document.body\n )}\n </>\n );\n}\n","import React from 'react';\n\n// Helper to parse inline styles (bold, links, and inline code) safely into React nodes\nconst parseInline = (text: string, keyPrefix: string): React.ReactNode => {\n // Regex to match markdown links, bold text, and inline code\n const tokenRegex = /(\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+\\*\\*|`[^`]+`)/g;\n const parts = text.split(tokenRegex);\n\n return parts.map((part, index) => {\n if (!part) return null;\n const key = `${keyPrefix}-inline-${index}`;\n\n // Handle Inline Code\n if (part.startsWith('`') && part.endsWith('`')) {\n return (\n <code key={key} className=\"hsk-markdown-code\">\n {part.slice(1, -1)}\n </code>\n );\n }\n\n // Handle Bold\n if (part.startsWith('**') && part.endsWith('**')) {\n return <strong key={key}>{parseInline(part.slice(2, -2), key)}</strong>;\n }\n\n // Handle Links\n const linkMatch = part.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (linkMatch) {\n // Basic sanitization: ensure the URL doesn't contain javascript:\n const url = linkMatch[2];\n const isSafeUrl = /^(https?|mailto|tel):/i.test(url) || url.startsWith('/');\n if (isSafeUrl) {\n return (\n <a key={key} href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"hsk-markdown-link\">\n {parseInline(linkMatch[1], key)}\n </a>\n );\n }\n return <span key={key}>{parseInline(linkMatch[1], key)}</span>; // Fallback to plain text if unsafe\n }\n\n // Return standard text\n return part;\n });\n};\n\nexport function renderMarkdown(content: string): React.ReactNode {\n const lines = content.split('\\n');\n const elements: React.ReactNode[] = [];\n \n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n const key = `md-line-${i}`;\n\n // 1. Empty lines (spacing)\n if (!line.trim()) {\n i++;\n continue;\n }\n\n // 2. Headers\n const headerMatch = line.match(/^(#{1,3})\\s+(.*)/);\n if (headerMatch) {\n const level = headerMatch[1].length;\n const Tag = `h${level + 3}` as keyof JSX.IntrinsicElements; // Maps # to h4, ## to h5 to avoid messing up host page hierarchy\n elements.push(<Tag key={key} className={`hsk-markdown-h${level}`}>{parseInline(headerMatch[2], key)}</Tag>);\n i++;\n continue;\n }\n\n // 3. Unordered Lists\n if (line.match(/^[-*]\\s+/)) {\n const listItems: React.ReactNode[] = [];\n while (i < lines.length && lines[i].match(/^[-*]\\s+/)) {\n const itemText = lines[i].replace(/^[-*]\\s+/, '');\n listItems.push(<li key={`li-${i}`}>{parseInline(itemText, `li-${i}`)}</li>);\n i++;\n }\n elements.push(<ul key={`ul-${key}`} className=\"hsk-markdown-list\">{listItems}</ul>);\n continue;\n }\n\n // 4. Tables\n if (line.trim().startsWith('|')) {\n const tableRows: React.ReactNode[] = [];\n let isHeader = true;\n\n while (i < lines.length && lines[i].trim().startsWith('|')) {\n const rowLine = lines[i].trim();\n // Skip markdown table separator (e.g., |---|---|)\n if (rowLine.match(/^\\|[-:| ]+\\|$/)) {\n i++;\n isHeader = false;\n continue;\n }\n\n // Slice to remove outer pipes and map trim to handle empty cells properly\n const cells = rowLine.split('|').slice(1, -1).map(c => c.trim());\n const Tag = isHeader ? 'th' : 'td';\n \n tableRows.push(\n <tr key={`tr-${i}`}>\n {cells.map((cell, cIdx) => (\n <Tag key={`td-${i}-${cIdx}`}>{parseInline(cell, `td-${i}-${cIdx}`)}</Tag>\n ))}\n </tr>\n );\n i++;\n }\n \n elements.push(\n <div key={`table-wrapper-${key}`} className=\"hsk-table-wrapper\">\n <table className=\"hsk-markdown-table\">\n <tbody>{tableRows}</tbody>\n </table>\n </div>\n );\n continue;\n }\n\n // 5. Default Paragraph\n elements.push(\n <p key={key} className=\"hsk-markdown-p\">\n {parseInline(line, key)}\n </p>\n );\n i++;\n }\n\n return <>{elements}</>;\n}\n","import React, { useState, useRef, useEffect } from 'react';\nimport { useChat, ChatMessage, ChatSource } from '../hooks/useChat';\nimport { renderMarkdown } from '../utils/markdown';\nimport { HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\n\n\n\n// Better Prop Interface for SDKs\nexport interface ChatWidgetProps {\n title?: string;\n placeholder?: string;\n emptyStateText?: string;\n emptyStateSuggestions?: string;\n defaultCurrency?: string;\n className?: string;\n \n // Allow overriding styles via standard CSS variables\n theme?: HuskelTheme;\n \n // Allow targeting specific elements with custom classes (e.g. Tailwind)\n classNames?: {\n root?: string;\n header?: string;\n messageBubble?: string;\n input?: string;\n };\n \n onSelectSource?: (source: ChatSource) => void;\n}\n\n// Simple SVG Icons instead of text characters\nconst SparkleIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z\"/>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\nfunction SourceCard({ source, defaultCurrency, onSelect }: { source: ChatSource; defaultCurrency: string; onSelect?: (s: ChatSource) => void }) {\n return (\n <div className=\"hsk-source-card\" onClick={() => onSelect?.(source)}>\n {source.image && <img src={source.image} alt={source.name} className=\"hsk-source-img\" />}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div className=\"hsk-source-name\">{source.name}</div>\n {source.price && (\n <div className=\"hsk-source-price\">{source.currency ?? defaultCurrency} {source.price}</div>\n )}\n </div>\n </div>\n );\n}\n\nexport function ChatWidget({ \n title = 'AI Shopping Assistant',\n placeholder = 'Ask about anything in our store…', \n emptyStateText = 'Ask me anything about our products',\n emptyStateSuggestions = '\"Find me headphones under KSh 5,000\" · \"Gift ideas\"',\n defaultCurrency = 'KES',\n className,\n theme,\n classNames = {},\n onSelectSource \n}: ChatWidgetProps) {\n const { messages, sources, loading, error, send, reset } = useChat();\n const [input, setInput] = useState('');\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n bottomRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages, loading]);\n\n const handleSend = async () => {\n const q = input.trim();\n if (!q || loading) return;\n setInput('');\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n await send(q);\n };\n\n const handleKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = Math.min(t.scrollHeight, 120) + 'px';\n };\n\n // Apply custom CSS variables inline to the root wrapper\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div \n className={cn(\"hsk-chat-widget\", classNames.root, className)} \n style={customStyles}\n >\n <div className={cn(\"hsk-chat-header\", classNames.header)}>\n <span className=\"hsk-chat-header-icon\"><SparkleIcon /></span>\n <span className=\"hsk-chat-title\">{title}</span>\n <span className=\"hsk-chat-badge\">AI</span>\n {messages.length > 0 && (\n <button className=\"hsk-chat-reset\" onClick={reset} style={{ marginLeft: 'auto' }}>Clear</button>\n )}\n </div>\n\n <div className=\"hsk-chat-messages\">\n {messages.length === 0 ? (\n <div className=\"hsk-chat-empty\">\n <div className=\"hsk-chat-empty-icon\"><SparkleIcon /></div>\n <div>{emptyStateText}</div>\n <div className=\"hsk-chat-empty-suggestions\">{emptyStateSuggestions}</div>\n </div>\n ) : (\n messages.map((msg, idx) => (\n <div key={idx}>\n <div className={`hsk-msg-row ${msg.role}`}>\n <div className={cn(\"hsk-msg-avatar\", msg.role === 'assistant' ? 'ai' : 'user')}>\n {msg.role === 'assistant' ? <SparkleIcon /> : 'U'}\n </div>\n <div className={cn(\"hsk-msg-bubble\", msg.role, classNames.messageBubble)}>\n {renderMarkdown(msg.content)}\n </div>\n </div>\n {msg.role === 'assistant' && idx === messages.length - 1 && sources.length > 0 && (\n <div className=\"hsk-sources-container\">\n <div className=\"hsk-sources\">\n {sources.map((src, si) => (\n <SourceCard key={si} source={src} defaultCurrency={defaultCurrency} onSelect={onSelectSource} />\n ))}\n </div>\n </div>\n )}\n </div>\n ))\n )}\n\n {loading && (\n <div className=\"hsk-msg-row\">\n <div className=\"hsk-msg-avatar ai\"><SparkleIcon /></div>\n <div className=\"hsk-typing\">\n <div className=\"hsk-typing-dot\" /><div className=\"hsk-typing-dot\" /><div className=\"hsk-typing-dot\" />\n </div>\n </div>\n )}\n\n {error && (\n <div className=\"hsk-chat-error\">\n {(() => {\n try {\n const parsed = JSON.parse(error);\n return parsed.error || parsed.message || error;\n } catch {\n return error;\n }\n })()}\n </div>\n )}\n <div ref={bottomRef} />\n </div>\n\n <div className=\"hsk-chat-input-area\">\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-chat-input\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKey}\n placeholder={placeholder}\n rows={1}\n disabled={loading}\n />\n <button\n className=\"hsk-chat-send\"\n onClick={handleSend}\n disabled={!input.trim() || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n </div>\n );\n}\n\n","'use client';\n\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useChat, ChatMessage, ChatSource } from '../hooks/useChat';\nimport { usePaymentPolling } from '../hooks/usePaymentPolling';\nimport { useHuskelContext } from './HuskelProvider';\nimport { renderMarkdown } from '../utils/markdown';\nimport { HuskelTheme } from '../types';\nimport { cn } from '../utils/cn';\n\n\nexport interface AIChatButtonProps {\n label?: string;\n title?: string;\n placeholder?: string;\n backdropColor?: string;\n backdropBlur?: string | number;\n className?: string;\n onSelectSource?: (source: ChatSource) => void;\n defaultCurrency?: string;\n chips?: string[];\n theme?: HuskelTheme;\n classNames?: {\n button?: string;\n overlay?: string;\n panel?: string;\n input?: string;\n sendButton?: string;\n };\n}\n\nconst SparkleIcon = ({ className }: { className?: string }) => (\n <svg className={className} width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z\"/>\n </svg>\n);\n\nconst ArrowUpIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m5 12 7-7 7 7\"/>\n <path d=\"M12 19V5\"/>\n </svg>\n);\n\nconst CloseIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n);\n\nconst ChevronRightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\"/>\n </svg>\n);\n\nconst DEFAULT_CHIPS = [\n 'Cheapest smartphone',\n 'Smart TV under KSh 20,000',\n 'Noise-cancelling headphones',\n 'Best laptop for students',\n];\n\ninterface SourcesCarouselProps {\n sources: ChatSource[];\n defaultCurrency: string;\n onSelectSource?: (src: ChatSource) => void;\n}\n\nfunction SourcesCarousel({ sources, defaultCurrency, onSelectSource }: SourcesCarouselProps) {\n const railRef = useRef<HTMLDivElement>(null);\n const [showNext, setShowNext] = useState(false);\n\n const measure = useCallback(() => {\n const el = railRef.current;\n if (!el) return;\n const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;\n setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);\n }, []);\n\n useEffect(() => {\n measure();\n const el = railRef.current;\n if (!el) return;\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n el.addEventListener('scroll', measure, { passive: true });\n return () => { ro.disconnect(); el.removeEventListener('scroll', measure); };\n }, [measure, sources]);\n\n const scrollNext = () => {\n railRef.current?.scrollBy({ left: 170, behavior: 'smooth' });\n };\n\n return (\n <div className=\"hsk-cb-sources-wrap\">\n <div className=\"hsk-cb-sources\" ref={railRef}>\n {sources.map((src, si) => (\n <div\n key={si}\n className=\"hsk-cb-source\"\n style={{ animationDelay: `${si * 50}ms` }}\n onClick={() => onSelectSource?.(src)}\n >\n {src.image ? (\n <div className=\"hsk-cb-src-imgwrap\">\n <img src={src.image} alt={src.name} loading=\"lazy\" />\n </div>\n ) : (\n <div className=\"hsk-cb-src-imgwrap-empty\">\n <SparkleIcon />\n </div>\n )}\n <div className=\"hsk-cb-src-info\">\n <div className=\"hsk-cb-src-name\">{src.name}</div>\n {src.price && (\n <div className=\"hsk-cb-src-price\">\n {src.currency ?? defaultCurrency}{' '}\n {parseFloat(src.price.replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n {showNext && (\n <>\n <div\n className=\"hsk-cb-sources-fade\"\n style={{ background: 'linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))' }}\n />\n <button className=\"hsk-cb-sources-next\" onClick={scrollNext} aria-label=\"See more\">\n <ChevronRightIcon />\n </button>\n </>\n )}\n </div>\n );\n}\n\ninterface ChatModalProps extends Pick<AIChatButtonProps, 'title' | 'placeholder' | 'backdropColor' | 'backdropBlur' | 'onSelectSource' | 'defaultCurrency' | 'chips' | 'theme' | 'classNames'> {\n onClose: () => void;\n}\n\nconst getFriendlyError = (err: any) => {\n let str = '';\n if (typeof err === 'string') str = err;\n else if (err && typeof err === 'object' && err.message) str = err.message;\n else try { str = JSON.stringify(err); } catch { str = String(err); }\n\n if (str.toLowerCase().includes('token limit')) {\n return \"You've reached your usage limit. Please update your billing limits in your dashboard to continue.\";\n }\n\n try {\n const parsed = JSON.parse(str);\n return parsed.error || parsed.message || str;\n } catch {\n return str;\n }\n};\n\nfunction ChatModal({\n title = 'Shopping Assistant',\n placeholder = 'Ask me anything — gifts, budget, use case…',\n backdropColor,\n backdropBlur,\n onClose,\n onSelectSource,\n defaultCurrency = 'KES',\n chips = DEFAULT_CHIPS,\n theme,\n classNames = {},\n}: ChatModalProps) {\n const client = useHuskelContext();\n const { messages, sources, loading, error, lastAction, send, reset } = useChat();\n const [input, setInput] = useState('');\n const [selectedProduct, setSelectedProduct] = useState<ChatSource | null>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [phoneInput, setPhoneInput] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('huskel_user_phone') || '';\n }\n return '';\n });\n const [merchantRef, setMerchantRef] = useState<string | null>(null);\n const [paymentPhase, setPaymentPhase] = useState<'idle' | 'prompt_phone' | 'awaiting' | 'done' | 'failed'>('idle');\n\n const { status: pollStatus } = usePaymentPolling({\n client: client.api,\n merchantReference: merchantRef,\n onSuccess: () => {\n setPaymentPhase('done');\n setMerchantRef(null);\n },\n onFailure: () => {\n setPaymentPhase('failed');\n setMerchantRef(null);\n },\n });\n\n // React to lastAction from chat\n useEffect(() => {\n if (!lastAction) return;\n if (lastAction.type === 'request_phone') {\n setPaymentPhase('prompt_phone');\n } else if (lastAction.type === 'awaiting_payment') {\n setMerchantRef(lastAction.merchantReference ?? null);\n setPaymentPhase('awaiting');\n }\n }, [lastAction]);\n\n const handlePhoneSubmit = async () => {\n if (!phoneInput.trim()) return;\n try {\n if (typeof window !== 'undefined') {\n localStorage.setItem('huskel_user_phone', phoneInput.trim());\n }\n const res = await client.api.initiatePayment(phoneInput.trim());\n setMerchantRef(res.merchantReference);\n setPaymentPhase('awaiting');\n } catch (e: any) {\n console.error('[Huskel] initiatePayment error', e);\n setPaymentPhase('failed');\n }\n };\n\n useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages, loading, selectedProduct]);\n\n useEffect(() => {\n const h = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n document.addEventListener('keydown', h);\n return () => document.removeEventListener('keydown', h);\n }, []);\n\n const handleSourceClick = (src: ChatSource) => {\n setSelectedProduct(src);\n onSelectSource?.(src);\n const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ''} — what are its key specs, who is it best for, and is it worth buying?`;\n send(q);\n };\n\n const handleSend = async (text?: string) => {\n const q = (text ?? input).trim();\n if (!q || loading) return;\n setSelectedProduct(null);\n setInput('');\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto';\n }\n await send(q);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }\n };\n\n const handleInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInput(e.target.value);\n const t = e.target;\n t.style.height = 'auto';\n t.style.height = `${Math.min(t.scrollHeight, 140)}px`;\n };\n\n const blurVal = typeof backdropBlur === 'number' ? `${backdropBlur}px` : (backdropBlur ?? '20px');\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <div\n className={cn(\"hsk-cb-overlay\", classNames.overlay)}\n onClick={onClose}\n style={{\n backdropFilter: `blur(${blurVal})`,\n WebkitBackdropFilter: `blur(${blurVal})`,\n ...(backdropColor ? { background: backdropColor } : {}),\n ...customStyles,\n }}\n >\n <div className={cn(\"hsk-cb-panel\", classNames.panel)} onClick={e => e.stopPropagation()}>\n\n {/* Top bar */}\n <div className=\"hsk-cb-topbar\">\n <div className=\"hsk-cb-topbar-left\">\n <span className=\"hsk-cb-topbar-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n <div>\n <div className=\"hsk-cb-topbar-title\">{title}</div>\n </div>\n </div>\n <div className=\"hsk-cb-topbar-actions\">\n {messages.length > 0 && (\n <button className=\"hsk-cb-topbar-btn\" onClick={reset}>Clear chat</button>\n )}\n <button className=\"hsk-cb-close\" onClick={onClose} aria-label=\"Close\">\n <CloseIcon />\n </button>\n </div>\n </div>\n\n {/* Messages */}\n <div className=\"hsk-cb-msgs\">\n {messages.length === 0 ? (\n <div className=\"hsk-cb-empty\">\n <div className=\"hsk-cb-empty-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-empty-title\">Find exactly what you need</div>\n <div className=\"hsk-cb-chips\">\n {chips.map(chip => (\n <button\n key={chip}\n className=\"hsk-cb-chip\"\n onClick={() => handleSend(chip)}\n >\n {chip}\n </button>\n ))}\n </div>\n </div>\n ) : (\n messages.map((msg: ChatMessage, idx: number) => {\n const isLast = idx === messages.length - 1;\n const isUser = msg.role === 'user';\n return (\n <div key={idx} className=\"hsk-cb-msg-group\">\n {isUser ? (\n <div className=\"hsk-cb-user-msg\">\n <div className=\"hsk-cb-user-bubble\">{msg.content}</div>\n </div>\n ) : (\n <div className=\"hsk-cb-ai-msg\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-ai-body\">\n <div className=\"hsk-cb-ai-text\">{renderMarkdown(msg.content)}</div>\n\n {/* Sources as horizontal carousel — only after latest assistant reply */}\n {isLast && sources.length > 0 && lastAction?.type !== 'request_phone' && lastAction?.type !== 'awaiting_payment' && lastAction?.type !== 'checkout' && (\n <SourcesCarousel\n sources={sources}\n defaultCurrency={defaultCurrency}\n onSelectSource={handleSourceClick}\n />\n )}\n </div>\n </div>\n )}\n </div>\n );\n })\n )}\n\n {/* Selected product pinned card — shows while LLM fetches details */}\n {selectedProduct && loading && (\n <div\n className=\"hsk-cb-selected-product\"\n onClick={() => selectedProduct.url && window.open(selectedProduct.url, '_blank')}\n >\n {selectedProduct.image && (\n <img className=\"hsk-cb-selected-img\" src={selectedProduct.image} alt={selectedProduct.name} />\n )}\n <div className=\"hsk-cb-selected-info\">\n <div className=\"hsk-cb-selected-name\">{selectedProduct.name}</div>\n {selectedProduct.price && (\n <div className=\"hsk-cb-selected-price\">\n {selectedProduct.currency ?? defaultCurrency} {parseFloat((selectedProduct.price ?? '').replace(/[^0-9.]/g, '') || '0').toLocaleString()}\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Typing dots */}\n {loading && (\n <div className=\"hsk-cb-typing-row\">\n <div className=\"hsk-cb-ai-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </div>\n <div className=\"hsk-cb-typing\">\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n <div className=\"hsk-cb-dot\" />\n </div>\n </div>\n )}\n\n {error && <div className=\"hsk-cb-error\">{error}</div>}\n\n {/* Payment phase UIs */}\n {paymentPhase === 'prompt_phone' && (\n <div className=\"hsk-cb-payment-prompt\">\n <div className=\"hsk-cb-payment-icon\">📱</div>\n <p className=\"hsk-cb-payment-label\">Enter your M-Pesa number to pay</p>\n <input\n type=\"tel\"\n className=\"hsk-cb-phone-input\"\n placeholder=\"e.g. 0712 345 678\"\n value={phoneInput}\n onChange={e => setPhoneInput(e.target.value)}\n onKeyDown={e => e.key === 'Enter' && handlePhoneSubmit()}\n />\n <button className=\"hsk-cb-pay-submit\" onClick={handlePhoneSubmit}>\n Send STK Push →\n </button>\n </div>\n )}\n\n {paymentPhase === 'awaiting' && (\n <div className=\"hsk-cb-payment-prompt\">\n <div className=\"hsk-cb-payment-icon\" style={{fontSize: '2rem'}}>⏳</div>\n <p className=\"hsk-cb-payment-label\" style={{fontWeight: 600}}>Check your phone</p>\n <p style={{fontSize: '0.8rem', opacity: 0.6}}>An M-Pesa STK push has been sent. Enter your PIN to complete payment.</p>\n </div>\n )}\n\n {paymentPhase === 'done' && (\n <div className=\"hsk-cb-payment-prompt\">\n <div className=\"hsk-cb-payment-icon\" style={{color: '#22c55e', fontSize: '2rem'}}>✅</div>\n <p className=\"hsk-cb-payment-label\">Payment complete! Thank you.</p>\n </div>\n )}\n\n {paymentPhase === 'failed' && (\n <div className=\"hsk-cb-payment-prompt\">\n <div className=\"hsk-cb-payment-icon\" style={{color: '#ef4444', fontSize: '2rem'}}>❌</div>\n <p className=\"hsk-cb-payment-label\">Payment failed or timed out.</p>\n <button className=\"hsk-cb-pay-submit\" onClick={() => { setPaymentPhase('idle'); setMerchantRef(null); }}>\n Try again\n </button>\n </div>\n )}\n\n <div ref={bottomRef} style={{ height: 1 }} />\n </div>\n\n {/* Input */}\n <div className=\"hsk-cb-input-wrap\">\n <div className=\"hsk-cb-input-box\">\n <textarea\n ref={textareaRef}\n className={cn(\"hsk-cb-textarea\", classNames.input)}\n value={input}\n onChange={handleInput}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n rows={1}\n disabled={loading}\n autoFocus\n />\n <button\n className={cn(\"hsk-cb-send\", classNames.sendButton)}\n onClick={() => handleSend()}\n disabled={!input.trim() || loading}\n aria-label=\"Send message\"\n >\n <ArrowUpIcon />\n </button>\n </div>\n <div className=\"hsk-cb-hint\">Huskel AI · searches the whole catalogue in real time</div>\n </div>\n\n </div>\n </div>\n );\n}\n\nexport function AIChatButton({\n label,\n title,\n placeholder,\n backdropColor,\n backdropBlur,\n className,\n onSelectSource,\n defaultCurrency,\n chips,\n theme,\n classNames = {},\n}: AIChatButtonProps) {\n const [open, setOpen] = useState(false);\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => { setMounted(true); }, []);\n\n const customStyles = {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties;\n\n return (\n <>\n <button\n className={cn(\"hsk-cb-btn\", classNames.button, className)}\n onClick={() => setOpen(true)}\n style={customStyles}\n aria-label=\"Open AI chat\"\n >\n <span className=\"hsk-cb-btn-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n <SparkleIcon />\n </span>\n {label !== undefined ? label : null}\n </button>\n {open && mounted && createPortal(\n <ChatModal\n title={title}\n placeholder={placeholder}\n backdropColor={backdropColor}\n backdropBlur={backdropBlur}\n onClose={() => setOpen(false)}\n onSelectSource={onSelectSource}\n defaultCurrency={defaultCurrency}\n chips={chips}\n theme={theme}\n classNames={classNames}\n />,\n document.body\n )}\n </>\n );\n}\n","import React from 'react';\nimport { useCart } from '../hooks/useCart';\nimport { cn } from '../utils/cn';\n\nexport function CartBadge({ className }: { className?: string }) {\n const { cart } = useCart();\n \n if (!cart || cart.item_count === 0) return null;\n \n return (\n <span className={cn(\"hsk-cart-badge\", className)}>\n {cart.item_count}\n </span>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useCart } from '../hooks/useCart';\nimport { useHuskelContext } from './HuskelProvider';\nimport { HuskelTheme } from '../types';\nimport { CheckoutModal } from './CheckoutModal';\nimport { cn } from '../utils/cn';\n\nexport function CartDrawer({ \n trigger, \n className,\n theme \n}: { \n trigger?: React.ReactNode, \n className?: string,\n theme?: 'light' | 'dark' | HuskelTheme \n}) {\n const { cart, loading } = useCart();\n const [open, setOpen] = useState(false);\n const [showCheckout, setShowCheckout] = useState(false);\n const [mounted, setMounted] = useState(false);\n const client = useHuskelContext();\n\n useEffect(() => {\n setMounted(true);\n const handleTriggerCheckout = () => {\n setShowCheckout(true);\n setOpen(false);\n };\n window.addEventListener('huskel:trigger_checkout', handleTriggerCheckout);\n return () => {\n window.removeEventListener('huskel:trigger_checkout', handleTriggerCheckout);\n };\n }, []);\n\n // Block body scroll when drawer is open\n useEffect(() => {\n if (open) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => { document.body.style.overflow = ''; };\n }, [open]);\n\n const handleCheckout = async () => {\n if (!cart || cart.items.length === 0) return;\n \n const event = new CustomEvent('huskel:trigger_checkout', { cancelable: true });\n window.dispatchEvent(event);\n \n if (event.defaultPrevented) {\n setOpen(false);\n return;\n }\n \n setShowCheckout(true);\n };\n\n const isStringTheme = typeof theme === 'string';\n const hskThemeAttr = isStringTheme ? theme : undefined;\n \n const customStyles = (!isStringTheme && theme) ? {\n ...(theme?.primaryColor && { '--hsk-primary': theme.primaryColor, '--hsk-primary-color': theme.primaryColor }),\n ...(theme?.backgroundColor && { '--hsk-bg': theme.backgroundColor }),\n ...(theme?.textColor && { '--hsk-text': theme.textColor }),\n ...(theme?.fontFamily && { '--hsk-font': theme.fontFamily }),\n ...(theme?.borderRadius && { '--hsk-border-radius': theme.borderRadius }),\n } as React.CSSProperties : undefined;\n\n return (\n <>\n <div onClick={() => setOpen(true)} style={{ display: 'inline-block' }}>\n {trigger || (\n <button \n className={cn(\"hsk-cart-trigger\", className)} \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n aria-label=\"Open cart\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"9\" cy=\"21\" r=\"1\"></circle>\n <circle cx=\"20\" cy=\"21\" r=\"1\"></circle>\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"></path>\n </svg>\n {cart && cart.item_count > 0 ? (\n <span className=\"hsk-cart-trigger-badge\">{cart.item_count}</span>\n ) : null}\n </button>\n )}\n </div>\n \n {open && mounted && createPortal(\n <div \n className=\"hsk-cart-backdrop\" \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n onClick={() => setOpen(false)}\n >\n <div \n className=\"hsk-cart-bottom-sheet\" \n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"hsk-cart-sheet-handle\" />\n \n <div className=\"hsk-cart-sheet-header\">\n <h2>Your Cart</h2>\n <button onClick={() => setOpen(false)} className=\"hsk-close-btn\">×</button>\n </div>\n \n <div className=\"hsk-cart-sheet-content\">\n {loading && !cart ? (\n <div className=\"hsk-cart-loading\">Loading cart...</div>\n ) : !cart || cart.items.length === 0 ? (\n <div className=\"hsk-cart-empty\">Your cart is empty.</div>\n ) : (\n <ul className=\"hsk-cart-items\">\n {cart.items.map(item => (\n <li key={item.id} className=\"hsk-cart-item\">\n {item.image && <img src={item.image} alt={item.name} className=\"hsk-cart-item-img\" />}\n <div className=\"hsk-cart-item-info\">\n <span className=\"hsk-cart-item-name\">{item.name}</span>\n <span className=\"hsk-cart-item-price\">{item.currency} {item.price_numeric.toLocaleString(undefined, { minimumFractionDigits: 2 })}</span>\n </div>\n <div className=\"hsk-cart-item-qty\">x{item.quantity}</div>\n </li>\n ))}\n </ul>\n )}\n </div>\n \n {cart && cart.items.length > 0 && (\n <div className=\"hsk-cart-sheet-footer\">\n <div className=\"hsk-cart-total\">\n <span>Total</span>\n <span>{cart.currency} {cart.total.toLocaleString(undefined, { minimumFractionDigits: 2 })}</span>\n </div>\n <button onClick={handleCheckout} className=\"hsk-checkout-btn\">\n Checkout securely\n </button>\n </div>\n )}\n </div>\n </div>,\n document.body\n )}\n\n {showCheckout && mounted && (\n <CheckoutModal \n onClose={() => {\n setShowCheckout(false);\n setOpen(false);\n }}\n theme={isStringTheme ? (theme as string) : undefined}\n customStyles={customStyles}\n hskThemeAttr={hskThemeAttr}\n />\n )}\n </>\n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useCart } from '../hooks/useCart';\nimport { useHuskelContext } from './HuskelProvider';\nimport { usePaymentPolling } from '../hooks/usePaymentPolling';\n\ntype Phase = 'idle' | 'awaiting' | 'done' | 'failed';\n\nexport function CheckoutModal({\n onClose,\n theme,\n customStyles,\n hskThemeAttr\n}: {\n onClose: () => void;\n theme?: string;\n customStyles?: React.CSSProperties;\n hskThemeAttr?: string;\n}) {\n const { cart, loading: cartLoading } = useCart();\n const client = useHuskelContext();\n const [config, setConfig] = useState<any>(null);\n const [loadingConfig, setLoadingConfig] = useState(true);\n\n // Form fields prefilled from localStorage\n const [phone, setPhone] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('huskel_user_phone') || '';\n }\n return '';\n });\n const [email, setEmail] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('huskel_user_email') || '';\n }\n return '';\n });\n const [firstName, setFirstName] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('huskel_user_firstname') || '';\n }\n return '';\n });\n const [lastName, setLastName] = useState(() => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem('huskel_user_lastname') || '';\n }\n return '';\n });\n\n // Payment state\n const [phase, setPhase] = useState<Phase>('idle');\n const [merchantRef, setMerchantRef] = useState<string | null>(null);\n const [payError, setPayError] = useState<string | null>(null);\n\n // Poll for payment confirmation\n const { } = usePaymentPolling({\n client: client.api,\n merchantReference: merchantRef,\n onSuccess: () => { setPhase('done'); setMerchantRef(null); },\n onFailure: () => {\n setPhase('failed');\n setPayError('Payment failed or timed out. Please try again.');\n setMerchantRef(null);\n },\n });\n\n useEffect(() => {\n client.api.getCheckoutConfig()\n .then(res => setConfig(res.payment_methods))\n .catch(() => {})\n .finally(() => setLoadingConfig(false));\n }, [client]);\n\n const hasPaymentMethods = config && Object.values(config).some((m: any) => m.enabled);\n\n const handlePay = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!phone.trim()) { setPayError('Phone number is required.'); return; }\n setPayError(null);\n setPhase('awaiting');\n try {\n if (typeof window !== 'undefined') {\n localStorage.setItem('huskel_user_phone', phone.trim());\n localStorage.setItem('huskel_user_email', email.trim());\n localStorage.setItem('huskel_user_firstname', firstName.trim());\n localStorage.setItem('huskel_user_lastname', lastName.trim());\n }\n const res = await client.api.initiatePayment(phone.trim(), email, firstName, lastName);\n if (res?.merchantReference) {\n setMerchantRef(res.merchantReference);\n } else {\n throw new Error('No merchant reference returned.');\n }\n } catch (err: any) {\n setPhase('failed');\n setPayError(err.message || 'Could not connect to payment processor.');\n }\n };\n\n const currency = cart?.currency || 'KES';\n const total = cart?.total || 0;\n\n const backdropStyle: React.CSSProperties = { ...customStyles, fontSize: '15px', fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif', zIndex: 999999 };\n\n return createPortal(\n <div\n className=\"hsk-checkout-backdrop-full\"\n style={backdropStyle}\n data-hsk-theme={hskThemeAttr}\n >\n <div\n className=\"hsk-checkout-modal-full\"\n style={customStyles}\n data-hsk-theme={hskThemeAttr}\n >\n {/* Left Panel: Order Summary */}\n <div className=\"hsk-checkout-panel-left\">\n <div className=\"hsk-checkout-left-content\">\n <button onClick={onClose} className=\"hsk-checkout-back-btn\" disabled={phase !== 'idle'}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\n <polyline points=\"12 19 5 12 12 5\"></polyline>\n </svg>\n Back to store\n </button>\n \n <div className=\"hsk-checkout-store-info\">\n <h2>Secure Checkout</h2>\n </div>\n \n <div className=\"hsk-checkout-amount-due\">\n <span className=\"hsk-checkout-label-muted\">Pay total</span>\n <div className=\"hsk-checkout-grand-total\">\n {currency} {total.toLocaleString(undefined, { minimumFractionDigits: 2 })}\n </div>\n </div>\n \n {cartLoading || !cart ? (\n <p className=\"hsk-cart-loading\">Loading order...</p>\n ) : (\n <div className=\"hsk-checkout-items-list-wrap\">\n <ul className=\"hsk-checkout-items-list\">\n {cart.items.map(item => (\n <li key={item.id} className=\"hsk-checkout-item-row\">\n <div className=\"hsk-checkout-item-img-container\">\n {item.image ? (\n <img src={item.image} alt={item.name} className=\"hsk-checkout-item-img\" />\n ) : (\n <div className=\"hsk-checkout-item-img-placeholder\">🛒</div>\n )}\n <span className=\"hsk-checkout-item-qty-badge\">{item.quantity}</span>\n </div>\n <div className=\"hsk-checkout-item-details\">\n <span className=\"hsk-checkout-item-name\">{item.name}</span>\n </div>\n <span className=\"hsk-checkout-item-price\">\n {item.currency} {(item.price_numeric * item.quantity).toLocaleString(undefined, { minimumFractionDigits: 2 })}\n </span>\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n </div>\n\n {/* Right Panel: Payment Forms & Status */}\n <div className=\"hsk-checkout-panel-right\">\n <div className=\"hsk-checkout-right-content\">\n {phase === 'done' ? (\n <div className=\"hsk-checkout-status-card success\">\n <div className=\"hsk-status-icon-wrap success\">✅</div>\n <h3>Payment Successful!</h3>\n <p>Your transaction has been confirmed successfully. Thank you for your order!</p>\n <button onClick={onClose} className=\"hsk-pay-btn hsk-btn-primary\" style={{ marginTop: '1.5rem' }}>\n Continue Shopping\n </button>\n </div>\n ) : phase === 'awaiting' ? (\n <div className=\"hsk-checkout-status-card awaiting\">\n <div className=\"hsk-status-spinner-wrap\">\n <div className=\"hsk-status-spinner\"></div>\n </div>\n <h3>Confirm payment on your phone</h3>\n <p>We've sent an M-Pesa STK push prompt to <strong>254{phone}</strong>.</p>\n <div className=\"hsk-checkout-stk-instructions\">\n <p>1. Check your phone lockscreen for the M-Pesa prompt.</p>\n <p>2. Enter your M-Pesa PIN and press OK.</p>\n <p>3. Wait here; this page will automatically redirect once confirmed.</p>\n </div>\n <button\n onClick={() => { setPhase('idle'); setMerchantRef(null); }}\n className=\"hsk-checkout-cancel-btn\"\n >\n Cancel and change phone number\n </button>\n </div>\n ) : phase === 'failed' ? (\n <div className=\"hsk-checkout-status-card failed\">\n <div className=\"hsk-status-icon-wrap failed\">❌</div>\n <h3>Payment failed or timed out</h3>\n <p className=\"hsk-checkout-error-text\">{payError || 'Could not verify M-Pesa transaction.'}</p>\n <button onClick={() => { setPhase('idle'); setPayError(null); }} className=\"hsk-pay-btn hsk-btn-primary\" style={{ marginTop: '1.5rem' }}>\n Try Again\n </button>\n </div>\n ) : (\n <div className=\"hsk-checkout-payment-form-wrap\">\n <h3 className=\"hsk-checkout-section-title\">Payment details</h3>\n {loadingConfig ? (\n <p className=\"hsk-cart-loading\">Loading payment configuration...</p>\n ) : !hasPaymentMethods ? (\n <p className=\"hsk-checkout-error\">No payment methods configured for this store.</p>\n ) : (\n <form onSubmit={handlePay} className=\"hsk-stripe-checkout-form\">\n \n {/* Phone field */}\n <div className=\"hsk-form-group\">\n <label className=\"hsk-form-label\">M-Pesa Mobile Number</label>\n <div className=\"hsk-phone-input-container\">\n <span className=\"hsk-phone-prefix\">254</span>\n <input\n type=\"tel\"\n required\n placeholder=\"712345678\"\n pattern=\"[0-9]{9}\"\n maxLength={9}\n value={phone}\n onChange={e => setPhone(e.target.value.replace(/\\D/g, ''))}\n className=\"hsk-phone-input-field\"\n />\n </div>\n <span className=\"hsk-form-hint\">Enter your 9-digit number (e.g. 712345678)</span>\n </div>\n\n {/* Email field */}\n <div className=\"hsk-form-group\">\n <label className=\"hsk-form-label\">Email address</label>\n <input\n type=\"email\"\n placeholder=\"john.doe@example.com\"\n value={email}\n onChange={e => setEmail(e.target.value)}\n className=\"hsk-form-input\"\n />\n </div>\n\n {/* Name row */}\n <div className=\"hsk-form-row\">\n <div className=\"hsk-form-group\">\n <label className=\"hsk-form-label\">First Name</label>\n <input\n type=\"text\"\n placeholder=\"John\"\n value={firstName}\n onChange={e => setFirstName(e.target.value)}\n className=\"hsk-form-input\"\n />\n </div>\n <div className=\"hsk-form-group\">\n <label className=\"hsk-form-label\">Last Name</label>\n <input\n type=\"text\"\n placeholder=\"Doe\"\n value={lastName}\n onChange={e => setLastName(e.target.value)}\n className=\"hsk-form-input\"\n />\n </div>\n </div>\n\n {payError && (\n <div className=\"hsk-form-error-banner\">\n {payError}\n </div>\n )}\n\n <button type=\"submit\" className=\"hsk-checkout-submit-btn\">\n Pay {currency} {total.toLocaleString()}\n </button>\n \n <div className=\"hsk-checkout-footer-brand\">\n <span>Powered by Huskel AI</span>\n </div>\n </form>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n </div>,\n document.body\n );\n}\n"],"mappings":"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","names":["useRef","useRef","useRef","useRef","e","useCallback","useState","useState","useCallback","useEffect","useRef","useRef","useEffect","useState","useCallback","useRef","useState","useRef","useCallback","e","useState","useEffect","useCallback","useState","useCallback","useEffect","useState","useEffect","useRef","useState","useEffect","useRef","jsx","useState","useRef","useEffect","useState","useEffect","useRef","Fragment","jsx","Fragment","jsx","jsxs","useState","useRef","useEffect","_a","_b","_c","useState","useRef","useEffect","jsx","jsxs","SparkleIcon","ArrowUpIcon","useState","useRef","useEffect","useState","useEffect","useRef","useCallback","createPortal","Fragment","jsx","jsxs","SparkleIcon","ArrowUpIcon","CloseIcon","useRef","useState","useCallback","useEffect","useState","useRef","useEffect","_a","jsx","jsxs","SparkleIcon","CloseIcon","ArrowUpIcon","Fragment","createPortal","jsx","useState","useEffect","createPortal","useState","useEffect","createPortal","jsx","jsxs","useState","useEffect","createPortal","Fragment","jsx","jsxs","useState","useEffect","createPortal"]}
|