medusa-analytics 0.0.2 → 0.0.3

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.
@@ -29,25 +29,32 @@ function formatCurrency(value) {
29
29
  maximumFractionDigits: 0
30
30
  }).format(value);
31
31
  }
32
+ const SUMMARY_PERIODS = [
33
+ { value: "0", label: "Today's orders" },
34
+ { value: "7", label: "Last 7 days" },
35
+ { value: "30", label: "Last 30 days" },
36
+ { value: "90", label: "Last 90 days" }
37
+ ];
38
+ const OVER_TIME_PERIODS = [
39
+ { value: "1d", label: "1 day" },
40
+ { value: "7d", label: "1 week" },
41
+ { value: "30d", label: "1 month" }
42
+ ];
32
43
  function OrdersDashboard() {
33
44
  const [data, setData] = react.useState(null);
34
45
  const [loading, setLoading] = react.useState(true);
35
46
  const [error, setError] = react.useState(null);
36
47
  const [filter, setFilter] = react.useState("7");
48
+ const [dailyOrders, setDailyOrders] = react.useState([]);
49
+ const [overTimePeriod, setOverTimePeriod] = react.useState("7d");
50
+ const [overTimeLoading, setOverTimeLoading] = react.useState(true);
51
+ const [overTimeError, setOverTimeError] = react.useState(null);
37
52
  react.useEffect(() => {
38
53
  let cancelled = false;
39
54
  setLoading(true);
40
55
  setError(null);
41
56
  const url = `/admin/analytics/orders-summary?days=${filter}`;
42
- if (typeof fetch !== "undefined") {
43
- fetch("http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288", { method: "POST", headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "21bff8" }, body: JSON.stringify({ sessionId: "21bff8", location: "OrdersDashboard.tsx:useEffect", message: "OrdersDashboard fetch", data: { filter, url }, timestamp: Date.now(), hypothesisId: "C" }) }).catch(() => {
44
- });
45
- }
46
57
  fetch(url).then((res) => {
47
- if (typeof fetch !== "undefined") {
48
- fetch("http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288", { method: "POST", headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "21bff8" }, body: JSON.stringify({ sessionId: "21bff8", location: "OrdersDashboard.tsx:fetch.then", message: "API response", data: { status: res.status, statusText: res.statusText, url: res.url }, timestamp: Date.now(), hypothesisId: "C" }) }).catch(() => {
49
- });
50
- }
51
58
  if (!res.ok) throw new Error(res.statusText);
52
59
  return res.json();
53
60
  }).then((body) => {
@@ -61,6 +68,25 @@ function OrdersDashboard() {
61
68
  cancelled = true;
62
69
  };
63
70
  }, [filter]);
71
+ react.useEffect(() => {
72
+ let cancelled = false;
73
+ setOverTimeLoading(true);
74
+ setOverTimeError(null);
75
+ const url = `/admin/analytics/orders-over-time?period=${overTimePeriod}`;
76
+ fetch(url).then((res) => {
77
+ if (!res.ok) throw new Error(res.statusText);
78
+ return res.json();
79
+ }).then((body) => {
80
+ if (!cancelled) setDailyOrders(body.dailyOrders ?? []);
81
+ }).catch((e) => {
82
+ if (!cancelled) setOverTimeError(e instanceof Error ? e.message : String(e));
83
+ }).finally(() => {
84
+ if (!cancelled) setOverTimeLoading(false);
85
+ });
86
+ return () => {
87
+ cancelled = true;
88
+ };
89
+ }, [overTimePeriod]);
64
90
  if (loading) {
65
91
  return /* @__PURE__ */ jsxRuntime.jsx(
66
92
  "div",
@@ -85,24 +111,19 @@ function OrdersDashboard() {
85
111
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-8", children: [
86
112
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
87
113
  /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Orders Analytics" }),
88
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
114
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
89
115
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "analytics-period", className: "text-ui-fg-muted text-sm", children: "Period" }),
90
- /* @__PURE__ */ jsxRuntime.jsxs(
116
+ /* @__PURE__ */ jsxRuntime.jsx(
91
117
  "select",
92
118
  {
93
119
  id: "analytics-period",
94
120
  value: filter,
95
121
  onChange: (e) => setFilter(e.target.value),
96
122
  className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive",
97
- children: [
98
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "0", children: "Today's orders" }),
99
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "7", children: "Last 7 days" }),
100
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "30", children: "Last 30 days" }),
101
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "90", children: "Last 90 days" })
102
- ]
123
+ children: SUMMARY_PERIODS.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.value, children: p.label }, p.value))
103
124
  }
104
125
  )
105
- ] })
126
+ ] }) })
106
127
  ] }),
107
128
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4", children: [
108
129
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-4", children: [
@@ -133,11 +154,56 @@ function OrdersDashboard() {
133
154
  ] })
134
155
  ] }),
