astrogators-shared-ui 0.4.4 → 0.6.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.
Files changed (29) hide show
  1. package/dist/index.css +2 -0
  2. package/dist/index.js +732 -791
  3. package/dist/{components → src/components}/display/Badge.d.ts +0 -1
  4. package/dist/{components → src/components}/display/Card.d.ts +0 -1
  5. package/dist/{components → src/components}/display/Modal.d.ts +0 -1
  6. package/dist/{components → src/components}/feedback/Loader.d.ts +0 -1
  7. package/dist/{components → src/components}/forms/AllyCodeDropdown.d.ts +0 -1
  8. package/dist/{components → src/components}/forms/Button.d.ts +0 -1
  9. package/dist/{components → src/components}/forms/Input.d.ts +0 -1
  10. package/dist/{components → src/components}/forms/Select.d.ts +0 -1
  11. package/dist/{components → src/components}/layout/Container.d.ts +0 -1
  12. package/dist/{components → src/components}/layout/Footer.d.ts +0 -1
  13. package/dist/{components → src/components}/layout/TopBar.d.ts +0 -1
  14. package/dist/{contexts → src/contexts}/AuthContext.d.ts +2 -1
  15. package/dist/{index.d.ts → src/index.d.ts} +0 -1
  16. package/package.json +18 -13
  17. package/dist/style.css +0 -1
  18. /package/dist/{components → src/components}/display/index.d.ts +0 -0
  19. /package/dist/{components → src/components}/feedback/index.d.ts +0 -0
  20. /package/dist/{components → src/components}/forms/index.d.ts +0 -0
  21. /package/dist/{components → src/components}/layout/index.d.ts +0 -0
  22. /package/dist/{services → src/services}/allyCodeStorage.d.ts +0 -0
  23. /package/dist/{services → src/services}/api.d.ts +0 -0
  24. /package/dist/{services → src/services}/auth.d.ts +0 -0
  25. /package/dist/{types → src/types}/api.d.ts +0 -0
  26. /package/dist/{types → src/types}/index.d.ts +0 -0
  27. /package/dist/{types → src/types}/mod.d.ts +0 -0
  28. /package/dist/{types → src/types}/user.d.ts +0 -0
  29. /package/dist/{utils → src/utils}/formatAllyCode.d.ts +0 -0
