@agilo/medusa-analytics-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +1632 -0
- package/.medusa/server/src/admin/index.mjs +1616 -0
- package/.medusa/server/src/api/admin/agilo-analytics/orders/route.js +177 -0
- package/.medusa/server/src/api/admin/agilo-analytics/products/route.js +106 -0
- package/.medusa/server/src/utils/orders.js +184 -0
- package/README.md +68 -0
- package/package.json +107 -0
|
@@ -0,0 +1,1632 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const React = require("react");
|
|
4
|
+
const adminSdk = require("@medusajs/admin-sdk");
|
|
5
|
+
const ui = require("@medusajs/ui");
|
|
6
|
+
const icons = require("@medusajs/icons");
|
|
7
|
+
const lucideReact = require("lucide-react");
|
|
8
|
+
const dateFns = require("date-fns");
|
|
9
|
+
const reactAriaComponents = require("react-aria-components");
|
|
10
|
+
const recharts = require("recharts");
|
|
11
|
+
const clsx = require("clsx");
|
|
12
|
+
const tailwindMerge = require("tailwind-merge");
|
|
13
|
+
const reactRouterDom = require("react-router-dom");
|
|
14
|
+
const reactQuery = require("@tanstack/react-query");
|
|
15
|
+
function _interopNamespace(e) {
|
|
16
|
+
if (e && e.__esModule) return e;
|
|
17
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
18
|
+
if (e) {
|
|
19
|
+
for (const k in e) {
|
|
20
|
+
if (k !== "default") {
|
|
21
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
22
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: () => e[k]
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
n.default = e;
|
|
30
|
+
return Object.freeze(n);
|
|
31
|
+
}
|
|
32
|
+
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
|
|
33
|
+
function $2b4dce13dd5a17fa$export$842a2cf37af977e1(amount, numerator) {
|
|
34
|
+
return amount - numerator * Math.floor(amount / numerator);
|
|
35
|
+
}
|
|
36
|
+
const $3b62074eb05584b2$var$EPOCH = 1721426;
|
|
37
|
+
function $3b62074eb05584b2$export$f297eb839006d339(era, year, month, day) {
|
|
38
|
+
year = $3b62074eb05584b2$export$c36e0ecb2d4fa69d(era, year);
|
|
39
|
+
let y1 = year - 1;
|
|
40
|
+
let monthOffset = -2;
|
|
41
|
+
if (month <= 2) monthOffset = 0;
|
|
42
|
+
else if ($3b62074eb05584b2$export$553d7fa8e3805fc0(year)) monthOffset = -1;
|
|
43
|
+
return $3b62074eb05584b2$var$EPOCH - 1 + 365 * y1 + Math.floor(y1 / 4) - Math.floor(y1 / 100) + Math.floor(y1 / 400) + Math.floor((367 * month - 362) / 12 + monthOffset + day);
|
|
44
|
+
}
|
|
45
|
+
function $3b62074eb05584b2$export$553d7fa8e3805fc0(year) {
|
|
46
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
47
|
+
}
|
|
48
|
+
function $3b62074eb05584b2$export$c36e0ecb2d4fa69d(era, year) {
|
|
49
|
+
return era === "BC" ? 1 - year : year;
|
|
50
|
+
}
|
|
51
|
+
function $3b62074eb05584b2$export$4475b7e617eb123c(year) {
|
|
52
|
+
let era = "AD";
|
|
53
|
+
if (year <= 0) {
|
|
54
|
+
era = "BC";
|
|
55
|
+
year = 1 - year;
|
|
56
|
+
}
|
|
57
|
+
return [
|
|
58
|
+
era,
|
|
59
|
+
year
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
const $3b62074eb05584b2$var$daysInMonth = {
|
|
63
|
+
standard: [
|
|
64
|
+
31,
|
|
65
|
+
28,
|
|
66
|
+
31,
|
|
67
|
+
30,
|
|
68
|
+
31,
|
|
69
|
+
30,
|
|
70
|
+
31,
|
|
71
|
+
31,
|
|
72
|
+
30,
|
|
73
|
+
31,
|
|
74
|
+
30,
|
|
75
|
+
31
|
|
76
|
+
],
|
|
77
|
+
leapyear: [
|
|
78
|
+
31,
|
|
79
|
+
29,
|
|
80
|
+
31,
|
|
81
|
+
30,
|
|
82
|
+
31,
|
|
83
|
+
30,
|
|
84
|
+
31,
|
|
85
|
+
31,
|
|
86
|
+
30,
|
|
87
|
+
31,
|
|
88
|
+
30,
|
|
89
|
+
31
|
|
90
|
+
]
|
|
91
|
+
};
|
|
92
|
+
class $3b62074eb05584b2$export$80ee6245ec4f29ec {
|
|
93
|
+
fromJulianDay(jd) {
|
|
94
|
+
let jd0 = jd;
|
|
95
|
+
let depoch = jd0 - $3b62074eb05584b2$var$EPOCH;
|
|
96
|
+
let quadricent = Math.floor(depoch / 146097);
|
|
97
|
+
let dqc = $2b4dce13dd5a17fa$export$842a2cf37af977e1(depoch, 146097);
|
|
98
|
+
let cent = Math.floor(dqc / 36524);
|
|
99
|
+
let dcent = $2b4dce13dd5a17fa$export$842a2cf37af977e1(dqc, 36524);
|
|
100
|
+
let quad = Math.floor(dcent / 1461);
|
|
101
|
+
let dquad = $2b4dce13dd5a17fa$export$842a2cf37af977e1(dcent, 1461);
|
|
102
|
+
let yindex = Math.floor(dquad / 365);
|
|
103
|
+
let extendedYear = quadricent * 400 + cent * 100 + quad * 4 + yindex + (cent !== 4 && yindex !== 4 ? 1 : 0);
|
|
104
|
+
let [era, year] = $3b62074eb05584b2$export$4475b7e617eb123c(extendedYear);
|
|
105
|
+
let yearDay = jd0 - $3b62074eb05584b2$export$f297eb839006d339(era, year, 1, 1);
|
|
106
|
+
let leapAdj = 2;
|
|
107
|
+
if (jd0 < $3b62074eb05584b2$export$f297eb839006d339(era, year, 3, 1)) leapAdj = 0;
|
|
108
|
+
else if ($3b62074eb05584b2$export$553d7fa8e3805fc0(year)) leapAdj = 1;
|
|
109
|
+
let month = Math.floor(((yearDay + leapAdj) * 12 + 373) / 367);
|
|
110
|
+
let day = jd0 - $3b62074eb05584b2$export$f297eb839006d339(era, year, month, 1) + 1;
|
|
111
|
+
return new $35ea8db9cb2ccb90$export$99faa760c7908e4f(era, year, month, day);
|
|
112
|
+
}
|
|
113
|
+
toJulianDay(date) {
|
|
114
|
+
return $3b62074eb05584b2$export$f297eb839006d339(date.era, date.year, date.month, date.day);
|
|
115
|
+
}
|
|
116
|
+
getDaysInMonth(date) {
|
|
117
|
+
return $3b62074eb05584b2$var$daysInMonth[$3b62074eb05584b2$export$553d7fa8e3805fc0(date.year) ? "leapyear" : "standard"][date.month - 1];
|
|
118
|
+
}
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
120
|
+
getMonthsInYear(date) {
|
|
121
|
+
return 12;
|
|
122
|
+
}
|
|
123
|
+
getDaysInYear(date) {
|
|
124
|
+
return $3b62074eb05584b2$export$553d7fa8e3805fc0(date.year) ? 366 : 365;
|
|
125
|
+
}
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
127
|
+
getYearsInEra(date) {
|
|
128
|
+
return 9999;
|
|
129
|
+
}
|
|
130
|
+
getEras() {
|
|
131
|
+
return [
|
|
132
|
+
"BC",
|
|
133
|
+
"AD"
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
isInverseEra(date) {
|
|
137
|
+
return date.era === "BC";
|
|
138
|
+
}
|
|
139
|
+
balanceDate(date) {
|
|
140
|
+
if (date.year <= 0) {
|
|
141
|
+
date.era = date.era === "BC" ? "AD" : "BC";
|
|
142
|
+
date.year = 1 - date.year;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
constructor() {
|
|
146
|
+
this.identifier = "gregory";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function $14e0f24ef4ac5c92$export$dbc69fd56b53d5e(a, b) {
|
|
150
|
+
var _a_isEqual, _b_isEqual;
|
|
151
|
+
var _a_isEqual1, _ref;
|
|
152
|
+
return (_ref = (_a_isEqual1 = (_a_isEqual = a.isEqual) === null || _a_isEqual === void 0 ? void 0 : _a_isEqual.call(a, b)) !== null && _a_isEqual1 !== void 0 ? _a_isEqual1 : (_b_isEqual = b.isEqual) === null || _b_isEqual === void 0 ? void 0 : _b_isEqual.call(b, a)) !== null && _ref !== void 0 ? _ref : a.identifier === b.identifier;
|
|
153
|
+
}
|
|
154
|
+
function $14e0f24ef4ac5c92$export$68781ddf31c0090f(a, b) {
|
|
155
|
+
return a.calendar.toJulianDay(a) - b.calendar.toJulianDay(b);
|
|
156
|
+
}
|
|
157
|
+
function $14e0f24ef4ac5c92$export$c19a80a9721b80f6(a, b) {
|
|
158
|
+
return $14e0f24ef4ac5c92$var$timeToMs(a) - $14e0f24ef4ac5c92$var$timeToMs(b);
|
|
159
|
+
}
|
|
160
|
+
function $14e0f24ef4ac5c92$var$timeToMs(a) {
|
|
161
|
+
return a.hour * 36e5 + a.minute * 6e4 + a.second * 1e3 + a.millisecond;
|
|
162
|
+
}
|
|
163
|
+
let $14e0f24ef4ac5c92$var$localTimeZone = null;
|
|
164
|
+
function $14e0f24ef4ac5c92$export$aa8b41735afcabd2() {
|
|
165
|
+
if ($14e0f24ef4ac5c92$var$localTimeZone == null) $14e0f24ef4ac5c92$var$localTimeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
166
|
+
return $14e0f24ef4ac5c92$var$localTimeZone;
|
|
167
|
+
}
|
|
168
|
+
function $11d87f3f76e88657$export$bd4fb2bc8bb06fb(date) {
|
|
169
|
+
date = $11d87f3f76e88657$export$b4a036af3fc0b032(date, new $3b62074eb05584b2$export$80ee6245ec4f29ec());
|
|
170
|
+
let year = $3b62074eb05584b2$export$c36e0ecb2d4fa69d(date.era, date.year);
|
|
171
|
+
return $11d87f3f76e88657$var$epochFromParts(year, date.month, date.day, date.hour, date.minute, date.second, date.millisecond);
|
|
172
|
+
}
|
|
173
|
+
function $11d87f3f76e88657$var$epochFromParts(year, month, day, hour, minute, second, millisecond) {
|
|
174
|
+
let date = /* @__PURE__ */ new Date();
|
|
175
|
+
date.setUTCHours(hour, minute, second, millisecond);
|
|
176
|
+
date.setUTCFullYear(year, month - 1, day);
|
|
177
|
+
return date.getTime();
|
|
178
|
+
}
|
|
179
|
+
function $11d87f3f76e88657$export$59c99f3515d3493f(ms, timeZone) {
|
|
180
|
+
if (timeZone === "UTC") return 0;
|
|
181
|
+
if (ms > 0 && timeZone === $14e0f24ef4ac5c92$export$aa8b41735afcabd2()) return new Date(ms).getTimezoneOffset() * -6e4;
|
|
182
|
+
let { year, month, day, hour, minute, second } = $11d87f3f76e88657$var$getTimeZoneParts(ms, timeZone);
|
|
183
|
+
let utc = $11d87f3f76e88657$var$epochFromParts(year, month, day, hour, minute, second, 0);
|
|
184
|
+
return utc - Math.floor(ms / 1e3) * 1e3;
|
|
185
|
+
}
|
|
186
|
+
const $11d87f3f76e88657$var$formattersByTimeZone = /* @__PURE__ */ new Map();
|
|
187
|
+
function $11d87f3f76e88657$var$getTimeZoneParts(ms, timeZone) {
|
|
188
|
+
let formatter = $11d87f3f76e88657$var$formattersByTimeZone.get(timeZone);
|
|
189
|
+
if (!formatter) {
|
|
190
|
+
formatter = new Intl.DateTimeFormat("en-US", {
|
|
191
|
+
timeZone,
|
|
192
|
+
hour12: false,
|
|
193
|
+
era: "short",
|
|
194
|
+
year: "numeric",
|
|
195
|
+
month: "numeric",
|
|
196
|
+
day: "numeric",
|
|
197
|
+
hour: "numeric",
|
|
198
|
+
minute: "numeric",
|
|
199
|
+
second: "numeric"
|
|
200
|
+
});
|
|
201
|
+
$11d87f3f76e88657$var$formattersByTimeZone.set(timeZone, formatter);
|
|
202
|
+
}
|
|
203
|
+
let parts = formatter.formatToParts(new Date(ms));
|
|
204
|
+
let namedParts = {};
|
|
205
|
+
for (let part of parts) if (part.type !== "literal") namedParts[part.type] = part.value;
|
|
206
|
+
return {
|
|
207
|
+
// Firefox returns B instead of BC... https://bugzilla.mozilla.org/show_bug.cgi?id=1752253
|
|
208
|
+
year: namedParts.era === "BC" || namedParts.era === "B" ? -namedParts.year + 1 : +namedParts.year,
|
|
209
|
+
month: +namedParts.month,
|
|
210
|
+
day: +namedParts.day,
|
|
211
|
+
hour: namedParts.hour === "24" ? 0 : +namedParts.hour,
|
|
212
|
+
minute: +namedParts.minute,
|
|
213
|
+
second: +namedParts.second
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const $11d87f3f76e88657$var$DAYMILLIS = 864e5;
|
|
217
|
+
function $11d87f3f76e88657$var$getValidWallTimes(date, timeZone, earlier, later) {
|
|
218
|
+
let found = earlier === later ? [
|
|
219
|
+
earlier
|
|
220
|
+
] : [
|
|
221
|
+
earlier,
|
|
222
|
+
later
|
|
223
|
+
];
|
|
224
|
+
return found.filter((absolute) => $11d87f3f76e88657$var$isValidWallTime(date, timeZone, absolute));
|
|
225
|
+
}
|
|
226
|
+
function $11d87f3f76e88657$var$isValidWallTime(date, timeZone, absolute) {
|
|
227
|
+
let parts = $11d87f3f76e88657$var$getTimeZoneParts(absolute, timeZone);
|
|
228
|
+
return date.year === parts.year && date.month === parts.month && date.day === parts.day && date.hour === parts.hour && date.minute === parts.minute && date.second === parts.second;
|
|
229
|
+
}
|
|
230
|
+
function $11d87f3f76e88657$export$5107c82f94518f5c(date, timeZone, disambiguation = "compatible") {
|
|
231
|
+
let dateTime = $11d87f3f76e88657$export$b21e0b124e224484(date);
|
|
232
|
+
if (timeZone === "UTC") return $11d87f3f76e88657$export$bd4fb2bc8bb06fb(dateTime);
|
|
233
|
+
if (timeZone === $14e0f24ef4ac5c92$export$aa8b41735afcabd2() && disambiguation === "compatible") {
|
|
234
|
+
dateTime = $11d87f3f76e88657$export$b4a036af3fc0b032(dateTime, new $3b62074eb05584b2$export$80ee6245ec4f29ec());
|
|
235
|
+
let date2 = /* @__PURE__ */ new Date();
|
|
236
|
+
let year = $3b62074eb05584b2$export$c36e0ecb2d4fa69d(dateTime.era, dateTime.year);
|
|
237
|
+
date2.setFullYear(year, dateTime.month - 1, dateTime.day);
|
|
238
|
+
date2.setHours(dateTime.hour, dateTime.minute, dateTime.second, dateTime.millisecond);
|
|
239
|
+
return date2.getTime();
|
|
240
|
+
}
|
|
241
|
+
let ms = $11d87f3f76e88657$export$bd4fb2bc8bb06fb(dateTime);
|
|
242
|
+
let offsetBefore = $11d87f3f76e88657$export$59c99f3515d3493f(ms - $11d87f3f76e88657$var$DAYMILLIS, timeZone);
|
|
243
|
+
let offsetAfter = $11d87f3f76e88657$export$59c99f3515d3493f(ms + $11d87f3f76e88657$var$DAYMILLIS, timeZone);
|
|
244
|
+
let valid = $11d87f3f76e88657$var$getValidWallTimes(dateTime, timeZone, ms - offsetBefore, ms - offsetAfter);
|
|
245
|
+
if (valid.length === 1) return valid[0];
|
|
246
|
+
if (valid.length > 1) switch (disambiguation) {
|
|
247
|
+
case "compatible":
|
|
248
|
+
case "earlier":
|
|
249
|
+
return valid[0];
|
|
250
|
+
case "later":
|
|
251
|
+
return valid[valid.length - 1];
|
|
252
|
+
case "reject":
|
|
253
|
+
throw new RangeError("Multiple possible absolute times found");
|
|
254
|
+
}
|
|
255
|
+
switch (disambiguation) {
|
|
256
|
+
case "earlier":
|
|
257
|
+
return Math.min(ms - offsetBefore, ms - offsetAfter);
|
|
258
|
+
case "compatible":
|
|
259
|
+
case "later":
|
|
260
|
+
return Math.max(ms - offsetBefore, ms - offsetAfter);
|
|
261
|
+
case "reject":
|
|
262
|
+
throw new RangeError("No such absolute time found");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function $11d87f3f76e88657$export$e67a095c620b86fe(dateTime, timeZone, disambiguation = "compatible") {
|
|
266
|
+
return new Date($11d87f3f76e88657$export$5107c82f94518f5c(dateTime, timeZone, disambiguation));
|
|
267
|
+
}
|
|
268
|
+
function $11d87f3f76e88657$export$b21e0b124e224484(date, time) {
|
|
269
|
+
let hour = 0, minute = 0, second = 0, millisecond = 0;
|
|
270
|
+
if ("timeZone" in date) ({ hour, minute, second, millisecond } = date);
|
|
271
|
+
else if ("hour" in date && !time) return date;
|
|
272
|
+
if (time) ({ hour, minute, second, millisecond } = time);
|
|
273
|
+
return new $35ea8db9cb2ccb90$export$ca871e8dbb80966f(date.calendar, date.era, date.year, date.month, date.day, hour, minute, second, millisecond);
|
|
274
|
+
}
|
|
275
|
+
function $11d87f3f76e88657$export$b4a036af3fc0b032(date, calendar) {
|
|
276
|
+
if ($14e0f24ef4ac5c92$export$dbc69fd56b53d5e(date.calendar, calendar)) return date;
|
|
277
|
+
let calendarDate = calendar.fromJulianDay(date.calendar.toJulianDay(date));
|
|
278
|
+
let copy = date.copy();
|
|
279
|
+
copy.calendar = calendar;
|
|
280
|
+
copy.era = calendarDate.era;
|
|
281
|
+
copy.year = calendarDate.year;
|
|
282
|
+
copy.month = calendarDate.month;
|
|
283
|
+
copy.day = calendarDate.day;
|
|
284
|
+
$735220c2d4774dd3$export$c4e2ecac49351ef2(copy);
|
|
285
|
+
return copy;
|
|
286
|
+
}
|
|
287
|
+
function $735220c2d4774dd3$export$e16d8520af44a096(date, duration) {
|
|
288
|
+
let mutableDate = date.copy();
|
|
289
|
+
let days = "hour" in mutableDate ? $735220c2d4774dd3$var$addTimeFields(mutableDate, duration) : 0;
|
|
290
|
+
$735220c2d4774dd3$var$addYears(mutableDate, duration.years || 0);
|
|
291
|
+
if (mutableDate.calendar.balanceYearMonth) mutableDate.calendar.balanceYearMonth(mutableDate, date);
|
|
292
|
+
mutableDate.month += duration.months || 0;
|
|
293
|
+
$735220c2d4774dd3$var$balanceYearMonth(mutableDate);
|
|
294
|
+
$735220c2d4774dd3$var$constrainMonthDay(mutableDate);
|
|
295
|
+
mutableDate.day += (duration.weeks || 0) * 7;
|
|
296
|
+
mutableDate.day += duration.days || 0;
|
|
297
|
+
mutableDate.day += days;
|
|
298
|
+
$735220c2d4774dd3$var$balanceDay(mutableDate);
|
|
299
|
+
if (mutableDate.calendar.balanceDate) mutableDate.calendar.balanceDate(mutableDate);
|
|
300
|
+
if (mutableDate.year < 1) {
|
|
301
|
+
mutableDate.year = 1;
|
|
302
|
+
mutableDate.month = 1;
|
|
303
|
+
mutableDate.day = 1;
|
|
304
|
+
}
|
|
305
|
+
let maxYear = mutableDate.calendar.getYearsInEra(mutableDate);
|
|
306
|
+
if (mutableDate.year > maxYear) {
|
|
307
|
+
var _mutableDate_calendar_isInverseEra, _mutableDate_calendar;
|
|
308
|
+
let isInverseEra = (_mutableDate_calendar_isInverseEra = (_mutableDate_calendar = mutableDate.calendar).isInverseEra) === null || _mutableDate_calendar_isInverseEra === void 0 ? void 0 : _mutableDate_calendar_isInverseEra.call(_mutableDate_calendar, mutableDate);
|
|
309
|
+
mutableDate.year = maxYear;
|
|
310
|
+
mutableDate.month = isInverseEra ? 1 : mutableDate.calendar.getMonthsInYear(mutableDate);
|
|
311
|
+
mutableDate.day = isInverseEra ? 1 : mutableDate.calendar.getDaysInMonth(mutableDate);
|
|
312
|
+
}
|
|
313
|
+
if (mutableDate.month < 1) {
|
|
314
|
+
mutableDate.month = 1;
|
|
315
|
+
mutableDate.day = 1;
|
|
316
|
+
}
|
|
317
|
+
let maxMonth = mutableDate.calendar.getMonthsInYear(mutableDate);
|
|
318
|
+
if (mutableDate.month > maxMonth) {
|
|
319
|
+
mutableDate.month = maxMonth;
|
|
320
|
+
mutableDate.day = mutableDate.calendar.getDaysInMonth(mutableDate);
|
|
321
|
+
}
|
|
322
|
+
mutableDate.day = Math.max(1, Math.min(mutableDate.calendar.getDaysInMonth(mutableDate), mutableDate.day));
|
|
323
|
+
return mutableDate;
|
|
324
|
+
}
|
|
325
|
+
function $735220c2d4774dd3$var$addYears(date, years) {
|
|
326
|
+
var _date_calendar_isInverseEra, _date_calendar;
|
|
327
|
+
if ((_date_calendar_isInverseEra = (_date_calendar = date.calendar).isInverseEra) === null || _date_calendar_isInverseEra === void 0 ? void 0 : _date_calendar_isInverseEra.call(_date_calendar, date)) years = -years;
|
|
328
|
+
date.year += years;
|
|
329
|
+
}
|
|
330
|
+
function $735220c2d4774dd3$var$balanceYearMonth(date) {
|
|
331
|
+
while (date.month < 1) {
|
|
332
|
+
$735220c2d4774dd3$var$addYears(date, -1);
|
|
333
|
+
date.month += date.calendar.getMonthsInYear(date);
|
|
334
|
+
}
|
|
335
|
+
let monthsInYear = 0;
|
|
336
|
+
while (date.month > (monthsInYear = date.calendar.getMonthsInYear(date))) {
|
|
337
|
+
date.month -= monthsInYear;
|
|
338
|
+
$735220c2d4774dd3$var$addYears(date, 1);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function $735220c2d4774dd3$var$balanceDay(date) {
|
|
342
|
+
while (date.day < 1) {
|
|
343
|
+
date.month--;
|
|
344
|
+
$735220c2d4774dd3$var$balanceYearMonth(date);
|
|
345
|
+
date.day += date.calendar.getDaysInMonth(date);
|
|
346
|
+
}
|
|
347
|
+
while (date.day > date.calendar.getDaysInMonth(date)) {
|
|
348
|
+
date.day -= date.calendar.getDaysInMonth(date);
|
|
349
|
+
date.month++;
|
|
350
|
+
$735220c2d4774dd3$var$balanceYearMonth(date);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
function $735220c2d4774dd3$var$constrainMonthDay(date) {
|
|
354
|
+
date.month = Math.max(1, Math.min(date.calendar.getMonthsInYear(date), date.month));
|
|
355
|
+
date.day = Math.max(1, Math.min(date.calendar.getDaysInMonth(date), date.day));
|
|
356
|
+
}
|
|
357
|
+
function $735220c2d4774dd3$export$c4e2ecac49351ef2(date) {
|
|
358
|
+
if (date.calendar.constrainDate) date.calendar.constrainDate(date);
|
|
359
|
+
date.year = Math.max(1, Math.min(date.calendar.getYearsInEra(date), date.year));
|
|
360
|
+
$735220c2d4774dd3$var$constrainMonthDay(date);
|
|
361
|
+
}
|
|
362
|
+
function $735220c2d4774dd3$export$3e2544e88a25bff8(duration) {
|
|
363
|
+
let inverseDuration = {};
|
|
364
|
+
for (let key in duration) if (typeof duration[key] === "number") inverseDuration[key] = -duration[key];
|
|
365
|
+
return inverseDuration;
|
|
366
|
+
}
|
|
367
|
+
function $735220c2d4774dd3$export$4e2d2ead65e5f7e3(date, duration) {
|
|
368
|
+
return $735220c2d4774dd3$export$e16d8520af44a096(date, $735220c2d4774dd3$export$3e2544e88a25bff8(duration));
|
|
369
|
+
}
|
|
370
|
+
function $735220c2d4774dd3$export$adaa4cf7ef1b65be(date, fields) {
|
|
371
|
+
let mutableDate = date.copy();
|
|
372
|
+
if (fields.era != null) mutableDate.era = fields.era;
|
|
373
|
+
if (fields.year != null) mutableDate.year = fields.year;
|
|
374
|
+
if (fields.month != null) mutableDate.month = fields.month;
|
|
375
|
+
if (fields.day != null) mutableDate.day = fields.day;
|
|
376
|
+
$735220c2d4774dd3$export$c4e2ecac49351ef2(mutableDate);
|
|
377
|
+
return mutableDate;
|
|
378
|
+
}
|
|
379
|
+
function $735220c2d4774dd3$export$e5d5e1c1822b6e56(value, fields) {
|
|
380
|
+
let mutableValue = value.copy();
|
|
381
|
+
if (fields.hour != null) mutableValue.hour = fields.hour;
|
|
382
|
+
if (fields.minute != null) mutableValue.minute = fields.minute;
|
|
383
|
+
if (fields.second != null) mutableValue.second = fields.second;
|
|
384
|
+
if (fields.millisecond != null) mutableValue.millisecond = fields.millisecond;
|
|
385
|
+
$735220c2d4774dd3$export$7555de1e070510cb(mutableValue);
|
|
386
|
+
return mutableValue;
|
|
387
|
+
}
|
|
388
|
+
function $735220c2d4774dd3$var$balanceTime(time) {
|
|
389
|
+
time.second += Math.floor(time.millisecond / 1e3);
|
|
390
|
+
time.millisecond = $735220c2d4774dd3$var$nonNegativeMod(time.millisecond, 1e3);
|
|
391
|
+
time.minute += Math.floor(time.second / 60);
|
|
392
|
+
time.second = $735220c2d4774dd3$var$nonNegativeMod(time.second, 60);
|
|
393
|
+
time.hour += Math.floor(time.minute / 60);
|
|
394
|
+
time.minute = $735220c2d4774dd3$var$nonNegativeMod(time.minute, 60);
|
|
395
|
+
let days = Math.floor(time.hour / 24);
|
|
396
|
+
time.hour = $735220c2d4774dd3$var$nonNegativeMod(time.hour, 24);
|
|
397
|
+
return days;
|
|
398
|
+
}
|
|
399
|
+
function $735220c2d4774dd3$export$7555de1e070510cb(time) {
|
|
400
|
+
time.millisecond = Math.max(0, Math.min(time.millisecond, 1e3));
|
|
401
|
+
time.second = Math.max(0, Math.min(time.second, 59));
|
|
402
|
+
time.minute = Math.max(0, Math.min(time.minute, 59));
|
|
403
|
+
time.hour = Math.max(0, Math.min(time.hour, 23));
|
|
404
|
+
}
|
|
405
|
+
function $735220c2d4774dd3$var$nonNegativeMod(a, b) {
|
|
406
|
+
let result = a % b;
|
|
407
|
+
if (result < 0) result += b;
|
|
408
|
+
return result;
|
|
409
|
+
}
|
|
410
|
+
function $735220c2d4774dd3$var$addTimeFields(time, duration) {
|
|
411
|
+
time.hour += duration.hours || 0;
|
|
412
|
+
time.minute += duration.minutes || 0;
|
|
413
|
+
time.second += duration.seconds || 0;
|
|
414
|
+
time.millisecond += duration.milliseconds || 0;
|
|
415
|
+
return $735220c2d4774dd3$var$balanceTime(time);
|
|
416
|
+
}
|
|
417
|
+
function $735220c2d4774dd3$export$d52ced6badfb9a4c(value, field, amount, options) {
|
|
418
|
+
let mutable = value.copy();
|
|
419
|
+
switch (field) {
|
|
420
|
+
case "era": {
|
|
421
|
+
let eras = value.calendar.getEras();
|
|
422
|
+
let eraIndex = eras.indexOf(value.era);
|
|
423
|
+
if (eraIndex < 0) throw new Error("Invalid era: " + value.era);
|
|
424
|
+
eraIndex = $735220c2d4774dd3$var$cycleValue(eraIndex, amount, 0, eras.length - 1, options === null || options === void 0 ? void 0 : options.round);
|
|
425
|
+
mutable.era = eras[eraIndex];
|
|
426
|
+
$735220c2d4774dd3$export$c4e2ecac49351ef2(mutable);
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
case "year":
|
|
430
|
+
var _mutable_calendar_isInverseEra, _mutable_calendar;
|
|
431
|
+
if ((_mutable_calendar_isInverseEra = (_mutable_calendar = mutable.calendar).isInverseEra) === null || _mutable_calendar_isInverseEra === void 0 ? void 0 : _mutable_calendar_isInverseEra.call(_mutable_calendar, mutable)) amount = -amount;
|
|
432
|
+
mutable.year = $735220c2d4774dd3$var$cycleValue(value.year, amount, -Infinity, 9999, options === null || options === void 0 ? void 0 : options.round);
|
|
433
|
+
if (mutable.year === -Infinity) mutable.year = 1;
|
|
434
|
+
if (mutable.calendar.balanceYearMonth) mutable.calendar.balanceYearMonth(mutable, value);
|
|
435
|
+
break;
|
|
436
|
+
case "month":
|
|
437
|
+
mutable.month = $735220c2d4774dd3$var$cycleValue(value.month, amount, 1, value.calendar.getMonthsInYear(value), options === null || options === void 0 ? void 0 : options.round);
|
|
438
|
+
break;
|
|
439
|
+
case "day":
|
|
440
|
+
mutable.day = $735220c2d4774dd3$var$cycleValue(value.day, amount, 1, value.calendar.getDaysInMonth(value), options === null || options === void 0 ? void 0 : options.round);
|
|
441
|
+
break;
|
|
442
|
+
default:
|
|
443
|
+
throw new Error("Unsupported field " + field);
|
|
444
|
+
}
|
|
445
|
+
if (value.calendar.balanceDate) value.calendar.balanceDate(mutable);
|
|
446
|
+
$735220c2d4774dd3$export$c4e2ecac49351ef2(mutable);
|
|
447
|
+
return mutable;
|
|
448
|
+
}
|
|
449
|
+
function $735220c2d4774dd3$export$dd02b3e0007dfe28(value, field, amount, options) {
|
|
450
|
+
let mutable = value.copy();
|
|
451
|
+
switch (field) {
|
|
452
|
+
case "hour": {
|
|
453
|
+
let hours = value.hour;
|
|
454
|
+
let min = 0;
|
|
455
|
+
let max = 23;
|
|
456
|
+
if ((options === null || options === void 0 ? void 0 : options.hourCycle) === 12) {
|
|
457
|
+
let isPM = hours >= 12;
|
|
458
|
+
min = isPM ? 12 : 0;
|
|
459
|
+
max = isPM ? 23 : 11;
|
|
460
|
+
}
|
|
461
|
+
mutable.hour = $735220c2d4774dd3$var$cycleValue(hours, amount, min, max, options === null || options === void 0 ? void 0 : options.round);
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
case "minute":
|
|
465
|
+
mutable.minute = $735220c2d4774dd3$var$cycleValue(value.minute, amount, 0, 59, options === null || options === void 0 ? void 0 : options.round);
|
|
466
|
+
break;
|
|
467
|
+
case "second":
|
|
468
|
+
mutable.second = $735220c2d4774dd3$var$cycleValue(value.second, amount, 0, 59, options === null || options === void 0 ? void 0 : options.round);
|
|
469
|
+
break;
|
|
470
|
+
case "millisecond":
|
|
471
|
+
mutable.millisecond = $735220c2d4774dd3$var$cycleValue(value.millisecond, amount, 0, 999, options === null || options === void 0 ? void 0 : options.round);
|
|
472
|
+
break;
|
|
473
|
+
default:
|
|
474
|
+
throw new Error("Unsupported field " + field);
|
|
475
|
+
}
|
|
476
|
+
return mutable;
|
|
477
|
+
}
|
|
478
|
+
function $735220c2d4774dd3$var$cycleValue(value, amount, min, max, round = false) {
|
|
479
|
+
if (round) {
|
|
480
|
+
value += Math.sign(amount);
|
|
481
|
+
if (value < min) value = max;
|
|
482
|
+
let div = Math.abs(amount);
|
|
483
|
+
if (amount > 0) value = Math.ceil(value / div) * div;
|
|
484
|
+
else value = Math.floor(value / div) * div;
|
|
485
|
+
if (value > max) value = min;
|
|
486
|
+
} else {
|
|
487
|
+
value += amount;
|
|
488
|
+
if (value < min) value = max - (min - value - 1);
|
|
489
|
+
else if (value > max) value = min + (value - max - 1);
|
|
490
|
+
}
|
|
491
|
+
return value;
|
|
492
|
+
}
|
|
493
|
+
function $fae977aafc393c5c$export$f59dee82248f5ad4(time) {
|
|
494
|
+
return `${String(time.hour).padStart(2, "0")}:${String(time.minute).padStart(2, "0")}:${String(time.second).padStart(2, "0")}${time.millisecond ? String(time.millisecond / 1e3).slice(1) : ""}`;
|
|
495
|
+
}
|
|
496
|
+
function $fae977aafc393c5c$export$60dfd74aa96791bd(date) {
|
|
497
|
+
let gregorianDate = $11d87f3f76e88657$export$b4a036af3fc0b032(date, new $3b62074eb05584b2$export$80ee6245ec4f29ec());
|
|
498
|
+
let year;
|
|
499
|
+
if (gregorianDate.era === "BC") year = gregorianDate.year === 1 ? "0000" : "-" + String(Math.abs(1 - gregorianDate.year)).padStart(6, "00");
|
|
500
|
+
else year = String(gregorianDate.year).padStart(4, "0");
|
|
501
|
+
return `${year}-${String(gregorianDate.month).padStart(2, "0")}-${String(gregorianDate.day).padStart(2, "0")}`;
|
|
502
|
+
}
|
|
503
|
+
function $fae977aafc393c5c$export$4223de14708adc63(date) {
|
|
504
|
+
return `${$fae977aafc393c5c$export$60dfd74aa96791bd(date)}T${$fae977aafc393c5c$export$f59dee82248f5ad4(date)}`;
|
|
505
|
+
}
|
|
506
|
+
function _check_private_redeclaration(obj, privateCollection) {
|
|
507
|
+
if (privateCollection.has(obj)) {
|
|
508
|
+
throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
function _class_private_field_init(obj, privateMap, value) {
|
|
512
|
+
_check_private_redeclaration(obj, privateMap);
|
|
513
|
+
privateMap.set(obj, value);
|
|
514
|
+
}
|
|
515
|
+
function $35ea8db9cb2ccb90$var$shiftArgs(args) {
|
|
516
|
+
let calendar = typeof args[0] === "object" ? args.shift() : new $3b62074eb05584b2$export$80ee6245ec4f29ec();
|
|
517
|
+
let era;
|
|
518
|
+
if (typeof args[0] === "string") era = args.shift();
|
|
519
|
+
else {
|
|
520
|
+
let eras = calendar.getEras();
|
|
521
|
+
era = eras[eras.length - 1];
|
|
522
|
+
}
|
|
523
|
+
let year = args.shift();
|
|
524
|
+
let month = args.shift();
|
|
525
|
+
let day = args.shift();
|
|
526
|
+
return [
|
|
527
|
+
calendar,
|
|
528
|
+
era,
|
|
529
|
+
year,
|
|
530
|
+
month,
|
|
531
|
+
day
|
|
532
|
+
];
|
|
533
|
+
}
|
|
534
|
+
var $35ea8db9cb2ccb90$var$_type = /* @__PURE__ */ new WeakMap();
|
|
535
|
+
class $35ea8db9cb2ccb90$export$99faa760c7908e4f {
|
|
536
|
+
/** Returns a copy of this date. */
|
|
537
|
+
copy() {
|
|
538
|
+
if (this.era) return new $35ea8db9cb2ccb90$export$99faa760c7908e4f(this.calendar, this.era, this.year, this.month, this.day);
|
|
539
|
+
else return new $35ea8db9cb2ccb90$export$99faa760c7908e4f(this.calendar, this.year, this.month, this.day);
|
|
540
|
+
}
|
|
541
|
+
/** Returns a new `CalendarDate` with the given duration added to it. */
|
|
542
|
+
add(duration) {
|
|
543
|
+
return $735220c2d4774dd3$export$e16d8520af44a096(this, duration);
|
|
544
|
+
}
|
|
545
|
+
/** Returns a new `CalendarDate` with the given duration subtracted from it. */
|
|
546
|
+
subtract(duration) {
|
|
547
|
+
return $735220c2d4774dd3$export$4e2d2ead65e5f7e3(this, duration);
|
|
548
|
+
}
|
|
549
|
+
/** Returns a new `CalendarDate` with the given fields set to the provided values. Other fields will be constrained accordingly. */
|
|
550
|
+
set(fields) {
|
|
551
|
+
return $735220c2d4774dd3$export$adaa4cf7ef1b65be(this, fields);
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Returns a new `CalendarDate` with the given field adjusted by a specified amount.
|
|
555
|
+
* When the resulting value reaches the limits of the field, it wraps around.
|
|
556
|
+
*/
|
|
557
|
+
cycle(field, amount, options) {
|
|
558
|
+
return $735220c2d4774dd3$export$d52ced6badfb9a4c(this, field, amount, options);
|
|
559
|
+
}
|
|
560
|
+
/** Converts the date to a native JavaScript Date object, with the time set to midnight in the given time zone. */
|
|
561
|
+
toDate(timeZone) {
|
|
562
|
+
return $11d87f3f76e88657$export$e67a095c620b86fe(this, timeZone);
|
|
563
|
+
}
|
|
564
|
+
/** Converts the date to an ISO 8601 formatted string. */
|
|
565
|
+
toString() {
|
|
566
|
+
return $fae977aafc393c5c$export$60dfd74aa96791bd(this);
|
|
567
|
+
}
|
|
568
|
+
/** Compares this date with another. A negative result indicates that this date is before the given one, and a positive date indicates that it is after. */
|
|
569
|
+
compare(b) {
|
|
570
|
+
return $14e0f24ef4ac5c92$export$68781ddf31c0090f(this, b);
|
|
571
|
+
}
|
|
572
|
+
constructor(...args) {
|
|
573
|
+
_class_private_field_init(this, $35ea8db9cb2ccb90$var$_type, {
|
|
574
|
+
writable: true,
|
|
575
|
+
value: void 0
|
|
576
|
+
});
|
|
577
|
+
let [calendar, era, year, month, day] = $35ea8db9cb2ccb90$var$shiftArgs(args);
|
|
578
|
+
this.calendar = calendar;
|
|
579
|
+
this.era = era;
|
|
580
|
+
this.year = year;
|
|
581
|
+
this.month = month;
|
|
582
|
+
this.day = day;
|
|
583
|
+
$735220c2d4774dd3$export$c4e2ecac49351ef2(this);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
var $35ea8db9cb2ccb90$var$_type2 = /* @__PURE__ */ new WeakMap();
|
|
587
|
+
class $35ea8db9cb2ccb90$export$ca871e8dbb80966f {
|
|
588
|
+
/** Returns a copy of this date. */
|
|
589
|
+
copy() {
|
|
590
|
+
if (this.era) return new $35ea8db9cb2ccb90$export$ca871e8dbb80966f(this.calendar, this.era, this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond);
|
|
591
|
+
else return new $35ea8db9cb2ccb90$export$ca871e8dbb80966f(this.calendar, this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond);
|
|
592
|
+
}
|
|
593
|
+
/** Returns a new `CalendarDateTime` with the given duration added to it. */
|
|
594
|
+
add(duration) {
|
|
595
|
+
return $735220c2d4774dd3$export$e16d8520af44a096(this, duration);
|
|
596
|
+
}
|
|
597
|
+
/** Returns a new `CalendarDateTime` with the given duration subtracted from it. */
|
|
598
|
+
subtract(duration) {
|
|
599
|
+
return $735220c2d4774dd3$export$4e2d2ead65e5f7e3(this, duration);
|
|
600
|
+
}
|
|
601
|
+
/** Returns a new `CalendarDateTime` with the given fields set to the provided values. Other fields will be constrained accordingly. */
|
|
602
|
+
set(fields) {
|
|
603
|
+
return $735220c2d4774dd3$export$adaa4cf7ef1b65be($735220c2d4774dd3$export$e5d5e1c1822b6e56(this, fields), fields);
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Returns a new `CalendarDateTime` with the given field adjusted by a specified amount.
|
|
607
|
+
* When the resulting value reaches the limits of the field, it wraps around.
|
|
608
|
+
*/
|
|
609
|
+
cycle(field, amount, options) {
|
|
610
|
+
switch (field) {
|
|
611
|
+
case "era":
|
|
612
|
+
case "year":
|
|
613
|
+
case "month":
|
|
614
|
+
case "day":
|
|
615
|
+
return $735220c2d4774dd3$export$d52ced6badfb9a4c(this, field, amount, options);
|
|
616
|
+
default:
|
|
617
|
+
return $735220c2d4774dd3$export$dd02b3e0007dfe28(this, field, amount, options);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/** Converts the date to a native JavaScript Date object in the given time zone. */
|
|
621
|
+
toDate(timeZone, disambiguation) {
|
|
622
|
+
return $11d87f3f76e88657$export$e67a095c620b86fe(this, timeZone, disambiguation);
|
|
623
|
+
}
|
|
624
|
+
/** Converts the date to an ISO 8601 formatted string. */
|
|
625
|
+
toString() {
|
|
626
|
+
return $fae977aafc393c5c$export$4223de14708adc63(this);
|
|
627
|
+
}
|
|
628
|
+
/** Compares this date with another. A negative result indicates that this date is before the given one, and a positive date indicates that it is after. */
|
|
629
|
+
compare(b) {
|
|
630
|
+
let res = $14e0f24ef4ac5c92$export$68781ddf31c0090f(this, b);
|
|
631
|
+
if (res === 0) return $14e0f24ef4ac5c92$export$c19a80a9721b80f6(this, $11d87f3f76e88657$export$b21e0b124e224484(b));
|
|
632
|
+
return res;
|
|
633
|
+
}
|
|
634
|
+
constructor(...args) {
|
|
635
|
+
_class_private_field_init(this, $35ea8db9cb2ccb90$var$_type2, {
|
|
636
|
+
writable: true,
|
|
637
|
+
value: void 0
|
|
638
|
+
});
|
|
639
|
+
let [calendar, era, year, month, day] = $35ea8db9cb2ccb90$var$shiftArgs(args);
|
|
640
|
+
this.calendar = calendar;
|
|
641
|
+
this.era = era;
|
|
642
|
+
this.year = year;
|
|
643
|
+
this.month = month;
|
|
644
|
+
this.day = day;
|
|
645
|
+
this.hour = args.shift() || 0;
|
|
646
|
+
this.minute = args.shift() || 0;
|
|
647
|
+
this.second = args.shift() || 0;
|
|
648
|
+
this.millisecond = args.shift() || 0;
|
|
649
|
+
$735220c2d4774dd3$export$c4e2ecac49351ef2(this);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
const useDarkMode = () => {
|
|
653
|
+
const [isDark, setIsDark] = React.useState(false);
|
|
654
|
+
React.useEffect(() => {
|
|
655
|
+
const checkDarkMode = () => {
|
|
656
|
+
setIsDark(document.documentElement.classList.contains("dark"));
|
|
657
|
+
};
|
|
658
|
+
checkDarkMode();
|
|
659
|
+
const observer = new MutationObserver(checkDarkMode);
|
|
660
|
+
observer.observe(document.documentElement, {
|
|
661
|
+
attributes: true,
|
|
662
|
+
attributeFilter: ["class"]
|
|
663
|
+
});
|
|
664
|
+
return () => observer.disconnect();
|
|
665
|
+
}, []);
|
|
666
|
+
return isDark;
|
|
667
|
+
};
|
|
668
|
+
const LineChart = ({
|
|
669
|
+
data,
|
|
670
|
+
xAxisDataKey,
|
|
671
|
+
yAxisDataKey,
|
|
672
|
+
lineColor = "#3B82F6",
|
|
673
|
+
yAxisTickFormatter
|
|
674
|
+
}) => {
|
|
675
|
+
const isDark = useDarkMode();
|
|
676
|
+
const isSingleDataPoint = data && data.length === 1;
|
|
677
|
+
if (isSingleDataPoint) {
|
|
678
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
679
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-ui-fg-muted mb-2", children: "Single day selected - showing as bar chart for better visibility" }) }),
|
|
680
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { aspect: 16 / 9, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data, margin: { left: 20 }, children: [
|
|
681
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
682
|
+
recharts.CartesianGrid,
|
|
683
|
+
{
|
|
684
|
+
strokeDasharray: "3 3",
|
|
685
|
+
stroke: isDark ? "#374151" : "#E5E7EB"
|
|
686
|
+
}
|
|
687
|
+
),
|
|
688
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
689
|
+
recharts.XAxis,
|
|
690
|
+
{
|
|
691
|
+
dataKey: xAxisDataKey,
|
|
692
|
+
tick: { fill: isDark ? "#D1D5DB" : "#6B7280" },
|
|
693
|
+
axisLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
694
|
+
tickLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
695
|
+
tickMargin: 10
|
|
696
|
+
}
|
|
697
|
+
),
|
|
698
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
699
|
+
recharts.YAxis,
|
|
700
|
+
{
|
|
701
|
+
tickFormatter: yAxisTickFormatter,
|
|
702
|
+
allowDecimals: false,
|
|
703
|
+
tick: { fill: isDark ? "#D1D5DB" : "#6B7280" },
|
|
704
|
+
axisLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
705
|
+
tickLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" }
|
|
706
|
+
}
|
|
707
|
+
),
|
|
708
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
709
|
+
recharts.Tooltip,
|
|
710
|
+
{
|
|
711
|
+
cursor: {
|
|
712
|
+
fill: isDark ? "rgba(55, 65, 81, 0.2)" : "rgba(243, 244, 246, 0.5)"
|
|
713
|
+
},
|
|
714
|
+
formatter: (value) => yAxisTickFormatter ? yAxisTickFormatter(value) : value,
|
|
715
|
+
contentStyle: {
|
|
716
|
+
backgroundColor: isDark ? "#1F2937" : "#FFFFFF",
|
|
717
|
+
border: `1px solid ${isDark ? "#374151" : "#E5E7EB"}`,
|
|
718
|
+
borderRadius: "0.5rem",
|
|
719
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
720
|
+
boxShadow: isDark ? "0 4px 6px -1px rgba(0, 0, 0, 0.3)" : "0 4px 6px -1px rgba(0, 0, 0, 0.1)"
|
|
721
|
+
},
|
|
722
|
+
labelStyle: {
|
|
723
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
724
|
+
fontWeight: "500",
|
|
725
|
+
marginBottom: "4px"
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
),
|
|
729
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
730
|
+
recharts.Bar,
|
|
731
|
+
{
|
|
732
|
+
dataKey: yAxisDataKey,
|
|
733
|
+
fill: lineColor,
|
|
734
|
+
radius: [4, 4, 0, 0],
|
|
735
|
+
maxBarSize: 60
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
] }) })
|
|
739
|
+
] });
|
|
740
|
+
}
|
|
741
|
+
return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { aspect: 16 / 9, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data, margin: { left: 20 }, children: [
|
|
742
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
743
|
+
recharts.CartesianGrid,
|
|
744
|
+
{
|
|
745
|
+
strokeDasharray: "3 3",
|
|
746
|
+
stroke: isDark ? "#374151" : "#E5E7EB"
|
|
747
|
+
}
|
|
748
|
+
),
|
|
749
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
750
|
+
recharts.XAxis,
|
|
751
|
+
{
|
|
752
|
+
dataKey: xAxisDataKey,
|
|
753
|
+
tick: { fill: isDark ? "#D1D5DB" : "#6B7280" },
|
|
754
|
+
axisLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
755
|
+
tickLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
756
|
+
tickMargin: 10
|
|
757
|
+
}
|
|
758
|
+
),
|
|
759
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
760
|
+
recharts.YAxis,
|
|
761
|
+
{
|
|
762
|
+
tickFormatter: yAxisTickFormatter,
|
|
763
|
+
allowDecimals: false,
|
|
764
|
+
tick: { fill: isDark ? "#D1D5DB" : "#6B7280" },
|
|
765
|
+
axisLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
766
|
+
tickLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" }
|
|
767
|
+
}
|
|
768
|
+
),
|
|
769
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
770
|
+
recharts.Tooltip,
|
|
771
|
+
{
|
|
772
|
+
cursor: {
|
|
773
|
+
stroke: isDark ? "#4B5563" : "#E5E7EB",
|
|
774
|
+
strokeWidth: 1,
|
|
775
|
+
fill: isDark ? "rgba(55, 65, 81, 0.2)" : "rgba(243, 244, 246, 0.5)"
|
|
776
|
+
},
|
|
777
|
+
formatter: (value) => yAxisTickFormatter ? yAxisTickFormatter(value) : value,
|
|
778
|
+
contentStyle: {
|
|
779
|
+
backgroundColor: isDark ? "#1F2937" : "#FFFFFF",
|
|
780
|
+
border: `1px solid ${isDark ? "#374151" : "#E5E7EB"}`,
|
|
781
|
+
borderRadius: "0.5rem",
|
|
782
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
783
|
+
boxShadow: isDark ? "0 4px 6px -1px rgba(0, 0, 0, 0.3)" : "0 4px 6px -1px rgba(0, 0, 0, 0.1)"
|
|
784
|
+
},
|
|
785
|
+
labelStyle: {
|
|
786
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
787
|
+
fontWeight: "500",
|
|
788
|
+
marginBottom: "4px"
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
),
|
|
792
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
793
|
+
recharts.Line,
|
|
794
|
+
{
|
|
795
|
+
type: "monotone",
|
|
796
|
+
dataKey: yAxisDataKey,
|
|
797
|
+
stroke: lineColor,
|
|
798
|
+
activeDot: {
|
|
799
|
+
r: 5,
|
|
800
|
+
fill: lineColor,
|
|
801
|
+
stroke: isDark ? "#1F2937" : "#FFFFFF",
|
|
802
|
+
strokeWidth: 2
|
|
803
|
+
},
|
|
804
|
+
strokeWidth: 2,
|
|
805
|
+
dot: {
|
|
806
|
+
r: 4,
|
|
807
|
+
fill: lineColor,
|
|
808
|
+
stroke: isDark ? "#1F2937" : "#FFFFFF",
|
|
809
|
+
strokeWidth: 1
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
)
|
|
813
|
+
] }) });
|
|
814
|
+
};
|
|
815
|
+
function cn(...inputs) {
|
|
816
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
817
|
+
}
|
|
818
|
+
function generateStableColor(input, saturation = 70, lightness = 50) {
|
|
819
|
+
let hash = 0;
|
|
820
|
+
for (let i = 0; i < input.length; i++) {
|
|
821
|
+
const char = input.charCodeAt(i);
|
|
822
|
+
hash = (hash << 5) - hash + char;
|
|
823
|
+
hash = hash & hash;
|
|
824
|
+
}
|
|
825
|
+
const hue = Math.abs(hash) % 360;
|
|
826
|
+
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
|
827
|
+
}
|
|
828
|
+
function generateColorsForData(data, keyField, saturation = 70, lightness = 50) {
|
|
829
|
+
return data.map(
|
|
830
|
+
(item) => generateStableColor(String(item[keyField]), saturation, lightness)
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
const BarChart = ({
|
|
834
|
+
data,
|
|
835
|
+
xAxisDataKey,
|
|
836
|
+
yAxisDataKey,
|
|
837
|
+
lineColor = "#3B82F6",
|
|
838
|
+
yAxisTickFormatter,
|
|
839
|
+
useStableColors = false,
|
|
840
|
+
colorKeyField
|
|
841
|
+
}) => {
|
|
842
|
+
const isDark = useDarkMode();
|
|
843
|
+
const colors = React__namespace.default.useMemo(() => {
|
|
844
|
+
if (!useStableColors || !data || !colorKeyField) {
|
|
845
|
+
return [];
|
|
846
|
+
}
|
|
847
|
+
return generateColorsForData(data, colorKeyField, 70, isDark ? 60 : 50);
|
|
848
|
+
}, [data, useStableColors, colorKeyField, isDark]);
|
|
849
|
+
return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { aspect: 16 / 9, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.BarChart, { data, margin: { left: 20 }, children: [
|
|
850
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
851
|
+
recharts.CartesianGrid,
|
|
852
|
+
{
|
|
853
|
+
strokeDasharray: "3 3",
|
|
854
|
+
stroke: isDark ? "#374151" : "#E5E7EB"
|
|
855
|
+
}
|
|
856
|
+
),
|
|
857
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
858
|
+
recharts.XAxis,
|
|
859
|
+
{
|
|
860
|
+
dataKey: String(xAxisDataKey),
|
|
861
|
+
tick: { fill: isDark ? "#D1D5DB" : "#6B7280" },
|
|
862
|
+
axisLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
863
|
+
tickLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
864
|
+
tickMargin: 10
|
|
865
|
+
}
|
|
866
|
+
),
|
|
867
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
868
|
+
recharts.YAxis,
|
|
869
|
+
{
|
|
870
|
+
tickFormatter: yAxisTickFormatter,
|
|
871
|
+
allowDecimals: false,
|
|
872
|
+
tick: { fill: isDark ? "#D1D5DB" : "#6B7280" },
|
|
873
|
+
axisLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" },
|
|
874
|
+
tickLine: { stroke: isDark ? "#4B5563" : "#D1D5DB" }
|
|
875
|
+
}
|
|
876
|
+
),
|
|
877
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
878
|
+
recharts.Tooltip,
|
|
879
|
+
{
|
|
880
|
+
cursor: {
|
|
881
|
+
fill: isDark ? "rgba(55, 65, 81, 0.2)" : "rgba(243, 244, 246, 0.5)"
|
|
882
|
+
},
|
|
883
|
+
formatter: (value) => yAxisTickFormatter ? yAxisTickFormatter(value) : value,
|
|
884
|
+
contentStyle: {
|
|
885
|
+
backgroundColor: isDark ? "#1F2937" : "#FFFFFF",
|
|
886
|
+
border: `1px solid ${isDark ? "#374151" : "#E5E7EB"}`,
|
|
887
|
+
borderRadius: "0.5rem",
|
|
888
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
889
|
+
boxShadow: isDark ? "0 4px 6px -1px rgba(0, 0, 0, 0.3)" : "0 4px 6px -1px rgba(0, 0, 0, 0.1)"
|
|
890
|
+
},
|
|
891
|
+
labelStyle: {
|
|
892
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
893
|
+
fontWeight: "500",
|
|
894
|
+
marginBottom: "4px"
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
),
|
|
898
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.Bar, { dataKey: String(yAxisDataKey), fill: lineColor, children: useStableColors && colors.length > 0 ? data == null ? void 0 : data.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(recharts.Cell, { fill: colors[index] }, `cell-${index}`)) : null })
|
|
899
|
+
] }) });
|
|
900
|
+
};
|
|
901
|
+
const COLORS = [
|
|
902
|
+
"#3B82F6",
|
|
903
|
+
// blue-500
|
|
904
|
+
"#10B981",
|
|
905
|
+
// emerald-500
|
|
906
|
+
"#F59E0B",
|
|
907
|
+
// amber-500
|
|
908
|
+
"#EF4444",
|
|
909
|
+
// red-500
|
|
910
|
+
"#8B5CF6",
|
|
911
|
+
// violet-500
|
|
912
|
+
"#06B6D4",
|
|
913
|
+
// cyan-500
|
|
914
|
+
"#84CC16",
|
|
915
|
+
// lime-500
|
|
916
|
+
"#F97316"
|
|
917
|
+
// orange-500
|
|
918
|
+
];
|
|
919
|
+
const DARK_COLORS = [
|
|
920
|
+
"#60A5FA",
|
|
921
|
+
// blue-400
|
|
922
|
+
"#34D399",
|
|
923
|
+
// emerald-400
|
|
924
|
+
"#FBBF24",
|
|
925
|
+
// amber-400
|
|
926
|
+
"#F87171",
|
|
927
|
+
// red-400
|
|
928
|
+
"#A78BFA",
|
|
929
|
+
// violet-400
|
|
930
|
+
"#22D3EE",
|
|
931
|
+
// cyan-400
|
|
932
|
+
"#A3E635",
|
|
933
|
+
// lime-400
|
|
934
|
+
"#FB923C"
|
|
935
|
+
// orange-400
|
|
936
|
+
];
|
|
937
|
+
const PieChart = ({ data, dataKey }) => {
|
|
938
|
+
const isDark = useDarkMode();
|
|
939
|
+
const colors = isDark ? DARK_COLORS : COLORS;
|
|
940
|
+
return /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { aspect: 16 / 9, maxHeight: 400, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
|
|
941
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
942
|
+
recharts.Pie,
|
|
943
|
+
{
|
|
944
|
+
data,
|
|
945
|
+
label: ({ percent }) => `${((percent || 0) * 100).toFixed(0)}%`,
|
|
946
|
+
dataKey,
|
|
947
|
+
children: data && data.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
948
|
+
recharts.Cell,
|
|
949
|
+
{
|
|
950
|
+
fill: colors[index % colors.length]
|
|
951
|
+
},
|
|
952
|
+
`cell-${index}`
|
|
953
|
+
))
|
|
954
|
+
}
|
|
955
|
+
),
|
|
956
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
957
|
+
recharts.Tooltip,
|
|
958
|
+
{
|
|
959
|
+
contentStyle: {
|
|
960
|
+
backgroundColor: isDark ? "#1F2937" : "#FFFFFF",
|
|
961
|
+
border: `1px solid ${isDark ? "#374151" : "#E5E7EB"}`,
|
|
962
|
+
borderRadius: "0.5rem",
|
|
963
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
964
|
+
boxShadow: isDark ? "0 4px 6px -1px rgba(0, 0, 0, 0.3)" : "0 4px 6px -1px rgba(0, 0, 0, 0.1)"
|
|
965
|
+
},
|
|
966
|
+
labelStyle: {
|
|
967
|
+
color: isDark ? "#F9FAFB" : "#111827",
|
|
968
|
+
fontWeight: "500",
|
|
969
|
+
marginBottom: "4px"
|
|
970
|
+
},
|
|
971
|
+
itemStyle: {
|
|
972
|
+
color: isDark ? "#F9FAFB" : "#111827"
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
)
|
|
976
|
+
] }) });
|
|
977
|
+
};
|
|
978
|
+
const columnHelper$1 = ui.createDataTableColumnHelper();
|
|
979
|
+
const columns$1 = [
|
|
980
|
+
columnHelper$1.accessor("sku", {
|
|
981
|
+
header: "SKU",
|
|
982
|
+
enableSorting: true,
|
|
983
|
+
sortLabel: "SKU",
|
|
984
|
+
sortAscLabel: "A-Z",
|
|
985
|
+
sortDescLabel: "Z-A"
|
|
986
|
+
}),
|
|
987
|
+
columnHelper$1.accessor("variantName", {
|
|
988
|
+
header: "Variant Name",
|
|
989
|
+
enableSorting: true,
|
|
990
|
+
sortLabel: "Variant Name",
|
|
991
|
+
sortAscLabel: "A-Z",
|
|
992
|
+
sortDescLabel: "Z-A"
|
|
993
|
+
}),
|
|
994
|
+
columnHelper$1.accessor("inventoryQuantity", {
|
|
995
|
+
header: "Inventory",
|
|
996
|
+
enableSorting: true,
|
|
997
|
+
sortLabel: "Inventory",
|
|
998
|
+
sortAscLabel: "Low to High",
|
|
999
|
+
sortDescLabel: "High to Low",
|
|
1000
|
+
cell: ({ getValue }) => {
|
|
1001
|
+
const value = getValue();
|
|
1002
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn(value === 0 && "text-ui-fg-error"), children: value === 0 ? "Out of Stock" : value });
|
|
1003
|
+
}
|
|
1004
|
+
})
|
|
1005
|
+
];
|
|
1006
|
+
const PAGE_SIZE = 10;
|
|
1007
|
+
const ProductsTable = ({ products }) => {
|
|
1008
|
+
const [pagination, setPagination] = React__namespace.useState({
|
|
1009
|
+
pageSize: PAGE_SIZE,
|
|
1010
|
+
pageIndex: 0
|
|
1011
|
+
});
|
|
1012
|
+
const [search, setSearch] = React__namespace.useState("");
|
|
1013
|
+
const [sorting, setSorting] = React__namespace.useState(
|
|
1014
|
+
null
|
|
1015
|
+
);
|
|
1016
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1017
|
+
const shownProducts = React__namespace.useMemo(() => {
|
|
1018
|
+
let filtered = products.filter(
|
|
1019
|
+
(product) => product.variantName.toLowerCase().includes(search.toLowerCase()) || product.sku.toLowerCase().includes(search.toLowerCase())
|
|
1020
|
+
);
|
|
1021
|
+
if (sorting && sorting.id) {
|
|
1022
|
+
filtered = filtered.slice().sort((a, b) => {
|
|
1023
|
+
const aVal = a[sorting.id];
|
|
1024
|
+
const bVal = b[sorting.id];
|
|
1025
|
+
if (aVal < bVal) {
|
|
1026
|
+
return sorting.desc ? 1 : -1;
|
|
1027
|
+
}
|
|
1028
|
+
if (aVal > bVal) {
|
|
1029
|
+
return sorting.desc ? -1 : 1;
|
|
1030
|
+
}
|
|
1031
|
+
return 0;
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
return filtered.slice(
|
|
1035
|
+
pagination.pageIndex * pagination.pageSize,
|
|
1036
|
+
(pagination.pageIndex + 1) * pagination.pageSize
|
|
1037
|
+
);
|
|
1038
|
+
}, [products, search, sorting, pagination]);
|
|
1039
|
+
const table = ui.useDataTable({
|
|
1040
|
+
columns: columns$1,
|
|
1041
|
+
data: shownProducts,
|
|
1042
|
+
getRowId: (product) => product.sku,
|
|
1043
|
+
rowCount: products.length,
|
|
1044
|
+
search: {
|
|
1045
|
+
state: search,
|
|
1046
|
+
onSearchChange: setSearch
|
|
1047
|
+
},
|
|
1048
|
+
pagination: {
|
|
1049
|
+
state: pagination,
|
|
1050
|
+
onPaginationChange: setPagination
|
|
1051
|
+
},
|
|
1052
|
+
sorting: {
|
|
1053
|
+
state: sorting,
|
|
1054
|
+
onSortingChange: setSorting
|
|
1055
|
+
},
|
|
1056
|
+
onRowClick: (_, row) => {
|
|
1057
|
+
navigate(`/products/${row.original.productId}/variants/${row.original.variantId}`);
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable, { instance: table, children: [
|
|
1061
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Toolbar, { className: "px-0 pt-0", children: /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Search, { placeholder: "Search..." }) }),
|
|
1062
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1063
|
+
ui.DataTable.Table,
|
|
1064
|
+
{
|
|
1065
|
+
emptyState: {
|
|
1066
|
+
filtered: {
|
|
1067
|
+
heading: "No products found"
|
|
1068
|
+
},
|
|
1069
|
+
empty: {
|
|
1070
|
+
heading: "No products available"
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
),
|
|
1075
|
+
products.length > PAGE_SIZE && /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Pagination, {})
|
|
1076
|
+
] });
|
|
1077
|
+
};
|
|
1078
|
+
const BACKEND_URL$1 = window.location.origin;
|
|
1079
|
+
async function retrieveProductAnalytics(date) {
|
|
1080
|
+
if (!date || !date.from || !(date == null ? void 0 : date.to)) {
|
|
1081
|
+
return void 0;
|
|
1082
|
+
}
|
|
1083
|
+
const dateFrom = dateFns.format(date.from, "yyyy-MM-dd");
|
|
1084
|
+
const dateTo = dateFns.format(date.to, "yyyy-MM-dd");
|
|
1085
|
+
const data = await fetch(
|
|
1086
|
+
`${BACKEND_URL$1}/admin/agilo-analytics/products?date_from=${dateFrom}&date_to=${dateTo}`
|
|
1087
|
+
);
|
|
1088
|
+
const productAnalytics = await data.json();
|
|
1089
|
+
return productAnalytics;
|
|
1090
|
+
}
|
|
1091
|
+
const useProductAnalytics = (query, options) => {
|
|
1092
|
+
return reactQuery.useQuery({
|
|
1093
|
+
queryKey: ["product-analytics", query == null ? void 0 : query.from, query == null ? void 0 : query.to],
|
|
1094
|
+
queryFn: async () => {
|
|
1095
|
+
const data = await retrieveProductAnalytics(query);
|
|
1096
|
+
return data;
|
|
1097
|
+
},
|
|
1098
|
+
...options
|
|
1099
|
+
});
|
|
1100
|
+
};
|
|
1101
|
+
const BACKEND_URL = window.location.origin;
|
|
1102
|
+
async function retrieveOrderAnalytics(preset, date) {
|
|
1103
|
+
if (!date || !date.from || !(date == null ? void 0 : date.to)) {
|
|
1104
|
+
const data2 = await fetch(
|
|
1105
|
+
`${BACKEND_URL}/admin/agilo-analytics/orders?preset=${preset}`
|
|
1106
|
+
);
|
|
1107
|
+
const orderAnalytics2 = await data2.json();
|
|
1108
|
+
return orderAnalytics2;
|
|
1109
|
+
}
|
|
1110
|
+
const dateFrom = dateFns.format(date.from, "yyyy-MM-dd");
|
|
1111
|
+
const dateTo = dateFns.format(date.to, "yyyy-MM-dd");
|
|
1112
|
+
const data = await fetch(
|
|
1113
|
+
`${BACKEND_URL}/admin/agilo-analytics/orders?date_from=${dateFrom}&date_to=${dateTo}&preset=${preset}`
|
|
1114
|
+
);
|
|
1115
|
+
const orderAnalytics = await data.json();
|
|
1116
|
+
return orderAnalytics;
|
|
1117
|
+
}
|
|
1118
|
+
const useOrderAnalytics = (preset, query, options) => {
|
|
1119
|
+
return reactQuery.useQuery({
|
|
1120
|
+
queryKey: ["order-analytics", query == null ? void 0 : query.from, query == null ? void 0 : query.to],
|
|
1121
|
+
queryFn: async () => {
|
|
1122
|
+
const data = await retrieveOrderAnalytics(preset, query);
|
|
1123
|
+
return data;
|
|
1124
|
+
},
|
|
1125
|
+
...options
|
|
1126
|
+
});
|
|
1127
|
+
};
|
|
1128
|
+
const Skeleton = ({
|
|
1129
|
+
className,
|
|
1130
|
+
...props
|
|
1131
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1132
|
+
"div",
|
|
1133
|
+
{
|
|
1134
|
+
...props,
|
|
1135
|
+
className: tailwindMerge.twMerge(
|
|
1136
|
+
"animate-pulse rounded-md bg-[#F4F4F4] dark:bg-[#3F3F46]",
|
|
1137
|
+
className
|
|
1138
|
+
)
|
|
1139
|
+
}
|
|
1140
|
+
);
|
|
1141
|
+
const SmallCardSkeleton = () => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1142
|
+
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-20 h-[1.4375rem] my-1" }),
|
|
1143
|
+
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-40 h-3.5" })
|
|
1144
|
+
] });
|
|
1145
|
+
const LineChartSkeleton = () => {
|
|
1146
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-full h-full" }) });
|
|
1147
|
+
};
|
|
1148
|
+
const BarChartSkeleton = () => {
|
|
1149
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-full h-full" }) });
|
|
1150
|
+
};
|
|
1151
|
+
const PieChartSkeleton = () => {
|
|
1152
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full aspect-square max-h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-full h-full" }) });
|
|
1153
|
+
};
|
|
1154
|
+
const dummyData = [
|
|
1155
|
+
{
|
|
1156
|
+
a: "a",
|
|
1157
|
+
b: "b",
|
|
1158
|
+
c: 0
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
a: "a",
|
|
1162
|
+
b: "b",
|
|
1163
|
+
c: 0
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
a: "a",
|
|
1167
|
+
b: "b",
|
|
1168
|
+
c: 0
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
a: "a",
|
|
1172
|
+
b: "b",
|
|
1173
|
+
c: 0
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
a: "a",
|
|
1177
|
+
b: "b",
|
|
1178
|
+
c: 0
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
a: "a",
|
|
1182
|
+
b: "b",
|
|
1183
|
+
c: 0
|
|
1184
|
+
}
|
|
1185
|
+
];
|
|
1186
|
+
const columnHelper = ui.createDataTableColumnHelper();
|
|
1187
|
+
const columns = [
|
|
1188
|
+
columnHelper.accessor("a", {
|
|
1189
|
+
header: () => null,
|
|
1190
|
+
cell: () => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-full h-5" })
|
|
1191
|
+
}),
|
|
1192
|
+
columnHelper.accessor("b", {
|
|
1193
|
+
header: () => null,
|
|
1194
|
+
cell: () => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-full h-5" })
|
|
1195
|
+
}),
|
|
1196
|
+
columnHelper.accessor("c", {
|
|
1197
|
+
header: () => null,
|
|
1198
|
+
cell: () => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-full h-5" })
|
|
1199
|
+
})
|
|
1200
|
+
];
|
|
1201
|
+
const ProductsTableSkeleton = () => {
|
|
1202
|
+
const [search, setSearch] = React__namespace.useState("");
|
|
1203
|
+
const table = ui.useDataTable({
|
|
1204
|
+
columns,
|
|
1205
|
+
data: dummyData,
|
|
1206
|
+
getRowId: (product) => product.a,
|
|
1207
|
+
rowCount: dummyData.length,
|
|
1208
|
+
search: {
|
|
1209
|
+
state: search,
|
|
1210
|
+
onSearchChange: setSearch
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable, { instance: table, children: [
|
|
1214
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Toolbar, { className: "px-0 pt-0", children: /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Search, { placeholder: "Search..." }) }),
|
|
1215
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Table, {})
|
|
1216
|
+
] });
|
|
1217
|
+
};
|
|
1218
|
+
function dateToCalendarDate(date) {
|
|
1219
|
+
return new $35ea8db9cb2ccb90$export$99faa760c7908e4f(
|
|
1220
|
+
date.getFullYear(),
|
|
1221
|
+
date.getMonth() + 1,
|
|
1222
|
+
date.getDate()
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
function calendarDateToDate(calendarDate) {
|
|
1226
|
+
const year = "year" in calendarDate ? calendarDate.year : (/* @__PURE__ */ new Date()).getFullYear();
|
|
1227
|
+
const month = "month" in calendarDate ? calendarDate.month : (/* @__PURE__ */ new Date()).getMonth() + 1;
|
|
1228
|
+
const day = "day" in calendarDate ? calendarDate.day : (/* @__PURE__ */ new Date()).getDate();
|
|
1229
|
+
return new Date(year, month - 1, day);
|
|
1230
|
+
}
|
|
1231
|
+
function dateRangeToRangeValue(dateRange) {
|
|
1232
|
+
if (!(dateRange == null ? void 0 : dateRange.from)) return null;
|
|
1233
|
+
return {
|
|
1234
|
+
start: dateToCalendarDate(dateRange.from),
|
|
1235
|
+
end: dateRange.to ? dateToCalendarDate(dateRange.to) : dateToCalendarDate(dateRange.from)
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
function rangeValueToDateRange(rangeValue) {
|
|
1239
|
+
if (!rangeValue) return void 0;
|
|
1240
|
+
return {
|
|
1241
|
+
from: calendarDateToDate(rangeValue.start),
|
|
1242
|
+
to: rangeValue.end ? calendarDateToDate(rangeValue.end) : void 0
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
const AnalyticsPage = () => {
|
|
1246
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1247
|
+
const [date, setDate] = React__namespace.useState({
|
|
1248
|
+
from: dateFns.startOfMonth(/* @__PURE__ */ new Date()),
|
|
1249
|
+
to: dateFns.endOfMonth(/* @__PURE__ */ new Date())
|
|
1250
|
+
});
|
|
1251
|
+
const [selectValue, setSelectValue] = React__namespace.useState("this-month");
|
|
1252
|
+
const { data: products, isLoading: isLoadingProducts } = useProductAnalytics(date);
|
|
1253
|
+
const { data: orders, isLoading: isLoadingOrders } = useOrderAnalytics(
|
|
1254
|
+
selectValue,
|
|
1255
|
+
date
|
|
1256
|
+
);
|
|
1257
|
+
const someOrderCountsGreaterThanZero = (_a = orders == null ? void 0 : orders.order_count) == null ? void 0 : _a.some(
|
|
1258
|
+
(item) => item.count > 0
|
|
1259
|
+
);
|
|
1260
|
+
const someOrderSalesGreaterThanZero = (_b = orders == null ? void 0 : orders.order_sales) == null ? void 0 : _b.some(
|
|
1261
|
+
(item) => item.sales > 0
|
|
1262
|
+
);
|
|
1263
|
+
const someTopSellingProductsGreaterThanZero = (_c = products == null ? void 0 : products.variantQuantitySold) == null ? void 0 : _c.some((item) => item.quantity > 0);
|
|
1264
|
+
const updateDatePreset = React__namespace.useCallback((preset) => {
|
|
1265
|
+
const today = /* @__PURE__ */ new Date();
|
|
1266
|
+
switch (preset) {
|
|
1267
|
+
case "this-month":
|
|
1268
|
+
setDate({
|
|
1269
|
+
from: dateFns.startOfMonth(today),
|
|
1270
|
+
to: today
|
|
1271
|
+
});
|
|
1272
|
+
setSelectValue("this-month");
|
|
1273
|
+
break;
|
|
1274
|
+
case "last-month":
|
|
1275
|
+
setDate({
|
|
1276
|
+
from: dateFns.startOfMonth(dateFns.subMonths(today, 1)),
|
|
1277
|
+
to: dateFns.endOfMonth(dateFns.subMonths(today, 1))
|
|
1278
|
+
});
|
|
1279
|
+
setSelectValue("last-month");
|
|
1280
|
+
break;
|
|
1281
|
+
case "last-3-months":
|
|
1282
|
+
setDate({
|
|
1283
|
+
from: dateFns.startOfMonth(dateFns.subMonths(today, 3)),
|
|
1284
|
+
to: dateFns.endOfMonth(dateFns.subMonths(today, 1))
|
|
1285
|
+
});
|
|
1286
|
+
setSelectValue("last-3-months");
|
|
1287
|
+
break;
|
|
1288
|
+
case "custom":
|
|
1289
|
+
default:
|
|
1290
|
+
setSelectValue("custom");
|
|
1291
|
+
break;
|
|
1292
|
+
}
|
|
1293
|
+
}, []);
|
|
1294
|
+
const handleDateRangeChange = React__namespace.useCallback(
|
|
1295
|
+
(value) => {
|
|
1296
|
+
const newDateRange = rangeValueToDateRange(value);
|
|
1297
|
+
setDate(newDateRange);
|
|
1298
|
+
if (selectValue !== "custom") {
|
|
1299
|
+
setSelectValue("custom");
|
|
1300
|
+
}
|
|
1301
|
+
},
|
|
1302
|
+
[]
|
|
1303
|
+
);
|
|
1304
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
1305
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-x-2 gap-y-4 items-center justify-between px-6 py-4", children: [
|
|
1306
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Analytics" }),
|
|
1307
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
1308
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[170px]", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1309
|
+
ui.Select,
|
|
1310
|
+
{
|
|
1311
|
+
disabled: isLoadingOrders || isLoadingProducts,
|
|
1312
|
+
defaultValue: "this-month",
|
|
1313
|
+
value: selectValue,
|
|
1314
|
+
onValueChange: updateDatePreset,
|
|
1315
|
+
children: [
|
|
1316
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, {}) }),
|
|
1317
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
|
|
1318
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "this-month", children: "This Month" }),
|
|
1319
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "last-month", children: "Last Month" }),
|
|
1320
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "last-3-months", children: "Last 3 Months" }),
|
|
1321
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: "custom", children: "Custom" })
|
|
1322
|
+
] })
|
|
1323
|
+
]
|
|
1324
|
+
}
|
|
1325
|
+
) }),
|
|
1326
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1327
|
+
reactAriaComponents.DateRangePicker,
|
|
1328
|
+
{
|
|
1329
|
+
value: dateRangeToRangeValue(date),
|
|
1330
|
+
onChange: handleDateRangeChange,
|
|
1331
|
+
isDisabled: isLoadingOrders || isLoadingProducts,
|
|
1332
|
+
"aria-label": "Date range",
|
|
1333
|
+
children: [
|
|
1334
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactAriaComponents.Group, { className: "inline-flex items-center gap-2 whitespace-nowrap rounded-md text-sm transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive justify-start focus-visible:shadow-borders-interactive-with-active disabled:bg-ui-bg-disabled disabled:text-ui-fg-disabled bg-ui-bg-field text-ui-fg-base txt-compact-small h-8 text-left font-normal data-[state=open]:!shadow-borders-interactive-with-active shadow-buttons-neutral hover:bg-ui-bg-field-hover outline-none transition-fg disabled:cursor-not-allowed min-w-[260px] bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-ui-bg-field-component dark:border-ui-border-base dark:hover:bg-ui-bg-field-hover px-4 border cursor-pointer", children: [
|
|
1335
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Calendar, { className: "h-4 w-4 text-ui-fg-muted group-disabled:text-ui-fg-disabled flex-shrink-0" }),
|
|
1336
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.DateInput, { slot: "start", className: "flex-1 min-w-0", children: (segment) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1337
|
+
reactAriaComponents.DateSegment,
|
|
1338
|
+
{
|
|
1339
|
+
segment,
|
|
1340
|
+
className: "outline-none rounded-sm focus:bg-ui-bg-interactive focus:text-ui-fg-on-color caret-transparent placeholder-shown:italic text-ui-fg-base data-[placeholder]:text-ui-fg-muted"
|
|
1341
|
+
}
|
|
1342
|
+
) }),
|
|
1343
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "text-ui-fg-muted px-1", children: "—" }),
|
|
1344
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.DateInput, { slot: "end", className: "flex-1 min-w-0", children: (segment) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1345
|
+
reactAriaComponents.DateSegment,
|
|
1346
|
+
{
|
|
1347
|
+
segment,
|
|
1348
|
+
className: "outline-none rounded-sm focus:bg-ui-bg-interactive focus:text-ui-fg-on-color caret-transparent placeholder-shown:italic text-ui-fg-base data-[placeholder]:text-ui-fg-muted"
|
|
1349
|
+
}
|
|
1350
|
+
) }),
|
|
1351
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Button, { className: "text-ui-fg-muted hover:bg-ui-bg-subtle dark:hover:bg-ui-bg-subtle rounded p-1", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDown, { className: "size-4" }) })
|
|
1352
|
+
] }),
|
|
1353
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Popover, { className: "w-auto p-0 bg-transparent z-50", children: /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Dialog, { className: "bg-ui-bg-base dark:bg-ui-bg-base border border-ui-border-base dark:border-ui-border-base rounded-lg shadow-lg p-6 max-w-fit", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1354
|
+
reactAriaComponents.RangeCalendar,
|
|
1355
|
+
{
|
|
1356
|
+
className: "w-fit",
|
|
1357
|
+
visibleDuration: { months: 2 },
|
|
1358
|
+
children: [
|
|
1359
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-center justify-between mb-4", children: [
|
|
1360
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1361
|
+
reactAriaComponents.Button,
|
|
1362
|
+
{
|
|
1363
|
+
slot: "previous",
|
|
1364
|
+
className: "p-2 hover:bg-ui-bg-subtle dark:hover:bg-ui-bg-subtle rounded text-ui-fg-base",
|
|
1365
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronLeft, { className: "size-4" })
|
|
1366
|
+
}
|
|
1367
|
+
),
|
|
1368
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Heading, { className: "font-semibold text-lg text-ui-fg-base" }),
|
|
1369
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1370
|
+
reactAriaComponents.Button,
|
|
1371
|
+
{
|
|
1372
|
+
slot: "next",
|
|
1373
|
+
className: "p-2 hover:bg-ui-bg-subtle dark:hover:bg-ui-bg-subtle rounded text-ui-fg-base",
|
|
1374
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronRight, { className: "size-4" })
|
|
1375
|
+
}
|
|
1376
|
+
)
|
|
1377
|
+
] }),
|
|
1378
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-6", children: [
|
|
1379
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.CalendarGrid, { className: "border-collapse gap-1", children: (date2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1380
|
+
reactAriaComponents.CalendarCell,
|
|
1381
|
+
{
|
|
1382
|
+
date: date2,
|
|
1383
|
+
className: "w-9 h-9 text-sm cursor-pointer rounded flex items-center justify-center hover:bg-ui-bg-subtle dark:hover:bg-ui-bg-subtle selected:bg-ui-bg-interactive selected:text-ui-fg-on-color selection-start:bg-ui-bg-interactive selection-start:text-ui-fg-on-color selection-end:bg-ui-bg-interactive selection-end:text-ui-fg-on-color outside-month:text-ui-fg-disabled unavailable:text-ui-fg-disabled unavailable:cursor-default text-ui-fg-base data-[selected]:bg-ui-bg-interactive data-[selected]:text-ui-fg-on-color data-[selection-start]:bg-ui-bg-interactive data-[selection-start]:text-ui-fg-on-color data-[selection-end]:bg-ui-bg-interactive data-[selection-end]:text-ui-fg-on-color"
|
|
1384
|
+
}
|
|
1385
|
+
) }),
|
|
1386
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1387
|
+
reactAriaComponents.CalendarGrid,
|
|
1388
|
+
{
|
|
1389
|
+
offset: { months: 1 },
|
|
1390
|
+
className: "border-collapse gap-1",
|
|
1391
|
+
children: (date2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1392
|
+
reactAriaComponents.CalendarCell,
|
|
1393
|
+
{
|
|
1394
|
+
date: date2,
|
|
1395
|
+
className: "w-9 h-9 text-sm cursor-pointer rounded flex items-center justify-center hover:bg-ui-bg-subtle dark:hover:bg-ui-bg-subtle selected:bg-ui-bg-interactive selected:text-ui-fg-on-color selection-start:bg-ui-bg-interactive selection-start:text-ui-fg-on-color selection-end:bg-ui-bg-interactive selection-end:text-ui-fg-on-color outside-month:text-ui-fg-disabled unavailable:text-ui-fg-disabled unavailable:cursor-default text-ui-fg-base data-[selected]:bg-ui-bg-interactive data-[selected]:text-ui-fg-on-color data-[selection-start]:bg-ui-bg-interactive data-[selection-start]:text-ui-fg-on-color data-[selection-end]:bg-ui-bg-interactive data-[selection-end]:text-ui-fg-on-color"
|
|
1396
|
+
}
|
|
1397
|
+
)
|
|
1398
|
+
}
|
|
1399
|
+
)
|
|
1400
|
+
] })
|
|
1401
|
+
]
|
|
1402
|
+
}
|
|
1403
|
+
) }) })
|
|
1404
|
+
]
|
|
1405
|
+
}
|
|
1406
|
+
)
|
|
1407
|
+
] })
|
|
1408
|
+
] }),
|
|
1409
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { defaultValue: "orders", children: [
|
|
1410
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs.List, { children: [
|
|
1411
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1412
|
+
ui.Tabs.Trigger,
|
|
1413
|
+
{
|
|
1414
|
+
value: "orders",
|
|
1415
|
+
disabled: isLoadingOrders || isLoadingProducts,
|
|
1416
|
+
children: "Orders"
|
|
1417
|
+
}
|
|
1418
|
+
),
|
|
1419
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1420
|
+
ui.Tabs.Trigger,
|
|
1421
|
+
{
|
|
1422
|
+
value: "products",
|
|
1423
|
+
disabled: isLoadingOrders || isLoadingProducts,
|
|
1424
|
+
children: "Products"
|
|
1425
|
+
}
|
|
1426
|
+
)
|
|
1427
|
+
] }),
|
|
1428
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8", children: [
|
|
1429
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs.Content, { value: "orders", children: [
|
|
1430
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-md:flex-col gap-4 mb-4", children: [
|
|
1431
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 flex-1", children: [
|
|
1432
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "relative", children: [
|
|
1433
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ShoppingCart, { className: "absolute right-6 top-4 text-ui-fg-muted" }),
|
|
1434
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: "Total Orders" }),
|
|
1435
|
+
isLoadingOrders ? /* @__PURE__ */ jsxRuntime.jsx(SmallCardSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1436
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: (orders == null ? void 0 : orders.total_orders) || 0 }),
|
|
1437
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
1438
|
+
((orders == null ? void 0 : orders.prev_orders_percent) || 0) > 0 && "+",
|
|
1439
|
+
(orders == null ? void 0 : orders.prev_orders_percent) || 0,
|
|
1440
|
+
"% from previous period"
|
|
1441
|
+
] })
|
|
1442
|
+
] })
|
|
1443
|
+
] }),
|
|
1444
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "min-h-[9.375rem]", children: [
|
|
1445
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Orders Over Time" }),
|
|
1446
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: "Total number of orders in the selected period" }),
|
|
1447
|
+
isLoadingOrders ? /* @__PURE__ */ jsxRuntime.jsx(LineChartSkeleton, {}) : (orders == null ? void 0 : orders.order_count) && ((_d = orders == null ? void 0 : orders.order_count) == null ? void 0 : _d.length) > 0 && someOrderCountsGreaterThanZero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1448
|
+
LineChart,
|
|
1449
|
+
{
|
|
1450
|
+
data: orders == null ? void 0 : orders.order_count,
|
|
1451
|
+
xAxisDataKey: "name",
|
|
1452
|
+
yAxisDataKey: "count"
|
|
1453
|
+
}
|
|
1454
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1455
|
+
ui.Text,
|
|
1456
|
+
{
|
|
1457
|
+
size: "small",
|
|
1458
|
+
className: "text-ui-fg-muted text-center",
|
|
1459
|
+
children: "No data available for the selected period."
|
|
1460
|
+
}
|
|
1461
|
+
)
|
|
1462
|
+
] })
|
|
1463
|
+
] }),
|
|
1464
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 flex-1", children: [
|
|
1465
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "relative", children: [
|
|
1466
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChartNoAxesCombined, { className: "absolute right-6 text-ui-fg-muted top-4 size-[15px]" }),
|
|
1467
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: "Total Sales" }),
|
|
1468
|
+
isLoadingOrders ? /* @__PURE__ */ jsxRuntime.jsx(SmallCardSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1469
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: new Intl.NumberFormat("en-US", {
|
|
1470
|
+
style: "currency",
|
|
1471
|
+
currency: (orders == null ? void 0 : orders.currency_code) || "EUR"
|
|
1472
|
+
}).format((orders == null ? void 0 : orders.total_sales) || 0) }),
|
|
1473
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "xsmall", className: "text-ui-fg-muted", children: [
|
|
1474
|
+
((orders == null ? void 0 : orders.prev_sales_percent) || 0) > 0 && "+",
|
|
1475
|
+
(orders == null ? void 0 : orders.prev_sales_percent) || 0,
|
|
1476
|
+
"% from previous period"
|
|
1477
|
+
] })
|
|
1478
|
+
] })
|
|
1479
|
+
] }),
|
|
1480
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "min-h-[9.375rem]", children: [
|
|
1481
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Sales Over Time" }),
|
|
1482
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: [
|
|
1483
|
+
"Total sales in the selected period (",
|
|
1484
|
+
orders == null ? void 0 : orders.currency_code,
|
|
1485
|
+
")"
|
|
1486
|
+
] }),
|
|
1487
|
+
isLoadingOrders ? /* @__PURE__ */ jsxRuntime.jsx(LineChartSkeleton, {}) : (orders == null ? void 0 : orders.order_sales) && ((_e = orders == null ? void 0 : orders.order_sales) == null ? void 0 : _e.length) > 0 && someOrderSalesGreaterThanZero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1488
|
+
LineChart,
|
|
1489
|
+
{
|
|
1490
|
+
data: orders.order_sales,
|
|
1491
|
+
xAxisDataKey: "name",
|
|
1492
|
+
yAxisDataKey: "sales",
|
|
1493
|
+
lineColor: "#82ca9d",
|
|
1494
|
+
yAxisTickFormatter: (value) => new Intl.NumberFormat("en-US", {
|
|
1495
|
+
currency: orders.currency_code,
|
|
1496
|
+
maximumFractionDigits: 0
|
|
1497
|
+
}).format(value)
|
|
1498
|
+
}
|
|
1499
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1500
|
+
ui.Text,
|
|
1501
|
+
{
|
|
1502
|
+
size: "small",
|
|
1503
|
+
className: "text-ui-fg-muted text-center",
|
|
1504
|
+
children: "No data available for the selected period."
|
|
1505
|
+
}
|
|
1506
|
+
)
|
|
1507
|
+
] })
|
|
1508
|
+
] })
|
|
1509
|
+
] }),
|
|
1510
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-md:flex-col gap-4", children: [
|
|
1511
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "min-h-[9.375rem]", children: [
|
|
1512
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Top Regions by Sales" }),
|
|
1513
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: "Sales breakdown by region in the selected period" }),
|
|
1514
|
+
isLoadingOrders ? /* @__PURE__ */ jsxRuntime.jsx(BarChartSkeleton, {}) : (orders == null ? void 0 : orders.regions) && ((_f = orders == null ? void 0 : orders.regions) == null ? void 0 : _f.length) > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1515
|
+
BarChart,
|
|
1516
|
+
{
|
|
1517
|
+
data: orders.regions,
|
|
1518
|
+
xAxisDataKey: "name",
|
|
1519
|
+
yAxisDataKey: "sales",
|
|
1520
|
+
lineColor: "#82ca9d",
|
|
1521
|
+
useStableColors: true,
|
|
1522
|
+
colorKeyField: "name",
|
|
1523
|
+
yAxisTickFormatter: (value) => new Intl.NumberFormat("en-US", {
|
|
1524
|
+
currency: orders.currency_code,
|
|
1525
|
+
maximumFractionDigits: 0
|
|
1526
|
+
}).format(value)
|
|
1527
|
+
}
|
|
1528
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1529
|
+
ui.Text,
|
|
1530
|
+
{
|
|
1531
|
+
size: "small",
|
|
1532
|
+
className: "text-ui-fg-muted text-center",
|
|
1533
|
+
children: "No data available for the selected period."
|
|
1534
|
+
}
|
|
1535
|
+
)
|
|
1536
|
+
] }) }),
|
|
1537
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "min-h-[9.375rem]", children: [
|
|
1538
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Order Status Breakdown" }),
|
|
1539
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: "Distribution of orders by status in the selected period" }),
|
|
1540
|
+
isLoadingOrders ? /* @__PURE__ */ jsxRuntime.jsx(PieChartSkeleton, {}) : (orders == null ? void 0 : orders.statuses) && ((_g = orders == null ? void 0 : orders.statuses) == null ? void 0 : _g.length) > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(PieChart, { data: orders == null ? void 0 : orders.statuses, dataKey: "count" }) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1541
|
+
ui.Text,
|
|
1542
|
+
{
|
|
1543
|
+
size: "small",
|
|
1544
|
+
className: "text-ui-fg-muted text-center",
|
|
1545
|
+
children: "No data available for the selected period."
|
|
1546
|
+
}
|
|
1547
|
+
)
|
|
1548
|
+
] }) })
|
|
1549
|
+
] })
|
|
1550
|
+
] }),
|
|
1551
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs.Content, { value: "products", children: [
|
|
1552
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mb-4 min-h-[9.375rem]", children: [
|
|
1553
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Top-Selling Products" }),
|
|
1554
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: "Products by quantity sold in selected period" }),
|
|
1555
|
+
isLoadingProducts ? /* @__PURE__ */ jsxRuntime.jsx(BarChartSkeleton, {}) : (products == null ? void 0 : products.variantQuantitySold) && someTopSellingProductsGreaterThanZero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", style: { aspectRatio: "16/9" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1556
|
+
BarChart,
|
|
1557
|
+
{
|
|
1558
|
+
data: products.variantQuantitySold,
|
|
1559
|
+
xAxisDataKey: "title",
|
|
1560
|
+
yAxisDataKey: "quantity",
|
|
1561
|
+
lineColor: "#82ca9d",
|
|
1562
|
+
useStableColors: true,
|
|
1563
|
+
colorKeyField: "title"
|
|
1564
|
+
}
|
|
1565
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted text-center", children: "No data available for the selected period." })
|
|
1566
|
+
] }),
|
|
1567
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 max-xl:flex-col", children: [
|
|
1568
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [
|
|
1569
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Out-of-Stock Variants" }),
|
|
1570
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: "Products with zero inventory" }),
|
|
1571
|
+
isLoadingProducts ? /* @__PURE__ */ jsxRuntime.jsx(ProductsTableSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1572
|
+
ProductsTable,
|
|
1573
|
+
{
|
|
1574
|
+
products: ((_h = products == null ? void 0 : products.lowStockVariants) == null ? void 0 : _h.filter(
|
|
1575
|
+
(product) => product.inventoryQuantity === 0
|
|
1576
|
+
)) || []
|
|
1577
|
+
}
|
|
1578
|
+
)
|
|
1579
|
+
] }),
|
|
1580
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [
|
|
1581
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xlarge", weight: "plus", children: "Low Stock Variants" }),
|
|
1582
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mb-8 text-ui-fg-muted", children: "Products with inventory below threshold" }),
|
|
1583
|
+
isLoadingProducts ? /* @__PURE__ */ jsxRuntime.jsx(ProductsTableSkeleton, {}) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1584
|
+
ProductsTable,
|
|
1585
|
+
{
|
|
1586
|
+
products: ((_i = products == null ? void 0 : products.lowStockVariants) == null ? void 0 : _i.filter(
|
|
1587
|
+
(product) => product.inventoryQuantity > 0
|
|
1588
|
+
)) || []
|
|
1589
|
+
}
|
|
1590
|
+
)
|
|
1591
|
+
] })
|
|
1592
|
+
] })
|
|
1593
|
+
] })
|
|
1594
|
+
] })
|
|
1595
|
+
] }) })
|
|
1596
|
+
] });
|
|
1597
|
+
};
|
|
1598
|
+
const config = adminSdk.defineRouteConfig({
|
|
1599
|
+
label: "Analytics",
|
|
1600
|
+
icon: icons.ChartBar
|
|
1601
|
+
});
|
|
1602
|
+
const widgetModule = { widgets: [] };
|
|
1603
|
+
const routeModule = {
|
|
1604
|
+
routes: [
|
|
1605
|
+
{
|
|
1606
|
+
Component: AnalyticsPage,
|
|
1607
|
+
path: "/analytics"
|
|
1608
|
+
}
|
|
1609
|
+
]
|
|
1610
|
+
};
|
|
1611
|
+
const menuItemModule = {
|
|
1612
|
+
menuItems: [
|
|
1613
|
+
{
|
|
1614
|
+
label: config.label,
|
|
1615
|
+
icon: config.icon,
|
|
1616
|
+
path: "/analytics",
|
|
1617
|
+
nested: void 0
|
|
1618
|
+
}
|
|
1619
|
+
]
|
|
1620
|
+
};
|
|
1621
|
+
const formModule = { customFields: {} };
|
|
1622
|
+
const displayModule = {
|
|
1623
|
+
displays: {}
|
|
1624
|
+
};
|
|
1625
|
+
const plugin = {
|
|
1626
|
+
widgetModule,
|
|
1627
|
+
routeModule,
|
|
1628
|
+
menuItemModule,
|
|
1629
|
+
formModule,
|
|
1630
|
+
displayModule
|
|
1631
|
+
};
|
|
1632
|
+
module.exports = plugin;
|