135
156
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-6", children: [
136
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mb-4", children: "Orders over time" }),
137
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-72", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
157
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mb-4", children: "Orders by status" }),
158
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-72", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
159
+ /* @__PURE__ */ jsxRuntime.jsx(
160
+ recharts.Pie,
161
+ {
162
+ data: pieData,
163
+ cx: "50%",
164
+ cy: "50%",
165
+ innerRadius: 60,
166
+ outerRadius: 100,
167
+ paddingAngle: 2,
168
+ dataKey: "value",
169
+ nameKey: "name",
170
+ label: ({ name, value }) => `${name}: ${value}`,
171
+ children: pieData.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: entry.color }, `cell-${index}`))
172
+ }
173
+ ),
174
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { formatter: (value) => [value ?? 0, "Orders"] }),
175
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {})
176
+ ] }) }) })
177
+ ] }),
178
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-6", children: [
179
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 mb-4", children: [
180
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", children: "Orders over time" }),
181
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
182
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "over-time-period", className: "text-ui-fg-muted text-sm", children: "Range" }),
183
+ /* @__PURE__ */ jsxRuntime.jsx(
184
+ "select",
185
+ {
186
+ id: "over-time-period",
187
+ value: overTimePeriod,
188
+ onChange: (e) => setOverTimePeriod(e.target.value),
189
+ className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive",
190
+ children: OVER_TIME_PERIODS.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.value, children: p.label }, p.value))
191
+ }
192
+ )
193
+ ] })
194
+ ] }),
195
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-72", children: overTimeLoading ? /* @__PURE__ */ jsxRuntime.jsx(
196
+ "div",
197
+ {
198
+ className: "flex items-center justify-center h-full",
199
+ role: "status",
200
+ "aria-label": "Loading orders over time",
201
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted", children: "Loading chart…" })
202
+ }
203
+ ) : overTimeError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-danger", children: overTimeError }) }) : /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
138
204
  recharts.LineChart,
139
205
  {
140
- data: data.dailyOrders,
206
+ data: dailyOrders,
141
207
  margin: { top: 8, right: 8, left: 8, bottom: 8 },
142
208
  children: [
143
209
  /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { strokeDasharray: "3 3", className: "stroke-ui-border-base" }),
@@ -174,28 +240,6 @@ function OrdersDashboard() {
174
240
  ]
175
241
  }
176
242
  ) }) })
177
- ] }),
178
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-6", children: [
179
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mb-4", children: "Orders by status" }),
180
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-72", children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
181
- /* @__PURE__ */ jsxRuntime.jsx(
182
- recharts.Pie,
183
- {
184
- data: pieData,
185
- cx: "50%",
186
- cy: "50%",
187
- innerRadius: 60,
188
- outerRadius: 100,
189
- paddingAngle: 2,
190
- dataKey: "value",
191
- nameKey: "name",
192
- label: ({ name, value }) => `${name}: ${value}`,
193
- children: pieData.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: entry.color }, `cell-${index}`))
194
- }
195
- ),
196
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { formatter: (value) => [value ?? 0, "Orders"] }),
197
- /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, {})
198
- ] }) }) })
199
243
  ] })
200
244
  ] });
201
245
  }
@@ -203,13 +247,23 @@ const ANALYTICS_MODULES = [{ id: "orders", label: "Orders" }];
203
247
  const PLUGIN_VERSION = "0.2";
204
248
  const AnalyticsPage = () => {
205
249
  const [activeModule, setActiveModule] = react.useState("orders");
206
- if (typeof fetch !== "undefined") {
207
- fetch("http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288", { method: "POST", headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "21bff8" }, body: JSON.stringify({ sessionId: "21bff8", location: "page.tsx:AnalyticsPage", message: "Analytics page mounted", data: { pluginVersion: PLUGIN_VERSION, activeModule }, timestamp: Date.now(), hypothesisId: "A" }) }).catch(() => {
208
- });
209
- }
250
+ const [sidebarOpen, setSidebarOpen] = react.useState(false);
210
251
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full bg-ui-bg-base", children: [
211
- /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "w-56 shrink-0 border-r border-ui-border-base bg-ui-bg-subtle p-4 flex flex-col", children: [
212
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mb-3 text-ui-fg-subtle", children: "Analysis" }),
252
+ sidebarOpen && /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "w-56 shrink-0 border-r border-ui-border-base bg-ui-bg-subtle p-4 flex flex-col relative", children: [
253
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
254
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-ui-fg-subtle", children: "Analysis" }),
255
+ /* @__PURE__ */ jsxRuntime.jsx(
256
+ ui.Button,
257
+ {
258
+ variant: "transparent",
259
+ size: "small",
260
+ className: "shrink-0",
261
+ onClick: () => setSidebarOpen(false),
262
+ "aria-label": "Close sidebar",
263
+ children: "×"
264
+ }
265
+ )
266
+ ] }),
213
267
  /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex flex-col gap-1 flex-1", children: ANALYTICS_MODULES.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
