medusa-analytics 0.0.19 → 0.0.21

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.
@@ -3,7 +3,7 @@ import { useState, useEffect, useMemo } from "react";
3
3
  import { defineRouteConfig } from "@medusajs/admin-sdk";
4
4
  import { CurrencyDollar, ShoppingCart, TruckFast, Cash, UsersSolid, User, UserGroup, Trash, Tag, CubeSolid, ChartBar } from "@medusajs/icons";
5
5
  import { Container, Text, Heading, Label, Table } from "@medusajs/ui";
6
- import { ResponsiveContainer, LineChart, CartesianGrid, XAxis, YAxis, Tooltip, Line, ComposedChart, Legend, Area, ReferenceLine, BarChart, Bar, PieChart, Pie, Cell, ScatterChart, Scatter } from "recharts";
6
+ import { ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Tooltip, Bar, ComposedChart, Line, Legend, Area, LineChart, ReferenceLine, PieChart, Pie, Cell, ScatterChart, Scatter } from "recharts";
7
7
  const ACCENT_STYLES = {
8
8
  blue: {
9
9
  border: "border-sky-400/30",
@@ -295,37 +295,72 @@ function formatChartLabel$2(value) {
295
295
  function formatPercent(value) {
296
296
  return `${value.toFixed(1)}%`;
297
297
  }
298
- function ordersCountFromPiePayload(payload) {
299
- if (typeof payload !== "object" || payload === null) return 0;
300
- if (!("orders_count" in payload)) return 0;
301
- const c = payload.orders_count;
302
- return Math.floor(Number(c) || 0);
303
- }
304
298
  function formatShortNumber$1(value) {
305
299
  return new Intl.NumberFormat("en-IN", {
306
300
  notation: "compact",
307
301
  maximumFractionDigits: value < 10 ? 1 : 0
308
302
  }).format(value);
309
303
  }
310
- function OrdersTrendTooltip({
304
+ const SALES_GRANULARITY_TABS = [
305
+ { value: "day", label: "Day" },
306
+ { value: "hour", label: "Hour" },
307
+ { value: "week", label: "Week" },
308
+ { value: "month", label: "Month" }
309
+ ];
310
+ function monthKeyFromDateStr(dateStr) {
311
+ if (dateStr.length >= 7) return dateStr.slice(0, 7);
312
+ return dateStr;
313
+ }
314
+ function formatMonthBucketLabel(ymKey) {
315
+ const [ys, ms] = ymKey.split("-");
316
+ const y = Number(ys);
317
+ const m = Number(ms);
318
+ if (!Number.isFinite(y) || !Number.isFinite(m)) return ymKey;
319
+ return new Intl.DateTimeFormat("en-IN", {
320
+ month: "short",
321
+ year: "numeric",
322
+ timeZone: "UTC"
323
+ }).format(new Date(Date.UTC(y, m - 1, 1)));
324
+ }
325
+ function aggregateDailyOrdersForBreakdown(rows, keyFn, labelFn) {
326
+ const map = /* @__PURE__ */ new Map();
327
+ for (const d of rows) {
328
+ const key = keyFn(d);
329
+ const cur = map.get(key) ?? { orders: 0, revenue: 0, bucketRows: [] };
330
+ cur.orders += d.orders_count;
331
+ cur.revenue += d.total_revenue;
332
+ cur.bucketRows.push(d);
333
+ map.set(key, cur);
334
+ }
335
+ return Array.from(map.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([key, v]) => ({
336
+ key,
337
+ label: labelFn(key, v.bucketRows),
338
+ orders_count: v.orders,
339
+ revenue: v.revenue
340
+ }));
341
+ }
342
+ function isSalesBreakdownBarRow(value) {
343
+ if (typeof value !== "object" || value === null) return false;
344
+ const v = value;
345
+ return typeof v.key === "string" && typeof v.label === "string" && typeof v.orders_count === "number" && typeof v.revenue === "number";
346
+ }
347
+ function SalesBreakdownTooltip({
311
348
  active,
312
- payload,
313
- label
349
+ payload
314
350
  }) {
315
- var _a, _b, _c, _d;
351
+ var _a, _b;
316
352
  if (!active || !(payload == null ? void 0 : payload.length)) return null;
317
- const row = isDailyOrderRow((_a = payload[0]) == null ? void 0 : _a.payload) ? (_b = payload[0]) == null ? void 0 : _b.payload : void 0;
318
- const displayLabel = (row == null ? void 0 : row.label) ?? (label ? new Date(label).toLocaleDateString() : "");
319
- const orders = ((_c = payload.find((entry) => entry.name === "Orders")) == null ? void 0 : _c.value) ?? 0;
320
- const revenue = ((_d = payload.find((entry) => entry.name === "Revenue")) == null ? void 0 : _d.value) ?? 0;
321
- return /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { title: displayLabel, children: [
353
+ const row = isSalesBreakdownBarRow((_a = payload[0]) == null ? void 0 : _a.payload) ? (_b = payload[0]) == null ? void 0 : _b.payload : void 0;
354
+ if (!row) return null;
355
+ return /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: row.label, children: [
322
356
  /* @__PURE__ */ jsxs("div", { children: [
323
- "Orders: ",
324
- /* @__PURE__ */ jsx("strong", { children: Math.floor(orders).toLocaleString() })
357
+ "Revenue: ",
358
+ /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(row.revenue) })
325
359
  ] }),
326
360
  /* @__PURE__ */ jsxs("div", { children: [
327
- "Revenue: ",
328
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(Number(revenue)) })
361
+ "Orders:",
362
+ " ",
363
+ /* @__PURE__ */ jsx("strong", { children: Math.floor(row.orders_count).toLocaleString() })
329
364
  ] })
330
365
  ] });
331
366
  }
@@ -347,21 +382,6 @@ function OrdersTodayTooltip({
347
382
  (row == null ? void 0 : row.isToday) ? /* @__PURE__ */ jsx("div", { style: { color: "#6B7280" }, children: "Current day" }) : null
348
383
  ] });
349
384
  }
350
- function OrdersSparklineTooltip({
351
- active,
352
- payload,
353
- label
354
- }) {
355
- var _a, _b, _c;
356
- if (!active || !(payload == null ? void 0 : payload.length)) return null;
357
- const row = isDailyOrderRow((_a = payload[0]) == null ? void 0 : _a.payload) ? (_b = payload[0]) == null ? void 0 : _b.payload : void 0;
358
- const displayLabel = (row == null ? void 0 : row.label) ?? (label ? new Date(label).toLocaleDateString() : "");
359
- const orders = Number((_c = payload[0]) == null ? void 0 : _c.value) || 0;
360
- return /* @__PURE__ */ jsx(AnalyticsTooltipCard, { variant: "compact", title: displayLabel, children: /* @__PURE__ */ jsxs("div", { children: [
361
- "Orders: ",
362
- /* @__PURE__ */ jsx("strong", { children: Math.floor(orders).toLocaleString() })
363
- ] }) });
364
- }
365
385
  function OutcomesTrendTooltip({
366
386
  active,
367
387
  payload,
@@ -378,6 +398,53 @@ function OutcomesTrendTooltip({
378
398
  /* @__PURE__ */ jsx("strong", { children: Math.floor(Number(entry.value) || 0).toLocaleString() })
379
399
  ] }, String(entry.name))) });
380
400
  }
401
+ function isTrendRowDetailed(value) {
402
+ if (!isDailyOrderRow(value)) return false;
403
+ const v = value;
404
+ return typeof v.aov === "number" && typeof v.prev_revenue === "number" && typeof v.prev_orders === "number" && typeof v.prev_aov === "number";
405
+ }
406
+ function CombinedMetricsTooltip({
407
+ active,
408
+ payload
409
+ }) {
410
+ var _a, _b;
411
+ if (!active || !(payload == null ? void 0 : payload.length)) return null;
412
+ const row = isTrendRowDetailed((_a = payload[0]) == null ? void 0 : _a.payload) ? (_b = payload[0]) == null ? void 0 : _b.payload : void 0;
413
+ if (!row) return null;
414
+ const title = row.label ?? formatChartLabel$2(row.date);
415
+ return /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title, children: [
416
+ /* @__PURE__ */ jsxs("div", { children: [
417
+ "Revenue:",
418
+ " ",
419
+ /* @__PURE__ */ jsx("strong", { children: formatCompactCurrency$1(row.total_revenue) }),
420
+ /* @__PURE__ */ jsxs("span", { className: "text-ui-fg-muted", children: [
421
+ " ",
422
+ "· prev ",
423
+ formatCompactCurrency$1(row.prev_revenue)
424
+ ] })
425
+ ] }),
426
+ /* @__PURE__ */ jsxs("div", { children: [
427
+ "Orders:",
428
+ " ",
429
+ /* @__PURE__ */ jsx("strong", { children: Math.floor(row.orders_count).toLocaleString() }),
430
+ /* @__PURE__ */ jsxs("span", { className: "text-ui-fg-muted", children: [
431
+ " ",
432
+ "· prev ",
433
+ Math.floor(row.prev_orders).toLocaleString()
434
+ ] })
435
+ ] }),
436
+ /* @__PURE__ */ jsxs("div", { children: [
437
+ "AOV (non-canc.):",
438
+ " ",
439
+ /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(row.aov) }),
440
+ /* @__PURE__ */ jsxs("span", { className: "text-ui-fg-muted", children: [
441
+ " ",
442
+ "· prev ",
443
+ formatCurrency$1(row.prev_aov)
444
+ ] })
445
+ ] })
446
+ ] });
447
+ }
381
448
  const KPI_ICON_BG$2 = {
382
449
  green: "bg-emerald-500/20",
383
450
  blue: "bg-sky-500/20",
@@ -391,53 +458,6 @@ const KPI_ICONS$2 = {
391
458
  amber: Cash
392
459
  };
393
460
  const PIE_PALETTE = ["#6366F1", "#94A3B8", "#10B981", "#F59E0B"];
394
- function TrafficRevenueDonut({ traffic }) {
395
- return /* @__PURE__ */ jsx("div", { className: "h-[152px] w-full shrink-0", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { margin: { top: 2, right: 2, left: 2, bottom: 2 }, children: [
396
- /* @__PURE__ */ jsx(
397
- Pie,
398
- {
399
- data: traffic,
400
- dataKey: "revenue",
401
- nameKey: "label",
402
- cx: "50%",
403
- cy: "48%",
404
- innerRadius: 34,
405
- outerRadius: 54,
406
- paddingAngle: 2,
407
- children: traffic.map((_, i) => /* @__PURE__ */ jsx(Cell, { fill: PIE_PALETTE[i % PIE_PALETTE.length] }, `traffic-slice-${i}`))
408
- }
409
- ),
410
- /* @__PURE__ */ jsx(
411
- Tooltip,
412
- {
413
- content: ({ active, payload }) => {
414
- var _a, _b, _c;
415
- return active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: String(((_a = payload[0]) == null ? void 0 : _a.name) ?? ""), children: [
416
- /* @__PURE__ */ jsxs("div", { children: [
417
- "Revenue:",
418
- " ",
419
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(Number((_b = payload[0]) == null ? void 0 : _b.value) || 0) })
420
- ] }),
421
- /* @__PURE__ */ jsxs("div", { children: [
422
- "Orders:",
423
- " ",
424
- /* @__PURE__ */ jsx("strong", { children: ordersCountFromPiePayload((_c = payload[0]) == null ? void 0 : _c.payload).toLocaleString() })
425
- ] })
426
- ] }) : null;
427
- }
428
- }
429
- ),
430
- /* @__PURE__ */ jsx(
431
- Legend,
432
- {
433
- wrapperStyle: { fontSize: 9, paddingTop: 0 },
434
- verticalAlign: "bottom",
435
- height: 22,
436
- iconType: "circle"
437
- }
438
- )
439
- ] }) }) });
440
- }
441
461
  function AtlasKpiCard$2({
442
462
  label,
443
463
  value,
@@ -497,7 +517,7 @@ function EmptyAnalyticsPanel$1({
497
517
  ] });
498
518
  }
