@uptrademedia/site-kit 1.0.35 → 1.0.36

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.
@@ -254,6 +254,24 @@ async function registerForEvent(eventId, scheduleId, customer) {
254
254
  return { success: false, error: "Network error. Please try again." };
255
255
  }
256
256
  }
257
+ async function fetchProcessorConfig() {
258
+ const { apiUrl, apiKey } = getApiConfig();
259
+ if (!apiKey) return null;
260
+ try {
261
+ const response = await fetch(`${apiUrl}/api/public/commerce/processor-config`, {
262
+ method: "POST",
263
+ headers: {
264
+ "Content-Type": "application/json",
265
+ "x-api-key": apiKey
266
+ },
267
+ body: JSON.stringify({})
268
+ });
269
+ if (!response.ok) return null;
270
+ return await response.json();
271
+ } catch {
272
+ return null;
273
+ }
274
+ }
257
275
  async function createCheckoutSession(optionsOrOfferingId, legacyOptions) {
258
276
  const { apiUrl, apiKey } = getApiConfig();
259
277
  const options = typeof optionsOrOfferingId === "string" ? { offeringId: optionsOrOfferingId, ...legacyOptions } : optionsOrOfferingId;
@@ -274,8 +292,12 @@ async function createCheckoutSession(optionsOrOfferingId, legacyOptions) {
274
292
  })
275
293
  });
276
294
  if (!response.ok) {
277
- const error = await response.json();
278
- return { success: false, error: error.message || "Checkout failed" };
295
+ const error = await response.json().catch(() => ({}));
296
+ const message = error?.message || (typeof error?.error === "string" ? error.error : null) || "Checkout failed";
297
+ if (typeof console !== "undefined" && console.error) {
298
+ console.error("[Commerce] Checkout failed:", response.status, message, error);
299
+ }
300
+ return { success: false, error: message };
279
301
  }
280
302
  const result = await response.json();
281
303
  return {
@@ -2811,6 +2833,17 @@ function CalendarView({
2811
2833
  }, children: "Loading..." })
2812
2834
  ] });
2813
2835
  }