package/dist/index.js CHANGED
@@ -1,791 +1,732 @@
1
- var ue = Object.defineProperty;
2
- var he = (e, s, t) => s in e ? ue(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t;
3
- var R = (e, s, t) => he(e, typeof s != "symbol" ? s + "" : s, t);
4
- import { jsx as r, jsxs as m, Fragment as ge } from "react/jsx-runtime";
5
- import ae, { createContext as fe, useState as b, useEffect as j, useCallback as S, useContext as pe } from "react";
6
- const ye = "_container_u3o0e_1", ve = "_padding_u3o0e_7", X = {
7
- container: ye,
8
- padding: ve,
9
- "maxWidth-sm": "_maxWidth-sm_u3o0e_12",
10
- "maxWidth-md": "_maxWidth-md_u3o0e_16",
11
- "maxWidth-lg": "_maxWidth-lg_u3o0e_20",
12
- "maxWidth-xl": "_maxWidth-xl_u3o0e_24",
13
- "maxWidth-full": "_maxWidth-full_u3o0e_28"
14
- }, vs = ({
15
- children: e,
16
- maxWidth: s = "xl",
17
- padding: t = !0,
18
- className: o = "",
19
- style: d
20
- }) => /* @__PURE__ */ r(
21
- "div",
22
- {
23
- className: `${X.container} ${X[`maxWidth-${s}`]} ${t ? X.padding : ""} ${o}`,
24
- style: d,
25
- children: e
26
- }
27
- ), $e = "_topBar_10g3c_1", be = "_content_10g3c_13", we = "_left_10g3c_23", Ne = "_right_10g3c_30", Ae = "_logo_10g3c_36", P = {
28
- topBar: $e,
29
- content: be,
30
- left: we,
31
- right: Ne,
32
- logo: Ae
33
- }, $s = ({
34
- logo: e,
35
- leftContent: s,
36
- rightContent: t,
37
- className: o = ""
38
- }) => /* @__PURE__ */ r("header", { className: `${P.topBar} ${o}`, children: /* @__PURE__ */ m("div", { className: P.content, children: [
39
- /* @__PURE__ */ m("div", { className: P.left, children: [
40
- e && /* @__PURE__ */ r("div", { className: P.logo, children: e }),
41
- s
42
- ] }),
43
- /* @__PURE__ */ r("div", { className: P.right, children: t })
44
- ] }) }), Se = "_footer_zjuj8_1", xe = "_content_zjuj8_7", Te = "_defaultContent_zjuj8_13", Ce = "_copyright_zjuj8_21", ke = "_disclaimer_zjuj8_26", B = {
45
- footer: Se,
46
- content: xe,
47
- defaultContent: Te,
48
- copyright: Ce,
49
- disclaimer: ke
50
- }, bs = ({ children: e, className: s = "" }) => /* @__PURE__ */ r("footer", { className: `${B.footer} ${s}`, children: /* @__PURE__ */ r("div", { className: B.content, children: e || /* @__PURE__ */ m("div", { className: B.defaultContent, children: [
51
- /* @__PURE__ */ m("p", { className: B.copyright, children: [
52
- ",
53
- (/* @__PURE__ */ new Date()).getFullYear(),
54
- " The Astrogator's Table. All rights reserved."
55
- ] }),
56
- /* @__PURE__ */ r("p", { className: B.disclaimer, children: "Star Wars: Galaxy of Heroes is a trademark of Electronic Arts Inc." })
57
- ] }) }) }), Ee = "_button_159ms_1", We = "_sm_159ms_22", Ie = "_md_159ms_28", Le = "_lg_159ms_34", qe = "_primary_159ms_41", Re = "_secondary_159ms_55", Pe = "_outline_159ms_69", Be = "_ghost_159ms_80", Ue = "_danger_159ms_89", je = "_fullWidth_159ms_100", Fe = "_loading_159ms_105", De = "_loadingSpinner_159ms_110", Oe = "_spinner_159ms_116", ze = "_spin_159ms_116", Me = "_loadingText_159ms_131", x = {
58
- button: Ee,
59
- sm: We,
60
- md: Ie,
61
- lg: Le,
62
- primary: qe,
63
- secondary: Re,
64
- outline: Pe,
65
- ghost: Be,
66
- danger: Ue,
67
- fullWidth: je,
68
- loading: Fe,
69
- loadingSpinner: De,
70
- spinner: Oe,
71
- spin: ze,
72
- loadingText: Me
73
- }, M = ({
74
- children: e,
75
- variant: s = "primary",
76
- size: t = "md",
77
- fullWidth: o = !1,
78
- loading: d = !1,
79
- disabled: g = !1,
80
- className: c = "",
81
- ...l
82
- }) => /* @__PURE__ */ r(
83
- "button",
84
- {
85
- className: `${x.button} ${x[s]} ${x[t]} ${o ? x.fullWidth : ""} ${d ? x.loading : ""} ${c}`,
86
- disabled: g || d,
87
- ...l,
88
- children: d ? /* @__PURE__ */ m("span", { className: x.loadingSpinner, children: [
89
- /* @__PURE__ */ r("span", { className: x.spinner }),
90
- /* @__PURE__ */ r("span", { className: x.loadingText, children: e })
91
- ] }) : e
92
- }
93
- ), Je = "_inputWrapper_15t4g_1", He = "_fullWidth_15t4g_7", Ye = "_label_15t4g_11", Ge = "_required_15t4g_20", Ke = "_input_15t4g_1", Ve = "_error_15t4g_55", Qe = "_errorText_15t4g_63", Xe = "_helperText_15t4g_68", T = {
94
- inputWrapper: Je,
95
- fullWidth: He,
96
- label: Ye,
97
- required: Ge,
98
- input: Ke,
99
- error: Ve,
100
- errorText: Qe,
101
- helperText: Xe
102
- }, ne = ae.forwardRef(
103
- ({
104
- label: e,
105
- error: s,
106
- helperText: t,
107
- fullWidth: o = !1,
108
- className: d = "",
109
- id: g,
110
- ...c
111
- }, l) => {
112
- const i = g || `input-${Math.random().toString(36).substr(2, 9)}`, h = !!s;
113
- return /* @__PURE__ */ m("div", { className: `${T.inputWrapper} ${o ? T.fullWidth : ""} ${d}`, children: [
114
- e && /* @__PURE__ */ m("label", { htmlFor: i, className: T.label, children: [
115
- e,
116
- c.required && /* @__PURE__ */ r("span", { className: T.required, children: "*" })
117
- ] }),
118
- /* @__PURE__ */ r(
119
- "input",
120
- {
121
- ref: l,
122
- id: i,
123
- className: `${T.input} ${h ? T.error : ""}`,
124
- ...c
125
- }
126
- ),
127
- s && /* @__PURE__ */ r("span", { className: T.errorText, children: s }),
128
- t && !s && /* @__PURE__ */ r("span", { className: T.helperText, children: t })
129
- ] });
130
- }
131
- );
132
- ne.displayName = "Input";
133
- const Ze = "_selectWrapper_ir4bq_1", et = "_fullWidth_ir4bq_7", tt = "_label_ir4bq_11", st = "_required_ir4bq_20", ot = "_selectContainer_ir4bq_24", rt = "_select_ir4bq_1", at = "_error_ir4bq_63", nt = "_arrow_ir4bq_71", lt = "_errorText_ir4bq_81", ct = "_helperText_ir4bq_86", w = {
134
- selectWrapper: Ze,
135
- fullWidth: et,
136
- label: tt,
137
- required: st,
138
- selectContainer: ot,
139
- select: rt,
140
- error: at,
141
- arrow: nt,
142
- errorText: lt,
143
- helperText: ct
144
- }, le = ae.forwardRef(
145
- ({
146
- label: e,
147
- error: s,
148
- helperText: t,
149
- options: o,
150
- placeholder: d,
151
- fullWidth: g = !1,
152
- className: c = "",
153
- id: l,
154
- ...i
155
- }, h) => {
156
- const p = l || `select-${Math.random().toString(36).substr(2, 9)}`, N = !!s;
157
- return /* @__PURE__ */ m("div", { className: `${w.selectWrapper} ${g ? w.fullWidth : ""} ${c}`, children: [
158
- e && /* @__PURE__ */ m("label", { htmlFor: p, className: w.label, children: [
159
- e,
160
- i.required && /* @__PURE__ */ r("span", { className: w.required, children: "*" })
161
- ] }),
162
- /* @__PURE__ */ m("div", { className: w.selectContainer, children: [
163
- /* @__PURE__ */ m(
164
- "select",
165
- {
166
- ref: h,
167
- id: p,
168
- className: `${w.select} ${N ? w.error : ""}`,
169
- ...i,
170
- children: [
171
- d && /* @__PURE__ */ r("option", { value: "", disabled: !0, children: d }),
172
- o && o.map((f) => /* @__PURE__ */ r(
173
- "option",
174
- {
175
- value: f.value,
176
- disabled: f.disabled,
177
- children: f.label
178
- },
179
- f.value
180
- )),
181
- !o && i.children
182
- ]
183
- }
184
- ),
185
- /* @__PURE__ */ r("span", { className: w.arrow, children: "▼" })
186
- ] }),
187
- s && /* @__PURE__ */ r("span", { className: w.errorText, children: s }),
188
- t && !s && /* @__PURE__ */ r("span", { className: w.helperText, children: t })
189
- ] });
190
- }
191
- );
192
- le.displayName = "Select";
193
- const te = "astrogators_access_token", se = "astrogators_refresh_token", ce = () => localStorage.getItem(te), it = (e) => {
194
- localStorage.setItem(te, e);
195
- }, dt = () => {
196
- localStorage.removeItem(te);
197
- }, _t = () => localStorage.getItem(se), mt = (e) => {
198
- localStorage.setItem(se, e);
199
- }, ut = () => {
200
- localStorage.removeItem(se);
201
- }, ie = (e, s) => {
202
- it(e), mt(s);
203
- }, ee = () => {
204
- dt(), ut();
205
- }, ht = () => !!ce();
206
- class gt {
207
- constructor(s) {
208
- R(this, "baseURL");
209
- R(this, "onUnauthorized");
210
- R(this, "isRefreshing", !1);
211
- R(this, "refreshPromise", null);
212
- this.baseURL = s.baseURL, this.onUnauthorized = s.onUnauthorized;
213
- }
214
- async refreshAccessToken() {
215
- var d;
216
- const s = _t();
217
- if (!s)
218
- throw new Error("No refresh token available");
219
- const t = await fetch(`${this.baseURL}/api/v1/auth/refresh-token`, {
220
- method: "POST",
221
- headers: {
222
- "Content-Type": "application/json"
223
- },
224
- body: JSON.stringify({ refresh_token: s })
225
- });
226
- if (!t.ok)
227
- throw ee(), (d = this.onUnauthorized) == null || d.call(this), new Error("Token refresh failed");
228
- const o = await t.json();
229
- return ie(o.access_token, s), o.access_token;
230
- }
231
- async request(s, t = {}) {
232
- const o = ce(), d = {
233
- "Content-Type": "application/json",
234
- ...t.headers
235
- };
236
- o && (d.Authorization = `Bearer ${o}`);
237
- const g = `${this.baseURL}${s}`;
238
- let c = await fetch(g, {
239
- ...t,
240
- headers: d
241
- });
242
- if (c.status === 401 && o) {
243
- this.isRefreshing || (this.isRefreshing = !0, this.refreshPromise = this.refreshAccessToken().finally(() => {
244
- this.isRefreshing = !1, this.refreshPromise = null;
245
- }));
246
- try {
247
- const l = await this.refreshPromise;
248
- d.Authorization = `Bearer ${l}`, c = await fetch(g, {
249
- ...t,
250
- headers: d
251
- });
252
- } catch {
253
- throw new Error("Authentication failed");
254
- }
255
- }
256
- if (!c.ok) {
257
- const l = {
258
- message: c.statusText,
259
- status: c.status
260
- };
261
- try {
262
- const i = await c.json();
263
- if (c.status === 422 && Array.isArray(i.detail)) {
264
- const h = i.detail.map((p) => p.msg || "Validation error").join(", ");
265
- l.message = h;
266
- } else typeof i.detail == "string" ? l.message = i.detail : i.message && (l.message = i.message);
267
- l.detail = i.detail;
268
- } catch {
269
- }
270
- throw l;
271
- }
272
- return c.status === 204 ? {} : c.json();
273
- }
274
- async get(s, t) {
275
- return this.request(s, { ...t, method: "GET" });
276
- }
277
- async post(s, t, o) {
278
- return this.request(s, {
279
- ...o,
280
- method: "POST",
281
- body: t ? JSON.stringify(t) : void 0
282
- });
283
- }
284
- async put(s, t, o) {
285
- return this.request(s, {
286
- ...o,
287
- method: "PUT",
288
- body: t ? JSON.stringify(t) : void 0
289
- });
290
- }
291
- async patch(s, t, o) {
292
- return this.request(s, {
293
- ...o,
294
- method: "PATCH",
295
- body: t ? JSON.stringify(t) : void 0
296
- });
297
- }
298
- async delete(s, t) {
299
- return this.request(s, { ...t, method: "DELETE" });
300
- }
301
- }
302
- let y;
303
- const ft = (e) => {
304
- y = new gt(e);
305
- }, F = "astrogators_ally_codes", H = "astrogators_selected_ally_code", A = () => {
306
- try {
307
- const e = localStorage.getItem(F);
308
- return e ? JSON.parse(e) : [];
309
- } catch (e) {
310
- return console.error("Failed to read ally codes from localStorage:", e), [];
311
- }
312
- }, pt = (e) => {
313
- try {
314
- const s = A();
315
- if (s.some((o) => o.ally_code === e.ally_code))
316
- return;
317
- s.push(e), localStorage.setItem(F, JSON.stringify(s));
318
- } catch (s) {
319
- console.error("Failed to save ally code to localStorage:", s);
320
- }
321
- }, yt = (e) => {
322
- try {
323
- const t = A().filter((o) => o.ally_code !== e);
324
- localStorage.setItem(F, JSON.stringify(t));
325
- } catch (s) {
326
- console.error("Failed to remove ally code from localStorage:", s);
327
- }
328
- }, re = (e) => {
329
- try {
330
- const t = A().map(
331
- (o) => o.ally_code === e ? { ...o, last_used_at: (/* @__PURE__ */ new Date()).toISOString() } : o
332
- );
333
- localStorage.setItem(F, JSON.stringify(t));
334
- } catch (s) {
335
- console.error("Failed to update ally code last used:", s);
336
- }
337
- }, vt = () => localStorage.getItem(H), $t = (e) => {
338
- e ? localStorage.setItem(H, e) : localStorage.removeItem(H);
339
- }, bt = () => {
340
- localStorage.removeItem(F), localStorage.removeItem(H);
341
- }, de = fe(void 0), ws = ({ children: e, apiBaseUrl: s }) => {
342
- const [t, o] = b(null), [d, g] = b(!0), [c, l] = b([]), [i, h] = b(null), [p, N] = b(!1), [f, k] = b({
343
- show: !1,
344
- localStorageCodes: []
345
- });
346
- j(() => {
347
- ft({
348
- baseURL: s
349
- });
350
- }, [s]);
351
- const W = S(async () => {
352
- if (!ht()) {
353
- o(null), g(!1);
354
- return;
355
- }
356
- try {
357
- const a = await y.get("/api/v1/users/me");
358
- o(a);
359
- } catch (a) {
360
- console.error("Failed to fetch user:", a), o(null), ee();
361
- } finally {
362
- g(!1);
363
- }
364
- }, []);
365
- j(() => {
366
- W();
367
- }, [W]);
368
- const I = async (a) => {
369
- try {
370
- const n = await y.post("/api/v1/auth/login", a);
371
- ie(n.access_token, n.refresh_token);
372
- const u = await y.get("/api/v1/users/me");
373
- o(u);
374
- } catch (n) {
375
- throw console.error("Login failed:", n), n;
376
- }
377
- }, D = async (a) => {
378
- try {
379
- await y.post("/api/v1/auth/register", a);
380
- } catch (n) {
381
- throw console.error("Registration failed:", n), n;
382
- }
383
- }, O = () => {
384
- ee(), o(null), l([]), h(null), k({ show: !1, localStorageCodes: [] });
385
- }, Y = async () => {
386
- await W();
387
- }, G = async (a) => {
388
- try {
389
- return (await y.post(
390
- "/api/v1/auth/forgot-password",
391
- a
392
- )).message;
393
- } catch (n) {
394
- throw console.error("Forgot password failed:", n), n;
395
- }
396
- }, K = async (a) => {
397
- try {
398
- return (await y.post(
399
- "/api/v1/auth/reset-password",
400
- a
401
- )).message;
402
- } catch (n) {
403
- throw console.error("Reset password failed:", n), n;
404
- }
405
- }, V = async (a) => {
406
- try {
407
- return (await y.post(
408
- "/api/v1/auth/resend-verification",
409
- a
410
- )).message;
411
- } catch (n) {
412
- throw console.error("Resend verification failed:", n), n;
413
- }
414
- }, _ = S(async () => {
415
- N(!0);
416
- try {
417
- if (t) {
418
- const n = await y.get("/api/v1/users/me/ally-codes");
419
- l(n.ally_codes);
420
- const u = A();
421
- u.length > 0 && k({
422
- show: !0,
423
- localStorageCodes: u.map((q) => q.ally_code)
424
- });
425
- } else {
426
- const n = A();
427
- l(n);
428
- }
429
- const a = vt();
430
- h(a);
431
- } catch (a) {
432
- console.error("Failed to fetch ally codes:", a), l([]);
433
- } finally {
434
- N(!1);
435
- }
436
- }, [t]), v = S(async (a) => {
437
- var n;
438
- if (!/^\d{9}$/.test(a))
439
- throw new Error("Ally code must be exactly 9 digits");
440
- if (t) {
441
- const u = await y.post(
442
- "/api/v1/users/me/ally-codes",
443
- { ally_code: a }
444
- );
445
- l((q) => [u, ...q]), c.length === 0 && z(a);
446
- } else {
447
- const u = await y.get(`/api/v1/player-data/player/${a}`);
448
- if (!u)
449
- throw new Error("Invalid ally code - player not found");
450
- const q = {
451
- ally_code: a,
452
- player_name: ((n = u == null ? void 0 : u.data) == null ? void 0 : n.name) || null,
453
- last_used_at: (/* @__PURE__ */ new Date()).toISOString()
454
- };
455
- pt(q), l(A()), c.length === 0 && z(a);
456
- }
457
- }, [t, c.length]), L = S(async (a) => {
458
- t && typeof a == "number" ? (await y.delete(`/api/v1/users/me/ally-codes/${a}`), l((n) => n.filter((u) => "id" in u && u.id !== a))) : !t && typeof a == "string" && (yt(a), l(A()), i === a && z(null));
459
- }, [t, i]), z = S((a) => {
460
- if (h(a), $t(a), a && t) {
461
- const n = c.find((u) => "ally_code" in u && u.ally_code === a);
462
- n && "id" in n && oe(n.id);
463
- } else a && !t && re(a);
464
- }, [t, c]), oe = S(async (a) => {
465
- t && typeof a == "number" ? (await y.put(`/api/v1/users/me/ally-codes/${a}/use`, {}), await _()) : !t && typeof a == "string" && (re(a), l(A()));
466
- }, [t, _]), Q = S(() => {
467
- k({ show: !1, localStorageCodes: [] });
468
- }, []), _e = S(async () => {
469
- if (!t) return;
470
- const a = A();
471
- for (const n of a)
472
- try {
473
- await v(n.ally_code);
474
- } catch (u) {
475
- console.error(`Failed to migrate ally code ${n.ally_code}:`, u);
476
- }
477
- bt(), Q();
478
- }, [t, v, Q]);
479
- j(() => {
480
- _();
481
- }, [_]);
482
- const me = {
483
- user: t,
484
- isAuthenticated: !!t,
485
- isLoading: d,
486
- login: I,
487
- register: D,
488
- logout: O,
489
- refreshUser: Y,
490
- forgotPassword: G,
491
- resetPassword: K,
492
- resendVerification: V,
493
- // Ally code values
494
- allyCodes: c,
495
- selectedAllyCode: i,
496
- isLoadingAllyCodes: p,
497
- fetchAllyCodes: _,
498
- addAllyCode: v,
499
- removeAllyCode: L,
500
- selectAllyCode: z,
501
- updateAllyCodeLastUsed: oe,
502
- migrationPrompt: f,
503
- dismissMigrationPrompt: Q,
504
- migrateLocalStorageCodes: _e
505
- };
506
- return /* @__PURE__ */ r(de.Provider, { value: me, children: e });
507
- }, wt = () => {
508
- const e = pe(de);
509
- if (e === void 0)
510
- throw new Error("useAuth must be used within an AuthProvider");
511
- return e;
512
- }, J = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e.slice(6, 9)}`, Ns = (e) => e.replace(/-/g, ""), Nt = "_allyCodeDropdown_1m0tw_1", At = "_select_1m0tw_8", St = "_manageButton_1m0tw_12", xt = "_managePanel_1m0tw_16", Tt = "_addSection_1m0tw_37", Ct = "_addInputGroup_1m0tw_43", kt = "_error_1m0tw_55", Et = "_success_1m0tw_61", Wt = "_codesList_1m0tw_67", It = "_codeItem_1m0tw_71", Lt = "_doneButton_1m0tw_88", $ = {
513
- allyCodeDropdown: Nt,
514
- select: At,
515
- manageButton: St,
516
- managePanel: xt,
517
- addSection: Tt,
518
- addInputGroup: Ct,
519
- error: kt,
520
- success: Et,
521
- codesList: Wt,
522
- codeItem: It,
523
- doneButton: Lt
524
- }, As = ({
525
- onAllyCodeSelected: e,
526
- className: s = ""
527
- }) => {
528
- const {
529
- allyCodes: t,
530
- selectedAllyCode: o,
531
- selectAllyCode: d,
532
- removeAllyCode: g,
533
- addAllyCode: c,
534
- isLoadingAllyCodes: l
535
- } = wt(), [i, h] = b(!1), [p, N] = b(""), [f, k] = b(""), [W, I] = b(""), [D, O] = b(!1), Y = t.map((_) => ({
536
- value: _.ally_code,
537
- label: _.player_name ? `${_.player_name} (${J(_.ally_code)})` : J(_.ally_code)
538
- })), G = (_) => {
539
- const v = _.target.value || null;
540
- d(v), e == null || e(v);
541
- }, K = async (_) => {
542
- const v = t.find((L) => L.ally_code === _);
543
- if (v) {
544
- const L = "id" in v ? v.id : v.ally_code;
545
- await g(L);
546
- }
547
- }, V = async () => {
548
- if (k(""), I(""), !/^\d{9}$/.test(p)) {
549
- k("Ally code must be exactly 9 digits");
550
- return;
551
- }
552
- O(!0);
553
- try {
554
- await c(p), I("Added successfully!"), N(""), setTimeout(() => I(""), 2e3);
555
- } catch (_) {
556
- k(_.message || "Failed to add ally code");
557
- } finally {
558
- O(!1);
559
- }
560
- };
561
- return t.length === 0 ? null : /* @__PURE__ */ m("div", { className: `${$.allyCodeDropdown} ${s}`, children: [
562
- /* @__PURE__ */ r(
563
- le,
564
- {
565
- options: Y,
566
- value: o || "",
567
- onChange: G,
568
- placeholder: "Select ally code",
569
- disabled: l,
570
- className: $.select
571
- }
572
- ),
573
- i && /* @__PURE__ */ m("div", { className: $.managePanel, children: [
574
- /* @__PURE__ */ r("h4", { children: "Manage Ally Codes" }),
575
- /* @__PURE__ */ m("div", { className: $.addSection, children: [
576
- /* @__PURE__ */ m("div", { className: $.addInputGroup, children: [
577
- /* @__PURE__ */ r(
578
- ne,
579
- {
580
- type: "text",
581
- placeholder: "9-digit ally code",
582
- value: p,
583
- onChange: (_) => N(_.target.value.replace(/\D/g, "").slice(0, 9)),
584
- disabled: D
585
- }
586
- ),
587
- /* @__PURE__ */ r(
588
- M,
589
- {
590
- variant: "primary",
591
- size: "sm",
592
- onClick: V,
593
- loading: D,
594
- disabled: p.length !== 9,
595
- children: "Add"
596
- }
597
- )
598
- ] }),
599
- f && /* @__PURE__ */ r("div", { className: $.error, children: f }),
600
- W && /* @__PURE__ */ r("div", { className: $.success, children: W })
601
- ] }),
602
- /* @__PURE__ */ r("div", { className: $.codesList, children: t.map((_) => /* @__PURE__ */ m("div", { className: $.codeItem, children: [
603
- /* @__PURE__ */ r("span", { children: _.player_name ? `${_.player_name} (${J(_.ally_code)})` : J(_.ally_code) }),
604
- /* @__PURE__ */ r(
605
- M,
606
- {
607
- variant: "ghost",
608
- size: "sm",
609
- onClick: () => K(_.ally_code),
610
- children: "Remove"
611
- }
612
- )
613
- ] }, _.ally_code)) }),
614
- /* @__PURE__ */ r(
615
- M,
616
- {
617
- variant: "secondary",
618
- size: "sm",
619
- onClick: () => h(!1),
620
- className: $.doneButton,
621
- children: "Done"
622
- }
623
- )
624
- ] }),
625
- /* @__PURE__ */ r(
626
- M,
627
- {
628
- variant: "ghost",
629
- size: "sm",
630
- onClick: () => h(!i),
631
- className: $.manageButton,
632
- children: "Manage"
633
- }
634
- )
635
- ] });
636
- }, qt = "_card_b4471_1", Rt = "_chamfered_b4471_8", Pt = "_elevated_b4471_17", Bt = "_outline_b4471_22", Ut = "_hoverable_b4471_45", U = {
637
- card: qt,
638
- chamfered: Rt,
639
- default: "_default_b4471_13",
640
- elevated: Pt,
641
- outline: Bt,
642
- "padding-none": "_padding-none_b4471_28",
643
- "padding-sm": "_padding-sm_b4471_32",
644
- "padding-md": "_padding-md_b4471_36",
645
- "padding-lg": "_padding-lg_b4471_40",
646
- hoverable: Ut
647
- }, Ss = ({
648
- children: e,
649
- variant: s = "default",
650
- chamfered: t = !1,
651
- chamferSize: o = "md",
652
- padding: d = "md",
653
- hoverable: g = !1,
654
- showDiagonalBorders: c = !1,
655
- diagonalBorderColor: l,
656
- className: i = "",
657
- onClick: h,
658
- style: p
659
- }) => {
660
- const N = t ? o === "asymmetric" ? "chamfered-box-asymmetric" : o === "sm" ? "chamfered-box-sm" : o === "lg" ? "chamfered-box-lg" : "chamfered-box" : "", f = l ? { color: l } : void 0;
661
- return /* @__PURE__ */ m(
662
- "div",
663
- {
664
- className: `${U.card} ${t ? U.chamfered : ""} ${U[s]} ${U[`padding-${d}`]} ${N} ${g ? U.hoverable : ""} ${i}`,
665
- onClick: h,
666
- role: h ? "button" : void 0,
667
- tabIndex: h ? 0 : void 0,
668
- style: p,
669
- children: [
670
- c && /* @__PURE__ */ m(ge, { children: [
671
- /* @__PURE__ */ r("div", { className: "chamfered-diagonal-border chamfered-diagonal-tl", style: f }),
672
- /* @__PURE__ */ r("div", { className: "chamfered-diagonal-border chamfered-diagonal-tr", style: f }),
673
- /* @__PURE__ */ r("div", { className: "chamfered-diagonal-border chamfered-diagonal-bl", style: f }),
674
- /* @__PURE__ */ r("div", { className: `chamfered-diagonal-border ${o === "asymmetric" ? "chamfered-diagonal-br-large" : "chamfered-diagonal-br"}`, style: f })
675
- ] }),
676
- e
677
- ]
678
- }
679
- );
680
- }, jt = "_badge_rk7t5_1", Ft = "_sm_rk7t5_11", Dt = "_md_rk7t5_16", Ot = "_lg_rk7t5_21", zt = "_primary_rk7t5_32", Mt = "_secondary_rk7t5_37", Jt = "_success_rk7t5_42", Ht = "_warning_rk7t5_47", Yt = "_error_rk7t5_52", Gt = "_info_rk7t5_57", Z = {
681
- badge: jt,
682
- sm: Ft,
683
- md: Dt,
684
- lg: Ot,
685
- default: "_default_rk7t5_27",
686
- primary: zt,
687
- secondary: Mt,
688
- success: Jt,
689
- warning: Ht,
690
- error: Yt,
691
- info: Gt
692
- }, xs = ({
693
- children: e,
694
- variant: s = "default",
695
- size: t = "md",
696
- className: o = ""
697
- }) => /* @__PURE__ */ r("span", { className: `${Z.badge} ${Z[s]} ${Z[t]} ${o}`, children: e }), Kt = "_overlay_1b3yt_1", Vt = "_fadeIn_1b3yt_1", Qt = "_modal_1b3yt_13", Xt = "_slideUp_1b3yt_1", Zt = "_sm_1b3yt_25", es = "_md_1b3yt_30", ts = "_lg_1b3yt_35", ss = "_xl_1b3yt_40", os = "_header_1b3yt_45", rs = "_title_1b3yt_53", as = "_closeButton_1b3yt_60", ns = "_content_1b3yt_78", E = {
698
- overlay: Kt,
699
- fadeIn: Vt,
700
- modal: Qt,
701
- slideUp: Xt,
702
- sm: Zt,
703
- md: es,
704
- lg: ts,
705
- xl: ss,
706
- header: os,
707
- title: rs,
708
- closeButton: as,
709
- content: ns
710
- }, Ts = ({
711
- isOpen: e,
712
- onClose: s,
713
- title: t,
714
- children: o,
715
- size: d = "md",
716
- closeOnOverlayClick: g = !0,
717
- className: c = ""
718
- }) => {
719
- if (j(() => (e ? document.body.style.overflow = "hidden" : document.body.style.overflow = "unset", () => {
720
- document.body.style.overflow = "unset";
721
- }), [e]), j(() => {
722
- const i = (h) => {
723
- h.key === "Escape" && e && s();
724
- };
725
- return document.addEventListener("keydown", i), () => document.removeEventListener("keydown", i);
726
- }, [e, s]), !e) return null;
727
- const l = (i) => {
728
- g && i.target === i.currentTarget && s();
729
- };
730
- return /* @__PURE__ */ r("div", { className: E.overlay, onClick: l, children: /* @__PURE__ */ m("div", { className: `${E.modal} ${E[d]} ${c}`, role: "dialog", "aria-modal": "true", children: [
731
- t && /* @__PURE__ */ m("div", { className: E.header, children: [
732
- /* @__PURE__ */ r("h2", { className: E.title, children: t }),
733
- /* @__PURE__ */ r("button", { className: E.closeButton, onClick: s, "aria-label": "Close modal", children: "✕" })
734
- ] }),
735
- /* @__PURE__ */ r("div", { className: E.content, children: o })
736
- ] }) });
737
- }, ls = "_spinner_1uhnh_2", cs = "_spin_1uhnh_2", is = "_sm_1uhnh_9", ds = "_md_1uhnh_15", _s = "_lg_1uhnh_21", ms = "_dots_1uhnh_34", us = "_dot_1uhnh_34", hs = "_bounce_1uhnh_1", gs = "_visuallyHidden_1uhnh_91", C = {
738
- spinner: ls,
739
- spin: cs,
740
- sm: is,
741
- md: ds,
742
- lg: _s,
743
- dots: ms,
744
- dot: us,
745
- bounce: hs,
746
- visuallyHidden: gs
747
- }, Cs = ({
748
- size: e = "md",
749
- variant: s = "spinner",
750
- className: t = ""
751
- }) => s === "dots" ? /* @__PURE__ */ m("div", { className: `${C.dots} ${C[e]} ${t}`, children: [
752
- /* @__PURE__ */ r("span", { className: C.dot }),
753
- /* @__PURE__ */ r("span", { className: C.dot }),
754
- /* @__PURE__ */ r("span", { className: C.dot })
755
- ] }) : /* @__PURE__ */ r("div", { className: `${C.spinner} ${C[e]} ${t}`, role: "status", children: /* @__PURE__ */ r("span", { className: C.visuallyHidden, children: "Loading..." }) });
756
- export {
757
- As as AllyCodeDropdown,
758
- gt as ApiClient,
759
- ws as AuthProvider,
760
- xs as Badge,
761
- M as Button,
762
- Ss as Card,
763
- vs as Container,
764
- bs as Footer,
765
- ne as Input,
766
- Cs as Loader,
767
- Ts as Modal,
768
- le as Select,
769
- $s as TopBar,
770
- y as apiClient,
771
- bt as clearAllyCodes,
772
- ee as clearTokens,
773
- J as formatAllyCode,
774
- ce as getAccessToken,
775
- A as getAllyCodesFromStorage,
776
- _t as getRefreshToken,
777
- vt as getSelectedAllyCode,
778
- ft as initializeApiClient,
779
- ht as isAuthenticated,
780
- dt as removeAccessToken,
781
- yt as removeAllyCodeFromStorage,
782
- ut as removeRefreshToken,
783
- pt as saveAllyCodeToStorage,
784
- it as setAccessToken,
785
- mt as setRefreshToken,
786
- $t as setSelectedAllyCode,
787
- ie as setTokens,
788
- Ns as unformatAllyCode,
789
- re as updateAllyCodeLastUsed,
790
- wt as useAuth
791
- };
1
+ import e, { createContext as t, useCallback as n, useContext as r, useEffect as i, useState as a } from "react";
2
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
3
+ var l = {
4
+ container: "_container_u3o0e_1",
5
+ padding: "_padding_u3o0e_7",
6
+ "maxWidth-sm": "_maxWidth-sm_u3o0e_12",
7
+ "maxWidth-md": "_maxWidth-md_u3o0e_16",
8
+ "maxWidth-lg": "_maxWidth-lg_u3o0e_20",
9
+ "maxWidth-xl": "_maxWidth-xl_u3o0e_24",
10
+ "maxWidth-full": "_maxWidth-full_u3o0e_28"
11
+ }, u = ({ children: e, maxWidth: t = "xl", padding: n = !0, className: r = "", style: i }) => /* @__PURE__ */ s("div", {
12
+ className: `${l.container} ${l[`maxWidth-${t}`]} ${n ? l.padding : ""} ${r}`,
13
+ style: i,
14
+ children: e
15
+ }), d = {
16
+ topBar: "_topBar_10g3c_1",
17
+ content: "_content_10g3c_13",
18
+ left: "_left_10g3c_23",
19
+ right: "_right_10g3c_30",
20
+ logo: "_logo_10g3c_36"
21
+ }, f = ({ logo: e, leftContent: t, rightContent: n, className: r = "" }) => /* @__PURE__ */ s("header", {
22
+ className: `${d.topBar} ${r}`,
23
+ children: /* @__PURE__ */ c("div", {
24
+ className: d.content,
25
+ children: [/* @__PURE__ */ c("div", {
26
+ className: d.left,
27
+ children: [e && /* @__PURE__ */ s("div", {
28
+ className: d.logo,
29
+ children: e
30
+ }), t]
31
+ }), /* @__PURE__ */ s("div", {
32
+ className: d.right,
33
+ children: n
34
+ })]
35
+ })
36
+ }), p = {
37
+ footer: "_footer_zjuj8_1",
38
+ content: "_content_zjuj8_7",
39
+ defaultContent: "_defaultContent_zjuj8_13",
40
+ copyright: "_copyright_zjuj8_21",
41
+ disclaimer: "_disclaimer_zjuj8_26"
42
+ }, m = ({ children: e, className: t = "" }) => /* @__PURE__ */ s("footer", {
43
+ className: `${p.footer} ${t}`,
44
+ children: /* @__PURE__ */ s("div", {
45
+ className: p.content,
46
+ children: e || /* @__PURE__ */ c("div", {
47
+ className: p.defaultContent,
48
+ children: [/* @__PURE__ */ c("p", {
49
+ className: p.copyright,
50
+ children: [
51
+ ",
52
+ (/* @__PURE__ */ new Date()).getFullYear(),
53
+ " The Astrogator's Table. All rights reserved."
54
+ ]
55
+ }), /* @__PURE__ */ s("p", {
56
+ className: p.disclaimer,
57
+ children: "Star Wars: Galaxy of Heroes is a trademark of Electronic Arts Inc."
58
+ })]
59
+ })
60
+ })
61
+ }), h = {
62
+ button: "_button_159ms_1",
63
+ sm: "_sm_159ms_22",
64
+ md: "_md_159ms_28",
65
+ lg: "_lg_159ms_34",
66
+ primary: "_primary_159ms_41",
67
+ secondary: "_secondary_159ms_55",
68
+ outline: "_outline_159ms_69",
69
+ ghost: "_ghost_159ms_80",
70
+ danger: "_danger_159ms_89",
71
+ fullWidth: "_fullWidth_159ms_100",
72
+ loading: "_loading_159ms_105",
73
+ loadingSpinner: "_loadingSpinner_159ms_110",
74
+ spinner: "_spinner_159ms_116",
75
+ spin: "_spin_159ms_116",
76
+ loadingText: "_loadingText_159ms_131"
77
+ }, g = ({ children: e, variant: t = "primary", size: n = "md", fullWidth: r = !1, loading: i = !1, disabled: a = !1, className: o = "", ...l }) => /* @__PURE__ */ s("button", {
78
+ className: `${h.button} ${h[t]} ${h[n]} ${r ? h.fullWidth : ""} ${i ? h.loading : ""} ${o}`,
79
+ disabled: a || i,
80
+ ...l,
81
+ children: i ? /* @__PURE__ */ c("span", {
82
+ className: h.loadingSpinner,
83
+ children: [/* @__PURE__ */ s("span", { className: h.spinner }), /* @__PURE__ */ s("span", {
84
+ className: h.loadingText,
85
+ children: e
86
+ })]
87
+ }) : e
88
+ }), _ = {
89
+ inputWrapper: "_inputWrapper_15t4g_1",
90
+ fullWidth: "_fullWidth_15t4g_7",
91
+ label: "_label_15t4g_11",
92
+ required: "_required_15t4g_20",
93
+ input: "_input_15t4g_1",
94
+ error: "_error_15t4g_55",
95
+ errorText: "_errorText_15t4g_63",
96
+ helperText: "_helperText_15t4g_68"
97
+ }, v = e.forwardRef(({ label: e, error: t, helperText: n, fullWidth: r = !1, className: i = "", id: a, ...o }, l) => {
98
+ let u = a || `input-${Math.random().toString(36).substr(2, 9)}`, d = !!t;
99
+ return /* @__PURE__ */ c("div", {
100
+ className: `${_.inputWrapper} ${r ? _.fullWidth : ""} ${i}`,
101
+ children: [
102
+ e && /* @__PURE__ */ c("label", {
103
+ htmlFor: u,
104
+ className: _.label,
105
+ children: [e, o.required && /* @__PURE__ */ s("span", {
106
+ className: _.required,
107
+ children: "*"
108
+ })]
109
+ }),
110
+ /* @__PURE__ */ s("input", {
111
+ ref: l,
112
+ id: u,
113
+ className: `${_.input} ${d ? _.error : ""}`,
114
+ ...o
115
+ }),
116
+ t && /* @__PURE__ */ s("span", {
117
+ className: _.errorText,
118
+ children: t
119
+ }),
120
+ n && !t && /* @__PURE__ */ s("span", {
121
+ className: _.helperText,
122
+ children: n
123
+ })
124
+ ]
125
+ });
126
+ });
127
+ v.displayName = "Input";
128
+ var y = {
129
+ selectWrapper: "_selectWrapper_ir4bq_1",
130
+ fullWidth: "_fullWidth_ir4bq_7",
131
+ label: "_label_ir4bq_11",
132
+ required: "_required_ir4bq_20",
133
+ selectContainer: "_selectContainer_ir4bq_24",
134
+ select: "_select_ir4bq_1",
135
+ error: "_error_ir4bq_63",
136
+ arrow: "_arrow_ir4bq_71",
137
+ errorText: "_errorText_ir4bq_81",
138
+ helperText: "_helperText_ir4bq_86"
139
+ }, b = e.forwardRef(({ label: e, error: t, helperText: n, options: r, placeholder: i, fullWidth: a = !1, className: o = "", id: l, ...u }, d) => {
140
+ let f = l || `select-${Math.random().toString(36).substr(2, 9)}`, p = !!t;
141
+ return /* @__PURE__ */ c("div", {
142
+ className: `${y.selectWrapper} ${a ? y.fullWidth : ""} ${o}`,
143
+ children: [
144
+ e && /* @__PURE__ */ c("label", {
145
+ htmlFor: f,
146
+ className: y.label,
147
+ children: [e, u.required && /* @__PURE__ */ s("span", {
148
+ className: y.required,
149
+ children: "*"
150
+ })]
151
+ }),
152
+ /* @__PURE__ */ c("div", {
153
+ className: y.selectContainer,
154
+ children: [/* @__PURE__ */ c("select", {
155
+ ref: d,
156
+ id: f,
157
+ className: `${y.select} ${p ? y.error : ""}`,
158
+ ...u,
159
+ children: [
160
+ i && /* @__PURE__ */ s("option", {
161
+ value: "",
162
+ disabled: !0,
163
+ children: i
164
+ }),
165
+ r && r.map((e) => /* @__PURE__ */ s("option", {
166
+ value: e.value,
167
+ disabled: e.disabled,
168
+ children: e.label
169
+ }, e.value)),
170
+ !r && u.children
171
+ ]
172
+ }), /* @__PURE__ */ s("span", {
173
+ className: y.arrow,
174
+ children: "▼"
175
+ })]
176
+ }),
177
+ t && /* @__PURE__ */ s("span", {
178
+ className: y.errorText,
179
+ children: t
180
+ }),
181
+ n && !t && /* @__PURE__ */ s("span", {
182
+ className: y.helperText,
183
+ children: n
184
+ })
185
+ ]
186
+ });
187
+ });
188
+ b.displayName = "Select";
189
+ //#endregion
190
+ //#region src/services/auth.ts
191
+ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => localStorage.getItem(x), w = (e) => {
192
+ localStorage.setItem(x, e);
193
+ }, T = () => {
194
+ localStorage.removeItem(x);
195
+ }, E = () => localStorage.getItem(S), D = (e) => {
196
+ localStorage.setItem(S, e);
197
+ }, O = () => {
198
+ localStorage.removeItem(S);
199
+ }, k = (e, t) => {
200
+ w(e), D(t);
201
+ }, A = () => {
202
+ T(), O();
203
+ }, j = () => !!C(), M = class {
204
+ baseURL;
205
+ onUnauthorized;
206
+ isRefreshing = !1;
207
+ refreshPromise = null;
208
+ constructor(e) {
209
+ this.baseURL = e.baseURL, this.onUnauthorized = e.onUnauthorized;
210
+ }
211
+ async refreshAccessToken() {
212
+ let e = E();
213
+ if (!e) throw Error("No refresh token available");
214
+ let t = await fetch(`${this.baseURL}/api/v1/auth/refresh-token`, {
215
+ method: "POST",
216
+ headers: { "Content-Type": "application/json" },
217
+ body: JSON.stringify({ refresh_token: e })
218
+ });
219
+ if (!t.ok) throw A(), this.onUnauthorized?.(), Error("Token refresh failed");
220
+ let n = await t.json();
221
+ return k(n.access_token, e), n.access_token;
222
+ }
223
+ async request(e, t = {}) {
224
+ let n = C(), r = {
225
+ "Content-Type": "application/json",
226
+ ...t.headers
227
+ };
228
+ n && (r.Authorization = `Bearer ${n}`);
229
+ let i = `${this.baseURL}${e}`, a = await fetch(i, {
230
+ ...t,
231
+ headers: r
232
+ });
233
+ if (a.status === 401 && n) {
234
+ this.isRefreshing || (this.isRefreshing = !0, this.refreshPromise = this.refreshAccessToken().finally(() => {
235
+ this.isRefreshing = !1, this.refreshPromise = null;
236
+ }));
237
+ try {
238
+ r.Authorization = `Bearer ${await this.refreshPromise}`, a = await fetch(i, {
239
+ ...t,
240
+ headers: r
241
+ });
242
+ } catch {
243
+ throw Error("Authentication failed");
244
+ }
245
+ }
246
+ if (!a.ok) {
247
+ let e = {
248
+ message: a.statusText,
249
+ status: a.status
250
+ };
251
+ try {
252
+ let t = await a.json();
253
+ a.status === 422 && Array.isArray(t.detail) ? e.message = t.detail.map((e) => e.msg || "Validation error").join(", ") : typeof t.detail == "string" ? e.message = t.detail : t.message && (e.message = t.message), e.detail = t.detail;
254
+ } catch {}
255
+ throw e;
256
+ }
257
+ return a.status === 204 ? {} : a.json();
258
+ }
259
+ async get(e, t) {
260
+ return this.request(e, {
261
+ ...t,
262
+ method: "GET"
263
+ });
264
+ }
265
+ async post(e, t, n) {
266
+ return this.request(e, {
267
+ ...n,
268
+ method: "POST",
269
+ body: t ? JSON.stringify(t) : void 0
270
+ });
271
+ }
272
+ async put(e, t, n) {
273
+ return this.request(e, {
274
+ ...n,
275
+ method: "PUT",
276
+ body: t ? JSON.stringify(t) : void 0
277
+ });
278
+ }
279
+ async patch(e, t, n) {
280
+ return this.request(e, {
281
+ ...n,
282
+ method: "PATCH",
283
+ body: t ? JSON.stringify(t) : void 0
284
+ });
285
+ }
286
+ async delete(e, t) {
287
+ return this.request(e, {
288
+ ...t,
289
+ method: "DELETE"
290
+ });
291
+ }
292
+ }, N, P = (e) => {
293
+ N = new M(e);
294
+ }, F = "astrogators_ally_codes", I = "astrogators_selected_ally_code", L = () => {
295
+ try {
296
+ let e = localStorage.getItem(F);
297
+ return e ? JSON.parse(e) : [];
298
+ } catch (e) {
299
+ return console.error("Failed to read ally codes from localStorage:", e), [];
300
+ }
301
+ }, R = (e) => {
302
+ try {
303
+ let t = L();
304
+ if (t.some((t) => t.ally_code === e.ally_code)) return;
305
+ t.push(e), localStorage.setItem(F, JSON.stringify(t));
306
+ } catch (e) {
307
+ console.error("Failed to save ally code to localStorage:", e);
308
+ }
309
+ }, z = (e) => {
310
+ try {
311
+ let t = L().filter((t) => t.ally_code !== e);
312
+ localStorage.setItem(F, JSON.stringify(t));
313
+ } catch (e) {
314
+ console.error("Failed to remove ally code from localStorage:", e);
315
+ }
316
+ }, B = (e) => {
317
+ try {
318
+ let t = L().map((t) => t.ally_code === e ? {
319
+ ...t,
320
+ last_used_at: (/* @__PURE__ */ new Date()).toISOString()
321
+ } : t);
322
+ localStorage.setItem(F, JSON.stringify(t));
323
+ } catch (e) {
324
+ console.error("Failed to update ally code last used:", e);
325
+ }
326
+ }, V = () => localStorage.getItem(I), H = (e) => {
327
+ e ? localStorage.setItem(I, e) : localStorage.removeItem(I);
328
+ }, U = () => {
329
+ localStorage.removeItem(F), localStorage.removeItem(I);
330
+ }, W = t(void 0), G = ({ children: e, apiBaseUrl: t }) => {
331
+ let [r, o] = a(null), [c, l] = a(!0), [u, d] = a(!0), [f, p] = a(!0), [m, h] = a([]), [g, _] = a(null), [v, y] = a(!1), [b, x] = a({
332
+ show: !1,
333
+ localStorageCodes: []
334
+ });
335
+ i(() => {
336
+ P({ baseURL: t });
337
+ }, [t]), i(() => {
338
+ (async () => {
339
+ try {
340
+ d((await N.get("/api/v1/config/features")).auth_enabled);
341
+ } catch (e) {
342
+ console.error("Failed to fetch features:", e), d(!0);
343
+ } finally {
344
+ p(!1);
345
+ }
346
+ })();
347
+ }, [t]);
348
+ let S = n(async () => {
349
+ if (!j()) {
350
+ o(null), l(!1);
351
+ return;
352
+ }
353
+ try {
354
+ o(await N.get("/api/v1/users/me"));
355
+ } catch (e) {
356
+ console.error("Failed to fetch user:", e), o(null), A();
357
+ } finally {
358
+ l(!1);
359
+ }
360
+ }, []);
361
+ i(() => {
362
+ S();
363
+ }, [S]);
364
+ let C = async (e) => {
365
+ try {
366
+ let t = await N.post("/api/v1/auth/login", e);
367
+ k(t.access_token, t.refresh_token), o(await N.get("/api/v1/users/me"));
368
+ } catch (e) {
369
+ throw console.error("Login failed:", e), e;
370
+ }
371
+ }, w = async (e) => {
372
+ try {
373
+ await N.post("/api/v1/auth/register", e);
374
+ } catch (e) {
375
+ throw console.error("Registration failed:", e), e;
376
+ }
377
+ }, T = () => {
378
+ A(), o(null), h([]), _(null), x({
379
+ show: !1,
380
+ localStorageCodes: []
381
+ });
382
+ }, E = async () => {
383
+ await S();
384
+ }, D = async (e) => {
385
+ try {
386
+ return (await N.post("/api/v1/auth/forgot-password", e)).message;
387
+ } catch (e) {
388
+ throw console.error("Forgot password failed:", e), e;
389
+ }
390
+ }, O = async (e) => {
391
+ try {
392
+ return (await N.post("/api/v1/auth/reset-password", e)).message;
393
+ } catch (e) {
394
+ throw console.error("Reset password failed:", e), e;
395
+ }
396
+ }, M = async (e) => {
397
+ try {
398
+ return (await N.post("/api/v1/auth/resend-verification", e)).message;
399
+ } catch (e) {
400
+ throw console.error("Resend verification failed:", e), e;
401
+ }
402
+ }, F = n(async () => {
403
+ y(!0);
404
+ try {
405
+ if (r) {
406
+ h((await N.get("/api/v1/users/me/ally-codes")).ally_codes);
407
+ let e = L();
408
+ e.length > 0 && x({
409
+ show: !0,
410
+ localStorageCodes: e.map((e) => e.ally_code)
411
+ });
412
+ } else h(L());
413
+ _(V());
414
+ } catch (e) {
415
+ console.error("Failed to fetch ally codes:", e), h([]);
416
+ } finally {
417
+ y(!1);
418
+ }
419
+ }, [r]), I = n(async (e) => {
420
+ if (!/^\d{9}$/.test(e)) throw Error("Ally code must be exactly 9 digits");
421
+ if (r) {
422
+ let t = await N.post("/api/v1/users/me/ally-codes", { ally_code: e });
423
+ h((e) => [t, ...e]), m.length === 0 && K(e);
424
+ } else {
425
+ let t = await N.get(`/api/v1/player-data/player/${e}`);
426
+ if (!t) throw Error("Invalid ally code - player not found");
427
+ R({
428
+ ally_code: e,
429
+ player_name: t?.data?.name || null,
430
+ last_used_at: (/* @__PURE__ */ new Date()).toISOString()
431
+ }), h(L()), m.length === 0 && K(e);
432
+ }
433
+ }, [r, m.length]), G = n(async (e) => {
434
+ r && typeof e == "number" ? (await N.delete(`/api/v1/users/me/ally-codes/${e}`), h((t) => t.filter((t) => "id" in t && t.id !== e))) : !r && typeof e == "string" && (z(e), h(L()), g === e && K(null));
435
+ }, [r, g]), K = n((e) => {
436
+ if (_(e), H(e), e && r) {
437
+ let t = m.find((t) => "ally_code" in t && t.ally_code === e);
438
+ t && "id" in t && q(t.id);
439
+ } else e && !r && B(e);
440
+ }, [r, m]), q = n(async (e) => {
441
+ r && typeof e == "number" ? (await N.put(`/api/v1/users/me/ally-codes/${e}/use`, {}), await F()) : !r && typeof e == "string" && (B(e), h(L()));
442
+ }, [r, F]), J = n(() => {
443
+ x({
444
+ show: !1,
445
+ localStorageCodes: []
446
+ });
447
+ }, []), Y = n(async () => {
448
+ if (!r) return;
449
+ let e = L();
450
+ for (let t of e) try {
451
+ await I(t.ally_code);
452
+ } catch (e) {
453
+ console.error(`Failed to migrate ally code ${t.ally_code}:`, e);
454
+ }
455
+ U(), J();
456
+ }, [
457
+ r,
458
+ I,
459
+ J
460
+ ]);
461
+ i(() => {
462
+ F();
463
+ }, [F]);
464
+ let ee = {
465
+ user: r,
466
+ isAuthenticated: !!r,
467
+ isLoading: c,
468
+ login: C,
469
+ register: w,
470
+ logout: T,
471
+ refreshUser: E,
472
+ forgotPassword: D,
473
+ resetPassword: O,
474
+ resendVerification: M,
475
+ authEnabled: u,
476
+ isLoadingFeatures: f,
477
+ allyCodes: m,
478
+ selectedAllyCode: g,
479
+ isLoadingAllyCodes: v,
480
+ fetchAllyCodes: F,
481
+ addAllyCode: I,
482
+ removeAllyCode: G,
483
+ selectAllyCode: K,
484
+ updateAllyCodeLastUsed: q,
485
+ migrationPrompt: b,
486
+ dismissMigrationPrompt: J,
487
+ migrateLocalStorageCodes: Y
488
+ };
489
+ return /* @__PURE__ */ s(W.Provider, {
490
+ value: ee,
491
+ children: e
492
+ });
493
+ }, K = () => {
494
+ let e = r(W);
495
+ if (e === void 0) throw Error("useAuth must be used within an AuthProvider");
496
+ return e;
497
+ }, q = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e.slice(6, 9)}`, J = (e) => e.replace(/-/g, ""), Y = {
498
+ allyCodeDropdown: "_allyCodeDropdown_1m0tw_1",
499
+ select: "_select_1m0tw_8",
500
+ manageButton: "_manageButton_1m0tw_12",
501
+ managePanel: "_managePanel_1m0tw_16",
502
+ addSection: "_addSection_1m0tw_37",
503
+ addInputGroup: "_addInputGroup_1m0tw_43",
504
+ error: "_error_1m0tw_55",
505
+ success: "_success_1m0tw_61",
506
+ codesList: "_codesList_1m0tw_67",
507
+ codeItem: "_codeItem_1m0tw_71",
508
+ doneButton: "_doneButton_1m0tw_88"
509
+ }, ee = ({ onAllyCodeSelected: e, className: t = "" }) => {
510
+ let { allyCodes: n, selectedAllyCode: r, selectAllyCode: i, removeAllyCode: o, addAllyCode: l, isLoadingAllyCodes: u } = K(), [d, f] = a(!1), [p, m] = a(""), [h, _] = a(""), [y, x] = a(""), [S, C] = a(!1), w = n.map((e) => ({
511
+ value: e.ally_code,
512
+ label: e.player_name ? `${e.player_name} (${q(e.ally_code)})` : q(e.ally_code)
513
+ })), T = (t) => {
514
+ let n = t.target.value || null;
515
+ i(n), e?.(n);
516
+ }, E = async (e) => {
517
+ let t = n.find((t) => t.ally_code === e);
518
+ t && await o("id" in t ? t.id : t.ally_code);
519
+ };
520
+ return n.length === 0 ? null : /* @__PURE__ */ c("div", {
521
+ className: `${Y.allyCodeDropdown} ${t}`,
522
+ children: [
523
+ /* @__PURE__ */ s(b, {
524
+ options: w,
525
+ value: r || "",
526
+ onChange: T,
527
+ placeholder: "Select ally code",
528
+ disabled: u,
529
+ className: Y.select
530
+ }),
531
+ d && /* @__PURE__ */ c("div", {
532
+ className: Y.managePanel,
533
+ children: [
534
+ /* @__PURE__ */ s("h4", { children: "Manage Ally Codes" }),
535
+ /* @__PURE__ */ c("div", {
536
+ className: Y.addSection,
537
+ children: [
538
+ /* @__PURE__ */ c("div", {
539
+ className: Y.addInputGroup,
540
+ children: [/* @__PURE__ */ s(v, {
541
+ type: "text",
542
+ placeholder: "9-digit ally code",
543
+ value: p,
544
+ onChange: (e) => m(e.target.value.replace(/\D/g, "").slice(0, 9)),
545
+ disabled: S
546
+ }), /* @__PURE__ */ s(g, {
547
+ variant: "primary",
548
+ size: "sm",
549
+ onClick: async () => {
550
+ if (_(""), x(""), !/^\d{9}$/.test(p)) {
551
+ _("Ally code must be exactly 9 digits");
552
+ return;
553
+ }
554
+ C(!0);
555
+ try {
556
+ await l(p), x("Added successfully!"), m(""), setTimeout(() => x(""), 2e3);
557
+ } catch (e) {
558
+ _(e.message || "Failed to add ally code");
559
+ } finally {
560
+ C(!1);
561
+ }
562
+ },
563
+ loading: S,
564
+ disabled: p.length !== 9,
565
+ children: "Add"
566
+ })]
567
+ }),
568
+ h && /* @__PURE__ */ s("div", {
569
+ className: Y.error,
570
+ children: h
571
+ }),
572
+ y && /* @__PURE__ */ s("div", {
573
+ className: Y.success,
574
+ children: y
575
+ })
576
+ ]
577
+ }),
578
+ /* @__PURE__ */ s("div", {
579
+ className: Y.codesList,
580
+ children: n.map((e) => /* @__PURE__ */ c("div", {
581
+ className: Y.codeItem,
582
+ children: [/* @__PURE__ */ s("span", { children: e.player_name ? `${e.player_name} (${q(e.ally_code)})` : q(e.ally_code) }), /* @__PURE__ */ s(g, {
583
+ variant: "ghost",
584
+ size: "sm",
585
+ onClick: () => E(e.ally_code),
586
+ children: "Remove"
587
+ })]
588
+ }, e.ally_code))
589
+ }),
590
+ /* @__PURE__ */ s(g, {
591
+ variant: "secondary",
592
+ size: "sm",
593
+ onClick: () => f(!1),
594
+ className: Y.doneButton,
595
+ children: "Done"
596
+ })
597
+ ]
598
+ }),
599
+ /* @__PURE__ */ s(g, {
600
+ variant: "ghost",
601
+ size: "sm",
602
+ onClick: () => f(!d),
603
+ className: Y.manageButton,
604
+ children: "Manage"
605
+ })
606
+ ]
607
+ });
608
+ }, X = {
609
+ card: "_card_b4471_1",
610
+ chamfered: "_chamfered_b4471_8",
611
+ default: "_default_b4471_13",
612
+ elevated: "_elevated_b4471_17",
613
+ outline: "_outline_b4471_22",
614
+ "padding-none": "_padding-none_b4471_28",
615
+ "padding-sm": "_padding-sm_b4471_32",
616
+ "padding-md": "_padding-md_b4471_36",
617
+ "padding-lg": "_padding-lg_b4471_40",
618
+ hoverable: "_hoverable_b4471_45"
619
+ }, te = ({ children: e, variant: t = "default", chamfered: n = !1, chamferSize: r = "md", padding: i = "md", hoverable: a = !1, showDiagonalBorders: l = !1, diagonalBorderColor: u, className: d = "", onClick: f, style: p }) => {
620
+ let m = n ? r === "asymmetric" ? "chamfered-box-asymmetric" : r === "sm" ? "chamfered-box-sm" : r === "lg" ? "chamfered-box-lg" : "chamfered-box" : "", h = u ? { color: u } : void 0;
621
+ return /* @__PURE__ */ c("div", {
622
+ className: `${X.card} ${n ? X.chamfered : ""} ${X[t]} ${X[`padding-${i}`]} ${m} ${a ? X.hoverable : ""} ${d}`,
623
+ onClick: f,
624
+ role: f ? "button" : void 0,
625
+ tabIndex: f ? 0 : void 0,
626
+ style: p,
627
+ children: [l && /* @__PURE__ */ c(o, { children: [
628
+ /* @__PURE__ */ s("div", {
629
+ className: "chamfered-diagonal-border chamfered-diagonal-tl",
630
+ style: h
631
+ }),
632
+ /* @__PURE__ */ s("div", {
633
+ className: "chamfered-diagonal-border chamfered-diagonal-tr",
634
+ style: h
635
+ }),
636
+ /* @__PURE__ */ s("div", {
637
+ className: "chamfered-diagonal-border chamfered-diagonal-bl",
638
+ style: h
639
+ }),
640
+ /* @__PURE__ */ s("div", {
641
+ className: `chamfered-diagonal-border ${r === "asymmetric" ? "chamfered-diagonal-br-large" : "chamfered-diagonal-br"}`,
642
+ style: h
643
+ })
644
+ ] }), e]
645
+ });
646
+ }, Z = {
647
+ badge: "_badge_rk7t5_1",
648
+ sm: "_sm_rk7t5_11",
649
+ md: "_md_rk7t5_16",
650
+ lg: "_lg_rk7t5_21",
651
+ default: "_default_rk7t5_27",
652
+ primary: "_primary_rk7t5_32",
653
+ secondary: "_secondary_rk7t5_37",
654
+ success: "_success_rk7t5_42",
655
+ warning: "_warning_rk7t5_47",
656
+ error: "_error_rk7t5_52",
657
+ info: "_info_rk7t5_57"
658
+ }, ne = ({ children: e, variant: t = "default", size: n = "md", className: r = "" }) => /* @__PURE__ */ s("span", {
659
+ className: `${Z.badge} ${Z[t]} ${Z[n]} ${r}`,
660
+ children: e
661
+ }), Q = {
662
+ overlay: "_overlay_1b3yt_1",
663
+ fadeIn: "_fadeIn_1b3yt_1",
664
+ modal: "_modal_1b3yt_13",
665
+ slideUp: "_slideUp_1b3yt_1",
666
+ sm: "_sm_1b3yt_25",
667
+ md: "_md_1b3yt_30",
668
+ lg: "_lg_1b3yt_35",
669
+ xl: "_xl_1b3yt_40",
670
+ header: "_header_1b3yt_45",
671
+ title: "_title_1b3yt_53",
672
+ closeButton: "_closeButton_1b3yt_60",
673
+ content: "_content_1b3yt_78"
674
+ }, re = ({ isOpen: e, onClose: t, title: n, children: r, size: a = "md", closeOnOverlayClick: o = !0, className: l = "" }) => (i(() => (e ? document.body.style.overflow = "hidden" : document.body.style.overflow = "unset", () => {
675
+ document.body.style.overflow = "unset";
676
+ }), [e]), i(() => {
677
+ let n = (n) => {
678
+ n.key === "Escape" && e && t();
679
+ };
680
+ return document.addEventListener("keydown", n), () => document.removeEventListener("keydown", n);
681
+ }, [e, t]), e ? /* @__PURE__ */ s("div", {
682
+ className: Q.overlay,
683
+ onClick: (e) => {
684
+ o && e.target === e.currentTarget && t();
685
+ },
686
+ children: /* @__PURE__ */ c("div", {
687
+ className: `${Q.modal} ${Q[a]} ${l}`,
688
+ role: "dialog",
689
+ "aria-modal": "true",
690
+ children: [n && /* @__PURE__ */ c("div", {
691
+ className: Q.header,
692
+ children: [/* @__PURE__ */ s("h2", {
693
+ className: Q.title,
694
+ children: n
695
+ }), /* @__PURE__ */ s("button", {
696
+ className: Q.closeButton,
697
+ onClick: t,
698
+ "aria-label": "Close modal",
699
+ children: "✕"
700
+ })]
701
+ }), /* @__PURE__ */ s("div", {
702
+ className: Q.content,
703
+ children: r
704
+ })]
705
+ })
706
+ }) : null), $ = {
707
+ spinner: "_spinner_1uhnh_2",
708
+ spin: "_spin_1uhnh_2",
709
+ sm: "_sm_1uhnh_9",
710
+ md: "_md_1uhnh_15",
711
+ lg: "_lg_1uhnh_21",
712
+ dots: "_dots_1uhnh_34",
713
+ dot: "_dot_1uhnh_34",
714
+ bounce: "_bounce_1uhnh_1",
715
+ visuallyHidden: "_visuallyHidden_1uhnh_91"
716
+ }, ie = ({ size: e = "md", variant: t = "spinner", className: n = "" }) => t === "dots" ? /* @__PURE__ */ c("div", {
717
+ className: `${$.dots} ${$[e]} ${n}`,
718
+ children: [
719
+ /* @__PURE__ */ s("span", { className: $.dot }),
720
+ /* @__PURE__ */ s("span", { className: $.dot }),
721
+ /* @__PURE__ */ s("span", { className: $.dot })
722
+ ]
723
+ }) : /* @__PURE__ */ s("div", {
724
+ className: `${$.spinner} ${$[e]} ${n}`,
725
+ role: "status",
726
+ children: /* @__PURE__ */ s("span", {
727
+ className: $.visuallyHidden,
728
+ children: "Loading..."
729
+ })
730
+ });
731
+ //#endregion
732
+ export { ee as AllyCodeDropdown, M as ApiClient, G as AuthProvider, ne as Badge, g as Button, te as Card, u as Container, m as Footer, v as Input, ie as Loader, re as Modal, b as Select, f as TopBar, N as apiClient, U as clearAllyCodes, A as clearTokens, q as formatAllyCode, C as getAccessToken, L as getAllyCodesFromStorage, E as getRefreshToken, V as getSelectedAllyCode, P as initializeApiClient, j as isAuthenticated, T as removeAccessToken, z as removeAllyCodeFromStorage, O as removeRefreshToken, R as saveAllyCodeToStorage, w as setAccessToken, D as setRefreshToken, H as setSelectedAllyCode, k as setTokens, J as unformatAllyCode, B as updateAllyCodeLastUsed, K as useAuth };