@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.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/ConsentBanner.tsx
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
2
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
3
|
+
|
|
4
|
+
// src/hooks.ts
|
|
5
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
6
|
|
|
4
7
|
// ../tracking-core/src/consent.ts
|
|
5
8
|
var CONSENT_STATE_KEY = "consent_state";
|
|
@@ -28,6 +31,12 @@ function setConsentState(state) {
|
|
|
28
31
|
if (typeof window.gtag === "function")
|
|
29
32
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
30
33
|
}
|
|
34
|
+
function resetConsent() {
|
|
35
|
+
if (typeof window === "undefined")
|
|
36
|
+
return;
|
|
37
|
+
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
38
|
+
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
39
|
+
}
|
|
31
40
|
function restoreStoredConsent() {
|
|
32
41
|
const consentState = getConsentState();
|
|
33
42
|
if (consentState === "granted" || consentState === "denied")
|
|
@@ -1331,6 +1340,16 @@ function createSalesClient(config) {
|
|
|
1331
1340
|
...cursor !== void 0 ? { cursor } : {}
|
|
1332
1341
|
});
|
|
1333
1342
|
},
|
|
1343
|
+
async summary(query) {
|
|
1344
|
+
const { range, include_categories, include_deleted_services, top_n, ...filters } = query;
|
|
1345
|
+
return salesRequest(config, "POST", "/sales/summary", {
|
|
1346
|
+
filters,
|
|
1347
|
+
range,
|
|
1348
|
+
...include_categories !== void 0 ? { include_categories } : {},
|
|
1349
|
+
...include_deleted_services !== void 0 ? { include_deleted_services } : {},
|
|
1350
|
+
...top_n !== void 0 ? { top_n } : {}
|
|
1351
|
+
});
|
|
1352
|
+
},
|
|
1334
1353
|
async get(id) {
|
|
1335
1354
|
return salesRequest(config, "GET", `/sales/${id}`);
|
|
1336
1355
|
},
|
|
@@ -1368,59 +1387,251 @@ function formatMoney(cents, currency, locale) {
|
|
|
1368
1387
|
);
|
|
1369
1388
|
}
|
|
1370
1389
|
|
|
1371
|
-
// src/
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
const [consentState, setBannerConsentState] = useState("pending");
|
|
1375
|
-
const [isReady, setIsReady] = useState(false);
|
|
1390
|
+
// src/hooks.ts
|
|
1391
|
+
function useGclid() {
|
|
1392
|
+
const [gclid, setGclid] = useState(null);
|
|
1376
1393
|
useEffect(() => {
|
|
1377
|
-
|
|
1378
|
-
setIsReady(true);
|
|
1394
|
+
setGclid(getCookieValueFromDocument("gclid"));
|
|
1379
1395
|
}, []);
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1396
|
+
return gclid;
|
|
1397
|
+
}
|
|
1398
|
+
function useTrackingParams() {
|
|
1399
|
+
const [trackingParams, setTrackingParams] = useState(createEmptyTrackingParams());
|
|
1400
|
+
useEffect(() => {
|
|
1401
|
+
setTrackingParams(getTrackingParamsFromCookieReader(getCookieValueFromDocument));
|
|
1402
|
+
}, []);
|
|
1403
|
+
return trackingParams;
|
|
1404
|
+
}
|
|
1405
|
+
function useConsentState() {
|
|
1406
|
+
return useConsent().state;
|
|
1407
|
+
}
|
|
1408
|
+
function useConsent() {
|
|
1409
|
+
const [state, setState] = useState("pending");
|
|
1410
|
+
useEffect(() => {
|
|
1411
|
+
setState(getConsentState());
|
|
1412
|
+
const handleStorage = (event) => {
|
|
1413
|
+
if (event.key === CONSENT_STATE_KEY) setState(getConsentState());
|
|
1414
|
+
};
|
|
1415
|
+
window.addEventListener("storage", handleStorage);
|
|
1416
|
+
return () => window.removeEventListener("storage", handleStorage);
|
|
1417
|
+
}, []);
|
|
1418
|
+
const accept = useCallback(() => {
|
|
1383
1419
|
setConsentState("granted");
|
|
1384
|
-
|
|
1420
|
+
setState("granted");
|
|
1421
|
+
}, []);
|
|
1422
|
+
const decline = useCallback(() => {
|
|
1423
|
+
setConsentState("denied");
|
|
1424
|
+
setState("denied");
|
|
1425
|
+
}, []);
|
|
1426
|
+
const reset = useCallback(() => {
|
|
1427
|
+
resetConsent();
|
|
1428
|
+
setState("pending");
|
|
1429
|
+
}, []);
|
|
1430
|
+
return {
|
|
1431
|
+
state,
|
|
1432
|
+
isPending: state === "pending",
|
|
1433
|
+
isGranted: state === "granted",
|
|
1434
|
+
isDenied: state === "denied",
|
|
1435
|
+
accept,
|
|
1436
|
+
decline,
|
|
1437
|
+
reset
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
// src/ConsentBanner.tsx
|
|
1442
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
1443
|
+
var LIGHT_THEME = {
|
|
1444
|
+
background: "#ffffff",
|
|
1445
|
+
border: "#e5e7eb",
|
|
1446
|
+
text: "#111827",
|
|
1447
|
+
mutedText: "#4b5563",
|
|
1448
|
+
acceptBg: "#111827",
|
|
1449
|
+
acceptText: "#ffffff",
|
|
1450
|
+
declineBg: "transparent",
|
|
1451
|
+
declineText: "#111827",
|
|
1452
|
+
declineBorder: "#d1d5db",
|
|
1453
|
+
shadow: "0 -4px 16px -2px rgba(15, 23, 42, 0.08), 0 -2px 6px -1px rgba(15, 23, 42, 0.04)",
|
|
1454
|
+
linkColor: "#1f2937"
|
|
1455
|
+
};
|
|
1456
|
+
var DARK_THEME = {
|
|
1457
|
+
background: "#0f172a",
|
|
1458
|
+
border: "#1e293b",
|
|
1459
|
+
text: "#f1f5f9",
|
|
1460
|
+
mutedText: "#cbd5e1",
|
|
1461
|
+
acceptBg: "#f1f5f9",
|
|
1462
|
+
acceptText: "#0f172a",
|
|
1463
|
+
declineBg: "transparent",
|
|
1464
|
+
declineText: "#f1f5f9",
|
|
1465
|
+
declineBorder: "#334155",
|
|
1466
|
+
shadow: "0 -4px 16px -2px rgba(0, 0, 0, 0.5), 0 -2px 6px -1px rgba(0, 0, 0, 0.3)",
|
|
1467
|
+
linkColor: "#e2e8f0"
|
|
1468
|
+
};
|
|
1469
|
+
function useResolvedTheme(theme) {
|
|
1470
|
+
const [prefersDark, setPrefersDark] = useState2(false);
|
|
1471
|
+
useEffect2(() => {
|
|
1472
|
+
if (theme !== "auto" || typeof window === "undefined" || !window.matchMedia) return;
|
|
1473
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1474
|
+
setPrefersDark(mql.matches);
|
|
1475
|
+
const onChange = (e) => setPrefersDark(e.matches);
|
|
1476
|
+
mql.addEventListener("change", onChange);
|
|
1477
|
+
return () => mql.removeEventListener("change", onChange);
|
|
1478
|
+
}, [theme]);
|
|
1479
|
+
if (theme === "dark") return DARK_THEME;
|
|
1480
|
+
if (theme === "auto" && prefersDark) return DARK_THEME;
|
|
1481
|
+
return LIGHT_THEME;
|
|
1482
|
+
}
|
|
1483
|
+
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.";
|
|
1484
|
+
function ConsentBanner({
|
|
1485
|
+
message,
|
|
1486
|
+
title,
|
|
1487
|
+
acceptLabel = "Accept",
|
|
1488
|
+
declineLabel = "Decline",
|
|
1489
|
+
policyHref,
|
|
1490
|
+
policyLabel = "Learn more",
|
|
1491
|
+
onAccept,
|
|
1492
|
+
onDecline,
|
|
1493
|
+
position = "bottom",
|
|
1494
|
+
theme = "light",
|
|
1495
|
+
className,
|
|
1496
|
+
style
|
|
1497
|
+
} = {}) {
|
|
1498
|
+
const { isPending, accept, decline } = useConsent();
|
|
1499
|
+
const tokens = useResolvedTheme(theme);
|
|
1500
|
+
const [hasMounted, setHasMounted] = useState2(false);
|
|
1501
|
+
useEffect2(() => {
|
|
1502
|
+
setHasMounted(true);
|
|
1503
|
+
}, []);
|
|
1504
|
+
if (!hasMounted || !isPending) return null;
|
|
1505
|
+
const wrapperStyle = {
|
|
1506
|
+
position: "fixed",
|
|
1507
|
+
left: 0,
|
|
1508
|
+
right: 0,
|
|
1509
|
+
[position]: 0,
|
|
1510
|
+
zIndex: 2147483640,
|
|
1511
|
+
background: tokens.background,
|
|
1512
|
+
color: tokens.text,
|
|
1513
|
+
borderTop: position === "bottom" ? `1px solid ${tokens.border}` : "none",
|
|
1514
|
+
borderBottom: position === "top" ? `1px solid ${tokens.border}` : "none",
|
|
1515
|
+
boxShadow: tokens.shadow,
|
|
1516
|
+
padding: "16px 20px",
|
|
1517
|
+
boxSizing: "border-box",
|
|
1518
|
+
animation: `${ANIMATION_NAME}-${position} 200ms ease-out`,
|
|
1519
|
+
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
1520
|
+
...style
|
|
1521
|
+
};
|
|
1522
|
+
const innerStyle = {
|
|
1523
|
+
maxWidth: 1100,
|
|
1524
|
+
margin: "0 auto",
|
|
1525
|
+
display: "flex",
|
|
1526
|
+
flexWrap: "wrap",
|
|
1527
|
+
gap: 16,
|
|
1528
|
+
alignItems: "center",
|
|
1529
|
+
justifyContent: "space-between"
|
|
1530
|
+
};
|
|
1531
|
+
const messageStyle = {
|
|
1532
|
+
flex: "1 1 320px",
|
|
1533
|
+
margin: 0,
|
|
1534
|
+
fontSize: 14,
|
|
1535
|
+
lineHeight: 1.5,
|
|
1536
|
+
color: tokens.mutedText
|
|
1537
|
+
};
|
|
1538
|
+
const titleStyle = {
|
|
1539
|
+
margin: "0 0 4px 0",
|
|
1540
|
+
fontSize: 14,
|
|
1541
|
+
fontWeight: 600,
|
|
1542
|
+
color: tokens.text
|
|
1543
|
+
};
|
|
1544
|
+
const actionsStyle = {
|
|
1545
|
+
display: "flex",
|
|
1546
|
+
gap: 8,
|
|
1547
|
+
flexShrink: 0
|
|
1548
|
+
};
|
|
1549
|
+
const buttonBase = {
|
|
1550
|
+
appearance: "none",
|
|
1551
|
+
fontFamily: "inherit",
|
|
1552
|
+
fontSize: 14,
|
|
1553
|
+
fontWeight: 500,
|
|
1554
|
+
padding: "8px 16px",
|
|
1555
|
+
borderRadius: 6,
|
|
1556
|
+
cursor: "pointer",
|
|
1557
|
+
border: "1px solid transparent",
|
|
1558
|
+
transition: "opacity 120ms ease"
|
|
1559
|
+
};
|
|
1560
|
+
const declineStyle = {
|
|
1561
|
+
...buttonBase,
|
|
1562
|
+
background: tokens.declineBg,
|
|
1563
|
+
color: tokens.declineText,
|
|
1564
|
+
borderColor: tokens.declineBorder
|
|
1565
|
+
};
|
|
1566
|
+
const acceptStyle = {
|
|
1567
|
+
...buttonBase,
|
|
1568
|
+
background: tokens.acceptBg,
|
|
1569
|
+
color: tokens.acceptText
|
|
1570
|
+
};
|
|
1571
|
+
const linkStyle = {
|
|
1572
|
+
color: tokens.linkColor,
|
|
1573
|
+
textDecoration: "underline",
|
|
1574
|
+
textUnderlineOffset: 2
|
|
1575
|
+
};
|
|
1576
|
+
const handleAccept = () => {
|
|
1577
|
+
accept();
|
|
1578
|
+
onAccept?.();
|
|
1385
1579
|
};
|
|
1386
1580
|
const handleDecline = () => {
|
|
1387
|
-
|
|
1388
|
-
|
|
1581
|
+
decline();
|
|
1582
|
+
onDecline?.();
|
|
1389
1583
|
};
|
|
1390
|
-
return /* @__PURE__ */
|
|
1391
|
-
/* @__PURE__ */ jsx("
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1584
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1585
|
+
/* @__PURE__ */ jsx("style", { children: ANIMATION_KEYFRAMES }),
|
|
1586
|
+
/* @__PURE__ */ jsx(
|
|
1587
|
+
"div",
|
|
1588
|
+
{
|
|
1589
|
+
role: "dialog",
|
|
1590
|
+
"aria-live": "polite",
|
|
1591
|
+
"aria-label": "Cookie consent",
|
|
1592
|
+
className,
|
|
1593
|
+
style: wrapperStyle,
|
|
1594
|
+
children: /* @__PURE__ */ jsxs("div", { style: innerStyle, children: [
|
|
1595
|
+
/* @__PURE__ */ jsxs("div", { style: { flex: "1 1 320px" }, children: [
|
|
1596
|
+
title ? /* @__PURE__ */ jsx("p", { style: titleStyle, children: title }) : null,
|
|
1597
|
+
/* @__PURE__ */ jsxs("p", { style: messageStyle, children: [
|
|
1598
|
+
message ?? DEFAULT_MESSAGE,
|
|
1599
|
+
policyHref ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1600
|
+
" ",
|
|
1601
|
+
/* @__PURE__ */ jsx("a", { href: policyHref, style: linkStyle, children: policyLabel })
|
|
1602
|
+
] }) : null
|
|
1603
|
+
] })
|
|
1604
|
+
] }),
|
|
1605
|
+
/* @__PURE__ */ jsxs("div", { style: actionsStyle, children: [
|
|
1606
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleDecline, style: declineStyle, children: declineLabel }),
|
|
1607
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleAccept, style: acceptStyle, children: acceptLabel })
|
|
1608
|
+
] })
|
|
1609
|
+
] })
|
|
1610
|
+
}
|
|
1611
|
+
)
|
|
1612
|
+
] });
|
|
1613
|
+
}
|
|
1614
|
+
var ANIMATION_NAME = "aranova-consent-banner";
|
|
1615
|
+
var ANIMATION_KEYFRAMES = `
|
|
1616
|
+
@keyframes ${ANIMATION_NAME}-bottom {
|
|
1617
|
+
from { transform: translateY(100%); opacity: 0; }
|
|
1618
|
+
to { transform: translateY(0); opacity: 1; }
|
|
1619
|
+
}
|
|
1620
|
+
@keyframes ${ANIMATION_NAME}-top {
|
|
1621
|
+
from { transform: translateY(-100%); opacity: 0; }
|
|
1622
|
+
to { transform: translateY(0); opacity: 1; }
|
|
1413
1623
|
}
|
|
1624
|
+
`;
|
|
1414
1625
|
|
|
1415
1626
|
// src/GoogleAdsTracking.tsx
|
|
1416
|
-
import { useEffect as
|
|
1627
|
+
import { useEffect as useEffect3, useMemo } from "react";
|
|
1417
1628
|
function GoogleAdsTracking(props) {
|
|
1418
1629
|
const { gtagId, gtagIds } = props;
|
|
1419
1630
|
const gtagIdsKey = useMemo(
|
|
1420
1631
|
() => gtagIds ? JSON.stringify(gtagIds) : "",
|
|
1421
1632
|
[gtagIds]
|
|
1422
1633
|
);
|
|
1423
|
-
|
|
1634
|
+
useEffect3(() => {
|
|
1424
1635
|
if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
1425
1636
|
bootstrapMultipleGtags(gtagIds);
|
|
1426
1637
|
} else if (gtagId) {
|
|
@@ -1430,38 +1641,6 @@ function GoogleAdsTracking(props) {
|
|
|
1430
1641
|
return null;
|
|
1431
1642
|
}
|
|
1432
1643
|
|
|
1433
|
-
// src/hooks.ts
|
|
1434
|
-
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
1435
|
-
function useGclid() {
|
|
1436
|
-
const [gclid, setGclid] = useState2(null);
|
|
1437
|
-
useEffect3(() => {
|
|
1438
|
-
setGclid(getCookieValueFromDocument("gclid"));
|
|
1439
|
-
}, []);
|
|
1440
|
-
return gclid;
|
|
1441
|
-
}
|
|
1442
|
-
function useTrackingParams() {
|
|
1443
|
-
const [trackingParams, setTrackingParams] = useState2(createEmptyTrackingParams());
|
|
1444
|
-
useEffect3(() => {
|
|
1445
|
-
setTrackingParams(getTrackingParamsFromCookieReader(getCookieValueFromDocument));
|
|
1446
|
-
}, []);
|
|
1447
|
-
return trackingParams;
|
|
1448
|
-
}
|
|
1449
|
-
function useConsentState() {
|
|
1450
|
-
const [consentState, setConsentStateValue] = useState2("pending");
|
|
1451
|
-
useEffect3(() => {
|
|
1452
|
-
setConsentStateValue(getConsentState());
|
|
1453
|
-
const handleStorage = (event) => {
|
|
1454
|
-
if (event.key === "consent_state")
|
|
1455
|
-
setConsentStateValue(getConsentState());
|
|
1456
|
-
};
|
|
1457
|
-
window.addEventListener("storage", handleStorage);
|
|
1458
|
-
return () => {
|
|
1459
|
-
window.removeEventListener("storage", handleStorage);
|
|
1460
|
-
};
|
|
1461
|
-
}, []);
|
|
1462
|
-
return consentState;
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
1644
|
// src/factory.tsx
|
|
1466
1645
|
import {
|
|
1467
1646
|
createContext,
|
|
@@ -1471,7 +1650,7 @@ import {
|
|
|
1471
1650
|
} from "react";
|
|
1472
1651
|
|
|
1473
1652
|
// package.json
|
|
1474
|
-
var version = "0.
|
|
1653
|
+
var version = "0.10.0";
|
|
1475
1654
|
|
|
1476
1655
|
// src/factory.tsx
|
|
1477
1656
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
@@ -1594,8 +1773,10 @@ export {
|
|
|
1594
1773
|
formatMoney,
|
|
1595
1774
|
fromMinor,
|
|
1596
1775
|
getConsentState,
|
|
1776
|
+
resetConsent,
|
|
1597
1777
|
setConsentState,
|
|
1598
1778
|
toMinor,
|
|
1779
|
+
useConsent,
|
|
1599
1780
|
useConsentState,
|
|
1600
1781
|
useGclid,
|
|
1601
1782
|
useTrackingParams
|