214
268
  ui.Button,
215
269
  {
@@ -225,6 +279,16 @@ const AnalyticsPage = () => {
225
279
  PLUGIN_VERSION
226
280
  ] })
227
281
  ] }),
282
+ !sidebarOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-r border-ui-border-base p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
283
+ ui.Button,
284
+ {
285
+ variant: "secondary",
286
+ size: "small",
287
+ onClick: () => setSidebarOpen(true),
288
+ "aria-label": "Show sidebar",
289
+ children: "Analysis"
290
+ }
291
+ ) }),
228
292
  /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-6 px-6", children: activeModule === "orders" && /* @__PURE__ */ jsxRuntime.jsx(OrdersDashboard, {}) }) }) })
229
293
  ] });
230
294
  };
@@ -3,7 +3,7 @@ import { useState, useEffect } from "react";
3
3
  import { defineRouteConfig } from "@medusajs/admin-sdk";
4
4
  import { ChartBar } from "@medusajs/icons";
5
5
  import { Text, Container, Heading, Label, Button } from "@medusajs/ui";
6
- import { ResponsiveContainer, LineChart, CartesianGrid, XAxis, YAxis, Tooltip, Line, PieChart, Pie, Cell, Legend } from "recharts";
6
+ import { ResponsiveContainer, PieChart, Pie, Cell, Tooltip, Legend, LineChart, CartesianGrid, XAxis, YAxis, Line } from "recharts";
7
7
  const STATUS_COLORS = {
8
8
  pending: "#F59E0B",
9
9
  confirmed: "#3B82F6",
@@ -28,25 +28,32 @@ function formatCurrency(value) {
28
28
  maximumFractionDigits: 0
29
29
  }).format(value);
30
30
  }
31
+ const SUMMARY_PERIODS = [
32
+ { value: "0", label: "Today's orders" },
33
+ { value: "7", label: "Last 7 days" },
34
+ { value: "30", label: "Last 30 days" },
35
+ { value: "90", label: "Last 90 days" }
36
+ ];
37
+ const OVER_TIME_PERIODS = [
38
+ { value: "1d", label: "1 day" },
39
+ { value: "7d", label: "1 week" },
40
+ { value: "30d", label: "1 month" }
41
+ ];
31
42
  function OrdersDashboard() {
32
43
  const [data, setData] = useState(null);
33
44
  const [loading, setLoading] = useState(true);
34
45
  const [error, setError] = useState(null);
35
46
  const [filter, setFilter] = useState("7");
47
+ const [dailyOrders, setDailyOrders] = useState([]);
48
+ const [overTimePeriod, setOverTimePeriod] = useState("7d");
49
+ const [overTimeLoading, setOverTimeLoading] = useState(true);
50
+ const [overTimeError, setOverTimeError] = useState(null);
36
51
  useEffect(() => {
37
52
  let cancelled = false;
38
53
  setLoading(true);
39
54
  setError(null);
40
55
  const url = `/admin/analytics/orders-summary?days=${filter}`;
41
- if (typeof fetch !== "undefined") {
42
- fetch("http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288", { method: "POST", headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "21bff8" }, body: JSON.stringify({ sessionId: "21bff8", location: "OrdersDashboard.tsx:useEffect", message: "OrdersDashboard fetch", data: { filter, url }, timestamp: Date.now(), hypothesisId: "C" }) }).catch(() => {
43
- });
44
- }
45
56
  fetch(url).then((res) => {
46
- if (typeof fetch !== "undefined") {
47
- fetch("http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288", { method: "POST", headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "21bff8" }, body: JSON.stringify({ sessionId: "21bff8", location: "OrdersDashboard.tsx:fetch.then", message: "API response", data: { status: res.status, statusText: res.statusText, url: res.url }, timestamp: Date.now(), hypothesisId: "C" }) }).catch(() => {
48
- });
49
- }
50
57
  if (!res.ok) throw new Error(res.statusText);
51
58
  return res.json();
52
59
  }).then((body) => {
@@ -60,6 +67,25 @@ function OrdersDashboard() {
60
67
  cancelled = true;
61
68
  };
62
69
  }, [filter]);
70
+ useEffect(() => {
71
+ let cancelled = false;
72
+ setOverTimeLoading(true);
73
+ setOverTimeError(null);
74
+ const url = `/admin/analytics/orders-over-time?period=${overTimePeriod}`;
75
+ fetch(url).then((res) => {
76
+ if (!res.ok) throw new Error(res.statusText);
77
+ return res.json();
78
+ }).then((body) => {
79
+ if (!cancelled) setDailyOrders(body.dailyOrders ?? []);
80
+ }).catch((e) => {
81
+ if (!cancelled) setOverTimeError(e instanceof Error ? e.message : String(e));
82
+ }).finally(() => {
83
+ if (!cancelled) setOverTimeLoading(false);
84
+ });
85
+ return () => {
86
+ cancelled = true;
87
+ };
88
+ }, [overTimePeriod]);
63
89
  if (loading) {
64
90
  return /* @__PURE__ */ jsx(
65
91
  "div",
@@ -84,24 +110,19 @@ function OrdersDashboard() {
84
110
  return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
85
111
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
86
112
  /* @__PURE__ */ jsx(Heading, { level: "h1", children: "Orders Analytics" }),
87
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
113
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
88
114
  /* @__PURE__ */ jsx(Label, { htmlFor: "analytics-period", className: "text-ui-fg-muted text-sm", children: "Period" }),
89
- /* @__PURE__ */ jsxs(
115
+ /* @__PURE__ */ jsx(
90
116
  "select",
91
117
  {
92
118
  id: "analytics-period",
93
119
  value: filter,
94
120
  onChange: (e) => setFilter(e.target.value),
95
121
  className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive",
96
- children: [
97
- /* @__PURE__ */ jsx("option", { value: "0", children: "Today's orders" }),
98
- /* @__PURE__ */ jsx("option", { value: "7", children: "Last 7 days" }),
99
- /* @__PURE__ */ jsx("option", { value: "30", children: "Last 30 days" }),
100
- /* @__PURE__ */ jsx("option", { value: "90", children: "Last 90 days" })
101
- ]
122
+ children: SUMMARY_PERIODS.map((p) => /* @__PURE__ */ jsx("option", { value: p.value, children: p.label }, p.value))
102
123
  }
103
124
  )
104
- ] })
125
+ ] }) })
105
126
  ] }),
