@aranova/tracking-react 1.2.5 → 1.3.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 +70 -0
- package/dist/{tracking-config-runtime-C6H7ofmo.d.mts → bookings-CqdjLMkv.d.ts} +144 -1
- package/dist/{tracking-config-runtime-C6H7ofmo.d.ts → bookings-VsQdopTt.d.mts} +144 -1
- package/dist/client.d.mts +56 -5
- package/dist/client.d.ts +56 -5
- package/dist/client.js +281 -11
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +276 -11
- package/dist/client.mjs.map +1 -1
- package/dist/form-submit-BLb28aCk.d.mts +75 -0
- package/dist/form-submit-BLb28aCk.d.ts +75 -0
- package/dist/index.d.mts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +429 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +424 -4
- package/dist/index.mjs.map +1 -1
- package/dist/{ingest-typed-oAwnKqH2.d.mts → ingest-typed-BCUv93ax.d.mts} +78 -2
- package/dist/{ingest-typed-CUpdCtmM.d.ts → ingest-typed-DGqzbteM.d.ts} +78 -2
- package/dist/{phone-utils-qLfVpQI7.d.mts → phone-utils-CM8eUPz8.d.mts} +2 -74
- package/dist/{phone-utils-qLfVpQI7.d.ts → phone-utils-l8ey3Zdm.d.ts} +2 -74
- package/dist/phone.d.mts +2 -1
- package/dist/phone.d.ts +2 -1
- package/dist/{sales-C3O_xxZ_.d.ts → sales-DSL6vMuY.d.mts} +23 -2
- package/dist/{sales-BuKD_bdo.d.mts → sales-_F3nnI2r.d.ts} +23 -2
- package/dist/sales.d.mts +3 -2
- package/dist/sales.d.ts +3 -2
- package/dist/sales.js +307 -9
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +305 -9
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -32,10 +32,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
var client_exports = {};
|
|
33
33
|
__export(client_exports, {
|
|
34
34
|
AdPlatformTracking: () => AdPlatformTracking,
|
|
35
|
+
BookingHandoffLink: () => BookingHandoffLink,
|
|
35
36
|
ConsentBanner: () => ConsentBanner,
|
|
36
37
|
GoogleAdsTracking: () => GoogleAdsTracking,
|
|
37
38
|
PhoneField: () => PhoneField,
|
|
38
39
|
createTracking: () => createTracking,
|
|
40
|
+
useBookingHandoffUrl: () => useBookingHandoffUrl,
|
|
41
|
+
useBookingIntegration: () => useBookingIntegration,
|
|
42
|
+
useBookingSlots: () => useBookingSlots,
|
|
43
|
+
useBookingSubmit: () => useBookingSubmit,
|
|
39
44
|
useConsent: () => useConsent,
|
|
40
45
|
useConsentState: () => useConsentState,
|
|
41
46
|
useCookiePreferences: () => useCookiePreferences,
|
|
@@ -289,6 +294,8 @@ var TRACKING_CAPABILITIES = [
|
|
|
289
294
|
"ad_tags_meta",
|
|
290
295
|
"base_tracking",
|
|
291
296
|
"blog_rendering",
|
|
297
|
+
"booking_handoff",
|
|
298
|
+
"booking_integration",
|
|
292
299
|
"calendar_read",
|
|
293
300
|
"calendar_write",
|
|
294
301
|
"consent_controls",
|
|
@@ -691,15 +698,23 @@ function buildLandingPayloadFields(sessionId, override) {
|
|
|
691
698
|
};
|
|
692
699
|
}
|
|
693
700
|
|
|
701
|
+
// ../tracking-core/src/uuid.ts
|
|
702
|
+
function uuidV4() {
|
|
703
|
+
const cryptoApi = globalThis.crypto;
|
|
704
|
+
if (typeof cryptoApi?.randomUUID === "function") return cryptoApi.randomUUID();
|
|
705
|
+
const bytes = new Uint8Array(16);
|
|
706
|
+
if (typeof cryptoApi?.getRandomValues === "function") cryptoApi.getRandomValues(bytes);
|
|
707
|
+
else for (let i = 0; i < 16; i += 1) bytes[i] = Math.floor(Math.random() * 256);
|
|
708
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
709
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
710
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
711
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
712
|
+
}
|
|
713
|
+
|
|
694
714
|
// ../tracking-core/src/session.ts
|
|
695
715
|
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
696
716
|
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
697
717
|
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
698
|
-
function safeUuid() {
|
|
699
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
|
|
700
|
-
return crypto.randomUUID();
|
|
701
|
-
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}-${Math.random().toString(16).slice(2)}`;
|
|
702
|
-
}
|
|
703
718
|
function readLocalStorage(key) {
|
|
704
719
|
try {
|
|
705
720
|
return window.localStorage.getItem(key);
|
|
@@ -714,10 +729,10 @@ function writeLocalStorage(key, value) {
|
|
|
714
729
|
}
|
|
715
730
|
}
|
|
716
731
|
function getVisitorId() {
|
|
717
|
-
if (typeof window === "undefined") return
|
|
732
|
+
if (typeof window === "undefined") return uuidV4();
|
|
718
733
|
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
719
734
|
if (existing && existing.length > 0) return existing;
|
|
720
|
-
const fresh =
|
|
735
|
+
const fresh = uuidV4();
|
|
721
736
|
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
722
737
|
return fresh;
|
|
723
738
|
}
|
|
@@ -729,7 +744,7 @@ function adoptVisitorId(visitorId) {
|
|
|
729
744
|
return readLocalStorage(VISITOR_STORAGE_KEY) === visitorId;
|
|
730
745
|
}
|
|
731
746
|
function getOrRotateSessionId(now = Date.now()) {
|
|
732
|
-
if (typeof window === "undefined") return { id:
|
|
747
|
+
if (typeof window === "undefined") return { id: uuidV4(), isNew: true };
|
|
733
748
|
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
734
749
|
if (raw) {
|
|
735
750
|
try {
|
|
@@ -744,7 +759,7 @@ function getOrRotateSessionId(now = Date.now()) {
|
|
|
744
759
|
} catch {
|
|
745
760
|
}
|
|
746
761
|
}
|
|
747
|
-
const fresh = { id:
|
|
762
|
+
const fresh = { id: uuidV4(), last_event_at: now };
|
|
748
763
|
writeLocalStorage(SESSION_STORAGE_KEY, JSON.stringify(fresh));
|
|
749
764
|
return { id: fresh.id, isNew: true };
|
|
750
765
|
}
|
|
@@ -977,6 +992,69 @@ function parseFiring(value) {
|
|
|
977
992
|
currency: typeof f.currency === "string" ? f.currency : null
|
|
978
993
|
};
|
|
979
994
|
}
|
|
995
|
+
function isNumberList(value) {
|
|
996
|
+
return Array.isArray(value) && value.every((v) => typeof v === "number");
|
|
997
|
+
}
|
|
998
|
+
function isStringList(value) {
|
|
999
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
1000
|
+
}
|
|
1001
|
+
function parseWindowsMap(value) {
|
|
1002
|
+
const windowsByKey = {};
|
|
1003
|
+
if (!value || typeof value !== "object") return windowsByKey;
|
|
1004
|
+
for (const [key, windows] of Object.entries(value)) {
|
|
1005
|
+
if (!windows || typeof windows !== "object") continue;
|
|
1006
|
+
const w = windows;
|
|
1007
|
+
windowsByKey[key] = {
|
|
1008
|
+
morning: isNumberList(w.morning) ? w.morning : [],
|
|
1009
|
+
afternoon: isNumberList(w.afternoon) ? w.afternoon : []
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
return windowsByKey;
|
|
1013
|
+
}
|
|
1014
|
+
function parseBookingRules(value) {
|
|
1015
|
+
if (!value || typeof value !== "object") return null;
|
|
1016
|
+
const r = value;
|
|
1017
|
+
if (typeof r.min_days_ahead !== "number" || typeof r.max_days_ahead !== "number") return null;
|
|
1018
|
+
if (!r.hours || typeof r.hours !== "object") return null;
|
|
1019
|
+
const hours = parseWindowsMap(r.hours);
|
|
1020
|
+
return {
|
|
1021
|
+
min_days_ahead: r.min_days_ahead,
|
|
1022
|
+
max_days_ahead: r.max_days_ahead,
|
|
1023
|
+
hours,
|
|
1024
|
+
closed_dates: isStringList(r.closed_dates) ? r.closed_dates : [],
|
|
1025
|
+
special_hours: parseWindowsMap(r.special_hours),
|
|
1026
|
+
vehicle_required: r.vehicle_required === true,
|
|
1027
|
+
drop_off_options: isStringList(r.drop_off_options) ? r.drop_off_options : []
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
function parseBookingOption(value) {
|
|
1031
|
+
if (!value || typeof value !== "object") return [];
|
|
1032
|
+
const o = value;
|
|
1033
|
+
if (typeof o.key !== "string" || !o.key || typeof o.label !== "string") return [];
|
|
1034
|
+
return [{ key: o.key, label: o.label }];
|
|
1035
|
+
}
|
|
1036
|
+
function parseIntegrations(value) {
|
|
1037
|
+
if (!value || typeof value !== "object") return {};
|
|
1038
|
+
const autoleap = value.autoleap;
|
|
1039
|
+
if (!autoleap || typeof autoleap !== "object") return {};
|
|
1040
|
+
const booking = autoleap.booking;
|
|
1041
|
+
if (!booking || typeof booking !== "object") return {};
|
|
1042
|
+
const b = booking;
|
|
1043
|
+
if (typeof b.fallback_url !== "string" || !b.fallback_url) return {};
|
|
1044
|
+
return {
|
|
1045
|
+
autoleap: {
|
|
1046
|
+
booking: {
|
|
1047
|
+
enabled: b.enabled === true,
|
|
1048
|
+
fallback_url: b.fallback_url,
|
|
1049
|
+
timezone: typeof b.timezone === "string" ? b.timezone : "UTC",
|
|
1050
|
+
config_version: typeof b.config_version === "number" ? b.config_version : null,
|
|
1051
|
+
accepts_bookings: b.accepts_bookings === true,
|
|
1052
|
+
rules: parseBookingRules(b.rules),
|
|
1053
|
+
options: Array.isArray(b.options) ? b.options.flatMap(parseBookingOption) : []
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
980
1058
|
function parseTrigger(value) {
|
|
981
1059
|
if (!value || typeof value !== "object") return null;
|
|
982
1060
|
const t = value;
|
|
@@ -1036,7 +1114,8 @@ function parseConversionConfig(raw) {
|
|
|
1036
1114
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
1037
1115
|
services,
|
|
1038
1116
|
goals,
|
|
1039
|
-
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : []
|
|
1117
|
+
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : [],
|
|
1118
|
+
integrations: parseIntegrations(obj.integrations)
|
|
1040
1119
|
};
|
|
1041
1120
|
}
|
|
1042
1121
|
var CACHE_PREFIX = "_aranova_cfg_";
|
|
@@ -1460,6 +1539,13 @@ var TrackingConfigRuntime = class {
|
|
|
1460
1539
|
linkedHostnames() {
|
|
1461
1540
|
return this.current?.linked_hostnames ?? [];
|
|
1462
1541
|
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Integration blocks, from the cached object even while unconfirmed: the booking fallback
|
|
1544
|
+
* link is safe to show stale. Same reference until the next adopt, for `useSyncExternalStore`.
|
|
1545
|
+
*/
|
|
1546
|
+
integrations() {
|
|
1547
|
+
return this.current?.integrations ?? null;
|
|
1548
|
+
}
|
|
1463
1549
|
async revalidateNow() {
|
|
1464
1550
|
try {
|
|
1465
1551
|
const headers = {};
|
|
@@ -1629,6 +1715,105 @@ function getTrackingConfigRuntime(ref, fetchImpl) {
|
|
|
1629
1715
|
return runtime;
|
|
1630
1716
|
}
|
|
1631
1717
|
|
|
1718
|
+
// ../../contracts/autoleap-booking-links.json
|
|
1719
|
+
var autoleap_booking_links_default = {
|
|
1720
|
+
hosts: ["myalp.io"]
|
|
1721
|
+
};
|
|
1722
|
+
|
|
1723
|
+
// ../tracking-core/src/integrations-public.ts
|
|
1724
|
+
var HANDOFF_HOSTS = new Set(autoleap_booking_links_default.hosts);
|
|
1725
|
+
function getBookingIntegration(integrations) {
|
|
1726
|
+
const booking = integrations?.autoleap?.booking;
|
|
1727
|
+
if (!booking) return null;
|
|
1728
|
+
const rules = booking.rules ? camelRules(booking.rules) : null;
|
|
1729
|
+
return {
|
|
1730
|
+
provider: "autoleap",
|
|
1731
|
+
enabled: booking.enabled,
|
|
1732
|
+
fallbackUrl: booking.fallback_url,
|
|
1733
|
+
acceptsBookings: booking.accepts_bookings && rules !== null && booking.config_version !== null,
|
|
1734
|
+
timezone: booking.timezone,
|
|
1735
|
+
configVersion: booking.config_version,
|
|
1736
|
+
rules,
|
|
1737
|
+
options: booking.options.map((option) => ({ key: option.key, label: option.label }))
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
function camelRules(rules) {
|
|
1741
|
+
return {
|
|
1742
|
+
minDaysAhead: rules.min_days_ahead,
|
|
1743
|
+
maxDaysAhead: rules.max_days_ahead,
|
|
1744
|
+
hours: rules.hours,
|
|
1745
|
+
closedDates: rules.closed_dates,
|
|
1746
|
+
specialHours: rules.special_hours,
|
|
1747
|
+
vehicleRequired: rules.vehicle_required,
|
|
1748
|
+
dropOffOptions: rules.drop_off_options
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
var WEEKDAYS = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
|
|
1752
|
+
function shopToday(timeZone, now = /* @__PURE__ */ new Date()) {
|
|
1753
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
1754
|
+
timeZone,
|
|
1755
|
+
year: "numeric",
|
|
1756
|
+
month: "2-digit",
|
|
1757
|
+
day: "2-digit"
|
|
1758
|
+
}).formatToParts(now);
|
|
1759
|
+
const part = (type) => parts.find((p) => p.type === type)?.value ?? "";
|
|
1760
|
+
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
1761
|
+
}
|
|
1762
|
+
function addDays(isoDate, days) {
|
|
1763
|
+
const [year, month, day] = isoDate.split("-").map(Number);
|
|
1764
|
+
const date = new Date(Date.UTC(year, month - 1, day + days));
|
|
1765
|
+
return date.toISOString().slice(0, 10);
|
|
1766
|
+
}
|
|
1767
|
+
function bookableSlots(rules, { timeZone, now = /* @__PURE__ */ new Date() }) {
|
|
1768
|
+
const today = shopToday(timeZone, now);
|
|
1769
|
+
const days = [];
|
|
1770
|
+
const closed = new Set(rules.closedDates);
|
|
1771
|
+
for (let offset = rules.minDaysAhead; offset <= rules.maxDaysAhead; offset += 1) {
|
|
1772
|
+
const date = addDays(today, offset);
|
|
1773
|
+
if (closed.has(date)) continue;
|
|
1774
|
+
const weekday = WEEKDAYS[(/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getUTCDay()];
|
|
1775
|
+
const windows = rules.specialHours[date] ?? rules.hours[weekday];
|
|
1776
|
+
if (!windows || windows.morning.length === 0 && windows.afternoon.length === 0) continue;
|
|
1777
|
+
days.push({
|
|
1778
|
+
date,
|
|
1779
|
+
weekday,
|
|
1780
|
+
morning: [...windows.morning],
|
|
1781
|
+
afternoon: [...windows.afternoon]
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
return days;
|
|
1785
|
+
}
|
|
1786
|
+
function buildBookingHandoffUrl(fallbackUrl, prefill = {}) {
|
|
1787
|
+
let url;
|
|
1788
|
+
try {
|
|
1789
|
+
url = new URL(fallbackUrl);
|
|
1790
|
+
} catch {
|
|
1791
|
+
return null;
|
|
1792
|
+
}
|
|
1793
|
+
if (url.protocol !== "https:" || !HANDOFF_HOSTS.has(url.hostname) || url.username || url.password || url.port) {
|
|
1794
|
+
return null;
|
|
1795
|
+
}
|
|
1796
|
+
const [firstName, lastName] = prefill.firstName?.trim() ? [prefill.firstName, prefill.lastName] : splitFullName(prefill.name);
|
|
1797
|
+
const values = [
|
|
1798
|
+
["firstName", firstName?.trim()],
|
|
1799
|
+
["lastName", lastName?.trim()],
|
|
1800
|
+
["phone", prefill.phone ? nationalDigits(prefill.phone) : ""],
|
|
1801
|
+
["email", prefill.email?.trim()]
|
|
1802
|
+
];
|
|
1803
|
+
for (const [key, value] of values) {
|
|
1804
|
+
if (value) url.searchParams.set(key, value);
|
|
1805
|
+
}
|
|
1806
|
+
return url.toString();
|
|
1807
|
+
}
|
|
1808
|
+
function splitFullName(name) {
|
|
1809
|
+
const [first = "", ...rest] = (name ?? "").trim().split(/\s+/);
|
|
1810
|
+
return [first, rest.join(" ")];
|
|
1811
|
+
}
|
|
1812
|
+
function nationalDigits(phone) {
|
|
1813
|
+
const parsed = parsePhone(phone);
|
|
1814
|
+
return (parsed.isValid ? parsed.national : phone).replace(/\D/g, "");
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1632
1817
|
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
1633
1818
|
function currentPath() {
|
|
1634
1819
|
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
@@ -3448,6 +3633,9 @@ function attachPhoneClickCapture(client, config) {
|
|
|
3448
3633
|
};
|
|
3449
3634
|
}
|
|
3450
3635
|
|
|
3636
|
+
// ../tracking-core/src/resources/sales/bookings.ts
|
|
3637
|
+
var newBookingAttemptKey = uuidV4;
|
|
3638
|
+
|
|
3451
3639
|
// src/hooks.ts
|
|
3452
3640
|
function useGclid() {
|
|
3453
3641
|
const [gclid, setGclid] = (0, import_react.useState)(null);
|
|
@@ -3779,7 +3967,7 @@ function GoogleAdsTracking(props) {
|
|
|
3779
3967
|
var import_react6 = require("react");
|
|
3780
3968
|
|
|
3781
3969
|
// package.json
|
|
3782
|
-
var version = "1.
|
|
3970
|
+
var version = "1.3.0";
|
|
3783
3971
|
|
|
3784
3972
|
// ../tracking-core/src/phone-react.tsx
|
|
3785
3973
|
var import_react5 = require("react");
|
|
@@ -4046,13 +4234,95 @@ function createTracking(options) {
|
|
|
4046
4234
|
)
|
|
4047
4235
|
};
|
|
4048
4236
|
}
|
|
4237
|
+
|
|
4238
|
+
// ../tracking-core/src/booking-react.tsx
|
|
4239
|
+
var import_react7 = require("react");
|
|
4240
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
4241
|
+
function serverSnapshot() {
|
|
4242
|
+
return null;
|
|
4243
|
+
}
|
|
4244
|
+
function useBookingIntegration(trackingConfig) {
|
|
4245
|
+
registerCapability("booking_handoff");
|
|
4246
|
+
const subscribe = (0, import_react7.useCallback)(
|
|
4247
|
+
(listener) => trackingConfig ? getTrackingConfigRuntime(trackingConfig).subscribe(listener) : () => {
|
|
4248
|
+
},
|
|
4249
|
+
[trackingConfig]
|
|
4250
|
+
);
|
|
4251
|
+
const integrations = (0, import_react7.useSyncExternalStore)(
|
|
4252
|
+
subscribe,
|
|
4253
|
+
() => trackingConfig ? getTrackingConfigRuntime(trackingConfig).integrations() : null,
|
|
4254
|
+
serverSnapshot
|
|
4255
|
+
);
|
|
4256
|
+
return (0, import_react7.useMemo)(() => getBookingIntegration(integrations), [integrations]);
|
|
4257
|
+
}
|
|
4258
|
+
function useBookingHandoffUrl(trackingConfig, { fallbackUrl, prefill } = {}) {
|
|
4259
|
+
const booking = useBookingIntegration(trackingConfig);
|
|
4260
|
+
const base = booking?.fallbackUrl ?? fallbackUrl;
|
|
4261
|
+
return base ? buildBookingHandoffUrl(base, prefill) : null;
|
|
4262
|
+
}
|
|
4263
|
+
function BookingHandoffLink({
|
|
4264
|
+
trackingConfig,
|
|
4265
|
+
fallbackUrl,
|
|
4266
|
+
prefill,
|
|
4267
|
+
children,
|
|
4268
|
+
target = "_blank",
|
|
4269
|
+
rel = "noopener noreferrer",
|
|
4270
|
+
...anchorProps
|
|
4271
|
+
}) {
|
|
4272
|
+
const href = useBookingHandoffUrl(trackingConfig, { fallbackUrl, prefill });
|
|
4273
|
+
if (!href) return null;
|
|
4274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { ...anchorProps, href, target, rel, children });
|
|
4275
|
+
}
|
|
4276
|
+
function useBookingSlots(trackingConfig) {
|
|
4277
|
+
const booking = useBookingIntegration(trackingConfig);
|
|
4278
|
+
if (!booking?.acceptsBookings || !booking.rules) return [];
|
|
4279
|
+
return bookableSlots(booking.rules, { timeZone: booking.timezone });
|
|
4280
|
+
}
|
|
4281
|
+
function useBookingSubmit(bookings, options = {}) {
|
|
4282
|
+
registerCapability("booking_integration");
|
|
4283
|
+
const [outcome, setOutcome] = (0, import_react7.useState)(null);
|
|
4284
|
+
const [submitting, setSubmitting] = (0, import_react7.useState)(false);
|
|
4285
|
+
const attemptKey = (0, import_react7.useRef)(null);
|
|
4286
|
+
const inFlight = (0, import_react7.useRef)(null);
|
|
4287
|
+
const { formSubmit } = options;
|
|
4288
|
+
const submit = (0, import_react7.useCallback)(
|
|
4289
|
+
(input) => {
|
|
4290
|
+
if (inFlight.current) return inFlight.current;
|
|
4291
|
+
attemptKey.current ?? (attemptKey.current = newBookingAttemptKey());
|
|
4292
|
+
setSubmitting(true);
|
|
4293
|
+
const run = bookings.submit(input, { attemptKey: attemptKey.current, formSubmit }).then((result) => {
|
|
4294
|
+
const unrecorded = result.status === "invalid" || result.status === "stale" || result.status === "failed" && result.id === null;
|
|
4295
|
+
if (!unrecorded) attemptKey.current = null;
|
|
4296
|
+
setOutcome(result);
|
|
4297
|
+
return result;
|
|
4298
|
+
}).finally(() => {
|
|
4299
|
+
inFlight.current = null;
|
|
4300
|
+
setSubmitting(false);
|
|
4301
|
+
});
|
|
4302
|
+
inFlight.current = run;
|
|
4303
|
+
return run;
|
|
4304
|
+
},
|
|
4305
|
+
[bookings, formSubmit]
|
|
4306
|
+
);
|
|
4307
|
+
const reset = (0, import_react7.useCallback)(() => {
|
|
4308
|
+
attemptKey.current = null;
|
|
4309
|
+
setOutcome(null);
|
|
4310
|
+
}, []);
|
|
4311
|
+
const status = submitting ? "submitting" : outcome?.status ?? "idle";
|
|
4312
|
+
return { status, outcome, submit, reset };
|
|
4313
|
+
}
|
|
4049
4314
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4050
4315
|
0 && (module.exports = {
|
|
4051
4316
|
AdPlatformTracking,
|
|
4317
|
+
BookingHandoffLink,
|
|
4052
4318
|
ConsentBanner,
|
|
4053
4319
|
GoogleAdsTracking,
|
|
4054
4320
|
PhoneField,
|
|
4055
4321
|
createTracking,
|
|
4322
|
+
useBookingHandoffUrl,
|
|
4323
|
+
useBookingIntegration,
|
|
4324
|
+
useBookingSlots,
|
|
4325
|
+
useBookingSubmit,
|
|
4056
4326
|
useConsent,
|
|
4057
4327
|
useConsentState,
|
|
4058
4328
|
useCookiePreferences,
|