@aranova/tracking-react 0.9.0 → 0.10.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 +65 -4
- package/dist/index.d.mts +178 -7
- package/dist/index.d.ts +178 -7
- package/dist/index.js +254 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +253 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34,8 +34,10 @@ __export(src_exports, {
|
|
|
34
34
|
formatMoney: () => formatMoney,
|
|
35
35
|
fromMinor: () => fromMinor,
|
|
36
36
|
getConsentState: () => getConsentState,
|
|
37
|
+
resetConsent: () => resetConsent,
|
|
37
38
|
setConsentState: () => setConsentState,
|
|
38
39
|
toMinor: () => toMinor,
|
|
40
|
+
useConsent: () => useConsent,
|
|
39
41
|
useConsentState: () => useConsentState,
|
|
40
42
|
useGclid: () => useGclid,
|
|
41
43
|
useTrackingParams: () => useTrackingParams
|
|
@@ -43,6 +45,9 @@ __export(src_exports, {
|
|
|
43
45
|
module.exports = __toCommonJS(src_exports);
|
|
44
46
|
|
|
45
47
|
// src/ConsentBanner.tsx
|
|
48
|
+
var import_react2 = require("react");
|
|
49
|
+
|
|
50
|
+
// src/hooks.ts
|
|
46
51
|
var import_react = require("react");
|
|
47
52
|
|
|
48
53
|
// ../tracking-core/src/consent.ts
|
|
@@ -72,6 +77,12 @@ function setConsentState(state) {
|
|
|
72
77
|
if (typeof window.gtag === "function")
|
|
73
78
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
74
79
|
}
|
|
80
|
+
function resetConsent() {
|
|
81
|
+
if (typeof window === "undefined")
|
|
82
|
+
return;
|
|
83
|
+
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
84
|
+
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
85
|
+
}
|
|
75
86
|
function restoreStoredConsent() {
|
|
76
87
|
const consentState = getConsentState();
|
|
77
88
|
if (consentState === "granted" || consentState === "denied")
|
|
@@ -1375,6 +1386,16 @@ function createSalesClient(config) {
|
|
|
1375
1386
|
...cursor !== void 0 ? { cursor } : {}
|
|
1376
1387
|
});
|
|
1377
1388
|
},
|
|
1389
|
+
async summary(query) {
|
|
1390
|
+
const { range, include_categories, include_deleted_services, top_n, ...filters } = query;
|
|
1391
|
+
return salesRequest(config, "POST", "/sales/summary", {
|
|
1392
|
+
filters,
|
|
1393
|
+
range,
|
|
1394
|
+
...include_categories !== void 0 ? { include_categories } : {},
|
|
1395
|
+
...include_deleted_services !== void 0 ? { include_deleted_services } : {},
|
|
1396
|
+
...top_n !== void 0 ? { top_n } : {}
|
|
1397
|
+
});
|
|
1398
|
+
},
|
|
1378
1399
|
async get(id) {
|
|
1379
1400
|
return salesRequest(config, "GET", `/sales/${id}`);
|
|
1380
1401
|
},
|
|
@@ -1412,59 +1433,251 @@ function formatMoney(cents, currency, locale) {
|
|
|
1412
1433
|
);
|
|
1413
1434
|
}
|
|
1414
1435
|
|
|
1436
|
+
// src/hooks.ts
|
|
1437
|
+
function useGclid() {
|
|
1438
|
+
const [gclid, setGclid] = (0, import_react.useState)(null);
|
|
1439
|
+
(0, import_react.useEffect)(() => {
|
|
1440
|
+
setGclid(getCookieValueFromDocument("gclid"));
|
|
1441
|
+
}, []);
|
|
1442
|
+
return gclid;
|
|
1443
|
+
}
|
|
1444
|
+
function useTrackingParams() {
|
|
1445
|
+
const [trackingParams, setTrackingParams] = (0, import_react.useState)(createEmptyTrackingParams());
|
|
1446
|
+
(0, import_react.useEffect)(() => {
|
|
1447
|
+
setTrackingParams(getTrackingParamsFromCookieReader(getCookieValueFromDocument));
|
|
1448
|
+
}, []);
|
|
1449
|
+
return trackingParams;
|
|
1450
|
+
}
|
|
1451
|
+
function useConsentState() {
|
|
1452
|
+
return useConsent().state;
|
|
1453
|
+
}
|
|
1454
|
+
function useConsent() {
|
|
1455
|
+
const [state, setState] = (0, import_react.useState)("pending");
|
|
1456
|
+
(0, import_react.useEffect)(() => {
|
|
1457
|
+
setState(getConsentState());
|
|
1458
|
+
const handleStorage = (event) => {
|
|
1459
|
+
if (event.key === CONSENT_STATE_KEY) setState(getConsentState());
|
|
1460
|
+
};
|
|
1461
|
+
window.addEventListener("storage", handleStorage);
|
|
1462
|
+
return () => window.removeEventListener("storage", handleStorage);
|
|
1463
|
+
}, []);
|
|
1464
|
+
const accept = (0, import_react.useCallback)(() => {
|
|
1465
|
+
setConsentState("granted");
|
|
1466
|
+
setState("granted");
|
|
1467
|
+
}, []);
|
|
1468
|
+
const decline = (0, import_react.useCallback)(() => {
|
|
1469
|
+
setConsentState("denied");
|
|
1470
|
+
setState("denied");
|
|
1471
|
+
}, []);
|
|
1472
|
+
const reset = (0, import_react.useCallback)(() => {
|
|
1473
|
+
resetConsent();
|
|
1474
|
+
setState("pending");
|
|
1475
|
+
}, []);
|
|
1476
|
+
return {
|
|
1477
|
+
state,
|
|
1478
|
+
isPending: state === "pending",
|
|
1479
|
+
isGranted: state === "granted",
|
|
1480
|
+
isDenied: state === "denied",
|
|
1481
|
+
accept,
|
|
1482
|
+
decline,
|
|
1483
|
+
reset
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1415
1487
|
// src/ConsentBanner.tsx
|
|
1416
1488
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1489
|
+
var LIGHT_THEME = {
|
|
1490
|
+
background: "#ffffff",
|
|
1491
|
+
border: "#e5e7eb",
|
|
1492
|
+
text: "#111827",
|
|
1493
|
+
mutedText: "#4b5563",
|
|
1494
|
+
acceptBg: "#111827",
|
|
1495
|
+
acceptText: "#ffffff",
|
|
1496
|
+
declineBg: "transparent",
|
|
1497
|
+
declineText: "#111827",
|
|
1498
|
+
declineBorder: "#d1d5db",
|
|
1499
|
+
shadow: "0 -4px 16px -2px rgba(15, 23, 42, 0.08), 0 -2px 6px -1px rgba(15, 23, 42, 0.04)",
|
|
1500
|
+
linkColor: "#1f2937"
|
|
1501
|
+
};
|
|
1502
|
+
var DARK_THEME = {
|
|
1503
|
+
background: "#0f172a",
|
|
1504
|
+
border: "#1e293b",
|
|
1505
|
+
text: "#f1f5f9",
|
|
1506
|
+
mutedText: "#cbd5e1",
|
|
1507
|
+
acceptBg: "#f1f5f9",
|
|
1508
|
+
acceptText: "#0f172a",
|
|
1509
|
+
declineBg: "transparent",
|
|
1510
|
+
declineText: "#f1f5f9",
|
|
1511
|
+
declineBorder: "#334155",
|
|
1512
|
+
shadow: "0 -4px 16px -2px rgba(0, 0, 0, 0.5), 0 -2px 6px -1px rgba(0, 0, 0, 0.3)",
|
|
1513
|
+
linkColor: "#e2e8f0"
|
|
1514
|
+
};
|
|
1515
|
+
function useResolvedTheme(theme) {
|
|
1516
|
+
const [prefersDark, setPrefersDark] = (0, import_react2.useState)(false);
|
|
1517
|
+
(0, import_react2.useEffect)(() => {
|
|
1518
|
+
if (theme !== "auto" || typeof window === "undefined" || !window.matchMedia) return;
|
|
1519
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1520
|
+
setPrefersDark(mql.matches);
|
|
1521
|
+
const onChange = (e) => setPrefersDark(e.matches);
|
|
1522
|
+
mql.addEventListener("change", onChange);
|
|
1523
|
+
return () => mql.removeEventListener("change", onChange);
|
|
1524
|
+
}, [theme]);
|
|
1525
|
+
if (theme === "dark") return DARK_THEME;
|
|
1526
|
+
if (theme === "auto" && prefersDark) return DARK_THEME;
|
|
1527
|
+
return LIGHT_THEME;
|
|
1528
|
+
}
|
|
1529
|
+
var DEFAULT_MESSAGE = "We use cookies to understand ad performance and improve how our marketing works across visits. You can accept or decline this tracking.";
|
|
1530
|
+
function ConsentBanner({
|
|
1531
|
+
message,
|
|
1532
|
+
title,
|
|
1533
|
+
acceptLabel = "Accept",
|
|
1534
|
+
declineLabel = "Decline",
|
|
1535
|
+
policyHref,
|
|
1536
|
+
policyLabel = "Learn more",
|
|
1537
|
+
onAccept,
|
|
1538
|
+
onDecline,
|
|
1539
|
+
position = "bottom",
|
|
1540
|
+
theme = "light",
|
|
1541
|
+
className,
|
|
1542
|
+
style
|
|
1543
|
+
} = {}) {
|
|
1544
|
+
const { isPending, accept, decline } = useConsent();
|
|
1545
|
+
const tokens = useResolvedTheme(theme);
|
|
1546
|
+
const [hasMounted, setHasMounted] = (0, import_react2.useState)(false);
|
|
1547
|
+
(0, import_react2.useEffect)(() => {
|
|
1548
|
+
setHasMounted(true);
|
|
1423
1549
|
}, []);
|
|
1424
|
-
if (!
|
|
1425
|
-
|
|
1550
|
+
if (!hasMounted || !isPending) return null;
|
|
1551
|
+
const wrapperStyle = {
|
|
1552
|
+
position: "fixed",
|
|
1553
|
+
left: 0,
|
|
1554
|
+
right: 0,
|
|
1555
|
+
[position]: 0,
|
|
1556
|
+
zIndex: 2147483640,
|
|
1557
|
+
background: tokens.background,
|
|
1558
|
+
color: tokens.text,
|
|
1559
|
+
borderTop: position === "bottom" ? `1px solid ${tokens.border}` : "none",
|
|
1560
|
+
borderBottom: position === "top" ? `1px solid ${tokens.border}` : "none",
|
|
1561
|
+
boxShadow: tokens.shadow,
|
|
1562
|
+
padding: "16px 20px",
|
|
1563
|
+
boxSizing: "border-box",
|
|
1564
|
+
animation: `${ANIMATION_NAME}-${position} 200ms ease-out`,
|
|
1565
|
+
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
1566
|
+
...style
|
|
1567
|
+
};
|
|
1568
|
+
const innerStyle = {
|
|
1569
|
+
maxWidth: 1100,
|
|
1570
|
+
margin: "0 auto",
|
|
1571
|
+
display: "flex",
|
|
1572
|
+
flexWrap: "wrap",
|
|
1573
|
+
gap: 16,
|
|
1574
|
+
alignItems: "center",
|
|
1575
|
+
justifyContent: "space-between"
|
|
1576
|
+
};
|
|
1577
|
+
const messageStyle = {
|
|
1578
|
+
flex: "1 1 320px",
|
|
1579
|
+
margin: 0,
|
|
1580
|
+
fontSize: 14,
|
|
1581
|
+
lineHeight: 1.5,
|
|
1582
|
+
color: tokens.mutedText
|
|
1583
|
+
};
|
|
1584
|
+
const titleStyle = {
|
|
1585
|
+
margin: "0 0 4px 0",
|
|
1586
|
+
fontSize: 14,
|
|
1587
|
+
fontWeight: 600,
|
|
1588
|
+
color: tokens.text
|
|
1589
|
+
};
|
|
1590
|
+
const actionsStyle = {
|
|
1591
|
+
display: "flex",
|
|
1592
|
+
gap: 8,
|
|
1593
|
+
flexShrink: 0
|
|
1594
|
+
};
|
|
1595
|
+
const buttonBase = {
|
|
1596
|
+
appearance: "none",
|
|
1597
|
+
fontFamily: "inherit",
|
|
1598
|
+
fontSize: 14,
|
|
1599
|
+
fontWeight: 500,
|
|
1600
|
+
padding: "8px 16px",
|
|
1601
|
+
borderRadius: 6,
|
|
1602
|
+
cursor: "pointer",
|
|
1603
|
+
border: "1px solid transparent",
|
|
1604
|
+
transition: "opacity 120ms ease"
|
|
1605
|
+
};
|
|
1606
|
+
const declineStyle = {
|
|
1607
|
+
...buttonBase,
|
|
1608
|
+
background: tokens.declineBg,
|
|
1609
|
+
color: tokens.declineText,
|
|
1610
|
+
borderColor: tokens.declineBorder
|
|
1611
|
+
};
|
|
1612
|
+
const acceptStyle = {
|
|
1613
|
+
...buttonBase,
|
|
1614
|
+
background: tokens.acceptBg,
|
|
1615
|
+
color: tokens.acceptText
|
|
1616
|
+
};
|
|
1617
|
+
const linkStyle = {
|
|
1618
|
+
color: tokens.linkColor,
|
|
1619
|
+
textDecoration: "underline",
|
|
1620
|
+
textUnderlineOffset: 2
|
|
1621
|
+
};
|
|
1426
1622
|
const handleAccept = () => {
|
|
1427
|
-
|
|
1428
|
-
|
|
1623
|
+
accept();
|
|
1624
|
+
onAccept?.();
|
|
1429
1625
|
};
|
|
1430
1626
|
const handleDecline = () => {
|
|
1431
|
-
|
|
1432
|
-
|
|
1627
|
+
decline();
|
|
1628
|
+
onDecline?.();
|
|
1433
1629
|
};
|
|
1434
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
1435
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
1436
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: ANIMATION_KEYFRAMES }),
|
|
1632
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1633
|
+
"div",
|
|
1634
|
+
{
|
|
1635
|
+
role: "dialog",
|
|
1636
|
+
"aria-live": "polite",
|
|
1637
|
+
"aria-label": "Cookie consent",
|
|
1638
|
+
className,
|
|
1639
|
+
style: wrapperStyle,
|
|
1640
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: innerStyle, children: [
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flex: "1 1 320px" }, children: [
|
|
1642
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: titleStyle, children: title }) : null,
|
|
1643
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: messageStyle, children: [
|
|
1644
|
+
message ?? DEFAULT_MESSAGE,
|
|
1645
|
+
policyHref ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1646
|
+
" ",
|
|
1647
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: policyHref, style: linkStyle, children: policyLabel })
|
|
1648
|
+
] }) : null
|
|
1649
|
+
] })
|
|
1650
|
+
] }),
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: actionsStyle, children: [
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: handleDecline, style: declineStyle, children: declineLabel }),
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: handleAccept, style: acceptStyle, children: acceptLabel })
|
|
1654
|
+
] })
|
|
1655
|
+
] })
|
|
1656
|
+
}
|
|
1657
|
+
)
|
|
1658
|
+
] });
|
|
1659
|
+
}
|
|
1660
|
+
var ANIMATION_NAME = "aranova-consent-banner";
|
|
1661
|
+
var ANIMATION_KEYFRAMES = `
|
|
1662
|
+
@keyframes ${ANIMATION_NAME}-bottom {
|
|
1663
|
+
from { transform: translateY(100%); opacity: 0; }
|
|
1664
|
+
to { transform: translateY(0); opacity: 1; }
|
|
1457
1665
|
}
|
|
1666
|
+
@keyframes ${ANIMATION_NAME}-top {
|
|
1667
|
+
from { transform: translateY(-100%); opacity: 0; }
|
|
1668
|
+
to { transform: translateY(0); opacity: 1; }
|
|
1669
|
+
}
|
|
1670
|
+
`;
|
|
1458
1671
|
|
|
1459
1672
|
// src/GoogleAdsTracking.tsx
|
|
1460
|
-
var
|
|
1673
|
+
var import_react3 = require("react");
|
|
1461
1674
|
function GoogleAdsTracking(props) {
|
|
1462
1675
|
const { gtagId, gtagIds } = props;
|
|
1463
|
-
const gtagIdsKey = (0,
|
|
1676
|
+
const gtagIdsKey = (0, import_react3.useMemo)(
|
|
1464
1677
|
() => gtagIds ? JSON.stringify(gtagIds) : "",
|
|
1465
1678
|
[gtagIds]
|
|
1466
1679
|
);
|
|
1467
|
-
(0,
|
|
1680
|
+
(0, import_react3.useEffect)(() => {
|
|
1468
1681
|
if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
1469
1682
|
bootstrapMultipleGtags(gtagIds);
|
|
1470
1683
|
} else if (gtagId) {
|
|
@@ -1474,43 +1687,11 @@ function GoogleAdsTracking(props) {
|
|
|
1474
1687
|
return null;
|
|
1475
1688
|
}
|
|
1476
1689
|
|
|
1477
|
-
// src/hooks.ts
|
|
1478
|
-
var import_react3 = require("react");
|
|
1479
|
-
function useGclid() {
|
|
1480
|
-
const [gclid, setGclid] = (0, import_react3.useState)(null);
|
|
1481
|
-
(0, import_react3.useEffect)(() => {
|
|
1482
|
-
setGclid(getCookieValueFromDocument("gclid"));
|
|
1483
|
-
}, []);
|
|
1484
|
-
return gclid;
|
|
1485
|
-
}
|
|
1486
|
-
function useTrackingParams() {
|
|
1487
|
-
const [trackingParams, setTrackingParams] = (0, import_react3.useState)(createEmptyTrackingParams());
|
|
1488
|
-
(0, import_react3.useEffect)(() => {
|
|
1489
|
-
setTrackingParams(getTrackingParamsFromCookieReader(getCookieValueFromDocument));
|
|
1490
|
-
}, []);
|
|
1491
|
-
return trackingParams;
|
|
1492
|
-
}
|
|
1493
|
-
function useConsentState() {
|
|
1494
|
-
const [consentState, setConsentStateValue] = (0, import_react3.useState)("pending");
|
|
1495
|
-
(0, import_react3.useEffect)(() => {
|
|
1496
|
-
setConsentStateValue(getConsentState());
|
|
1497
|
-
const handleStorage = (event) => {
|
|
1498
|
-
if (event.key === "consent_state")
|
|
1499
|
-
setConsentStateValue(getConsentState());
|
|
1500
|
-
};
|
|
1501
|
-
window.addEventListener("storage", handleStorage);
|
|
1502
|
-
return () => {
|
|
1503
|
-
window.removeEventListener("storage", handleStorage);
|
|
1504
|
-
};
|
|
1505
|
-
}, []);
|
|
1506
|
-
return consentState;
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
1690
|
// src/factory.tsx
|
|
1510
1691
|
var import_react4 = require("react");
|
|
1511
1692
|
|
|
1512
1693
|
// package.json
|
|
1513
|
-
var version = "0.
|
|
1694
|
+
var version = "0.10.0";
|
|
1514
1695
|
|
|
1515
1696
|
// src/factory.tsx
|
|
1516
1697
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -1634,8 +1815,10 @@ function createTracking(options) {
|
|
|
1634
1815
|
formatMoney,
|
|
1635
1816
|
fromMinor,
|
|
1636
1817
|
getConsentState,
|
|
1818
|
+
resetConsent,
|
|
1637
1819
|
setConsentState,
|
|
1638
1820
|
toMinor,
|
|
1821
|
+
useConsent,
|
|
1639
1822
|
useConsentState,
|
|
1640
1823
|
useGclid,
|
|
1641
1824
|
useTrackingParams
|