106
127
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4", children: [
107
128
  /* @__PURE__ */ jsxs(Container, { className: "p-4", children: [
@@ -132,11 +153,56 @@ function OrdersDashboard() {
132
153
  ] })
133
154
  ] }),
134
155
  /* @__PURE__ */ jsxs(Container, { className: "p-6", children: [
135
- /* @__PURE__ */ jsx(Heading, { level: "h3", className: "mb-4", children: "Orders over time" }),
136
- /* @__PURE__ */ jsx("div", { className: "h-72", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
156
+ /* @__PURE__ */ jsx(Heading, { level: "h3", className: "mb-4", children: "Orders by status" }),
157
+ /* @__PURE__ */ jsx("div", { className: "h-72", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { children: [
158
+ /* @__PURE__ */ jsx(
159
+ Pie,
160
+ {
161
+ data: pieData,
162
+ cx: "50%",
163
+ cy: "50%",
164
+ innerRadius: 60,
165
+ outerRadius: 100,
166
+ paddingAngle: 2,
167
+ dataKey: "value",
168
+ nameKey: "name",
169
+ label: ({ name, value }) => `${name}: ${value}`,
170
+ children: pieData.map((entry, index) => /* @__PURE__ */ jsx(Cell, { fill: entry.color }, `cell-${index}`))
171
+ }
172
+ ),
173
+ /* @__PURE__ */ jsx(Tooltip, { formatter: (value) => [value ?? 0, "Orders"] }),
174
+ /* @__PURE__ */ jsx(Legend, {})
175
+ ] }) }) })
176
+ ] }),
177
+ /* @__PURE__ */ jsxs(Container, { className: "p-6", children: [
178
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 mb-4", children: [
179
+ /* @__PURE__ */ jsx(Heading, { level: "h3", children: "Orders over time" }),
180
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
181
+ /* @__PURE__ */ jsx(Label, { htmlFor: "over-time-period", className: "text-ui-fg-muted text-sm", children: "Range" }),
182
+ /* @__PURE__ */ jsx(
183
+ "select",
184
+ {
185
+ id: "over-time-period",
186
+ value: overTimePeriod,
187
+ onChange: (e) => setOverTimePeriod(e.target.value),
188
+ className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive",
189
+ children: OVER_TIME_PERIODS.map((p) => /* @__PURE__ */ jsx("option", { value: p.value, children: p.label }, p.value))
190
+ }
191
+ )
192
+ ] })
193
+ ] }),
194
+ /* @__PURE__ */ jsx("div", { className: "h-72", children: overTimeLoading ? /* @__PURE__ */ jsx(
195
+ "div",
196
+ {
197
+ className: "flex items-center justify-center h-full",
198
+ role: "status",
199
+ "aria-label": "Loading orders over time",
200
+ children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted", children: "Loading chart…" })
201
+ }
202
+ ) : overTimeError ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-danger", children: overTimeError }) }) : /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
137
203
  LineChart,
138
204
  {
139
- data: data.dailyOrders,
205
+ data: dailyOrders,
140
206
  margin: { top: 8, right: 8, left: 8, bottom: 8 },
141
207
  children: [
142
208
  /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", className: "stroke-ui-border-base" }),
@@ -173,28 +239,6 @@ function OrdersDashboard() {
173
239
  ]
174
240
  }
175
241
  ) }) })