499
519
  function OrdersDashboard() {
500
- var _a, _b, _c;
520
+ var _a, _b;
501
521
  const [data, setData] = useState(null);
502
522
  const [loading, setLoading] = useState(true);
503
523
  const [error, setError] = useState(null);
@@ -513,6 +533,7 @@ function OrdersDashboard() {
513
533
  const [todayContext, setTodayContext] = useState([]);
514
534
  const [todayContextLoading, setTodayContextLoading] = useState(true);
515
535
  const [todayContextError, setTodayContextError] = useState(null);
536
+ const [salesGranularity, setSalesGranularity] = useState("day");
516
537
  useEffect(() => {
517
538
  let cancelled = false;
518
539
  setLoading(true);
@@ -708,14 +729,61 @@ function OrdersDashboard() {
708
729
  revenue: h.revenue
709
730
  }));
710
731
  }, [ordersInsights]);
711
- const weekdayChartRows = useMemo(() => {
712
- if (!ordersInsights) return [];
713
- return ordersInsights.byWeekday.map((w) => ({
714
- label: w.label,
715
- orders_count: w.orders_count,
716
- revenue: w.revenue
732
+ const salesBreakdownChartRows = useMemo(() => {
733
+ if (salesGranularity === "hour") {
734
+ return hourlyChartRows.map((h) => ({
735
+ key: `hour-${h.hour}`,
736
+ label: h.label,
737
+ orders_count: h.orders_count,
738
+ revenue: h.revenue
739
+ }));
740
+ }
741
+ if (salesGranularity === "week") {
742
+ if (!ordersInsights) return [];
743
+ return ordersInsights.byWeekday.map((w) => ({
744
+ key: `weekday-${w.weekday}`,
745
+ label: w.label,
746
+ orders_count: w.orders_count,
747
+ revenue: w.revenue
748
+ }));
749
+ }
750
+ if (salesGranularity === "month") {
751
+ return aggregateDailyOrdersForBreakdown(
752
+ dailyOrders,
753
+ (d) => monthKeyFromDateStr(d.date),
754
+ (ymKey) => formatMonthBucketLabel(ymKey)
755
+ );
756
+ }
757
+ return dailyOrders.map((d) => ({
758
+ key: d.date,
759
+ label: d.label ?? formatChartLabel$2(d.date),
760
+ orders_count: d.orders_count,
761
+ revenue: d.total_revenue
717
762
  }));
718
- }, [ordersInsights]);
763
+ }, [salesGranularity, dailyOrders, hourlyChartRows, ordersInsights]);
764
+ const salesBreakdownDescription = useMemo(() => {
765
+ var _a2;
766
+ const rangeLabel = ((_a2 = OVER_TIME_PERIODS.find((p) => p.value === overTimePeriod)) == null ? void 0 : _a2.label) ?? "selected range";
767
+ const insightsHint = `Order-time breakdown uses last ${insightsWindowDays} days (UTC).`;
768
+ switch (salesGranularity) {
769
+ case "day":
770
+ return `Revenue by calendar day for ${rangeLabel} (aligned with Revenue & orders).`;
771
+ case "hour":
772
+ return `${insightsHint} Bars show revenue by hour of day.`;
773
+ case "week":
774
+ return `Revenue by UTC weekday — last ${insightsWindowDays} days.`;
775
+ case "month":
776
+ return `Revenue summed by calendar month (UTC) across ${rangeLabel}.`;
777
+ default:
778
+ return "";
779
+ }
780
+ }, [salesGranularity, overTimePeriod, insightsWindowDays]);
781
+ const salesBreakdownXAxisInterval = useMemo(() => {
782
+ const n = salesBreakdownChartRows.length;
783
+ if (salesGranularity === "hour") return 3;
784
+ if (salesGranularity === "day" && n > 24) return Math.max(0, Math.ceil(n / 10) - 1);
785
+ return 0;
786
+ }, [salesGranularity, salesBreakdownChartRows.length]);
719
787
  const ordersVsDraftsPie = useMemo(() => {
720
788
  var _a2;
721
789
  if (!ordersInsights) return [];
@@ -752,10 +820,6 @@ function OrdersDashboard() {
752
820
  };
753
821
  });
754
822
  }, [dailyOrders]);
755
- const trafficTotalRevenue = useMemo(
756
- () => (ordersInsights == null ? void 0 : ordersInsights.traffic.reduce((sum, t) => sum + (t.revenue || 0), 0)) ?? 0,
757
- [ordersInsights]
758
- );
759
823
  const quickPulseMetrics = [
760
824
  {
761
825
  label: "Range revenue",
@@ -796,6 +860,84 @@ function OrdersDashboard() {
796
860
  if (error || !data) {
797
861
  return /* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger", children: error ?? "Failed to load analytics" }) });
798
862
  }
863
+ const needsSalesOverTime = salesGranularity === "day" || salesGranularity === "month";
864
+ const needsSalesInsights = salesGranularity === "hour" || salesGranularity === "week";
865
+ const salesBreakdownBody = (() => {
866
+ if (needsSalesOverTime && overTimeLoading) {
867
+ return /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[min(176px,28vh)] items-center justify-center py-6", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading chart…" }) }) });
868
+ }
869
+ if (needsSalesOverTime && overTimeError) {
870
+ return /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[min(176px,28vh)] items-center justify-center px-2 py-6", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: overTimeError }) }) });
871
+ }
872
+ if (needsSalesInsights && insightsLoading) {
873
+ return /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[min(176px,28vh)] items-center justify-center py-6", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading chart…" }) }) });
874
+ }
875
+ if (needsSalesInsights && insightsError) {
876
+ return /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[min(176px,28vh)] items-center justify-center px-2 py-6", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: insightsError }) }) });
877
+ }
878
+ if (salesBreakdownChartRows.length === 0) {
879
+ return /* @__PURE__ */ jsx(
880
+ EmptyAnalyticsPanel$1,
881
+ {
882
+ title: "No sales data",
883
+ description: "Nothing to show for this view and range."
884
+ }
885
+ );
886
+ }
887
+ return /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "h-[min(200px,30vh)] min-h-[160px] w-full sm:h-[min(220px,32vh)]", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
888
+ BarChart,
889
+ {
890
+ data: salesBreakdownChartRows,
891
+ margin: { top: 4, right: 8, left: 4, bottom: 4 },
892
+ children: [
893
+ /* @__PURE__ */ jsx(
894
+ CartesianGrid,
895
+ {
896
+ strokeDasharray: "3 3",
897
+ vertical: false,
898
+ stroke: "rgba(148,163,184,0.12)"
899
+ }
900
+ ),
901
+ /* @__PURE__ */ jsx(
902
+ XAxis,
903
+ {
904
+ dataKey: "label",
905
+ tick: CHART_AXIS_TICK_SM$1,
906
+ tickLine: false,
907
+ axisLine: false,
908
+ interval: salesBreakdownXAxisInterval
909
+ }
910
+ ),
911
+ /* @__PURE__ */ jsx(
912
+ YAxis,
913
+ {
914
+ width: 44,
915
+ tick: CHART_AXIS_TICK_SM$1,
916
+ tickLine: false,
917
+ axisLine: false,
918
+ tickFormatter: (v) => formatCompactCurrency$1(Number(v))
919
+ }
920
+ ),
921
+ /* @__PURE__ */ jsx(
922
+ Tooltip,
923
+ {
924
+ content: /* @__PURE__ */ jsx(SalesBreakdownTooltip, {}),
925
+ cursor: { fill: "rgba(148,163,184,0.08)" }
926
+ }
927
+ ),
928
+ /* @__PURE__ */ jsx(
929
+ Bar,
930
+ {
931
+ dataKey: "revenue",
932
+ name: "Revenue",
933
+ fill: "#D946EF",
934
+ radius: [6, 6, 0, 0]
935
+ }
936
+ )
937
+ ]
938
+ }
939
+ ) }) }) });
940
+ })();
799
941
  return /* @__PURE__ */ jsx(AnalyticsDashboardShell, { children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-2xl border border-ui-border-base/80 bg-ui-bg-base shadow-sm", children: [
800
942
  /* @__PURE__ */ jsx(
801
943
  AnalyticsDashboardHeader,
@@ -910,397 +1052,197 @@ function OrdersDashboard() {
910
1052
  ] }) })
911
1053
  ] }),
912
1054
  !overTimeLoading && !overTimeError && dailyOrders.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
