@huskel/sdk 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -97,6 +97,12 @@ var HuskelAPI = class {
97
97
  if (sessionId) {
98
98
  headers["X-Huskel-Session-Id"] = sessionId;
99
99
  }
100
+ if (typeof window !== "undefined") {
101
+ const phone = localStorage.getItem("huskel_user_phone");
102
+ if (phone) {
103
+ headers["X-Huskel-Shopper-Phone"] = phone;
104
+ }
105
+ }
100
106
  const res = await fetch(url, {
101
107
  method: "POST",
102
108
  headers,
@@ -175,6 +181,12 @@ var HuskelAPI = class {
175
181
  if (shopperId) headers["X-Huskel-Shopper-Id"] = shopperId;
176
182
  const sessionId = (_b = this.getSessionId) == null ? void 0 : _b.call(this);
177
183
  if (sessionId) headers["X-Huskel-Session-Id"] = sessionId;
184
+ if (typeof window !== "undefined") {
185
+ const phone = localStorage.getItem("huskel_user_phone");
186
+ if (phone) {
187
+ headers["X-Huskel-Shopper-Phone"] = phone;
188
+ }
189
+ }
178
190
  return headers;
179
191
  }
180
192
  async getCart() {
@@ -1660,7 +1672,12 @@ function ChatModal({
1660
1672
  const [selectedProduct, setSelectedProduct] = (0, import_react12.useState)(null);
1661
1673
  const bottomRef = (0, import_react12.useRef)(null);
1662
1674
  const textareaRef = (0, import_react12.useRef)(null);
1663
- const [phoneInput, setPhoneInput] = (0, import_react12.useState)("");
1675
+ const [phoneInput, setPhoneInput] = (0, import_react12.useState)(() => {
1676
+ if (typeof window !== "undefined") {
1677
+ return localStorage.getItem("huskel_user_phone") || "";
1678
+ }
1679
+ return "";
1680
+ });
1664
1681
  const [merchantRef, setMerchantRef] = (0, import_react12.useState)(null);
1665
1682
  const [paymentPhase, setPaymentPhase] = (0, import_react12.useState)("idle");
1666
1683
  const { status: pollStatus } = usePaymentPolling({
@@ -1688,7 +1705,10 @@ function ChatModal({
1688
1705
  const handlePhoneSubmit = async () => {
1689
1706
  if (!phoneInput.trim()) return;
1690
1707
  try {
1691
- const res = await client.api.initiatePayment(phoneInput);
1708
+ if (typeof window !== "undefined") {
1709
+ localStorage.setItem("huskel_user_phone", phoneInput.trim());
1710
+ }
1711
+ const res = await client.api.initiatePayment(phoneInput.trim());
1692
1712
  setMerchantRef(res.merchantReference);
1693
1713
  setPaymentPhase("awaiting");
1694
1714
  } catch (e) {
@@ -1778,7 +1798,7 @@ function ChatModal({
1778
1798
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SparkleIcon3, {}) }),
1779
1799
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hsk-cb-ai-body", children: [
1780
1800
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
1781
- isLast && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1801
+ isLast && sources.length > 0 && (lastAction == null ? void 0 : lastAction.type) !== "request_phone" && (lastAction == null ? void 0 : lastAction.type) !== "awaiting_payment" && (lastAction == null ? void 0 : lastAction.type) !== "checkout" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1782
1802
  SourcesCarousel,
1783
1803
  {
1784
1804
  sources,
@@ -1960,98 +1980,242 @@ function CheckoutModal({
1960
1980
  customStyles,
1961
1981
  hskThemeAttr
1962
1982
  }) {
1963
- var _a, _b, _c, _d;
1964
1983
  const { cart, loading: cartLoading } = useCart();
1965
1984
  const client = useHuskelContext();
1966
1985
  const [config, setConfig] = (0, import_react13.useState)(null);
1967
- const [loading, setLoading] = (0, import_react13.useState)(true);
1968
- const [checkingOut, setCheckingOut] = (0, import_react13.useState)(false);
1969
- const [paymentSuccess, setPaymentSuccess] = (0, import_react13.useState)(false);
1986
+ const [loadingConfig, setLoadingConfig] = (0, import_react13.useState)(true);
1987
+ const [phone, setPhone] = (0, import_react13.useState)(() => {
1988
+ if (typeof window !== "undefined") {
1989
+ return localStorage.getItem("huskel_user_phone") || "";
1990
+ }
1991
+ return "";
1992
+ });
1993
+ const [email, setEmail] = (0, import_react13.useState)(() => {
1994
+ if (typeof window !== "undefined") {
1995
+ return localStorage.getItem("huskel_user_email") || "";
1996
+ }
1997
+ return "";
1998
+ });
1999
+ const [firstName, setFirstName] = (0, import_react13.useState)(() => {
2000
+ if (typeof window !== "undefined") {
2001
+ return localStorage.getItem("huskel_user_firstname") || "";
2002
+ }
2003
+ return "";
2004
+ });
2005
+ const [lastName, setLastName] = (0, import_react13.useState)(() => {
2006
+ if (typeof window !== "undefined") {
2007
+ return localStorage.getItem("huskel_user_lastname") || "";
2008
+ }
2009
+ return "";
2010
+ });
2011
+ const [phase, setPhase] = (0, import_react13.useState)("idle");
2012
+ const [merchantRef, setMerchantRef] = (0, import_react13.useState)(null);
2013
+ const [payError, setPayError] = (0, import_react13.useState)(null);
2014
+ const {} = usePaymentPolling({
2015
+ client: client.api,
2016
+ merchantReference: merchantRef,
2017
+ onSuccess: () => {
2018
+ setPhase("done");
2019
+ setMerchantRef(null);
2020
+ },
2021
+ onFailure: () => {
2022
+ setPhase("failed");
2023
+ setPayError("Payment failed or timed out. Please try again.");
2024
+ setMerchantRef(null);
2025
+ }
2026
+ });
1970
2027
  (0, import_react13.useEffect)(() => {
1971
- client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch((e) => console.error("[Huskel] Failed to fetch checkout config", e)).finally(() => setLoading(false));
2028
+ client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch(() => {
2029
+ }).finally(() => setLoadingConfig(false));
1972
2030
  }, [client]);
1973
- const handlePay = async (method) => {
1974
- setCheckingOut(true);
1975
- setTimeout(async () => {
1976
- try {
1977
- const payload = await client.api.checkoutCart();
1978
- if (client.onCheckout) {
1979
- client.onCheckout(payload);
1980
- }
1981
- setPaymentSuccess(true);
1982
- setTimeout(() => {
1983
- onClose();
1984
- }, 3e3);
1985
- } catch (e) {
1986
- console.error("[Huskel] Checkout failed", e);
1987
- setCheckingOut(false);
2031
+ const hasPaymentMethods = config && Object.values(config).some((m) => m.enabled);
2032
+ const handlePay = async (e) => {
2033
+ e.preventDefault();
2034
+ if (!phone.trim()) {
2035
+ setPayError("Phone number is required.");
2036
+ return;
2037
+ }
2038
+ setPayError(null);
2039
+ setPhase("awaiting");
2040
+ try {
2041
+ if (typeof window !== "undefined") {
2042
+ localStorage.setItem("huskel_user_phone", phone.trim());
2043
+ localStorage.setItem("huskel_user_email", email.trim());
2044
+ localStorage.setItem("huskel_user_firstname", firstName.trim());
2045
+ localStorage.setItem("huskel_user_lastname", lastName.trim());
2046
+ }
2047
+ const res = await client.api.initiatePayment(phone.trim(), email, firstName, lastName);
2048
+ if (res == null ? void 0 : res.merchantReference) {
2049
+ setMerchantRef(res.merchantReference);
2050
+ } else {
2051
+ throw new Error("No merchant reference returned.");
1988
2052
  }
1989
- }, 1500);
2053
+ } catch (err) {
2054
+ setPhase("failed");
2055
+ setPayError(err.message || "Could not connect to payment processor.");
2056
+ }
1990
2057
  };
1991
- const hasPaymentMethods = config && Object.values(config).some((m) => m.enabled);
2058
+ const currency = (cart == null ? void 0 : cart.currency) || "KES";
2059
+ const total = (cart == null ? void 0 : cart.total) || 0;
2060
+ const backdropStyle = __spreadProps(__spreadValues({}, customStyles), { fontSize: "15px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', zIndex: 999999 });
1992
2061
  return (0, import_react_dom3.createPortal)(
1993
2062
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1994
2063
  "div",
1995
2064
  {
1996
- className: "hsk-cart-backdrop",
1997
- style: __spreadProps(__spreadValues({}, customStyles), { zIndex: 999999 }),
2065
+ className: "hsk-checkout-backdrop-full",
2066
+ style: backdropStyle,
1998
2067
  "data-hsk-theme": hskThemeAttr,
1999
- onClick: onClose,
2000
2068
  children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2001
2069
  "div",
2002
2070
  {
2003
- className: "hsk-checkout-modal",
2071
+ className: "hsk-checkout-modal-full",
2004
2072
  style: customStyles,
2005
2073
  "data-hsk-theme": hskThemeAttr,
2006
- onClick: (e) => e.stopPropagation(),
2007
2074
  children: [
2008
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-header", children: [
2009
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { children: "Secure Checkout" }),
2010
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: onClose, className: "hsk-close-btn", children: "\xD7" })
2011
- ] }),
2012
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-content", children: paymentSuccess ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-success", children: [
2013
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "hsk-success-icon", children: [
2014
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
2015
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "22 4 12 14.01 9 11.01" })
2075
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-panel-left", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-left-content", children: [
2076
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { onClick: onClose, className: "hsk-checkout-back-btn", disabled: phase !== "idle", children: [
2077
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2078
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
2079
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "12 19 5 12 12 5" })
2080
+ ] }),
2081
+ "Back to store"
2016
2082
  ] }),
2017
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment Successful!" }),
2018
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "Thank you for your order." })
2019
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-split", children: [
2020
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-summary", children: [
2021
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Order Summary" }),
2022
- cartLoading || !cart ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2023
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "hsk-checkout-items", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { children: [
2024
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2025
- item.quantity,
2026
- "x ",
2027
- item.name
2028
- ] }),
2029
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2030
- item.currency,
2031
- " ",
2032
- (item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
2033
- ] })
2034
- ] }, item.id)) }),
2035
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-total", children: [
2036
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Total" }),
2037
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2038
- cart.currency,
2039
- " ",
2040
- cart.total.toLocaleString(void 0, { minimumFractionDigits: 2 })
2041
- ] })
2042
- ] })
2083
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-store-info", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { children: "Secure Checkout" }) }),
2084
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-amount-due", children: [
2085
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-checkout-label-muted", children: "Pay total" }),
2086
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-grand-total", children: [
2087
+ currency,
2088
+ " ",
2089
+ total.toLocaleString(void 0, { minimumFractionDigits: 2 })
2043
2090
  ] })