176
- ] }),
177
- /* @__PURE__ */ jsxs(Container, { className: "p-6", children: [
178
- /* @__PURE__ */ jsx(Heading, { level: "h3", className: "mb-4", children: "Orders by status" }),
179
- /* @__PURE__ */ jsx("div", { className: "h-72", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { children: [
180
- /* @__PURE__ */ jsx(
181
- Pie,
182
- {
183
- data: pieData,
184
- cx: "50%",
185
- cy: "50%",
186
- innerRadius: 60,
187
- outerRadius: 100,
188
- paddingAngle: 2,
189
- dataKey: "value",
190
- nameKey: "name",
191
- label: ({ name, value }) => `${name}: ${value}`,
192
- children: pieData.map((entry, index) => /* @__PURE__ */ jsx(Cell, { fill: entry.color }, `cell-${index}`))
193
- }
194
- ),
195
- /* @__PURE__ */ jsx(Tooltip, { formatter: (value) => [value ?? 0, "Orders"] }),
196
- /* @__PURE__ */ jsx(Legend, {})
197
- ] }) }) })
198
242
  ] })
199
243
  ] });
200
244
  }
@@ -202,13 +246,23 @@ const ANALYTICS_MODULES = [{ id: "orders", label: "Orders" }];
202
246
  const PLUGIN_VERSION = "0.2";