2836
+ function loadSquareSDK(environment) {
2837
+ return new Promise((resolve, reject) => {
2838
+ if (typeof window === "undefined") return reject(new Error("No window"));
2839
+ if (window.Square) return resolve();
2840
+ const script = document.createElement("script");
2841
+ script.src = environment === "sandbox" ? "https://sandbox.web.squarecdn.com/v1/square.js" : "https://web.squarecdn.com/v1/square.js";
2842
+ script.onload = () => resolve();
2843
+ script.onerror = () => reject(new Error("Failed to load Square SDK"));
2844
+ document.head.appendChild(script);
2845
+ });
2846
+ }
2814
2847
  function EventModal({
2815
2848
  event,
2816
2849
  schedule: propSchedule,
@@ -2835,13 +2868,54 @@ function EventModal({
2835
2868
  });
2836
2869
  const [additionalData, setAdditionalData] = React5.useState({});
2837
2870
  const [processor, setProcessor] = React5.useState(null);
2871
+ const [processorConfig, setProcessorConfig] = React5.useState(null);
2872
+ const [squareCard, setSquareCard] = React5.useState(null);
2873
+ const [cardReady, setCardReady] = React5.useState(false);
2874
+ const cardContainerRef = React5.useRef(null);
2838
2875
  const schedule = propSchedule || event?.schedules?.[0] || event?.next_schedule;
2839
2876
  React5.useEffect(() => {
2840
- if (isOpen) {
2841
- fetchActiveProcessor().then((p) => {
2842
- if (p) setProcessor(p);
2877
+ if (!isOpen) return;
2878
+ fetchProcessorConfig().then(async (config) => {
2879
+ setProcessorConfig(config);
2880
+ if (config?.processor) setProcessor(config.processor);
2881
+ if (config?.processor === "square" && config.squareAppId && config.squareLocationId) {
2882
+ try {
2883
+ await loadSquareSDK(config.squareEnvironment || "production");
2884
+ const Square = window.Square;
2885
+ const payments = Square.payments(config.squareAppId, config.squareLocationId);
2886
+ const card = await payments.card({
2887
+ style: {
2888
+ ".input-container": {
2889
+ borderColor: "#d1d5db",
2890
+ borderRadius: "6px"
2891
+ },
2892
+ ".input-container.is-focus": {
2893
+ borderColor: "#2563eb"
2894
+ },
2895
+ ".input-container.is-error": {
2896
+ borderColor: "#dc2626"
2897
+ }
2898
+ }
2899
+ });
2900
+ await card.attach("#sq-card-container");
2901
+ setSquareCard(card);
2902
+ setCardReady(true);
2903
+ } catch (err) {
2904
+ console.error("[Commerce] Square card init failed:", err);
2905
+ }
2906
+ }
2907
+ });
2908
+ return () => {
2909
+ setSquareCard((prev) => {
2910
+ if (prev) {
2911
+ prev.destroy?.().catch(() => {
2912
+ });
2913
+ }
2914
+ return null;
2843
2915
  });
2844
- }
2916
+ setCardReady(false);
2917
+ setProcessorConfig(null);
2918
+ };
2845
2919
  }, [isOpen]);
2846
2920
  React5.useEffect(() => {
2847
2921
  if (isOpen && event) {
@@ -2903,17 +2977,34 @@ function EventModal({
2903
2977
  onError?.(result.error || "Registration failed");
2904
2978
  }
2905
2979
  } else {
2906
- const result = await createCheckoutSession(event.id, {
2980
+ let sourceId;
2981
+ if (squareCard && cardReady) {
2982
+ const tokenResult = await squareCard.tokenize();
2983
+ if (tokenResult.status !== "OK") {
2984
+ const msg = tokenResult.errors?.[0]?.message || "Card verification failed. Please check your card details.";
2985
+ setError(msg);
2986
+ onError?.(msg);
2987
+ setLoading(false);
2988
+ return;
2989
+ }
2990
+ sourceId = tokenResult.token;
2991
+ }
2992
+ const result = await createCheckoutSession({
2993
+ offeringId: event.id,
2907
2994
  scheduleId: schedule.id,
2908
2995
  quantity,
2909
2996
  customer: {
2910
2997
  ...customer,
2911
2998
  ...additionalData
2912
2999
  },
3000
+ sourceId,
2913
3001
  successUrl: window.location.href + "?registration=success",
2914
3002
  cancelUrl: window.location.href
2915
3003
  });
2916
- if (result.success && result.payment_url) {
3004
+ if (result.success && !result.payment_url) {
3005
+ setSuccess(true);
3006
+ onSuccess?.(result);
3007
+ } else if (result.success && result.payment_url) {
2917
3008
  window.location.href = result.payment_url;
2918
3009
  } else {
2919
3010
  setError(result.error || "Checkout failed");
@@ -3237,6 +3328,30 @@ function EventModal({
3237
3328
  )
3238
3329
  ] }, field.name))
3239
3330
  ] }),
3331
+ !isFree && processor === "square" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1rem" }, children: [
3332
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: {
3333
+ display: "block",
3334
+ fontSize: "0.875rem",
3335
+ fontWeight: 500,
3336
+ color: "#374151",
3337
+ marginBottom: "0.375rem"
3338
+ }, children: "Card Details *" }),
3339
+ /* @__PURE__ */ jsxRuntime.jsx(
3340
+ "div",
3341
+ {
3342
+ id: "sq-card-container",
3343
+ ref: cardContainerRef,
3344
+ style: {
3345
+ minHeight: "42px",
3346
+ border: "1px solid #d1d5db",
3347
+ borderRadius: "6px",
3348
+ padding: "0.5rem 0.75rem",
3349
+ background: "#fff"
3350
+ }
3351
+ }
3352
+ ),
3353
+ !cardReady && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.75rem", color: "#9ca3af", marginTop: "0.25rem" }, children: "Loading card form..." })
3354
+ ] }),
3240
3355
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
3241
3356
  marginTop: "1rem",
3242
3357
  padding: "0.75rem",
@@ -3250,7 +3365,7 @@ function EventModal({
3250
3365
  "button",
3251
3366
  {
3252
3367
  type: "submit",
3253
- disabled: loading,
3368
+ disabled: loading || !isFree && processor === "square" && !cardReady,
3254
3369
  style: {
3255
3370
  width: "100%",
3256
3371
  marginTop: "1.25rem",
@@ -3259,9 +3374,9 @@ function EventModal({
3259
3374
  fontWeight: 600,
3260
3375
  borderRadius: "8px",
3261
3376
  border: "none",
3262
- background: loading ? "#93c5fd" : "#2563eb",
3377
+ background: loading || !isFree && processor === "square" && !cardReady ? "#93c5fd" : "#2563eb",
3263
3378
  color: "white",
3264
- cursor: loading ? "not-allowed" : "pointer"
3379
+ cursor: loading || !isFree && processor === "square" && !cardReady ? "not-allowed" : "pointer"
3265
3380
  },
3266
3381
  children: loading ? "Processing..." : isFree ? "Register Free" : `Pay ${formatPrice(total, event.currency)}`
3267
3382
  }
@@ -3937,6 +4052,7 @@ exports.fetchLatestOffering = fetchLatestOffering;
3937
4052
  exports.fetchNextEvent = fetchNextEvent;
3938
4053
  exports.fetchOffering = fetchOffering;
3939
4054
  exports.fetchOfferings = fetchOfferings;
4055
+ exports.fetchProcessorConfig = fetchProcessorConfig;
3940
4056
  exports.fetchProductBySlug = fetchProductBySlug;
3941
4057
  exports.fetchProducts = fetchProducts;
3942
4058
  exports.fetchProductsPublic = fetchProductsPublic;
@@ -3953,5 +4069,5 @@ exports.getSpotsRemaining = getSpotsRemaining;
3953
4069
  exports.isEventSoldOut = isEventSoldOut;
3954
4070
  exports.registerForEvent = registerForEvent;
3955
4071
  exports.useEventModal = useEventModal;
3956
- //# sourceMappingURL=chunk-NQWSKGOX.js.map
3957
- //# sourceMappingURL=chunk-NQWSKGOX.js.map
4072
+ //# sourceMappingURL=chunk-WTMMXY7S.js.map
4073
+ //# sourceMappingURL=chunk-WTMMXY7S.js.map