913
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-1.5 lg:grid-cols-3", children: [
914
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
915
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Revenue over time" }),
916
- /* @__PURE__ */ jsx("div", { className: "h-[118px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
917
- LineChart,
918
- {
919
- data: trendRowsDetailed,
920
- margin: { top: 4, right: 4, left: 0, bottom: 0 },
921
- children: [
922
- /* @__PURE__ */ jsx(
923
- CartesianGrid,
924
- {
925
- strokeDasharray: "3 3",
926
- vertical: false,
927
- stroke: "rgba(148,163,184,0.12)"
928
- }
929
- ),
930
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
931
- /* @__PURE__ */ jsx(
932
- YAxis,
933
- {
934
- width: 36,
935
- tick: CHART_AXIS_TICK_SM$1,
936
- tickFormatter: (v) => formatCompactCurrency$1(Number(v))
937
- }
938
- ),
939
- /* @__PURE__ */ jsx(
940
- Tooltip,
941
- {
942
- content: ({ active, payload, label }) => {
943
- var _a2, _b2, _c2, _d;
944
- return active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsxs(
945
- AnalyticsTooltipCard,
946
- {
947
- variant: "compact",
948
- title: String(
949
- isDailyOrderRow((_a2 = payload[0]) == null ? void 0 : _a2.payload) ? ((_b2 = payload[0]) == null ? void 0 : _b2.payload.label) ?? formatChartLabel$2(String(label)) : label
950
- ),
951
- children: [
952
- /* @__PURE__ */ jsxs("div", { children: [
953
- "This:",
954
- " ",
955
- /* @__PURE__ */ jsx("strong", { children: formatCompactCurrency$1(
956
- Number(
957
- (_c2 = payload.find((p) => p.dataKey === "total_revenue")) == null ? void 0 : _c2.value
958
- ) || 0
959
- ) })
960
- ] }),
961
- /* @__PURE__ */ jsxs("div", { children: [
962
- "Previous:",
963
- " ",
964
- /* @__PURE__ */ jsx("strong", { children: formatCompactCurrency$1(
965
- Number(
966
- (_d = payload.find((p) => p.dataKey === "prev_revenue")) == null ? void 0 : _d.value
967
- ) || 0
968
- ) })
969
- ] })
970
- ]
971
- }
972
- ) : null;
973
- }
974
- }
975
- ),
976
- /* @__PURE__ */ jsx(
977
- Line,
978
- {
979
- type: "natural",
980
- dataKey: "total_revenue",
981
- name: "This period",
982
- stroke: "#D946EF",
983
- strokeWidth: 2,
984
- dot: false
985
- }
986
- ),
987
- /* @__PURE__ */ jsx(
988
- Line,
989
- {
990
- type: "natural",
991
- dataKey: "prev_revenue",
992
- name: "Previous",
993
- stroke: "#94a3b8",
994
- strokeWidth: 1.5,
995
- strokeDasharray: "5 4",
996
- dot: false
997
- }
998
- )
999
- ]
1000
- }
1001
- ) }) })
1002
- ] }),
1003
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
1004
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Orders count" }),
1005
- /* @__PURE__ */ jsx("div", { className: "h-[118px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1006
- LineChart,
1007
- {
1008
- data: trendRowsDetailed,
1009
- margin: { top: 4, right: 4, left: 0, bottom: 0 },
1010
- children: [
1011
- /* @__PURE__ */ jsx(
1012
- CartesianGrid,
1013
- {
1014
- strokeDasharray: "3 3",
1015
- vertical: false,
1016
- stroke: "rgba(148,163,184,0.12)"
1017
- }
1018
- ),
1019
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
1020
- /* @__PURE__ */ jsx(
1021
- YAxis,
1022
- {
1023
- width: 28,
1024
- tick: CHART_AXIS_TICK_SM$1,
1025
- allowDecimals: false
1026
- }
1027
- ),
1028
- /* @__PURE__ */ jsx(
1029
- Tooltip,
1030
- {
1031
- content: ({ active, payload, label }) => {
1032
- var _a2, _b2;
1033
- return active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: String(label), children: [
1034
- /* @__PURE__ */ jsxs("div", { children: [
1035
- "This:",
1036
- " ",
1037
- /* @__PURE__ */ jsx("strong", { children: Math.floor(
1038
- Number(
1039
- (_a2 = payload.find((p) => p.dataKey === "orders_count")) == null ? void 0 : _a2.value
1040
- ) || 0
1041
- ).toLocaleString() })
1042
- ] }),
1043
- /* @__PURE__ */ jsxs("div", { children: [
1044
- "Previous:",
1045
- " ",
1046
- /* @__PURE__ */ jsx("strong", { children: Math.floor(
1047
- Number(
1048
- (_b2 = payload.find((p) => p.dataKey === "prev_orders")) == null ? void 0 : _b2.value
1049
- ) || 0
1050
- ).toLocaleString() })
1051
- ] })
1052
- ] }) : null;
1053
- }
1054
- }
1055
- ),
1056
- /* @__PURE__ */ jsx(
1057
- Line,
1058
- {
1059
- type: "natural",
1060
- dataKey: "orders_count",
1061
- name: "This period",
1062
- stroke: "#38BDF8",
1063
- strokeWidth: 2,
1064
- dot: false
1065
- }
1066
- ),
1067
- /* @__PURE__ */ jsx(
1068
- Line,
1069
- {
1070
- type: "natural",
1071
- dataKey: "prev_orders",
1072
- name: "Previous",
1073
- stroke: "#94a3b8",
1074
- strokeWidth: 1.5,
1075
- strokeDasharray: "5 4",
1076
- dot: false
1077
- }
1078
- )
1079
- ]
1080
- }
1081
- ) }) })
1055
+ /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
1056
+ /* @__PURE__ */ jsxs("div", { className: "mb-1 flex flex-col gap-0.5 sm:flex-row sm:items-start sm:justify-between", children: [
1057
+ /* @__PURE__ */ jsxs("div", { children: [
1058
+ /* @__PURE__ */ jsx(Text, { className: "text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Revenue, orders & AOV" }),
1059
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[9px] leading-snug", children: "One timeline · solid = this range, dashed = previous period (same length)" })
1060
+ ] }),
1061
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-x-3 gap-y-0.5 text-[9px] text-ui-fg-muted sm:justify-end", children: [
1062
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1063
+ /* @__PURE__ */ jsx("span", { className: "h-2 w-2 shrink-0 rounded-full bg-fuchsia-500" }),
1064
+ "Revenue"
1065
+ ] }),
1066
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1067
+ /* @__PURE__ */ jsx("span", { className: "h-2 w-2 shrink-0 rounded-full bg-sky-400" }),
1068
+ "Orders"
1069
+ ] }),
1070
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1071
+ /* @__PURE__ */ jsx("span", { className: "h-2 w-2 shrink-0 rounded-full bg-amber-500" }),
1072
+ "AOV"
1073
+ ] }),
1074
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1075
+ /* @__PURE__ */ jsx(
1076
+ "span",
1077
+ {
1078
+ className: "h-0 w-4 shrink-0 border-t border-dashed border-slate-400",
1079
+ "aria-hidden": true
1080
+ }
1081
+ ),
1082
+ "Previous"
1083
+ ] })
1084
+ ] })
1082
1085
  ] }),