203
247
  const AnalyticsPage = () => {
204
248
  const [activeModule, setActiveModule] = useState("orders");
205
- if (typeof fetch !== "undefined") {
206
- fetch("http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288", { method: "POST", headers: { "Content-Type": "application/json", "X-Debug-Session-Id": "21bff8" }, body: JSON.stringify({ sessionId: "21bff8", location: "page.tsx:AnalyticsPage", message: "Analytics page mounted", data: { pluginVersion: PLUGIN_VERSION, activeModule }, timestamp: Date.now(), hypothesisId: "A" }) }).catch(() => {
207
- });
208
- }
249
+ const [sidebarOpen, setSidebarOpen] = useState(false);
209
250
  return /* @__PURE__ */ jsxs("div", { className: "flex h-full bg-ui-bg-base", children: [
210
- /* @__PURE__ */ jsxs("aside", { className: "w-56 shrink-0 border-r border-ui-border-base bg-ui-bg-subtle p-4 flex flex-col", children: [
211
- /* @__PURE__ */ jsx(Heading, { level: "h3", className: "mb-3 text-ui-fg-subtle", children: "Analysis" }),
251
+ sidebarOpen && /* @__PURE__ */ jsxs("aside", { className: "w-56 shrink-0 border-r border-ui-border-base bg-ui-bg-subtle p-4 flex flex-col relative", children: [
252
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
253
+ /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-ui-fg-subtle", children: "Analysis" }),
254
+ /* @__PURE__ */ jsx(
255
+ Button,
256
+ {
257
+ variant: "transparent",
258
+ size: "small",
259
+ className: "shrink-0",
260
+ onClick: () => setSidebarOpen(false),
261
+ "aria-label": "Close sidebar",
262
+ children: "×"
263
+ }
264
+ )
265
+ ] }),
212
266
  /* @__PURE__ */ jsx("nav", { className: "flex flex-col gap-1 flex-1", children: ANALYTICS_MODULES.map((m) => /* @__PURE__ */ jsx(
213
267
  Button,
214
268
  {
@@ -224,6 +278,16 @@ const AnalyticsPage = () => {
224
278
  PLUGIN_VERSION
225
279
  ] })
226
280
  ] }),
281
+ !sidebarOpen && /* @__PURE__ */ jsx("div", { className: "shrink-0 border-r border-ui-border-base p-2", children: /* @__PURE__ */ jsx(
282
+ Button,
283
+ {
284
+ variant: "secondary",
285
+ size: "small",
286
+ onClick: () => setSidebarOpen(true),
287
+ "aria-label": "Show sidebar",
288
+ children: "Analysis"
289
+ }
290
+ ) }),
227
291
  /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsx(Container, { className: "divide-y p-0", children: /* @__PURE__ */ jsx("div", { className: "py-6 px-6", children: activeModule === "orders" && /* @__PURE__ */ jsx(OrdersDashboard, {}) }) }) })
228
292
  ] });
229
293
  };
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const ALLOWED_PERIODS = ["1d", "7d", "30d"];
6
+ function toDateKey(d) {
7
+ return d.toISOString().slice(0, 10);
8
+ }
9
+ function getDaysForPeriod(period) {
10
+ switch (period) {
11
+ case "1d":
12
+ return 1;
13
+ case "7d":
14
+ return 7;
15
+ case "30d":
16
+ return 30;
17
+ default:
18
+ return 7;
19
+ }
20
+ }
21
+ async function GET(req, res) {
22
+ const remoteQuery = req.scope.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
23
+ const periodParam = req.query?.period;
24
+ const period = typeof periodParam === "string" && ALLOWED_PERIODS.includes(periodParam)
25
+ ? periodParam
26
+ : "7d";
27
+ const days = getDaysForPeriod(period);
28
+ const today = new Date();
29
+ today.setUTCHours(0, 0, 0, 0);
30
+ const rangeStart = new Date(today);
31
+ rangeStart.setUTCDate(rangeStart.getUTCDate() - (days - 1));
32
+ rangeStart.setUTCHours(0, 0, 0, 0);
33
+ const rangeEnd = new Date(today);
34
+ rangeEnd.setUTCHours(23, 59, 59, 999);
35
+ try {
36
+ const queryObject = (0, utils_1.remoteQueryObjectFromString)({
37
+ entryPoint: "order",
38
+ fields: ["id", "created_at"],
39
+ take: 50000,
40
+ });
41
+ const ordersRaw = await remoteQuery(queryObject);
42
+ const allOrders = Array.isArray(ordersRaw) ? ordersRaw : ordersRaw ? [ordersRaw] : [];
43
+ const dailyMap = {};
44
+ for (const order of allOrders) {
45
+ const o = order;
46
+ const createdAt = o.created_at ? new Date(o.created_at) : null;
47
+ const dateKey = createdAt ? toDateKey(createdAt) : null;
48
+ if (createdAt &&
49
+ dateKey &&
50
+ createdAt >= rangeStart &&
51
+ createdAt <= rangeEnd) {
52
+ dailyMap[dateKey] = (dailyMap[dateKey] ?? 0) + 1;
53
+ }
54
+ }
55
+ const dailyOrders = [];
56
+ for (let i = 0; i < days; i++) {
57
+ const d = new Date(rangeStart);
58
+ d.setUTCDate(d.getUTCDate() + i);
59
+ const key = toDateKey(d);
60
+ dailyOrders.push({
61
+ date: key,
62
+ orders_count: dailyMap[key] ?? 0,
63
+ });
64
+ }
65
+ dailyOrders.sort((a, b) => a.date.localeCompare(b.date));
66
+ const body = { dailyOrders };
67
+ res.json(body);
68
+ }
69
+ catch (err) {
70
+ console.error("Orders over time analytics error:", err);
71
+ res.status(500).json({
72
+ error: "Failed to fetch orders over time",
73
+ message: err instanceof Error ? err.message : String(err),
74
+ });
75
+ }
76
+ }
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FuYWx5dGljcy9vcmRlcnMtb3Zlci10aW1lL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBOEJBLGtCQTBFQztBQWxHRCxxREFBa0c7QUFJbEcsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBVSxDQUFBO0FBR3BELFNBQVMsU0FBUyxDQUFDLENBQU87SUFDeEIsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUNyQyxDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFjO0lBQ3RDLFFBQVEsTUFBTSxFQUFFLENBQUM7UUFDZixLQUFLLElBQUk7WUFDUCxPQUFPLENBQUMsQ0FBQTtRQUNWLEtBQUssSUFBSTtZQUNQLE9BQU8sQ0FBQyxDQUFBO1FBQ1YsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLENBQUE7UUFDWDtZQUNFLE9BQU8sQ0FBQyxDQUFBO0lBQ1osQ0FBQztBQUNILENBQUM7QUFFTSxLQUFLLFVBQVUsR0FBRyxDQUN2QixHQUFrQixFQUNsQixHQUFtQjtJQUVuQixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FDbkMsaUNBQXlCLENBQUMsWUFBWSxDQUN2QyxDQUFBO0lBRUQsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUE7SUFDckMsTUFBTSxNQUFNLEdBQ1YsT0FBTyxXQUFXLEtBQUssUUFBUSxJQUFJLGVBQWUsQ0FBQyxRQUFRLENBQUMsV0FBcUIsQ0FBQztRQUNoRixDQUFDLENBQUUsV0FBc0I7UUFDekIsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUVWLE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBRXJDLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUE7SUFDeEIsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUU3QixNQUFNLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNsQyxVQUFVLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQzNELFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFFbEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUVyQyxJQUFJLENBQUM7UUFDSCxNQUFNLFdBQVcsR0FBRyxJQUFBLG1DQUEyQixFQUFDO1lBQzlDLFVBQVUsRUFBRSxPQUFPO1lBQ25CLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxZQUFZLENBQUM7WUFDNUIsSUFBSSxFQUFFLEtBQUs7U0FDWixDQUFDLENBQUE7UUFFRixNQUFNLFNBQVMsR0FBRyxNQUFNLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUNoRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO1FBRXJGLE1BQU0sUUFBUSxHQUEyQixFQUFFLENBQUE7UUFFM0MsS0FBSyxNQUFNLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUM5QixNQUFNLENBQUMsR0FBRyxLQUFvRCxDQUFBO1lBQzlELE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFBO1lBQzlELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7WUFFdkQsSUFDRSxTQUFTO2dCQUNULE9BQU87Z0JBQ1AsU0FBUyxJQUFJLFVBQVU7Z0JBQ3ZCLFNBQVMsSUFBSSxRQUFRLEVBQ3JCLENBQUM7Z0JBQ0QsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNsRCxDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFvQixFQUFFLENBQUE7UUFDdkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzlCLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQ2hDLE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN4QixXQUFXLENBQUMsSUFBSSxDQUFDO2dCQUNmLElBQUksRUFBRSxHQUFHO2dCQUNULFlBQVksRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQzthQUNqQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBQ0QsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBRXhELE1BQU0sSUFBSSxHQUFzQixFQUFFLFdBQVcsRUFBRSxDQUFBO1FBQy9DLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDaEIsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1FBQ3ZELEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ25CLEtBQUssRUFBRSxrQ0FBa0M7WUFDekMsT0FBTyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7U0FDMUQsQ0FBQyxDQUFBO0lBQ0osQ0FBQztBQUNILENBQUMifQ==
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * DTO for GET /admin/analytics/orders-over-time response.
4
+ * Dedicated endpoint for the "Orders over time" chart; real-time data per period (1d, 7d, 30d).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FuYWx5dGljcy9vcmRlcnMtb3Zlci10aW1lL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0cifQ==
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GET = GET;
4
4
  const utils_1 = require("@medusajs/framework/utils");
5
+ /** Status buckets used for Orders by status pie chart */
5
6
  const STATUS_BUCKETS = [
6
7
  "pending",
7
8
  "confirmed",
@@ -35,12 +36,10 @@ async function GET(req, res) {
35
36
  ? Number(daysParam)
36
37
  : 7;
37
38
  const days = daysInput === 0 ? 1 : daysInput;
38
- // #region agent log
39
- fetch('http://127.0.0.1:7242/ingest/47f434f8-0643-48e5-bd1a-edfe05973288', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '21bff8' }, body: JSON.stringify({ sessionId: '21bff8', location: 'orders-summary/route.ts:GET', message: 'orders-summary GET hit', data: { daysParam, daysInput, days }, timestamp: Date.now(), hypothesisId: 'C' }) }).catch(() => { });
40
- // #endregion
41
39
  const today = new Date();
42
40
  today.setUTCHours(0, 0, 0, 0);
43
41
  const todayKey = toDateKey(today);
42
+ // Date range for KPIs and status counts (days param: 0 = today, 7/30/90 = last N days)
44
43
  const rangeStart = new Date(today);
45
44
  rangeStart.setUTCDate(rangeStart.getUTCDate() - (days - 1));
46
45
  rangeStart.setUTCHours(0, 0, 0, 0);
@@ -65,10 +64,12 @@ async function GET(req, res) {
65
64
  for (const key of STATUS_BUCKETS) {
66
65
  statusCounts[key] = 0;
67
66
  }
67
+ // Revenue and AOV exclude cancelled orders; totalOrders KPI counts all orders in range
68
68
  let totalRevenue = 0;
69
+ let nonCancelledCount = 0;
69
70
  let ordersTodayCount = 0;
70
71
  let pendingOrders = 0;
71
- const dailyMap = {};
72
+ let totalOrders = 0;
72
73
  const fulfillmentTimesMs = [];
73
74
  for (const order of allOrders) {
74
75
  const o = order;
@@ -83,15 +84,17 @@ async function GET(req, res) {
83
84
  const status = o.status;
84
85
  const normalized = normalizeStatus(status);
85
86
  statusCounts[normalized] = (statusCounts[normalized] ?? 0) + 1;
86
- const total = typeof o.total === "number" ? o.total : 0;
87
- totalRevenue += total;
87
+ totalOrders += 1;
88
+ // Total revenue and AOV: only include non-cancelled orders
89
+ if (normalized !== "cancelled") {
90
+ const total = typeof o.total === "number" ? o.total : 0;
91
+ totalRevenue += total;
92
+ nonCancelledCount += 1;
93
+ }
88
94
  if (dateKey === todayKey)
89
95
  ordersTodayCount += 1;
90
96
  if (isPendingStatus(status))
91
97
  pendingOrders += 1;
92
- if (dateKey) {
93
- dailyMap[dateKey] = (dailyMap[dateKey] ?? 0) + 1;
94
- }
95
98
  const fulfillments = o.fulfillments ?? [];
96
99
  for (const f of fulfillments) {
97
100
  const shippedAt = f.shipped_at ? new Date(f.shipped_at) : null;
@@ -101,20 +104,7 @@ async function GET(req, res) {
101
104
  }
102
105
  }
103
106
  }
104
- const totalOrders = Object.values(dailyMap).reduce((s, n) => s + n, 0);
105
- const aov = totalOrders > 0 ? totalRevenue / totalOrders : 0;
106
- const dayCount = daysInput === 0 ? 1 : days;
107
- const dailyOrders = [];
108
- for (let i = 0; i < dayCount; i++) {
109
- const d = new Date(rangeStart);
110
- d.setUTCDate(d.getUTCDate() + i);
111
- const key = toDateKey(d);
112
- dailyOrders.push({
113
- date: key,
114
- orders_count: dailyMap[key] ?? 0,
115
- });
116
- }
117
- dailyOrders.sort((a, b) => a.date.localeCompare(b.date));
107
+ const aov = nonCancelledCount > 0 ? totalRevenue / nonCancelledCount : 0;
118
108
  let avgFulfillmentTimeHours = null;
119
109
  if (fulfillmentTimesMs.length > 0) {
120
110
  const avgMs = fulfillmentTimesMs.reduce((s, t) => s + t, 0) / fulfillmentTimesMs.length;
@@ -128,7 +118,6 @@ async function GET(req, res) {
128
118
  pendingOrders,
129
119
  avgFulfillmentTimeHours,
130
120
  statusCounts,
131
- dailyOrders,
132
121
  };
133
122
  res.json(body);
134
123
  }
@@ -140,4 +129,4 @@ async function GET(req, res) {
140
129
  });
141
130
  }
142
131
  }
