@akropolys/kiku 1.5.18 → 1.6.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/README.md +23 -167
- package/dist/index.d.mts +3 -20
- package/dist/index.d.ts +3 -20
- package/dist/index.js +30 -558
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -548
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +0 -4
- package/dist/styles.css.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -21,10 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var src_exports = {};
|
|
23
23
|
__export(src_exports, {
|
|
24
|
-
CartBadge: () => CartBadge,
|
|
25
|
-
CartDrawer: () => CartDrawer,
|
|
26
24
|
ChatWidget: () => ChatWidget,
|
|
27
|
-
CheckoutModal: () => CheckoutModal,
|
|
28
25
|
ComparisonMatrix: () => ComparisonMatrix,
|
|
29
26
|
KikuButton: () => KikuButton,
|
|
30
27
|
KikuChat: () => ChatWidget,
|
|
@@ -106,7 +103,7 @@ function SearchBar({
|
|
|
106
103
|
}
|
|
107
104
|
ignoreNextQueryChange.current = true;
|
|
108
105
|
setOpen(false);
|
|
109
|
-
setQuery(r.
|
|
106
|
+
setQuery(r.entity.title ?? r.entity.name ?? "");
|
|
110
107
|
onSelect?.(r);
|
|
111
108
|
};
|
|
112
109
|
const handleCommitSearch = () => {
|
|
@@ -186,8 +183,8 @@ function SearchBar({
|
|
|
186
183
|
children: [
|
|
187
184
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "hsk-sb-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SearchIcon, {}) }),
|
|
188
185
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hsk-sb-row-body", children: [
|
|
189
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hsk-sb-row-title", children: r.
|
|
190
|
-
(r.
|
|
186
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hsk-sb-row-title", children: r.entity.title ?? r.entity.name }),
|
|
187
|
+
(r.entity.category || r.entity.brand) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hsk-sb-row-sub", children: r.entity.category ?? r.entity.brand })
|
|
191
188
|
] })
|
|
192
189
|
]
|
|
193
190
|
},
|
|
@@ -688,7 +685,7 @@ I couldn't find any matching products in the store.`;
|
|
|
688
685
|
}) }) });
|
|
689
686
|
}
|
|
690
687
|
const featured = sources.filter((src) => src.id && referencedIds.includes(src.id));
|
|
691
|
-
const general =
|
|
688
|
+
const general = referencedIds.length > 0 ? [] : sources.filter((src) => !src.id || !referencedIds.includes(src.id));
|
|
692
689
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-sources-container", children: [
|
|
693
690
|
featured.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-sources-group", style: { marginBottom: "10px" }, children: [
|
|
694
691
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-sources-group-title", children: "\u2B50 Featured in response" }),
|
|
@@ -800,7 +797,6 @@ var import_react5 = require("react");
|
|
|
800
797
|
var import_react_dom = require("react-dom");
|
|
801
798
|
var import_sdk5 = require("@akropolys/sdk");
|
|
802
799
|
var import_sdk6 = require("@akropolys/sdk");
|
|
803
|
-
var import_sdk7 = require("@akropolys/sdk");
|
|
804
800
|
|
|
805
801
|
// src/components/ComparisonMatrix.tsx
|
|
806
802
|
var import_sdk4 = require("@akropolys/sdk");
|
|
@@ -1334,7 +1330,7 @@ function ActionPills({ cart, actionType, onSend, loading }) {
|
|
|
1334
1330
|
)) });
|
|
1335
1331
|
}
|
|
1336
1332
|
function SourcesCarousel({ sources, defaultCurrency, onSelectSource, referencedIds = [] }) {
|
|
1337
|
-
const client = (0,
|
|
1333
|
+
const client = (0, import_sdk6.useAkropolysContext)();
|
|
1338
1334
|
const isProperty = client?.vertical === "property";
|
|
1339
1335
|
const railRef = (0, import_react5.useRef)(null);
|
|
1340
1336
|
const [showNext, setShowNext] = (0, import_react5.useState)(false);
|
|
@@ -1360,7 +1356,7 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, referencedI
|
|
|
1360
1356
|
railRef.current?.scrollBy({ left: 170, behavior: "smooth" });
|
|
1361
1357
|
};
|
|
1362
1358
|
const referenced = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
1363
|
-
const display =
|
|
1359
|
+
const display = referencedIds.length > 0 ? referenced : sources;
|
|
1364
1360
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-sources-wrap", children: [
|
|
1365
1361
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-sources", ref: railRef, children: display.map((src, si) => {
|
|
1366
1362
|
const isReferenced = !!(src.id && referencedIds.includes(src.id));
|
|
@@ -1434,7 +1430,7 @@ function SmartContextPills({
|
|
|
1434
1430
|
onSend,
|
|
1435
1431
|
loading
|
|
1436
1432
|
}) {
|
|
1437
|
-
const client = (0,
|
|
1433
|
+
const client = (0, import_sdk6.useAkropolysContext)();
|
|
1438
1434
|
const isProperty = client?.vertical === "property";
|
|
1439
1435
|
if (!intent) return null;
|
|
1440
1436
|
const pills = [];
|
|
@@ -1664,7 +1660,7 @@ function ChatModal({
|
|
|
1664
1660
|
enableVision = false,
|
|
1665
1661
|
visionCategoryHint
|
|
1666
1662
|
}) {
|
|
1667
|
-
const client = (0,
|
|
1663
|
+
const client = (0, import_sdk6.useAkropolysContext)();
|
|
1668
1664
|
const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset, referencedIds } = (0, import_sdk5.useKiku)();
|
|
1669
1665
|
const [input, setInput] = (0, import_react5.useState)("");
|
|
1670
1666
|
const [attachments, setAttachments] = (0, import_react5.useState)([]);
|
|
@@ -1748,31 +1744,15 @@ function ChatModal({
|
|
|
1748
1744
|
}
|
|
1749
1745
|
return "";
|
|
1750
1746
|
});
|
|
1751
|
-
const [merchantRef, setMerchantRef] = (0, import_react5.useState)(null);
|
|
1752
1747
|
const [paymentPhase, setPaymentPhase] = (0, import_react5.useState)("idle");
|
|
1753
1748
|
const [memoryKey, setMemoryKey] = (0, import_react5.useState)(null);
|
|
1754
1749
|
const [sessions, setSessions] = (0, import_react5.useState)(() => loadSessions());
|
|
1755
1750
|
const [sidebarOpen, setSidebarOpen] = (0, import_react5.useState)(false);
|
|
1756
1751
|
const [replayMessages, setReplayMessages] = (0, import_react5.useState)(null);
|
|
1757
|
-
const { status: pollStatus } = (0, import_sdk6.usePaymentPolling)({
|
|
1758
|
-
client: client.api,
|
|
1759
|
-
merchantReference: merchantRef,
|
|
1760
|
-
onSuccess: () => {
|
|
1761
|
-
setPaymentPhase("done");
|
|
1762
|
-
setMerchantRef(null);
|
|
1763
|
-
},
|
|
1764
|
-
onFailure: () => {
|
|
1765
|
-
setPaymentPhase("failed");
|
|
1766
|
-
setMerchantRef(null);
|
|
1767
|
-
}
|
|
1768
|
-
});
|
|
1769
1752
|
(0, import_react5.useEffect)(() => {
|
|
1770
1753
|
if (!lastAction) return;
|
|
1771
1754
|
if (lastAction.type === "request_phone") {
|
|
1772
1755
|
setPaymentPhase("prompt_phone");
|
|
1773
|
-
} else if (lastAction.type === "awaiting_payment") {
|
|
1774
|
-
setMerchantRef(lastAction.merchantReference ?? null);
|
|
1775
|
-
setPaymentPhase("awaiting");
|
|
1776
1756
|
}
|
|
1777
1757
|
}, [lastAction]);
|
|
1778
1758
|
const isStringTheme = typeof theme === "string";
|
|
@@ -1829,7 +1809,6 @@ function ChatModal({
|
|
|
1829
1809
|
reset();
|
|
1830
1810
|
setReplayMessages(null);
|
|
1831
1811
|
setPaymentPhase("idle");
|
|
1832
|
-
setMerchantRef(null);
|
|
1833
1812
|
}, [reset, saveCurrentSession]);
|
|
1834
1813
|
const handleSourceClick = (src) => {
|
|
1835
1814
|
setSelectedProduct(src);
|
|
@@ -2117,56 +2096,6 @@ function ChatModal({
|
|
|
2117
2096
|
] })
|
|
2118
2097
|
] }) }) })
|
|
2119
2098
|
] }),
|
|
2120
|
-
!replayMessages && paymentPhase === "awaiting" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--awaiting", children: [
|
|
2121
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-pulse-ring" }),
|
|
2122
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: "2rem" }, children: "\u{1F4F1}" }) }),
|
|
2123
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-label", style: { fontWeight: 600 }, children: "Check your phone" }),
|
|
2124
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "hsk-cb-payment-sub", children: [
|
|
2125
|
-
"An M-Pesa STK push has been sent.",
|
|
2126
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("br", {}),
|
|
2127
|
-
"Enter your PIN to complete payment."
|
|
2128
|
-
] }),
|
|
2129
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-dots", children: [
|
|
2130
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
|
|
2131
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" }),
|
|
2132
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-dot hsk-cb-dot--amber" })
|
|
2133
|
-
] })
|
|
2134
|
-
] }),
|
|
2135
|
-
!replayMessages && paymentPhase === "done" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--success", children: [
|
|
2136
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-success-ring" }),
|
|
2137
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: "2.5rem" }, children: "\u2705" }) }),
|
|
2138
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-label", children: "Payment complete!" }),
|
|
2139
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-sub", children: "Thank you for your order. A confirmation has been sent." })
|
|
2140
|
-
] }),
|
|
2141
|
-
!replayMessages && paymentPhase === "failed" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-prompt hsk-cb-payment-prompt--failed", children: [
|
|
2142
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hsk-cb-payment-icon-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: "2.5rem" }, children: "\u274C" }) }),
|
|
2143
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-label", children: "Payment failed or timed out" }),
|
|
2144
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "hsk-cb-payment-sub", children: "Please check your M-Pesa PIN and try again, or contact support." }),
|
|
2145
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-payment-actions", children: [
|
|
2146
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2147
|
-
"button",
|
|
2148
|
-
{
|
|
2149
|
-
className: "hsk-cb-pay-submit",
|
|
2150
|
-
onClick: () => {
|
|
2151
|
-
setPaymentPhase("prompt_phone");
|
|
2152
|
-
setMerchantRef(null);
|
|
2153
|
-
},
|
|
2154
|
-
children: "Try again"
|
|
2155
|
-
}
|
|
2156
|
-
),
|
|
2157
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2158
|
-
"button",
|
|
2159
|
-
{
|
|
2160
|
-
className: "hsk-cb-pay-secondary",
|
|
2161
|
-
onClick: () => {
|
|
2162
|
-
setPaymentPhase("idle");
|
|
2163
|
-
setMerchantRef(null);
|
|
2164
|
-
},
|
|
2165
|
-
children: "Cancel"
|
|
2166
|
-
}
|
|
2167
|
-
)
|
|
2168
|
-
] })
|
|
2169
|
-
] }),
|
|
2170
2099
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: bottomRef, style: { height: 1 } })
|
|
2171
2100
|
] }),
|
|
2172
2101
|
!replayMessages && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
|
|
@@ -2349,7 +2278,7 @@ function KikuButton({
|
|
|
2349
2278
|
// src/components/Sparkle.tsx
|
|
2350
2279
|
var import_react6 = require("react");
|
|
2351
2280
|
var import_react_dom2 = require("react-dom");
|
|
2352
|
-
var
|
|
2281
|
+
var import_sdk7 = require("@akropolys/sdk");
|
|
2353
2282
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2354
2283
|
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2355
2284
|
"svg",
|
|
@@ -2460,11 +2389,11 @@ function SparkleModal({
|
|
|
2460
2389
|
classNames = {},
|
|
2461
2390
|
product: initialProduct
|
|
2462
2391
|
}) {
|
|
2463
|
-
const client = (0,
|
|
2392
|
+
const client = (0, import_sdk7.useAkropolysContext)();
|
|
2464
2393
|
const [fetchedProduct, setFetchedProduct] = (0, import_react6.useState)(null);
|
|
2465
2394
|
const displayProduct = initialProduct || fetchedProduct;
|
|
2466
|
-
const { results, loading: searchLoading, search } = (0,
|
|
2467
|
-
const { messages, sources, loading: chatLoading, error: chatError, send } = (0,
|
|
2395
|
+
const { results, loading: searchLoading, search } = (0, import_sdk7.useSearch)({ type: "vector" });
|
|
2396
|
+
const { messages, sources, loading: chatLoading, error: chatError, send } = (0, import_sdk7.useKiku)();
|
|
2468
2397
|
const [chatInput, setChatInput] = (0, import_react6.useState)("");
|
|
2469
2398
|
const [isMobile, setIsMobile] = (0, import_react6.useState)(false);
|
|
2470
2399
|
const [showSpecs, setShowSpecs] = (0, import_react6.useState)(false);
|
|
@@ -2475,7 +2404,7 @@ function SparkleModal({
|
|
|
2475
2404
|
if (!initialProduct && !fetchedProduct) {
|
|
2476
2405
|
client.api.searchVector(productName, 1).then((res) => {
|
|
2477
2406
|
if (res.results && res.results.length > 0) {
|
|
2478
|
-
setFetchedProduct(res.results[0].
|
|
2407
|
+
setFetchedProduct(res.results[0].entity);
|
|
2479
2408
|
}
|
|
2480
2409
|
}).catch((err) => console.error("[Akropolys] Failed to fetch product details", err));
|
|
2481
2410
|
}
|
|
@@ -2508,7 +2437,7 @@ function SparkleModal({
|
|
|
2508
2437
|
const prevent = onNavigate?.(r);
|
|
2509
2438
|
if (prevent !== false) {
|
|
2510
2439
|
onClose();
|
|
2511
|
-
if (r.
|
|
2440
|
+
if (r.entity.url) window.location.href = r.entity.url;
|
|
2512
2441
|
}
|
|
2513
2442
|
};
|
|
2514
2443
|
const handleSend = async (text) => {
|
|
@@ -2595,7 +2524,7 @@ Question: ${q}`;
|
|
|
2595
2524
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
|
|
2596
2525
|
idx === 0 && displayProduct && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-attachment-deck", children: [
|
|
2597
2526
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-main-card", children: [
|
|
2598
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\
|
|
2527
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2599
2528
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-main-card-info", children: [
|
|
2600
2529
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-brand", children: displayProduct.brand || displayProduct.category || "Product" }),
|
|
2601
2530
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-main-card-name", children: displayProduct.name }),
|
|
@@ -2618,8 +2547,8 @@ Question: ${q}`;
|
|
|
2618
2547
|
(() => {
|
|
2619
2548
|
const similarProducts = results.filter(
|
|
2620
2549
|
(r) => {
|
|
2621
|
-
const isSameName = !!(r.
|
|
2622
|
-
const isSameSlug = r.
|
|
2550
|
+
const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());
|
|
2551
|
+
const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();
|
|
2623
2552
|
return !isSameName && !isSameSlug;
|
|
2624
2553
|
}
|
|
2625
2554
|
);
|
|
@@ -2627,17 +2556,17 @@ Question: ${q}`;
|
|
|
2627
2556
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-inline", children: [
|
|
2628
2557
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-title", children: "Similar Products" }),
|
|
2629
2558
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-list", children: similarProducts.map((r) => {
|
|
2630
|
-
const price = parseFloat(r.
|
|
2631
|
-
const currency = r.
|
|
2559
|
+
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2560
|
+
const currency = r.entity.currency ?? "KES";
|
|
2632
2561
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2633
2562
|
"div",
|
|
2634
2563
|
{
|
|
2635
2564
|
className: "hsk-sp-mobile-similar-carousel-item",
|
|
2636
2565
|
onClick: () => handleNav(r),
|
|
2637
2566
|
children: [
|
|
2638
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.
|
|
2567
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.entity.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: r.entity.images[0], alt: r.entity.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2639
2568
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-meta", children: [
|
|
2640
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.entity.name, children: r.entity.name }),
|
|
2641
2570
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-mobile-similar-carousel-price", children: [
|
|
2642
2571
|
currency,
|
|
2643
2572
|
" ",
|
|
@@ -2741,7 +2670,7 @@ Question: ${q}`;
|
|
|
2741
2670
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-details-pane", children: [
|
|
2742
2671
|
displayProduct && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-product-profile-container", children: [
|
|
2743
2672
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-product-profile", children: [
|
|
2744
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\
|
|
2673
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2745
2674
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-details-meta", children: [
|
|
2746
2675
|
displayProduct.brand && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-brand", children: displayProduct.brand }),
|
|
2747
2676
|
displayProduct.category && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-cat", children: displayProduct.category }),
|
|
@@ -2758,7 +2687,7 @@ Question: ${q}`;
|
|
|
2758
2687
|
] }),
|
|
2759
2688
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-meta-badges", children: [
|
|
2760
2689
|
displayProduct.rating && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-rating", children: [
|
|
2761
|
-
"\
|
|
2690
|
+
"\xE2\u02DC\u2026 ",
|
|
2762
2691
|
parseFloat(displayProduct.rating.toString()).toFixed(1),
|
|
2763
2692
|
" ",
|
|
2764
2693
|
displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ""
|
|
@@ -2788,8 +2717,8 @@ Question: ${q}`;
|
|
|
2788
2717
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-results", children: (() => {
|
|
2789
2718
|
const similarProducts = results.filter(
|
|
2790
2719
|
(r) => {
|
|
2791
|
-
const isSameName = !!(r.
|
|
2792
|
-
const isSameSlug = r.
|
|
2720
|
+
const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());
|
|
2721
|
+
const isSameSlug = r.entity.slug && displayProduct?.slug && r.entity.slug.toLowerCase() === displayProduct.slug.toLowerCase();
|
|
2793
2722
|
return !isSameName && !isSameSlug;
|
|
2794
2723
|
}
|
|
2795
2724
|
);
|
|
@@ -2797,8 +2726,8 @@ Question: ${q}`;
|
|
|
2797
2726
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-empty", children: "No similar products found." });
|
|
2798
2727
|
}
|
|
2799
2728
|
return similarProducts.map((r, i) => {
|
|
2800
|
-
const price = parseFloat(r.
|
|
2801
|
-
const currency = r.
|
|
2729
|
+
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2730
|
+
const currency = r.entity.currency ?? "KES";
|
|
2802
2731
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2803
2732
|
"div",
|
|
2804
2733
|
{
|
|
@@ -2806,11 +2735,11 @@ Question: ${q}`;
|
|
|
2806
2735
|
style: { animationDelay: `${i * 55}ms`, cursor: "pointer" },
|
|
2807
2736
|
onClick: () => handleNav(r),
|
|
2808
2737
|
children: [
|
|
2809
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-img-wrap", children: r.
|
|
2738
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-img-wrap", children: r.entity.images?.[0] ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: r.entity.images[0], alt: r.entity.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2810
2739
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-body", children: [
|
|
2811
2740
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
2812
|
-
r.
|
|
2813
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-item-name", title: r.
|
|
2741
|
+
r.entity.category && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-item-cat", children: r.entity.category }),
|
|
2742
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-sp-item-name", title: r.entity.name, children: r.entity.name })
|
|
2814
2743
|
] }),
|
|
2815
2744
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
|
|
2816
2745
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-sp-item-currency", children: currency }),
|
|
@@ -2948,466 +2877,9 @@ function Sparkle({
|
|
|
2948
2877
|
)
|
|
2949
2878
|
] });
|
|
2950
2879
|
}
|
|
2951
|
-
|
|
2952
|
-
// src/components/CartBadge.tsx
|
|
2953
|
-
var import_sdk9 = require("@akropolys/sdk");
|
|
2954
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2955
|
-
function CartBadge({ className }) {
|
|
2956
|
-
const { cart } = (0, import_sdk9.useCart)();
|
|
2957
|
-
if (!cart || cart.item_count === 0) return null;
|
|
2958
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: cn("hsk-cart-badge", className), children: cart.item_count });
|
|
2959
|
-
}
|
|
2960
|
-
|
|
2961
|
-
// src/components/CartDrawer.tsx
|
|
2962
|
-
var import_react8 = require("react");
|
|
2963
|
-
var import_react_dom4 = require("react-dom");
|
|
2964
|
-
var import_sdk11 = require("@akropolys/sdk");
|
|
2965
|
-
|
|
2966
|
-
// src/components/CheckoutModal.tsx
|
|
2967
|
-
var import_react7 = require("react");
|
|
2968
|
-
var import_react_dom3 = require("react-dom");
|
|
2969
|
-
var import_sdk10 = require("@akropolys/sdk");
|
|
2970
|
-
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2971
|
-
function CheckoutModal({
|
|
2972
|
-
onClose,
|
|
2973
|
-
theme,
|
|
2974
|
-
customStyles,
|
|
2975
|
-
hskThemeAttr
|
|
2976
|
-
}) {
|
|
2977
|
-
const { cart, loading: cartLoading } = (0, import_sdk10.useCart)();
|
|
2978
|
-
const client = (0, import_sdk10.useAkropolysContext)();
|
|
2979
|
-
const [config, setConfig] = (0, import_react7.useState)(null);
|
|
2980
|
-
const [loadingConfig, setLoadingConfig] = (0, import_react7.useState)(true);
|
|
2981
|
-
const [phone, setPhone] = (0, import_react7.useState)(() => {
|
|
2982
|
-
if (typeof window !== "undefined") {
|
|
2983
|
-
return localStorage.getItem("akropolys_user_phone") || "";
|
|
2984
|
-
}
|
|
2985
|
-
return "";
|
|
2986
|
-
});
|
|
2987
|
-
const [email, setEmail] = (0, import_react7.useState)(() => {
|
|
2988
|
-
if (typeof window !== "undefined") {
|
|
2989
|
-
return localStorage.getItem("akropolys_user_email") || "";
|
|
2990
|
-
}
|
|
2991
|
-
return "";
|
|
2992
|
-
});
|
|
2993
|
-
const [firstName, setFirstName] = (0, import_react7.useState)(() => {
|
|
2994
|
-
if (typeof window !== "undefined") {
|
|
2995
|
-
return localStorage.getItem("akropolys_user_firstname") || "";
|
|
2996
|
-
}
|
|
2997
|
-
return "";
|
|
2998
|
-
});
|
|
2999
|
-
const [lastName, setLastName] = (0, import_react7.useState)(() => {
|
|
3000
|
-
if (typeof window !== "undefined") {
|
|
3001
|
-
return localStorage.getItem("akropolys_user_lastname") || "";
|
|
3002
|
-
}
|
|
3003
|
-
return "";
|
|
3004
|
-
});
|
|
3005
|
-
const [phase, setPhase] = (0, import_react7.useState)("idle");
|
|
3006
|
-
const [merchantRef, setMerchantRef] = (0, import_react7.useState)(null);
|
|
3007
|
-
const [payError, setPayError] = (0, import_react7.useState)(null);
|
|
3008
|
-
const {} = (0, import_sdk10.usePaymentPolling)({
|
|
3009
|
-
client: client.api,
|
|
3010
|
-
merchantReference: merchantRef,
|
|
3011
|
-
onSuccess: () => {
|
|
3012
|
-
setPhase("done");
|
|
3013
|
-
setMerchantRef(null);
|
|
3014
|
-
},
|
|
3015
|
-
onFailure: () => {
|
|
3016
|
-
setPhase("failed");
|
|
3017
|
-
setPayError("Payment failed or timed out. Please try again.");
|
|
3018
|
-
setMerchantRef(null);
|
|
3019
|
-
}
|
|
3020
|
-
});
|
|
3021
|
-
(0, import_react7.useEffect)(() => {
|
|
3022
|
-
client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch(() => {
|
|
3023
|
-
}).finally(() => setLoadingConfig(false));
|
|
3024
|
-
}, [client]);
|
|
3025
|
-
const hasPaymentMethods = config && Object.values(config).some((m) => m.enabled);
|
|
3026
|
-
const handlePay = async (e) => {
|
|
3027
|
-
e.preventDefault();
|
|
3028
|
-
if (!phone.trim()) {
|
|
3029
|
-
setPayError("Phone number is required.");
|
|
3030
|
-
return;
|
|
3031
|
-
}
|
|
3032
|
-
setPayError(null);
|
|
3033
|
-
setPhase("awaiting");
|
|
3034
|
-
try {
|
|
3035
|
-
if (typeof window !== "undefined") {
|
|
3036
|
-
localStorage.setItem("akropolys_user_phone", phone.trim());
|
|
3037
|
-
localStorage.setItem("akropolys_user_email", email.trim());
|
|
3038
|
-
localStorage.setItem("akropolys_user_firstname", firstName.trim());
|
|
3039
|
-
localStorage.setItem("akropolys_user_lastname", lastName.trim());
|
|
3040
|
-
}
|
|
3041
|
-
const res = await client.api.initiatePayment(phone.trim(), email, firstName, lastName);
|
|
3042
|
-
if (res?.merchantReference) {
|
|
3043
|
-
setMerchantRef(res.merchantReference);
|
|
3044
|
-
} else {
|
|
3045
|
-
throw new Error("No merchant reference returned.");
|
|
3046
|
-
}
|
|
3047
|
-
} catch (err) {
|
|
3048
|
-
setPhase("failed");
|
|
3049
|
-
setPayError(err.message || "Could not connect to payment processor.");
|
|
3050
|
-
}
|
|
3051
|
-
};
|
|
3052
|
-
const currency = cart?.currency || "KES";
|
|
3053
|
-
const total = cart?.total || 0;
|
|
3054
|
-
const backdropStyle = { ...customStyles, fontSize: "15px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', zIndex: 999999 };
|
|
3055
|
-
return (0, import_react_dom3.createPortal)(
|
|
3056
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3057
|
-
"div",
|
|
3058
|
-
{
|
|
3059
|
-
className: "hsk-checkout-backdrop-full",
|
|
3060
|
-
style: backdropStyle,
|
|
3061
|
-
"data-hsk-theme": hskThemeAttr,
|
|
3062
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3063
|
-
"div",
|
|
3064
|
-
{
|
|
3065
|
-
className: "hsk-checkout-modal-full",
|
|
3066
|
-
style: customStyles,
|
|
3067
|
-
"data-hsk-theme": hskThemeAttr,
|
|
3068
|
-
children: [
|
|
3069
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3070
|
-
"button",
|
|
3071
|
-
{
|
|
3072
|
-
onClick: (e) => {
|
|
3073
|
-
e.preventDefault();
|
|
3074
|
-
e.stopPropagation();
|
|
3075
|
-
onClose();
|
|
3076
|
-
},
|
|
3077
|
-
className: "hsk-checkout-close-x",
|
|
3078
|
-
"aria-label": "Close checkout",
|
|
3079
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3080
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
3081
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
3082
|
-
] })
|
|
3083
|
-
}
|
|
3084
|
-
),
|
|
3085
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-panel-left", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-left-content", children: [
|
|
3086
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { onClick: (e) => {
|
|
3087
|
-
e.preventDefault();
|
|
3088
|
-
e.stopPropagation();
|
|
3089
|
-
onClose();
|
|
3090
|
-
}, className: "hsk-checkout-back-btn", children: [
|
|
3091
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3092
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
|
|
3093
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("polyline", { points: "12 19 5 12 12 5" })
|
|
3094
|
-
] }),
|
|
3095
|
-
"Back to store"
|
|
3096
|
-
] }),
|
|
3097
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-store-info", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { children: "Secure Checkout" }) }),
|
|
3098
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-amount-due", children: [
|
|
3099
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-checkout-label-muted", children: "Pay total" }),
|
|
3100
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-grand-total", children: [
|
|
3101
|
-
currency,
|
|
3102
|
-
" ",
|
|
3103
|
-
total.toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
3104
|
-
] })
|
|
3105
|
-
] }),
|
|
3106
|
-
cartLoading || !cart ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-items-list-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "hsk-checkout-items-list", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { className: "hsk-checkout-item-row", children: [
|
|
3107
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-item-img-container", children: [
|
|
3108
|
-
item.image ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { src: item.image, alt: item.name, className: "hsk-checkout-item-img" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-item-img-placeholder", children: "\u{1F6D2}" }),
|
|
3109
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-checkout-item-qty-badge", children: item.quantity })
|
|
3110
|
-
] }),
|
|
3111
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-item-details", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-checkout-item-name", children: item.name }) }),
|
|
3112
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "hsk-checkout-item-price", children: [
|
|
3113
|
-
item.currency,
|
|
3114
|
-
" ",
|
|
3115
|
-
(item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
3116
|
-
] })
|
|
3117
|
-
] }, item.id)) }) })
|
|
3118
|
-
] }) }),
|
|
3119
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-panel-right", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-right-content", children: phase === "done" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card success", children: [
|
|
3120
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-icon-wrap success", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3121
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
|
|
3122
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("polyline", { points: "22 4 12 14.01 9 11.01" })
|
|
3123
|
-
] }) }),
|
|
3124
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Payment Successful!" }),
|
|
3125
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "Your transaction has been confirmed. Thank you for your order!" }),
|
|
3126
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: onClose, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Continue Shopping" })
|
|
3127
|
-
] }) : phase === "awaiting" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card awaiting", children: [
|
|
3128
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-spinner-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-spinner" }) }),
|
|
3129
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Confirm payment on your phone" }),
|
|
3130
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { children: [
|
|
3131
|
-
"We've sent an M-Pesa STK push prompt to ",
|
|
3132
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("strong", { children: [
|
|
3133
|
-
"254",
|
|
3134
|
-
phone
|
|
3135
|
-
] }),
|
|
3136
|
-
"."
|
|
3137
|
-
] }),
|
|
3138
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-stk-instructions", children: [
|
|
3139
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "1. Check your phone lockscreen for the M-Pesa prompt." }),
|
|
3140
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "2. Enter your M-Pesa PIN and press OK." }),
|
|
3141
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "3. Wait here \u2014 this page auto-updates once confirmed." })
|
|
3142
|
-
] }),
|
|
3143
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3144
|
-
"button",
|
|
3145
|
-
{
|
|
3146
|
-
onClick: () => {
|
|
3147
|
-
setPhase("cancelled");
|
|
3148
|
-
setMerchantRef(null);
|
|
3149
|
-
},
|
|
3150
|
-
className: "hsk-checkout-cancel-btn",
|
|
3151
|
-
children: "Cancel payment"
|
|
3152
|
-
}
|
|
3153
|
-
)
|
|
3154
|
-
] }) : phase === "cancelled" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card cancelled", children: [
|
|
3155
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-icon-wrap cancelled", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3156
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m15 9-6 6M9 9l6 6" }),
|
|
3157
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" })
|
|
3158
|
-
] }) }),
|
|
3159
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Payment Cancelled" }),
|
|
3160
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "No charge was made. You can update your phone number and try again whenever you're ready." }),
|
|
3161
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-actions", children: [
|
|
3162
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => {
|
|
3163
|
-
setPhase("idle");
|
|
3164
|
-
setPayError(null);
|
|
3165
|
-
}, className: "hsk-pay-btn hsk-btn-primary", children: "Try again" }),
|
|
3166
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
|
|
3167
|
-
] })
|
|
3168
|
-
] }) : phase === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-card failed", children: [
|
|
3169
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-status-icon-wrap failed", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3170
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
3171
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
3172
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
|
|
3173
|
-
] }) }),
|
|
3174
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Payment Failed" }),
|
|
3175
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-checkout-error-text", children: payError || "Could not verify M-Pesa transaction. Please check your phone and try again." }),
|
|
3176
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-status-actions", children: [
|
|
3177
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => {
|
|
3178
|
-
setPhase("idle");
|
|
3179
|
-
setPayError(null);
|
|
3180
|
-
}, className: "hsk-pay-btn hsk-btn-primary", children: "Try again" }),
|
|
3181
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: onClose, className: "hsk-checkout-cancel-btn", children: "Back to cart" })
|
|
3182
|
-
] })
|
|
3183
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-checkout-payment-form-wrap", children: [
|
|
3184
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "hsk-checkout-section-title", children: "Payment details" }),
|
|
3185
|
-
loadingConfig ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-cart-loading", children: "Loading payment configuration..." }) : !hasPaymentMethods ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "hsk-checkout-error", children: "No payment methods configured for this store." }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: handlePay, className: "hsk-stripe-checkout-form", children: [
|
|
3186
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
|
|
3187
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "M-Pesa Mobile Number" }),
|
|
3188
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-phone-input-container", children: [
|
|
3189
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-phone-prefix", children: "254" }),
|
|
3190
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3191
|
-
"input",
|
|
3192
|
-
{
|
|
3193
|
-
type: "tel",
|
|
3194
|
-
required: true,
|
|
3195
|
-
placeholder: "712345678",
|
|
3196
|
-
pattern: "[0-9]{9}",
|
|
3197
|
-
maxLength: 9,
|
|
3198
|
-
value: phone,
|
|
3199
|
-
onChange: (e) => setPhone(e.target.value.replace(/\D/g, "")),
|
|
3200
|
-
className: "hsk-phone-input-field"
|
|
3201
|
-
}
|
|
3202
|
-
)
|
|
3203
|
-
] }),
|
|
3204
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hsk-form-hint", children: "Enter your 9-digit number (e.g. 712345678)" })
|
|
3205
|
-
] }),
|
|
3206
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
|
|
3207
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "Email address" }),
|
|
3208
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3209
|
-
"input",
|
|
3210
|
-
{
|
|
3211
|
-
type: "email",
|
|
3212
|
-
placeholder: "john.doe@example.com",
|
|
3213
|
-
value: email,
|
|
3214
|
-
onChange: (e) => setEmail(e.target.value),
|
|
3215
|
-
className: "hsk-form-input"
|
|
3216
|
-
}
|
|
3217
|
-
)
|
|
3218
|
-
] }),
|
|
3219
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-row", children: [
|
|
3220
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
|
|
3221
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "First Name" }),
|
|
3222
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3223
|
-
"input",
|
|
3224
|
-
{
|
|
3225
|
-
type: "text",
|
|
3226
|
-
placeholder: "John",
|
|
3227
|
-
value: firstName,
|
|
3228
|
-
onChange: (e) => setFirstName(e.target.value),
|
|
3229
|
-
className: "hsk-form-input"
|
|
3230
|
-
}
|
|
3231
|
-
)
|
|
3232
|
-
] }),
|
|
3233
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "hsk-form-group", children: [
|
|
3234
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "hsk-form-label", children: "Last Name" }),
|
|
3235
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3236
|
-
"input",
|
|
3237
|
-
{
|
|
3238
|
-
type: "text",
|
|
3239
|
-
placeholder: "Doe",
|
|
3240
|
-
value: lastName,
|
|
3241
|
-
onChange: (e) => setLastName(e.target.value),
|
|
3242
|
-
className: "hsk-form-input"
|
|
3243
|
-
}
|
|
3244
|
-
)
|
|
3245
|
-
] })
|
|
3246
|
-
] }),
|
|
3247
|
-
payError && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-form-error-banner", children: payError }),
|
|
3248
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "submit", className: "hsk-checkout-submit-btn", children: [
|
|
3249
|
-
"Pay ",
|
|
3250
|
-
currency,
|
|
3251
|
-
" ",
|
|
3252
|
-
total.toLocaleString()
|
|
3253
|
-
] }),
|
|
3254
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hsk-checkout-footer-brand", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Powered by Akropolys" }) })
|
|
3255
|
-
] })
|
|
3256
|
-
] }) }) })
|
|
3257
|
-
]
|
|
3258
|
-
}
|
|
3259
|
-
)
|
|
3260
|
-
}
|
|
3261
|
-
),
|
|
3262
|
-
document.body
|
|
3263
|
-
);
|
|
3264
|
-
}
|
|
3265
|
-
|
|
3266
|
-
// src/components/CartDrawer.tsx
|
|
3267
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3268
|
-
function CartDrawer({
|
|
3269
|
-
trigger,
|
|
3270
|
-
className,
|
|
3271
|
-
theme
|
|
3272
|
-
}) {
|
|
3273
|
-
const { cart, loading } = (0, import_sdk11.useCart)();
|
|
3274
|
-
const [open, setOpen] = (0, import_react8.useState)(false);
|
|
3275
|
-
const [showCheckout, setShowCheckout] = (0, import_react8.useState)(false);
|
|
3276
|
-
const [mounted, setMounted] = (0, import_react8.useState)(false);
|
|
3277
|
-
const client = (0, import_sdk11.useAkropolysContext)();
|
|
3278
|
-
(0, import_react8.useEffect)(() => {
|
|
3279
|
-
setMounted(true);
|
|
3280
|
-
const handleTriggerCheckout = () => {
|
|
3281
|
-
setShowCheckout(true);
|
|
3282
|
-
setOpen(false);
|
|
3283
|
-
};
|
|
3284
|
-
window.addEventListener("akropolys:trigger_checkout", handleTriggerCheckout);
|
|
3285
|
-
return () => {
|
|
3286
|
-
window.removeEventListener("akropolys:trigger_checkout", handleTriggerCheckout);
|
|
3287
|
-
};
|
|
3288
|
-
}, []);
|
|
3289
|
-
(0, import_react8.useEffect)(() => {
|
|
3290
|
-
if (open) {
|
|
3291
|
-
document.body.style.overflow = "hidden";
|
|
3292
|
-
} else {
|
|
3293
|
-
document.body.style.overflow = "";
|
|
3294
|
-
}
|
|
3295
|
-
return () => {
|
|
3296
|
-
document.body.style.overflow = "";
|
|
3297
|
-
};
|
|
3298
|
-
}, [open]);
|
|
3299
|
-
const handleCheckout = async () => {
|
|
3300
|
-
if (!cart || cart.items.length === 0) return;
|
|
3301
|
-
const event = new CustomEvent("akropolys:trigger_checkout", { cancelable: true });
|
|
3302
|
-
window.dispatchEvent(event);
|
|
3303
|
-
if (event.defaultPrevented) {
|
|
3304
|
-
setOpen(false);
|
|
3305
|
-
return;
|
|
3306
|
-
}
|
|
3307
|
-
setShowCheckout(true);
|
|
3308
|
-
};
|
|
3309
|
-
const isStringTheme = typeof theme === "string";
|
|
3310
|
-
const hskThemeAttr = isStringTheme ? theme : void 0;
|
|
3311
|
-
const customStyles = !isStringTheme && theme ? {
|
|
3312
|
-
...theme?.primaryColor && { "--hsk-primary": theme.primaryColor, "--hsk-primary-color": theme.primaryColor },
|
|
3313
|
-
...theme?.backgroundColor && { "--hsk-bg": theme.backgroundColor },
|
|
3314
|
-
...theme?.textColor && { "--hsk-text": theme.textColor },
|
|
3315
|
-
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
3316
|
-
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
3317
|
-
} : void 0;
|
|
3318
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3319
|
-
trigger ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { onClick: () => setOpen(true), style: { display: "inline-block" }, children: trigger }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3320
|
-
"button",
|
|
3321
|
-
{
|
|
3322
|
-
onClick: () => setOpen(true),
|
|
3323
|
-
className: cn("hsk-cart-trigger", className),
|
|
3324
|
-
style: customStyles,
|
|
3325
|
-
"data-hsk-theme": hskThemeAttr,
|
|
3326
|
-
"aria-label": "Open cart",
|
|
3327
|
-
children: [
|
|
3328
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3329
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "21", r: "1" }),
|
|
3330
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "20", cy: "21", r: "1" }),
|
|
3331
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" })
|
|
3332
|
-
] }),
|
|
3333
|
-
cart && cart.item_count > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "hsk-cart-trigger-badge", children: cart.item_count }) : null
|
|
3334
|
-
]
|
|
3335
|
-
}
|
|
3336
|
-
),
|
|
3337
|
-
open && mounted && (0, import_react_dom4.createPortal)(
|
|
3338
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3339
|
-
"div",
|
|
3340
|
-
{
|
|
3341
|
-
className: "hsk-cart-backdrop",
|
|
3342
|
-
style: customStyles,
|
|
3343
|
-
"data-hsk-theme": hskThemeAttr,
|
|
3344
|
-
onClick: () => setOpen(false),
|
|
3345
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3346
|
-
"div",
|
|
3347
|
-
{
|
|
3348
|
-
className: "hsk-cart-bottom-sheet",
|
|
3349
|
-
style: customStyles,
|
|
3350
|
-
"data-hsk-theme": hskThemeAttr,
|
|
3351
|
-
onClick: (e) => e.stopPropagation(),
|
|
3352
|
-
children: [
|
|
3353
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-sheet-handle" }),
|
|
3354
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-sheet-header", children: [
|
|
3355
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { children: "Your Cart" }),
|
|
3356
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: () => setOpen(false), className: "hsk-close-btn", children: "\xD7" })
|
|
3357
|
-
] }),
|
|
3358
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-sheet-content", children: loading && !cart ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-loading", children: "Loading cart..." }) : !cart || cart.items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "hsk-cart-empty", children: "Your cart is empty." }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "hsk-cart-items", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { className: "hsk-cart-item", children: [
|
|
3359
|
-
item.image && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { src: item.image, alt: item.name, className: "hsk-cart-item-img" }),
|
|
3360
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-item-info", children: [
|
|
3361
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "hsk-cart-item-name", children: item.name }),
|
|
3362
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "hsk-cart-item-price", children: [
|
|
3363
|
-
item.currency,
|
|
3364
|
-
" ",
|
|
3365
|
-
item.price_numeric.toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
3366
|
-
] })
|
|
3367
|
-
] }),
|
|
3368
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-item-qty", children: [
|
|
3369
|
-
"x",
|
|
3370
|
-
item.quantity
|
|
3371
|
-
] })
|
|
3372
|
-
] }, item.id)) }) }),
|
|
3373
|
-
cart && cart.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-sheet-footer", children: [
|
|
3374
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "hsk-cart-total", children: [
|
|
3375
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Total" }),
|
|
3376
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
3377
|
-
cart.currency,
|
|
3378
|
-
" ",
|
|
3379
|
-
cart.total.toLocaleString(void 0, { minimumFractionDigits: 2 })
|
|
3380
|
-
] })
|
|
3381
|
-
] }),
|
|
3382
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: handleCheckout, className: "hsk-checkout-btn", children: "Checkout securely" })
|
|
3383
|
-
] })
|
|
3384
|
-
]
|
|
3385
|
-
}
|
|
3386
|
-
)
|
|
3387
|
-
}
|
|
3388
|
-
),
|
|
3389
|
-
document.body
|
|
3390
|
-
),
|
|
3391
|
-
showCheckout && mounted && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3392
|
-
CheckoutModal,
|
|
3393
|
-
{
|
|
3394
|
-
onClose: () => {
|
|
3395
|
-
setShowCheckout(false);
|
|
3396
|
-
setOpen(false);
|
|
3397
|
-
},
|
|
3398
|
-
theme: isStringTheme ? theme : void 0,
|
|
3399
|
-
customStyles,
|
|
3400
|
-
hskThemeAttr
|
|
3401
|
-
}
|
|
3402
|
-
)
|
|
3403
|
-
] });
|
|
3404
|
-
}
|
|
3405
2880
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3406
2881
|
0 && (module.exports = {
|
|
3407
|
-
CartBadge,
|
|
3408
|
-
CartDrawer,
|
|
3409
2882
|
ChatWidget,
|
|
3410
|
-
CheckoutModal,
|
|
3411
2883
|
ComparisonMatrix,
|
|
3412
2884
|
KikuButton,
|
|
3413
2885
|
KikuChat,
|