1083
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
1084
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "AOV (non-cancelled)" }),
1085
- /* @__PURE__ */ jsx("div", { className: "h-[118px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1086
- LineChart,
1087
- {
1088
- data: trendRowsDetailed,
1089
- margin: { top: 4, right: 4, left: 0, bottom: 0 },
1090
- children: [
1091
- /* @__PURE__ */ jsx(
1092
- CartesianGrid,
1093
- {
1094
- strokeDasharray: "3 3",
1095
- vertical: false,
1096
- stroke: "rgba(148,163,184,0.12)"
1097
- }
1098
- ),
1099
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
1100
- /* @__PURE__ */ jsx(
1101
- YAxis,
1102
- {
1103
- width: 36,
1104
- tick: CHART_AXIS_TICK_SM$1,
1105
- tickFormatter: (v) => formatCompactCurrency$1(Number(v))
1106
- }
1107
- ),
1108
- /* @__PURE__ */ jsx(
1109
- Tooltip,
1110
- {
1111
- content: ({ active, payload, label }) => {
1112
- var _a2, _b2;
1113
- return active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: String(label), children: [
1114
- /* @__PURE__ */ jsxs("div", { children: [
1115
- "This:",
1116
- " ",
1117
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(
1118
- Number(
1119
- (_a2 = payload.find((p) => p.dataKey === "aov")) == null ? void 0 : _a2.value
1120
- ) || 0
1121
- ) })
1122
- ] }),
1123
- /* @__PURE__ */ jsxs("div", { children: [
1124
- "Previous:",
1125
- " ",
1126
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(
1127
- Number(
1128
- (_b2 = payload.find((p) => p.dataKey === "prev_aov")) == null ? void 0 : _b2.value
1129
- ) || 0
1130
- ) })
1131
- ] })
1132
- ] }) : null;
1133
- }
1134
- }
1135
- ),
1136
- /* @__PURE__ */ jsx(
1137
- Line,
1138
- {
1139
- type: "natural",
1140
- dataKey: "aov",
1141
- name: "This period",
1142
- stroke: "#D97706",
1143
- strokeWidth: 2,
1144
- dot: false
1145
- }
1146
- ),
1147
- /* @__PURE__ */ jsx(
1148
- Line,
1149
- {
1150
- type: "natural",
1151
- dataKey: "prev_aov",
1152
- name: "Previous",
1153
- stroke: "#94a3b8",
1154
- strokeWidth: 1.5,
1155
- strokeDasharray: "5 4",
1156
- dot: false
1157
- }
1158
- )
1159
- ]
1160
- }
1161
- ) }) })
1162
- ] })
1163
- ] }),
1164
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", className: "mt-1.5", children: [
1165
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Revenue breakdown (stacked — by order status)" }),
1166
- /* @__PURE__ */ jsx("div", { className: "h-[min(168px,26vh)] min-h-[140px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1086
+ /* @__PURE__ */ jsx("div", { className: "h-[min(220px,32vh)] min-h-[156px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1167
1087
  ComposedChart,
1168
1088
  {
1169
- data: dailyOrders,
1170
- margin: { top: 4, right: 8, left: -4, bottom: 0 },
1089
+ data: trendRowsDetailed,
1090
+ margin: { top: 6, right: 8, left: 2, bottom: 4 },
1171
1091
  children: [
1172
1092
  /* @__PURE__ */ jsx(
1173
1093
  CartesianGrid,
1174
1094
  {
1175
- stroke: "rgba(148,163,184,0.14)",
1176
1095
  strokeDasharray: "3 3",
1177
- vertical: false
1096
+ vertical: false,
1097
+ stroke: "rgba(148,163,184,0.12)"
1178
1098
  }
1179
1099
  ),
1180
1100
  /* @__PURE__ */ jsx(
1181
1101
  XAxis,
1182
1102
  {
1183
1103
  dataKey: "date",
1184
- tick: CHART_AXIS_TICK$2,
1104
+ tick: CHART_AXIS_TICK_SM$1,
1185
1105
  tickLine: false,
1186
1106
  axisLine: false,
1187
1107
  tickFormatter: (value, index) => {
1188
- const row = dailyOrders[index];
1189
- return (row == null ? void 0 : row.label) ?? formatChartLabel$2(value);
1108
+ const row = trendRowsDetailed[index];
1109
+ return (row == null ? void 0 : row.label) ?? formatChartLabel$2(String(value));
1190
1110
  }
1191
1111
  }
1192
1112
  ),
1193
1113
  /* @__PURE__ */ jsx(
1194
1114
  YAxis,
1195
1115
  {
1196
- tick: CHART_AXIS_TICK$2,
1116
+ yAxisId: "orders",
1117
+ width: 30,
1118
+ tick: CHART_AXIS_TICK_SM$1,
1119
+ tickLine: false,
1120
+ axisLine: false,
1121
+ allowDecimals: false,
1122
+ tickFormatter: (v) => Math.floor(Number(v) || 0).toLocaleString()
1123
+ }
1124
+ ),
1125
+ /* @__PURE__ */ jsx(
1126
+ YAxis,
1127
+ {
1128
+ yAxisId: "revenue",
1129
+ orientation: "right",
1130
+ width: 42,
1131
+ tick: CHART_AXIS_TICK_SM$1,
1132
+ tickLine: false,
1133
+ axisLine: false,
1134
+ tickFormatter: (v) => formatCompactCurrency$1(Number(v))
1135
+ }
1136
+ ),
1137
+ /* @__PURE__ */ jsx(
1138
+ YAxis,
1139
+ {
1140
+ yAxisId: "aov",
1141
+ orientation: "right",
1142
+ width: 40,
1143
+ tick: CHART_AXIS_TICK_SM$1,
1144
+ tickLine: false,
1145
+ axisLine: false,
1197
1146
  tickFormatter: (v) => formatCompactCurrency$1(Number(v))
1198
1147
  }
1199
1148
  ),
1200
1149
  /* @__PURE__ */ jsx(
1201
1150
  Tooltip,
1202
1151
  {
1203
- content: ({ active, payload, label }) => active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsx(AnalyticsTooltipCard, { variant: "compact", title: String(label), children: payload.map((p) => /* @__PURE__ */ jsxs("div", { children: [
1204
- p.name,
1205
- ":",
1206
- " ",
1207
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(Number(p.value) || 0) })
1208
- ] }, String(p.name))) }) : null
1152
+ content: /* @__PURE__ */ jsx(CombinedMetricsTooltip, {}),
1153
+ cursor: {
1154
+ stroke: "rgba(248, 250, 252, 0.35)",
1155
+ strokeWidth: 1
1156
+ }
1209
1157
  }
1210
1158
  ),
1211
- /* @__PURE__ */ jsx(Legend, { wrapperStyle: { fontSize: 10 }, iconType: "circle" }),
1212
1159
  /* @__PURE__ */ jsx(
1213
- Area,
1160
+ Line,
1214
1161
  {
1162
+ yAxisId: "orders",
1215
1163
  type: "natural",
1216
- dataKey: "revenue_delivered",
1217
- name: "Delivered",
1218
- stackId: "r",
1219
- fill: "#10B981",
1220
- stroke: "#059669",
1221
- fillOpacity: 0.85
1164
+ dataKey: "orders_count",
1165
+ name: "Orders",
1166
+ stroke: "#38BDF8",
1167
+ strokeWidth: 2,
1168
+ dot: false
1222
1169
  }
1223
1170
  ),
1224
1171
  /* @__PURE__ */ jsx(
1225
- Area,
1172
+ Line,
1226
1173
  {
1174
+ yAxisId: "orders",
1227
1175
  type: "natural",
1228
- dataKey: "revenue_open",
1229
- name: "Open / pending",
1230
- stackId: "r",
1231
- fill: "#3B82F6",
1232
- stroke: "#2563eb",
1233
- fillOpacity: 0.85
1176
+ dataKey: "prev_orders",
1177
+ name: "Orders (prev)",
1178
+ stroke: "#64748b",
1179
+ strokeWidth: 1.5,
1180
+ strokeDasharray: "5 4",
1181
+ dot: false
1234
1182
  }
1235
1183
  ),
1236
1184
  /* @__PURE__ */ jsx(
1237
- Area,
1185
+ Line,
1238
1186
  {
1187
+ yAxisId: "revenue",
1239
1188
  type: "natural",
1240
- dataKey: "revenue_cancelled",
1241
- name: "Cancelled",
1242
- stackId: "r",
1243
- fill: "#F87171",
1244
- stroke: "#EF4444",
1245
- fillOpacity: 0.75
1189
+ dataKey: "total_revenue",
1190
+ name: "Revenue",
1191
+ stroke: "#D946EF",
1192
+ strokeWidth: 2,
1193
+ dot: false
1194
+ }
1195
+ ),
1196
+ /* @__PURE__ */ jsx(
1197
+ Line,
1198
+ {
1199
+ yAxisId: "revenue",
1200
+ type: "natural",
1201
+ dataKey: "prev_revenue",
1202
+ name: "Revenue (prev)",
1203
+ stroke: "#64748b",
1204
+ strokeWidth: 1.5,
1205
+ strokeDasharray: "5 4",
1206
+ dot: false
1207
+ }
1208
+ ),
1209
+ /* @__PURE__ */ jsx(
1210
+ Line,
1211
+ {
1212
+ yAxisId: "aov",
1213
+ type: "natural",
1214
+ dataKey: "aov",
1215
+ name: "AOV",
1216
+ stroke: "#D97706",
1217
+ strokeWidth: 2,
1218
+ dot: false
1219
+ }
1220
+ ),
1221
+ /* @__PURE__ */ jsx(
1222
+ Line,
1223
+ {
1224
+ yAxisId: "aov",
1225
+ type: "natural",
1226
+ dataKey: "prev_aov",
1227
+ name: "AOV (prev)",
1228
+ stroke: "#64748b",
1229
+ strokeWidth: 1.5,
1230
+ strokeDasharray: "5 4",
1231
+ dot: false
1246
1232
  }
1247
1233
  )
1248
1234
  ]
1249
1235
  }
1250
1236
  ) }) })
1251
- ] })
1252
- ] }) : null,
1253
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", className: "relative overflow-hidden", children: [
1254
- /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-6 top-0 h-12 rounded-b-full bg-gradient-to-r from-sky-400/10 via-fuchsia-400/10 to-transparent blur-xl" }),
1255
- /* @__PURE__ */ jsxs("div", { className: "relative space-y-1", children: [
1256
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-1.5", children: [
1257
- /* @__PURE__ */ jsxs("div", { className: "space-y-0", children: [
1258
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[10px] font-medium uppercase tracking-[0.16em]", children: "Trend overview" }),
1259
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-base text-sm font-semibold", children: ((_b = OVER_TIME_PERIODS.find((period) => period.value === overTimePeriod)) == null ? void 0 : _b.label) ?? "One week" })
1260
- ] }),
1261
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap justify-end gap-2 text-[10px] text-ui-fg-muted", children: [
1262
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1263
- /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-sky-400" }),
1264
- "Orders"
1265
- ] }),
1266
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1267
- /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-fuchsia-400" }),
1268
- "Revenue"
1269
- ] })
1270
- ] })
1271
- ] }),
1272
- /* @__PURE__ */ jsx("div", { className: "h-[min(200px,30vh)] min-h-[160px] sm:h-[min(216px,32vh)]", children: overTimeLoading ? /* @__PURE__ */ jsx(
1273
- "div",
1274
- {
1275
- className: "flex h-full items-center justify-center",
1276
- role: "status",
1277
- "aria-label": "Loading orders over time",
1278
- children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading chart…" })
1279
- }
1280
- ) : overTimeError ? /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-xs", children: overTimeError }) }) : /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1237
+ ] }),
1238
+ /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", className: "mt-1.5", children: [
1239
+ /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Revenue breakdown (stacked — by order status)" }),
1240
+ /* @__PURE__ */ jsx("div", { className: "h-[min(168px,26vh)] min-h-[140px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1281
1241
  ComposedChart,
1282
1242
  {
1283
1243
  data: dailyOrders,
1284
- margin: { top: 4, right: 6, left: -6, bottom: 0 },
1244
+ margin: { top: 4, right: 8, left: -4, bottom: 0 },
1285
1245
  children: [
1286
- /* @__PURE__ */ jsxs("defs", { children: [
1287
- /* @__PURE__ */ jsxs("linearGradient", { id: "ordersGradient", x1: "0", y1: "0", x2: "1", y2: "0", children: [
1288
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#67E8F9" }),
1289
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#3B82F6" })
1290
- ] }),
1291
- /* @__PURE__ */ jsxs("linearGradient", { id: "revenueGradient", x1: "0", y1: "0", x2: "1", y2: "0", children: [
1292
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#F472B6" }),
1293
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#C084FC" })
1294
- ] }),
1295
- /* @__PURE__ */ jsxs("linearGradient", { id: "ordersAreaFill", x1: "0", y1: "0", x2: "0", y2: "1", children: [
1296
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#38BDF8", stopOpacity: 0.22 }),
1297
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#38BDF8", stopOpacity: 0 })
1298
- ] }),
1299
- /* @__PURE__ */ jsxs("linearGradient", { id: "revenueAreaFill", x1: "0", y1: "0", x2: "0", y2: "1", children: [
1300
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#E879F9", stopOpacity: 0.2 }),
1301
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#E879F9", stopOpacity: 0 })
1302
- ] })
1303
- ] }),
1304
1246
  /* @__PURE__ */ jsx(
1305
1247
  CartesianGrid,
1306
1248
  {
@@ -1325,156 +1267,85 @@ function OrdersDashboard() {
1325
1267
  /* @__PURE__ */ jsx(
1326
1268
  YAxis,
1327
1269
  {
1328
- yAxisId: "orders",
1329
- width: 32,
1330
- tick: CHART_AXIS_TICK$2,
1331
- tickLine: false,
1332
- axisLine: false,
1333
- allowDecimals: false,
1334
- tickFormatter: (value) => Math.floor(Number(value) || 0).toLocaleString()
1335
- }
1336
- ),
1337
- /* @__PURE__ */ jsx(
1338
- YAxis,
1339
- {
1340
- yAxisId: "revenue",
1341
- orientation: "right",
1342
- width: 40,
1343
1270
  tick: CHART_AXIS_TICK$2,
1344
- tickLine: false,
1345
- axisLine: false,
1346
- tickFormatter: (value) => formatCompactCurrency$1(Number(value) || 0)
1271
+ tickFormatter: (v) => formatCompactCurrency$1(Number(v))
1347
1272
  }
1348
1273
  ),
1349
1274
  /* @__PURE__ */ jsx(
1350
1275
  Tooltip,
1351
1276
  {
1352
- content: /* @__PURE__ */ jsx(OrdersTrendTooltip, {}),
1353
- cursor: {
1354
- stroke: "rgba(248, 250, 252, 0.35)",
1355
- strokeWidth: 1
1356
- }
1277
+ content: ({ active, payload, label }) => active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsx(AnalyticsTooltipCard, { variant: "compact", title: String(label), children: payload.map((p) => /* @__PURE__ */ jsxs("div", { children: [
1278
+ p.name,
1279
+ ":",
1280
+ " ",
1281
+ /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(Number(p.value) || 0) })
1282
+ ] }, String(p.name))) }) : null
1357
1283
  }
1358
1284
  ),
1285
+ /* @__PURE__ */ jsx(Legend, { wrapperStyle: { fontSize: 10 }, iconType: "circle" }),
1359
1286
  /* @__PURE__ */ jsx(
1360
1287
  Area,
1361
1288
  {
1362
- yAxisId: "orders",
1363
1289
  type: "natural",
1364
- dataKey: "orders_count",
1365
- stroke: "none",
1366
- fill: "url(#ordersAreaFill)",
1367
- isAnimationActive: false,
1368
- legendType: "none"
1290
+ dataKey: "revenue_delivered",
1291
+ name: "Delivered",
1292
+ stackId: "r",
1293
+ fill: "#10B981",
1294
+ stroke: "#059669",
1295
+ fillOpacity: 0.85
1369
1296
  }
1370
1297
  ),
1371
1298
  /* @__PURE__ */ jsx(
1372
1299
  Area,
1373
1300
  {
1374
- yAxisId: "revenue",
1375
- type: "natural",
1376
- dataKey: "total_revenue",
1377
- stroke: "none",
1378
- fill: "url(#revenueAreaFill)",
1379
- isAnimationActive: false,
1380
- legendType: "none"
1381
- }
1382
- ),
1383
- /* @__PURE__ */ jsx(
1384
- Line,
1385
- {
1386
- yAxisId: "orders",
1387
1301
  type: "natural",
1388
- dataKey: "orders_count",
1389
- name: "Orders",
1390
- stroke: "url(#ordersGradient)",
1391
- strokeWidth: 2,
1392
- dot: false,
1393
- activeDot: { r: 4, fill: STATUS_BAR_COLORS.orders }
1302
+ dataKey: "revenue_open",
1303
+ name: "Open / pending",
1304
+ stackId: "r",
1305
+ fill: "#3B82F6",
1306
+ stroke: "#2563eb",
1307
+ fillOpacity: 0.85
1394
1308
  }
1395
1309
  ),
1396
1310
  /* @__PURE__ */ jsx(
1397
- Line,
1311
+ Area,
1398
1312
  {
1399
- yAxisId: "revenue",
1400
1313
  type: "natural",
1401
- dataKey: "total_revenue",
1402
- name: "Revenue",
1403
- stroke: "url(#revenueGradient)",
1404
- strokeWidth: 2,
1405
- dot: false,
1406
- activeDot: { r: 4, fill: STATUS_BAR_COLORS.revenue }
1314
+ dataKey: "revenue_cancelled",
1315
+ name: "Cancelled",
1316
+ stackId: "r",
1317
+ fill: "#F87171",
1318
+ stroke: "#EF4444",
1319
+ fillOpacity: 0.75
1407
1320
  }
1408
1321
  )
1409
1322
  ]
1410
1323
  }
1411
1324
  ) }) })