143
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FuYWx5dGljcy9vcmRlcnMtc3VtbWFyeS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW1DQSxrQkErSUM7QUFqTEQscURBQWtHO0FBUWxHLE1BQU0sY0FBYyxHQUFHO0lBQ3JCLFNBQVM7SUFDVCxXQUFXO0lBQ1gsWUFBWTtJQUNaLFNBQVM7SUFDVCxXQUFXO0lBQ1gsV0FBVztDQUNILENBQUE7QUFFVixTQUFTLGVBQWUsQ0FBQyxNQUEwQjtJQUNqRCxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVE7UUFBRSxPQUFPLFNBQVMsQ0FBQTtJQUMzRCxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDOUIsSUFBSSxDQUFDLEtBQUssVUFBVSxJQUFJLENBQUMsS0FBSyxXQUFXO1FBQUUsT0FBTyxXQUFXLENBQUE7SUFDN0QsSUFBSSxjQUFjLENBQUMsUUFBUSxDQUFDLENBQW9DLENBQUM7UUFBRSxPQUFPLENBQW9DLENBQUE7SUFDOUcsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLE1BQTBCO0lBQ2pELE1BQU0sVUFBVSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMxQyxPQUFPLFVBQVUsS0FBSyxXQUFXLElBQUksVUFBVSxLQUFLLFdBQVcsQ0FBQTtBQUNqRSxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsQ0FBTztJQUN4QixPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFBO0FBQ3JDLENBQUM7QUFFTSxLQUFLLFVBQVUsR0FBRyxDQUN2QixHQUFrQixFQUNsQixHQUFtQjtJQUVuQixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9B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
132
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FuYWx5dGljcy9vcmRlcnMtc3VtbWFyeS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFDQSxrQkFrSUM7QUFqS0QscURBQWtHO0FBSWxHLHlEQUF5RDtBQUN6RCxNQUFNLGNBQWMsR0FBRztJQUNyQixTQUFTO0lBQ1QsV0FBVztJQUNYLFlBQVk7SUFDWixTQUFTO0lBQ1QsV0FBVztJQUNYLFdBQVc7Q0FDSCxDQUFBO0FBRVYsU0FBUyxlQUFlLENBQUMsTUFBMEI7SUFDakQsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRO1FBQUUsT0FBTyxTQUFTLENBQUE7SUFDM0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQzlCLElBQUksQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUFDLEtBQUssV0FBVztRQUFFLE9BQU8sV0FBVyxDQUFBO0lBQzdELElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFvQyxDQUFDO1FBQUUsT0FBTyxDQUFvQyxDQUFBO0lBQzlHLE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxNQUEwQjtJQUNqRCxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDMUMsT0FBTyxVQUFVLEtBQUssV0FBVyxJQUFJLFVBQVUsS0FBSyxXQUFXLENBQUE7QUFDakUsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLENBQU87SUFDeEIsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUNyQyxDQUFDO0FBRU0sS0FBSyxVQUFVLEdBQUcsQ0FDdkIsR0FBa0IsRUFDbEIsR0FBbUI7SUFFbkIsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFD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
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * DTO for GET /admin/analytics/orders-summary response.
4
+ * KPI cards and order-by-status only; for orders-over-time series use the orders-over-time API.
4
5
  */
5
6
  Object.defineProperty(exports, "__esModule", { value: true });
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FuYWx5dGljcy9vcmRlcnMtc3VtbWFyeS90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0dBRUcifQ==
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2FuYWx5dGljcy9vcmRlcnMtc3VtbWFyeS90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "medusa-analytics",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",