@carlonicora/nextjs-jsonapi 6.19.0 → 6.20.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/{BlockNoteEditor-5HSL74IX.mjs → BlockNoteEditor-7JRJ3XWV.mjs} +5 -5
- package/dist/{BlockNoteEditor-6RZXGMSD.js → BlockNoteEditor-MH2D5L4A.js} +20 -20
- package/dist/{BlockNoteEditor-6RZXGMSD.js.map → BlockNoteEditor-MH2D5L4A.js.map} +1 -1
- package/dist/{BlockNoteViewer-XYKFY77F.js → BlockNoteViewer-72J3CBAH.js} +4 -4
- package/dist/{BlockNoteViewer-XYKFY77F.js.map → BlockNoteViewer-72J3CBAH.js.map} +1 -1
- package/dist/{BlockNoteViewer-X4UEVI2A.mjs → BlockNoteViewer-UKYEU3E3.mjs} +3 -3
- package/dist/{analytics.modules-Bsacu6ik.d.ts → analytics.modules-C4OT7fVa.d.ts} +1 -0
- package/dist/{analytics.modules-txdCLNG-.d.mts → analytics.modules-DEnXnRGt.d.mts} +1 -0
- package/dist/billing/index.js +492 -492
- package/dist/billing/index.mjs +4 -4
- package/dist/{chunk-OKBJEIOP.mjs → chunk-2U57XVNF.mjs} +1 -1
- package/dist/chunk-2U57XVNF.mjs.map +1 -0
- package/dist/{chunk-KMPBSOFB.mjs → chunk-ASORDSWQ.mjs} +50 -2
- package/dist/chunk-ASORDSWQ.mjs.map +1 -0
- package/dist/{chunk-B4ZH2FOC.js → chunk-IN2F6HI2.js} +906 -906
- package/dist/{chunk-B4ZH2FOC.js.map → chunk-IN2F6HI2.js.map} +1 -1
- package/dist/{chunk-DFA566KY.js → chunk-JAOBCIE7.js} +4 -4
- package/dist/{chunk-DFA566KY.js.map → chunk-JAOBCIE7.js.map} +1 -1
- package/dist/{chunk-YVKWACDP.mjs → chunk-LSZZIQJ5.mjs} +2 -2
- package/dist/{chunk-I5BQLY7V.js → chunk-MVAIYPIN.js} +9 -9
- package/dist/{chunk-I5BQLY7V.js.map → chunk-MVAIYPIN.js.map} +1 -1
- package/dist/{chunk-HEDHJAKT.mjs → chunk-NKXNOGMH.mjs} +6 -6
- package/dist/{chunk-OO2DBP6L.js → chunk-SGLFQ55U.js} +942 -894
- package/dist/chunk-SGLFQ55U.js.map +1 -0
- package/dist/{chunk-TY5YWBLL.mjs → chunk-SJ3K3ATF.mjs} +3 -3
- package/dist/{chunk-A7Y5YW7Q.js → chunk-V7CHD7QT.js} +1 -1
- package/dist/{chunk-A7Y5YW7Q.js.map → chunk-V7CHD7QT.js.map} +1 -1
- package/dist/client/index.js +5 -5
- package/dist/client/index.mjs +4 -4
- package/dist/components/index.js +5 -5
- package/dist/components/index.mjs +4 -4
- package/dist/contexts/index.js +5 -5
- package/dist/contexts/index.mjs +4 -4
- package/dist/core/index.d.mts +2 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.js +3 -3
- package/dist/core/index.mjs +2 -2
- package/dist/email-automations/index.js +118 -118
- package/dist/email-automations/index.mjs +4 -4
- package/dist/features/analytics/index.d.mts +60 -3
- package/dist/features/analytics/index.d.ts +60 -3
- package/dist/features/analytics/index.js +320 -128
- package/dist/features/analytics/index.js.map +1 -1
- package/dist/features/analytics/index.mjs +314 -122
- package/dist/features/analytics/index.mjs.map +1 -1
- package/dist/features/analytics/server.js +5 -5
- package/dist/features/analytics/server.mjs +3 -3
- package/dist/features/blog/index.js +151 -151
- package/dist/features/blog/index.mjs +4 -4
- package/dist/features/blog/server.js +17 -17
- package/dist/features/blog/server.mjs +2 -2
- package/dist/features/help/index.js +38 -38
- package/dist/features/help/index.mjs +4 -4
- package/dist/features/tokenusage/index.js +127 -127
- package/dist/features/tokenusage/index.mjs +4 -4
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/index.mjs +3 -3
- package/dist/offline/index.js +14 -14
- package/dist/offline/index.mjs +1 -1
- package/dist/server/index.js +4 -4
- package/dist/server/index.mjs +3 -3
- package/messages/en.json +8 -0
- package/messages/it.json +8 -0
- package/package.json +1 -1
- package/src/core/registry/ModuleRegistry.ts +1 -0
- package/src/features/analytics/analytics.modules.ts +6 -0
- package/src/features/analytics/components/AnalyticsAdminContainer.tsx +20 -0
- package/src/features/analytics/components/AnalyticsDailyUniquesChart.tsx +224 -0
- package/src/features/analytics/components/__tests__/AnalyticsDailyUniquesChart.spec.tsx +88 -0
- package/src/features/analytics/components/__tests__/AnalyticsPageContainers.spec.tsx +22 -0
- package/src/features/analytics/contexts/AnalyticsAdminContext.tsx +15 -2
- package/src/features/analytics/contexts/__tests__/AnalyticsAdminContext.spec.tsx +38 -0
- package/src/features/analytics/data/AnalyticsAdminService.ts +20 -0
- package/src/features/analytics/data/__tests__/AnalyticsAdminService.spec.ts +15 -0
- package/src/features/analytics/data/__tests__/models.spec.ts +29 -0
- package/src/features/analytics/data/analytics-daily-unique-timeline.interface.ts +11 -0
- package/src/features/analytics/data/analytics-daily-unique-timeline.ts +53 -0
- package/src/features/analytics/data/analytics.types.ts +10 -0
- package/src/features/analytics/data/index.ts +2 -0
- package/src/features/analytics/i18n-keys.ts +8 -0
- package/src/features/analytics/index.ts +1 -0
- package/dist/chunk-KMPBSOFB.mjs.map +0 -1
- package/dist/chunk-OKBJEIOP.mjs.map +0 -1
- package/dist/chunk-OO2DBP6L.js.map +0 -1
- /package/dist/{BlockNoteEditor-5HSL74IX.mjs.map → BlockNoteEditor-7JRJ3XWV.mjs.map} +0 -0
- /package/dist/{BlockNoteViewer-X4UEVI2A.mjs.map → BlockNoteViewer-UKYEU3E3.mjs.map} +0 -0
- /package/dist/{chunk-YVKWACDP.mjs.map → chunk-LSZZIQJ5.mjs.map} +0 -0
- /package/dist/{chunk-HEDHJAKT.mjs.map → chunk-NKXNOGMH.mjs.map} +0 -0
- /package/dist/{chunk-TY5YWBLL.mjs.map → chunk-SJ3K3ATF.mjs.map} +0 -0
|
@@ -31,26 +31,28 @@ import {
|
|
|
31
31
|
seriesColor,
|
|
32
32
|
usePageUrlGenerator,
|
|
33
33
|
useUsageFormatters
|
|
34
|
-
} from "../../chunk-
|
|
34
|
+
} from "../../chunk-NKXNOGMH.mjs";
|
|
35
35
|
import "../../chunk-VOXD3ZLY.mjs";
|
|
36
|
-
import "../../chunk-
|
|
36
|
+
import "../../chunk-SJ3K3ATF.mjs";
|
|
37
37
|
import "../../chunk-PW42LRSL.mjs";
|
|
38
38
|
import {
|
|
39
39
|
AbstractService,
|
|
40
40
|
AnalyticsBreakdown,
|
|
41
|
+
AnalyticsDailyUniqueTimeline,
|
|
41
42
|
AnalyticsEvent,
|
|
42
43
|
AnalyticsPageView,
|
|
43
44
|
AnalyticsSession,
|
|
44
45
|
AnalyticsSummary,
|
|
45
46
|
AnalyticsTimeline,
|
|
46
47
|
analyticsModules,
|
|
47
|
-
cn
|
|
48
|
-
|
|
48
|
+
cn,
|
|
49
|
+
formatLocalDate
|
|
50
|
+
} from "../../chunk-ASORDSWQ.mjs";
|
|
49
51
|
import "../../chunk-OY65RYD3.mjs";
|
|
50
52
|
import {
|
|
51
53
|
EndpointCreator,
|
|
52
54
|
Modules
|
|
53
|
-
} from "../../chunk-
|
|
55
|
+
} from "../../chunk-2U57XVNF.mjs";
|
|
54
56
|
import "../../chunk-AUD6ZLBB.mjs";
|
|
55
57
|
import "../../chunk-M3N7LPHX.mjs";
|
|
56
58
|
import "../../chunk-4ZJIUTIV.mjs";
|
|
@@ -321,6 +323,20 @@ var AnalyticsAdminService = class extends AbstractService {
|
|
|
321
323
|
endpoint: endpoint.generate()
|
|
322
324
|
});
|
|
323
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* One row per calendar day from fromDate to toDate (YYYY-MM-DD, local dates).
|
|
328
|
+
* Always daily and never filtered by section, so it skips withFilters.
|
|
329
|
+
*/
|
|
330
|
+
static async getDailyUniques(params) {
|
|
331
|
+
const endpoint = new EndpointCreator({ endpoint: Modules.AnalyticsDailyUniqueTimeline });
|
|
332
|
+
endpoint.addAdditionalParam("fromDate", params.fromDate);
|
|
333
|
+
endpoint.addAdditionalParam("toDate", params.toDate);
|
|
334
|
+
return this.callApi({
|
|
335
|
+
type: Modules.AnalyticsDailyUniqueTimeline,
|
|
336
|
+
method: "GET" /* GET */,
|
|
337
|
+
endpoint: endpoint.generate()
|
|
338
|
+
});
|
|
339
|
+
}
|
|
324
340
|
static async getBreakdown(params) {
|
|
325
341
|
const endpoint = withFilters(new EndpointCreator({ endpoint: Modules.AnalyticsBreakdown }), params);
|
|
326
342
|
endpoint.addAdditionalParam("dimension", params.dimension);
|
|
@@ -404,6 +420,7 @@ var AnalyticsAdminProvider = /* @__PURE__ */ __name(({
|
|
|
404
420
|
const [timeline, setTimeline] = useState([]);
|
|
405
421
|
const [breakdowns, setBreakdowns] = useState(EMPTY_BREAKDOWNS);
|
|
406
422
|
const [sessions, setSessions] = useState([]);
|
|
423
|
+
const [dailyUniques, setDailyUniques] = useState([]);
|
|
407
424
|
const [sessionsNextPage, setSessionsNextPage] = useState(void 0);
|
|
408
425
|
const [isLoading, setIsLoading] = useState(true);
|
|
409
426
|
const [error, setError] = useState(null);
|
|
@@ -422,8 +439,14 @@ var AnalyticsAdminProvider = /* @__PURE__ */ __name(({
|
|
|
422
439
|
(dimension) => AnalyticsAdminService.getBreakdown({ ...base, dimension, limit: BREAKDOWN_LIMIT })
|
|
423
440
|
)
|
|
424
441
|
),
|
|
425
|
-
AnalyticsAdminService.getSessions({ ...base, next: sessionsNext })
|
|
426
|
-
|
|
442
|
+
AnalyticsAdminService.getSessions({ ...base, next: sessionsNext }),
|
|
443
|
+
// The local calendar days the admin picked: the picker emits local-midnight
|
|
444
|
+
// instants, so slicing the UTC instant would shift the range a day east of UTC.
|
|
445
|
+
AnalyticsAdminService.getDailyUniques({
|
|
446
|
+
fromDate: formatLocalDate(new Date(from)),
|
|
447
|
+
toDate: formatLocalDate(new Date(to))
|
|
448
|
+
})
|
|
449
|
+
]).then(([nextSummary, nextTimeline, nextBreakdowns, nextSessions, nextDailyUniques]) => {
|
|
427
450
|
if (cancelled) return;
|
|
428
451
|
setSummary(nextSummary ?? []);
|
|
429
452
|
setTimeline(nextTimeline ?? []);
|
|
@@ -434,6 +457,7 @@ var AnalyticsAdminProvider = /* @__PURE__ */ __name(({
|
|
|
434
457
|
);
|
|
435
458
|
setSessions(nextSessions ?? []);
|
|
436
459
|
setSessionsNextPage(sessionsNext.next);
|
|
460
|
+
setDailyUniques(nextDailyUniques ?? []);
|
|
437
461
|
}).catch((err) => {
|
|
438
462
|
if (cancelled) return;
|
|
439
463
|
console.error("Failed to load analytics:", err);
|
|
@@ -487,6 +511,7 @@ var AnalyticsAdminProvider = /* @__PURE__ */ __name(({
|
|
|
487
511
|
timeline,
|
|
488
512
|
breakdowns,
|
|
489
513
|
sessions,
|
|
514
|
+
dailyUniques,
|
|
490
515
|
filters,
|
|
491
516
|
setFilters,
|
|
492
517
|
loadMoreSessions,
|
|
@@ -500,6 +525,7 @@ var AnalyticsAdminProvider = /* @__PURE__ */ __name(({
|
|
|
500
525
|
timeline,
|
|
501
526
|
breakdowns,
|
|
502
527
|
sessions,
|
|
528
|
+
dailyUniques,
|
|
503
529
|
filters,
|
|
504
530
|
setFilters,
|
|
505
531
|
loadMoreSessions,
|
|
@@ -520,7 +546,7 @@ var useAnalyticsAdmin = /* @__PURE__ */ __name(() => {
|
|
|
520
546
|
}, "useAnalyticsAdmin");
|
|
521
547
|
|
|
522
548
|
// src/features/analytics/components/AnalyticsAdminContainer.tsx
|
|
523
|
-
import { useTranslations as
|
|
549
|
+
import { useTranslations as useTranslations8 } from "next-intl";
|
|
524
550
|
|
|
525
551
|
// src/features/analytics/components/AnalyticsAdminTiles.tsx
|
|
526
552
|
import { ArrowDownIcon, ArrowUpIcon } from "lucide-react";
|
|
@@ -706,34 +732,182 @@ function BreakdownRows({ rows }) {
|
|
|
706
732
|
}
|
|
707
733
|
__name(BreakdownRows, "BreakdownRows");
|
|
708
734
|
|
|
709
|
-
// src/features/analytics/components/
|
|
710
|
-
import {
|
|
735
|
+
// src/features/analytics/components/AnalyticsDailyUniquesChart.tsx
|
|
736
|
+
import { useTranslations as useTranslations5 } from "next-intl";
|
|
737
|
+
import { useTheme } from "next-themes";
|
|
711
738
|
import { useMemo as useMemo3 } from "react";
|
|
712
|
-
import {
|
|
739
|
+
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
|
|
740
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
741
|
+
var METRIC_SLOT = { visitors: 0, users: 2 };
|
|
742
|
+
var DOT_RADIUS = 4;
|
|
743
|
+
var bucketKey = /* @__PURE__ */ __name((date) => {
|
|
744
|
+
const y = date.getUTCFullYear();
|
|
745
|
+
const m = `${date.getUTCMonth() + 1}`.padStart(2, "0");
|
|
746
|
+
const d = `${date.getUTCDate()}`.padStart(2, "0");
|
|
747
|
+
return `${y}-${m}-${d}`;
|
|
748
|
+
}, "bucketKey");
|
|
749
|
+
function buildDailyUniquesSeries(rows, metric, todayKey) {
|
|
750
|
+
const entries = rows.map((row) => {
|
|
751
|
+
const day = bucketKey(row.day);
|
|
752
|
+
const value = row[metric] ?? null;
|
|
753
|
+
return { day, value, line: value, todayLine: null, isToday: day === todayKey };
|
|
754
|
+
});
|
|
755
|
+
const last = entries.length - 1;
|
|
756
|
+
if (last >= 1 && entries[last].isToday && entries[last].value !== null && entries[last - 1].value !== null) {
|
|
757
|
+
entries[last - 1].todayLine = entries[last - 1].value;
|
|
758
|
+
entries[last].todayLine = entries[last].value;
|
|
759
|
+
entries[last].line = null;
|
|
760
|
+
}
|
|
761
|
+
return entries;
|
|
762
|
+
}
|
|
763
|
+
__name(buildDailyUniquesSeries, "buildDailyUniquesSeries");
|
|
764
|
+
function AnalyticsDailyUniquesChart({ rows, metric, className }) {
|
|
765
|
+
const t = useTranslations5();
|
|
766
|
+
const { compact, bucketDate, decimal } = useUsageFormatters();
|
|
767
|
+
const { resolvedTheme } = useTheme();
|
|
768
|
+
const mode = resolvedTheme === "dark" ? "dark" : "light";
|
|
769
|
+
const color = seriesColor(METRIC_SLOT[metric], mode);
|
|
770
|
+
const chartData = useMemo3(() => buildDailyUniquesSeries(rows, metric, bucketKey(/* @__PURE__ */ new Date())), [rows, metric]);
|
|
771
|
+
const points = useMemo3(() => chartData.map(({ day, value }) => ({ day, value })), [chartData]);
|
|
772
|
+
const seriesLabel = t(`analytics.admin.daily_uniques.${metric}`);
|
|
773
|
+
const chartConfig = useMemo3(() => ({ line: { label: seriesLabel, color } }), [seriesLabel, color]);
|
|
774
|
+
if (chartData.length === 0) {
|
|
775
|
+
return /* @__PURE__ */ jsx5("p", { className: className ? `text-muted-foreground text-xs ${className}` : "text-muted-foreground text-xs", children: t("analytics.admin.no_data") });
|
|
776
|
+
}
|
|
777
|
+
const renderDot = /* @__PURE__ */ __name(({ cx, cy, index, payload }) => {
|
|
778
|
+
if (cx == null || cy == null || payload?.value == null) return /* @__PURE__ */ jsx5("g", {}, `dot-${index}`);
|
|
779
|
+
return /* @__PURE__ */ jsx5(
|
|
780
|
+
"circle",
|
|
781
|
+
{
|
|
782
|
+
cx,
|
|
783
|
+
cy,
|
|
784
|
+
r: DOT_RADIUS,
|
|
785
|
+
fill: payload.isToday ? "var(--card)" : color,
|
|
786
|
+
stroke: payload.isToday ? color : "var(--card)",
|
|
787
|
+
strokeWidth: 2
|
|
788
|
+
},
|
|
789
|
+
`dot-${index}`
|
|
790
|
+
);
|
|
791
|
+
}, "renderDot");
|
|
792
|
+
const renderTodayDot = /* @__PURE__ */ __name((props) => props.payload?.isToday ? renderDot(props) : /* @__PURE__ */ jsx5("g", {}, `today-dot-${props.index}`), "renderTodayDot");
|
|
793
|
+
return (
|
|
794
|
+
// The chart is a coordinate system, not prose: it stays an LTR island.
|
|
795
|
+
// rtl-ok: deliberate LTR island (chart)
|
|
796
|
+
/* @__PURE__ */ jsxs4("div", { className, dir: "ltr", children: [
|
|
797
|
+
/* @__PURE__ */ jsx5("span", { className: "sr-only", "data-testid": `analytics-daily-${metric}-data`, children: JSON.stringify(points) }),
|
|
798
|
+
/* @__PURE__ */ jsx5(ChartContainer, { config: chartConfig, className: "aspect-auto h-72 w-full", children: /* @__PURE__ */ jsxs4(LineChart, { accessibilityLayer: true, data: chartData, margin: { top: 8, right: 16, bottom: 0, left: 0 }, children: [
|
|
799
|
+
/* @__PURE__ */ jsx5(CartesianGrid, { vertical: false }),
|
|
800
|
+
/* @__PURE__ */ jsx5(
|
|
801
|
+
XAxis,
|
|
802
|
+
{
|
|
803
|
+
dataKey: "day",
|
|
804
|
+
tickLine: false,
|
|
805
|
+
axisLine: false,
|
|
806
|
+
tickMargin: 8,
|
|
807
|
+
minTickGap: 16,
|
|
808
|
+
tickFormatter: (value) => bucketDate(value, "day")
|
|
809
|
+
}
|
|
810
|
+
),
|
|
811
|
+
/* @__PURE__ */ jsx5(
|
|
812
|
+
YAxis,
|
|
813
|
+
{
|
|
814
|
+
domain: [0, "auto"],
|
|
815
|
+
allowDecimals: false,
|
|
816
|
+
tickLine: false,
|
|
817
|
+
axisLine: false,
|
|
818
|
+
tickMargin: 8,
|
|
819
|
+
width: 48,
|
|
820
|
+
tickFormatter: (value) => compact(value)
|
|
821
|
+
}
|
|
822
|
+
),
|
|
823
|
+
/* @__PURE__ */ jsx5(
|
|
824
|
+
ChartTooltip,
|
|
825
|
+
{
|
|
826
|
+
filterNull: false,
|
|
827
|
+
content: /* @__PURE__ */ jsx5(
|
|
828
|
+
ChartTooltipContent,
|
|
829
|
+
{
|
|
830
|
+
labelFormatter: (value, payload) => {
|
|
831
|
+
const entry = payload?.[0]?.payload;
|
|
832
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
833
|
+
bucketDate(String(value), "day"),
|
|
834
|
+
entry?.isToday && /* @__PURE__ */ jsx5("div", { className: "text-muted-foreground text-xs", children: t("analytics.admin.daily_uniques.today") })
|
|
835
|
+
] });
|
|
836
|
+
},
|
|
837
|
+
formatter: (_value, _name, item) => {
|
|
838
|
+
const entry = item.payload;
|
|
839
|
+
return /* @__PURE__ */ jsxs4("div", { className: "flex flex-1 justify-between gap-4 leading-none", children: [
|
|
840
|
+
/* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: seriesLabel }),
|
|
841
|
+
/* @__PURE__ */ jsx5("span", { className: "text-xs tabular-nums text-end", children: entry.value === null ? t("analytics.admin.daily_uniques.no_data") : decimal(entry.value, 0) })
|
|
842
|
+
] });
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
)
|
|
846
|
+
}
|
|
847
|
+
),
|
|
848
|
+
/* @__PURE__ */ jsx5(
|
|
849
|
+
Line,
|
|
850
|
+
{
|
|
851
|
+
dataKey: "line",
|
|
852
|
+
type: "linear",
|
|
853
|
+
stroke: color,
|
|
854
|
+
strokeWidth: 2,
|
|
855
|
+
connectNulls: false,
|
|
856
|
+
dot: renderDot,
|
|
857
|
+
activeDot: { r: DOT_RADIUS, strokeWidth: 2, stroke: "var(--card)" },
|
|
858
|
+
isAnimationActive: false
|
|
859
|
+
}
|
|
860
|
+
),
|
|
861
|
+
/* @__PURE__ */ jsx5(
|
|
862
|
+
Line,
|
|
863
|
+
{
|
|
864
|
+
dataKey: "todayLine",
|
|
865
|
+
type: "linear",
|
|
866
|
+
stroke: color,
|
|
867
|
+
strokeWidth: 2,
|
|
868
|
+
strokeDasharray: "2 5",
|
|
869
|
+
connectNulls: false,
|
|
870
|
+
dot: renderTodayDot,
|
|
871
|
+
activeDot: false,
|
|
872
|
+
tooltipType: "none",
|
|
873
|
+
legendType: "none",
|
|
874
|
+
isAnimationActive: false
|
|
875
|
+
}
|
|
876
|
+
)
|
|
877
|
+
] }) })
|
|
878
|
+
] })
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
__name(AnalyticsDailyUniquesChart, "AnalyticsDailyUniquesChart");
|
|
882
|
+
|
|
883
|
+
// src/features/analytics/components/AnalyticsSessionsTable.tsx
|
|
884
|
+
import { useLocale, useTranslations as useTranslations6 } from "next-intl";
|
|
885
|
+
import { useMemo as useMemo4 } from "react";
|
|
886
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
713
887
|
var VISITOR_SUFFIX_LENGTH = 6;
|
|
714
888
|
function AnalyticsSessionsTable({ rows, sessionPageUrl, onLoadMore, hasMore }) {
|
|
715
|
-
const t =
|
|
889
|
+
const t = useTranslations6();
|
|
716
890
|
const locale = useLocale();
|
|
717
891
|
const generateUrl = usePageUrlGenerator();
|
|
718
892
|
const { decimal } = useUsageFormatters();
|
|
719
|
-
const dateTime =
|
|
893
|
+
const dateTime = useMemo4(() => new Intl.DateTimeFormat(locale, { dateStyle: "short", timeStyle: "short" }), [locale]);
|
|
720
894
|
if (rows.length === 0) {
|
|
721
|
-
return /* @__PURE__ */
|
|
895
|
+
return /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-sm", children: t("analytics.admin.no_data") });
|
|
722
896
|
}
|
|
723
|
-
return /* @__PURE__ */
|
|
724
|
-
/* @__PURE__ */
|
|
725
|
-
/* @__PURE__ */
|
|
726
|
-
/* @__PURE__ */
|
|
727
|
-
/* @__PURE__ */
|
|
728
|
-
/* @__PURE__ */
|
|
729
|
-
/* @__PURE__ */
|
|
730
|
-
/* @__PURE__ */
|
|
731
|
-
/* @__PURE__ */
|
|
897
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-3", children: [
|
|
898
|
+
/* @__PURE__ */ jsx6("div", { className: "overflow-x-auto [&_[data-slot=table-container]]:overflow-x-visible", children: /* @__PURE__ */ jsxs5(Table, { children: [
|
|
899
|
+
/* @__PURE__ */ jsx6(TableHeader, { children: /* @__PURE__ */ jsxs5(TableRow, { children: [
|
|
900
|
+
/* @__PURE__ */ jsx6(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.started") }),
|
|
901
|
+
/* @__PURE__ */ jsx6(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.visitor") }),
|
|
902
|
+
/* @__PURE__ */ jsx6(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.source") }),
|
|
903
|
+
/* @__PURE__ */ jsx6(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.landing") }),
|
|
904
|
+
/* @__PURE__ */ jsx6(TableHead, { className: "text-end text-xs font-medium", children: t("analytics.admin.columns.pages") }),
|
|
905
|
+
/* @__PURE__ */ jsx6(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.device") })
|
|
732
906
|
] }) }),
|
|
733
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ jsx6(TableBody, { children: rows.map((row) => {
|
|
734
908
|
const source = [row.utmSource ?? row.referrerHost, row.utmMedium].filter(Boolean).join(" / ");
|
|
735
|
-
return /* @__PURE__ */
|
|
736
|
-
/* @__PURE__ */
|
|
909
|
+
return /* @__PURE__ */ jsxs5(TableRow, { "data-testid": `analytics-session-row-${row.id}`, children: [
|
|
910
|
+
/* @__PURE__ */ jsx6(TableCell, { className: "text-xs tabular-nums", children: /* @__PURE__ */ jsx6(
|
|
737
911
|
Link,
|
|
738
912
|
{
|
|
739
913
|
href: generateUrl({ page: sessionPageUrl, id: row.id }),
|
|
@@ -741,33 +915,33 @@ function AnalyticsSessionsTable({ rows, sessionPageUrl, onLoadMore, hasMore }) {
|
|
|
741
915
|
children: dateTime.format(row.startedAt)
|
|
742
916
|
}
|
|
743
917
|
) }),
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
746
|
-
/* @__PURE__ */
|
|
747
|
-
] }) : /* @__PURE__ */
|
|
748
|
-
/* @__PURE__ */
|
|
749
|
-
/* @__PURE__ */
|
|
918
|
+
/* @__PURE__ */ jsx6(TableCell, { className: "text-xs", children: row.user ? /* @__PURE__ */ jsxs5("span", { className: "flex flex-col", children: [
|
|
919
|
+
/* @__PURE__ */ jsx6("span", { children: row.user.name }),
|
|
920
|
+
/* @__PURE__ */ jsx6("span", { className: "text-muted-foreground text-xs", children: row.user.email })
|
|
921
|
+
] }) : /* @__PURE__ */ jsxs5("span", { className: "flex items-center gap-2", children: [
|
|
922
|
+
/* @__PURE__ */ jsx6(Badge, { variant: "softGray", children: t("analytics.admin.anonymous") }),
|
|
923
|
+
/* @__PURE__ */ jsx6("span", { className: "text-muted-foreground text-xs tabular-nums", children: row.visitorId.slice(-VISITOR_SUFFIX_LENGTH) })
|
|
750
924
|
] }) }),
|
|
751
|
-
/* @__PURE__ */
|
|
752
|
-
/* @__PURE__ */
|
|
753
|
-
/* @__PURE__ */
|
|
754
|
-
/* @__PURE__ */
|
|
925
|
+
/* @__PURE__ */ jsx6(TableCell, { className: "text-xs", children: source }),
|
|
926
|
+
/* @__PURE__ */ jsx6(TableCell, { className: "text-xs", children: row.landingRoute }),
|
|
927
|
+
/* @__PURE__ */ jsx6(TableCell, { className: "text-end text-xs tabular-nums", children: decimal(row.pageViews, 0) }),
|
|
928
|
+
/* @__PURE__ */ jsx6(TableCell, { className: "text-muted-foreground text-xs", children: row.deviceType })
|
|
755
929
|
] }, row.id);
|
|
756
930
|
}) })
|
|
757
931
|
] }) }),
|
|
758
|
-
hasMore && /* @__PURE__ */
|
|
932
|
+
hasMore && /* @__PURE__ */ jsx6("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", size: "sm", onClick: onLoadMore, children: t("analytics.admin.load_more") }) })
|
|
759
933
|
] });
|
|
760
934
|
}
|
|
761
935
|
__name(AnalyticsSessionsTable, "AnalyticsSessionsTable");
|
|
762
936
|
|
|
763
937
|
// src/features/analytics/components/AnalyticsTimelineChart.tsx
|
|
764
|
-
import { useTranslations as
|
|
765
|
-
import { useTheme } from "next-themes";
|
|
766
|
-
import { useMemo as
|
|
767
|
-
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
|
|
768
|
-
import { jsx as
|
|
938
|
+
import { useTranslations as useTranslations7 } from "next-intl";
|
|
939
|
+
import { useTheme as useTheme2 } from "next-themes";
|
|
940
|
+
import { useMemo as useMemo5 } from "react";
|
|
941
|
+
import { Bar, BarChart, CartesianGrid as CartesianGrid2, XAxis as XAxis2, YAxis as YAxis2 } from "recharts";
|
|
942
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
769
943
|
var SERIES = ["visitors", "pageViews"];
|
|
770
|
-
var
|
|
944
|
+
var bucketKey2 = /* @__PURE__ */ __name((date) => {
|
|
771
945
|
const y = date.getUTCFullYear();
|
|
772
946
|
const m = `${date.getUTCMonth() + 1}`.padStart(2, "0");
|
|
773
947
|
const d = `${date.getUTCDate()}`.padStart(2, "0");
|
|
@@ -786,14 +960,14 @@ var inferGranularity = /* @__PURE__ */ __name((buckets) => {
|
|
|
786
960
|
return "day";
|
|
787
961
|
}, "inferGranularity");
|
|
788
962
|
function AnalyticsTimelineChart({ rows, className }) {
|
|
789
|
-
const t =
|
|
963
|
+
const t = useTranslations7();
|
|
790
964
|
const { compact, bucketDate, decimal } = useUsageFormatters();
|
|
791
|
-
const { resolvedTheme } =
|
|
965
|
+
const { resolvedTheme } = useTheme2();
|
|
792
966
|
const mode = resolvedTheme === "dark" ? "dark" : "light";
|
|
793
|
-
const chartData =
|
|
967
|
+
const chartData = useMemo5(() => {
|
|
794
968
|
const byBucket = /* @__PURE__ */ new Map();
|
|
795
969
|
for (const row of rows) {
|
|
796
|
-
const key =
|
|
970
|
+
const key = bucketKey2(row.bucket);
|
|
797
971
|
let entry = byBucket.get(key);
|
|
798
972
|
if (!entry) {
|
|
799
973
|
entry = { bucket: key, visitors: 0, pageViews: 0 };
|
|
@@ -804,7 +978,7 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
804
978
|
}
|
|
805
979
|
return [...byBucket.values()].sort((a, b) => a.bucket.localeCompare(b.bucket));
|
|
806
980
|
}, [rows]);
|
|
807
|
-
const chartConfig =
|
|
981
|
+
const chartConfig = useMemo5(
|
|
808
982
|
() => ({
|
|
809
983
|
visitors: { label: t("analytics.admin.series.visitors") },
|
|
810
984
|
pageViews: { label: t("analytics.admin.series.page_views") }
|
|
@@ -812,7 +986,7 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
812
986
|
[t]
|
|
813
987
|
);
|
|
814
988
|
if (chartData.length === 0) {
|
|
815
|
-
return /* @__PURE__ */
|
|
989
|
+
return /* @__PURE__ */ jsx7("p", { className: className ? `text-muted-foreground text-sm ${className}` : "text-muted-foreground text-sm", children: t("analytics.admin.no_data") });
|
|
816
990
|
}
|
|
817
991
|
const granularity = inferGranularity(chartData.map((entry) => entry.bucket));
|
|
818
992
|
return (
|
|
@@ -820,12 +994,12 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
820
994
|
// bars out left-to-right, so the whole chart stays an LTR island even under
|
|
821
995
|
// dir="rtl". Only the labels inside it are translated.
|
|
822
996
|
// rtl-ok: deliberate LTR island (chart)
|
|
823
|
-
/* @__PURE__ */
|
|
824
|
-
/* @__PURE__ */
|
|
825
|
-
/* @__PURE__ */
|
|
826
|
-
/* @__PURE__ */
|
|
827
|
-
/* @__PURE__ */
|
|
828
|
-
|
|
997
|
+
/* @__PURE__ */ jsxs6("div", { className, dir: "ltr", children: [
|
|
998
|
+
/* @__PURE__ */ jsx7("span", { className: "sr-only", "data-testid": "analytics-timeline-data", children: JSON.stringify(chartData) }),
|
|
999
|
+
/* @__PURE__ */ jsx7(ChartContainer, { config: chartConfig, className: "aspect-auto h-72 w-full", children: /* @__PURE__ */ jsxs6(BarChart, { accessibilityLayer: true, data: chartData, margin: { top: 8, right: 8, bottom: 0, left: 0 }, children: [
|
|
1000
|
+
/* @__PURE__ */ jsx7(CartesianGrid2, { vertical: false }),
|
|
1001
|
+
/* @__PURE__ */ jsx7(
|
|
1002
|
+
XAxis2,
|
|
829
1003
|
{
|
|
830
1004
|
dataKey: "bucket",
|
|
831
1005
|
tickLine: false,
|
|
@@ -835,8 +1009,8 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
835
1009
|
tickFormatter: (value) => bucketDate(value, granularity)
|
|
836
1010
|
}
|
|
837
1011
|
),
|
|
838
|
-
/* @__PURE__ */
|
|
839
|
-
|
|
1012
|
+
/* @__PURE__ */ jsx7(
|
|
1013
|
+
YAxis2,
|
|
840
1014
|
{
|
|
841
1015
|
tickLine: false,
|
|
842
1016
|
axisLine: false,
|
|
@@ -845,10 +1019,10 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
845
1019
|
tickFormatter: (value) => compact(value)
|
|
846
1020
|
}
|
|
847
1021
|
),
|
|
848
|
-
/* @__PURE__ */
|
|
1022
|
+
/* @__PURE__ */ jsx7(
|
|
849
1023
|
ChartTooltip,
|
|
850
1024
|
{
|
|
851
|
-
content: /* @__PURE__ */
|
|
1025
|
+
content: /* @__PURE__ */ jsx7(
|
|
852
1026
|
ChartTooltipContent,
|
|
853
1027
|
{
|
|
854
1028
|
labelFormatter: (value) => bucketDate(String(value), granularity),
|
|
@@ -857,8 +1031,8 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
857
1031
|
)
|
|
858
1032
|
}
|
|
859
1033
|
),
|
|
860
|
-
/* @__PURE__ */
|
|
861
|
-
SERIES.map((series, index) => /* @__PURE__ */
|
|
1034
|
+
/* @__PURE__ */ jsx7(ChartLegend, { content: /* @__PURE__ */ jsx7(ChartLegendContent, {}) }),
|
|
1035
|
+
SERIES.map((series, index) => /* @__PURE__ */ jsx7(
|
|
862
1036
|
Bar,
|
|
863
1037
|
{
|
|
864
1038
|
dataKey: series,
|
|
@@ -877,14 +1051,15 @@ function AnalyticsTimelineChart({ rows, className }) {
|
|
|
877
1051
|
__name(AnalyticsTimelineChart, "AnalyticsTimelineChart");
|
|
878
1052
|
|
|
879
1053
|
// src/features/analytics/components/AnalyticsAdminContainer.tsx
|
|
880
|
-
import { jsx as
|
|
1054
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
881
1055
|
function AnalyticsAdminContainer() {
|
|
882
|
-
const t =
|
|
1056
|
+
const t = useTranslations8();
|
|
883
1057
|
const {
|
|
884
1058
|
summary,
|
|
885
1059
|
timeline,
|
|
886
1060
|
breakdowns,
|
|
887
1061
|
sessions,
|
|
1062
|
+
dailyUniques,
|
|
888
1063
|
loadMoreSessions,
|
|
889
1064
|
hasMoreSessions,
|
|
890
1065
|
sessionPageUrl,
|
|
@@ -892,25 +1067,33 @@ function AnalyticsAdminContainer() {
|
|
|
892
1067
|
error
|
|
893
1068
|
} = useAnalyticsAdmin();
|
|
894
1069
|
if (error) {
|
|
895
|
-
return /* @__PURE__ */
|
|
1070
|
+
return /* @__PURE__ */ jsx8(RoundPageContainer, { module: Modules.AnalyticsSummary, fullWidth: true, forceHeader: true, children: /* @__PURE__ */ jsx8("div", { className: "p-4", children: /* @__PURE__ */ jsx8(Card, { children: /* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsx8("p", { className: "text-destructive text-xs/relaxed", children: error }) }) }) }) });
|
|
896
1071
|
}
|
|
897
|
-
if (isLoading) return /* @__PURE__ */
|
|
898
|
-
return /* @__PURE__ */
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
1072
|
+
if (isLoading) return /* @__PURE__ */ jsx8(RoundPageContainer, { module: Modules.AnalyticsSummary, fullWidth: true, forceHeader: true });
|
|
1073
|
+
return /* @__PURE__ */ jsx8(RoundPageContainer, { module: Modules.AnalyticsSummary, fullWidth: true, forceHeader: true, children: /* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-4 p-4", children: [
|
|
1074
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
|
|
1075
|
+
/* @__PURE__ */ jsx8(AnalyticsAdminTiles, { summary }),
|
|
1076
|
+
/* @__PURE__ */ jsx8("p", { className: "text-muted-foreground text-xs", children: t("analytics.admin.tiles.summarised_note") })
|
|
1077
|
+
] }),
|
|
1078
|
+
/* @__PURE__ */ jsxs7(Card, { children: [
|
|
1079
|
+
/* @__PURE__ */ jsx8(CardHeader, { children: /* @__PURE__ */ jsx8(CardTitle, { children: t("analytics.admin.panels.over_time") }) }),
|
|
1080
|
+
/* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsx8(AnalyticsTimelineChart, { rows: timeline }) })
|
|
902
1081
|
] }),
|
|
903
|
-
/* @__PURE__ */
|
|
904
|
-
/* @__PURE__ */
|
|
905
|
-
/* @__PURE__ */
|
|
1082
|
+
/* @__PURE__ */ jsxs7(Card, { "data-testid": "analytics-daily-visitors-card", children: [
|
|
1083
|
+
/* @__PURE__ */ jsx8(CardHeader, { children: /* @__PURE__ */ jsx8(CardTitle, { children: t("analytics.admin.panels.daily_visitors") }) }),
|
|
1084
|
+
/* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsx8(AnalyticsDailyUniquesChart, { rows: dailyUniques, metric: "visitors" }) })
|
|
906
1085
|
] }),
|
|
907
|
-
/* @__PURE__ */
|
|
908
|
-
/* @__PURE__ */
|
|
909
|
-
/* @__PURE__ */
|
|
1086
|
+
/* @__PURE__ */ jsxs7(Card, { "data-testid": "analytics-daily-users-card", children: [
|
|
1087
|
+
/* @__PURE__ */ jsx8(CardHeader, { children: /* @__PURE__ */ jsx8(CardTitle, { children: t("analytics.admin.panels.daily_users") }) }),
|
|
1088
|
+
/* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsx8(AnalyticsDailyUniquesChart, { rows: dailyUniques, metric: "users" }) })
|
|
910
1089
|
] }),
|
|
911
|
-
/* @__PURE__ */
|
|
912
|
-
/* @__PURE__ */
|
|
913
|
-
/* @__PURE__ */
|
|
1090
|
+
/* @__PURE__ */ jsxs7(Card, { children: [
|
|
1091
|
+
/* @__PURE__ */ jsx8(CardHeader, { children: /* @__PURE__ */ jsx8(CardTitle, { children: t("analytics.admin.panels.breakdown") }) }),
|
|
1092
|
+
/* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsx8(AnalyticsBreakdownTable, { breakdowns }) })
|
|
1093
|
+
] }),
|
|
1094
|
+
/* @__PURE__ */ jsxs7(Card, { children: [
|
|
1095
|
+
/* @__PURE__ */ jsx8(CardHeader, { children: /* @__PURE__ */ jsx8(CardTitle, { children: t("analytics.admin.panels.sessions") }) }),
|
|
1096
|
+
/* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsx8(
|
|
914
1097
|
AnalyticsSessionsTable,
|
|
915
1098
|
{
|
|
916
1099
|
rows: sessions,
|
|
@@ -925,13 +1108,13 @@ function AnalyticsAdminContainer() {
|
|
|
925
1108
|
__name(AnalyticsAdminContainer, "AnalyticsAdminContainer");
|
|
926
1109
|
|
|
927
1110
|
// src/features/analytics/components/AnalyticsJourneyContainer.tsx
|
|
928
|
-
import { useLocale as useLocale2, useTranslations as
|
|
929
|
-
import { useEffect as useEffect3, useMemo as
|
|
930
|
-
import { jsx as
|
|
1111
|
+
import { useLocale as useLocale2, useTranslations as useTranslations9 } from "next-intl";
|
|
1112
|
+
import { useEffect as useEffect3, useMemo as useMemo6, useState as useState2 } from "react";
|
|
1113
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
931
1114
|
var ANALYTICS_ADMIN_PAGE_URL = "/administration/analytics";
|
|
932
1115
|
var OTHER_SESSIONS_WINDOW_DAYS = 395;
|
|
933
1116
|
function AnalyticsJourneyContainer({ sessionId, pageUrl = ANALYTICS_ADMIN_PAGE_URL }) {
|
|
934
|
-
const t =
|
|
1117
|
+
const t = useTranslations9();
|
|
935
1118
|
const locale = useLocale2();
|
|
936
1119
|
const generateUrl = usePageUrlGenerator();
|
|
937
1120
|
const [session, setSession] = useState2(void 0);
|
|
@@ -972,7 +1155,7 @@ function AnalyticsJourneyContainer({ sessionId, pageUrl = ANALYTICS_ADMIN_PAGE_U
|
|
|
972
1155
|
cancelled = true;
|
|
973
1156
|
};
|
|
974
1157
|
}, [sessionId]);
|
|
975
|
-
const dateTime =
|
|
1158
|
+
const dateTime = useMemo6(
|
|
976
1159
|
() => new Intl.DateTimeFormat(locale, { dateStyle: "short", timeStyle: "medium" }),
|
|
977
1160
|
[locale]
|
|
978
1161
|
);
|
|
@@ -989,58 +1172,58 @@ function AnalyticsJourneyContainer({ sessionId, pageUrl = ANALYTICS_ADMIN_PAGE_U
|
|
|
989
1172
|
const title = { type: t("analytics.admin.panels.journey") };
|
|
990
1173
|
const renderBody = /* @__PURE__ */ __name(() => {
|
|
991
1174
|
if (error) {
|
|
992
|
-
return /* @__PURE__ */
|
|
1175
|
+
return /* @__PURE__ */ jsx9(RoundPageContainer, { module: Modules.AnalyticsSession, fullWidth: true, forceHeader: true, children: /* @__PURE__ */ jsx9("div", { className: "p-4", children: /* @__PURE__ */ jsx9(Card, { children: /* @__PURE__ */ jsx9(CardContent, { children: /* @__PURE__ */ jsx9("p", { className: "text-destructive text-xs/relaxed", children: error }) }) }) }) });
|
|
993
1176
|
}
|
|
994
|
-
if (isLoading || !session) return /* @__PURE__ */
|
|
1177
|
+
if (isLoading || !session) return /* @__PURE__ */ jsx9(RoundPageContainer, { module: Modules.AnalyticsSession, fullWidth: true, forceHeader: true });
|
|
995
1178
|
const source = [session.utmSource ?? session.referrerHost, session.utmMedium, session.utmCampaign].filter(Boolean).join(" / ");
|
|
996
|
-
return /* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
999
|
-
session.user ? /* @__PURE__ */
|
|
1000
|
-
/* @__PURE__ */
|
|
1001
|
-
/* @__PURE__ */
|
|
1002
|
-
] }) : /* @__PURE__ */
|
|
1003
|
-
session.consented ? /* @__PURE__ */
|
|
1179
|
+
return /* @__PURE__ */ jsx9(RoundPageContainer, { module: Modules.AnalyticsSession, fullWidth: true, forceHeader: true, children: /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-4 p-4", children: [
|
|
1180
|
+
/* @__PURE__ */ jsx9(Card, { "data-testid": "analytics-journey-attribution", children: /* @__PURE__ */ jsxs8(CardContent, { className: "flex flex-col gap-3", children: [
|
|
1181
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1182
|
+
session.user ? /* @__PURE__ */ jsxs8("span", { className: "flex flex-col", children: [
|
|
1183
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm", children: session.user.name }),
|
|
1184
|
+
/* @__PURE__ */ jsx9("span", { className: "text-muted-foreground text-xs", children: session.user.email })
|
|
1185
|
+
] }) : /* @__PURE__ */ jsx9(Badge, { variant: "softGray", children: t("analytics.admin.anonymous") }),
|
|
1186
|
+
session.consented ? /* @__PURE__ */ jsx9(Badge, { variant: "softGreen", children: t("analytics.admin.consented") }) : /* @__PURE__ */ jsx9(Badge, { variant: "softGray", children: t("analytics.admin.not_consented") })
|
|
1004
1187
|
] }),
|
|
1005
|
-
/* @__PURE__ */
|
|
1006
|
-
/* @__PURE__ */
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1010
|
-
/* @__PURE__ */
|
|
1188
|
+
/* @__PURE__ */ jsxs8("div", { className: "grid gap-3 sm:grid-cols-3", children: [
|
|
1189
|
+
/* @__PURE__ */ jsx9(DetailField, { label: t("analytics.admin.columns.started"), value: dateTime.format(session.startedAt) }),
|
|
1190
|
+
/* @__PURE__ */ jsx9(DetailField, { label: t("analytics.admin.columns.source"), value: source }),
|
|
1191
|
+
/* @__PURE__ */ jsx9(DetailField, { label: t("analytics.admin.columns.landing"), value: session.landingRoute }),
|
|
1192
|
+
/* @__PURE__ */ jsx9(DetailField, { label: t("analytics.admin.columns.device"), value: session.deviceType }),
|
|
1193
|
+
/* @__PURE__ */ jsx9(
|
|
1011
1194
|
DetailField,
|
|
1012
1195
|
{
|
|
1013
1196
|
label: t("analytics.admin.columns.visitor"),
|
|
1014
|
-
value: /* @__PURE__ */
|
|
1197
|
+
value: /* @__PURE__ */ jsx9("span", { className: "tabular-nums", children: session.visitorId })
|
|
1015
1198
|
}
|
|
1016
1199
|
)
|
|
1017
1200
|
] })
|
|
1018
1201
|
] }) }),
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
/* @__PURE__ */
|
|
1021
|
-
/* @__PURE__ */
|
|
1202
|
+
/* @__PURE__ */ jsxs8(Card, { children: [
|
|
1203
|
+
/* @__PURE__ */ jsx9(CardHeader, { children: /* @__PURE__ */ jsx9(CardTitle, { children: t("analytics.admin.columns.pages") }) }),
|
|
1204
|
+
/* @__PURE__ */ jsx9(CardContent, { children: pageViews.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground text-sm", children: t("analytics.admin.no_data") }) : (
|
|
1022
1205
|
// The package's <Table> wraps itself in an `overflow-x-clip`
|
|
1023
1206
|
// container — hence the child override, so wide rows scroll.
|
|
1024
|
-
/* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
/* @__PURE__ */
|
|
1027
|
-
/* @__PURE__ */
|
|
1028
|
-
/* @__PURE__ */
|
|
1207
|
+
/* @__PURE__ */ jsx9("div", { className: "overflow-x-auto [&_[data-slot=table-container]]:overflow-x-visible", children: /* @__PURE__ */ jsxs8(Table, { children: [
|
|
1208
|
+
/* @__PURE__ */ jsx9(TableHeader, { children: /* @__PURE__ */ jsxs8(TableRow, { children: [
|
|
1209
|
+
/* @__PURE__ */ jsx9(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.time") }),
|
|
1210
|
+
/* @__PURE__ */ jsx9(TableHead, { className: "text-end text-xs font-medium", children: t("analytics.admin.columns.gap") }),
|
|
1211
|
+
/* @__PURE__ */ jsx9(TableHead, { className: "text-xs font-medium", children: t("analytics.admin.columns.path") })
|
|
1029
1212
|
] }) }),
|
|
1030
|
-
/* @__PURE__ */
|
|
1213
|
+
/* @__PURE__ */ jsx9(TableBody, { children: pageViews.map((pageView, index) => {
|
|
1031
1214
|
const previous = index > 0 ? pageViews[index - 1] : void 0;
|
|
1032
|
-
return /* @__PURE__ */
|
|
1033
|
-
/* @__PURE__ */
|
|
1034
|
-
/* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1215
|
+
return /* @__PURE__ */ jsxs8(TableRow, { "data-testid": `analytics-pageview-row-${pageView.id}`, children: [
|
|
1216
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-xs tabular-nums", children: dateTime.format(pageView.createdAt) }),
|
|
1217
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-end text-xs tabular-nums", children: previous ? formatGap(pageView.createdAt.getTime() - previous.createdAt.getTime()) : "\u2014" }),
|
|
1218
|
+
/* @__PURE__ */ jsx9(TableCell, { className: "text-xs", children: pageView.path })
|
|
1036
1219
|
] }, pageView.id);
|
|
1037
1220
|
}) })
|
|
1038
1221
|
] }) })
|
|
1039
1222
|
) })
|
|
1040
1223
|
] }),
|
|
1041
|
-
/* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
1043
|
-
/* @__PURE__ */
|
|
1224
|
+
/* @__PURE__ */ jsxs8(Card, { children: [
|
|
1225
|
+
/* @__PURE__ */ jsx9(CardHeader, { children: /* @__PURE__ */ jsx9(CardTitle, { children: t("analytics.admin.panels.other_sessions") }) }),
|
|
1226
|
+
/* @__PURE__ */ jsx9(CardContent, { children: /* @__PURE__ */ jsx9(
|
|
1044
1227
|
AnalyticsSessionsTable,
|
|
1045
1228
|
{
|
|
1046
1229
|
rows: otherSessions,
|
|
@@ -1052,7 +1235,7 @@ function AnalyticsJourneyContainer({ sessionId, pageUrl = ANALYTICS_ADMIN_PAGE_U
|
|
|
1052
1235
|
] })
|
|
1053
1236
|
] }) });
|
|
1054
1237
|
}, "renderBody");
|
|
1055
|
-
return /* @__PURE__ */
|
|
1238
|
+
return /* @__PURE__ */ jsx9(SharedProvider, { value: { breadcrumbs: breadcrumb, title }, children: renderBody() });
|
|
1056
1239
|
}
|
|
1057
1240
|
__name(AnalyticsJourneyContainer, "AnalyticsJourneyContainer");
|
|
1058
1241
|
function unit(locale, name, value) {
|
|
@@ -1061,16 +1244,16 @@ function unit(locale, name, value) {
|
|
|
1061
1244
|
__name(unit, "unit");
|
|
1062
1245
|
|
|
1063
1246
|
// src/features/analytics/components/AnalyticsAdminPageContainer.tsx
|
|
1064
|
-
import { jsx as
|
|
1247
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1065
1248
|
function AnalyticsAdminPageContainer({ sessionPageUrl }) {
|
|
1066
|
-
return /* @__PURE__ */
|
|
1249
|
+
return /* @__PURE__ */ jsx10(AnalyticsAdminProvider, { sessionPageUrl, children: /* @__PURE__ */ jsx10(AnalyticsAdminContainer, {}) });
|
|
1067
1250
|
}
|
|
1068
1251
|
__name(AnalyticsAdminPageContainer, "AnalyticsAdminPageContainer");
|
|
1069
1252
|
|
|
1070
1253
|
// src/features/analytics/components/AnalyticsJourneyPageContainer.tsx
|
|
1071
|
-
import { jsx as
|
|
1254
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1072
1255
|
function AnalyticsJourneyPageContainer({ sessionId, pageUrl }) {
|
|
1073
|
-
return /* @__PURE__ */
|
|
1256
|
+
return /* @__PURE__ */ jsx11(AnalyticsJourneyContainer, { sessionId, pageUrl });
|
|
1074
1257
|
}
|
|
1075
1258
|
__name(AnalyticsJourneyPageContainer, "AnalyticsJourneyPageContainer");
|
|
1076
1259
|
|
|
@@ -1102,6 +1285,8 @@ var ANALYTICS_ADMIN_I18N_KEYS = [
|
|
|
1102
1285
|
"analytics.admin.panels.sessions",
|
|
1103
1286
|
"analytics.admin.panels.journey",
|
|
1104
1287
|
"analytics.admin.panels.other_sessions",
|
|
1288
|
+
"analytics.admin.panels.daily_visitors",
|
|
1289
|
+
"analytics.admin.panels.daily_users",
|
|
1105
1290
|
// Breakdown tabs
|
|
1106
1291
|
"analytics.admin.dimensions.source",
|
|
1107
1292
|
"analytics.admin.dimensions.medium",
|
|
@@ -1132,7 +1317,12 @@ var ANALYTICS_ADMIN_I18N_KEYS = [
|
|
|
1132
1317
|
"analytics.admin.other",
|
|
1133
1318
|
// Timeline chart series
|
|
1134
1319
|
"analytics.admin.series.visitors",
|
|
1135
|
-
"analytics.admin.series.page_views"
|
|
1320
|
+
"analytics.admin.series.page_views",
|
|
1321
|
+
// Daily uniques charts
|
|
1322
|
+
"analytics.admin.daily_uniques.visitors",
|
|
1323
|
+
"analytics.admin.daily_uniques.users",
|
|
1324
|
+
"analytics.admin.daily_uniques.today",
|
|
1325
|
+
"analytics.admin.daily_uniques.no_data"
|
|
1136
1326
|
];
|
|
1137
1327
|
export {
|
|
1138
1328
|
ANALYTICS_ADMIN_I18N_KEYS,
|
|
@@ -1147,6 +1337,8 @@ export {
|
|
|
1147
1337
|
AnalyticsAdminTiles,
|
|
1148
1338
|
AnalyticsBreakdown,
|
|
1149
1339
|
AnalyticsBreakdownTable,
|
|
1340
|
+
AnalyticsDailyUniqueTimeline,
|
|
1341
|
+
AnalyticsDailyUniquesChart,
|
|
1150
1342
|
AnalyticsEvent,
|
|
1151
1343
|
AnalyticsJourneyContainer,
|
|
1152
1344
|
AnalyticsJourneyPageContainer,
|