1412
1325
  ] })
1413
- ] })
1326
+ ] }) : null
1414
1327
  ] })
1415
1328
  }
1416
1329
  ) }),
1417
1330
  /* @__PURE__ */ jsxs("div", { className: "col-span-12 flex flex-col gap-2 xl:col-span-6", children: [
1418
- /* @__PURE__ */ jsxs(
1331
+ /* @__PURE__ */ jsx(
1419
1332
  AnalyticsSection,
1420
1333
  {
1421
1334
  variant: "atlas",
1422
1335
  title: "Pulse & range",
1423
- description: "Window totals and an orders time series for the selected range.",
1424
- children: [
1425
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2", children: quickPulseMetrics.map((metric) => /* @__PURE__ */ jsxs(
1426
- "div",
1427
- {
1428
- className: `rounded-lg border border-ui-border-base bg-ui-bg-base px-2 py-2 shadow-sm ${metric.accentClassName}`.trim(),
1429
- children: [
1430
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[10px] font-medium uppercase tracking-[0.14em]", children: metric.label }),
1431
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-base mt-0.5 text-sm font-semibold tracking-tight", children: metric.value }),
1432
- /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted mt-0.5 text-[9px] leading-snug", children: metric.helper })
1433
- ]
1434
- },
1435
- metric.label
1436
- )) }),
1437
- !overTimeLoading && !overTimeError && dailyOrders.length > 0 ? /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", className: "mt-1.5", children: [
1438
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Orders (time series)" }),
1439
- /* @__PURE__ */ jsx("div", { className: "h-[76px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1440
- LineChart,
1441
- {
1442
- data: dailyOrders,
1443
- margin: { top: 2, right: 4, left: -18, bottom: 2 },
1444
- children: [
1445
- /* @__PURE__ */ jsx(
1446
- CartesianGrid,
1447
- {
1448
- strokeDasharray: "3 3",
1449
- vertical: false,
1450
- stroke: "rgba(148,163,184,0.12)"
1451
- }
1452
- ),
1453
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
1454
- /* @__PURE__ */ jsx(YAxis, { hide: true, domain: ["auto", "auto"] }),
1455
- /* @__PURE__ */ jsx(
1456
- Tooltip,
1457
- {
1458
- content: /* @__PURE__ */ jsx(OrdersSparklineTooltip, {}),
1459
- cursor: { stroke: "rgba(148,163,184,0.35)", strokeWidth: 1 }
1460
- }
1461
- ),
1462
- /* @__PURE__ */ jsx(
1463
- Line,
1464
- {
1465
- type: "natural",
1466
- dataKey: "orders_count",
1467
- stroke: "#3b82f6",
1468
- strokeWidth: 2,
1469
- dot: { r: 2, fill: "#3b82f6" },
1470
- activeDot: { r: 3 }
1471
- }
1472
- )
1473
- ]
1474
- }
1475
- ) }) })
1476
- ] }) : null
1477
- ]
1336
+ description: "Window totals for the selected range.",
1337
+ children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2", children: quickPulseMetrics.map((metric) => /* @__PURE__ */ jsxs(
1338
+ "div",
1339
+ {
1340
+ className: `rounded-lg border border-ui-border-base bg-ui-bg-base px-2 py-2 shadow-sm ${metric.accentClassName}`.trim(),
1341
+ children: [
1342
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[10px] font-medium uppercase tracking-[0.14em]", children: metric.label }),
1343
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-base mt-0.5 text-sm font-semibold tracking-tight", children: metric.value }),
1344
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted mt-0.5 text-[9px] leading-snug", children: metric.helper })
1345
+ ]
1346
+ },
1347
+ metric.label
1348
+ )) })
1478
1349
  }
1479
1350
  ),
1480
1351
  /* @__PURE__ */ jsx(
@@ -1482,7 +1353,7 @@ function OrdersDashboard() {
1482
1353
  {
1483
1354
  variant: "atlas",
1484
1355
  title: "Order → fulfillment funnel",
1485
- description: `Stages by order created date (UTC), same range as Revenue & orders (${((_c = OVER_TIME_PERIODS.find((p) => p.value === overTimePeriod)) == null ? void 0 : _c.label) ?? "period"}). Not storefront visitors.`,
1356
+ description: `Stages by order created date (UTC), same range as Revenue & orders (${((_b = OVER_TIME_PERIODS.find((p) => p.value === overTimePeriod)) == null ? void 0 : _b.label) ?? "period"}). Not storefront visitors.`,
1486
1357
  children: overTimeLoading ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[120px] items-center justify-center py-3", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading…" }) }) }) : overTimeError ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[120px] items-center justify-center px-2 py-3", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: overTimeError }) }) }) : funnelTimeSeriesRows.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1487
1358
  /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
1488
1359
  /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Stage counts (time series)" }),
@@ -1713,21 +1584,6 @@ function OrdersDashboard() {
1713
1584
  }
1714
1585
  )
1715
1586
  }
1716
- ),
1717
- /* @__PURE__ */ jsx(
1718
- AnalyticsSection,
1719
- {
1720
- variant: "atlas",
1721
- title: "Order revenue (attribution)",
1722
- description: "All revenue is from captured Medusa orders until storefront channel data exists.",
1723
- children: insightsLoading ? /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center py-3", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading…" }) }) : insightsError ? /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center px-2 py-3", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: insightsError }) }) : ordersInsights && ordersInsights.traffic.length > 0 ? trafficTotalRevenue <= 0 ? /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted px-0.5 text-center text-[11px] leading-snug", children: "No recorded revenue in this window (totals may be zero until orders are paid or finalized)." }) : /* @__PURE__ */ jsx(TrafficRevenueDonut, { traffic: ordersInsights.traffic }) : /* @__PURE__ */ jsx(
1724
- EmptyAnalyticsPanel$1,
1725
- {
1726
- title: "No order revenue",
1727
- description: "No orders in this window."
1728
- }
1729
- )
1730
- }
1731
1587
  )
1732
1588
  ] })
1733
1589
  ] }),
@@ -1969,86 +1825,46 @@ function OrdersDashboard() {
1969
1825
  }
1970
1826
  )
1971
1827
  ] }),
1972
- /* @__PURE__ */ jsxs("div", { className: "mt-3 grid grid-cols-1 items-start gap-2 md:grid-cols-3", children: [
1828
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 grid grid-cols-1 items-start gap-3 xl:grid-cols-12", children: [
1973
1829
  /* @__PURE__ */ jsx(
1974
1830
  AnalyticsSection,
1975
1831
  {
1976
1832
  variant: "atlas",
1977
- title: "Sales by weekday",
1978
- description: `Order revenue by UTC weekday — last ${insightsWindowDays} days.`,
1979
- children: insightsLoading ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading…" }) }) }) : insightsError ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center px-2 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: insightsError }) }) }) : weekdayChartRows.length > 0 ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "h-[min(176px,28vh)] min-h-[148px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
1980
- BarChart,
1833
+ className: "xl:col-span-8",
1834
+ title: "Sales breakdown",
1835
+ description: salesBreakdownDescription,
1836
+ actionsBare: true,
1837
+ actions: /* @__PURE__ */ jsx(
1838
+ "div",
1981
1839
  {
1982
- data: weekdayChartRows,
1983
- margin: { top: 2, right: 4, left: -8, bottom: 2 },
1984
- children: [
1985
- /* @__PURE__ */ jsx(
1986
- CartesianGrid,
1987
- {
1988
- strokeDasharray: "3 3",
1989
- vertical: false,
1990
- stroke: "rgba(148,163,184,0.12)"
1991
- }
1992
- ),
1993
- /* @__PURE__ */ jsx(
1994
- XAxis,
1995
- {
1996
- dataKey: "label",
1997
- tick: CHART_AXIS_TICK$2
1998
- }
1999
- ),
2000
- /* @__PURE__ */ jsx(
2001
- YAxis,
2002
- {
2003
- width: 40,
2004
- tick: CHART_AXIS_TICK_SM$1,
2005
- tickFormatter: (v) => formatCompactCurrency$1(Number(v))
2006
- }
2007
- ),
2008
- /* @__PURE__ */ jsx(
2009
- Tooltip,
1840
+ className: "flex flex-wrap items-center gap-1 rounded-lg border border-ui-border-base bg-ui-bg-subtle/40 p-0.5",
1841
+ role: "tablist",
1842
+ "aria-label": "Sales breakdown granularity",
1843
+ children: SALES_GRANULARITY_TABS.map((tab) => {
1844
+ const selected = salesGranularity === tab.value;
1845
+ return /* @__PURE__ */ jsx(
1846
+ "button",
2010
1847
  {
2011
- content: ({ active, payload, label }) => {
2012
- var _a2, _b2;
2013
- return active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: String(label), children: [
2014
- /* @__PURE__ */ jsxs("div", { children: [
2015
- "Revenue:",
2016
- " ",
2017
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(
2018
- Number(
2019
- (_a2 = payload.find((p) => p.dataKey === "revenue")) == null ? void 0 : _a2.value
2020
- ) || 0
2021
- ) })
2022
- ] }),
2023
- /* @__PURE__ */ jsxs("div", { children: [
2024
- "Orders:",
2025
- " ",
2026
- /* @__PURE__ */ jsx("strong", { children: Math.floor(
2027
- Number(
2028
- (_b2 = payload.find((p) => p.dataKey === "orders_count")) == null ? void 0 : _b2.value
2029
- ) || 0
2030
- ).toLocaleString() })
2031
- ] })
2032
- ] }) : null;
2033
- }
2034
- }
2035
- ),
2036
- /* @__PURE__ */ jsx(Bar, { dataKey: "revenue", name: "Revenue", fill: "#D946EF", radius: [4, 4, 0, 0] })
2037
- ]
2038
- }
2039
- ) }) }) }) : /* @__PURE__ */ jsx(
2040
- EmptyAnalyticsPanel$1,
2041
- {
2042
- title: "No weekday data",
2043
- description: "No orders in this window."
1848
+ type: "button",
1849
+ role: "tab",
1850
+ "aria-selected": selected,
1851
+ onClick: () => setSalesGranularity(tab.value),
1852
+ className: `rounded-md px-2.5 py-1.5 text-xs font-medium transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ui-fg-interactive ${selected ? "bg-ui-bg-base text-ui-fg-base shadow-sm" : "text-ui-fg-muted hover:text-ui-fg-base"}`,
1853
+ children: tab.label
1854
+ },
1855
+ tab.value
1856
+ );
1857
+ })
2044
1858
  }
