@aranova/tracking-react 1.2.5 → 1.4.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 +77 -0
- package/dist/{tracking-config-runtime-C6H7ofmo.d.ts → bookings-CqCuuyP6.d.mts} +165 -1
- package/dist/{tracking-config-runtime-C6H7ofmo.d.mts → bookings-DIu1ho6v.d.ts} +165 -1
- package/dist/client.d.mts +58 -5
- package/dist/client.d.ts +58 -5
- package/dist/client.js +287 -11
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +282 -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 +470 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +465 -4
- package/dist/index.mjs.map +1 -1
- package/dist/{ingest-typed-CUpdCtmM.d.ts → ingest-typed-D2S3Kb8m.d.ts} +83 -2
- package/dist/{ingest-typed-oAwnKqH2.d.mts → ingest-typed-D7UZr0EM.d.mts} +83 -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-CxJVthx_.d.mts} +23 -2
- package/dist/{sales-BuKD_bdo.d.mts → sales-hlcVTJSS.d.ts} +23 -2
- package/dist/sales.d.mts +3 -2
- package/dist/sales.d.ts +3 -2
- package/dist/sales.js +386 -38
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +384 -38
- 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
|
}
|
|
@@ -964,6 +979,10 @@ function fireConversionWithConsent(input, options) {
|
|
|
964
979
|
}
|
|
965
980
|
|
|
966
981
|
// ../tracking-core/src/resources/conversion-config.ts
|
|
982
|
+
var BOOKING_MODES = ["live", "test", "simulated"];
|
|
983
|
+
function isBookingMode(value) {
|
|
984
|
+
return BOOKING_MODES.includes(value);
|
|
985
|
+
}
|
|
967
986
|
function isStringMap(value) {
|
|
968
987
|
return typeof value === "object" && value !== null && Object.values(value).every((v) => typeof v === "string");
|
|
969
988
|
}
|
|
@@ -977,6 +996,70 @@ function parseFiring(value) {
|
|
|
977
996
|
currency: typeof f.currency === "string" ? f.currency : null
|
|
978
997
|
};
|
|
979
998
|
}
|
|
999
|
+
function isNumberList(value) {
|
|
1000
|
+
return Array.isArray(value) && value.every((v) => typeof v === "number");
|
|
1001
|
+
}
|
|
1002
|
+
function isStringList(value) {
|
|
1003
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
1004
|
+
}
|
|
1005
|
+
function parseWindowsMap(value) {
|
|
1006
|
+
const windowsByKey = {};
|
|
1007
|
+
if (!value || typeof value !== "object") return windowsByKey;
|
|
1008
|
+
for (const [key, windows] of Object.entries(value)) {
|
|
1009
|
+
if (!windows || typeof windows !== "object") continue;
|
|
1010
|
+
const w = windows;
|
|
1011
|
+
windowsByKey[key] = {
|
|
1012
|
+
morning: isNumberList(w.morning) ? w.morning : [],
|
|
1013
|
+
afternoon: isNumberList(w.afternoon) ? w.afternoon : []
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
return windowsByKey;
|
|
1017
|
+
}
|
|
1018
|
+
function parseBookingRules(value) {
|
|
1019
|
+
if (!value || typeof value !== "object") return null;
|
|
1020
|
+
const r = value;
|
|
1021
|
+
if (typeof r.min_days_ahead !== "number" || typeof r.max_days_ahead !== "number") return null;
|
|
1022
|
+
if (!r.hours || typeof r.hours !== "object") return null;
|
|
1023
|
+
const hours = parseWindowsMap(r.hours);
|
|
1024
|
+
return {
|
|
1025
|
+
min_days_ahead: r.min_days_ahead,
|
|
1026
|
+
max_days_ahead: r.max_days_ahead,
|
|
1027
|
+
hours,
|
|
1028
|
+
closed_dates: isStringList(r.closed_dates) ? r.closed_dates : [],
|
|
1029
|
+
special_hours: parseWindowsMap(r.special_hours),
|
|
1030
|
+
vehicle_required: r.vehicle_required === true,
|
|
1031
|
+
drop_off_options: isStringList(r.drop_off_options) ? r.drop_off_options : []
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
function parseBookingOption(value) {
|
|
1035
|
+
if (!value || typeof value !== "object") return [];
|
|
1036
|
+
const o = value;
|
|
1037
|
+
if (typeof o.key !== "string" || !o.key || typeof o.label !== "string") return [];
|
|
1038
|
+
return [{ key: o.key, label: o.label }];
|
|
1039
|
+
}
|
|
1040
|
+
function parseIntegrations(value) {
|
|
1041
|
+
if (!value || typeof value !== "object") return {};
|
|
1042
|
+
const autoleap = value.autoleap;
|
|
1043
|
+
if (!autoleap || typeof autoleap !== "object") return {};
|
|
1044
|
+
const booking = autoleap.booking;
|
|
1045
|
+
if (!booking || typeof booking !== "object") return {};
|
|
1046
|
+
const b = booking;
|
|
1047
|
+
if (typeof b.fallback_url !== "string" || !b.fallback_url) return {};
|
|
1048
|
+
return {
|
|
1049
|
+
autoleap: {
|
|
1050
|
+
booking: {
|
|
1051
|
+
enabled: b.enabled === true,
|
|
1052
|
+
fallback_url: b.fallback_url,
|
|
1053
|
+
timezone: typeof b.timezone === "string" ? b.timezone : "UTC",
|
|
1054
|
+
config_version: typeof b.config_version === "number" ? b.config_version : null,
|
|
1055
|
+
accepts_bookings: b.accepts_bookings === true,
|
|
1056
|
+
rules: parseBookingRules(b.rules),
|
|
1057
|
+
options: Array.isArray(b.options) ? b.options.flatMap(parseBookingOption) : [],
|
|
1058
|
+
...isBookingMode(b.mode) ? { mode: b.mode } : {}
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
980
1063
|
function parseTrigger(value) {
|
|
981
1064
|
if (!value || typeof value !== "object") return null;
|
|
982
1065
|
const t = value;
|
|
@@ -1036,7 +1119,8 @@ function parseConversionConfig(raw) {
|
|
|
1036
1119
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
1037
1120
|
services,
|
|
1038
1121
|
goals,
|
|
1039
|
-
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : []
|
|
1122
|
+
linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : [],
|
|
1123
|
+
integrations: parseIntegrations(obj.integrations)
|
|
1040
1124
|
};
|
|
1041
1125
|
}
|
|
1042
1126
|
var CACHE_PREFIX = "_aranova_cfg_";
|
|
@@ -1460,6 +1544,13 @@ var TrackingConfigRuntime = class {
|
|
|
1460
1544
|
linkedHostnames() {
|
|
1461
1545
|
return this.current?.linked_hostnames ?? [];
|
|
1462
1546
|
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Integration blocks, from the cached object even while unconfirmed: the booking fallback
|
|
1549
|
+
* link is safe to show stale. Same reference until the next adopt, for `useSyncExternalStore`.
|
|
1550
|
+
*/
|
|
1551
|
+
integrations() {
|
|
1552
|
+
return this.current?.integrations ?? null;
|
|
1553
|
+
}
|
|
1463
1554
|
async revalidateNow() {
|
|
1464
1555
|
try {
|
|
1465
1556
|
const headers = {};
|
|
@@ -1629,6 +1720,106 @@ function getTrackingConfigRuntime(ref, fetchImpl) {
|
|
|
1629
1720
|
return runtime;
|
|
1630
1721
|
}
|
|
1631
1722
|
|
|
1723
|
+
// ../../contracts/autoleap-booking-links.json
|
|
1724
|
+
var autoleap_booking_links_default = {
|
|
1725
|
+
hosts: ["myalp.io"]
|
|
1726
|
+
};
|
|
1727
|
+
|
|
1728
|
+
// ../tracking-core/src/integrations-public.ts
|
|
1729
|
+
var HANDOFF_HOSTS = new Set(autoleap_booking_links_default.hosts);
|
|
1730
|
+
function getBookingIntegration(integrations) {
|
|
1731
|
+
const booking = integrations?.autoleap?.booking;
|
|
1732
|
+
if (!booking) return null;
|
|
1733
|
+
const rules = booking.rules ? camelRules(booking.rules) : null;
|
|
1734
|
+
return {
|
|
1735
|
+
provider: "autoleap",
|
|
1736
|
+
enabled: booking.enabled,
|
|
1737
|
+
fallbackUrl: booking.fallback_url,
|
|
1738
|
+
acceptsBookings: booking.accepts_bookings && rules !== null && booking.config_version !== null,
|
|
1739
|
+
timezone: booking.timezone,
|
|
1740
|
+
configVersion: booking.config_version,
|
|
1741
|
+
rules,
|
|
1742
|
+
options: booking.options.map((option) => ({ key: option.key, label: option.label })),
|
|
1743
|
+
mode: booking.mode ?? "live"
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
function camelRules(rules) {
|
|
1747
|
+
return {
|
|
1748
|
+
minDaysAhead: rules.min_days_ahead,
|
|
1749
|
+
maxDaysAhead: rules.max_days_ahead,
|
|
1750
|
+
hours: rules.hours,
|
|
1751
|
+
closedDates: rules.closed_dates,
|
|
1752
|
+
specialHours: rules.special_hours,
|
|
1753
|
+
vehicleRequired: rules.vehicle_required,
|
|
1754
|
+
dropOffOptions: rules.drop_off_options
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
var WEEKDAYS = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
|
|
1758
|
+
function shopToday(timeZone, now = /* @__PURE__ */ new Date()) {
|
|
1759
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
1760
|
+
timeZone,
|
|
1761
|
+
year: "numeric",
|
|
1762
|
+
month: "2-digit",
|
|
1763
|
+
day: "2-digit"
|
|
1764
|
+
}).formatToParts(now);
|
|
1765
|
+
const part = (type) => parts.find((p) => p.type === type)?.value ?? "";
|
|
1766
|
+
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
1767
|
+
}
|
|
1768
|
+
function addDays(isoDate, days) {
|
|
1769
|
+
const [year, month, day] = isoDate.split("-").map(Number);
|
|
1770
|
+
const date = new Date(Date.UTC(year, month - 1, day + days));
|
|
1771
|
+
return date.toISOString().slice(0, 10);
|
|
1772
|
+
}
|
|
1773
|
+
function bookableSlots(rules, { timeZone, now = /* @__PURE__ */ new Date() }) {
|
|
1774
|
+
const today = shopToday(timeZone, now);
|
|
1775
|
+
const days = [];
|
|
1776
|
+
const closed = new Set(rules.closedDates);
|
|
1777
|
+
for (let offset = rules.minDaysAhead; offset <= rules.maxDaysAhead; offset += 1) {
|
|
1778
|
+
const date = addDays(today, offset);
|
|
1779
|
+
if (closed.has(date)) continue;
|
|
1780
|
+
const weekday = WEEKDAYS[(/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getUTCDay()];
|
|
1781
|
+
const windows = rules.specialHours[date] ?? rules.hours[weekday];
|
|
1782
|
+
if (!windows || windows.morning.length === 0 && windows.afternoon.length === 0) continue;
|
|
1783
|
+
days.push({
|
|
1784
|
+
date,
|
|
1785
|
+
weekday,
|
|
1786
|
+
morning: [...windows.morning],
|
|
1787
|
+
afternoon: [...windows.afternoon]
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1790
|
+
return days;
|
|
1791
|
+
}
|
|
1792
|
+
function buildBookingHandoffUrl(fallbackUrl, prefill = {}) {
|
|
1793
|
+
let url;
|
|
1794
|
+
try {
|
|
1795
|
+
url = new URL(fallbackUrl);
|
|
1796
|
+
} catch {
|
|
1797
|
+
return null;
|
|
1798
|
+
}
|
|
1799
|
+
if (url.protocol !== "https:" || !HANDOFF_HOSTS.has(url.hostname) || url.username || url.password || url.port) {
|
|
1800
|
+
return null;
|
|
1801
|
+
}
|
|
1802
|
+
const [firstName, lastName] = prefill.firstName?.trim() ? [prefill.firstName, prefill.lastName] : splitFullName(prefill.name);
|
|
1803
|
+
const values = [
|
|
1804
|
+
["firstName", firstName?.trim()],
|
|
1805
|
+
["lastName", lastName?.trim()],
|
|
1806
|
+
["phone", prefill.phone ? nationalDigits(prefill.phone) : ""],
|
|
1807
|
+
["email", prefill.email?.trim()]
|
|
1808
|
+
];
|
|
1809
|
+
for (const [key, value] of values) {
|
|
1810
|
+
if (value) url.searchParams.set(key, value);
|
|
1811
|
+
}
|
|
1812
|
+
return url.toString();
|
|
1813
|
+
}
|
|
1814
|
+
function splitFullName(name) {
|
|
1815
|
+
const [first = "", ...rest] = (name ?? "").trim().split(/\s+/);
|
|
1816
|
+
return [first, rest.join(" ")];
|
|
1817
|
+
}
|
|
1818
|
+
function nationalDigits(phone) {
|
|
1819
|
+
const parsed = parsePhone(phone);
|
|
1820
|
+
return (parsed.isValid ? parsed.national : phone).replace(/\D/g, "");
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1632
1823
|
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
1633
1824
|
function currentPath() {
|
|
1634
1825
|
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
@@ -3448,6 +3639,9 @@ function attachPhoneClickCapture(client, config) {
|
|
|
3448
3639
|
};
|
|
3449
3640
|
}
|
|
3450
3641
|
|
|
3642
|
+
// ../tracking-core/src/resources/sales/bookings.ts
|
|
3643
|
+
var newBookingAttemptKey = uuidV4;
|
|
3644
|
+
|
|
3451
3645
|
// src/hooks.ts
|
|
3452
3646
|
function useGclid() {
|
|
3453
3647
|
const [gclid, setGclid] = (0, import_react.useState)(null);
|
|
@@ -3779,7 +3973,7 @@ function GoogleAdsTracking(props) {
|
|
|
3779
3973
|
var import_react6 = require("react");
|
|
3780
3974
|
|
|
3781
3975
|
// package.json
|
|
3782
|
-
var version = "1.
|
|
3976
|
+
var version = "1.4.0";
|
|
3783
3977
|
|
|
3784
3978
|
// ../tracking-core/src/phone-react.tsx
|
|
3785
3979
|
var import_react5 = require("react");
|
|
@@ -4046,13 +4240,95 @@ function createTracking(options) {
|
|
|
4046
4240
|
)
|
|
4047
4241
|
};
|
|
4048
4242
|
}
|
|
4243
|
+
|
|
4244
|
+
// ../tracking-core/src/booking-react.tsx
|
|
4245
|
+
var import_react7 = require("react");
|
|
4246
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
4247
|
+
function serverSnapshot() {
|
|
4248
|
+
return null;
|
|
4249
|
+
}
|
|
4250
|
+
function useBookingIntegration(trackingConfig) {
|
|
4251
|
+
registerCapability("booking_handoff");
|
|
4252
|
+
const subscribe = (0, import_react7.useCallback)(
|
|
4253
|
+
(listener) => trackingConfig ? getTrackingConfigRuntime(trackingConfig).subscribe(listener) : () => {
|
|
4254
|
+
},
|
|
4255
|
+
[trackingConfig]
|
|
4256
|
+
);
|
|
4257
|
+
const integrations = (0, import_react7.useSyncExternalStore)(
|
|
4258
|
+
subscribe,
|
|
4259
|
+
() => trackingConfig ? getTrackingConfigRuntime(trackingConfig).integrations() : null,
|
|
4260
|
+
serverSnapshot
|
|
4261
|
+
);
|
|
4262
|
+
return (0, import_react7.useMemo)(() => getBookingIntegration(integrations), [integrations]);
|
|
4263
|
+
}
|
|
4264
|
+
function useBookingHandoffUrl(trackingConfig, { fallbackUrl, prefill } = {}) {
|
|
4265
|
+
const booking = useBookingIntegration(trackingConfig);
|
|
4266
|
+
const base = booking?.fallbackUrl ?? fallbackUrl;
|
|
4267
|
+
return base ? buildBookingHandoffUrl(base, prefill) : null;
|
|
4268
|
+
}
|
|
4269
|
+
function BookingHandoffLink({
|
|
4270
|
+
trackingConfig,
|
|
4271
|
+
fallbackUrl,
|
|
4272
|
+
prefill,
|
|
4273
|
+
children,
|
|
4274
|
+
target = "_blank",
|
|
4275
|
+
rel = "noopener noreferrer",
|
|
4276
|
+
...anchorProps
|
|
4277
|
+
}) {
|
|
4278
|
+
const href = useBookingHandoffUrl(trackingConfig, { fallbackUrl, prefill });
|
|
4279
|
+
if (!href) return null;
|
|
4280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { ...anchorProps, href, target, rel, children });
|
|
4281
|
+
}
|
|
4282
|
+
function useBookingSlots(trackingConfig) {
|
|
4283
|
+
const booking = useBookingIntegration(trackingConfig);
|
|
4284
|
+
if (!booking?.acceptsBookings || !booking.rules) return [];
|
|
4285
|
+
return bookableSlots(booking.rules, { timeZone: booking.timezone });
|
|
4286
|
+
}
|
|
4287
|
+
function useBookingSubmit(bookings, options = {}) {
|
|
4288
|
+
registerCapability("booking_integration");
|
|
4289
|
+
const [outcome, setOutcome] = (0, import_react7.useState)(null);
|
|
4290
|
+
const [submitting, setSubmitting] = (0, import_react7.useState)(false);
|
|
4291
|
+
const attemptKey = (0, import_react7.useRef)(null);
|
|
4292
|
+
const inFlight = (0, import_react7.useRef)(null);
|
|
4293
|
+
const { formSubmit, simulate } = options;
|
|
4294
|
+
const submit = (0, import_react7.useCallback)(
|
|
4295
|
+
(input) => {
|
|
4296
|
+
if (inFlight.current) return inFlight.current;
|
|
4297
|
+
attemptKey.current ?? (attemptKey.current = newBookingAttemptKey());
|
|
4298
|
+
setSubmitting(true);
|
|
4299
|
+
const run = bookings.submit(input, { attemptKey: attemptKey.current, formSubmit, simulate }).then((result) => {
|
|
4300
|
+
const unrecorded = result.status === "invalid" || result.status === "stale" || result.status === "failed" && result.id === null;
|
|
4301
|
+
if (!unrecorded) attemptKey.current = null;
|
|
4302
|
+
setOutcome(result);
|
|
4303
|
+
return result;
|
|
4304
|
+
}).finally(() => {
|
|
4305
|
+
inFlight.current = null;
|
|
4306
|
+
setSubmitting(false);
|
|
4307
|
+
});
|
|
4308
|
+
inFlight.current = run;
|
|
4309
|
+
return run;
|
|
4310
|
+
},
|
|
4311
|
+
[bookings, formSubmit, simulate]
|
|
4312
|
+
);
|
|
4313
|
+
const reset = (0, import_react7.useCallback)(() => {
|
|
4314
|
+
attemptKey.current = null;
|
|
4315
|
+
setOutcome(null);
|
|
4316
|
+
}, []);
|
|
4317
|
+
const status = submitting ? "submitting" : outcome?.status ?? "idle";
|
|
4318
|
+
return { status, outcome, submit, reset };
|
|
4319
|
+
}
|
|
4049
4320
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4050
4321
|
0 && (module.exports = {
|
|
4051
4322
|
AdPlatformTracking,
|
|
4323
|
+
BookingHandoffLink,
|
|
4052
4324
|
ConsentBanner,
|
|
4053
4325
|
GoogleAdsTracking,
|
|
4054
4326
|
PhoneField,
|
|
4055
4327
|
createTracking,
|
|
4328
|
+
useBookingHandoffUrl,
|
|
4329
|
+
useBookingIntegration,
|
|
4330
|
+
useBookingSlots,
|
|
4331
|
+
useBookingSubmit,
|
|
4056
4332
|
useConsent,
|
|
4057
4333
|
useConsentState,
|
|
4058
4334
|
useCookiePreferences,
|