@akropolys/kiku 1.2.3 → 1.4.0
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.d.mts +59 -4
- package/dist/index.d.ts +59 -4
- package/dist/index.js +968 -559
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +939 -532
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +441 -1
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -164,7 +164,7 @@ function SearchBar({
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
// src/components/ChatWidget.tsx
|
|
167
|
-
import { useState as
|
|
167
|
+
import { useState as useState4, useRef as useRef4, useEffect as useEffect2 } from "react";
|
|
168
168
|
import { useKiku } from "@akropolys/sdk";
|
|
169
169
|
|
|
170
170
|
// src/utils/markdown.tsx
|
|
@@ -252,19 +252,151 @@ function renderMarkdown(content) {
|
|
|
252
252
|
return /* @__PURE__ */ jsx2(Fragment2, { children: elements });
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
// src/components/
|
|
255
|
+
// src/components/VoiceButton.tsx
|
|
256
|
+
import { useState as useState2, useRef as useRef2, useCallback } from "react";
|
|
256
257
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
257
|
-
var
|
|
258
|
-
|
|
259
|
-
/* @__PURE__ */ jsx3("path", { d: "
|
|
260
|
-
/* @__PURE__ */ jsx3("
|
|
258
|
+
var MicIcon = ({ active }) => /* @__PURE__ */ jsxs2("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
259
|
+
/* @__PURE__ */ jsx3("rect", { x: "9", y: "2", width: "6", height: "11", rx: "3", fill: active ? "currentColor" : "none" }),
|
|
260
|
+
/* @__PURE__ */ jsx3("path", { d: "M5 10a7 7 0 0 0 14 0" }),
|
|
261
|
+
/* @__PURE__ */ jsx3("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
|
|
262
|
+
/* @__PURE__ */ jsx3("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
|
|
263
|
+
] });
|
|
264
|
+
function VoiceButton({
|
|
265
|
+
onTranscript,
|
|
266
|
+
onInterim,
|
|
267
|
+
lang = "en-US",
|
|
268
|
+
className = "",
|
|
269
|
+
disabled = false
|
|
270
|
+
}) {
|
|
271
|
+
const [listening, setListening] = useState2(false);
|
|
272
|
+
const recognitionRef = useRef2(null);
|
|
273
|
+
const isSupported = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
|
|
274
|
+
const start = useCallback(() => {
|
|
275
|
+
if (!isSupported || listening) return;
|
|
276
|
+
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
277
|
+
const recognition = new SR();
|
|
278
|
+
recognition.lang = lang;
|
|
279
|
+
recognition.interimResults = true;
|
|
280
|
+
recognition.maxAlternatives = 1;
|
|
281
|
+
recognitionRef.current = recognition;
|
|
282
|
+
recognition.onstart = () => setListening(true);
|
|
283
|
+
recognition.onend = () => setListening(false);
|
|
284
|
+
recognition.onerror = () => setListening(false);
|
|
285
|
+
recognition.onresult = (e) => {
|
|
286
|
+
const results = Array.from(e.results);
|
|
287
|
+
const transcript = results.map((r) => r[0].transcript).join("");
|
|
288
|
+
const isFinal = e.results[e.results.length - 1].isFinal;
|
|
289
|
+
if (isFinal) {
|
|
290
|
+
onTranscript(transcript);
|
|
291
|
+
setListening(false);
|
|
292
|
+
} else {
|
|
293
|
+
onInterim?.(transcript);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
recognition.start();
|
|
297
|
+
}, [isSupported, listening, lang, onTranscript, onInterim]);
|
|
298
|
+
const stop = useCallback(() => {
|
|
299
|
+
recognitionRef.current?.stop();
|
|
300
|
+
setListening(false);
|
|
301
|
+
}, []);
|
|
302
|
+
if (!isSupported) return null;
|
|
303
|
+
return /* @__PURE__ */ jsxs2(
|
|
304
|
+
"button",
|
|
305
|
+
{
|
|
306
|
+
type: "button",
|
|
307
|
+
className: `kiku-voice-btn${listening ? " kiku-voice-btn--active" : ""} ${className}`,
|
|
308
|
+
onClick: listening ? stop : start,
|
|
309
|
+
disabled,
|
|
310
|
+
title: listening ? "Stop listening" : "Speak your search",
|
|
311
|
+
"aria-label": listening ? "Stop voice input" : "Start voice input",
|
|
312
|
+
children: [
|
|
313
|
+
/* @__PURE__ */ jsx3(MicIcon, { active: listening }),
|
|
314
|
+
listening && /* @__PURE__ */ jsx3("span", { className: "kiku-voice-ripple", "aria-hidden": "true" })
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/components/VisualSearch.tsx
|
|
321
|
+
import { useRef as useRef3, useState as useState3 } from "react";
|
|
322
|
+
import { useAkropolysContext as useAkropolysContext2 } from "@akropolys/sdk";
|
|
323
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
324
|
+
var CameraIcon = () => /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
325
|
+
/* @__PURE__ */ jsx4("path", { d: "M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" }),
|
|
326
|
+
/* @__PURE__ */ jsx4("circle", { cx: "12", cy: "13", r: "4" })
|
|
327
|
+
] });
|
|
328
|
+
var SpinnerIcon = () => /* @__PURE__ */ jsx4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "kiku-vs-spin", children: /* @__PURE__ */ jsx4("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
|
|
329
|
+
function fileToBase64(file) {
|
|
330
|
+
return new Promise((resolve, reject) => {
|
|
331
|
+
const reader = new FileReader();
|
|
332
|
+
reader.onload = () => resolve(reader.result);
|
|
333
|
+
reader.onerror = reject;
|
|
334
|
+
reader.readAsDataURL(file);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function VisualSearch({
|
|
338
|
+
onResults,
|
|
339
|
+
onError,
|
|
340
|
+
categoryHint,
|
|
341
|
+
className = "",
|
|
342
|
+
disabled = false
|
|
343
|
+
}) {
|
|
344
|
+
const client = useAkropolysContext2();
|
|
345
|
+
const inputRef = useRef3(null);
|
|
346
|
+
const [loading, setLoading] = useState3(false);
|
|
347
|
+
const handleFile = async (file) => {
|
|
348
|
+
if (!file.type.startsWith("image/")) return;
|
|
349
|
+
setLoading(true);
|
|
350
|
+
try {
|
|
351
|
+
const base64 = await fileToBase64(file);
|
|
352
|
+
const res = await client.api.searchByImage(base64, categoryHint);
|
|
353
|
+
onResults(res, base64);
|
|
354
|
+
} catch (e) {
|
|
355
|
+
onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
356
|
+
} finally {
|
|
357
|
+
setLoading(false);
|
|
358
|
+
if (inputRef.current) inputRef.current.value = "";
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
return /* @__PURE__ */ jsxs3(
|
|
362
|
+
"label",
|
|
363
|
+
{
|
|
364
|
+
className: `kiku-vs-btn${loading ? " kiku-vs-btn--loading" : ""} ${className}`,
|
|
365
|
+
title: "Search by photo",
|
|
366
|
+
"aria-label": "Search by uploading a photo",
|
|
367
|
+
style: { cursor: disabled || loading ? "not-allowed" : "pointer" },
|
|
368
|
+
children: [
|
|
369
|
+
/* @__PURE__ */ jsx4(
|
|
370
|
+
"input",
|
|
371
|
+
{
|
|
372
|
+
ref: inputRef,
|
|
373
|
+
type: "file",
|
|
374
|
+
accept: "image/*",
|
|
375
|
+
capture: "environment",
|
|
376
|
+
onChange: (e) => e.target.files?.[0] && handleFile(e.target.files[0]),
|
|
377
|
+
disabled: disabled || loading,
|
|
378
|
+
hidden: true
|
|
379
|
+
}
|
|
380
|
+
),
|
|
381
|
+
loading ? /* @__PURE__ */ jsx4(SpinnerIcon, {}) : /* @__PURE__ */ jsx4(CameraIcon, {})
|
|
382
|
+
]
|
|
383
|
+
}
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// src/components/ChatWidget.tsx
|
|
388
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
389
|
+
var SparkleIcon = () => /* @__PURE__ */ jsx5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("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" }) });
|
|
390
|
+
var ArrowUpIcon = () => /* @__PURE__ */ jsxs4("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
391
|
+
/* @__PURE__ */ jsx5("path", { d: "m5 12 7-7 7 7" }),
|
|
392
|
+
/* @__PURE__ */ jsx5("path", { d: "M12 19V5" })
|
|
261
393
|
] });
|
|
262
394
|
function SourceCard({ source, defaultCurrency, onSelect }) {
|
|
263
|
-
return /* @__PURE__ */
|
|
264
|
-
source.image && /* @__PURE__ */
|
|
265
|
-
/* @__PURE__ */
|
|
266
|
-
/* @__PURE__ */
|
|
267
|
-
source.price && /* @__PURE__ */
|
|
395
|
+
return /* @__PURE__ */ jsxs4("div", { className: "hsk-source-card", onClick: () => onSelect?.(source), children: [
|
|
396
|
+
source.image && /* @__PURE__ */ jsx5("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
|
|
397
|
+
/* @__PURE__ */ jsxs4("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
398
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-source-name", children: source.name }),
|
|
399
|
+
source.price && /* @__PURE__ */ jsxs4("div", { className: "hsk-source-price", children: [
|
|
268
400
|
source.currency ?? defaultCurrency,
|
|
269
401
|
" ",
|
|
270
402
|
source.price
|
|
@@ -281,15 +413,56 @@ function ChatWidget({
|
|
|
281
413
|
className,
|
|
282
414
|
theme,
|
|
283
415
|
classNames = {},
|
|
284
|
-
onSelectSource
|
|
416
|
+
onSelectSource,
|
|
417
|
+
enableVoice = false,
|
|
418
|
+
enableVision = false,
|
|
419
|
+
visionCategoryHint
|
|
285
420
|
}) {
|
|
286
|
-
const { messages, sources, loading, error, send, reset } = useKiku();
|
|
287
|
-
const [input, setInput] =
|
|
288
|
-
const
|
|
289
|
-
const
|
|
421
|
+
const { messages, sources, loading: chatLoading, error, send, reset } = useKiku();
|
|
422
|
+
const [input, setInput] = useState4("");
|
|
423
|
+
const [visualLoading, setVisualLoading] = useState4(false);
|
|
424
|
+
const bottomRef = useRef4(null);
|
|
425
|
+
const textareaRef = useRef4(null);
|
|
426
|
+
const loading = chatLoading || visualLoading;
|
|
427
|
+
const [chatHistory, setChatHistory] = useState4([]);
|
|
428
|
+
const lastSyncedCount = useRef4(0);
|
|
429
|
+
useEffect2(() => {
|
|
430
|
+
if (messages.length === 0) {
|
|
431
|
+
setChatHistory([]);
|
|
432
|
+
lastSyncedCount.current = 0;
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (messages.length > lastSyncedCount.current) {
|
|
436
|
+
const newMsgs = messages.slice(lastSyncedCount.current);
|
|
437
|
+
setChatHistory((prev) => [...prev, ...newMsgs]);
|
|
438
|
+
lastSyncedCount.current = messages.length;
|
|
439
|
+
} else if (messages.length < lastSyncedCount.current) {
|
|
440
|
+
setChatHistory(messages);
|
|
441
|
+
lastSyncedCount.current = messages.length;
|
|
442
|
+
} else {
|
|
443
|
+
setChatHistory((prev) => {
|
|
444
|
+
const next = [...prev];
|
|
445
|
+
let hookIdx = messages.length - 1;
|
|
446
|
+
let historyIdx = next.length - 1;
|
|
447
|
+
while (hookIdx >= 0 && historyIdx >= 0) {
|
|
448
|
+
if (next[historyIdx].role === messages[hookIdx].role) {
|
|
449
|
+
next[historyIdx] = {
|
|
450
|
+
...next[historyIdx],
|
|
451
|
+
content: messages[hookIdx].content,
|
|
452
|
+
cartSnapshot: messages[hookIdx].cartSnapshot,
|
|
453
|
+
actionType: messages[hookIdx].actionType
|
|
454
|
+
};
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
historyIdx--;
|
|
458
|
+
}
|
|
459
|
+
return next;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}, [messages]);
|
|
290
463
|
useEffect2(() => {
|
|
291
464
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
292
|
-
}, [
|
|
465
|
+
}, [chatHistory, loading]);
|
|
293
466
|
const handleSend = async () => {
|
|
294
467
|
const q = input.trim();
|
|
295
468
|
if (!q || loading) return;
|
|
@@ -309,6 +482,56 @@ function ChatWidget({
|
|
|
309
482
|
t.style.height = "auto";
|
|
310
483
|
t.style.height = Math.min(t.scrollHeight, 120) + "px";
|
|
311
484
|
};
|
|
485
|
+
const handleVisualResults = (res, preview) => {
|
|
486
|
+
const userMsg = {
|
|
487
|
+
role: "user",
|
|
488
|
+
content: "Uploaded a photo for visual search",
|
|
489
|
+
imagePreview: preview
|
|
490
|
+
};
|
|
491
|
+
const dna = res.style_dna;
|
|
492
|
+
let content = `I've analyzed your image! Here is the Style DNA I found:
|
|
493
|
+
`;
|
|
494
|
+
if (dna) {
|
|
495
|
+
if (dna.color_palette) content += `* **Palette:** ${dna.color_palette}
|
|
496
|
+
`;
|
|
497
|
+
if (dna.dominant_colors && dna.dominant_colors.length > 0) {
|
|
498
|
+
content += `* **Colors:** ${dna.dominant_colors.join(", ")}
|
|
499
|
+
`;
|
|
500
|
+
}
|
|
501
|
+
if (dna.aesthetic && dna.aesthetic.length > 0) {
|
|
502
|
+
content += `* **Aesthetic:** ${dna.aesthetic.join(", ")}
|
|
503
|
+
`;
|
|
504
|
+
}
|
|
505
|
+
if (dna.texture) content += `* **Texture:** ${dna.texture}
|
|
506
|
+
`;
|
|
507
|
+
if (dna.formality) content += `* **Formality:** ${dna.formality}
|
|
508
|
+
`;
|
|
509
|
+
}
|
|
510
|
+
const results = res.results || [];
|
|
511
|
+
if (results.length > 0) {
|
|
512
|
+
content += `
|
|
513
|
+
I found ${results.length} matching products in the store for you.`;
|
|
514
|
+
} else {
|
|
515
|
+
content += `
|
|
516
|
+
I couldn't find any matching products in the store.`;
|
|
517
|
+
}
|
|
518
|
+
const assistantMsg = {
|
|
519
|
+
role: "assistant",
|
|
520
|
+
content,
|
|
521
|
+
styleDNA: dna,
|
|
522
|
+
visualSources: results.map((r) => ({
|
|
523
|
+
id: r.id,
|
|
524
|
+
name: r.product.name,
|
|
525
|
+
price: r.product.price,
|
|
526
|
+
currency: r.product.currency,
|
|
527
|
+
category: r.product.category,
|
|
528
|
+
url: r.product.url,
|
|
529
|
+
image: r.product.images && r.product.images.length > 0 ? r.product.images[0] : void 0,
|
|
530
|
+
brand: r.product.brand
|
|
531
|
+
}))
|
|
532
|
+
};
|
|
533
|
+
setChatHistory((prev) => [...prev, userMsg, assistantMsg]);
|
|
534
|
+
};
|
|
312
535
|
const customStyles = {
|
|
313
536
|
...theme?.primaryColor && { "--hsk-primary": theme.primaryColor },
|
|
314
537
|
...theme?.backgroundColor && { "--hsk-bg": theme.backgroundColor },
|
|
@@ -316,45 +539,60 @@ function ChatWidget({
|
|
|
316
539
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
317
540
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
318
541
|
};
|
|
319
|
-
return /* @__PURE__ */
|
|
542
|
+
return /* @__PURE__ */ jsxs4(
|
|
320
543
|
"div",
|
|
321
544
|
{
|
|
322
545
|
className: cn("hsk-chat-widget", classNames.root, className),
|
|
323
546
|
style: customStyles,
|
|
324
547
|
children: [
|
|
325
|
-
/* @__PURE__ */
|
|
326
|
-
/* @__PURE__ */
|
|
327
|
-
/* @__PURE__ */
|
|
328
|
-
/* @__PURE__ */
|
|
329
|
-
|
|
548
|
+
/* @__PURE__ */ jsxs4("div", { className: cn("hsk-chat-header", classNames.header), children: [
|
|
549
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ jsx5(SparkleIcon, {}) }),
|
|
550
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-chat-title", children: title }),
|
|
551
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-chat-badge", children: "AI" }),
|
|
552
|
+
chatHistory.length > 0 && /* @__PURE__ */ jsx5("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
|
|
330
553
|
] }),
|
|
331
|
-
/* @__PURE__ */
|
|
332
|
-
|
|
333
|
-
/* @__PURE__ */
|
|
334
|
-
/* @__PURE__ */
|
|
335
|
-
/* @__PURE__ */
|
|
336
|
-
] }) :
|
|
337
|
-
/* @__PURE__ */
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
/* @__PURE__ */
|
|
554
|
+
/* @__PURE__ */ jsxs4("div", { className: "hsk-chat-messages", children: [
|
|
555
|
+
chatHistory.length === 0 ? /* @__PURE__ */ jsxs4("div", { className: "hsk-chat-empty", children: [
|
|
556
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ jsx5(SparkleIcon, {}) }),
|
|
557
|
+
/* @__PURE__ */ jsx5("div", { children: emptyStateText }),
|
|
558
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
|
|
559
|
+
] }) : chatHistory.map((msg, idx) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
560
|
+
/* @__PURE__ */ jsxs4("div", { className: `hsk-msg-row ${msg.role}`, children: [
|
|
561
|
+
/* @__PURE__ */ jsx5("div", { className: cn("hsk-msg-avatar", msg.role === "assistant" ? "ai" : "user"), children: msg.role === "assistant" ? /* @__PURE__ */ jsx5(SparkleIcon, {}) : "U" }),
|
|
562
|
+
/* @__PURE__ */ jsxs4("div", { className: cn("hsk-msg-bubble", msg.role, classNames.messageBubble), children: [
|
|
563
|
+
msg.imagePreview && /* @__PURE__ */ jsx5("div", { className: "kiku-vs-preview-bubble", style: { marginBottom: "8px" }, children: /* @__PURE__ */ jsx5("img", { src: msg.imagePreview, alt: "Uploaded Preview", className: "kiku-vs-preview-bubble-img", style: { maxWidth: "200px", borderRadius: "8px" } }) }),
|
|
564
|
+
renderMarkdown(msg.content),
|
|
565
|
+
msg.styleDNA && /* @__PURE__ */ jsxs4("div", { className: "kiku-vs-preview-banner", style: { marginTop: "10px" }, children: [
|
|
566
|
+
chatHistory[idx - 1]?.imagePreview && /* @__PURE__ */ jsx5("img", { src: chatHistory[idx - 1].imagePreview, alt: "Visual Search Input", className: "kiku-vs-preview-img" }),
|
|
567
|
+
/* @__PURE__ */ jsxs4("div", { className: "kiku-vs-preview-info", children: [
|
|
568
|
+
/* @__PURE__ */ jsx5("div", { className: "kiku-vs-preview-label", children: "Visual Match Palette" }),
|
|
569
|
+
/* @__PURE__ */ jsx5("div", { className: "kiku-vs-preview-palette", children: msg.styleDNA.color_palette || "Detected Style DNA" }),
|
|
570
|
+
msg.styleDNA.style_tags && msg.styleDNA.style_tags.length > 0 && /* @__PURE__ */ jsx5("div", { className: "kiku-style-tags", children: msg.styleDNA.style_tags.map((tag, ti) => /* @__PURE__ */ jsxs4("span", { className: "kiku-style-tag", children: [
|
|
571
|
+
"#",
|
|
572
|
+
tag
|
|
573
|
+
] }, ti)) })
|
|
574
|
+
] })
|
|
575
|
+
] })
|
|
576
|
+
] })
|
|
340
577
|
] }),
|
|
341
|
-
msg.role === "assistant" &&
|
|
578
|
+
msg.role === "assistant" && msg.visualSources && msg.visualSources.length > 0 && /* @__PURE__ */ jsx5("div", { className: "hsk-sources-container", children: /* @__PURE__ */ jsx5("div", { className: "hsk-sources", children: msg.visualSources.map((src, si) => /* @__PURE__ */ jsx5(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) }),
|
|
579
|
+
msg.role === "assistant" && idx === chatHistory.length - 1 && !msg.visualSources && sources.length > 0 && /* @__PURE__ */ jsx5("div", { className: "hsk-sources-container", children: /* @__PURE__ */ jsx5("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ jsx5(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
|
|
342
580
|
] }, idx)),
|
|
343
|
-
loading && /* @__PURE__ */
|
|
344
|
-
/* @__PURE__ */
|
|
345
|
-
/* @__PURE__ */
|
|
346
|
-
/* @__PURE__ */
|
|
347
|
-
/* @__PURE__ */
|
|
348
|
-
/* @__PURE__ */
|
|
581
|
+
loading && /* @__PURE__ */ jsxs4("div", { className: "hsk-msg-row", children: [
|
|
582
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ jsx5(SparkleIcon, {}) }),
|
|
583
|
+
/* @__PURE__ */ jsxs4("div", { className: "hsk-pending", role: "status", "aria-live": "polite", children: [
|
|
584
|
+
/* @__PURE__ */ jsxs4("div", { className: "hsk-pending-glyph", children: [
|
|
585
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-pending-ring" }),
|
|
586
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-pending-dot" })
|
|
349
587
|
] }),
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
/* @__PURE__ */
|
|
352
|
-
/* @__PURE__ */
|
|
353
|
-
/* @__PURE__ */
|
|
588
|
+
/* @__PURE__ */ jsxs4("div", { className: "hsk-pending-text", children: [
|
|
589
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-pending-step step-1", children: "Searching catalog" }),
|
|
590
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-pending-step step-2", children: "Reasoning" }),
|
|
591
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-pending-step step-3", children: "Composing" })
|
|
354
592
|
] })
|
|
355
593
|
] })
|
|
356
594
|
] }),
|
|
357
|
-
error && /* @__PURE__ */
|
|
595
|
+
error && /* @__PURE__ */ jsx5("div", { className: "hsk-chat-error", children: (() => {
|
|
358
596
|
try {
|
|
359
597
|
const parsed = JSON.parse(error);
|
|
360
598
|
return parsed.error || parsed.message || error;
|
|
@@ -362,10 +600,19 @@ function ChatWidget({
|
|
|
362
600
|
return error;
|
|
363
601
|
}
|
|
364
602
|
})() }),
|
|
365
|
-
/* @__PURE__ */
|
|
603
|
+
/* @__PURE__ */ jsx5("div", { ref: bottomRef })
|
|
366
604
|
] }),
|
|
367
|
-
/* @__PURE__ */
|
|
368
|
-
/* @__PURE__ */
|
|
605
|
+
/* @__PURE__ */ jsxs4("div", { className: "hsk-chat-input-area", style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
606
|
+
enableVision && /* @__PURE__ */ jsx5(
|
|
607
|
+
VisualSearch,
|
|
608
|
+
{
|
|
609
|
+
onResults: handleVisualResults,
|
|
610
|
+
onError: (err) => console.error("[VisualSearch] error:", err),
|
|
611
|
+
categoryHint: visionCategoryHint,
|
|
612
|
+
disabled: loading
|
|
613
|
+
}
|
|
614
|
+
),
|
|
615
|
+
/* @__PURE__ */ jsx5(
|
|
369
616
|
"textarea",
|
|
370
617
|
{
|
|
371
618
|
ref: textareaRef,
|
|
@@ -375,17 +622,30 @@ function ChatWidget({
|
|
|
375
622
|
onKeyDown: handleKey,
|
|
376
623
|
placeholder,
|
|
377
624
|
rows: 1,
|
|
625
|
+
disabled: loading,
|
|
626
|
+
style: { flex: 1 }
|
|
627
|
+
}
|
|
628
|
+
),
|
|
629
|
+
enableVoice && /* @__PURE__ */ jsx5(
|
|
630
|
+
VoiceButton,
|
|
631
|
+
{
|
|
632
|
+
onTranscript: (text) => {
|
|
633
|
+
setInput(text);
|
|
634
|
+
send(text);
|
|
635
|
+
setInput("");
|
|
636
|
+
},
|
|
637
|
+
onInterim: (text) => setInput(text),
|
|
378
638
|
disabled: loading
|
|
379
639
|
}
|
|
380
640
|
),
|
|
381
|
-
/* @__PURE__ */
|
|
641
|
+
/* @__PURE__ */ jsx5(
|
|
382
642
|
"button",
|
|
383
643
|
{
|
|
384
644
|
className: "hsk-chat-send",
|
|
385
645
|
onClick: handleSend,
|
|
386
646
|
disabled: !input.trim() || loading,
|
|
387
647
|
"aria-label": "Send message",
|
|
388
|
-
children: /* @__PURE__ */
|
|
648
|
+
children: /* @__PURE__ */ jsx5(ArrowUpIcon, {})
|
|
389
649
|
}
|
|
390
650
|
)
|
|
391
651
|
] })
|
|
@@ -395,14 +655,14 @@ function ChatWidget({
|
|
|
395
655
|
}
|
|
396
656
|
|
|
397
657
|
// src/components/KikuButton.tsx
|
|
398
|
-
import { useState as
|
|
658
|
+
import { useState as useState5, useEffect as useEffect3, useRef as useRef5, useCallback as useCallback2 } from "react";
|
|
399
659
|
import { createPortal } from "react-dom";
|
|
400
660
|
import { useKiku as useKiku2 } from "@akropolys/sdk";
|
|
401
661
|
import { usePaymentPolling } from "@akropolys/sdk";
|
|
402
|
-
import { useAkropolysContext as
|
|
662
|
+
import { useAkropolysContext as useAkropolysContext3 } from "@akropolys/sdk";
|
|
403
663
|
|
|
404
664
|
// src/components/ComparisonMatrix.tsx
|
|
405
|
-
import { jsx as
|
|
665
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
406
666
|
function extractSize(p) {
|
|
407
667
|
const name = p.name;
|
|
408
668
|
const cat = (p.category || "").toLowerCase();
|
|
@@ -514,9 +774,9 @@ function buildRows(products, currency) {
|
|
|
514
774
|
}
|
|
515
775
|
function ImageCell({ value, name }) {
|
|
516
776
|
if (!value) {
|
|
517
|
-
return /* @__PURE__ */
|
|
777
|
+
return /* @__PURE__ */ jsx6("div", { style: { fontSize: 28, textAlign: "center" }, children: "\u{1F4E6}" });
|
|
518
778
|
}
|
|
519
|
-
return /* @__PURE__ */
|
|
779
|
+
return /* @__PURE__ */ jsx6(
|
|
520
780
|
"img",
|
|
521
781
|
{
|
|
522
782
|
src: value,
|
|
@@ -533,10 +793,10 @@ function ImageCell({ value, name }) {
|
|
|
533
793
|
);
|
|
534
794
|
}
|
|
535
795
|
function AvailabilityCell({ value }) {
|
|
536
|
-
if (!value) return /* @__PURE__ */
|
|
796
|
+
if (!value) return /* @__PURE__ */ jsx6("span", { style: { color: "#9ca3af" }, children: "\u2014" });
|
|
537
797
|
const inStock = /in.?stock/i.test(value);
|
|
538
|
-
return /* @__PURE__ */
|
|
539
|
-
/* @__PURE__ */
|
|
798
|
+
return /* @__PURE__ */ jsxs5("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--hsk-text, #111827)" }, children: [
|
|
799
|
+
/* @__PURE__ */ jsx6("span", { style: {
|
|
540
800
|
width: 8,
|
|
541
801
|
height: 8,
|
|
542
802
|
borderRadius: "50%",
|
|
@@ -577,7 +837,7 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
|
|
|
577
837
|
display: "flex",
|
|
578
838
|
alignItems: "center"
|
|
579
839
|
};
|
|
580
|
-
return /* @__PURE__ */
|
|
840
|
+
return /* @__PURE__ */ jsxs5(
|
|
581
841
|
"div",
|
|
582
842
|
{
|
|
583
843
|
className: "hsk-compare-matrix",
|
|
@@ -590,9 +850,9 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
|
|
|
590
850
|
fontSize: 13
|
|
591
851
|
},
|
|
592
852
|
children: [
|
|
593
|
-
/* @__PURE__ */
|
|
594
|
-
/* @__PURE__ */
|
|
595
|
-
products.map((p, i) => /* @__PURE__ */
|
|
853
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "grid", gridTemplateColumns: colTemplate, background: "var(--hsk-surface2, #f9fafb)", borderBottom: "2px solid var(--hsk-border, rgba(0,0,0,0.09))" }, children: [
|
|
854
|
+
/* @__PURE__ */ jsx6("div", { style: { ...labelStyle, borderBottom: "none", color: "var(--hsk-text, #111)", fontSize: 12 }, children: "Feature" }),
|
|
855
|
+
products.map((p, i) => /* @__PURE__ */ jsx6(
|
|
596
856
|
"a",
|
|
597
857
|
{
|
|
598
858
|
href: p.url || "#",
|
|
@@ -614,7 +874,7 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
|
|
|
614
874
|
i
|
|
615
875
|
))
|
|
616
876
|
] }),
|
|
617
|
-
rows.map((row, rowIdx) => /* @__PURE__ */
|
|
877
|
+
rows.map((row, rowIdx) => /* @__PURE__ */ jsxs5(
|
|
618
878
|
"div",
|
|
619
879
|
{
|
|
620
880
|
style: {
|
|
@@ -623,17 +883,17 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
|
|
|
623
883
|
background: rowIdx % 2 === 1 ? "var(--hsk-surface2, rgba(0,0,0,0.015))" : "transparent"
|
|
624
884
|
},
|
|
625
885
|
children: [
|
|
626
|
-
/* @__PURE__ */
|
|
886
|
+
/* @__PURE__ */ jsx6("div", { style: labelStyle, children: row.label }),
|
|
627
887
|
products.map((p, i) => {
|
|
628
888
|
const val = row.values[i];
|
|
629
889
|
const isBest = row.bestIdx === i && row.values.filter(Boolean).length > 1;
|
|
630
890
|
if (row.type === "image") {
|
|
631
|
-
return /* @__PURE__ */
|
|
891
|
+
return /* @__PURE__ */ jsx6("div", { style: { ...cellBase, justifyContent: "center", padding: "12px", borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none" }, children: /* @__PURE__ */ jsx6(ImageCell, { value: val, name: p.name }) }, i);
|
|
632
892
|
}
|
|
633
893
|
if (row.type === "availability") {
|
|
634
|
-
return /* @__PURE__ */
|
|
894
|
+
return /* @__PURE__ */ jsx6("div", { style: { ...cellBase, borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none" }, children: /* @__PURE__ */ jsx6(AvailabilityCell, { value: val }) }, i);
|
|
635
895
|
}
|
|
636
|
-
return /* @__PURE__ */
|
|
896
|
+
return /* @__PURE__ */ jsx6(
|
|
637
897
|
"div",
|
|
638
898
|
{
|
|
639
899
|
style: {
|
|
@@ -643,7 +903,7 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
|
|
|
643
903
|
color: isBest ? "var(--hsk-primary, #ea580c)" : row.type === "price" ? "var(--hsk-text, #374151)" : "var(--hsk-text, #111827)",
|
|
644
904
|
borderLeft: i > 0 ? "1px solid var(--hsk-border, rgba(0,0,0,0.07))" : "none"
|
|
645
905
|
},
|
|
646
|
-
children: val ?? /* @__PURE__ */
|
|
906
|
+
children: val ?? /* @__PURE__ */ jsx6("span", { style: { color: "#9ca3af" }, children: "\u2014" })
|
|
647
907
|
},
|
|
648
908
|
i
|
|
649
909
|
);
|
|
@@ -658,8 +918,8 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES" }) {
|
|
|
658
918
|
}
|
|
659
919
|
|
|
660
920
|
// src/components/KikuButton.tsx
|
|
661
|
-
import { Fragment as Fragment3, jsx as
|
|
662
|
-
var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */
|
|
921
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
922
|
+
var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs6(
|
|
663
923
|
"svg",
|
|
664
924
|
{
|
|
665
925
|
className: cn("hsk-brand-a", className),
|
|
@@ -670,7 +930,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
670
930
|
xmlns: "http://www.w3.org/2000/svg",
|
|
671
931
|
"aria-label": "Akropolys",
|
|
672
932
|
children: [
|
|
673
|
-
/* @__PURE__ */
|
|
933
|
+
/* @__PURE__ */ jsx7(
|
|
674
934
|
"path",
|
|
675
935
|
{
|
|
676
936
|
d: "M14.5 4.5 L6.5 25",
|
|
@@ -679,7 +939,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
679
939
|
strokeLinecap: "round"
|
|
680
940
|
}
|
|
681
941
|
),
|
|
682
|
-
/* @__PURE__ */
|
|
942
|
+
/* @__PURE__ */ jsx7(
|
|
683
943
|
"path",
|
|
684
944
|
{
|
|
685
945
|
d: "M14.5 4.5 L22.5 25",
|
|
@@ -688,7 +948,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
688
948
|
strokeLinecap: "round"
|
|
689
949
|
}
|
|
690
950
|
),
|
|
691
|
-
/* @__PURE__ */
|
|
951
|
+
/* @__PURE__ */ jsx7(
|
|
692
952
|
"path",
|
|
693
953
|
{
|
|
694
954
|
d: "M9.5 17 H19.5",
|
|
@@ -697,7 +957,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
697
957
|
strokeLinecap: "round"
|
|
698
958
|
}
|
|
699
959
|
),
|
|
700
|
-
/* @__PURE__ */
|
|
960
|
+
/* @__PURE__ */ jsx7(
|
|
701
961
|
"path",
|
|
702
962
|
{
|
|
703
963
|
d: "M3 25 H10",
|
|
@@ -706,7 +966,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
706
966
|
strokeLinecap: "round"
|
|
707
967
|
}
|
|
708
968
|
),
|
|
709
|
-
/* @__PURE__ */
|
|
969
|
+
/* @__PURE__ */ jsx7(
|
|
710
970
|
"path",
|
|
711
971
|
{
|
|
712
972
|
d: "M19 25 H26",
|
|
@@ -715,7 +975,7 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
715
975
|
strokeLinecap: "round"
|
|
716
976
|
}
|
|
717
977
|
),
|
|
718
|
-
/* @__PURE__ */
|
|
978
|
+
/* @__PURE__ */ jsx7(
|
|
719
979
|
"path",
|
|
720
980
|
{
|
|
721
981
|
d: "M8.5 2.5 C10 2.5, 11 3.5, 11 5 C11 7, 8.5 8.5, 7.5 9.5",
|
|
@@ -730,25 +990,39 @@ var AkropolysAIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs4(
|
|
|
730
990
|
}
|
|
731
991
|
);
|
|
732
992
|
var SparkleIcon2 = AkropolysAIcon;
|
|
733
|
-
var ArrowUpIcon2 = () => /* @__PURE__ */
|
|
734
|
-
/* @__PURE__ */
|
|
735
|
-
/* @__PURE__ */
|
|
993
|
+
var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs6("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
994
|
+
/* @__PURE__ */ jsx7("path", { d: "m5 12 7-7 7 7" }),
|
|
995
|
+
/* @__PURE__ */ jsx7("path", { d: "M12 19V5" })
|
|
736
996
|
] });
|
|
737
|
-
var CloseIcon = () => /* @__PURE__ */
|
|
738
|
-
/* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
997
|
+
var CloseIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
998
|
+
/* @__PURE__ */ jsx7("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
999
|
+
/* @__PURE__ */ jsx7("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
740
1000
|
] });
|
|
741
|
-
var ChevronRightIcon = () => /* @__PURE__ */
|
|
742
|
-
var HistoryIcon = () => /* @__PURE__ */
|
|
743
|
-
/* @__PURE__ */
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
1001
|
+
var ChevronRightIcon = () => /* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "m9 18 6-6-6-6" }) });
|
|
1002
|
+
var HistoryIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1003
|
+
/* @__PURE__ */ jsx7("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
1004
|
+
/* @__PURE__ */ jsx7("path", { d: "M3 3v5h5" }),
|
|
1005
|
+
/* @__PURE__ */ jsx7("path", { d: "M12 7v5l4 2" })
|
|
746
1006
|
] });
|
|
747
|
-
var NewChatIcon = () => /* @__PURE__ */
|
|
748
|
-
var ShoppingBagIcon = () => /* @__PURE__ */
|
|
749
|
-
/* @__PURE__ */
|
|
750
|
-
/* @__PURE__ */
|
|
751
|
-
/* @__PURE__ */
|
|
1007
|
+
var NewChatIcon = () => /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "M12 5v14M5 12h14" }) });
|
|
1008
|
+
var ShoppingBagIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1009
|
+
/* @__PURE__ */ jsx7("path", { d: "M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z" }),
|
|
1010
|
+
/* @__PURE__ */ jsx7("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
1011
|
+
/* @__PURE__ */ jsx7("path", { d: "M16 10a4 4 0 0 1-8 0" })
|
|
1012
|
+
] });
|
|
1013
|
+
var PaperclipIcon = () => /* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
|
|
1014
|
+
var MicIcon2 = () => /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1015
|
+
/* @__PURE__ */ jsx7("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
|
|
1016
|
+
/* @__PURE__ */ jsx7("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
1017
|
+
/* @__PURE__ */ jsx7("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
|
|
1018
|
+
] });
|
|
1019
|
+
var MicOffIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1020
|
+
/* @__PURE__ */ jsx7("line", { x1: "2", y1: "2", x2: "22", y2: "22" }),
|
|
1021
|
+
/* @__PURE__ */ jsx7("path", { d: "M18.89 13.23A7.12 7.12 0 0 0 19 12v-2" }),
|
|
1022
|
+
/* @__PURE__ */ jsx7("path", { d: "M5 10v2a7 7 0 0 0 12 5" }),
|
|
1023
|
+
/* @__PURE__ */ jsx7("path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33" }),
|
|
1024
|
+
/* @__PURE__ */ jsx7("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
|
|
1025
|
+
/* @__PURE__ */ jsx7("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
|
|
752
1026
|
] });
|
|
753
1027
|
var DEFAULT_CHIPS = [
|
|
754
1028
|
"Cheapest smartphone",
|
|
@@ -788,25 +1062,25 @@ function CartContextCard({ cart, defaultCurrency }) {
|
|
|
788
1062
|
if (!cart.items || cart.items.length === 0) return null;
|
|
789
1063
|
const currency = cart.currency || defaultCurrency;
|
|
790
1064
|
const total = cart.total ?? cart.items.reduce((s, i) => s + i.price_numeric * i.quantity, 0);
|
|
791
|
-
return /* @__PURE__ */
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
794
|
-
/* @__PURE__ */
|
|
1065
|
+
return /* @__PURE__ */ jsxs6("div", { className: "hsk-cart-card", children: [
|
|
1066
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cart-card-header", children: [
|
|
1067
|
+
/* @__PURE__ */ jsx7(ShoppingBagIcon, {}),
|
|
1068
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
795
1069
|
"Your cart \xB7 ",
|
|
796
1070
|
cart.item_count ?? cart.items.length,
|
|
797
1071
|
" item",
|
|
798
1072
|
(cart.item_count ?? cart.items.length) !== 1 ? "s" : ""
|
|
799
1073
|
] })
|
|
800
1074
|
] }),
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
item.image ? /* @__PURE__ */
|
|
804
|
-
item.quantity > 1 && /* @__PURE__ */
|
|
1075
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ jsxs6("div", { className: "hsk-cart-item", children: [
|
|
1076
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cart-item-img-wrap", children: [
|
|
1077
|
+
item.image ? /* @__PURE__ */ jsx7("img", { className: "hsk-cart-item-img", src: item.image, alt: item.name, loading: "lazy" }) : /* @__PURE__ */ jsx7("div", { className: "hsk-cart-item-img-placeholder", children: /* @__PURE__ */ jsx7(ShoppingBagIcon, {}) }),
|
|
1078
|
+
item.quantity > 1 && /* @__PURE__ */ jsx7("span", { className: "hsk-cart-item-qty", children: item.quantity })
|
|
805
1079
|
] }),
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
/* @__PURE__ */
|
|
808
|
-
/* @__PURE__ */
|
|
809
|
-
item.quantity > 1 && /* @__PURE__ */
|
|
1080
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cart-item-info", children: [
|
|
1081
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cart-item-name", children: item.name }),
|
|
1082
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cart-item-price", children: [
|
|
1083
|
+
item.quantity > 1 && /* @__PURE__ */ jsxs6("span", { className: "hsk-cart-item-qty-label", children: [
|
|
810
1084
|
item.quantity,
|
|
811
1085
|
"\xD7 "
|
|
812
1086
|
] }),
|
|
@@ -816,9 +1090,9 @@ function CartContextCard({ cart, defaultCurrency }) {
|
|
|
816
1090
|
] })
|
|
817
1091
|
] })
|
|
818
1092
|
] }, item.id)) }),
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
/* @__PURE__ */
|
|
821
|
-
/* @__PURE__ */
|
|
1093
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cart-total", children: [
|
|
1094
|
+
/* @__PURE__ */ jsx7("span", { children: "Total" }),
|
|
1095
|
+
/* @__PURE__ */ jsxs6("span", { className: "hsk-cart-total-amount", children: [
|
|
822
1096
|
currency,
|
|
823
1097
|
" ",
|
|
824
1098
|
total.toLocaleString()
|
|
@@ -850,14 +1124,14 @@ function ActionPills({ cart, actionType, onSend, loading }) {
|
|
|
850
1124
|
}
|
|
851
1125
|
}
|
|
852
1126
|
if (pills.length === 0) return null;
|
|
853
|
-
return /* @__PURE__ */
|
|
1127
|
+
return /* @__PURE__ */ jsx7("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ jsxs6(
|
|
854
1128
|
"button",
|
|
855
1129
|
{
|
|
856
1130
|
className: "hsk-action-pill",
|
|
857
1131
|
onClick: () => onSend(pill.query),
|
|
858
1132
|
disabled: loading,
|
|
859
1133
|
children: [
|
|
860
|
-
/* @__PURE__ */
|
|
1134
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-pill-emoji", children: pill.emoji }),
|
|
861
1135
|
pill.label
|
|
862
1136
|
]
|
|
863
1137
|
},
|
|
@@ -865,11 +1139,11 @@ function ActionPills({ cart, actionType, onSend, loading }) {
|
|
|
865
1139
|
)) });
|
|
866
1140
|
}
|
|
867
1141
|
function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
868
|
-
const client =
|
|
1142
|
+
const client = useAkropolysContext3();
|
|
869
1143
|
const isProperty = client?.vertical === "property";
|
|
870
|
-
const railRef =
|
|
871
|
-
const [showNext, setShowNext] =
|
|
872
|
-
const measure =
|
|
1144
|
+
const railRef = useRef5(null);
|
|
1145
|
+
const [showNext, setShowNext] = useState5(false);
|
|
1146
|
+
const measure = useCallback2(() => {
|
|
873
1147
|
const el = railRef.current;
|
|
874
1148
|
if (!el) return;
|
|
875
1149
|
const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;
|
|
@@ -890,17 +1164,17 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
|
890
1164
|
const scrollNext = () => {
|
|
891
1165
|
railRef.current?.scrollBy({ left: 170, behavior: "smooth" });
|
|
892
1166
|
};
|
|
893
|
-
return /* @__PURE__ */
|
|
894
|
-
/* @__PURE__ */
|
|
1167
|
+
return /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-sources-wrap", children: [
|
|
1168
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-sources", ref: railRef, children: sources.map((src, si) => /* @__PURE__ */ jsxs6(
|
|
895
1169
|
"div",
|
|
896
1170
|
{
|
|
897
1171
|
className: "hsk-cb-source",
|
|
898
1172
|
style: { animationDelay: `${si * 50}ms` },
|
|
899
1173
|
onClick: () => onSelectSource?.(src),
|
|
900
1174
|
children: [
|
|
901
|
-
src.image ? /* @__PURE__ */
|
|
902
|
-
/* @__PURE__ */
|
|
903
|
-
isProperty && /* @__PURE__ */
|
|
1175
|
+
src.image ? /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-src-imgwrap", style: { position: "relative" }, children: [
|
|
1176
|
+
/* @__PURE__ */ jsx7("img", { src: src.image, alt: src.name, loading: "lazy" }),
|
|
1177
|
+
isProperty && /* @__PURE__ */ jsx7("div", { style: {
|
|
904
1178
|
position: "absolute",
|
|
905
1179
|
top: "6px",
|
|
906
1180
|
right: "6px",
|
|
@@ -915,11 +1189,11 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
|
915
1189
|
color: "#fbbf24",
|
|
916
1190
|
// Gold sparkle badge
|
|
917
1191
|
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
918
|
-
}, children: /* @__PURE__ */
|
|
919
|
-
] }) : /* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
src.price && /* @__PURE__ */
|
|
1192
|
+
}, children: /* @__PURE__ */ jsx7(SparkleIcon2, { size: 12 }) })
|
|
1193
|
+
] }) : /* @__PURE__ */ jsx7("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1194
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-src-info", children: [
|
|
1195
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-src-name", children: src.name }),
|
|
1196
|
+
src.price && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-src-price", children: [
|
|
923
1197
|
src.currency ?? defaultCurrency,
|
|
924
1198
|
" ",
|
|
925
1199
|
parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -929,15 +1203,15 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
|
929
1203
|
},
|
|
930
1204
|
si
|
|
931
1205
|
)) }),
|
|
932
|
-
showNext && /* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
1206
|
+
showNext && /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1207
|
+
/* @__PURE__ */ jsx7(
|
|
934
1208
|
"div",
|
|
935
1209
|
{
|
|
936
1210
|
className: "hsk-cb-sources-fade",
|
|
937
1211
|
style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
|
|
938
1212
|
}
|
|
939
1213
|
),
|
|
940
|
-
/* @__PURE__ */
|
|
1214
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ jsx7(ChevronRightIcon, {}) })
|
|
941
1215
|
] })
|
|
942
1216
|
] });
|
|
943
1217
|
}
|
|
@@ -956,7 +1230,7 @@ function SmartContextPills({
|
|
|
956
1230
|
onSend,
|
|
957
1231
|
loading
|
|
958
1232
|
}) {
|
|
959
|
-
const client =
|
|
1233
|
+
const client = useAkropolysContext3();
|
|
960
1234
|
const isProperty = client?.vertical === "property";
|
|
961
1235
|
if (!intent) return null;
|
|
962
1236
|
const pills = [];
|
|
@@ -1025,14 +1299,14 @@ function SmartContextPills({
|
|
|
1025
1299
|
pills.push({ emoji: "\u{1F4A1}", label: "Recommend something", query: "What do you recommend for me?" });
|
|
1026
1300
|
}
|
|
1027
1301
|
if (pills.length === 0) return null;
|
|
1028
|
-
return /* @__PURE__ */
|
|
1302
|
+
return /* @__PURE__ */ jsx7("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ jsxs6(
|
|
1029
1303
|
"button",
|
|
1030
1304
|
{
|
|
1031
1305
|
className: "hsk-action-pill",
|
|
1032
1306
|
onClick: () => onSend(pill.query),
|
|
1033
1307
|
disabled: loading,
|
|
1034
1308
|
children: [
|
|
1035
|
-
/* @__PURE__ */
|
|
1309
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-pill-emoji", children: pill.emoji }),
|
|
1036
1310
|
pill.label
|
|
1037
1311
|
]
|
|
1038
1312
|
},
|
|
@@ -1091,12 +1365,66 @@ function ChatModal({
|
|
|
1091
1365
|
defaultCurrency = "KES",
|
|
1092
1366
|
chips = DEFAULT_CHIPS,
|
|
1093
1367
|
theme,
|
|
1094
|
-
classNames = {}
|
|
1368
|
+
classNames = {},
|
|
1369
|
+
enableVoice = false,
|
|
1370
|
+
enableVision = false,
|
|
1371
|
+
visionCategoryHint
|
|
1095
1372
|
}) {
|
|
1096
|
-
const client =
|
|
1373
|
+
const client = useAkropolysContext3();
|
|
1097
1374
|
const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset } = useKiku2();
|
|
1098
|
-
const [input, setInput] =
|
|
1099
|
-
const [loadingMessageIndex, setLoadingMessageIndex] =
|
|
1375
|
+
const [input, setInput] = useState5("");
|
|
1376
|
+
const [loadingMessageIndex, setLoadingMessageIndex] = useState5(0);
|
|
1377
|
+
const [attachments, setAttachments] = useState5([]);
|
|
1378
|
+
const imageInputRef = useRef5(null);
|
|
1379
|
+
const handleImageFiles = (files) => {
|
|
1380
|
+
if (!files || files.length === 0) return;
|
|
1381
|
+
Array.from(files).forEach((file) => {
|
|
1382
|
+
if (!file.type.startsWith("image/")) return;
|
|
1383
|
+
const reader = new FileReader();
|
|
1384
|
+
reader.onload = (e) => {
|
|
1385
|
+
const dataUrl = e.target?.result;
|
|
1386
|
+
if (dataUrl) {
|
|
1387
|
+
setAttachments((prev) => [...prev, { type: "image", data: dataUrl }]);
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
reader.readAsDataURL(file);
|
|
1391
|
+
});
|
|
1392
|
+
};
|
|
1393
|
+
const removeAttachment = (idx) => {
|
|
1394
|
+
setAttachments((prev) => prev.filter((_, i) => i !== idx));
|
|
1395
|
+
};
|
|
1396
|
+
const [voiceState, setVoiceState] = useState5("idle");
|
|
1397
|
+
const recognitionRef = useRef5(null);
|
|
1398
|
+
const pendingVoiceRef = useRef5(null);
|
|
1399
|
+
const hasSpeechAPI = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
|
|
1400
|
+
const startVoice = useCallback2(() => {
|
|
1401
|
+
if (!hasSpeechAPI || voiceState !== "idle") return;
|
|
1402
|
+
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
1403
|
+
const recognition = new SR();
|
|
1404
|
+
recognition.lang = "en-US";
|
|
1405
|
+
recognition.interimResults = false;
|
|
1406
|
+
recognition.maxAlternatives = 1;
|
|
1407
|
+
recognitionRef.current = recognition;
|
|
1408
|
+
recognition.onstart = () => setVoiceState("listening");
|
|
1409
|
+
recognition.onresult = (event) => {
|
|
1410
|
+
const transcript = event.results[0][0].transcript;
|
|
1411
|
+
setInput(transcript);
|
|
1412
|
+
pendingVoiceRef.current = transcript;
|
|
1413
|
+
setVoiceState("processing");
|
|
1414
|
+
};
|
|
1415
|
+
recognition.onerror = () => setVoiceState("idle");
|
|
1416
|
+
recognition.onend = () => {
|
|
1417
|
+
setVoiceState((prev) => prev === "listening" ? "idle" : prev);
|
|
1418
|
+
};
|
|
1419
|
+
recognition.start();
|
|
1420
|
+
}, [hasSpeechAPI, voiceState]);
|
|
1421
|
+
const stopVoice = useCallback2(() => {
|
|
1422
|
+
recognitionRef.current?.stop();
|
|
1423
|
+
setVoiceState("idle");
|
|
1424
|
+
}, []);
|
|
1425
|
+
useEffect3(() => {
|
|
1426
|
+
return () => recognitionRef.current?.abort();
|
|
1427
|
+
}, []);
|
|
1100
1428
|
const isProperty = client.vertical === "property";
|
|
1101
1429
|
const activeChips = chips === DEFAULT_CHIPS && isProperty ? PROPERTY_CHIPS : chips;
|
|
1102
1430
|
const activeTitle = title === "Shopping Assistant" && isProperty ? "Property Assistant" : title;
|
|
@@ -1111,20 +1439,20 @@ function ChatModal({
|
|
|
1111
1439
|
setLoadingMessageIndex(0);
|
|
1112
1440
|
}
|
|
1113
1441
|
}, [loading, streaming]);
|
|
1114
|
-
const [selectedProduct, setSelectedProduct] =
|
|
1115
|
-
const bottomRef =
|
|
1116
|
-
const textareaRef =
|
|
1117
|
-
const [phoneInput, setPhoneInput] =
|
|
1442
|
+
const [selectedProduct, setSelectedProduct] = useState5(null);
|
|
1443
|
+
const bottomRef = useRef5(null);
|
|
1444
|
+
const textareaRef = useRef5(null);
|
|
1445
|
+
const [phoneInput, setPhoneInput] = useState5(() => {
|
|
1118
1446
|
if (typeof window !== "undefined") {
|
|
1119
1447
|
return localStorage.getItem("akropolys_user_phone") || "";
|
|
1120
1448
|
}
|
|
1121
1449
|
return "";
|
|
1122
1450
|
});
|
|
1123
|
-
const [merchantRef, setMerchantRef] =
|
|
1124
|
-
const [paymentPhase, setPaymentPhase] =
|
|
1125
|
-
const [sessions, setSessions] =
|
|
1126
|
-
const [sidebarOpen, setSidebarOpen] =
|
|
1127
|
-
const [replayMessages, setReplayMessages] =
|
|
1451
|
+
const [merchantRef, setMerchantRef] = useState5(null);
|
|
1452
|
+
const [paymentPhase, setPaymentPhase] = useState5("idle");
|
|
1453
|
+
const [sessions, setSessions] = useState5(() => loadSessions());
|
|
1454
|
+
const [sidebarOpen, setSidebarOpen] = useState5(false);
|
|
1455
|
+
const [replayMessages, setReplayMessages] = useState5(null);
|
|
1128
1456
|
const { status: pollStatus } = usePaymentPolling({
|
|
1129
1457
|
client: client.api,
|
|
1130
1458
|
merchantReference: merchantRef,
|
|
@@ -1178,7 +1506,7 @@ function ChatModal({
|
|
|
1178
1506
|
setPaymentPhase("failed");
|
|
1179
1507
|
}
|
|
1180
1508
|
};
|
|
1181
|
-
const msgsContainerRef =
|
|
1509
|
+
const msgsContainerRef = useRef5(null);
|
|
1182
1510
|
useEffect3(() => {
|
|
1183
1511
|
const container = msgsContainerRef.current;
|
|
1184
1512
|
if (!container) return;
|
|
@@ -1194,7 +1522,7 @@ function ChatModal({
|
|
|
1194
1522
|
document.addEventListener("keydown", h);
|
|
1195
1523
|
return () => document.removeEventListener("keydown", h);
|
|
1196
1524
|
}, []);
|
|
1197
|
-
const saveCurrentSession =
|
|
1525
|
+
const saveCurrentSession = useCallback2(() => {
|
|
1198
1526
|
if (messages.length < 2) return;
|
|
1199
1527
|
const firstUser = messages.find((m) => m.role === "user");
|
|
1200
1528
|
const session = {
|
|
@@ -1207,7 +1535,7 @@ function ChatModal({
|
|
|
1207
1535
|
setSessions(updated);
|
|
1208
1536
|
saveSessions(updated);
|
|
1209
1537
|
}, [messages, sessions]);
|
|
1210
|
-
const handleReset =
|
|
1538
|
+
const handleReset = useCallback2(() => {
|
|
1211
1539
|
saveCurrentSession();
|
|
1212
1540
|
reset();
|
|
1213
1541
|
setReplayMessages(null);
|
|
@@ -1220,7 +1548,7 @@ function ChatModal({
|
|
|
1220
1548
|
const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ""} \u2014 what are its key specs, who is it best for, and is it worth buying?`;
|
|
1221
1549
|
send(q);
|
|
1222
1550
|
};
|
|
1223
|
-
const handleSend = async (text) => {
|
|
1551
|
+
const handleSend = async (text, extraAttachments) => {
|
|
1224
1552
|
const q = (text ?? input).trim();
|
|
1225
1553
|
if (!q || loading) return;
|
|
1226
1554
|
setReplayMessages(null);
|
|
@@ -1229,7 +1557,9 @@ function ChatModal({
|
|
|
1229
1557
|
if (textareaRef.current) {
|
|
1230
1558
|
textareaRef.current.style.height = "auto";
|
|
1231
1559
|
}
|
|
1232
|
-
|
|
1560
|
+
const toSend = extraAttachments ?? attachments;
|
|
1561
|
+
setAttachments([]);
|
|
1562
|
+
await send(q, void 0, toSend.length > 0 ? toSend : void 0);
|
|
1233
1563
|
};
|
|
1234
1564
|
const handleKeyDown = (e) => {
|
|
1235
1565
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
@@ -1243,6 +1573,20 @@ function ChatModal({
|
|
|
1243
1573
|
t.style.height = "auto";
|
|
1244
1574
|
t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
|
|
1245
1575
|
};
|
|
1576
|
+
useEffect3(() => {
|
|
1577
|
+
if (voiceState !== "processing") return;
|
|
1578
|
+
const transcript = pendingVoiceRef.current;
|
|
1579
|
+
if (!transcript) {
|
|
1580
|
+
setVoiceState("idle");
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
pendingVoiceRef.current = null;
|
|
1584
|
+
const timer = setTimeout(() => {
|
|
1585
|
+
setVoiceState("idle");
|
|
1586
|
+
handleSend(transcript);
|
|
1587
|
+
}, 400);
|
|
1588
|
+
return () => clearTimeout(timer);
|
|
1589
|
+
}, [voiceState]);
|
|
1246
1590
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "20px";
|
|
1247
1591
|
const displayMessages = replayMessages ?? messages;
|
|
1248
1592
|
const loadSession = (session) => {
|
|
@@ -1255,7 +1599,7 @@ function ChatModal({
|
|
|
1255
1599
|
setSessions(updated);
|
|
1256
1600
|
saveSessions(updated);
|
|
1257
1601
|
};
|
|
1258
|
-
return /* @__PURE__ */
|
|
1602
|
+
return /* @__PURE__ */ jsx7(
|
|
1259
1603
|
"div",
|
|
1260
1604
|
{
|
|
1261
1605
|
className: cn("hsk-cb-overlay", classNames.overlay),
|
|
@@ -1267,27 +1611,27 @@ function ChatModal({
|
|
|
1267
1611
|
...backdropColor ? { background: backdropColor } : {},
|
|
1268
1612
|
...customStyles
|
|
1269
1613
|
},
|
|
1270
|
-
children: /* @__PURE__ */
|
|
1271
|
-
/* @__PURE__ */
|
|
1272
|
-
/* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
1274
|
-
/* @__PURE__ */
|
|
1614
|
+
children: /* @__PURE__ */ jsxs6("div", { className: cn("hsk-cb-panel hsk-cb-panel--with-sidebar", classNames.panel), onClick: (e) => e.stopPropagation(), children: [
|
|
1615
|
+
/* @__PURE__ */ jsxs6("div", { className: cn("hsk-cb-sidebar", sidebarOpen && "hsk-cb-sidebar--open"), children: [
|
|
1616
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-sidebar-header", children: [
|
|
1617
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-cb-sidebar-title", children: "History" }),
|
|
1618
|
+
/* @__PURE__ */ jsxs6(
|
|
1275
1619
|
"button",
|
|
1276
1620
|
{
|
|
1277
1621
|
className: "hsk-cb-sidebar-new",
|
|
1278
1622
|
onClick: handleReset,
|
|
1279
1623
|
title: "New chat",
|
|
1280
1624
|
children: [
|
|
1281
|
-
/* @__PURE__ */
|
|
1282
|
-
/* @__PURE__ */
|
|
1625
|
+
/* @__PURE__ */ jsx7(NewChatIcon, {}),
|
|
1626
|
+
/* @__PURE__ */ jsx7("span", { children: "New chat" })
|
|
1283
1627
|
]
|
|
1284
1628
|
}
|
|
1285
1629
|
)
|
|
1286
1630
|
] }),
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
1289
|
-
/* @__PURE__ */
|
|
1290
|
-
] }) : sessions.map((session) => /* @__PURE__ */
|
|
1631
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-sidebar-list", children: sessions.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-sidebar-empty", children: [
|
|
1632
|
+
/* @__PURE__ */ jsx7(HistoryIcon, {}),
|
|
1633
|
+
/* @__PURE__ */ jsx7("span", { children: "No history yet" })
|
|
1634
|
+
] }) : sessions.map((session) => /* @__PURE__ */ jsxs6(
|
|
1291
1635
|
"div",
|
|
1292
1636
|
{
|
|
1293
1637
|
className: cn(
|
|
@@ -1296,9 +1640,9 @@ function ChatModal({
|
|
|
1296
1640
|
),
|
|
1297
1641
|
onClick: () => loadSession(session),
|
|
1298
1642
|
children: [
|
|
1299
|
-
/* @__PURE__ */
|
|
1300
|
-
/* @__PURE__ */
|
|
1301
|
-
/* @__PURE__ */
|
|
1643
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-sidebar-session-title", children: session.title }),
|
|
1644
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-sidebar-session-meta", children: relativeTime(session.ts) }),
|
|
1645
|
+
/* @__PURE__ */ jsx7(
|
|
1302
1646
|
"button",
|
|
1303
1647
|
{
|
|
1304
1648
|
className: "hsk-cb-sidebar-session-del",
|
|
@@ -1312,10 +1656,10 @@ function ChatModal({
|
|
|
1312
1656
|
session.id
|
|
1313
1657
|
)) })
|
|
1314
1658
|
] }),
|
|
1315
|
-
/* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1317
|
-
/* @__PURE__ */
|
|
1318
|
-
/* @__PURE__ */
|
|
1659
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-main", children: [
|
|
1660
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-topbar", children: [
|
|
1661
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-topbar-left", children: [
|
|
1662
|
+
/* @__PURE__ */ jsx7(
|
|
1319
1663
|
"button",
|
|
1320
1664
|
{
|
|
1321
1665
|
className: cn("hsk-cb-sidebar-toggle", sidebarOpen && "hsk-cb-sidebar-toggle--active"),
|
|
@@ -1324,29 +1668,29 @@ function ChatModal({
|
|
|
1324
1668
|
setSidebarOpen((v) => !v);
|
|
1325
1669
|
},
|
|
1326
1670
|
"aria-label": "Toggle history",
|
|
1327
|
-
children: /* @__PURE__ */
|
|
1671
|
+
children: /* @__PURE__ */ jsx7(HistoryIcon, {})
|
|
1328
1672
|
}
|
|
1329
1673
|
),
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
/* @__PURE__ */
|
|
1674
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1675
|
+
/* @__PURE__ */ jsx7("div", { children: /* @__PURE__ */ jsx7("div", { className: "hsk-cb-topbar-title", children: activeTitle }) })
|
|
1332
1676
|
] }),
|
|
1333
|
-
/* @__PURE__ */
|
|
1334
|
-
replayMessages ? /* @__PURE__ */
|
|
1677
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-topbar-actions", children: [
|
|
1678
|
+
replayMessages ? /* @__PURE__ */ jsx7("button", { className: "hsk-cb-topbar-btn", onClick: () => {
|
|
1335
1679
|
setReplayMessages(null);
|
|
1336
|
-
}, children: "\u2190 Live chat" }) : messages.length > 0 && /* @__PURE__ */
|
|
1337
|
-
/* @__PURE__ */
|
|
1680
|
+
}, children: "\u2190 Live chat" }) : messages.length > 0 && /* @__PURE__ */ jsx7("button", { className: "hsk-cb-topbar-btn", onClick: handleReset, children: "Clear chat" }),
|
|
1681
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx7(CloseIcon, {}) })
|
|
1338
1682
|
] })
|
|
1339
1683
|
] }),
|
|
1340
|
-
replayMessages && /* @__PURE__ */
|
|
1341
|
-
/* @__PURE__ */
|
|
1342
|
-
/* @__PURE__ */
|
|
1343
|
-
/* @__PURE__ */
|
|
1684
|
+
replayMessages && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-replay-banner", children: [
|
|
1685
|
+
/* @__PURE__ */ jsx7(HistoryIcon, {}),
|
|
1686
|
+
/* @__PURE__ */ jsx7("span", { children: "You're viewing a past conversation." }),
|
|
1687
|
+
/* @__PURE__ */ jsx7("button", { onClick: () => setReplayMessages(null), children: "Back to chat \u2192" })
|
|
1344
1688
|
] }),
|
|
1345
|
-
/* @__PURE__ */
|
|
1346
|
-
displayMessages.length === 0 ? /* @__PURE__ */
|
|
1347
|
-
/* @__PURE__ */
|
|
1348
|
-
/* @__PURE__ */
|
|
1349
|
-
/* @__PURE__ */
|
|
1689
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-msgs", ref: msgsContainerRef, children: [
|
|
1690
|
+
displayMessages.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-empty", children: [
|
|
1691
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1692
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-empty-title", children: "Find exactly what you need" }),
|
|
1693
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ jsx7(
|
|
1350
1694
|
"button",
|
|
1351
1695
|
{
|
|
1352
1696
|
className: "hsk-cb-chip",
|
|
@@ -1359,12 +1703,15 @@ function ChatModal({
|
|
|
1359
1703
|
const isLast = idx === displayMessages.length - 1 && !replayMessages;
|
|
1360
1704
|
const isUser = msg.role === "user";
|
|
1361
1705
|
const displayContent = !isUser && isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages ? stripMarkdownTables(msg.content) : msg.content;
|
|
1362
|
-
return /* @__PURE__ */
|
|
1363
|
-
/* @__PURE__ */
|
|
1364
|
-
/* @__PURE__ */
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1706
|
+
return /* @__PURE__ */ jsx7("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-user-msg", children: [
|
|
1707
|
+
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-user-imgs", children: msg.images.map((img, i) => /* @__PURE__ */ jsx7("img", { src: img, alt: `attachment ${i + 1}`, className: "hsk-cb-user-img-thumb" }, i)) }),
|
|
1708
|
+
msg.content && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-user-bubble", children: msg.content })
|
|
1709
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-msg", children: [
|
|
1710
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1711
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-body", children: [
|
|
1712
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-text", children: renderMarkdown(displayContent) }),
|
|
1713
|
+
isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages && /* @__PURE__ */ jsx7(ComparisonMatrix, { sources, defaultCurrency }),
|
|
1714
|
+
isLast && sources.length > 0 && lastIntent !== "compare" && lastAction?.type !== "request_phone" && lastAction?.type !== "awaiting_payment" && lastAction?.type !== "checkout" && !msg.cartSnapshot && /* @__PURE__ */ jsx7(
|
|
1368
1715
|
SourcesCarousel,
|
|
1369
1716
|
{
|
|
1370
1717
|
sources,
|
|
@@ -1372,14 +1719,14 @@ function ChatModal({
|
|
|
1372
1719
|
onSelectSource: handleSourceClick
|
|
1373
1720
|
}
|
|
1374
1721
|
),
|
|
1375
|
-
msg.cartSnapshot && msg.cartSnapshot.items?.length > 0 && /* @__PURE__ */
|
|
1722
|
+
msg.cartSnapshot && msg.cartSnapshot.items?.length > 0 && /* @__PURE__ */ jsx7(
|
|
1376
1723
|
CartContextCard,
|
|
1377
1724
|
{
|
|
1378
1725
|
cart: msg.cartSnapshot,
|
|
1379
1726
|
defaultCurrency
|
|
1380
1727
|
}
|
|
1381
1728
|
),
|
|
1382
|
-
isLast && msg.cartSnapshot && !loading && /* @__PURE__ */
|
|
1729
|
+
isLast && msg.cartSnapshot && !loading && /* @__PURE__ */ jsx7(
|
|
1383
1730
|
ActionPills,
|
|
1384
1731
|
{
|
|
1385
1732
|
cart: msg.cartSnapshot,
|
|
@@ -1388,7 +1735,7 @@ function ChatModal({
|
|
|
1388
1735
|
loading
|
|
1389
1736
|
}
|
|
1390
1737
|
),
|
|
1391
|
-
isLast && !loading && !msg.cartSnapshot && !replayMessages && /* @__PURE__ */
|
|
1738
|
+
isLast && !loading && !msg.cartSnapshot && !replayMessages && /* @__PURE__ */ jsx7(
|
|
1392
1739
|
SmartContextPills,
|
|
1393
1740
|
{
|
|
1394
1741
|
intent: lastIntent,
|
|
@@ -1400,16 +1747,16 @@ function ChatModal({
|
|
|
1400
1747
|
] })
|
|
1401
1748
|
] }) }, idx);
|
|
1402
1749
|
}),
|
|
1403
|
-
selectedProduct && loading && /* @__PURE__ */
|
|
1750
|
+
selectedProduct && loading && /* @__PURE__ */ jsxs6(
|
|
1404
1751
|
"div",
|
|
1405
1752
|
{
|
|
1406
1753
|
className: "hsk-cb-selected-product",
|
|
1407
1754
|
onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
|
|
1408
1755
|
children: [
|
|
1409
|
-
selectedProduct.image && /* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
/* @__PURE__ */
|
|
1412
|
-
selectedProduct.price && /* @__PURE__ */
|
|
1756
|
+
selectedProduct.image && /* @__PURE__ */ jsx7("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
|
|
1757
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-selected-info", children: [
|
|
1758
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
|
|
1759
|
+
selectedProduct.price && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-selected-price", children: [
|
|
1413
1760
|
selectedProduct.currency ?? defaultCurrency,
|
|
1414
1761
|
" ",
|
|
1415
1762
|
parseFloat(String(selectedProduct.price ?? "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -1418,34 +1765,34 @@ function ChatModal({
|
|
|
1418
1765
|
]
|
|
1419
1766
|
}
|
|
1420
1767
|
),
|
|
1421
|
-
loading && !streaming && /* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1424
|
-
/* @__PURE__ */
|
|
1768
|
+
loading && !streaming && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-typing-row", style: { display: "flex", alignItems: "flex-start", gap: "10px" }, children: [
|
|
1769
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center", marginTop: "4px" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1770
|
+
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
|
|
1771
|
+
/* @__PURE__ */ jsx7("style", { children: `
|
|
1425
1772
|
@keyframes hsk-pulse {
|
|
1426
1773
|
0%, 100% { opacity: 0.6; }
|
|
1427
1774
|
50% { opacity: 1; }
|
|
1428
1775
|
}
|
|
1429
1776
|
` }),
|
|
1430
|
-
/* @__PURE__ */
|
|
1431
|
-
/* @__PURE__ */
|
|
1432
|
-
/* @__PURE__ */
|
|
1433
|
-
/* @__PURE__ */
|
|
1434
|
-
/* @__PURE__ */
|
|
1777
|
+
/* @__PURE__ */ jsx7("div", { style: { fontSize: "0.85rem", color: "#6b7280", fontStyle: "italic", animation: "hsk-pulse 1.5s infinite ease-in-out" }, children: LOADING_MESSAGES[loadingMessageIndex] }),
|
|
1778
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-typing", style: { margin: 0, alignSelf: "flex-start" }, children: [
|
|
1779
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-dot" }),
|
|
1780
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-dot" }),
|
|
1781
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-dot" })
|
|
1435
1782
|
] })
|
|
1436
1783
|
] })
|
|
1437
1784
|
] }),
|
|
1438
|
-
error && /* @__PURE__ */
|
|
1785
|
+
error && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
|
|
1439
1786
|
!replayMessages && paymentPhase === "prompt_phone" && (() => {
|
|
1440
1787
|
const isHistoryIntent = lastIntent === "capture" || lastIntent === "delete" || lastIntent === "view_history";
|
|
1441
1788
|
if (isHistoryIntent) {
|
|
1442
1789
|
return null;
|
|
1443
1790
|
}
|
|
1444
|
-
return /* @__PURE__ */
|
|
1445
|
-
/* @__PURE__ */
|
|
1446
|
-
/* @__PURE__ */
|
|
1447
|
-
/* @__PURE__ */
|
|
1448
|
-
/* @__PURE__ */
|
|
1791
|
+
return /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-msg", children: [
|
|
1792
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1793
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-phone-form", children: [
|
|
1794
|
+
/* @__PURE__ */ jsx7("label", { className: "hsk-cb-phone-label", children: "Enter your M-Pesa number to pay" }),
|
|
1795
|
+
/* @__PURE__ */ jsx7(
|
|
1449
1796
|
"input",
|
|
1450
1797
|
{
|
|
1451
1798
|
type: "tel",
|
|
@@ -1457,37 +1804,37 @@ function ChatModal({
|
|
|
1457
1804
|
autoFocus: true
|
|
1458
1805
|
}
|
|
1459
1806
|
),
|
|
1460
|
-
/* @__PURE__ */
|
|
1807
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-cb-phone-submit", onClick: handlePhoneSubmit, children: "Send STK push" })
|
|
1461
1808
|
] }) }) })
|
|
1462
1809
|
] });
|
|
1463
1810
|
})(),
|
|
1464
|
-
!replayMessages && paymentPhase === "awaiting" && /* @__PURE__ */
|
|
1465
|
-
/* @__PURE__ */
|
|
1466
|
-
/* @__PURE__ */
|
|
1467
|
-
/* @__PURE__ */
|
|
1468
|
-
/* @__PURE__ */
|
|
1811
|
+
!replayMessages && paymentPhase === "awaiting" && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--awaiting", children: [
|
|
1812
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-payment-pulse-ring" }),
|
|
1813
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ jsx7("span", { style: { fontSize: "2rem" }, children: "\u{1F4F1}" }) }),
|
|
1814
|
+
/* @__PURE__ */ jsx7("p", { className: "hsk-cb-payment-label", style: { fontWeight: 600 }, children: "Check your phone" }),
|
|
1815
|
+
/* @__PURE__ */ jsxs6("p", { className: "hsk-cb-payment-sub", children: [
|
|
1469
1816
|
"An M-Pesa STK push has been sent.",
|
|
1470
|
-
/* @__PURE__ */
|
|
1817
|
+
/* @__PURE__ */ jsx7("br", {}),
|
|
1471
1818
|
"Enter your PIN to complete payment."
|
|
1472
1819
|
] }),
|
|
1473
|
-
/* @__PURE__ */
|
|
1474
|
-
/* @__PURE__ */
|
|
1475
|
-
/* @__PURE__ */
|
|
1476
|
-
/* @__PURE__ */
|
|
1820
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-payment-dots", children: [
|
|
1821
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
|
|
1822
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
|
|
1823
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-dot hsk-cb-dot--amber" })
|
|
1477
1824
|
] })
|
|
1478
1825
|
] }),
|
|
1479
|
-
!replayMessages && paymentPhase === "done" && /* @__PURE__ */
|
|
1480
|
-
/* @__PURE__ */
|
|
1481
|
-
/* @__PURE__ */
|
|
1482
|
-
/* @__PURE__ */
|
|
1483
|
-
/* @__PURE__ */
|
|
1826
|
+
!replayMessages && paymentPhase === "done" && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--success", children: [
|
|
1827
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-payment-success-ring" }),
|
|
1828
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ jsx7("span", { style: { fontSize: "2.5rem" }, children: "\u2705" }) }),
|
|
1829
|
+
/* @__PURE__ */ jsx7("p", { className: "hsk-cb-payment-label", children: "Payment complete!" }),
|
|
1830
|
+
/* @__PURE__ */ jsx7("p", { className: "hsk-cb-payment-sub", children: "Thank you for your order. A confirmation has been sent." })
|
|
1484
1831
|
] }),
|
|
1485
|
-
!replayMessages && paymentPhase === "failed" && /* @__PURE__ */
|
|
1486
|
-
/* @__PURE__ */
|
|
1487
|
-
/* @__PURE__ */
|
|
1488
|
-
/* @__PURE__ */
|
|
1489
|
-
/* @__PURE__ */
|
|
1490
|
-
/* @__PURE__ */
|
|
1832
|
+
!replayMessages && paymentPhase === "failed" && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--failed", children: [
|
|
1833
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ jsx7("span", { style: { fontSize: "2.5rem" }, children: "\u274C" }) }),
|
|
1834
|
+
/* @__PURE__ */ jsx7("p", { className: "hsk-cb-payment-label", children: "Payment failed or timed out" }),
|
|
1835
|
+
/* @__PURE__ */ jsx7("p", { className: "hsk-cb-payment-sub", children: "Please check your M-Pesa PIN and try again, or contact support." }),
|
|
1836
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-payment-actions", children: [
|
|
1837
|
+
/* @__PURE__ */ jsx7(
|
|
1491
1838
|
"button",
|
|
1492
1839
|
{
|
|
1493
1840
|
className: "hsk-cb-pay-submit",
|
|
@@ -1498,7 +1845,7 @@ function ChatModal({
|
|
|
1498
1845
|
children: "Try again"
|
|
1499
1846
|
}
|
|
1500
1847
|
),
|
|
1501
|
-
/* @__PURE__ */
|
|
1848
|
+
/* @__PURE__ */ jsx7(
|
|
1502
1849
|
"button",
|
|
1503
1850
|
{
|
|
1504
1851
|
className: "hsk-cb-pay-secondary",
|
|
@@ -1511,11 +1858,45 @@ function ChatModal({
|
|
|
1511
1858
|
)
|
|
1512
1859
|
] })
|
|
1513
1860
|
] }),
|
|
1514
|
-
/* @__PURE__ */
|
|
1861
|
+
/* @__PURE__ */ jsx7("div", { ref: bottomRef, style: { height: 1 } })
|
|
1515
1862
|
] }),
|
|
1516
|
-
!replayMessages && /* @__PURE__ */
|
|
1517
|
-
/* @__PURE__ */
|
|
1518
|
-
/* @__PURE__ */
|
|
1863
|
+
!replayMessages && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-input-wrap", children: [
|
|
1864
|
+
attachments.length > 0 && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-img-strip", children: attachments.map((att, i) => /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-img-thumb-wrap", children: [
|
|
1865
|
+
/* @__PURE__ */ jsx7("img", { src: att.data, alt: `attachment ${i + 1}`, className: "hsk-cb-img-thumb" }),
|
|
1866
|
+
/* @__PURE__ */ jsx7(
|
|
1867
|
+
"button",
|
|
1868
|
+
{
|
|
1869
|
+
className: "hsk-cb-img-thumb-remove",
|
|
1870
|
+
onClick: () => removeAttachment(i),
|
|
1871
|
+
"aria-label": "Remove image",
|
|
1872
|
+
children: "\xD7"
|
|
1873
|
+
}
|
|
1874
|
+
)
|
|
1875
|
+
] }, i)) }),
|
|
1876
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-cb-input-box", children: [
|
|
1877
|
+
/* @__PURE__ */ jsx7(
|
|
1878
|
+
"input",
|
|
1879
|
+
{
|
|
1880
|
+
ref: imageInputRef,
|
|
1881
|
+
type: "file",
|
|
1882
|
+
accept: "image/*",
|
|
1883
|
+
multiple: true,
|
|
1884
|
+
style: { display: "none" },
|
|
1885
|
+
onChange: (e) => handleImageFiles(e.target.files)
|
|
1886
|
+
}
|
|
1887
|
+
),
|
|
1888
|
+
enableVision && /* @__PURE__ */ jsx7(
|
|
1889
|
+
"button",
|
|
1890
|
+
{
|
|
1891
|
+
className: "hsk-cb-attach-btn",
|
|
1892
|
+
onClick: () => imageInputRef.current?.click(),
|
|
1893
|
+
disabled: loading,
|
|
1894
|
+
"aria-label": "Attach image",
|
|
1895
|
+
title: "Attach image",
|
|
1896
|
+
children: /* @__PURE__ */ jsx7(PaperclipIcon, {})
|
|
1897
|
+
}
|
|
1898
|
+
),
|
|
1899
|
+
/* @__PURE__ */ jsx7(
|
|
1519
1900
|
"textarea",
|
|
1520
1901
|
{
|
|
1521
1902
|
ref: textareaRef,
|
|
@@ -1529,18 +1910,36 @@ function ChatModal({
|
|
|
1529
1910
|
autoFocus: true
|
|
1530
1911
|
}
|
|
1531
1912
|
),
|
|
1532
|
-
/* @__PURE__ */
|
|
1913
|
+
hasSpeechAPI && enableVoice && /* @__PURE__ */ jsxs6(
|
|
1914
|
+
"button",
|
|
1915
|
+
{
|
|
1916
|
+
className: cn(
|
|
1917
|
+
"hsk-cb-mic-btn",
|
|
1918
|
+
voiceState === "listening" && "hsk-cb-mic-btn--listening",
|
|
1919
|
+
voiceState === "processing" && "hsk-cb-mic-btn--processing"
|
|
1920
|
+
),
|
|
1921
|
+
onClick: voiceState === "idle" ? startVoice : stopVoice,
|
|
1922
|
+
disabled: loading,
|
|
1923
|
+
"aria-label": voiceState === "idle" ? "Start voice input" : "Stop recording",
|
|
1924
|
+
title: voiceState === "idle" ? "Voice input" : "Stop",
|
|
1925
|
+
children: [
|
|
1926
|
+
voiceState === "listening" ? /* @__PURE__ */ jsx7(MicOffIcon, {}) : /* @__PURE__ */ jsx7(MicIcon2, {}),
|
|
1927
|
+
voiceState === "listening" && /* @__PURE__ */ jsx7("span", { className: "hsk-cb-mic-pulse" })
|
|
1928
|
+
]
|
|
1929
|
+
}
|
|
1930
|
+
),
|
|
1931
|
+
/* @__PURE__ */ jsx7(
|
|
1533
1932
|
"button",
|
|
1534
1933
|
{
|
|
1535
1934
|
className: cn("hsk-cb-send", classNames.sendButton),
|
|
1536
1935
|
onClick: () => handleSend(),
|
|
1537
|
-
disabled: !input.trim() || loading,
|
|
1936
|
+
disabled: !input.trim() && attachments.length === 0 || loading,
|
|
1538
1937
|
"aria-label": "Send message",
|
|
1539
|
-
children: /* @__PURE__ */
|
|
1938
|
+
children: /* @__PURE__ */ jsx7(ArrowUpIcon2, {})
|
|
1540
1939
|
}
|
|
1541
1940
|
)
|
|
1542
1941
|
] }),
|
|
1543
|
-
/* @__PURE__ */
|
|
1942
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-cb-hint", children: "Akropolys AI \xB7 searches the whole catalogue in real time" })
|
|
1544
1943
|
] })
|
|
1545
1944
|
] })
|
|
1546
1945
|
] })
|
|
@@ -1558,10 +1957,13 @@ function KikuButton({
|
|
|
1558
1957
|
defaultCurrency,
|
|
1559
1958
|
chips,
|
|
1560
1959
|
theme,
|
|
1561
|
-
classNames = {}
|
|
1960
|
+
classNames = {},
|
|
1961
|
+
enableVoice = false,
|
|
1962
|
+
enableVision = false,
|
|
1963
|
+
visionCategoryHint
|
|
1562
1964
|
}) {
|
|
1563
|
-
const [open, setOpen] =
|
|
1564
|
-
const [mounted, setMounted] =
|
|
1965
|
+
const [open, setOpen] = useState5(false);
|
|
1966
|
+
const [mounted, setMounted] = useState5(false);
|
|
1565
1967
|
useEffect3(() => {
|
|
1566
1968
|
setMounted(true);
|
|
1567
1969
|
if (typeof window !== "undefined" && !window.__akropolys_nav_patched) {
|
|
@@ -1596,8 +1998,8 @@ function KikuButton({
|
|
|
1596
1998
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
1597
1999
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
1598
2000
|
} : void 0;
|
|
1599
|
-
return /* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
2001
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
2002
|
+
/* @__PURE__ */ jsxs6(
|
|
1601
2003
|
"button",
|
|
1602
2004
|
{
|
|
1603
2005
|
className: cn("hsk-cb-btn", classNames.button, className),
|
|
@@ -1606,13 +2008,13 @@ function KikuButton({
|
|
|
1606
2008
|
"data-hsk-theme": hskThemeAttr,
|
|
1607
2009
|
"aria-label": "Open AI chat",
|
|
1608
2010
|
children: [
|
|
1609
|
-
/* @__PURE__ */
|
|
2011
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
|
|
1610
2012
|
label !== void 0 ? label : null
|
|
1611
2013
|
]
|
|
1612
2014
|
}
|
|
1613
2015
|
),
|
|
1614
2016
|
open && mounted && createPortal(
|
|
1615
|
-
/* @__PURE__ */
|
|
2017
|
+
/* @__PURE__ */ jsx7(
|
|
1616
2018
|
ChatModal,
|
|
1617
2019
|
{
|
|
1618
2020
|
title,
|
|
@@ -1624,7 +2026,10 @@ function KikuButton({
|
|
|
1624
2026
|
defaultCurrency,
|
|
1625
2027
|
chips,
|
|
1626
2028
|
theme,
|
|
1627
|
-
classNames
|
|
2029
|
+
classNames,
|
|
2030
|
+
enableVoice,
|
|
2031
|
+
enableVision,
|
|
2032
|
+
visionCategoryHint
|
|
1628
2033
|
}
|
|
1629
2034
|
),
|
|
1630
2035
|
document.body
|
|
@@ -1633,11 +2038,11 @@ function KikuButton({
|
|
|
1633
2038
|
}
|
|
1634
2039
|
|
|
1635
2040
|
// src/components/Sparkle.tsx
|
|
1636
|
-
import { useState as
|
|
2041
|
+
import { useState as useState6, useEffect as useEffect4, useRef as useRef6 } from "react";
|
|
1637
2042
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1638
|
-
import { useSearch as useSearch2, useKiku as useKiku3, useAkropolysContext as
|
|
1639
|
-
import { Fragment as Fragment4, jsx as
|
|
1640
|
-
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */
|
|
2043
|
+
import { useSearch as useSearch2, useKiku as useKiku3, useAkropolysContext as useAkropolysContext4 } from "@akropolys/sdk";
|
|
2044
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2045
|
+
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs7(
|
|
1641
2046
|
"svg",
|
|
1642
2047
|
{
|
|
1643
2048
|
className: cn("hsk-brand-a", className),
|
|
@@ -1648,7 +2053,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1648
2053
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1649
2054
|
"aria-label": "Akropolys",
|
|
1650
2055
|
children: [
|
|
1651
|
-
/* @__PURE__ */
|
|
2056
|
+
/* @__PURE__ */ jsx8(
|
|
1652
2057
|
"path",
|
|
1653
2058
|
{
|
|
1654
2059
|
d: "M14.5 4.5 L6.5 25",
|
|
@@ -1657,7 +2062,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1657
2062
|
strokeLinecap: "round"
|
|
1658
2063
|
}
|
|
1659
2064
|
),
|
|
1660
|
-
/* @__PURE__ */
|
|
2065
|
+
/* @__PURE__ */ jsx8(
|
|
1661
2066
|
"path",
|
|
1662
2067
|
{
|
|
1663
2068
|
d: "M14.5 4.5 L22.5 25",
|
|
@@ -1666,7 +2071,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1666
2071
|
strokeLinecap: "round"
|
|
1667
2072
|
}
|
|
1668
2073
|
),
|
|
1669
|
-
/* @__PURE__ */
|
|
2074
|
+
/* @__PURE__ */ jsx8(
|
|
1670
2075
|
"path",
|
|
1671
2076
|
{
|
|
1672
2077
|
d: "M9.5 17 H19.5",
|
|
@@ -1675,7 +2080,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1675
2080
|
strokeLinecap: "round"
|
|
1676
2081
|
}
|
|
1677
2082
|
),
|
|
1678
|
-
/* @__PURE__ */
|
|
2083
|
+
/* @__PURE__ */ jsx8(
|
|
1679
2084
|
"path",
|
|
1680
2085
|
{
|
|
1681
2086
|
d: "M3 25 H10",
|
|
@@ -1684,7 +2089,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1684
2089
|
strokeLinecap: "round"
|
|
1685
2090
|
}
|
|
1686
2091
|
),
|
|
1687
|
-
/* @__PURE__ */
|
|
2092
|
+
/* @__PURE__ */ jsx8(
|
|
1688
2093
|
"path",
|
|
1689
2094
|
{
|
|
1690
2095
|
d: "M19 25 H26",
|
|
@@ -1693,7 +2098,7 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1693
2098
|
strokeLinecap: "round"
|
|
1694
2099
|
}
|
|
1695
2100
|
),
|
|
1696
|
-
/* @__PURE__ */
|
|
2101
|
+
/* @__PURE__ */ jsx8(
|
|
1697
2102
|
"path",
|
|
1698
2103
|
{
|
|
1699
2104
|
d: "M8.5 2.5 C10 2.5, 11 3.5, 11 5 C11 7, 8.5 8.5, 7.5 9.5",
|
|
@@ -1707,13 +2112,13 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsxs5(
|
|
|
1707
2112
|
]
|
|
1708
2113
|
}
|
|
1709
2114
|
);
|
|
1710
|
-
var CloseIcon2 = () => /* @__PURE__ */
|
|
1711
|
-
/* @__PURE__ */
|
|
1712
|
-
/* @__PURE__ */
|
|
2115
|
+
var CloseIcon2 = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2116
|
+
/* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2117
|
+
/* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1713
2118
|
] });
|
|
1714
|
-
var ArrowUpIcon3 = () => /* @__PURE__ */
|
|
1715
|
-
/* @__PURE__ */
|
|
1716
|
-
/* @__PURE__ */
|
|
2119
|
+
var ArrowUpIcon3 = () => /* @__PURE__ */ jsxs7("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2120
|
+
/* @__PURE__ */ jsx8("path", { d: "m5 12 7-7 7 7" }),
|
|
2121
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 19V5" })
|
|
1717
2122
|
] });
|
|
1718
2123
|
var getFriendlyError2 = (err) => {
|
|
1719
2124
|
let str = "";
|
|
@@ -1746,17 +2151,17 @@ function SparkleModal({
|
|
|
1746
2151
|
classNames = {},
|
|
1747
2152
|
product: initialProduct
|
|
1748
2153
|
}) {
|
|
1749
|
-
const client =
|
|
1750
|
-
const [fetchedProduct, setFetchedProduct] =
|
|
2154
|
+
const client = useAkropolysContext4();
|
|
2155
|
+
const [fetchedProduct, setFetchedProduct] = useState6(null);
|
|
1751
2156
|
const displayProduct = initialProduct || fetchedProduct;
|
|
1752
2157
|
const { results, loading: searchLoading, search } = useSearch2();
|
|
1753
2158
|
const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku3();
|
|
1754
|
-
const [chatInput, setChatInput] =
|
|
1755
|
-
const [isMobile, setIsMobile] =
|
|
1756
|
-
const [showSpecs, setShowSpecs] =
|
|
1757
|
-
const [collapseSimilar, setCollapseSimilar] =
|
|
1758
|
-
const chatBottomRef =
|
|
1759
|
-
const chatTextareaRef =
|
|
2159
|
+
const [chatInput, setChatInput] = useState6("");
|
|
2160
|
+
const [isMobile, setIsMobile] = useState6(false);
|
|
2161
|
+
const [showSpecs, setShowSpecs] = useState6(false);
|
|
2162
|
+
const [collapseSimilar, setCollapseSimilar] = useState6(false);
|
|
2163
|
+
const chatBottomRef = useRef6(null);
|
|
2164
|
+
const chatTextareaRef = useRef6(null);
|
|
1760
2165
|
useEffect4(() => {
|
|
1761
2166
|
if (!initialProduct && !fetchedProduct) {
|
|
1762
2167
|
client.api.searchVector(productName, 1).then((res) => {
|
|
@@ -1839,7 +2244,7 @@ Question: ${q}`;
|
|
|
1839
2244
|
}
|
|
1840
2245
|
] : messages;
|
|
1841
2246
|
if (isMobile) {
|
|
1842
|
-
return /* @__PURE__ */
|
|
2247
|
+
return /* @__PURE__ */ jsx8(
|
|
1843
2248
|
"div",
|
|
1844
2249
|
{
|
|
1845
2250
|
className: cn("hsk-sp-backdrop hsk-sp-mobile-view", classNames.backdrop),
|
|
@@ -1850,13 +2255,13 @@ Question: ${q}`;
|
|
|
1850
2255
|
background: bg ?? void 0,
|
|
1851
2256
|
...customStyles
|
|
1852
2257
|
},
|
|
1853
|
-
children: /* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
1856
|
-
/* @__PURE__ */
|
|
1857
|
-
/* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
1859
|
-
displayProduct && /* @__PURE__ */
|
|
2258
|
+
children: /* @__PURE__ */ jsxs7("div", { className: cn("hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card", classNames.card), onClick: (e) => e.stopPropagation(), children: [
|
|
2259
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-header", children: [
|
|
2260
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon3, {}) }),
|
|
2261
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-header-body", children: [
|
|
2262
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-header-title-row", children: [
|
|
2263
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
|
|
2264
|
+
displayProduct && /* @__PURE__ */ jsx8(
|
|
1860
2265
|
"button",
|
|
1861
2266
|
{
|
|
1862
2267
|
type: "button",
|
|
@@ -1866,32 +2271,32 @@ Question: ${q}`;
|
|
|
1866
2271
|
}
|
|
1867
2272
|
)
|
|
1868
2273
|
] }),
|
|
1869
|
-
/* @__PURE__ */
|
|
2274
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-header-sub", children: "Akropolys AI Shopping Assistant" })
|
|
1870
2275
|
] }),
|
|
1871
|
-
/* @__PURE__ */
|
|
2276
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx8(CloseIcon2, {}) })
|
|
1872
2277
|
] }),
|
|
1873
|
-
searchLoading && /* @__PURE__ */
|
|
1874
|
-
/* @__PURE__ */
|
|
1875
|
-
/* @__PURE__ */
|
|
2278
|
+
searchLoading && /* @__PURE__ */ jsx8("div", { className: "hsk-sp-bar" }),
|
|
2279
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-chat-container", children: [
|
|
2280
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-msgs", children: [
|
|
1876
2281
|
displayMessages.map((msg, idx) => {
|
|
1877
2282
|
const isUser = msg.role === "user";
|
|
1878
|
-
return /* @__PURE__ */
|
|
1879
|
-
/* @__PURE__ */
|
|
1880
|
-
/* @__PURE__ */
|
|
1881
|
-
/* @__PURE__ */
|
|
1882
|
-
idx === 0 && displayProduct && /* @__PURE__ */
|
|
1883
|
-
/* @__PURE__ */
|
|
1884
|
-
/* @__PURE__ */
|
|
1885
|
-
/* @__PURE__ */
|
|
1886
|
-
/* @__PURE__ */
|
|
1887
|
-
/* @__PURE__ */
|
|
1888
|
-
/* @__PURE__ */
|
|
2283
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2284
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon3, {}) }),
|
|
2285
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-body", children: [
|
|
2286
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
|
|
2287
|
+
idx === 0 && displayProduct && /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-attachment-deck", children: [
|
|
2288
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-main-card", children: [
|
|
2289
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ jsx8("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ jsx8("span", { children: "\u{1F6CD}" }) }),
|
|
2290
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-main-card-info", children: [
|
|
2291
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-main-card-brand", children: displayProduct.brand || displayProduct.category || "Product" }),
|
|
2292
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-main-card-name", children: displayProduct.name }),
|
|
2293
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-main-card-price", children: [
|
|
1889
2294
|
displayProduct.currency ?? "KES",
|
|
1890
2295
|
" ",
|
|
1891
2296
|
parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
1892
2297
|
] })
|
|
1893
2298
|
] }),
|
|
1894
|
-
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */
|
|
2299
|
+
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */ jsx8(
|
|
1895
2300
|
"button",
|
|
1896
2301
|
{
|
|
1897
2302
|
type: "button",
|
|
@@ -1910,21 +2315,21 @@ Question: ${q}`;
|
|
|
1910
2315
|
}
|
|
1911
2316
|
);
|
|
1912
2317
|
if (similarProducts.length === 0) return null;
|
|
1913
|
-
return /* @__PURE__ */
|
|
1914
|
-
/* @__PURE__ */
|
|
1915
|
-
/* @__PURE__ */
|
|
2318
|
+
return /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-similar-carousel-inline", children: [
|
|
2319
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-similar-carousel-title", children: "Similar Products" }),
|
|
2320
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-similar-carousel-list", children: similarProducts.map((r) => {
|
|
1916
2321
|
const price = parseFloat(r.product.price?.replace(/[^0-9.]/g, "") || "0");
|
|
1917
2322
|
const currency = r.product.currency ?? "KES";
|
|
1918
|
-
return /* @__PURE__ */
|
|
2323
|
+
return /* @__PURE__ */ jsxs7(
|
|
1919
2324
|
"div",
|
|
1920
2325
|
{
|
|
1921
2326
|
className: "hsk-sp-mobile-similar-carousel-item",
|
|
1922
2327
|
onClick: () => handleNav(r),
|
|
1923
2328
|
children: [
|
|
1924
|
-
/* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
2329
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.product.images?.[0] ? /* @__PURE__ */ jsx8("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ jsx8("span", { children: "\u{1F6CD}" }) }),
|
|
2330
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-similar-carousel-meta", children: [
|
|
2331
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.product.name, children: r.product.name }),
|
|
2332
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-similar-carousel-price", children: [
|
|
1928
2333
|
currency,
|
|
1929
2334
|
" ",
|
|
1930
2335
|
price.toLocaleString()
|
|
@@ -1941,19 +2346,19 @@ Question: ${q}`;
|
|
|
1941
2346
|
] })
|
|
1942
2347
|
] }) }, idx);
|
|
1943
2348
|
}),
|
|
1944
|
-
chatLoading && /* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
/* @__PURE__ */
|
|
1947
|
-
/* @__PURE__ */
|
|
1948
|
-
/* @__PURE__ */
|
|
1949
|
-
/* @__PURE__ */
|
|
2349
|
+
chatLoading && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-typing-row", children: [
|
|
2350
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon3, {}) }),
|
|
2351
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-typing", children: [
|
|
2352
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-dot" }),
|
|
2353
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-dot" }),
|
|
2354
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-dot" })
|
|
1950
2355
|
] })
|
|
1951
2356
|
] }),
|
|
1952
|
-
chatError && /* @__PURE__ */
|
|
1953
|
-
/* @__PURE__ */
|
|
2357
|
+
chatError && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
2358
|
+
/* @__PURE__ */ jsx8("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
1954
2359
|
] }),
|
|
1955
|
-
/* @__PURE__ */
|
|
1956
|
-
/* @__PURE__ */
|
|
2360
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-input-wrap", children: /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-box", children: [
|
|
2361
|
+
/* @__PURE__ */ jsx8(
|
|
1957
2362
|
"textarea",
|
|
1958
2363
|
{
|
|
1959
2364
|
ref: chatTextareaRef,
|
|
@@ -1966,34 +2371,34 @@ Question: ${q}`;
|
|
|
1966
2371
|
disabled: chatLoading
|
|
1967
2372
|
}
|
|
1968
2373
|
),
|
|
1969
|
-
/* @__PURE__ */
|
|
2374
|
+
/* @__PURE__ */ jsx8(
|
|
1970
2375
|
"button",
|
|
1971
2376
|
{
|
|
1972
2377
|
className: "hsk-cb-send",
|
|
1973
2378
|
onClick: () => handleSend(),
|
|
1974
2379
|
disabled: !chatInput.trim() || chatLoading,
|
|
1975
2380
|
"aria-label": "Send message",
|
|
1976
|
-
children: /* @__PURE__ */
|
|
2381
|
+
children: /* @__PURE__ */ jsx8(ArrowUpIcon3, {})
|
|
1977
2382
|
}
|
|
1978
2383
|
)
|
|
1979
2384
|
] }) })
|
|
1980
2385
|
] }),
|
|
1981
|
-
showSpecs && displayProduct && /* @__PURE__ */
|
|
1982
|
-
/* @__PURE__ */
|
|
1983
|
-
/* @__PURE__ */
|
|
1984
|
-
/* @__PURE__ */
|
|
2386
|
+
showSpecs && displayProduct && /* @__PURE__ */ jsx8("div", { className: "hsk-sp-mobile-specs-overlay", onClick: () => setShowSpecs(false), children: /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-specs-drawer", onClick: (e) => e.stopPropagation(), children: [
|
|
2387
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-specs-header", children: [
|
|
2388
|
+
/* @__PURE__ */ jsx8("h3", { children: "Specifications" }),
|
|
2389
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: () => setShowSpecs(false), children: "Close" })
|
|
1985
2390
|
] }),
|
|
1986
|
-
/* @__PURE__ */
|
|
1987
|
-
/* @__PURE__ */
|
|
1988
|
-
displayProduct.description && /* @__PURE__ */
|
|
1989
|
-
/* @__PURE__ */
|
|
1990
|
-
/* @__PURE__ */
|
|
2391
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-specs-body", children: [
|
|
2392
|
+
/* @__PURE__ */ jsx8("h4", { className: "hsk-sp-mobile-specs-title", children: displayProduct.name }),
|
|
2393
|
+
displayProduct.description && /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-specs-desc", children: [
|
|
2394
|
+
/* @__PURE__ */ jsx8("h5", { children: "Description" }),
|
|
2395
|
+
/* @__PURE__ */ jsx8("p", { children: displayProduct.description })
|
|
1991
2396
|
] }),
|
|
1992
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
1993
|
-
/* @__PURE__ */
|
|
1994
|
-
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */
|
|
1995
|
-
/* @__PURE__ */
|
|
1996
|
-
/* @__PURE__ */
|
|
2397
|
+
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-specs-list", children: [
|
|
2398
|
+
/* @__PURE__ */ jsx8("h5", { children: "Details" }),
|
|
2399
|
+
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-mobile-spec-row", children: [
|
|
2400
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-mobile-spec-label", children: key }),
|
|
2401
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-mobile-spec-value", children: val })
|
|
1997
2402
|
] }, key))
|
|
1998
2403
|
] })
|
|
1999
2404
|
] })
|
|
@@ -2002,7 +2407,7 @@ Question: ${q}`;
|
|
|
2002
2407
|
}
|
|
2003
2408
|
);
|
|
2004
2409
|
}
|
|
2005
|
-
return /* @__PURE__ */
|
|
2410
|
+
return /* @__PURE__ */ jsx8(
|
|
2006
2411
|
"div",
|
|
2007
2412
|
{
|
|
2008
2413
|
className: cn("hsk-sp-backdrop", classNames.backdrop),
|
|
@@ -2013,65 +2418,65 @@ Question: ${q}`;
|
|
|
2013
2418
|
background: bg ?? void 0,
|
|
2014
2419
|
...customStyles
|
|
2015
2420
|
},
|
|
2016
|
-
children: /* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
2421
|
+
children: /* @__PURE__ */ jsxs7("div", { className: cn("hsk-sp-card hsk-sp-fullscreen", classNames.card), onClick: (e) => e.stopPropagation(), children: [
|
|
2422
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-header", children: [
|
|
2423
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon3, {}) }),
|
|
2424
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-header-body", children: [
|
|
2425
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
|
|
2426
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-header-sub", children: "Ask questions, compare specs, or check similar products" })
|
|
2022
2427
|
] }),
|
|
2023
|
-
/* @__PURE__ */
|
|
2428
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx8(CloseIcon2, {}) })
|
|
2024
2429
|
] }),
|
|
2025
|
-
searchLoading && /* @__PURE__ */
|
|
2026
|
-
/* @__PURE__ */
|
|
2027
|
-
/* @__PURE__ */
|
|
2028
|
-
displayProduct && /* @__PURE__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
/* @__PURE__ */
|
|
2031
|
-
/* @__PURE__ */
|
|
2032
|
-
displayProduct.brand && /* @__PURE__ */
|
|
2033
|
-
displayProduct.category && /* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2036
|
-
/* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2038
|
-
displayProduct.originalPrice && /* @__PURE__ */
|
|
2039
|
-
displayProduct.discount && /* @__PURE__ */
|
|
2430
|
+
searchLoading && /* @__PURE__ */ jsx8("div", { className: "hsk-sp-bar" }),
|
|
2431
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-body", children: [
|
|
2432
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-details-pane", children: [
|
|
2433
|
+
displayProduct && /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-product-profile-container", children: [
|
|
2434
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-product-profile", children: [
|
|
2435
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ jsx8("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ jsx8("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
|
|
2436
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-details-meta", children: [
|
|
2437
|
+
displayProduct.brand && /* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-brand", children: displayProduct.brand }),
|
|
2438
|
+
displayProduct.category && /* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-cat", children: displayProduct.category }),
|
|
2439
|
+
/* @__PURE__ */ jsx8("h2", { className: "hsk-sp-details-name", children: displayProduct.name }),
|
|
2440
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-item-price-row", children: [
|
|
2441
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-currency", children: displayProduct.currency ?? "KES" }),
|
|
2442
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-price", children: parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
|
|
2443
|
+
displayProduct.originalPrice && /* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-original-price", children: parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
|
|
2444
|
+
displayProduct.discount && /* @__PURE__ */ jsxs7("span", { className: "hsk-sp-item-discount", children: [
|
|
2040
2445
|
"(",
|
|
2041
2446
|
displayProduct.discount,
|
|
2042
2447
|
")"
|
|
2043
2448
|
] })
|
|
2044
2449
|
] }),
|
|
2045
|
-
/* @__PURE__ */
|
|
2046
|
-
displayProduct.rating && /* @__PURE__ */
|
|
2450
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-item-meta-badges", children: [
|
|
2451
|
+
displayProduct.rating && /* @__PURE__ */ jsxs7("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-rating", children: [
|
|
2047
2452
|
"\u2605 ",
|
|
2048
2453
|
parseFloat(displayProduct.rating.toString()).toFixed(1),
|
|
2049
2454
|
" ",
|
|
2050
2455
|
displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ""
|
|
2051
2456
|
] }),
|
|
2052
|
-
displayProduct.availability && /* @__PURE__ */
|
|
2053
|
-
displayProduct.stock && !displayProduct.availability && /* @__PURE__ */
|
|
2457
|
+
displayProduct.availability && /* @__PURE__ */ jsx8("span", { className: `hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes("in") ? "in-stock" : "out-stock"}`, children: displayProduct.availability }),
|
|
2458
|
+
displayProduct.stock && !displayProduct.availability && /* @__PURE__ */ jsxs7("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-stock", children: [
|
|
2054
2459
|
"Stock: ",
|
|
2055
2460
|
displayProduct.stock
|
|
2056
2461
|
] })
|
|
2057
2462
|
] })
|
|
2058
2463
|
] })
|
|
2059
2464
|
] }),
|
|
2060
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2061
|
-
/* @__PURE__ */
|
|
2465
|
+
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-sp-specs-horizontal", children: Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-spec-item-horizontal", children: [
|
|
2466
|
+
/* @__PURE__ */ jsxs7("span", { className: "hsk-sp-spec-label-horizontal", children: [
|
|
2062
2467
|
key,
|
|
2063
2468
|
":"
|
|
2064
2469
|
] }),
|
|
2065
|
-
/* @__PURE__ */
|
|
2470
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-spec-value-horizontal", title: val, children: val })
|
|
2066
2471
|
] }, key)) }),
|
|
2067
|
-
displayProduct.description && /* @__PURE__ */
|
|
2068
|
-
/* @__PURE__ */
|
|
2069
|
-
/* @__PURE__ */
|
|
2472
|
+
displayProduct.description && /* @__PURE__ */ jsxs7("div", { className: "hsk-sp-details-desc", children: [
|
|
2473
|
+
/* @__PURE__ */ jsx8("h4", { children: "Description" }),
|
|
2474
|
+
/* @__PURE__ */ jsx8("p", { children: displayProduct.description })
|
|
2070
2475
|
] })
|
|
2071
2476
|
] }),
|
|
2072
|
-
/* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2074
|
-
/* @__PURE__ */
|
|
2477
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-similar-section", children: [
|
|
2478
|
+
/* @__PURE__ */ jsx8("h3", { children: "Similar Products" }),
|
|
2479
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-results", children: (() => {
|
|
2075
2480
|
const similarProducts = results.filter(
|
|
2076
2481
|
(r) => {
|
|
2077
2482
|
const isSameName = r.product.name.toLowerCase() === displayProduct?.name?.toLowerCase();
|
|
@@ -2080,29 +2485,29 @@ Question: ${q}`;
|
|
|
2080
2485
|
}
|
|
2081
2486
|
);
|
|
2082
2487
|
if (!searchLoading && similarProducts.length === 0) {
|
|
2083
|
-
return /* @__PURE__ */
|
|
2488
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-sp-empty", children: "No similar products found." });
|
|
2084
2489
|
}
|
|
2085
2490
|
return similarProducts.map((r, i) => {
|
|
2086
2491
|
const price = parseFloat(r.product.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2087
2492
|
const currency = r.product.currency ?? "KES";
|
|
2088
|
-
return /* @__PURE__ */
|
|
2493
|
+
return /* @__PURE__ */ jsxs7(
|
|
2089
2494
|
"div",
|
|
2090
2495
|
{
|
|
2091
2496
|
className: cn("hsk-sp-item", classNames.item),
|
|
2092
2497
|
style: { animationDelay: `${i * 55}ms`, cursor: "pointer" },
|
|
2093
2498
|
onClick: () => handleNav(r),
|
|
2094
2499
|
children: [
|
|
2095
|
-
/* @__PURE__ */
|
|
2096
|
-
/* @__PURE__ */
|
|
2097
|
-
/* @__PURE__ */
|
|
2098
|
-
r.product.category && /* @__PURE__ */
|
|
2099
|
-
/* @__PURE__ */
|
|
2500
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-img-wrap", children: r.product.images?.[0] ? /* @__PURE__ */ jsx8("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ jsx8("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
|
|
2501
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-item-body", children: [
|
|
2502
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
2503
|
+
r.product.category && /* @__PURE__ */ jsx8("div", { className: "hsk-sp-item-cat", children: r.product.category }),
|
|
2504
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-item-name", title: r.product.name, children: r.product.name })
|
|
2100
2505
|
] }),
|
|
2101
|
-
/* @__PURE__ */
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2506
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-item-price-row", children: [
|
|
2507
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-currency", children: currency }),
|
|
2508
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
|
|
2104
2509
|
] }),
|
|
2105
|
-
/* @__PURE__ */
|
|
2510
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-actions", children: /* @__PURE__ */ jsx8(
|
|
2106
2511
|
"button",
|
|
2107
2512
|
{
|
|
2108
2513
|
className: "hsk-sp-action hsk-sp-action-primary",
|
|
@@ -2122,29 +2527,29 @@ Question: ${q}`;
|
|
|
2122
2527
|
})() })
|
|
2123
2528
|
] })
|
|
2124
2529
|
] }),
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
/* @__PURE__ */
|
|
2530
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-sp-chat-pane", children: [
|
|
2531
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-msgs", children: [
|
|
2127
2532
|
displayMessages.map((msg, idx) => {
|
|
2128
2533
|
const isUser = msg.role === "user";
|
|
2129
|
-
return /* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
/* @__PURE__ */
|
|
2534
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2535
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon3, {}) }),
|
|
2536
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }) })
|
|
2132
2537
|
] }) }, idx);
|
|
2133
2538
|
}),
|
|
2134
|
-
chatLoading && /* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
/* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
/* @__PURE__ */
|
|
2539
|
+
chatLoading && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-typing-row", children: [
|
|
2540
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon3, {}) }),
|
|
2541
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-typing", children: [
|
|
2542
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-dot" }),
|
|
2543
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-dot" }),
|
|
2544
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-dot" })
|
|
2140
2545
|
] })
|
|
2141
2546
|
] }),
|
|
2142
|
-
chatError && /* @__PURE__ */
|
|
2143
|
-
/* @__PURE__ */
|
|
2547
|
+
chatError && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
2548
|
+
/* @__PURE__ */ jsx8("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2144
2549
|
] }),
|
|
2145
|
-
/* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2550
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-wrap", children: [
|
|
2551
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-box", children: [
|
|
2552
|
+
/* @__PURE__ */ jsx8(
|
|
2148
2553
|
"textarea",
|
|
2149
2554
|
{
|
|
2150
2555
|
ref: chatTextareaRef,
|
|
@@ -2157,22 +2562,22 @@ Question: ${q}`;
|
|
|
2157
2562
|
disabled: chatLoading
|
|
2158
2563
|
}
|
|
2159
2564
|
),
|
|
2160
|
-
/* @__PURE__ */
|
|
2565
|
+
/* @__PURE__ */ jsx8(
|
|
2161
2566
|
"button",
|
|
2162
2567
|
{
|
|
2163
2568
|
className: "hsk-cb-send",
|
|
2164
2569
|
onClick: () => handleSend(),
|
|
2165
2570
|
disabled: !chatInput.trim() || chatLoading,
|
|
2166
2571
|
"aria-label": "Send message",
|
|
2167
|
-
children: /* @__PURE__ */
|
|
2572
|
+
children: /* @__PURE__ */ jsx8(ArrowUpIcon3, {})
|
|
2168
2573
|
}
|
|
2169
2574
|
)
|
|
2170
2575
|
] }),
|
|
2171
|
-
/* @__PURE__ */
|
|
2576
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-hint", children: "Akropolys \xB7 instant product knowledge" })
|
|
2172
2577
|
] })
|
|
2173
2578
|
] })
|
|
2174
2579
|
] }),
|
|
2175
|
-
/* @__PURE__ */
|
|
2580
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-sp-footer", children: /* @__PURE__ */ jsx8("span", { className: "hsk-sp-esc", children: "Esc to close" }) })
|
|
2176
2581
|
] })
|
|
2177
2582
|
}
|
|
2178
2583
|
);
|
|
@@ -2190,8 +2595,8 @@ function Sparkle({
|
|
|
2190
2595
|
product,
|
|
2191
2596
|
children
|
|
2192
2597
|
}) {
|
|
2193
|
-
const [open, setOpen] =
|
|
2194
|
-
const [mounted, setMounted] =
|
|
2598
|
+
const [open, setOpen] = useState6(false);
|
|
2599
|
+
const [mounted, setMounted] = useState6(false);
|
|
2195
2600
|
useEffect4(() => {
|
|
2196
2601
|
setMounted(true);
|
|
2197
2602
|
}, []);
|
|
@@ -2202,8 +2607,8 @@ function Sparkle({
|
|
|
2202
2607
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2203
2608
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2204
2609
|
};
|
|
2205
|
-
return /* @__PURE__ */
|
|
2206
|
-
/* @__PURE__ */
|
|
2610
|
+
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
2611
|
+
/* @__PURE__ */ jsx8(
|
|
2207
2612
|
"button",
|
|
2208
2613
|
{
|
|
2209
2614
|
className: cn("hsk-sp-btn", classNames.button, className),
|
|
@@ -2211,11 +2616,11 @@ function Sparkle({
|
|
|
2211
2616
|
style: customStyles,
|
|
2212
2617
|
title: "Find similar products",
|
|
2213
2618
|
"aria-label": "Find similar products",
|
|
2214
|
-
children: children || /* @__PURE__ */
|
|
2619
|
+
children: children || /* @__PURE__ */ jsx8(SparkleIcon3, {})
|
|
2215
2620
|
}
|
|
2216
2621
|
),
|
|
2217
2622
|
open && mounted && createPortal2(
|
|
2218
|
-
/* @__PURE__ */
|
|
2623
|
+
/* @__PURE__ */ jsx8(
|
|
2219
2624
|
SparkleModal,
|
|
2220
2625
|
{
|
|
2221
2626
|
productName,
|
|
@@ -2237,23 +2642,23 @@ function Sparkle({
|
|
|
2237
2642
|
|
|
2238
2643
|
// src/components/CartBadge.tsx
|
|
2239
2644
|
import { useCart } from "@akropolys/sdk";
|
|
2240
|
-
import { jsx as
|
|
2645
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2241
2646
|
function CartBadge({ className }) {
|
|
2242
2647
|
const { cart } = useCart();
|
|
2243
2648
|
if (!cart || cart.item_count === 0) return null;
|
|
2244
|
-
return /* @__PURE__ */
|
|
2649
|
+
return /* @__PURE__ */ jsx9("span", { className: cn("hsk-cart-badge", className), children: cart.item_count });
|
|
2245
2650
|
}
|
|
2246
2651
|
|
|
2247
2652
|
// src/components/CartDrawer.tsx
|
|
2248
|
-
import { useState as
|
|
2653
|
+
import { useState as useState8, useEffect as useEffect6 } from "react";
|
|
2249
2654
|
import { createPortal as createPortal4 } from "react-dom";
|
|
2250
|
-
import { useCart as useCart3, useAkropolysContext as
|
|
2655
|
+
import { useCart as useCart3, useAkropolysContext as useAkropolysContext6 } from "@akropolys/sdk";
|
|
2251
2656
|
|
|
2252
2657
|
// src/components/CheckoutModal.tsx
|
|
2253
|
-
import { useState as
|
|
2658
|
+
import { useState as useState7, useEffect as useEffect5 } from "react";
|
|
2254
2659
|
import { createPortal as createPortal3 } from "react-dom";
|
|
2255
|
-
import { useCart as useCart2, useAkropolysContext as
|
|
2256
|
-
import { jsx as
|
|
2660
|
+
import { useCart as useCart2, useAkropolysContext as useAkropolysContext5, usePaymentPolling as usePaymentPolling2 } from "@akropolys/sdk";
|
|
2661
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2257
2662
|
function CheckoutModal({
|
|
2258
2663
|
onClose,
|
|
2259
2664
|
theme,
|
|
@@ -2261,36 +2666,36 @@ function CheckoutModal({
|
|
|
2261
2666
|
hskThemeAttr
|
|
2262
2667
|
}) {
|
|
2263
2668
|
const { cart, loading: cartLoading } = useCart2();
|
|
2264
|
-
const client =
|
|
2265
|
-
const [config, setConfig] =
|
|
2266
|
-
const [loadingConfig, setLoadingConfig] =
|
|
2267
|
-
const [phone, setPhone] =
|
|
2669
|
+
const client = useAkropolysContext5();
|
|
2670
|
+
const [config, setConfig] = useState7(null);
|
|
2671
|
+
const [loadingConfig, setLoadingConfig] = useState7(true);
|
|
2672
|
+
const [phone, setPhone] = useState7(() => {
|
|
2268
2673
|
if (typeof window !== "undefined") {
|
|
2269
2674
|
return localStorage.getItem("akropolys_user_phone") || "";
|
|
2270
2675
|
}
|
|
2271
2676
|
return "";
|
|
2272
2677
|
});
|
|
2273
|
-
const [email, setEmail] =
|
|
2678
|
+
const [email, setEmail] = useState7(() => {
|
|
2274
2679
|
if (typeof window !== "undefined") {
|
|
2275
2680
|
return localStorage.getItem("akropolys_user_email") || "";
|
|
2276
2681
|
}
|
|
2277
2682
|
return "";
|
|
2278
2683
|
});
|
|
2279
|
-
const [firstName, setFirstName] =
|
|
2684
|
+
const [firstName, setFirstName] = useState7(() => {
|
|
2280
2685
|
if (typeof window !== "undefined") {
|
|
2281
2686
|
return localStorage.getItem("akropolys_user_firstname") || "";
|
|
2282
2687
|
}
|
|
2283
2688
|
return "";
|
|
2284
2689
|
});
|
|
2285
|
-
const [lastName, setLastName] =
|
|
2690
|
+
const [lastName, setLastName] = useState7(() => {
|
|
2286
2691
|
if (typeof window !== "undefined") {
|
|
2287
2692
|
return localStorage.getItem("akropolys_user_lastname") || "";
|
|
2288
2693
|
}
|
|
2289
2694
|
return "";
|
|
2290
2695
|
});
|
|
2291
|
-
const [phase, setPhase] =
|
|
2292
|
-
const [merchantRef, setMerchantRef] =
|
|
2293
|
-
const [payError, setPayError] =
|
|
2696
|
+
const [phase, setPhase] = useState7("idle");
|
|
2697
|
+
const [merchantRef, setMerchantRef] = useState7(null);
|
|
2698
|
+
const [payError, setPayError] = useState7(null);
|
|
2294
2699
|
const {} = usePaymentPolling2({
|
|
2295
2700
|
client: client.api,
|
|
2296
2701
|
merchantReference: merchantRef,
|
|
@@ -2339,20 +2744,20 @@ function CheckoutModal({
|
|
|
2339
2744
|
const total = cart?.total || 0;
|
|
2340
2745
|
const backdropStyle = { ...customStyles, fontSize: "15px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', zIndex: 999999 };
|
|
2341
2746
|
return createPortal3(
|
|
2342
|
-
/* @__PURE__ */
|
|
2747
|
+
/* @__PURE__ */ jsx10(
|
|
2343
2748
|
"div",
|
|
2344
2749
|
{
|
|
2345
2750
|
className: "hsk-checkout-backdrop-full",
|
|
2346
2751
|
style: backdropStyle,
|
|
2347
2752
|
"data-hsk-theme": hskThemeAttr,
|
|
2348
|
-
children: /* @__PURE__ */
|
|
2753
|
+
children: /* @__PURE__ */ jsxs8(
|
|
2349
2754
|
"div",
|
|
2350
2755
|
{
|
|
2351
2756
|
className: "hsk-checkout-modal-full",
|
|
2352
2757
|
style: customStyles,
|
|
2353
2758
|
"data-hsk-theme": hskThemeAttr,
|
|
2354
2759
|
children: [
|
|
2355
|
-
/* @__PURE__ */
|
|
2760
|
+
/* @__PURE__ */ jsx10(
|
|
2356
2761
|
"button",
|
|
2357
2762
|
{
|
|
2358
2763
|
onClick: (e) => {
|
|
@@ -2362,71 +2767,71 @@ function CheckoutModal({
|
|
|
2362
2767
|
},
|
|
2363
2768
|
className: "hsk-checkout-close-x",
|
|
2364
2769
|
"aria-label": "Close checkout",
|
|
2365
|
-
children: /* @__PURE__ */
|
|
2366
|
-
/* @__PURE__ */
|
|
2367
|
-
/* @__PURE__ */
|
|
2770
|
+
children: /* @__PURE__ */ jsxs8("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2771
|
+
/* @__PURE__ */ jsx10("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2772
|
+
/* @__PURE__ */ jsx10("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2368
2773
|
] })
|
|
2369
2774
|
}
|
|
2370
2775
|
),
|
|
2371
|
-
/* @__PURE__ */
|
|
2372
|
-
/* @__PURE__ */
|
|
2776
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-checkout-panel-left", children: /* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-left-content", children: [
|
|
2777
|
+
/* @__PURE__ */ jsxs8("button", { onClick: (e) => {
|
|
2373
2778
|
e.preventDefault();
|
|
2374
2779
|
e.stopPropagation();
|
|
2375
2780
|
onClose();
|
|
2376
2781
|
}, className: "hsk-checkout-back-btn", children: [
|
|
2377
|
-
/* @__PURE__ */
|
|
2378
|
-
/* @__PURE__ */
|
|
2379
|
-
/* @__PURE__ */
|
|
2782
|
+
/* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2783
|
+
/* @__PURE__ */ jsx10("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
|
|
2784
|
+
/* @__PURE__ */ jsx10("polyline", { points: "12 19 5 12 12 5" })
|
|
2380
2785
|
] }),
|
|
2381
2786
|
"Back to store"
|
|
2382
2787
|
] }),
|
|
2383
|
-
/* @__PURE__ */
|
|
2384
|
-
/* @__PURE__ */
|
|
2385
|
-
/* @__PURE__ */
|
|
2386
|
-
/* @__PURE__ */
|
|
2788
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-checkout-store-info", children: /* @__PURE__ */ jsx10("h2", { children: "Secure Checkout" }) }),
|
|
2789
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-amount-due", children: [
|
|
2790
|
+
/* @__PURE__ */ jsx10("span", { className: "hsk-checkout-label-muted", children: "Pay total" }),
|
|
2791
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-grand-total", children: [
|
|
2387
2792
|
currency,
|
|
2388
2793
|
" ",
|
|
2389
2794
|
total.toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
2390
2795
|
] })
|
|
2391
2796
|
] }),
|
|
2392
|
-
cartLoading || !cart ? /* @__PURE__ */
|
|
2393
|
-
/* @__PURE__ */
|
|
2394
|
-
item.image ? /* @__PURE__ */
|
|
2395
|
-
/* @__PURE__ */
|
|
2797
|
+
cartLoading || !cart ? /* @__PURE__ */ jsx10("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ jsx10("div", { className: "hsk-checkout-items-list-wrap", children: /* @__PURE__ */ jsx10("ul", { className: "hsk-checkout-items-list", children: cart.items.map((item) => /* @__PURE__ */ jsxs8("li", { className: "hsk-checkout-item-row", children: [
|
|
2798
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-item-img-container", children: [
|
|
2799
|
+
item.image ? /* @__PURE__ */ jsx10("img", { src: item.image, alt: item.name, className: "hsk-checkout-item-img" }) : /* @__PURE__ */ jsx10("div", { className: "hsk-checkout-item-img-placeholder", children: "\u{1F6D2}" }),
|
|
2800
|
+
/* @__PURE__ */ jsx10("span", { className: "hsk-checkout-item-qty-badge", children: item.quantity })
|
|
2396
2801
|
] }),
|
|
2397
|
-
/* @__PURE__ */
|
|
2398
|
-
/* @__PURE__ */
|
|
2802
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-checkout-item-details", children: /* @__PURE__ */ jsx10("span", { className: "hsk-checkout-item-name", children: item.name }) }),
|
|
2803
|
+
/* @__PURE__ */ jsxs8("span", { className: "hsk-checkout-item-price", children: [
|
|
2399
2804
|
item.currency,
|
|
2400
2805
|
" ",
|
|
2401
2806
|
(item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
2402
2807
|
] })
|
|
2403
2808
|
] }, item.id)) }) })
|
|
2404
2809
|
] }) }),
|
|
2405
|
-
/* @__PURE__ */
|
|
2406
|
-
/* @__PURE__ */
|
|
2407
|
-
/* @__PURE__ */
|
|
2408
|
-
/* @__PURE__ */
|
|
2810
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-checkout-panel-right", children: /* @__PURE__ */ jsx10("div", { className: "hsk-checkout-right-content", children: phase === "done" ? /* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-status-card success", children: [
|
|
2811
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-status-icon-wrap success", children: /* @__PURE__ */ jsxs8("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2812
|
+
/* @__PURE__ */ jsx10("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
|
|
2813
|
+
/* @__PURE__ */ jsx10("polyline", { points: "22 4 12 14.01 9 11.01" })
|
|
2409
2814
|
] }) }),
|
|
2410
|
-
/* @__PURE__ */
|
|
2411
|
-
/* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */
|
|
2413
|
-
] }) : phase === "awaiting" ? /* @__PURE__ */
|
|
2414
|
-
/* @__PURE__ */
|
|
2415
|
-
/* @__PURE__ */
|
|
2416
|
-
/* @__PURE__ */
|
|
2815
|
+
/* @__PURE__ */ jsx10("h3", { children: "Payment Successful!" }),
|
|
2816
|
+
/* @__PURE__ */ jsx10("p", { children: "Your transaction has been confirmed. Thank you for your order!" }),
|
|
2817
|
+
/* @__PURE__ */ jsx10("button", { onClick: onClose, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Continue Shopping" })
|
|
2818
|
+
] }) : phase === "awaiting" ? /* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-status-card awaiting", children: [
|
|
2819
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-status-spinner-wrap", children: /* @__PURE__ */ jsx10("div", { className: "hsk-status-spinner" }) }),
|
|
2820
|
+
/* @__PURE__ */ jsx10("h3", { children: "Confirm payment on your phone" }),
|
|
2821
|
+
/* @__PURE__ */ jsxs8("p", { children: [
|
|
2417
2822
|
"We've sent an M-Pesa STK push prompt to ",
|
|
2418
|
-
/* @__PURE__ */
|
|
2823
|
+
/* @__PURE__ */ jsxs8("strong", { children: [
|
|
2419
2824
|
"254",
|
|
2420
2825
|
phone
|
|
2421
2826
|
] }),
|
|
2422
2827
|
"."
|
|
2423
2828
|
] }),
|
|
2424
|
-
/* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
2829
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-stk-instructions", children: [
|
|
2830
|
+
/* @__PURE__ */ jsx10("p", { children: "1. Check your phone lockscreen for the M-Pesa prompt." }),
|
|
2831
|
+
/* @__PURE__ */ jsx10("p", { children: "2. Enter your M-Pesa PIN and press OK." }),
|
|
2832
|
+
/* @__PURE__ */ jsx10("p", { children: "3. Wait here \u2014 this page auto-updates once confirmed." })
|
|
2428
2833
|
] }),
|
|
2429
|
-
/* @__PURE__ */
|
|
2834
|
+
/* @__PURE__ */ jsx10(
|
|
2430
2835
|
"button",
|
|
2431
2836
|
{
|
|
2432
2837
|
onClick: () => {
|
|
@@ -2437,43 +2842,43 @@ function CheckoutModal({
|
|
|
2437
2842
|
children: "Cancel payment"
|
|
2438
2843
|
}
|
|
2439
2844
|
)
|
|
2440
|
-
] }) : phase === "cancelled" ? /* @__PURE__ */
|
|
2441
|
-
/* @__PURE__ */
|
|
2442
|
-
/* @__PURE__ */
|
|
2443
|
-
/* @__PURE__ */
|
|
2845
|
+
] }) : phase === "cancelled" ? /* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-status-card cancelled", children: [
|
|
2846
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-status-icon-wrap cancelled", children: /* @__PURE__ */ jsxs8("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2847
|
+
/* @__PURE__ */ jsx10("path", { d: "m15 9-6 6M9 9l6 6" }),
|
|
2848
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "10" })
|
|
2444
2849
|
] }) }),
|
|
2445
|
-
/* @__PURE__ */
|
|
2446
|
-
/* @__PURE__ */
|
|
2447
|
-
/* @__PURE__ */
|
|
2448
|
-
/* @__PURE__ */
|
|
2850
|
+
/* @__PURE__ */ jsx10("h3", { children: "Payment Cancelled" }),
|
|
2851
|
+
/* @__PURE__ */ jsx10("p", { children: "No charge was made. You can update your phone number and try again whenever you're ready." }),
|
|
2852
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-status-actions", children: [
|
|
2853
|
+
/* @__PURE__ */ jsx10("button", { onClick: () => {
|
|
2449
2854
|
setPhase("idle");
|
|
2450
2855
|
setPayError(null);
|
|
2451
2856
|
}, className: "hsk-pay-btn hsk-btn-primary", children: "Try again" }),
|
|
2452
|
-
/* @__PURE__ */
|
|
2857
|
+
/* @__PURE__ */ jsx10("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
|
|
2453
2858
|
] })
|
|
2454
|
-
] }) : phase === "failed" ? /* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2456
|
-
/* @__PURE__ */
|
|
2457
|
-
/* @__PURE__ */
|
|
2458
|
-
/* @__PURE__ */
|
|
2859
|
+
] }) : phase === "failed" ? /* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-status-card failed", children: [
|
|
2860
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-status-icon-wrap failed", children: /* @__PURE__ */ jsxs8("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2861
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "10" }),
|
|
2862
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
2863
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
2459
2864
|
] }) }),
|
|
2460
|
-
/* @__PURE__ */
|
|
2461
|
-
/* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
2463
|
-
/* @__PURE__ */
|
|
2865
|
+
/* @__PURE__ */ jsx10("h3", { children: "Payment Failed" }),
|
|
2866
|
+
/* @__PURE__ */ jsx10("p", { className: "hsk-checkout-error-text", children: payError || "Could not verify M-Pesa transaction. Please check your phone and try again." }),
|
|
2867
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-status-actions", children: [
|
|
2868
|
+
/* @__PURE__ */ jsx10("button", { onClick: () => {
|
|
2464
2869
|
setPhase("idle");
|
|
2465
2870
|
setPayError(null);
|
|
2466
2871
|
}, className: "hsk-pay-btn hsk-btn-primary", children: "Try again" }),
|
|
2467
|
-
/* @__PURE__ */
|
|
2872
|
+
/* @__PURE__ */ jsx10("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
|
|
2468
2873
|
] })
|
|
2469
|
-
] }) : /* @__PURE__ */
|
|
2470
|
-
/* @__PURE__ */
|
|
2471
|
-
loadingConfig ? /* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
2474
|
-
/* @__PURE__ */
|
|
2475
|
-
/* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
2874
|
+
] }) : /* @__PURE__ */ jsxs8("div", { className: "hsk-checkout-payment-form-wrap", children: [
|
|
2875
|
+
/* @__PURE__ */ jsx10("h3", { className: "hsk-checkout-section-title", children: "Payment details" }),
|
|
2876
|
+
loadingConfig ? /* @__PURE__ */ jsx10("p", { className: "hsk-cart-loading", children: "Loading payment configuration..." }) : !hasPaymentMethods ? /* @__PURE__ */ jsx10("p", { className: "hsk-checkout-error", children: "No payment methods configured for this store." }) : /* @__PURE__ */ jsxs8("form", { onSubmit: handlePay, className: "hsk-stripe-checkout-form", children: [
|
|
2877
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-form-group", children: [
|
|
2878
|
+
/* @__PURE__ */ jsx10("label", { className: "hsk-form-label", children: "M-Pesa Mobile Number" }),
|
|
2879
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-phone-input-container", children: [
|
|
2880
|
+
/* @__PURE__ */ jsx10("span", { className: "hsk-phone-prefix", children: "254" }),
|
|
2881
|
+
/* @__PURE__ */ jsx10(
|
|
2477
2882
|
"input",
|
|
2478
2883
|
{
|
|
2479
2884
|
type: "tel",
|
|
@@ -2487,11 +2892,11 @@ function CheckoutModal({
|
|
|
2487
2892
|
}
|
|
2488
2893
|
)
|
|
2489
2894
|
] }),
|
|
2490
|
-
/* @__PURE__ */
|
|
2895
|
+
/* @__PURE__ */ jsx10("span", { className: "hsk-form-hint", children: "Enter your 9-digit number (e.g. 712345678)" })
|
|
2491
2896
|
] }),
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
/* @__PURE__ */
|
|
2494
|
-
/* @__PURE__ */
|
|
2897
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-form-group", children: [
|
|
2898
|
+
/* @__PURE__ */ jsx10("label", { className: "hsk-form-label", children: "Email address" }),
|
|
2899
|
+
/* @__PURE__ */ jsx10(
|
|
2495
2900
|
"input",
|
|
2496
2901
|
{
|
|
2497
2902
|
type: "email",
|
|
@@ -2502,10 +2907,10 @@ function CheckoutModal({
|
|
|
2502
2907
|
}
|
|
2503
2908
|
)
|
|
2504
2909
|
] }),
|
|
2505
|
-
/* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
/* @__PURE__ */
|
|
2508
|
-
/* @__PURE__ */
|
|
2910
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-form-row", children: [
|
|
2911
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-form-group", children: [
|
|
2912
|
+
/* @__PURE__ */ jsx10("label", { className: "hsk-form-label", children: "First Name" }),
|
|
2913
|
+
/* @__PURE__ */ jsx10(
|
|
2509
2914
|
"input",
|
|
2510
2915
|
{
|
|
2511
2916
|
type: "text",
|
|
@@ -2516,9 +2921,9 @@ function CheckoutModal({
|
|
|
2516
2921
|
}
|
|
2517
2922
|
)
|
|
2518
2923
|
] }),
|
|
2519
|
-
/* @__PURE__ */
|
|
2520
|
-
/* @__PURE__ */
|
|
2521
|
-
/* @__PURE__ */
|
|
2924
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-form-group", children: [
|
|
2925
|
+
/* @__PURE__ */ jsx10("label", { className: "hsk-form-label", children: "Last Name" }),
|
|
2926
|
+
/* @__PURE__ */ jsx10(
|
|
2522
2927
|
"input",
|
|
2523
2928
|
{
|
|
2524
2929
|
type: "text",
|
|
@@ -2530,14 +2935,14 @@ function CheckoutModal({
|
|
|
2530
2935
|
)
|
|
2531
2936
|
] })
|
|
2532
2937
|
] }),
|
|
2533
|
-
payError && /* @__PURE__ */
|
|
2534
|
-
/* @__PURE__ */
|
|
2938
|
+
payError && /* @__PURE__ */ jsx10("div", { className: "hsk-form-error-banner", children: payError }),
|
|
2939
|
+
/* @__PURE__ */ jsxs8("button", { type: "submit", className: "hsk-checkout-submit-btn", children: [
|
|
2535
2940
|
"Pay ",
|
|
2536
2941
|
currency,
|
|
2537
2942
|
" ",
|
|
2538
2943
|
total.toLocaleString()
|
|
2539
2944
|
] }),
|
|
2540
|
-
/* @__PURE__ */
|
|
2945
|
+
/* @__PURE__ */ jsx10("div", { className: "hsk-checkout-footer-brand", children: /* @__PURE__ */ jsx10("span", { children: "Powered by Akropolys" }) })
|
|
2541
2946
|
] })
|
|
2542
2947
|
] }) }) })
|
|
2543
2948
|
]
|
|
@@ -2550,17 +2955,17 @@ function CheckoutModal({
|
|
|
2550
2955
|
}
|
|
2551
2956
|
|
|
2552
2957
|
// src/components/CartDrawer.tsx
|
|
2553
|
-
import { Fragment as Fragment5, jsx as
|
|
2958
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2554
2959
|
function CartDrawer({
|
|
2555
2960
|
trigger,
|
|
2556
2961
|
className,
|
|
2557
2962
|
theme
|
|
2558
2963
|
}) {
|
|
2559
2964
|
const { cart, loading } = useCart3();
|
|
2560
|
-
const [open, setOpen] =
|
|
2561
|
-
const [showCheckout, setShowCheckout] =
|
|
2562
|
-
const [mounted, setMounted] =
|
|
2563
|
-
const client =
|
|
2965
|
+
const [open, setOpen] = useState8(false);
|
|
2966
|
+
const [showCheckout, setShowCheckout] = useState8(false);
|
|
2967
|
+
const [mounted, setMounted] = useState8(false);
|
|
2968
|
+
const client = useAkropolysContext6();
|
|
2564
2969
|
useEffect6(() => {
|
|
2565
2970
|
setMounted(true);
|
|
2566
2971
|
const handleTriggerCheckout = () => {
|
|
@@ -2601,8 +3006,8 @@ function CartDrawer({
|
|
|
2601
3006
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2602
3007
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2603
3008
|
} : void 0;
|
|
2604
|
-
return /* @__PURE__ */
|
|
2605
|
-
trigger ? /* @__PURE__ */
|
|
3009
|
+
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3010
|
+
trigger ? /* @__PURE__ */ jsx11("div", { onClick: () => setOpen(true), style: { display: "inline-block" }, children: trigger }) : /* @__PURE__ */ jsxs9(
|
|
2606
3011
|
"button",
|
|
2607
3012
|
{
|
|
2608
3013
|
onClick: () => setOpen(true),
|
|
@@ -2611,24 +3016,24 @@ function CartDrawer({
|
|
|
2611
3016
|
"data-hsk-theme": hskThemeAttr,
|
|
2612
3017
|
"aria-label": "Open cart",
|
|
2613
3018
|
children: [
|
|
2614
|
-
/* @__PURE__ */
|
|
2615
|
-
/* @__PURE__ */
|
|
2616
|
-
/* @__PURE__ */
|
|
2617
|
-
/* @__PURE__ */
|
|
3019
|
+
/* @__PURE__ */ jsxs9("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3020
|
+
/* @__PURE__ */ jsx11("circle", { cx: "9", cy: "21", r: "1" }),
|
|
3021
|
+
/* @__PURE__ */ jsx11("circle", { cx: "20", cy: "21", r: "1" }),
|
|
3022
|
+
/* @__PURE__ */ jsx11("path", { d: "M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" })
|
|
2618
3023
|
] }),
|
|
2619
|
-
cart && cart.item_count > 0 ? /* @__PURE__ */
|
|
3024
|
+
cart && cart.item_count > 0 ? /* @__PURE__ */ jsx11("span", { className: "hsk-cart-trigger-badge", children: cart.item_count }) : null
|
|
2620
3025
|
]
|
|
2621
3026
|
}
|
|
2622
3027
|
),
|
|
2623
3028
|
open && mounted && createPortal4(
|
|
2624
|
-
/* @__PURE__ */
|
|
3029
|
+
/* @__PURE__ */ jsx11(
|
|
2625
3030
|
"div",
|
|
2626
3031
|
{
|
|
2627
3032
|
className: "hsk-cart-backdrop",
|
|
2628
3033
|
style: customStyles,
|
|
2629
3034
|
"data-hsk-theme": hskThemeAttr,
|
|
2630
3035
|
onClick: () => setOpen(false),
|
|
2631
|
-
children: /* @__PURE__ */
|
|
3036
|
+
children: /* @__PURE__ */ jsxs9(
|
|
2632
3037
|
"div",
|
|
2633
3038
|
{
|
|
2634
3039
|
className: "hsk-cart-bottom-sheet",
|
|
@@ -2636,36 +3041,36 @@ function CartDrawer({
|
|
|
2636
3041
|
"data-hsk-theme": hskThemeAttr,
|
|
2637
3042
|
onClick: (e) => e.stopPropagation(),
|
|
2638
3043
|
children: [
|
|
2639
|
-
/* @__PURE__ */
|
|
2640
|
-
/* @__PURE__ */
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
3044
|
+
/* @__PURE__ */ jsx11("div", { className: "hsk-cart-sheet-handle" }),
|
|
3045
|
+
/* @__PURE__ */ jsxs9("div", { className: "hsk-cart-sheet-header", children: [
|
|
3046
|
+
/* @__PURE__ */ jsx11("h2", { children: "Your Cart" }),
|
|
3047
|
+
/* @__PURE__ */ jsx11("button", { onClick: () => setOpen(false), className: "hsk-close-btn", children: "\xD7" })
|
|
2643
3048
|
] }),
|
|
2644
|
-
/* @__PURE__ */
|
|
2645
|
-
item.image && /* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
/* @__PURE__ */
|
|
2648
|
-
/* @__PURE__ */
|
|
3049
|
+
/* @__PURE__ */ jsx11("div", { className: "hsk-cart-sheet-content", children: loading && !cart ? /* @__PURE__ */ jsx11("div", { className: "hsk-cart-loading", children: "Loading cart..." }) : !cart || cart.items.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "hsk-cart-empty", children: "Your cart is empty." }) : /* @__PURE__ */ jsx11("ul", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ jsxs9("li", { className: "hsk-cart-item", children: [
|
|
3050
|
+
item.image && /* @__PURE__ */ jsx11("img", { src: item.image, alt: item.name, className: "hsk-cart-item-img" }),
|
|
3051
|
+
/* @__PURE__ */ jsxs9("div", { className: "hsk-cart-item-info", children: [
|
|
3052
|
+
/* @__PURE__ */ jsx11("span", { className: "hsk-cart-item-name", children: item.name }),
|
|
3053
|
+
/* @__PURE__ */ jsxs9("span", { className: "hsk-cart-item-price", children: [
|
|
2649
3054
|
item.currency,
|
|
2650
3055
|
" ",
|
|
2651
3056
|
item.price_numeric.toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
2652
3057
|
] })
|
|
2653
3058
|
] }),
|
|
2654
|
-
/* @__PURE__ */
|
|
3059
|
+
/* @__PURE__ */ jsxs9("div", { className: "hsk-cart-item-qty", children: [
|
|
2655
3060
|
"x",
|
|
2656
3061
|
item.quantity
|
|
2657
3062
|
] })
|
|
2658
3063
|
] }, item.id)) }) }),
|
|
2659
|
-
cart && cart.items.length > 0 && /* @__PURE__ */
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
2662
|
-
/* @__PURE__ */
|
|
3064
|
+
cart && cart.items.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "hsk-cart-sheet-footer", children: [
|
|
3065
|
+
/* @__PURE__ */ jsxs9("div", { className: "hsk-cart-total", children: [
|
|
3066
|
+
/* @__PURE__ */ jsx11("span", { children: "Total" }),
|
|
3067
|
+
/* @__PURE__ */ jsxs9("span", { children: [
|
|
2663
3068
|
cart.currency,
|
|
2664
3069
|
" ",
|
|
2665
3070
|
cart.total.toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
2666
3071
|
] })
|
|
2667
3072
|
] }),
|
|
2668
|
-
/* @__PURE__ */
|
|
3073
|
+
/* @__PURE__ */ jsx11("button", { onClick: handleCheckout, className: "hsk-checkout-btn", children: "Checkout securely" })
|
|
2669
3074
|
] })
|
|
2670
3075
|
]
|
|
2671
3076
|
}
|
|
@@ -2674,7 +3079,7 @@ function CartDrawer({
|
|
|
2674
3079
|
),
|
|
2675
3080
|
document.body
|
|
2676
3081
|
),
|
|
2677
|
-
showCheckout && mounted && /* @__PURE__ */
|
|
3082
|
+
showCheckout && mounted && /* @__PURE__ */ jsx11(
|
|
2678
3083
|
CheckoutModal,
|
|
2679
3084
|
{
|
|
2680
3085
|
onClose: () => {
|
|
@@ -2697,6 +3102,8 @@ export {
|
|
|
2697
3102
|
KikuButton,
|
|
2698
3103
|
ChatWidget as KikuChat,
|
|
2699
3104
|
SearchBar,
|
|
2700
|
-
Sparkle
|
|
3105
|
+
Sparkle,
|
|
3106
|
+
VisualSearch,
|
|
3107
|
+
VoiceButton
|
|
2701
3108
|
};
|
|
2702
3109
|
//# sourceMappingURL=index.mjs.map
|