@aranova/tracking-next 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 +64 -3
- package/dist/index.d.mts +178 -6
- package/dist/index.d.ts +178 -6
- package/dist/index.js +241 -58
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +241 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -25,6 +25,12 @@ function setConsentState(state) {
|
|
|
25
25
|
if (typeof window.gtag === "function")
|
|
26
26
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
27
27
|
}
|
|
28
|
+
function resetConsent() {
|
|
29
|
+
if (typeof window === "undefined")
|
|
30
|
+
return;
|
|
31
|
+
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
32
|
+
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
33
|
+
}
|
|
28
34
|
|
|
29
35
|
// ../tracking-core/src/payloads.ts
|
|
30
36
|
function createTrackingClientContext(surface, input = {}) {
|
|
@@ -1128,6 +1134,16 @@ function createSalesClient(config) {
|
|
|
1128
1134
|
...cursor !== void 0 ? { cursor } : {}
|
|
1129
1135
|
});
|
|
1130
1136
|
},
|
|
1137
|
+
async summary(query) {
|
|
1138
|
+
const { range, include_categories, include_deleted_services, top_n, ...filters } = query;
|
|
1139
|
+
return salesRequest(config, "POST", "/sales/summary", {
|
|
1140
|
+
filters,
|
|
1141
|
+
range,
|
|
1142
|
+
...include_categories !== void 0 ? { include_categories } : {},
|
|
1143
|
+
...include_deleted_services !== void 0 ? { include_deleted_services } : {},
|
|
1144
|
+
...top_n !== void 0 ? { top_n } : {}
|
|
1145
|
+
});
|
|
1146
|
+
},
|
|
1131
1147
|
async get(id) {
|
|
1132
1148
|
return salesRequest(config, "GET", `/sales/${id}`);
|
|
1133
1149
|
},
|
|
@@ -1166,92 +1182,255 @@ function formatMoney(cents, currency, locale) {
|
|
|
1166
1182
|
}
|
|
1167
1183
|
|
|
1168
1184
|
// src/ConsentBanner.tsx
|
|
1169
|
-
import { useEffect, useState } from "react";
|
|
1170
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1171
|
-
function ConsentBanner() {
|
|
1172
|
-
const [consentState, setBannerConsentState] = useState("pending");
|
|
1173
|
-
const [isReady, setIsReady] = useState(false);
|
|
1174
|
-
useEffect(() => {
|
|
1175
|
-
setBannerConsentState(getConsentState());
|
|
1176
|
-
setIsReady(true);
|
|
1177
|
-
}, []);
|
|
1178
|
-
if (!isReady || consentState !== "pending")
|
|
1179
|
-
return null;
|
|
1180
|
-
const handleAccept = () => {
|
|
1181
|
-
setConsentState("granted");
|
|
1182
|
-
setBannerConsentState("granted");
|
|
1183
|
-
};
|
|
1184
|
-
const handleDecline = () => {
|
|
1185
|
-
setConsentState("denied");
|
|
1186
|
-
setBannerConsentState("denied");
|
|
1187
|
-
};
|
|
1188
|
-
return /* @__PURE__ */ jsx("div", { className: "fixed bottom-0 left-0 right-0 z-50 border-t border-gray-200 bg-white p-4 shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto flex max-w-5xl flex-col gap-4 md:flex-row md:items-center md:justify-between", children: [
|
|
1189
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-700", children: "We use cookies to understand ad performance and improve how our marketing works across visits. You can accept or decline this tracking." }),
|
|
1190
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [
|
|
1191
|
-
/* @__PURE__ */ jsx(
|
|
1192
|
-
"button",
|
|
1193
|
-
{
|
|
1194
|
-
type: "button",
|
|
1195
|
-
onClick: handleDecline,
|
|
1196
|
-
className: "rounded-md border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition hover:bg-gray-100",
|
|
1197
|
-
children: "Decline"
|
|
1198
|
-
}
|
|
1199
|
-
),
|
|
1200
|
-
/* @__PURE__ */ jsx(
|
|
1201
|
-
"button",
|
|
1202
|
-
{
|
|
1203
|
-
type: "button",
|
|
1204
|
-
onClick: handleAccept,
|
|
1205
|
-
className: "rounded-md bg-gray-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-gray-800",
|
|
1206
|
-
children: "Accept"
|
|
1207
|
-
}
|
|
1208
|
-
)
|
|
1209
|
-
] })
|
|
1210
|
-
] }) });
|
|
1211
|
-
}
|
|
1185
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1212
1186
|
|
|
1213
1187
|
// src/hooks.ts
|
|
1214
|
-
import { useEffect
|
|
1188
|
+
import { useCallback, useEffect, useState } from "react";
|
|
1215
1189
|
function useGclid() {
|
|
1216
|
-
const [gclid, setGclid] =
|
|
1217
|
-
|
|
1190
|
+
const [gclid, setGclid] = useState(null);
|
|
1191
|
+
useEffect(() => {
|
|
1218
1192
|
setGclid(getCookieValueFromDocument("gclid"));
|
|
1219
1193
|
}, []);
|
|
1220
1194
|
return gclid;
|
|
1221
1195
|
}
|
|
1222
1196
|
function useTrackingParams() {
|
|
1223
|
-
const [trackingParams, setTrackingParams] =
|
|
1224
|
-
|
|
1197
|
+
const [trackingParams, setTrackingParams] = useState(createEmptyTrackingParams());
|
|
1198
|
+
useEffect(() => {
|
|
1225
1199
|
setTrackingParams(getTrackingParamsFromCookieReader(getCookieValueFromDocument));
|
|
1226
1200
|
}, []);
|
|
1227
1201
|
return trackingParams;
|
|
1228
1202
|
}
|
|
1229
1203
|
function useConsentState() {
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1204
|
+
return useConsent().state;
|
|
1205
|
+
}
|
|
1206
|
+
function useConsent() {
|
|
1207
|
+
const [state, setState] = useState("pending");
|
|
1208
|
+
useEffect(() => {
|
|
1209
|
+
setState(getConsentState());
|
|
1233
1210
|
const handleStorage = (event) => {
|
|
1234
|
-
if (event.key ===
|
|
1235
|
-
setConsentStateValue(getConsentState());
|
|
1211
|
+
if (event.key === CONSENT_STATE_KEY) setState(getConsentState());
|
|
1236
1212
|
};
|
|
1237
1213
|
window.addEventListener("storage", handleStorage);
|
|
1238
|
-
return () =>
|
|
1239
|
-
|
|
1240
|
-
|
|
1214
|
+
return () => window.removeEventListener("storage", handleStorage);
|
|
1215
|
+
}, []);
|
|
1216
|
+
const accept = useCallback(() => {
|
|
1217
|
+
setConsentState("granted");
|
|
1218
|
+
setState("granted");
|
|
1241
1219
|
}, []);
|
|
1242
|
-
|
|
1220
|
+
const decline = useCallback(() => {
|
|
1221
|
+
setConsentState("denied");
|
|
1222
|
+
setState("denied");
|
|
1223
|
+
}, []);
|
|
1224
|
+
const reset = useCallback(() => {
|
|
1225
|
+
resetConsent();
|
|
1226
|
+
setState("pending");
|
|
1227
|
+
}, []);
|
|
1228
|
+
return {
|
|
1229
|
+
state,
|
|
1230
|
+
isPending: state === "pending",
|
|
1231
|
+
isGranted: state === "granted",
|
|
1232
|
+
isDenied: state === "denied",
|
|
1233
|
+
accept,
|
|
1234
|
+
decline,
|
|
1235
|
+
reset
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// src/ConsentBanner.tsx
|
|
1240
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
1241
|
+
var LIGHT_THEME = {
|
|
1242
|
+
background: "#ffffff",
|
|
1243
|
+
border: "#e5e7eb",
|
|
1244
|
+
text: "#111827",
|
|
1245
|
+
mutedText: "#4b5563",
|
|
1246
|
+
acceptBg: "#111827",
|
|
1247
|
+
acceptText: "#ffffff",
|
|
1248
|
+
declineBg: "transparent",
|
|
1249
|
+
declineText: "#111827",
|
|
1250
|
+
declineBorder: "#d1d5db",
|
|
1251
|
+
shadow: "0 -4px 16px -2px rgba(15, 23, 42, 0.08), 0 -2px 6px -1px rgba(15, 23, 42, 0.04)",
|
|
1252
|
+
linkColor: "#1f2937"
|
|
1253
|
+
};
|
|
1254
|
+
var DARK_THEME = {
|
|
1255
|
+
background: "#0f172a",
|
|
1256
|
+
border: "#1e293b",
|
|
1257
|
+
text: "#f1f5f9",
|
|
1258
|
+
mutedText: "#cbd5e1",
|
|
1259
|
+
acceptBg: "#f1f5f9",
|
|
1260
|
+
acceptText: "#0f172a",
|
|
1261
|
+
declineBg: "transparent",
|
|
1262
|
+
declineText: "#f1f5f9",
|
|
1263
|
+
declineBorder: "#334155",
|
|
1264
|
+
shadow: "0 -4px 16px -2px rgba(0, 0, 0, 0.5), 0 -2px 6px -1px rgba(0, 0, 0, 0.3)",
|
|
1265
|
+
linkColor: "#e2e8f0"
|
|
1266
|
+
};
|
|
1267
|
+
function useResolvedTheme(theme) {
|
|
1268
|
+
const [prefersDark, setPrefersDark] = useState2(false);
|
|
1269
|
+
useEffect2(() => {
|
|
1270
|
+
if (theme !== "auto" || typeof window === "undefined" || !window.matchMedia) return;
|
|
1271
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1272
|
+
setPrefersDark(mql.matches);
|
|
1273
|
+
const onChange = (e) => setPrefersDark(e.matches);
|
|
1274
|
+
mql.addEventListener("change", onChange);
|
|
1275
|
+
return () => mql.removeEventListener("change", onChange);
|
|
1276
|
+
}, [theme]);
|
|
1277
|
+
if (theme === "dark") return DARK_THEME;
|
|
1278
|
+
if (theme === "auto" && prefersDark) return DARK_THEME;
|
|
1279
|
+
return LIGHT_THEME;
|
|
1280
|
+
}
|
|
1281
|
+
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.";
|
|
1282
|
+
function ConsentBanner({
|
|
1283
|
+
message,
|
|
1284
|
+
title,
|
|
1285
|
+
acceptLabel = "Accept",
|
|
1286
|
+
declineLabel = "Decline",
|
|
1287
|
+
policyHref,
|
|
1288
|
+
policyLabel = "Learn more",
|
|
1289
|
+
onAccept,
|
|
1290
|
+
onDecline,
|
|
1291
|
+
position = "bottom",
|
|
1292
|
+
theme = "light",
|
|
1293
|
+
className,
|
|
1294
|
+
style
|
|
1295
|
+
} = {}) {
|
|
1296
|
+
const { isPending, accept, decline } = useConsent();
|
|
1297
|
+
const tokens = useResolvedTheme(theme);
|
|
1298
|
+
const [hasMounted, setHasMounted] = useState2(false);
|
|
1299
|
+
useEffect2(() => {
|
|
1300
|
+
setHasMounted(true);
|
|
1301
|
+
}, []);
|
|
1302
|
+
if (!hasMounted || !isPending) return null;
|
|
1303
|
+
const wrapperStyle = {
|
|
1304
|
+
position: "fixed",
|
|
1305
|
+
left: 0,
|
|
1306
|
+
right: 0,
|
|
1307
|
+
[position]: 0,
|
|
1308
|
+
zIndex: 2147483640,
|
|
1309
|
+
background: tokens.background,
|
|
1310
|
+
color: tokens.text,
|
|
1311
|
+
borderTop: position === "bottom" ? `1px solid ${tokens.border}` : "none",
|
|
1312
|
+
borderBottom: position === "top" ? `1px solid ${tokens.border}` : "none",
|
|
1313
|
+
boxShadow: tokens.shadow,
|
|
1314
|
+
padding: "16px 20px",
|
|
1315
|
+
boxSizing: "border-box",
|
|
1316
|
+
animation: `${ANIMATION_NAME}-${position} 200ms ease-out`,
|
|
1317
|
+
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
1318
|
+
...style
|
|
1319
|
+
};
|
|
1320
|
+
const innerStyle = {
|
|
1321
|
+
maxWidth: 1100,
|
|
1322
|
+
margin: "0 auto",
|
|
1323
|
+
display: "flex",
|
|
1324
|
+
flexWrap: "wrap",
|
|
1325
|
+
gap: 16,
|
|
1326
|
+
alignItems: "center",
|
|
1327
|
+
justifyContent: "space-between"
|
|
1328
|
+
};
|
|
1329
|
+
const messageStyle = {
|
|
1330
|
+
flex: "1 1 320px",
|
|
1331
|
+
margin: 0,
|
|
1332
|
+
fontSize: 14,
|
|
1333
|
+
lineHeight: 1.5,
|
|
1334
|
+
color: tokens.mutedText
|
|
1335
|
+
};
|
|
1336
|
+
const titleStyle = {
|
|
1337
|
+
margin: "0 0 4px 0",
|
|
1338
|
+
fontSize: 14,
|
|
1339
|
+
fontWeight: 600,
|
|
1340
|
+
color: tokens.text
|
|
1341
|
+
};
|
|
1342
|
+
const actionsStyle = {
|
|
1343
|
+
display: "flex",
|
|
1344
|
+
gap: 8,
|
|
1345
|
+
flexShrink: 0
|
|
1346
|
+
};
|
|
1347
|
+
const buttonBase = {
|
|
1348
|
+
appearance: "none",
|
|
1349
|
+
fontFamily: "inherit",
|
|
1350
|
+
fontSize: 14,
|
|
1351
|
+
fontWeight: 500,
|
|
1352
|
+
padding: "8px 16px",
|
|
1353
|
+
borderRadius: 6,
|
|
1354
|
+
cursor: "pointer",
|
|
1355
|
+
border: "1px solid transparent",
|
|
1356
|
+
transition: "opacity 120ms ease"
|
|
1357
|
+
};
|
|
1358
|
+
const declineStyle = {
|
|
1359
|
+
...buttonBase,
|
|
1360
|
+
background: tokens.declineBg,
|
|
1361
|
+
color: tokens.declineText,
|
|
1362
|
+
borderColor: tokens.declineBorder
|
|
1363
|
+
};
|
|
1364
|
+
const acceptStyle = {
|
|
1365
|
+
...buttonBase,
|
|
1366
|
+
background: tokens.acceptBg,
|
|
1367
|
+
color: tokens.acceptText
|
|
1368
|
+
};
|
|
1369
|
+
const linkStyle = {
|
|
1370
|
+
color: tokens.linkColor,
|
|
1371
|
+
textDecoration: "underline",
|
|
1372
|
+
textUnderlineOffset: 2
|
|
1373
|
+
};
|
|
1374
|
+
const handleAccept = () => {
|
|
1375
|
+
accept();
|
|
1376
|
+
onAccept?.();
|
|
1377
|
+
};
|
|
1378
|
+
const handleDecline = () => {
|
|
1379
|
+
decline();
|
|
1380
|
+
onDecline?.();
|
|
1381
|
+
};
|
|
1382
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1383
|
+
/* @__PURE__ */ jsx("style", { children: ANIMATION_KEYFRAMES }),
|
|
1384
|
+
/* @__PURE__ */ jsx(
|
|
1385
|
+
"div",
|
|
1386
|
+
{
|
|
1387
|
+
role: "dialog",
|
|
1388
|
+
"aria-live": "polite",
|
|
1389
|
+
"aria-label": "Cookie consent",
|
|
1390
|
+
className,
|
|
1391
|
+
style: wrapperStyle,
|
|
1392
|
+
children: /* @__PURE__ */ jsxs("div", { style: innerStyle, children: [
|
|
1393
|
+
/* @__PURE__ */ jsxs("div", { style: { flex: "1 1 320px" }, children: [
|
|
1394
|
+
title ? /* @__PURE__ */ jsx("p", { style: titleStyle, children: title }) : null,
|
|
1395
|
+
/* @__PURE__ */ jsxs("p", { style: messageStyle, children: [
|
|
1396
|
+
message ?? DEFAULT_MESSAGE,
|
|
1397
|
+
policyHref ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1398
|
+
" ",
|
|
1399
|
+
/* @__PURE__ */ jsx("a", { href: policyHref, style: linkStyle, children: policyLabel })
|
|
1400
|
+
] }) : null
|
|
1401
|
+
] })
|
|
1402
|
+
] }),
|
|
1403
|
+
/* @__PURE__ */ jsxs("div", { style: actionsStyle, children: [
|
|
1404
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleDecline, style: declineStyle, children: declineLabel }),
|
|
1405
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleAccept, style: acceptStyle, children: acceptLabel })
|
|
1406
|
+
] })
|
|
1407
|
+
] })
|
|
1408
|
+
}
|
|
1409
|
+
)
|
|
1410
|
+
] });
|
|
1411
|
+
}
|
|
1412
|
+
var ANIMATION_NAME = "aranova-consent-banner";
|
|
1413
|
+
var ANIMATION_KEYFRAMES = `
|
|
1414
|
+
@keyframes ${ANIMATION_NAME}-bottom {
|
|
1415
|
+
from { transform: translateY(100%); opacity: 0; }
|
|
1416
|
+
to { transform: translateY(0); opacity: 1; }
|
|
1417
|
+
}
|
|
1418
|
+
@keyframes ${ANIMATION_NAME}-top {
|
|
1419
|
+
from { transform: translateY(-100%); opacity: 0; }
|
|
1420
|
+
to { transform: translateY(0); opacity: 1; }
|
|
1243
1421
|
}
|
|
1422
|
+
`;
|
|
1244
1423
|
|
|
1245
1424
|
// src/GoogleAdsTracking.tsx
|
|
1246
1425
|
import Script from "next/script";
|
|
1247
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1426
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1248
1427
|
function GoogleAdsTracking(props) {
|
|
1249
1428
|
const { gtagId, gtagIds } = props;
|
|
1250
1429
|
const allIds = gtagIds ? Object.values(gtagIds) : gtagId ? [gtagId] : [];
|
|
1251
1430
|
if (allIds.length === 0) return null;
|
|
1252
1431
|
const loaderId = allIds[0];
|
|
1253
1432
|
const initScript = allIds.length === 1 ? createGtagInitScript(allIds[0]) : createGtagInitScriptMulti(allIds);
|
|
1254
|
-
return /* @__PURE__ */ jsxs2(
|
|
1433
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1255
1434
|
/* @__PURE__ */ jsx2(Script, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
|
|
1256
1435
|
/* @__PURE__ */ jsx2(
|
|
1257
1436
|
Script,
|
|
@@ -1269,7 +1448,7 @@ function GoogleAdsTracking(props) {
|
|
|
1269
1448
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
1270
1449
|
|
|
1271
1450
|
// package.json
|
|
1272
|
-
var version = "0.
|
|
1451
|
+
var version = "0.10.0";
|
|
1273
1452
|
|
|
1274
1453
|
// src/factory.tsx
|
|
1275
1454
|
import {
|
|
@@ -1494,8 +1673,10 @@ export {
|
|
|
1494
1673
|
formatMoney,
|
|
1495
1674
|
fromMinor,
|
|
1496
1675
|
getConsentState,
|
|
1676
|
+
resetConsent,
|
|
1497
1677
|
setConsentState,
|
|
1498
1678
|
toMinor,
|
|
1679
|
+
useConsent,
|
|
1499
1680
|
useConsentState,
|
|
1500
1681
|
useGclid,
|
|
1501
1682
|
useTrackingParams
|