@huskel/sdk 0.4.7 → 0.4.9

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.mjs CHANGED
@@ -56,6 +56,12 @@ var HuskelAPI = class {
56
56
  if (sessionId) {
57
57
  headers["X-Huskel-Session-Id"] = sessionId;
58
58
  }
59
+ if (typeof window !== "undefined") {
60
+ const phone = localStorage.getItem("huskel_user_phone");
61
+ if (phone) {
62
+ headers["X-Huskel-Shopper-Phone"] = phone;
63
+ }
64
+ }
59
65
  const res = await fetch(url, {
60
66
  method: "POST",
61
67
  headers,
@@ -134,6 +140,12 @@ var HuskelAPI = class {
134
140
  if (shopperId) headers["X-Huskel-Shopper-Id"] = shopperId;
135
141
  const sessionId = (_b = this.getSessionId) == null ? void 0 : _b.call(this);
136
142
  if (sessionId) headers["X-Huskel-Session-Id"] = sessionId;
143
+ if (typeof window !== "undefined") {
144
+ const phone = localStorage.getItem("huskel_user_phone");
145
+ if (phone) {
146
+ headers["X-Huskel-Shopper-Phone"] = phone;
147
+ }
148
+ }
137
149
  return headers;
138
150
  }
139
151
  async getCart() {
@@ -1619,7 +1631,12 @@ function ChatModal({
1619
1631
  const [selectedProduct, setSelectedProduct] = useState9(null);
1620
1632
  const bottomRef = useRef10(null);
1621
1633
  const textareaRef = useRef10(null);
1622
- const [phoneInput, setPhoneInput] = useState9("");
1634
+ const [phoneInput, setPhoneInput] = useState9(() => {
1635
+ if (typeof window !== "undefined") {
1636
+ return localStorage.getItem("huskel_user_phone") || "";
1637
+ }
1638
+ return "";
1639
+ });
1623
1640
  const [merchantRef, setMerchantRef] = useState9(null);
1624
1641
  const [paymentPhase, setPaymentPhase] = useState9("idle");
1625
1642
  const { status: pollStatus } = usePaymentPolling({
@@ -1647,7 +1664,10 @@ function ChatModal({
1647
1664
  const handlePhoneSubmit = async () => {
1648
1665
  if (!phoneInput.trim()) return;
1649
1666
  try {
1650
- const res = await client.api.initiatePayment(phoneInput);
1667
+ if (typeof window !== "undefined") {
1668
+ localStorage.setItem("huskel_user_phone", phoneInput.trim());
1669
+ }
1670
+ const res = await client.api.initiatePayment(phoneInput.trim());
1651
1671
  setMerchantRef(res.merchantReference);
1652
1672
  setPaymentPhase("awaiting");
1653
1673
  } catch (e) {
@@ -1737,7 +1757,7 @@ function ChatModal({
1737
1757
  /* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
1738
1758
  /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-ai-body", children: [
1739
1759
  /* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
1740
- isLast && sources.length > 0 && /* @__PURE__ */ jsx6(
1760
+ 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__ */ jsx6(
1741
1761
  SourcesCarousel,
1742
1762
  {
1743
1763
  sources,
@@ -1912,105 +1932,253 @@ import { createPortal as createPortal4 } from "react-dom";
1912
1932
  // src/components/CheckoutModal.tsx
1913
1933
  import { useState as useState10, useEffect as useEffect9 } from "react";
1914
1934
  import { createPortal as createPortal3 } from "react-dom";
1915
- import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1935
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1916
1936
  function CheckoutModal({
1917
1937
  onClose,
1918
1938
  theme,
1919
1939
  customStyles,
1920
1940
  hskThemeAttr
1921
1941
  }) {
1922
- var _a, _b, _c, _d;
1923
1942
  const { cart, loading: cartLoading } = useCart();
1924
1943
  const client = useHuskelContext();
1925
1944
  const [config, setConfig] = useState10(null);
1926
- const [loading, setLoading] = useState10(true);
1927
- const [checkingOut, setCheckingOut] = useState10(false);
1928
- const [paymentSuccess, setPaymentSuccess] = useState10(false);
1945
+ const [loadingConfig, setLoadingConfig] = useState10(true);
1946
+ const [phone, setPhone] = useState10(() => {
1947
+ if (typeof window !== "undefined") {
1948
+ return localStorage.getItem("huskel_user_phone") || "";
1949
+ }
1950
+ return "";
1951
+ });
1952
+ const [email, setEmail] = useState10(() => {
1953
+ if (typeof window !== "undefined") {
1954
+ return localStorage.getItem("huskel_user_email") || "";
1955
+ }
1956
+ return "";
1957
+ });
1958
+ const [firstName, setFirstName] = useState10(() => {
1959
+ if (typeof window !== "undefined") {
1960
+ return localStorage.getItem("huskel_user_firstname") || "";
1961
+ }
1962
+ return "";
1963
+ });
1964
+ const [lastName, setLastName] = useState10(() => {
1965
+ if (typeof window !== "undefined") {
1966
+ return localStorage.getItem("huskel_user_lastname") || "";
1967
+ }
1968
+ return "";
1969
+ });
1970
+ const [phase, setPhase] = useState10("idle");
1971
+ const [merchantRef, setMerchantRef] = useState10(null);
1972
+ const [payError, setPayError] = useState10(null);
1973
+ const {} = usePaymentPolling({
1974
+ client: client.api,
1975
+ merchantReference: merchantRef,
1976
+ onSuccess: () => {
1977
+ setPhase("done");
1978
+ setMerchantRef(null);
1979
+ },
1980
+ onFailure: () => {
1981
+ setPhase("failed");
1982
+ setPayError("Payment failed or timed out. Please try again.");
1983
+ setMerchantRef(null);
1984
+ }
1985
+ });
1929
1986
  useEffect9(() => {
1930
- client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch((e) => console.error("[Huskel] Failed to fetch checkout config", e)).finally(() => setLoading(false));
1987
+ client.api.getCheckoutConfig().then((res) => setConfig(res.payment_methods)).catch(() => {
1988
+ }).finally(() => setLoadingConfig(false));
1931
1989
  }, [client]);
1932
- const handlePay = async (method) => {
1933
- setCheckingOut(true);
1934
- setTimeout(async () => {
1935
- try {
1936
- const payload = await client.api.checkoutCart();
1937
- if (client.onCheckout) {
1938
- client.onCheckout(payload);
1939
- }
1940
- setPaymentSuccess(true);
1941
- setTimeout(() => {
1942
- onClose();
1943
- }, 3e3);
1944
- } catch (e) {
1945
- console.error("[Huskel] Checkout failed", e);
1946
- setCheckingOut(false);
1990
+ const hasPaymentMethods = config && Object.values(config).some((m) => m.enabled);
1991
+ const handlePay = async (e) => {
1992
+ e.preventDefault();
1993
+ if (!phone.trim()) {
1994
+ setPayError("Phone number is required.");
1995
+ return;
1996
+ }
1997
+ setPayError(null);
1998
+ setPhase("awaiting");
1999
+ try {
2000
+ if (typeof window !== "undefined") {
2001
+ localStorage.setItem("huskel_user_phone", phone.trim());
2002
+ localStorage.setItem("huskel_user_email", email.trim());
2003
+ localStorage.setItem("huskel_user_firstname", firstName.trim());
2004
+ localStorage.setItem("huskel_user_lastname", lastName.trim());
2005
+ }
2006
+ const res = await client.api.initiatePayment(phone.trim(), email, firstName, lastName);
2007
+ if (res == null ? void 0 : res.merchantReference) {
2008
+ setMerchantRef(res.merchantReference);
2009
+ } else {
2010
+ throw new Error("No merchant reference returned.");
1947
2011
  }
1948
- }, 1500);
2012
+ } catch (err) {
2013
+ setPhase("failed");
2014
+ setPayError(err.message || "Could not connect to payment processor.");
2015
+ }
1949
2016
  };
1950
- const hasPaymentMethods = config && Object.values(config).some((m) => m.enabled);
2017
+ const currency = (cart == null ? void 0 : cart.currency) || "KES";
2018
+ const total = (cart == null ? void 0 : cart.total) || 0;
2019
+ const backdropStyle = __spreadProps(__spreadValues({}, customStyles), { fontSize: "15px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', zIndex: 999999 });
1951
2020
  return createPortal3(
1952
2021
  /* @__PURE__ */ jsx8(
1953
2022
  "div",
1954
2023
  {
1955
- className: "hsk-cart-backdrop",
1956
- style: __spreadProps(__spreadValues({}, customStyles), { zIndex: 999999 }),
2024
+ className: "hsk-checkout-backdrop-full",
2025
+ style: backdropStyle,
1957
2026
  "data-hsk-theme": hskThemeAttr,
1958
- onClick: onClose,
1959
2027
  children: /* @__PURE__ */ jsxs5(
1960
2028
  "div",
1961
2029
  {
1962
- className: "hsk-checkout-modal",
2030
+ className: "hsk-checkout-modal-full",
1963
2031
  style: customStyles,
1964
2032
  "data-hsk-theme": hskThemeAttr,
1965
- onClick: (e) => e.stopPropagation(),
1966
2033
  children: [
1967
- /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-header", children: [
1968
- /* @__PURE__ */ jsx8("h2", { children: "Secure Checkout" }),
1969
- /* @__PURE__ */ jsx8("button", { onClick: onClose, className: "hsk-close-btn", children: "\xD7" })
1970
- ] }),
1971
- /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-content", children: paymentSuccess ? /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-success", children: [
1972
- /* @__PURE__ */ jsxs5("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "hsk-success-icon", children: [
1973
- /* @__PURE__ */ jsx8("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
1974
- /* @__PURE__ */ jsx8("polyline", { points: "22 4 12 14.01 9 11.01" })
2034
+ /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-panel-left", children: /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-left-content", children: [
2035
+ /* @__PURE__ */ jsxs5("button", { onClick: (e) => {
2036
+ e.preventDefault();
2037
+ e.stopPropagation();
2038
+ onClose();
2039
+ }, className: "hsk-checkout-back-btn", disabled: phase !== "idle", children: [
2040
+ /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2041
+ /* @__PURE__ */ jsx8("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
2042
+ /* @__PURE__ */ jsx8("polyline", { points: "12 19 5 12 12 5" })
2043
+ ] }),
2044
+ "Back to store"
1975
2045
  ] }),
1976
- /* @__PURE__ */ jsx8("h3", { children: "Payment Successful!" }),
1977
- /* @__PURE__ */ jsx8("p", { children: "Thank you for your order." })
1978
- ] }) : /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-split", children: [
1979
- /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-summary", children: [
1980
- /* @__PURE__ */ jsx8("h3", { children: "Order Summary" }),
1981
- cartLoading || !cart ? /* @__PURE__ */ jsx8("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ jsxs5(Fragment5, { children: [
1982
- /* @__PURE__ */ jsx8("ul", { className: "hsk-checkout-items", children: cart.items.map((item) => /* @__PURE__ */ jsxs5("li", { children: [
1983
- /* @__PURE__ */ jsxs5("span", { children: [
1984
- item.quantity,
1985
- "x ",
1986
- item.name
1987
- ] }),
1988
- /* @__PURE__ */ jsxs5("span", { children: [
1989
- item.currency,
1990
- " ",
1991
- (item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
1992
- ] })
1993
- ] }, item.id)) }),
1994
- /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-total", children: [
1995
- /* @__PURE__ */ jsx8("span", { children: "Total" }),
1996
- /* @__PURE__ */ jsxs5("span", { children: [
1997
- cart.currency,
1998
- " ",
1999
- cart.total.toLocaleString(void 0, { minimumFractionDigits: 2 })
2000
- ] })
2001
- ] })
2046
+ /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-store-info", children: /* @__PURE__ */ jsx8("h2", { children: "Secure Checkout" }) }),
2047
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-amount-due", children: [
2048
+ /* @__PURE__ */ jsx8("span", { className: "hsk-checkout-label-muted", children: "Pay total" }),
2049
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-grand-total", children: [
2050
+ currency,
2051
+ " ",
2052
+ total.toLocaleString(void 0, { minimumFractionDigits: 2 })
2002
2053
  ] })
2003
2054
  ] }),
2004
- /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-payment", children: [
2005
- /* @__PURE__ */ jsx8("h3", { children: "Payment Method" }),
2006
- loading ? /* @__PURE__ */ jsx8("p", { className: "hsk-cart-loading", children: "Loading secure payment methods..." }) : !hasPaymentMethods ? /* @__PURE__ */ jsx8("p", { className: "hsk-checkout-error", children: "No payment methods are currently available for this store." }) : /* @__PURE__ */ jsxs5("div", { className: "hsk-payment-options", children: [
2007
- ((_a = config == null ? void 0 : config.mpesa) == null ? void 0 : _a.enabled) && /* @__PURE__ */ jsx8("button", { onClick: () => handlePay("mpesa"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-mpesa", children: checkingOut ? "Processing..." : "Pay with M-Pesa" }),
2008
- ((_b = config == null ? void 0 : config.equity) == null ? void 0 : _b.enabled) && /* @__PURE__ */ jsx8("button", { onClick: () => handlePay("equity"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-equity", children: checkingOut ? "Processing..." : "Pay with Equity Bank" }),
2009
- ((_c = config == null ? void 0 : config.stripe) == null ? void 0 : _c.enabled) && /* @__PURE__ */ jsx8("button", { onClick: () => handlePay("stripe"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-stripe", children: checkingOut ? "Processing..." : "Pay with Card (Stripe)" }),
2010
- ((_d = config == null ? void 0 : config.paypal) == null ? void 0 : _d.enabled) && /* @__PURE__ */ jsx8("button", { onClick: () => handlePay("paypal"), disabled: checkingOut, className: "hsk-pay-btn hsk-pay-paypal", children: checkingOut ? "Processing..." : "Pay with PayPal" })
2055
+ cartLoading || !cart ? /* @__PURE__ */ jsx8("p", { className: "hsk-cart-loading", children: "Loading order..." }) : /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-items-list-wrap", children: /* @__PURE__ */ jsx8("ul", { className: "hsk-checkout-items-list", children: cart.items.map((item) => /* @__PURE__ */ jsxs5("li", { className: "hsk-checkout-item-row", children: [
2056
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-item-img-container", children: [
2057
+ item.image ? /* @__PURE__ */ jsx8("img", { src: item.image, alt: item.name, className: "hsk-checkout-item-img" }) : /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-item-img-placeholder", children: "\u{1F6D2}" }),
2058
+ /* @__PURE__ */ jsx8("span", { className: "hsk-checkout-item-qty-badge", children: item.quantity })
2059
+ ] }),
2060
+ /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-item-details", children: /* @__PURE__ */ jsx8("span", { className: "hsk-checkout-item-name", children: item.name }) }),
2061
+ /* @__PURE__ */ jsxs5("span", { className: "hsk-checkout-item-price", children: [
2062
+ item.currency,
2063
+ " ",
2064
+ (item.price_numeric * item.quantity).toLocaleString(void 0, { minimumFractionDigits: 2 })
2011
2065
  ] })
2066
+ ] }, item.id)) }) })
2067
+ ] }) }),
2068
+ /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-panel-right", children: /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-right-content", children: phase === "done" ? /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-status-card success", children: [
2069
+ /* @__PURE__ */ jsx8("div", { className: "hsk-status-icon-wrap success", children: "\u2705" }),
2070
+ /* @__PURE__ */ jsx8("h3", { children: "Payment Successful!" }),
2071
+ /* @__PURE__ */ jsx8("p", { children: "Your transaction has been confirmed successfully. Thank you for your order!" }),
2072
+ /* @__PURE__ */ jsx8("button", { onClick: onClose, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Continue Shopping" })
2073
+ ] }) : phase === "awaiting" ? /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-status-card awaiting", children: [
2074
+ /* @__PURE__ */ jsx8("div", { className: "hsk-status-spinner-wrap", children: /* @__PURE__ */ jsx8("div", { className: "hsk-status-spinner" }) }),
2075
+ /* @__PURE__ */ jsx8("h3", { children: "Confirm payment on your phone" }),
2076
+ /* @__PURE__ */ jsxs5("p", { children: [
2077
+ "We've sent an M-Pesa STK push prompt to ",
2078
+ /* @__PURE__ */ jsxs5("strong", { children: [
2079
+ "254",
2080
+ phone
2081
+ ] }),
2082
+ "."
2083
+ ] }),
2084
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-stk-instructions", children: [
2085
+ /* @__PURE__ */ jsx8("p", { children: "1. Check your phone lockscreen for the M-Pesa prompt." }),
2086
+ /* @__PURE__ */ jsx8("p", { children: "2. Enter your M-Pesa PIN and press OK." }),
2087
+ /* @__PURE__ */ jsx8("p", { children: "3. Wait here; this page will automatically redirect once confirmed." })
2088
+ ] }),
2089
+ /* @__PURE__ */ jsx8(
2090
+ "button",
2091
+ {
2092
+ onClick: () => {
2093
+ setPhase("idle");
2094
+ setMerchantRef(null);
2095
+ },
2096
+ className: "hsk-checkout-cancel-btn",
2097
+ children: "Cancel and change phone number"
2098
+ }
2099
+ )
2100
+ ] }) : phase === "failed" ? /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-status-card failed", children: [
2101
+ /* @__PURE__ */ jsx8("div", { className: "hsk-status-icon-wrap failed", children: "\u274C" }),
2102
+ /* @__PURE__ */ jsx8("h3", { children: "Payment failed or timed out" }),
2103
+ /* @__PURE__ */ jsx8("p", { className: "hsk-checkout-error-text", children: payError || "Could not verify M-Pesa transaction." }),
2104
+ /* @__PURE__ */ jsx8("button", { onClick: () => {
2105
+ setPhase("idle");
2106
+ setPayError(null);
2107
+ }, className: "hsk-pay-btn hsk-btn-primary", style: { marginTop: "1.5rem" }, children: "Try Again" })
2108
+ ] }) : /* @__PURE__ */ jsxs5("div", { className: "hsk-checkout-payment-form-wrap", children: [
2109
+ /* @__PURE__ */ jsx8("h3", { className: "hsk-checkout-section-title", children: "Payment details" }),
2110
+ loadingConfig ? /* @__PURE__ */ jsx8("p", { className: "hsk-cart-loading", children: "Loading payment configuration..." }) : !hasPaymentMethods ? /* @__PURE__ */ jsx8("p", { className: "hsk-checkout-error", children: "No payment methods configured for this store." }) : /* @__PURE__ */ jsxs5("form", { onSubmit: handlePay, className: "hsk-stripe-checkout-form", children: [
2111
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-form-group", children: [
2112
+ /* @__PURE__ */ jsx8("label", { className: "hsk-form-label", children: "M-Pesa Mobile Number" }),
2113
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-phone-input-container", children: [
2114
+ /* @__PURE__ */ jsx8("span", { className: "hsk-phone-prefix", children: "254" }),
2115
+ /* @__PURE__ */ jsx8(
2116
+ "input",
2117
+ {
2118
+ type: "tel",
2119
+ required: true,
2120
+ placeholder: "712345678",
2121
+ pattern: "[0-9]{9}",
2122
+ maxLength: 9,
2123
+ value: phone,
2124
+ onChange: (e) => setPhone(e.target.value.replace(/\D/g, "")),
2125
+ className: "hsk-phone-input-field"
2126
+ }
2127
+ )
2128
+ ] }),
2129
+ /* @__PURE__ */ jsx8("span", { className: "hsk-form-hint", children: "Enter your 9-digit number (e.g. 712345678)" })
2130
+ ] }),
2131
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-form-group", children: [
2132
+ /* @__PURE__ */ jsx8("label", { className: "hsk-form-label", children: "Email address" }),
2133
+ /* @__PURE__ */ jsx8(
2134
+ "input",
2135
+ {
2136
+ type: "email",
2137
+ placeholder: "john.doe@example.com",
2138
+ value: email,
2139
+ onChange: (e) => setEmail(e.target.value),
2140
+ className: "hsk-form-input"
2141
+ }
2142
+ )
2143
+ ] }),
2144
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-form-row", children: [
2145
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-form-group", children: [
2146
+ /* @__PURE__ */ jsx8("label", { className: "hsk-form-label", children: "First Name" }),
2147
+ /* @__PURE__ */ jsx8(
2148
+ "input",
2149
+ {
2150
+ type: "text",
2151
+ placeholder: "John",
2152
+ value: firstName,
2153
+ onChange: (e) => setFirstName(e.target.value),
2154
+ className: "hsk-form-input"
2155
+ }
2156
+ )
2157
+ ] }),
2158
+ /* @__PURE__ */ jsxs5("div", { className: "hsk-form-group", children: [
2159
+ /* @__PURE__ */ jsx8("label", { className: "hsk-form-label", children: "Last Name" }),
2160
+ /* @__PURE__ */ jsx8(
2161
+ "input",
2162
+ {
2163
+ type: "text",
2164
+ placeholder: "Doe",
2165
+ value: lastName,
2166
+ onChange: (e) => setLastName(e.target.value),
2167
+ className: "hsk-form-input"
2168
+ }
2169
+ )
2170
+ ] })
2171
+ ] }),
2172
+ payError && /* @__PURE__ */ jsx8("div", { className: "hsk-form-error-banner", children: payError }),
2173
+ /* @__PURE__ */ jsxs5("button", { type: "submit", className: "hsk-checkout-submit-btn", children: [
2174
+ "Pay ",
2175
+ currency,
2176
+ " ",
2177
+ total.toLocaleString()
2178
+ ] }),
2179
+ /* @__PURE__ */ jsx8("div", { className: "hsk-checkout-footer-brand", children: /* @__PURE__ */ jsx8("span", { children: "Powered by Huskel AI" }) })
2012
2180
  ] })