2044
2091
  ] }),
2045
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-payment", children: [
2046
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment Method" }),
2047
- loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-cart-loading", children: "Loading secure payment methods..." }) : !hasPaymentMethods ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-checkout-error", children: "No payment methods are currently available for this store." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-payment-options", children: [
2048
- ((_a = config == null ? void 0 : config.mpesa) == null ? void 0 : _a.enabled) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => handlePay("mpesa"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-mpesa", children: checkingOut ? "Processing..." : "Pay with M-Pesa" }),
2049
- ((_b = config == null ? void 0 : config.equity) == null ? void 0 : _b.enabled) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => handlePay("equity"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-equity", children: checkingOut ? "Processing..." : "Pay with Equity Bank" }),
2050
- ((_c = config == null ? void 0 : config.stripe) == null ? void 0 : _c.enabled) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => handlePay("stripe"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-stripe", children: checkingOut ? "Processing..." : "Pay with Card (Stripe)" }),
2051
- ((_d = config == null ? void 0 : config.paypal) == null ? void 0 : _d.enabled) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => handlePay("paypal"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-paypal", children: checkingOut ? "Processing..." : "Pay with PayPal" })
2092
+ cartLoading || !cart ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-items-list-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "hsk-checkout-items-list", children: cart.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { className: "hsk-checkout-item-row", children: [
2093
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-item-img-container", children: [
2094
+ item.image ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: item.image, alt: item.name, className: "hsk-checkout-item-img" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-item-img-placeholder", children: "\u{1F6D2}" }),
2095
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-checkout-item-qty-badge", children: item.quantity })
2096
+ ] }),
2097
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-item-details", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-checkout-item-name", children: item.name }) }),
2098
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "hsk-checkout-item-price", children: [
2099
+ item.currency,
2100
+ " ",
2101
+ (item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
2052
2102
  ] })