2045
- )
1859
+ ),
1860
+ children: salesBreakdownBody
2046
1861
  }
2047
1862
  ),
2048
1863
  /* @__PURE__ */ jsx(
2049
1864
  AnalyticsSection,
2050
1865
  {
2051
1866
  variant: "atlas",
1867
+ className: "xl:col-span-4",
2052
1868
  title: "Placed orders vs drafts",
2053
1869
  description: "Window order count vs current open draft orders (admin). Not storefront cart abandonment.",
2054
1870
  children: insightsLoading ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading…" }) }) }) : insightsError ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center px-2 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: insightsError }) }) }) : ordersVsDraftsPie.some((s) => s.value > 0) ? /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
@@ -2107,82 +1923,6 @@ function OrdersDashboard() {
2107
1923
  }
2108
1924
  )
2109
1925
  }
2110
- ),
2111
- /* @__PURE__ */ jsx(
2112
- AnalyticsSection,
2113
- {
2114
- variant: "atlas",
2115
- title: "Sales by hour (UTC)",
2116
- description: `Orders created by hour — last ${insightsWindowDays} days.`,
2117
- children: insightsLoading ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading…" }) }) }) : insightsError ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex min-h-[100px] items-center justify-center px-2 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: insightsError }) }) }) : hourlyChartRows.length > 0 ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "h-[min(176px,28vh)] min-h-[148px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
2118
- BarChart,
2119
- {
2120
- data: hourlyChartRows,
2121
- margin: { top: 2, right: 4, left: -8, bottom: 2 },
2122
- children: [
2123
- /* @__PURE__ */ jsx(
2124
- CartesianGrid,
2125
- {
2126
- strokeDasharray: "3 3",
2127
- vertical: false,
2128
- stroke: "rgba(148,163,184,0.12)"
2129
- }
2130
- ),
2131
- /* @__PURE__ */ jsx(
2132
- XAxis,
2133
- {
2134
- dataKey: "label",
2135
- interval: 3,
2136
- tick: CHART_AXIS_TICK_SM$1
2137
- }
2138
- ),
2139
- /* @__PURE__ */ jsx(
2140
- YAxis,
2141
- {
2142
- width: 28,
2143
- tick: CHART_AXIS_TICK$2,
2144
- allowDecimals: false
2145
- }
2146
- ),
2147
- /* @__PURE__ */ jsx(
2148
- Tooltip,
2149
- {
2150
- content: ({ active, payload, label }) => {
2151
- var _a2, _b2;
2152
- return active && (payload == null ? void 0 : payload.length) ? /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: String(label), children: [
2153
- /* @__PURE__ */ jsxs("div", { children: [
2154
- "Orders:",
2155
- " ",
2156
- /* @__PURE__ */ jsx("strong", { children: Math.floor(
2157
- Number(
2158
- (_a2 = payload.find((p) => p.dataKey === "orders_count")) == null ? void 0 : _a2.value
2159
- ) || 0
2160
- ).toLocaleString() })
2161
- ] }),
2162
- /* @__PURE__ */ jsxs("div", { children: [
2163
- "Revenue:",
2164
- " ",
2165
- /* @__PURE__ */ jsx("strong", { children: formatCurrency$1(
2166
- Number(
2167
- (_b2 = payload.find((p) => p.dataKey === "revenue")) == null ? void 0 : _b2.value
2168
- ) || 0
2169
- ) })
2170
- ] })
2171
- ] }) : null;
2172
- }
2173
- }
2174
- ),
2175
- /* @__PURE__ */ jsx(Bar, { dataKey: "orders_count", name: "Orders", fill: "#38BDF8", radius: [4, 4, 0, 0] })
2176
- ]
2177
- }
2178
- ) }) }) }) : /* @__PURE__ */ jsx(
2179
- EmptyAnalyticsPanel$1,
2180
- {
2181
- title: "No hourly data",
2182
- description: "No orders in this window."
2183
- }
2184
- )
2185
- }
2186
1926
  )
2187
1927
  ] })
2188
1928
  ] })