2013
- ] }) })
2181
+ ] }) }) })
2014
2182
  ]
2015
2183
  }
2016
2184
  )
@@ -2021,7 +2189,7 @@ function CheckoutModal({
2021
2189
  }
2022
2190
 
2023
2191
  // src/components/CartDrawer.tsx
2024
- import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2192
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2025
2193
  function CartDrawer({
2026
2194
  trigger,
2027
2195
  className,
@@ -2055,12 +2223,18 @@ function CartDrawer({
2055
2223
  }, [open]);
2056
2224
  const handleCheckout = async () => {
2057
2225
  if (!cart || cart.items.length === 0) return;
2226
+ const event = new CustomEvent("huskel:trigger_checkout", { cancelable: true });
2227
+ window.dispatchEvent(event);
2228
+ if (event.defaultPrevented) {
2229
+ setOpen(false);
2230
+ return;
2231
+ }
2058
2232
  setShowCheckout(true);
2059
2233
  };
2060
2234
  const isStringTheme = typeof theme === "string";
2061
2235
  const hskThemeAttr = isStringTheme ? theme : void 0;
2062
2236
  const customStyles = !isStringTheme && theme ? __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor, "--hsk-primary-color": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily }), (theme == null ? void 0 : theme.borderRadius) && { "--hsk-border-radius": theme.borderRadius }) : void 0;
2063
- return /* @__PURE__ */ jsxs6(Fragment6, { children: [
2237
+ return /* @__PURE__ */ jsxs6(Fragment5, { children: [
2064
2238
  /* @__PURE__ */ jsx9("div", { onClick: () => setOpen(true), style: { display: "inline-block" }, children: trigger || /* @__PURE__ */ jsxs6(
2065
2239
  "button",
2066
2240
  {