@liiift-studio/sanity-visitor-insights 0.61.0 → 0.63.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/dist/index.js +46 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/studio/VisitorInsightsTool.tsx +13 -8
- package/src/studio/panels.test.tsx +86 -0
- package/src/studio/panels.tsx +74 -37
package/dist/index.js
CHANGED
|
@@ -2289,16 +2289,21 @@ function Verdict({ data, previous }) {
|
|
|
2289
2289
|
parts.push(Math.abs(change) < 5e-3 ? `${label} flat` : `${label} little changed (${change > 0 ? "+" : "\u2212"}${formatPercent(Math.abs(change), 0)})`);
|
|
2290
2290
|
} else if (unit === "money") {
|
|
2291
2291
|
parts.push(`${label} ${change > 0 ? "up" : "down"} to ${formatMoney(a, data.currency ?? null)} from ${formatMoney(b, data.currency ?? null)}`);
|
|
2292
|
+
} else if (Math.abs(b) < MIN_DELTA_BASE) {
|
|
2293
|
+
parts.push(`${label} ${formatCount(a)}, was ${formatCount(b)}`);
|
|
2292
2294
|
} else parts.push(`${label} ${change > 0 ? "up" : "down"} ${formatPercent(Math.abs(change), 0)}`);
|
|
2293
2295
|
};
|
|
2294
2296
|
say("Revenue", data.revenue, previous?.revenue, "money");
|
|
2297
|
+
say("Orders", data.orders, previous?.orders, "count");
|
|
2295
2298
|
say("Traffic", data.vercelPageviews, previous?.vercelPageviews, "count");
|
|
2296
2299
|
const sends = data.campaigns?.length ?? 0;
|
|
2297
2300
|
const shortfall = data.shortfallRatio;
|
|
2298
2301
|
const seeing = shortfall !== null && shortfall !== void 0 ? `GA4 is seeing ${formatPercent(1 - shortfall, 0)} of your traffic` : null;
|
|
2299
2302
|
const broken = shortfall === null || shortfall === void 0 ? data.capture?.discrepancy ? "measurement disagrees between sources" : null : shortfall > 0.6 ? `${seeing} \u2014 treat its figures as broken` : shortfall > 0.35 ? `${seeing} \u2014 its figures are undercounts, not what happened` : data.capture?.discrepancy ? "measurement disagrees between sources" : null;
|
|
2300
2303
|
if (broken) parts.push(broken);
|
|
2301
|
-
if (parts.length === 0)
|
|
2304
|
+
if (parts.length === 0) {
|
|
2305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Card, { padding: 3, radius: 2, tone: "transparent", border: true, style: { borderLeftWidth: 3, borderLeftStyle: "solid" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 4, children: "No figures arrived for this window." }) });
|
|
2306
|
+
}
|
|
2302
2307
|
const noticeable = shortfall !== null && shortfall !== void 0 && shortfall > 0.2;
|
|
2303
2308
|
const closing = broken || !noticeable ? "" : ` \xB7 ${seeing}`;
|
|
2304
2309
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -2320,6 +2325,10 @@ function DataHealthPanel({ data, diagnostics }) {
|
|
|
2320
2325
|
const pageviewMax = maxOf([data.ga4Pageviews, data.vercelPageviews]);
|
|
2321
2326
|
const contained = isContainment(data.vercelPageviews, data.ga4Pageviews);
|
|
2322
2327
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 4, children: [
|
|
2328
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Card, { padding: 3, radius: 2, tone: "transparent", border: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 2, children: [
|
|
2329
|
+
data.shortfallRatio !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, weight: "semibold", children: data.shortfallRatio >= 0 ? `GA4 saw ${formatPercent(data.shortfallRatio, 1)} fewer pageviews than Vercel` : `GA4 saw ${formatPercent(-data.shortfallRatio, 1)} more pageviews than Vercel` }),
|
|
2330
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, muted: true, children: data.interpretation })
|
|
2331
|
+
] }) }),
|
|
2323
2332
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 3, children: [
|
|
2324
2333
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionTitle, { title: "Pageviews, source against source" }),
|
|
2325
2334
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, muted: true, children: "Both counting pageviews. Google Analytics is blockable, so seeing fewer is normal." }),
|
|
@@ -2337,10 +2346,21 @@ function DataHealthPanel({ data, diagnostics }) {
|
|
|
2337
2346
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ComparisonBar, { label: "GA4 pageviews", metric: data.ga4Pageviews, max: pageviewMax })
|
|
2338
2347
|
] })
|
|
2339
2348
|
] }),
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2349
|
+
diagnostics && /* Open, and primary. This is the longest block on the tab and the obvious candidate
|
|
2350
|
+
for folding away — but the tab it sits on exists to answer "what should I fix
|
|
2351
|
+
before trusting any of this", and these checks ARE that answer. Folding it would
|
|
2352
|
+
have left Data health opening on a summary of the problem with the solution behind
|
|
2353
|
+
a click. It stays collapsible so a reader who has read it can get it out of the
|
|
2354
|
+
way. */
|
|
2355
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2356
|
+
Section,
|
|
2357
|
+
{
|
|
2358
|
+
title: "Configuration",
|
|
2359
|
+
subtitle: "What this site has wired up, and what it is missing.",
|
|
2360
|
+
collapsible: true,
|
|
2361
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DiagnosticsPanel, { data: diagnostics })
|
|
2362
|
+
}
|
|
2363
|
+
),
|
|
2344
2364
|
((data.capture?.estimates?.length ?? 0) > 0 || data.estimatedSessions?.status === "estimated") && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 3, children: [
|
|
2345
2365
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionTitle, { title: "How much GA4 is seeing" }),
|
|
2346
2366
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: cardGrid, children: (data.capture?.estimates ?? []).map((estimate) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Card, { padding: 3, radius: 2, tone: "transparent", border: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 3, children: [
|
|
@@ -2395,21 +2415,6 @@ function DataHealthPanel({ data, diagnostics }) {
|
|
|
2395
2415
|
] }) })
|
|
2396
2416
|
] })
|
|
2397
2417
|
}
|
|
2398
|
-
),
|
|
2399
|
-
diagnostics && /* Open, and primary. This is the longest block on the tab and the obvious candidate
|
|
2400
|
-
for folding away — but the tab it sits on exists to answer "what should I fix
|
|
2401
|
-
before trusting any of this", and these checks ARE that answer. Folding it would
|
|
2402
|
-
have left Data health opening on a summary of the problem with the solution behind
|
|
2403
|
-
a click. It stays collapsible so a reader who has read it can get it out of the
|
|
2404
|
-
way. */
|
|
2405
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2406
|
-
Section,
|
|
2407
|
-
{
|
|
2408
|
-
title: "Configuration",
|
|
2409
|
-
subtitle: "What this site has wired up, and what it is missing.",
|
|
2410
|
-
collapsible: true,
|
|
2411
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DiagnosticsPanel, { data: diagnostics })
|
|
2412
|
-
}
|
|
2413
2418
|
)
|
|
2414
2419
|
] });
|
|
2415
2420
|
}
|
|
@@ -3085,11 +3090,11 @@ var RANGES = [
|
|
|
3085
3090
|
];
|
|
3086
3091
|
var GA4_ONLY_TABS = ["acquisition", "journey", "typeface-interest"];
|
|
3087
3092
|
var PANELS = [
|
|
3088
|
-
{ id: "overview", report: "measurement-health", label: "Overview"
|
|
3089
|
-
{ id: "acquisition", report: "acquisition", label: "Acquisition"
|
|
3090
|
-
{ id: "journey", report: "journey", label: "Journey"
|
|
3091
|
-
{ id: "typeface-interest", report: "typeface-interest", label: "Typeface interest"
|
|
3092
|
-
{ id: "data-health", report: "measurement-health", label: "Data health"
|
|
3093
|
+
{ id: "overview", report: "measurement-health", label: "Overview" },
|
|
3094
|
+
{ id: "acquisition", report: "acquisition", label: "Acquisition" },
|
|
3095
|
+
{ id: "journey", report: "journey", label: "Journey" },
|
|
3096
|
+
{ id: "typeface-interest", report: "typeface-interest", label: "Typeface interest" },
|
|
3097
|
+
{ id: "data-health", report: "measurement-health", label: "Data health" }
|
|
3093
3098
|
];
|
|
3094
3099
|
function RangeSelector({
|
|
3095
3100
|
value,
|
|
@@ -3495,7 +3500,7 @@ function VisitorInsightsTool(props) {
|
|
|
3495
3500
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_sanity_ui_compat4.Heading, { size: 2, children: "Visitor insights" }),
|
|
3496
3501
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_sanity_ui_compat4.Stack, { space: 2, children: [
|
|
3497
3502
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RangeSelector, { value: range, custom, onChange: setRange, onCustomChange: setCustom }),
|
|
3498
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BasisSelector, { value: compare, onChange: setCompare })
|
|
3503
|
+
COMPARED_TABS.includes(activePanel) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BasisSelector, { value: compare, onChange: setCompare })
|
|
3499
3504
|
] })
|
|
3500
3505
|
] }),
|
|
3501
3506
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PanelTabs, { value: activePanel, onChange: setActivePanel }),
|
|
@@ -3555,25 +3560,22 @@ function VisitorInsightsTool(props) {
|
|
|
3555
3560
|
"aria-labelledby": `tab-${activePanel}`,
|
|
3556
3561
|
tabIndex: 0,
|
|
3557
3562
|
style: { position: "relative" },
|
|
3558
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime4.
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
setCustom({ start, end });
|
|
3572
|
-
setRange("custom");
|
|
3573
|
-
}
|
|
3563
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_sanity_ui_compat4.Stack, { space: 4, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PanelBoundary, { resetKey: `${activePanel}|${range}|${custom.start}|${custom.end}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3564
|
+
ReportPanel,
|
|
3565
|
+
{
|
|
3566
|
+
tabId: active?.id ?? "overview",
|
|
3567
|
+
report: active?.report ?? "measurement-health",
|
|
3568
|
+
apiBaseUrl,
|
|
3569
|
+
range,
|
|
3570
|
+
custom,
|
|
3571
|
+
compare,
|
|
3572
|
+
onBrush: (start, end) => {
|
|
3573
|
+
if (range !== "custom") setRangeBeforeBrush(range);
|
|
3574
|
+
setCustom({ start, end });
|
|
3575
|
+
setRange("custom");
|
|
3574
3576
|
}
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
+
}
|
|
3578
|
+
) }) })
|
|
3577
3579
|
}
|
|
3578
3580
|
)
|
|
3579
3581
|
] }) })
|