2103
+ ] }, item.id)) }) })
2104
+ ] }) }),
2105
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-panel-right", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-right-content", children: phase === "done" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card success", children: [
2106
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-icon-wrap success", children: "\u2705" }),
2107
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment Successful!" }),
2108
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "Your transaction has been confirmed successfully. Thank you for your order!" }),
2109
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: onClose, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Continue Shopping" })
2110
+ ] }) : phase === "awaiting" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card awaiting", children: [
2111
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-spinner-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-spinner" }) }),
2112
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Confirm payment on your phone" }),
2113
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
2114
+ "We've sent an M-Pesa STK push prompt to ",
2115
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("strong", { children: [
2116
+ "254",
2117
+ phone
2118
+ ] }),
2119
+ "."
2120
+ ] }),
2121
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-stk-instructions", children: [
2122
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "1. Check your phone lockscreen for the M-Pesa prompt." }),
2123
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "2. Enter your M-Pesa PIN and press OK." }),
2124
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "3. Wait here; this page will automatically redirect once confirmed." })
2125
+ ] }),
2126
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2127
+ "button",
2128
+ {
2129
+ onClick: () => {
2130
+ setPhase("idle");
2131
+ setMerchantRef(null);
2132
+ },
2133
+ className: "hsk-checkout-cancel-btn",
2134
+ children: "Cancel and change phone number"
2135
+ }
2136
+ )
2137
+ ] }) : phase === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-status-card failed", children: [
2138
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-status-icon-wrap failed", children: "\u274C" }),
2139
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Payment failed or timed out" }),
2140
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-checkout-error-text", children: payError || "Could not verify M-Pesa transaction." }),
2141
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: () => {
2142
+ setPhase("idle");
2143
+ setPayError(null);
2144
+ }, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Try Again" })
2145
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-checkout-payment-form-wrap", children: [
2146
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "hsk-checkout-section-title", children: "Payment details" }),
2147
+ loadingConfig ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-cart-loading", children: "Loading payment configuration..." }) : !hasPaymentMethods ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "hsk-checkout-error", children: "No payment methods configured for this store." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: handlePay, className: "hsk-stripe-checkout-form", children: [
2148
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2149
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "M-Pesa Mobile Number" }),
2150
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-phone-input-container", children: [
2151
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-phone-prefix", children: "254" }),
2152
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2153
+ "input",
2154
+ {
2155
+ type: "tel",
2156
+ required: true,
2157
+ placeholder: "712345678",
2158
+ pattern: "[0-9]{9}",
2159
+ maxLength: 9,
2160
+ value: phone,
2161
+ onChange: (e) => setPhone(e.target.value.replace(/\D/g, "")),
2162
+ className: "hsk-phone-input-field"
2163
+ }
2164
+ )
2165
+ ] }),
2166
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hsk-form-hint", children: "Enter your 9-digit number (e.g. 712345678)" })
2167
+ ] }),
2168
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2169
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "Email address" }),
2170
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2171
+ "input",
2172
+ {
2173
+ type: "email",
2174
+ placeholder: "john.doe@example.com",
2175
+ value: email,
2176
+ onChange: (e) => setEmail(e.target.value),
2177
+ className: "hsk-form-input"
2178
+ }
2179
+ )
2180
+ ] }),
2181
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-row", children: [
2182
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2183
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "First Name" }),
2184
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2185
+ "input",
2186
+ {
2187
+ type: "text",
2188
+ placeholder: "John",
2189
+ value: firstName,
2190
+ onChange: (e) => setFirstName(e.target.value),
2191
+ className: "hsk-form-input"
2192
+ }
2193
+ )
2194
+ ] }),
2195
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hsk-form-group", children: [
2196
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "hsk-form-label", children: "Last Name" }),
2197
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2198
+ "input",
2199
+ {
2200
+ type: "text",
2201
+ placeholder: "Doe",
2202
+ value: lastName,
2203
+ onChange: (e) => setLastName(e.target.value),
2204
+ className: "hsk-form-input"
2205
+ }
2206
+ )
2207
+ ] })
2208
+ ] }),
2209
+ payError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-form-error-banner", children: payError }),
2210
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "submit", className: "hsk-checkout-submit-btn", children: [
2211
+ "Pay ",
2212
+ currency,
2213
+ " ",
2214
+ total.toLocaleString()
2215
+ ] }),
2216
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hsk-checkout-footer-brand", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Powered by Huskel AI" }) })
2053
2217
  ] })
2054
- ] }) })
2218
+ ] }) }) })
2055
2219
  ]
2056
2220
  }
2057
2221
  )
@@ -2096,6 +2260,12 @@ function CartDrawer({
2096
2260
  }, [open]);
2097
2261
  const handleCheckout = async () => {
2098
2262
  if (!cart || cart.items.length === 0) return;
2263
+ const event = new CustomEvent("huskel:trigger_checkout", { cancelable: true });
2264
+ window.dispatchEvent(event);
2265
+ if (event.defaultPrevented) {
2266
+ setOpen(false);
2267
+ return;
2268
+ }
2099
2269
  setShowCheckout(true);
2100
2270
  };
2101
2271
  const isStringTheme = typeof theme === "string";