@@ -2808,28 +2548,35 @@ function TrendTooltip({
2808
2548
  function MiniTrendTooltip({
2809
2549
  active,
2810
2550
  payload,
2811
- label
2551
+ label,
2552
+ productHeadline,
2553
+ hideViewsRow,
2554
+ hideUnitsRow,
2555
+ hideRevenueRow
2812
2556
  }) {
2813
2557
  var _a, _b, _c, _d, _e;
2814
2558
  if (!active || !(payload == null ? void 0 : payload.length)) return null;
2815
2559
  const row = isProductOverTimePoint((_a = payload[0]) == null ? void 0 : _a.payload) ? (_b = payload[0]) == null ? void 0 : _b.payload : void 0;
2816
- const displayLabel = (row == null ? void 0 : row.label) ?? (label ? new Date(label).toLocaleDateString() : "");
2560
+ const labelKey = label !== void 0 && label !== null ? String(label) : "";
2561
+ const displayLabel = (row == null ? void 0 : row.label) ?? (labelKey ? new Date(labelKey).toLocaleDateString() : "");
2817
2562
  const unitsSold = ((_c = payload.find((entry) => entry.name === "Units sold")) == null ? void 0 : _c.value) ?? 0;
2818
2563
  const views = ((_d = payload.find((entry) => entry.name === "Views")) == null ? void 0 : _d.value) ?? 0;
2819
2564
  const revenue = ((_e = payload.find((entry) => entry.name === "Revenue")) == null ? void 0 : _e.value) ?? 0;
2820
- return /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title: displayLabel, children: [
2821
- /* @__PURE__ */ jsxs("div", { children: [
2565
+ const title = productHeadline ?? displayLabel;
2566
+ return /* @__PURE__ */ jsxs(AnalyticsTooltipCard, { variant: "compact", title, children: [
2567
+ productHeadline ? /* @__PURE__ */ jsx("div", { className: "mb-1 text-[10px] leading-tight opacity-80", children: displayLabel }) : null,
2568
+ !hideUnitsRow ? /* @__PURE__ */ jsxs("div", { children: [
2822
2569
  "Units sold: ",
2823
2570
  /* @__PURE__ */ jsx("strong", { children: Math.floor(Number(unitsSold)).toLocaleString() })
2824
- ] }),
2825
- /* @__PURE__ */ jsxs("div", { children: [
2571
+ ] }) : null,
2572
+ !hideViewsRow ? /* @__PURE__ */ jsxs("div", { children: [
2826
2573
  "Views: ",
2827
2574
  /* @__PURE__ */ jsx("strong", { children: Math.floor(Number(views)).toLocaleString() })
2828
- ] }),
2829
- /* @__PURE__ */ jsxs("div", { children: [
2575
+ ] }) : null,
2576
+ !hideRevenueRow ? /* @__PURE__ */ jsxs("div", { children: [
2830
2577
  "Revenue: ",
2831
2578
  /* @__PURE__ */ jsx("strong", { children: formatCurrency(Number(revenue)) })
2832
- ] })
2579
+ ] }) : null
2833
2580
  ] });
2834
2581
  }
2835
2582
  function ProductBarTooltip({
@@ -2889,7 +2636,7 @@ function EmptyAnalyticsPanel({ title, description }) {
2889
2636
  ] });
2890
2637
  }
2891
2638
  function ProductsDashboard() {
2892
- var _a, _b, _c, _d, _e;
2639
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2893
2640
  const [summaryDays, setSummaryDays] = useState("all");
2894
2641
  const [graphPeriod, setGraphPeriod] = useState("one_week");
2895
2642
  const [topSellerPeriod, setTopSellerPeriod] = useState("week");
@@ -3016,14 +2763,43 @@ function ProductsDashboard() {
3016
2763
  };
3017
2764
  }, [salesChannelId, topSellerPeriod]);
3018
2765
  useEffect(() => {
2766
+ var _a2, _b2;
3019
2767
  let cancelled = false;
2768
+ if (topSellersLoading) {
2769
+ setBestSellersTrendLoading(true);
2770
+ return () => {
2771
+ cancelled = true;
2772
+ };
2773
+ }
2774
+ if (topSellersError) {
2775
+ setBestSellersTrendLoading(false);
2776
+ setBestSellersTrendError(topSellersError);
2777
+ setBestSellersTrend(null);
2778
+ return () => {
2779
+ cancelled = true;
2780
+ };
2781
+ }
2782
+ const topProductId = (_b2 = (_a2 = topSellers == null ? void 0 : topSellers.products) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.product_id;
2783
+ if (!topProductId) {
2784
+ setBestSellersTrendLoading(false);
2785
+ setBestSellersTrendError(null);
2786
+ setBestSellersTrend({
2787
+ series: [],
2788
+ productViewsConnected: (topSellers == null ? void 0 : topSellers.productViewsConnected) ?? false,
2789
+ product: null
2790
+ });
2791
+ return () => {
2792
+ cancelled = true;
2793
+ };
2794
+ }
3020
2795
  setBestSellersTrendLoading(true);
3021
2796
  setBestSellersTrendError(null);
3022
2797
  const period = topSellerPeriodToGraphPeriod(topSellerPeriod);
3023
2798
  fetch(
3024
2799
  buildAnalyticsUrl("/admin/analytics/products-over-time", {
3025
2800
  period,
3026
- sales_channel_id: salesChannelId !== "all" ? salesChannelId : null
2801
+ sales_channel_id: salesChannelId !== "all" ? salesChannelId : null,
2802
+ product_id: topProductId
3027
2803
  }),
3028
2804
  { credentials: "include" }
3029
2805
  ).then((res) => {
@@ -3041,16 +2817,53 @@ function ProductsDashboard() {
3041
2817
  return () => {
3042
2818
  cancelled = true;
3043
2819
  };
3044
- }, [salesChannelId, topSellerPeriod]);
2820
+ }, [salesChannelId, topSellerPeriod, topSellersLoading, topSellersError, topSellers]);
3045
2821
  useEffect(() => {
2822
+ var _a2, _b2;
3046
2823
  let cancelled = false;
2824
+ if (performanceLoading) {
2825
+ setMostViewedTrendLoading(true);
2826
+ return () => {
2827
+ cancelled = true;
2828
+ };
2829
+ }
2830
+ if (performanceError) {
2831
+ setMostViewedTrendLoading(false);
2832
+ setMostViewedTrendError(performanceError);
2833
+ setMostViewedTrend(null);
2834
+ return () => {
2835
+ cancelled = true;
2836
+ };
2837
+ }
2838
+ if (!(performance == null ? void 0 : performance.productViewsConnected)) {
2839
+ setMostViewedTrendLoading(false);
2840
+ setMostViewedTrendError(null);
2841
+ setMostViewedTrend(null);
2842
+ return () => {
2843
+ cancelled = true;
2844
+ };
2845
+ }
2846
+ const topViewedId = (_b2 = (_a2 = performance.topViewedProducts) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.product_id;
2847
+ if (!topViewedId) {
2848
+ setMostViewedTrendLoading(false);
2849
+ setMostViewedTrendError(null);
2850
+ setMostViewedTrend({
2851
+ series: [],
2852
+ productViewsConnected: true,
2853
+ product: null
2854
+ });
2855
+ return () => {
2856
+ cancelled = true;
2857
+ };
2858
+ }
3047
2859
  setMostViewedTrendLoading(true);
3048
2860
  setMostViewedTrendError(null);
3049
2861
  const period = summaryDaysToGraphPeriod(summaryDays);
3050
2862
  fetch(
3051
2863
  buildAnalyticsUrl("/admin/analytics/products-over-time", {
3052
2864
  period,
3053
- sales_channel_id: salesChannelId !== "all" ? salesChannelId : null
2865
+ sales_channel_id: salesChannelId !== "all" ? salesChannelId : null,
2866
+ product_id: topViewedId
3054
2867
  }),
3055
2868
  { credentials: "include" }
3056
2869
  ).then((res) => {
@@ -3068,7 +2881,7 @@ function ProductsDashboard() {
3068
2881
  return () => {
3069
2882
  cancelled = true;
3070
2883
  };
3071
- }, [salesChannelId, summaryDays]);
2884
+ }, [salesChannelId, summaryDays, performanceLoading, performanceError, performance]);
3072
2885
  useEffect(() => {
3073
2886
  let cancelled = false;
3074
2887
  setPerformanceLoading(true);
@@ -3114,12 +2927,14 @@ function ProductsDashboard() {
3114
2927
  const viewsConnectedForPulse = ((summary == null ? void 0 : summary.productViewsConnected) ?? false) || (overTime == null ? void 0 : overTime.productViewsConnected) === true || (topSellers == null ? void 0 : topSellers.productViewsConnected) === true || (performance == null ? void 0 : performance.productViewsConnected) === true;
3115
2928
  const bestSellersTrendSeries = (bestSellersTrend == null ? void 0 : bestSellersTrend.series) ?? [];
3116
2929
  const mostViewedTrendSeries = (mostViewedTrend == null ? void 0 : mostViewedTrend.series) ?? [];
2930
+ const bestSellerTrendProductTitle = ((_a = bestSellersTrend == null ? void 0 : bestSellersTrend.product) == null ? void 0 : _a.product_title) ?? ((_c = (_b = topSellers == null ? void 0 : topSellers.products) == null ? void 0 : _b[0]) == null ? void 0 : _c.product_title) ?? null;
2931
+ const mostViewedTrendProductTitle = ((_d = mostViewedTrend == null ? void 0 : mostViewedTrend.product) == null ? void 0 : _d.product_title) ?? ((_f = (_e = performance == null ? void 0 : performance.topViewedProducts) == null ? void 0 : _e[0]) == null ? void 0 : _f.product_title) ?? null;
3117
2932
  const viewsVsUnitsScatterData = useMemo(
3118
2933
  () => ((performance == null ? void 0 : performance.topViewedProducts) ?? []).slice(0, 48).filter((row) => row.total_views > 0 || row.units_sold > 0),
3119
2934
  [performance]
3120
2935
  );
3121
- const selectedSummaryPeriod = ((_a = SUMMARY_PERIODS.find((p) => p.value === summaryDays)) == null ? void 0 : _a.label) ?? "All time";
3122
- const selectedGraphPeriodLabel = ((_b = GRAPH_PERIODS.find((p) => p.value === graphPeriod)) == null ? void 0 : _b.label) ?? "One week";
2936
+ const selectedSummaryPeriod = ((_g = SUMMARY_PERIODS.find((p) => p.value === summaryDays)) == null ? void 0 : _g.label) ?? "All time";
2937
+ const selectedGraphPeriodLabel = ((_h = GRAPH_PERIODS.find((p) => p.value === graphPeriod)) == null ? void 0 : _h.label) ?? "One week";
3123
2938
  const quickPulseMetrics = [
3124
2939
  {
3125
2940
  label: "Range units",
@@ -3161,7 +2976,7 @@ function ProductsDashboard() {
3161
2976
  return /* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger", children: summaryError ?? "Failed to load product analytics" }) });
3162
2977
  }
3163
2978
  const viewsConnected = summary.productViewsConnected || (overTime == null ? void 0 : overTime.productViewsConnected) === true || (topSellers == null ? void 0 : topSellers.productViewsConnected) === true || (performance == null ? void 0 : performance.productViewsConnected) === true;
3164
- const selectedChannelLabel = salesChannelId === "all" ? "All channels" : ((_c = salesChannels.find((channel) => channel.id === salesChannelId)) == null ? void 0 : _c.name) ?? "Selected channel";
2979
+ const selectedChannelLabel = salesChannelId === "all" ? "All channels" : ((_i = salesChannels.find((channel) => channel.id === salesChannelId)) == null ? void 0 : _i.name) ?? "Selected channel";
3165
2980
  const primaryStats = [
3166
2981
  {
3167
2982
  label: "Units sold",
@@ -3330,9 +3145,9 @@ function ProductsDashboard() {
3330
3145
  }
3331
3146
  )
3332
3147
  ] }),
3333
- children: /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
3334
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-1.5 sm:grid-cols-3", children: [
3335
- /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
3148
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
3149
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-3 sm:gap-1.5", children: [
3150
+ /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", className: "min-h-0", children: /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
3336
3151
  /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[10px] font-medium uppercase tracking-[0.14em]", children: "Window units" }),
3337
3152
  /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-base text-lg font-semibold tracking-tight", children: formatShortNumber(trendTotals.totalUnits) }),
3338
3153
  /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-muted text-[10px]", children: [
@@ -3340,7 +3155,7 @@ function ProductsDashboard() {
3340
3155
  trendTotals.avgUnitsPerDay.toFixed(1)
3341
3156
  ] })
3342
3157
  ] }) }),
3343
- /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
3158
+ /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", className: "min-h-0", children: /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
3344
3159
  /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[10px] font-medium uppercase tracking-[0.14em]", children: "Window revenue" }),
3345
3160
  /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-base text-lg font-semibold tracking-tight", children: formatCompactCurrency(trendTotals.totalRevenue) }),
3346
3161
  /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-muted text-[10px]", children: [
@@ -3348,7 +3163,7 @@ function ProductsDashboard() {
3348
3163
  formatCompactCurrency(trendTotals.avgRevenuePerDay)
3349
3164
  ] })
3350
3165
  ] }) }),
3351
- /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
3166
+ /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", className: "min-h-0", children: /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
3352
3167
  /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-[10px] font-medium uppercase tracking-[0.14em]", children: "Window views" }),
3353
3168
  /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-base text-lg font-semibold tracking-tight", children: formatShortNumber(trendTotals.totalViews) }),
3354
3169
  /* @__PURE__ */ jsxs(Text, { className: "text-ui-fg-muted text-[10px]", children: [
@@ -3357,131 +3172,6 @@ function ProductsDashboard() {
3357
3172
  ] })
3358
3173
  ] }) })
3359
3174
  ] }),
3360
- !overTimeLoading && !overTimeError && series.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-1.5 md:grid-cols-3", children: [
3361
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
3362
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Units sold" }),
3363
- /* @__PURE__ */ jsx("div", { className: "h-[96px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
3364
- LineChart,
3365
- {
3366
- data: series,
3367
- margin: { top: 4, right: 4, left: 0, bottom: 0 },
3368
- children: [
3369
- /* @__PURE__ */ jsx(
3370
- CartesianGrid,
3371
- {
3372
- strokeDasharray: "3 3",
3373
- vertical: false,
3374
- stroke: "rgba(148,163,184,0.12)"
3375
- }
3376
- ),
3377
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
3378
- /* @__PURE__ */ jsx(
3379
- YAxis,
3380
- {
3381
- width: 28,
3382
- tick: CHART_AXIS_TICK_SM,
3383
- allowDecimals: false
3384
- }
3385
- ),
3386
- /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(MiniTrendTooltip, {}) }),
3387
- /* @__PURE__ */ jsx(
3388
- Line,
3389
- {
3390
- type: "natural",
3391
- dataKey: "units_sold",
3392
- name: "Units sold",
3393
- stroke: PRODUCT_CHART_COLORS.units,
3394
- strokeWidth: 2,
3395
- dot: false
3396
- }
3397
- )
3398
- ]
3399
- }
3400
- ) }) })
3401
- ] }),
3402
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
3403
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Views" }),
3404
- /* @__PURE__ */ jsx("div", { className: "h-[96px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
3405
- LineChart,
3406
- {
3407
- data: series,
3408
- margin: { top: 4, right: 4, left: 0, bottom: 0 },
3409
- children: [
3410
- /* @__PURE__ */ jsx(
3411
- CartesianGrid,
3412
- {
3413
- strokeDasharray: "3 3",
3414
- vertical: false,
3415
- stroke: "rgba(148,163,184,0.12)"
3416
- }
3417
- ),
3418
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
3419
- /* @__PURE__ */ jsx(
3420
- YAxis,
3421
- {
3422
- width: 28,
3423
- tick: CHART_AXIS_TICK_SM,
3424
- allowDecimals: false
3425
- }
3426
- ),
3427
- /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(MiniTrendTooltip, {}) }),
3428
- /* @__PURE__ */ jsx(
3429
- Line,
3430
- {
3431
- type: "natural",
3432
- dataKey: "views",
3433
- name: "Views",
3434
- stroke: PRODUCT_CHART_COLORS.views,
3435
- strokeWidth: 2,
3436
- dot: false
3437
- }
3438
- )
3439
- ]
3440
- }
3441
- ) }) })
3442
- ] }),
3443
- /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", children: [
3444
- /* @__PURE__ */ jsx(Text, { className: "mb-0.5 text-[10px] font-medium uppercase tracking-[0.14em] text-ui-fg-muted", children: "Revenue" }),
3445
- /* @__PURE__ */ jsx("div", { className: "h-[96px] w-full", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
3446
- LineChart,
3447
- {
3448
- data: series,
3449
- margin: { top: 4, right: 4, left: 0, bottom: 0 },
3450
- children: [
3451
- /* @__PURE__ */ jsx(
3452
- CartesianGrid,
3453
- {
3454
- strokeDasharray: "3 3",
3455
- vertical: false,
3456
- stroke: "rgba(148,163,184,0.12)"
3457
- }
3458
- ),
3459
- /* @__PURE__ */ jsx(XAxis, { dataKey: "date", hide: true }),
3460
- /* @__PURE__ */ jsx(
3461
- YAxis,
3462
- {
3463
- width: 36,
3464
- tick: CHART_AXIS_TICK_SM,
3465
- tickFormatter: (v) => formatCompactCurrency(Number(v))
3466
- }
3467
- ),
3468
- /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(MiniTrendTooltip, {}) }),
3469
- /* @__PURE__ */ jsx(
3470
- Line,
3471
- {
3472
- type: "natural",
3473
- dataKey: "revenue",
3474
- name: "Revenue",
3475
- stroke: PRODUCT_CHART_COLORS.revenue,
3476
- strokeWidth: 2,
3477
- dot: false
3478
- }
3479
- )
3480
- ]
3481
- }
3482
- ) }) })
3483
- ] })
3484
- ] }) : null,
3485
3175
  /* @__PURE__ */ jsxs(AnalyticsChartSurface, { variant: "atlas", className: "relative overflow-hidden", children: [
3486
3176
  /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-6 top-0 h-12 rounded-b-full bg-gradient-to-r from-sky-400/10 via-fuchsia-400/10 to-transparent blur-xl" }),
3487
3177
  /* @__PURE__ */ jsxs("div", { className: "relative space-y-1", children: [
@@ -3707,7 +3397,7 @@ function ProductsDashboard() {
3707
3397
  variant: "atlas",
3708
3398
  actionsBare: true,
3709
3399
  title: "Best sellers",
3710
- description: "Total product revenue over time; bucket length matches the leaderboard window (all-time leaderboard uses a 12-month trend).",
3400
+ description: bestSellerTrendProductTitle ? `Revenue and units over time for “${bestSellerTrendProductTitle}” (#1 by revenue in this window; all-time uses a 12‑month chart).` : "Revenue and units over time for the top product by revenue in this window (all-time leaderboard uses a 12month chart).",
3711
3401
  actions: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
3712
3402
  /* @__PURE__ */ jsx(
3713
3403
  Label,
@@ -3783,6 +3473,20 @@ function ProductsDashboard() {
3783
3473
  /* @__PURE__ */ jsx(
3784
3474
  YAxis,
3785
3475
  {
3476
+ yAxisId: "units",
3477
+ tick: CHART_AXIS_TICK_SM,
3478
+ tickFormatter: (value) => formatShortNumber(Number(value)),
3479
+ width: 36,
3480
+ tickLine: false,
3481
+ axisLine: { stroke: CHART_AXIS_LINE },
3482
+ allowDecimals: false
3483
+ }
3484
+ ),
3485
+ /* @__PURE__ */ jsx(
3486
+ YAxis,
3487
+ {
3488
+ yAxisId: "revenue",
3489
+ orientation: "right",
3786
3490
  tick: CHART_AXIS_TICK_SM,
3787
3491
  tickFormatter: (value) => formatCompactCurrency(Number(value)),
3788
3492
  width: 44,
@@ -3790,10 +3494,23 @@ function ProductsDashboard() {
3790
3494
  axisLine: { stroke: CHART_AXIS_LINE }
3791
3495
  }
3792
3496
  ),
3793
- /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(MiniTrendTooltip, {}) }),
3497
+ /* @__PURE__ */ jsx(
3498
+ Tooltip,
3499
+ {
3500
+ content: (tooltipProps) => /* @__PURE__ */ jsx(
3501
+ MiniTrendTooltip,
3502
+ {
3503
+ ...tooltipProps,
3504
+ productHeadline: bestSellerTrendProductTitle,
3505
+ hideViewsRow: true
3506
+ }
3507
+ )
3508
+ }
3509
+ ),
3794
3510
  /* @__PURE__ */ jsx(
3795
3511
  Area,
3796
3512
  {
3513
+ yAxisId: "revenue",
3797
3514
  type: "natural",
3798
3515
  dataKey: "revenue",
3799
3516
  name: "Revenue",
@@ -3805,6 +3522,7 @@ function ProductsDashboard() {
3805
3522
  /* @__PURE__ */ jsx(
3806
3523
  Line,
3807
3524
  {
3525
+ yAxisId: "revenue",
3808
3526
  type: "natural",
3809
3527
  dataKey: "revenue",
3810
3528
  name: "Revenue",
@@ -3814,6 +3532,20 @@ function ProductsDashboard() {
3814
3532
  activeDot: { r: 4, fill: PRODUCT_CHART_COLORS.revenue },
3815
3533
  isAnimationActive: false
3816
3534
  }
3535
+ ),
3536
+ /* @__PURE__ */ jsx(
3537
+ Line,
3538
+ {
3539
+ yAxisId: "units",
3540
+ type: "natural",
3541
+ dataKey: "units_sold",
3542
+ name: "Units sold",
3543
+ stroke: PRODUCT_CHART_COLORS.units,
3544
+ strokeWidth: 2,
3545
+ dot: false,
3546
+ activeDot: { r: 4, fill: PRODUCT_CHART_COLORS.units },
3547
+ isAnimationActive: false
3548
+ }
3817
3549
  )
3818
3550
  ]
3819
3551
  }
@@ -3860,7 +3592,7 @@ function ProductsDashboard() {
3860
3592
  product.product_id
3861
3593
  );
3862
3594
  }) : null,
3863
- !topSellersLoading && !topSellersError && (((_d = topSellers == null ? void 0 : topSellers.products) == null ? void 0 : _d.length) ?? 0) === 0 ? /* @__PURE__ */ jsxs(Table.Row, { children: [
3595
+ !topSellersLoading && !topSellersError && (((_j = topSellers == null ? void 0 : topSellers.products) == null ? void 0 : _j.length) ?? 0) === 0 ? /* @__PURE__ */ jsxs(Table.Row, { children: [
3864
3596
  /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "No best seller data yet." }) }),
3865
3597
  /* @__PURE__ */ jsx(Table.Cell, {}),
3866
3598
  /* @__PURE__ */ jsx(Table.Cell, {}),
@@ -3876,7 +3608,7 @@ function ProductsDashboard() {
3876
3608
  variant: "atlas",
3877
3609
  className: "min-w-0 md:col-span-1 xl:col-span-1",
3878
3610
  title: "Most viewed products",
3879
- description: "Total product views over time; bucket length follows the summary period (today / 7d → week, 30d → month, 90d / all → year view).",
3611
+ description: mostViewedTrendProductTitle ? `Views over time for “${mostViewedTrendProductTitle}” (top of the list for your summary period; buckets follow period: today / 7d → week, 30d → month, 90d / all → year).` : "Views over time for the most-viewed product in your summary period (buckets: today / 7d → week, 30d → month, 90d / all → year).",
3880
3612
  children: performanceLoading ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex h-[212px] items-center justify-center sm:h-[228px]", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "Loading…" }) }) }) : performanceError ? /* @__PURE__ */ jsx(AnalyticsChartSurface, { variant: "atlas", children: /* @__PURE__ */ jsx("div", { className: "flex h-[212px] items-center justify-center px-2 sm:h-[228px]", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger text-center text-xs", children: performanceError }) }) }) : !(performance == null ? void 0 : performance.productViewsConnected) ? /* @__PURE__ */ jsx("div", { className: "min-h-[212px] sm:min-h-[228px]", children: /* @__PURE__ */ jsx(
3881
3613
  EmptyAnalyticsPanel,
3882
3614
  {
@@ -3952,7 +3684,20 @@ function ProductsDashboard() {
3952
3684
  allowDecimals: false
3953
3685
  }
3954
3686
  ),
3955
- /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(MiniTrendTooltip, {}) }),
3687
+ /* @__PURE__ */ jsx(
3688
+ Tooltip,
3689
+ {
3690
+ content: (tooltipProps) => /* @__PURE__ */ jsx(
3691
+ MiniTrendTooltip,
3692
+ {
3693
+ ...tooltipProps,
3694
+ productHeadline: mostViewedTrendProductTitle,
3695
+ hideUnitsRow: true,
3696
+ hideRevenueRow: true
3697
+ }
3698
+ )
3699
+ }
3700
+ ),
3956
3701
  /* @__PURE__ */ jsx(
3957
3702
  Area,
3958
3703
  {
@@ -4003,7 +3748,7 @@ function ProductsDashboard() {
4003
3748
  /* @__PURE__ */ jsx(Table.Cell, { children: product.units_sold.toLocaleString() }),
4004
3749
  /* @__PURE__ */ jsx(Table.Cell, { children: formatRatio(product.views_per_unit) })
4005
3750
  ] }, product.product_id)),
4006
- !performanceLoading && !performanceError && (((_e = performance == null ? void 0 : performance.viewOpportunities) == null ? void 0 : _e.length) ?? 0) === 0 ? /* @__PURE__ */ jsxs(Table.Row, { children: [
3751
+ !performanceLoading && !performanceError && (((_k = performance == null ? void 0 : performance.viewOpportunities) == null ? void 0 : _k.length) ?? 0) === 0 ? /* @__PURE__ */ jsxs(Table.Row, { children: [
4007
3752
  /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-xs", children: "No product view opportunities yet." }) }),
4008
3753
  /* @__PURE__ */ jsx(Table.Cell, {}),
4009
3754
  /* @__PURE__ */ jsx(Table.Cell, {}),