@sonatel-os/strapi-plugin-tcg 0.0.0-stage → 0.3.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.
@@ -0,0 +1,1012 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Flex, Typography, Button, Badge, EmptyStateLayout } from "@strapi/design-system";
4
+ import { Lightbulb, ChevronDown, ChevronUp, CheckCircle, ArrowRight } from "@strapi/icons";
5
+ import { EmptyDocuments } from "@strapi/icons/symbols";
6
+ import { useNavigate } from "react-router-dom";
7
+ import { styled, css, keyframes } from "styled-components";
8
+ import { adminApi } from "@strapi/strapi/admin";
9
+ import { P as PLUGIN_ID } from "./index-ClDgxnnH.mjs";
10
+ const fmtDateTime = (value, locale) => {
11
+ if (!value) return "—";
12
+ try {
13
+ return new Intl.DateTimeFormat(locale ?? void 0, {
14
+ dateStyle: "medium",
15
+ timeStyle: "short"
16
+ }).format(new Date(value));
17
+ } catch {
18
+ return String(value);
19
+ }
20
+ };
21
+ const fmtDate = (value, locale) => {
22
+ if (!value) return "—";
23
+ try {
24
+ return new Intl.DateTimeFormat(locale ?? void 0, { dateStyle: "medium" }).format(
25
+ new Date(value)
26
+ );
27
+ } catch {
28
+ return String(value);
29
+ }
30
+ };
31
+ const fmtNumber = (value, locale) => new Intl.NumberFormat(locale ?? void 0).format(Number(value ?? 0));
32
+ const timeAgo = (value) => {
33
+ if (!value) return "—";
34
+ const diff = Date.now() - new Date(value).getTime();
35
+ const s = Math.round(diff / 1e3);
36
+ if (s < 60) return `${s}s`;
37
+ const m = Math.round(s / 60);
38
+ if (m < 60) return `${m} min`;
39
+ const h = Math.round(m / 60);
40
+ if (h < 48) return `${h} h`;
41
+ return `${Math.round(h / 24)} j`;
42
+ };
43
+ const rarityOf = (season, key) => (season?.rarities ?? []).find((r) => r.key === key) ?? { key, label: key, color: "#8E8EA9" };
44
+ const errorMessage = (err) => err?.data?.error?.message ?? err?.response?.data?.error?.message ?? err?.error?.message ?? err?.message ?? "Une erreur est survenue.";
45
+ const SPRING = "cubic-bezier(0.32, 0.72, 0, 1)";
46
+ const rise = keyframes`
47
+ from { opacity: 0; transform: translateY(14px); filter: blur(6px); }
48
+ to { opacity: 1; transform: translateY(0); filter: blur(0); }
49
+ `;
50
+ const reveal = css`
51
+ animation: ${rise} 720ms ${SPRING} both;
52
+ animation-delay: calc(var(--i, 0) * 70ms);
53
+ @media (prefers-reduced-motion: reduce) {
54
+ animation: none;
55
+ }
56
+ `;
57
+ const Shell = styled.div`
58
+ ${reveal};
59
+ width: 100%;
60
+ height: 100%;
61
+ background: ${({ theme }) => theme.colors.neutral150};
62
+ border: 1px solid ${({ theme }) => theme.colors.neutral150};
63
+ border-radius: 2rem;
64
+ padding: 0.5rem;
65
+ box-shadow:
66
+ 0 1px 2px rgba(33, 33, 52, 0.04),
67
+ 0 18px 40px -24px rgba(33, 33, 52, 0.22);
68
+ transition:
69
+ transform 480ms ${SPRING},
70
+ box-shadow 480ms ${SPRING};
71
+ ${({ $hover }) => $hover && css`
72
+ cursor: pointer;
73
+ &:hover {
74
+ transform: translateY(-3px);
75
+ box-shadow:
76
+ 0 1px 2px rgba(33, 33, 52, 0.04),
77
+ 0 28px 56px -24px rgba(33, 33, 52, 0.28);
78
+ }
79
+ &:active {
80
+ transform: translateY(-1px) scale(0.995);
81
+ }
82
+ `}
83
+ `;
84
+ const Core = styled(Box)`
85
+ position: relative;
86
+ background: ${({ theme }) => theme.colors.neutral0};
87
+ border-radius: calc(2rem - 0.5rem);
88
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
89
+ height: 100%;
90
+ ${({ $accent }) => $accent && css`
91
+ overflow: hidden;
92
+ &::before {
93
+ content: '';
94
+ position: absolute;
95
+ top: -60px;
96
+ right: -60px;
97
+ width: 180px;
98
+ height: 180px;
99
+ border-radius: 50%;
100
+ background: radial-gradient(circle, ${$accent}33 0%, ${$accent}00 70%);
101
+ pointer-events: none;
102
+ }
103
+ `}
104
+ `;
105
+ const Card = ({ style, onClick, className, accent, hover, index, children, ...rest }) => /* @__PURE__ */ jsx(
106
+ Shell,
107
+ {
108
+ style: { ...index != null ? { "--i": index } : {}, ...style },
109
+ onClick,
110
+ className,
111
+ $hover: Boolean(hover || onClick),
112
+ children: /* @__PURE__ */ jsx(Core, { $accent: accent, ...rest, children })
113
+ }
114
+ );
115
+ const Eyebrow = styled(Typography).attrs({ variant: "sigma", tag: "p" })`
116
+ letter-spacing: 0.18em;
117
+ text-transform: uppercase;
118
+ font-size: 1rem;
119
+ color: ${({ theme }) => theme.colors.neutral500};
120
+ `;
121
+ const Section = ({ title, eyebrow, help, aside, children, index, accent, ...rest }) => /* @__PURE__ */ jsxs(Card, { padding: 6, index, accent, ...rest, children: [
122
+ title || aside ? /* @__PURE__ */ jsxs(
123
+ Flex,
124
+ {
125
+ justifyContent: "space-between",
126
+ alignItems: "flex-start",
127
+ paddingBottom: help ? 2 : 5,
128
+ gap: 4,
129
+ children: [
130
+ /* @__PURE__ */ jsxs(Box, { children: [
131
+ eyebrow ? /* @__PURE__ */ jsx(Eyebrow, { paddingBottom: 1, children: eyebrow }) : null,
132
+ typeof title === "string" ? /* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", fontWeight: "bold", children: title }) : title
133
+ ] }),
134
+ aside
135
+ ]
136
+ }
137
+ ) : null,
138
+ help ? /* @__PURE__ */ jsx(
139
+ Typography,
140
+ {
141
+ variant: "pi",
142
+ textColor: "neutral600",
143
+ tag: "p",
144
+ paddingBottom: 5,
145
+ style: { maxWidth: "72ch" },
146
+ children: help
147
+ }
148
+ ) : null,
149
+ children
150
+ ] });
151
+ const Big = styled(Typography)`
152
+ font-size: 3.2rem;
153
+ line-height: 1;
154
+ font-weight: 700;
155
+ letter-spacing: -0.035em;
156
+ font-variant-numeric: tabular-nums;
157
+ `;
158
+ const StatTile = ({ label, value, hint, accent, icon, index, children }) => /* @__PURE__ */ jsxs(Card, { padding: 5, accent, index, children: [
159
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
160
+ /* @__PURE__ */ jsx(Eyebrow, { children: label }),
161
+ icon ? /* @__PURE__ */ jsx(
162
+ Box,
163
+ {
164
+ style: {
165
+ color: accent ?? "#8E8EA9",
166
+ display: "inline-flex",
167
+ width: 32,
168
+ height: 32,
169
+ borderRadius: 10,
170
+ alignItems: "center",
171
+ justifyContent: "center",
172
+ background: `${accent ?? "#8E8EA9"}14`
173
+ },
174
+ children: icon
175
+ }
176
+ ) : null
177
+ ] }),
178
+ /* @__PURE__ */ jsx(Box, { paddingTop: 4, paddingBottom: 1, children: /* @__PURE__ */ jsx(Big, { tag: "p", children: value }) }),
179
+ hint ? /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", tag: "p", children: hint }) : null,
180
+ children
181
+ ] });
182
+ const PillBtn = styled.button`
183
+ display: inline-flex;
184
+ align-items: center;
185
+ gap: 1rem;
186
+ padding: 0.4rem 0.4rem 0.4rem 1.6rem;
187
+ border-radius: 999px;
188
+ border: 0;
189
+ cursor: pointer;
190
+ font: inherit;
191
+ font-size: 1.4rem;
192
+ font-weight: 600;
193
+ color: ${({ theme, $tone }) => $tone === "light" ? theme.colors.neutral800 : theme.colors.neutral0};
194
+ background: ${({ theme, $tone }) => $tone === "light" ? theme.colors.neutral0 : theme.colors.neutral800};
195
+ box-shadow:
196
+ inset 0 1px 0 rgba(255, 255, 255, 0.12),
197
+ 0 10px 24px -12px rgba(33, 33, 52, 0.45);
198
+ transition:
199
+ transform 420ms ${SPRING},
200
+ box-shadow 420ms ${SPRING};
201
+ span.disc {
202
+ display: inline-flex;
203
+ align-items: center;
204
+ justify-content: center;
205
+ width: 3rem;
206
+ height: 3rem;
207
+ border-radius: 50%;
208
+ background: ${({ $tone }) => $tone === "light" ? "rgba(33,33,52,0.06)" : "rgba(255,255,255,0.14)"};
209
+ transition: transform 420ms ${SPRING};
210
+ svg {
211
+ width: 1.4rem;
212
+ height: 1.4rem;
213
+ }
214
+ }
215
+ &:hover {
216
+ transform: translateY(-1px);
217
+ box-shadow:
218
+ inset 0 1px 0 rgba(255, 255, 255, 0.12),
219
+ 0 16px 30px -12px rgba(33, 33, 52, 0.5);
220
+ }
221
+ &:hover span.disc {
222
+ transform: translate(2px, -1px) scale(1.06);
223
+ }
224
+ &:active {
225
+ transform: scale(0.98);
226
+ }
227
+ `;
228
+ const Pill = ({ children, onClick, tone = "dark", icon = /* @__PURE__ */ jsx(ArrowRight, {}) }) => /* @__PURE__ */ jsxs(PillBtn, { type: "button", onClick, $tone: tone, children: [
229
+ children,
230
+ /* @__PURE__ */ jsx("span", { className: "disc", "aria-hidden": true, children: icon })
231
+ ] });
232
+ const Dot = styled.span`
233
+ display: inline-block;
234
+ width: 10px;
235
+ height: 10px;
236
+ border-radius: 50%;
237
+ background: ${({ $color }) => $color};
238
+ box-shadow:
239
+ 0 0 0 2px ${({ theme }) => theme.colors.neutral0},
240
+ 0 0 0 3px ${({ $color }) => $color}33;
241
+ `;
242
+ const RarityBadge = ({ season, rarity }) => {
243
+ const meta = rarityOf(season, rarity);
244
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", style: { display: "inline-flex" }, children: [
245
+ /* @__PURE__ */ jsx(Dot, { $color: meta.color }),
246
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "semiBold", children: meta.label })
247
+ ] });
248
+ };
249
+ const STATUS_LABEL = {
250
+ active: "Active",
251
+ pending: "Pending",
252
+ fulfilled: "Handed over",
253
+ accepted: "Accepted",
254
+ draft: "Draft",
255
+ archived: "Archived",
256
+ cancelled: "Cancelled",
257
+ rejected: "Rejected",
258
+ expired: "Expired",
259
+ open: "Open",
260
+ closed: "Closed",
261
+ inactive: "Inactive",
262
+ live: "Live",
263
+ scheduled: "Scheduled"
264
+ };
265
+ const StatusBadge = ({ status, label }) => {
266
+ const map = {
267
+ active: "success",
268
+ live: "success",
269
+ open: "success",
270
+ pending: "warning",
271
+ scheduled: "warning",
272
+ fulfilled: "success",
273
+ accepted: "success",
274
+ draft: "secondary",
275
+ archived: "neutral",
276
+ inactive: "neutral",
277
+ closed: "neutral",
278
+ cancelled: "danger",
279
+ rejected: "danger",
280
+ expired: "neutral"
281
+ };
282
+ const v = map[status] ?? "neutral";
283
+ return /* @__PURE__ */ jsx(Badge, { backgroundColor: `${v}100`, textColor: `${v}700`, size: "S", children: label ?? STATUS_LABEL[status] ?? status });
284
+ };
285
+ const Sparkline = ({ points = [], color = "currentColor", height = 36 }) => {
286
+ const w = 160;
287
+ const max = Math.max(1, ...points);
288
+ const step = points.length > 1 ? w / (points.length - 1) : w;
289
+ const d = points.map(
290
+ (p, i) => `${i === 0 ? "M" : "L"}${(i * step).toFixed(1)},${(height - p / max * (height - 4) - 2).toFixed(1)}`
291
+ ).join(" ");
292
+ const id = `sp-${color.replace(/[^a-z0-9]/gi, "")}`;
293
+ return /* @__PURE__ */ jsxs("svg", { width: w, height, viewBox: `0 0 ${w} ${height}`, role: "img", "aria-label": "trend", children: [
294
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id, x1: "0", y1: "0", x2: "0", y2: "1", children: [
295
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: "0.25" }),
296
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
297
+ ] }) }),
298
+ d ? /* @__PURE__ */ jsx("path", { d: `${d} L${w},${height} L0,${height} Z`, fill: `url(#${id})` }) : null,
299
+ /* @__PURE__ */ jsx(
300
+ "path",
301
+ {
302
+ d,
303
+ fill: "none",
304
+ stroke: color,
305
+ strokeWidth: "2",
306
+ strokeLinecap: "round",
307
+ strokeLinejoin: "round"
308
+ }
309
+ )
310
+ ] });
311
+ };
312
+ const Empty = ({ title, content, action }) => /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(
313
+ EmptyStateLayout,
314
+ {
315
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" }),
316
+ content: title ? `${title} ${content ?? ""}`.trim() : content,
317
+ action,
318
+ shadow: "none"
319
+ }
320
+ ) });
321
+ const Mono = styled(Typography)`
322
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
323
+ letter-spacing: 0.04em;
324
+ font-variant-numeric: tabular-nums;
325
+ `;
326
+ const Bar = ({ value, max, color }) => {
327
+ const w = max ? Math.min(100, Math.round(value / max * 100)) : 0;
328
+ return /* @__PURE__ */ jsx(Box, { background: "neutral150", hasRadius: true, style: { height: 8, overflow: "hidden" }, children: /* @__PURE__ */ jsx(
329
+ Box,
330
+ {
331
+ style: {
332
+ width: `${w}%`,
333
+ height: "100%",
334
+ borderRadius: 999,
335
+ background: color ? `linear-gradient(90deg, ${color}, ${color}cc)` : "linear-gradient(90deg, #FF7900, #FACC15)",
336
+ transition: `width 700ms ${SPRING}`
337
+ }
338
+ }
339
+ ) });
340
+ };
341
+ const introKey = (k) => `tcg.intro.${k}`;
342
+ const recallCollapsed = (k) => {
343
+ try {
344
+ return window.localStorage.getItem(introKey(k)) === "1";
345
+ } catch {
346
+ return false;
347
+ }
348
+ };
349
+ const rememberCollapsed = (k, v) => {
350
+ try {
351
+ if (v) window.localStorage.setItem(introKey(k), "1");
352
+ else window.localStorage.removeItem(introKey(k));
353
+ } catch {
354
+ }
355
+ };
356
+ const IntroShell = styled.div`
357
+ ${reveal};
358
+ position: relative;
359
+ overflow: hidden;
360
+ border-radius: 2rem;
361
+ padding: 0.5rem;
362
+ background: linear-gradient(135deg, #eef0ff 0%, #f6f6f9 55%, #fff4ea 100%);
363
+ box-shadow: 0 18px 40px -28px rgba(73, 69, 255, 0.35);
364
+ `;
365
+ const IntroCore = styled.div`
366
+ position: relative;
367
+ border-radius: calc(2rem - 0.5rem);
368
+ background: rgba(255, 255, 255, 0.72);
369
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
370
+ padding: ${({ $collapsed }) => $collapsed ? "1rem 1.6rem" : "2.4rem 2.8rem"};
371
+ transition: padding 420ms ${SPRING};
372
+ `;
373
+ const StepNo = styled.span`
374
+ display: inline-flex;
375
+ align-items: center;
376
+ justify-content: center;
377
+ width: 2.4rem;
378
+ height: 2.4rem;
379
+ border-radius: 50%;
380
+ flex-shrink: 0;
381
+ font-size: 1.1rem;
382
+ font-weight: 700;
383
+ background: ${({ theme }) => theme.colors.neutral800};
384
+ color: ${({ theme }) => theme.colors.neutral0};
385
+ `;
386
+ const Intro = ({ id, title, body = [], steps = [], links = [] }) => {
387
+ const navigate = useNavigate();
388
+ const [collapsed, setCollapsed] = useState(() => recallCollapsed(id));
389
+ const toggle = () => {
390
+ rememberCollapsed(id, !collapsed);
391
+ setCollapsed(!collapsed);
392
+ };
393
+ return /* @__PURE__ */ jsx(Box, { marginBottom: 7, children: /* @__PURE__ */ jsx(IntroShell, { children: /* @__PURE__ */ jsxs(IntroCore, { $collapsed: collapsed, children: [
394
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", gap: 4, children: [
395
+ /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", children: [
396
+ /* @__PURE__ */ jsx(Box, { style: { color: "#4945FF", display: "flex" }, children: /* @__PURE__ */ jsx(Lightbulb, { width: "1.8rem", height: "1.8rem" }) }),
397
+ /* @__PURE__ */ jsxs(Box, { children: [
398
+ collapsed ? null : /* @__PURE__ */ jsx(Eyebrow, { children: "Guide" }),
399
+ /* @__PURE__ */ jsx(Typography, { variant: collapsed ? "omega" : "beta", fontWeight: "bold", tag: "h2", children: title })
400
+ ] })
401
+ ] }),
402
+ /* @__PURE__ */ jsx(
403
+ Button,
404
+ {
405
+ variant: "ghost",
406
+ size: "S",
407
+ onClick: toggle,
408
+ endIcon: collapsed ? /* @__PURE__ */ jsx(ChevronDown, {}) : /* @__PURE__ */ jsx(ChevronUp, {}),
409
+ children: collapsed ? "Show the guide" : "Hide"
410
+ }
411
+ )
412
+ ] }),
413
+ collapsed ? null : /* @__PURE__ */ jsxs(Flex, { gap: 10, alignItems: "flex-start", paddingTop: 4, wrap: "wrap", children: [
414
+ /* @__PURE__ */ jsxs(Box, { style: { flex: "2 1 360px", minWidth: 0 }, children: [
415
+ body.map((p, i) => /* @__PURE__ */ jsx(
416
+ Typography,
417
+ {
418
+ tag: "p",
419
+ textColor: "neutral700",
420
+ paddingBottom: 3,
421
+ style: { maxWidth: "68ch", lineHeight: 1.6 },
422
+ children: p
423
+ },
424
+ i
425
+ )),
426
+ links.length ? /* @__PURE__ */ jsx(Flex, { gap: 3, paddingTop: 2, wrap: "wrap", children: links.map((l) => /* @__PURE__ */ jsx(Pill, { tone: "light", onClick: () => navigate(l.to), children: l.label }, l.to)) }) : null
427
+ ] }),
428
+ steps.length ? /* @__PURE__ */ jsxs(Box, { style: { flex: "1 1 260px", minWidth: 0 }, children: [
429
+ /* @__PURE__ */ jsx(Eyebrow, { paddingBottom: 3, children: "How to" }),
430
+ /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: steps.map((s, i) => {
431
+ const label = typeof s === "string" ? s : s.label;
432
+ const to = typeof s === "string" ? null : s.to;
433
+ return /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", children: [
434
+ /* @__PURE__ */ jsx(StepNo, { children: i + 1 }),
435
+ to ? /* @__PURE__ */ jsx(
436
+ Button,
437
+ {
438
+ variant: "ghost",
439
+ size: "S",
440
+ onClick: () => navigate(to),
441
+ style: { padding: 0 },
442
+ children: label
443
+ }
444
+ ) : /* @__PURE__ */ jsx(Typography, { variant: "omega", children: label })
445
+ ] }, i);
446
+ }) })
447
+ ] }) : null
448
+ ] })
449
+ ] }) }) });
450
+ };
451
+ const StepRow = styled(Flex)`
452
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
453
+ &:first-child {
454
+ border-top: none;
455
+ }
456
+ `;
457
+ const Circle = styled.span`
458
+ display: inline-flex;
459
+ width: 2.4rem;
460
+ height: 2.4rem;
461
+ border-radius: 50%;
462
+ border: 2px solid ${({ theme }) => theme.colors.neutral300};
463
+ flex-shrink: 0;
464
+ `;
465
+ const SetupSteps = ({ steps }) => {
466
+ const navigate = useNavigate();
467
+ return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", children: steps.map((s, i) => /* @__PURE__ */ jsxs(StepRow, { gap: 4, alignItems: "center", paddingTop: 4, paddingBottom: 4, children: [
468
+ s.done ? /* @__PURE__ */ jsx(Box, { style: { color: "#328048", display: "flex" }, children: /* @__PURE__ */ jsx(CheckCircle, { width: "2.4rem", height: "2.4rem" }) }) : /* @__PURE__ */ jsx(Circle, {}),
469
+ /* @__PURE__ */ jsxs(Box, { style: { flex: 1, minWidth: 0 }, children: [
470
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
471
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: s.done ? "neutral600" : "neutral800", children: s.title }),
472
+ s.count ? /* @__PURE__ */ jsx(Badge, { size: "S", children: s.count }) : null
473
+ ] }),
474
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", tag: "p", children: s.help })
475
+ ] }),
476
+ s.to ? /* @__PURE__ */ jsx(
477
+ Button,
478
+ {
479
+ size: "S",
480
+ variant: s.done ? "tertiary" : "secondary",
481
+ onClick: () => navigate(s.to),
482
+ children: s.done ? "Open" : s.cta ?? "Do it"
483
+ }
484
+ ) : null
485
+ ] }, i)) });
486
+ };
487
+ const BASE = `/${PLUGIN_ID}`;
488
+ const TAG = Object.freeze({
489
+ DASH: "TcgDashboard",
490
+ SEASON: "TcgSeason",
491
+ CARD: "TcgCard",
492
+ PACK: "TcgPack",
493
+ PLAYER: "TcgPlayer",
494
+ REDEMPTION: "TcgRedemption",
495
+ DROP: "TcgDrop",
496
+ BOOST: "TcgBoost",
497
+ REWARD: "TcgReward",
498
+ SET: "TcgSet",
499
+ BADGE: "TcgBadge"
500
+ });
501
+ const unwrap = (res) => res && typeof res === "object" && "data" in res ? res.data : res;
502
+ const qs = (params = {}) => {
503
+ const clean = Object.fromEntries(
504
+ Object.entries(params).filter(([, v]) => v !== void 0 && v !== null && v !== "")
505
+ );
506
+ const s = new URLSearchParams(clean).toString();
507
+ return s ? `?${s}` : "";
508
+ };
509
+ const enc = encodeURIComponent;
510
+ const api = adminApi.enhanceEndpoints({ addTagTypes: Object.values(TAG) }).injectEndpoints({
511
+ endpoints: (b) => ({
512
+ // dashboard
513
+ getDashboard: b.query({
514
+ query: (season) => `${BASE}/dashboard${qs({ season })}`,
515
+ transformResponse: unwrap,
516
+ providesTags: [TAG.DASH]
517
+ }),
518
+ getLeaderboard: b.query({
519
+ query: ({ season, limit }) => `${BASE}/seasons/${enc(season)}/leaderboard${qs({ limit })}`,
520
+ transformResponse: unwrap,
521
+ providesTags: [TAG.DASH]
522
+ }),
523
+ getPulls: b.query({
524
+ query: ({ season, ...p }) => `${BASE}/seasons/${enc(season)}/pulls${qs(p)}`,
525
+ providesTags: [TAG.DASH]
526
+ }),
527
+ // seasons
528
+ getSeasons: b.query({
529
+ query: () => `${BASE}/seasons`,
530
+ transformResponse: unwrap,
531
+ providesTags: [TAG.SEASON]
532
+ }),
533
+ getSeasonDefaults: b.query({
534
+ query: () => `${BASE}/seasons/defaults`,
535
+ transformResponse: unwrap
536
+ }),
537
+ getSeason: b.query({
538
+ query: (ref) => `${BASE}/seasons/${enc(ref)}`,
539
+ transformResponse: unwrap,
540
+ providesTags: (_r, _e, ref) => [{ type: TAG.SEASON, id: ref }, TAG.SEASON]
541
+ }),
542
+ createSeason: b.mutation({
543
+ query: (data) => ({ url: `${BASE}/seasons`, method: "POST", data: { data } }),
544
+ invalidatesTags: [TAG.SEASON, TAG.DASH]
545
+ }),
546
+ updateSeason: b.mutation({
547
+ query: ({ ref, data }) => ({
548
+ url: `${BASE}/seasons/${enc(ref)}`,
549
+ method: "PUT",
550
+ data: { data }
551
+ }),
552
+ invalidatesTags: [TAG.SEASON, TAG.DASH]
553
+ }),
554
+ deleteSeason: b.mutation({
555
+ query: (ref) => ({ url: `${BASE}/seasons/${enc(ref)}`, method: "DELETE" }),
556
+ invalidatesTags: [TAG.SEASON, TAG.DASH]
557
+ }),
558
+ // cards
559
+ getCards: b.query({
560
+ query: ({ season, ...p }) => `${BASE}/seasons/${enc(season)}/cards${qs(p)}`,
561
+ providesTags: [TAG.CARD]
562
+ }),
563
+ createCard: b.mutation({
564
+ query: ({ season, data }) => ({
565
+ url: `${BASE}/seasons/${enc(season)}/cards`,
566
+ method: "POST",
567
+ data: { data }
568
+ }),
569
+ invalidatesTags: [TAG.CARD, TAG.SEASON, TAG.DASH]
570
+ }),
571
+ updateCard: b.mutation({
572
+ query: ({ season, id, data }) => ({
573
+ url: `${BASE}/seasons/${enc(season)}/cards/${enc(id)}`,
574
+ method: "PUT",
575
+ data: { data }
576
+ }),
577
+ invalidatesTags: [TAG.CARD, TAG.PACK]
578
+ }),
579
+ deleteCard: b.mutation({
580
+ query: ({ season, id }) => ({
581
+ url: `${BASE}/seasons/${enc(season)}/cards/${enc(id)}`,
582
+ method: "DELETE"
583
+ }),
584
+ invalidatesTags: [TAG.CARD, TAG.PACK, TAG.SEASON]
585
+ }),
586
+ // packs
587
+ getPacks: b.query({
588
+ query: (season) => `${BASE}/seasons/${enc(season)}/packs`,
589
+ transformResponse: unwrap,
590
+ providesTags: [TAG.PACK]
591
+ }),
592
+ getPack: b.query({
593
+ query: ({ season, id }) => `${BASE}/seasons/${enc(season)}/packs/${enc(id)}`,
594
+ transformResponse: unwrap,
595
+ providesTags: (_r, _e, { id }) => [{ type: TAG.PACK, id }, TAG.PACK]
596
+ }),
597
+ createPack: b.mutation({
598
+ query: ({ season, data }) => ({
599
+ url: `${BASE}/seasons/${enc(season)}/packs`,
600
+ method: "POST",
601
+ data: { data }
602
+ }),
603
+ invalidatesTags: [TAG.PACK, TAG.SEASON, TAG.DASH]
604
+ }),
605
+ updatePack: b.mutation({
606
+ query: ({ season, id, data }) => ({
607
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}`,
608
+ method: "PUT",
609
+ data: { data }
610
+ }),
611
+ invalidatesTags: [TAG.PACK]
612
+ }),
613
+ deletePack: b.mutation({
614
+ query: ({ season, id }) => ({
615
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}`,
616
+ method: "DELETE"
617
+ }),
618
+ invalidatesTags: [TAG.PACK, TAG.SEASON]
619
+ }),
620
+ setPackCards: b.mutation({
621
+ query: ({ season, id, cards }) => ({
622
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/cards`,
623
+ method: "PUT",
624
+ data: { data: { cards } }
625
+ }),
626
+ invalidatesTags: [TAG.PACK]
627
+ }),
628
+ packQR: b.mutation({
629
+ query: ({ season, id }) => ({
630
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/qr`,
631
+ method: "POST",
632
+ data: {}
633
+ }),
634
+ transformResponse: unwrap
635
+ }),
636
+ rotatePackSecret: b.mutation({
637
+ query: ({ season, id }) => ({
638
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/rotate-secret`,
639
+ method: "POST",
640
+ data: {}
641
+ })
642
+ }),
643
+ simulatePack: b.query({
644
+ query: ({ season, id, n, drop }) => `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/simulate${qs({ n, drop })}`,
645
+ transformResponse: unwrap
646
+ }),
647
+ // drops
648
+ getDrops: b.query({
649
+ query: ({ season, id }) => `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops`,
650
+ transformResponse: unwrap,
651
+ providesTags: [TAG.DROP]
652
+ }),
653
+ getDrop: b.query({
654
+ query: ({ season, id, dropId }) => `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops/${enc(dropId)}`,
655
+ transformResponse: unwrap,
656
+ providesTags: (_r, _e, { dropId }) => [{ type: TAG.DROP, id: dropId }, TAG.DROP]
657
+ }),
658
+ createDrop: b.mutation({
659
+ query: ({ season, id, data }) => ({
660
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops`,
661
+ method: "POST",
662
+ data: { data }
663
+ }),
664
+ invalidatesTags: [TAG.DROP, TAG.PACK]
665
+ }),
666
+ updateDrop: b.mutation({
667
+ query: ({ season, id, dropId, data }) => ({
668
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops/${enc(dropId)}`,
669
+ method: "PUT",
670
+ data: { data }
671
+ }),
672
+ invalidatesTags: [TAG.DROP, TAG.PACK]
673
+ }),
674
+ deleteDrop: b.mutation({
675
+ query: ({ season, id, dropId }) => ({
676
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops/${enc(dropId)}`,
677
+ method: "DELETE"
678
+ }),
679
+ invalidatesTags: [TAG.DROP, TAG.PACK]
680
+ }),
681
+ setDropCards: b.mutation({
682
+ query: ({ season, id, dropId, cards }) => ({
683
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops/${enc(dropId)}/cards`,
684
+ method: "PUT",
685
+ data: { data: { cards } }
686
+ }),
687
+ invalidatesTags: [TAG.DROP, TAG.CARD]
688
+ }),
689
+ dropQR: b.mutation({
690
+ query: ({ season, id, dropId }) => ({
691
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops/${enc(dropId)}/qr`,
692
+ method: "POST",
693
+ data: {}
694
+ }),
695
+ transformResponse: unwrap
696
+ }),
697
+ rotateDropSecret: b.mutation({
698
+ query: ({ season, id, dropId }) => ({
699
+ url: `${BASE}/seasons/${enc(season)}/packs/${enc(id)}/drops/${enc(dropId)}/rotate-secret`,
700
+ method: "POST",
701
+ data: {}
702
+ })
703
+ }),
704
+ // boosts
705
+ getBoosts: b.query({
706
+ query: (season) => `${BASE}/seasons/${enc(season)}/boosts`,
707
+ transformResponse: unwrap,
708
+ providesTags: [TAG.BOOST]
709
+ }),
710
+ createBoost: b.mutation({
711
+ query: ({ season, data }) => ({
712
+ url: `${BASE}/seasons/${enc(season)}/boosts`,
713
+ method: "POST",
714
+ data: { data }
715
+ }),
716
+ invalidatesTags: [TAG.BOOST, TAG.DASH]
717
+ }),
718
+ updateBoost: b.mutation({
719
+ query: ({ season, id, data }) => ({
720
+ url: `${BASE}/seasons/${enc(season)}/boosts/${enc(id)}`,
721
+ method: "PUT",
722
+ data: { data }
723
+ }),
724
+ invalidatesTags: [TAG.BOOST, TAG.DASH]
725
+ }),
726
+ deleteBoost: b.mutation({
727
+ query: ({ season, id }) => ({
728
+ url: `${BASE}/seasons/${enc(season)}/boosts/${enc(id)}`,
729
+ method: "DELETE"
730
+ }),
731
+ invalidatesTags: [TAG.BOOST, TAG.DASH]
732
+ }),
733
+ // rewards
734
+ getRewards: b.query({
735
+ query: (season) => `${BASE}/seasons/${enc(season)}/rewards`,
736
+ transformResponse: unwrap,
737
+ providesTags: [TAG.REWARD]
738
+ }),
739
+ createReward: b.mutation({
740
+ query: ({ season, data }) => ({
741
+ url: `${BASE}/seasons/${enc(season)}/rewards`,
742
+ method: "POST",
743
+ data: { data }
744
+ }),
745
+ invalidatesTags: [TAG.REWARD, TAG.DASH]
746
+ }),
747
+ updateReward: b.mutation({
748
+ query: ({ season, id, data }) => ({
749
+ url: `${BASE}/seasons/${enc(season)}/rewards/${enc(id)}`,
750
+ method: "PUT",
751
+ data: { data }
752
+ }),
753
+ invalidatesTags: [TAG.REWARD, TAG.DASH]
754
+ }),
755
+ deleteReward: b.mutation({
756
+ query: ({ season, id }) => ({
757
+ url: `${BASE}/seasons/${enc(season)}/rewards/${enc(id)}`,
758
+ method: "DELETE"
759
+ }),
760
+ invalidatesTags: [TAG.REWARD]
761
+ }),
762
+ // sets & badges
763
+ getSets: b.query({
764
+ query: (season) => `${BASE}/seasons/${enc(season)}/sets`,
765
+ transformResponse: unwrap,
766
+ providesTags: [TAG.SET]
767
+ }),
768
+ createSet: b.mutation({
769
+ query: ({ season, data }) => ({
770
+ url: `${BASE}/seasons/${enc(season)}/sets`,
771
+ method: "POST",
772
+ data: { data }
773
+ }),
774
+ invalidatesTags: [TAG.SET]
775
+ }),
776
+ updateSet: b.mutation({
777
+ query: ({ season, id, data }) => ({
778
+ url: `${BASE}/seasons/${enc(season)}/sets/${enc(id)}`,
779
+ method: "PUT",
780
+ data: { data }
781
+ }),
782
+ invalidatesTags: [TAG.SET]
783
+ }),
784
+ deleteSet: b.mutation({
785
+ query: ({ season, id }) => ({
786
+ url: `${BASE}/seasons/${enc(season)}/sets/${enc(id)}`,
787
+ method: "DELETE"
788
+ }),
789
+ invalidatesTags: [TAG.SET]
790
+ }),
791
+ getBadges: b.query({
792
+ query: (season) => `${BASE}/seasons/${enc(season)}/badges`,
793
+ transformResponse: unwrap,
794
+ providesTags: [TAG.BADGE]
795
+ }),
796
+ createBadge: b.mutation({
797
+ query: ({ season, data }) => ({
798
+ url: `${BASE}/seasons/${enc(season)}/badges`,
799
+ method: "POST",
800
+ data: { data }
801
+ }),
802
+ invalidatesTags: [TAG.BADGE]
803
+ }),
804
+ updateBadge: b.mutation({
805
+ query: ({ season, id, data }) => ({
806
+ url: `${BASE}/seasons/${enc(season)}/badges/${enc(id)}`,
807
+ method: "PUT",
808
+ data: { data }
809
+ }),
810
+ invalidatesTags: [TAG.BADGE]
811
+ }),
812
+ deleteBadge: b.mutation({
813
+ query: ({ season, id }) => ({
814
+ url: `${BASE}/seasons/${enc(season)}/badges/${enc(id)}`,
815
+ method: "DELETE"
816
+ }),
817
+ invalidatesTags: [TAG.BADGE]
818
+ }),
819
+ seedBadges: b.mutation({
820
+ query: (season) => ({
821
+ url: `${BASE}/seasons/${enc(season)}/badges/seed`,
822
+ method: "POST",
823
+ data: {}
824
+ }),
825
+ invalidatesTags: [TAG.BADGE]
826
+ }),
827
+ // players
828
+ getPlayers: b.query({ query: (p) => `${BASE}/players${qs(p)}`, providesTags: [TAG.PLAYER] }),
829
+ getPlayer: b.query({
830
+ query: ({ id, season }) => `${BASE}/players/${enc(id)}${qs({ season })}`,
831
+ transformResponse: unwrap,
832
+ providesTags: (_r, _e, { id }) => [{ type: TAG.PLAYER, id }]
833
+ }),
834
+ setPlayerActive: b.mutation({
835
+ query: ({ id, isActive }) => ({
836
+ url: `${BASE}/players/${enc(id)}/active`,
837
+ method: "PUT",
838
+ data: { data: { isActive } }
839
+ }),
840
+ invalidatesTags: [TAG.PLAYER]
841
+ }),
842
+ grantCard: b.mutation({
843
+ query: ({ id, cardId }) => ({
844
+ url: `${BASE}/players/${enc(id)}/grant`,
845
+ method: "POST",
846
+ data: { data: { cardId } }
847
+ }),
848
+ invalidatesTags: [TAG.PLAYER, TAG.DASH]
849
+ }),
850
+ // redemptions
851
+ getRedemptions: b.query({
852
+ query: (p) => `${BASE}/redemptions${qs(p)}`,
853
+ providesTags: [TAG.REDEMPTION]
854
+ }),
855
+ getRedemption: b.query({
856
+ query: (code) => `${BASE}/redemptions/${enc(code)}`,
857
+ transformResponse: unwrap,
858
+ providesTags: (_r, _e, code) => [{ type: TAG.REDEMPTION, id: code }]
859
+ }),
860
+ fulfillRedemption: b.mutation({
861
+ query: ({ code, note }) => ({
862
+ url: `${BASE}/redemptions/${enc(code)}/fulfill`,
863
+ method: "POST",
864
+ data: { data: { note } }
865
+ }),
866
+ invalidatesTags: [TAG.REDEMPTION, TAG.DASH]
867
+ }),
868
+ cancelRedemption: b.mutation({
869
+ query: ({ code, note }) => ({
870
+ url: `${BASE}/redemptions/${enc(code)}/cancel`,
871
+ method: "POST",
872
+ data: { data: { note } }
873
+ }),
874
+ invalidatesTags: [TAG.REDEMPTION, TAG.DASH, TAG.PLAYER]
875
+ }),
876
+ // settings
877
+ getSettings: b.query({ query: () => `${BASE}/settings`, transformResponse: unwrap })
878
+ })
879
+ });
880
+ const {
881
+ useGetDashboardQuery,
882
+ useGetLeaderboardQuery,
883
+ useGetPullsQuery,
884
+ useGetSeasonsQuery,
885
+ useGetSeasonDefaultsQuery,
886
+ useGetSeasonQuery,
887
+ useCreateSeasonMutation,
888
+ useUpdateSeasonMutation,
889
+ useDeleteSeasonMutation,
890
+ useGetCardsQuery,
891
+ useCreateCardMutation,
892
+ useUpdateCardMutation,
893
+ useDeleteCardMutation,
894
+ useGetPacksQuery,
895
+ useGetPackQuery,
896
+ useCreatePackMutation,
897
+ useUpdatePackMutation,
898
+ useDeletePackMutation,
899
+ useSetPackCardsMutation,
900
+ usePackQRMutation,
901
+ useRotatePackSecretMutation,
902
+ useLazySimulatePackQuery,
903
+ useGetDropsQuery,
904
+ useGetDropQuery,
905
+ useCreateDropMutation,
906
+ useUpdateDropMutation,
907
+ useDeleteDropMutation,
908
+ useSetDropCardsMutation,
909
+ useDropQRMutation,
910
+ useRotateDropSecretMutation,
911
+ useGetBoostsQuery,
912
+ useCreateBoostMutation,
913
+ useUpdateBoostMutation,
914
+ useDeleteBoostMutation,
915
+ useGetRewardsQuery,
916
+ useCreateRewardMutation,
917
+ useUpdateRewardMutation,
918
+ useDeleteRewardMutation,
919
+ useGetSetsQuery,
920
+ useCreateSetMutation,
921
+ useUpdateSetMutation,
922
+ useDeleteSetMutation,
923
+ useGetBadgesQuery,
924
+ useCreateBadgeMutation,
925
+ useUpdateBadgeMutation,
926
+ useDeleteBadgeMutation,
927
+ useSeedBadgesMutation,
928
+ useGetPlayersQuery,
929
+ useGetPlayerQuery,
930
+ useSetPlayerActiveMutation,
931
+ useGrantCardMutation,
932
+ useGetRedemptionsQuery,
933
+ useLazyGetRedemptionQuery,
934
+ useFulfillRedemptionMutation,
935
+ useCancelRedemptionMutation,
936
+ useGetSettingsQuery
937
+ } = api;
938
+ export {
939
+ useUpdateDropMutation as $,
940
+ useGetPacksQuery as A,
941
+ Bar as B,
942
+ Card as C,
943
+ useCreatePackMutation as D,
944
+ Eyebrow as E,
945
+ useGetPackQuery as F,
946
+ useUpdatePackMutation as G,
947
+ useSetPackCardsMutation as H,
948
+ Intro as I,
949
+ useDeletePackMutation as J,
950
+ useCreateDropMutation as K,
951
+ useLazySimulatePackQuery as L,
952
+ useGetPlayersQuery as M,
953
+ fmtDateTime as N,
954
+ useGetPlayerQuery as O,
955
+ Pill as P,
956
+ useSetPlayerActiveMutation as Q,
957
+ RarityBadge as R,
958
+ SPRING as S,
959
+ useGrantCardMutation as T,
960
+ useLazyGetRedemptionQuery as U,
961
+ useFulfillRedemptionMutation as V,
962
+ useCancelRedemptionMutation as W,
963
+ useGetRedemptionsQuery as X,
964
+ Mono as Y,
965
+ useGetPullsQuery as Z,
966
+ useGetDropQuery as _,
967
+ useGetDashboardQuery as a,
968
+ useSetDropCardsMutation as a0,
969
+ useDeleteDropMutation as a1,
970
+ useRotateDropSecretMutation as a2,
971
+ useDropQRMutation as a3,
972
+ useGetBoostsQuery as a4,
973
+ useCreateBoostMutation as a5,
974
+ useUpdateBoostMutation as a6,
975
+ useDeleteBoostMutation as a7,
976
+ useCreateRewardMutation as a8,
977
+ useUpdateRewardMutation as a9,
978
+ useDeleteRewardMutation as aa,
979
+ useCreateSetMutation as ab,
980
+ useUpdateSetMutation as ac,
981
+ useDeleteSetMutation as ad,
982
+ useCreateBadgeMutation as ae,
983
+ useUpdateBadgeMutation as af,
984
+ useDeleteBadgeMutation as ag,
985
+ useSeedBadgesMutation as ah,
986
+ useGetSettingsQuery as ai,
987
+ useGetLeaderboardQuery as b,
988
+ useGetRewardsQuery as c,
989
+ useGetSetsQuery as d,
990
+ useGetBadgesQuery as e,
991
+ Empty as f,
992
+ Section as g,
993
+ SetupSteps as h,
994
+ StatTile as i,
995
+ Sparkline as j,
996
+ fmtNumber as k,
997
+ StatusBadge as l,
998
+ fmtDate as m,
999
+ useGetSeasonDefaultsQuery as n,
1000
+ useGetSeasonQuery as o,
1001
+ useCreateSeasonMutation as p,
1002
+ useUpdateSeasonMutation as q,
1003
+ useDeleteSeasonMutation as r,
1004
+ errorMessage as s,
1005
+ timeAgo as t,
1006
+ useGetSeasonsQuery as u,
1007
+ useGetCardsQuery as v,
1008
+ useCreateCardMutation as w,
1009
+ useUpdateCardMutation as x,
1010
+ useDeleteCardMutation as y,
1011
+ rarityOf as z
1012
+ };