@mundogamernetwork/shared-ui 1.13.3 → 1.13.4

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.
@@ -32,6 +32,27 @@ const emit = defineEmits<{ (e: "navigate"): void }>();
32
32
  /** Missions and the reward store live on Community for the whole ecosystem. */
33
33
  const COMMUNITY_URL = "https://mundogamer.community";
34
34
 
35
+ /**
36
+ * Dig out the payload regardless of how many envelopes wrap it.
37
+ *
38
+ * The API nests deeper than its own sendResponse() suggests — the gateway adds
39
+ * a second {message,data,status_code} layer on top, so the payload sits at
40
+ * response.data.data.data rather than response.data.data. Reading a fixed
41
+ * depth silently returned the inner envelope, which has no `level`, so the bar
42
+ * loaded and vanished on a perfectly good 200. Walking down until the shape
43
+ * appears survives either nesting.
44
+ */
45
+ function unwrapSummary(payload: any): GamificationSummary | null {
46
+ let node = payload;
47
+
48
+ for (let depth = 0; depth < 4 && node && typeof node === "object"; depth += 1) {
49
+ if (node.level || node.wallet || node.missions) return node as GamificationSummary;
50
+ node = node.data;
51
+ }
52
+
53
+ return null;
54
+ }
55
+
35
56
  const summary = ref<GamificationSummary | null>(null);
36
57
  const loaded = ref(false);
37
58
 
@@ -55,7 +76,12 @@ const destination = computed(() => {
55
76
  const balance = computed(() => {
56
77
  const fromHost = props.mgcBalance;
57
78
  const value = fromHost !== null && fromHost !== undefined ? fromHost : summary.value?.wallet?.balance;
58
- return typeof value === "number" ? Math.floor(value).toLocaleString() : null;
79
+ // The API sends the balance as a decimal string ("1801.50"), not a number.
80
+ const numeric = typeof value === "string" ? Number(value) : value;
81
+
82
+ return typeof numeric === "number" && Number.isFinite(numeric)
83
+ ? Math.floor(numeric).toLocaleString()
84
+ : null;
59
85
  });
60
86
 
61
87
  // progress_percent comes from the API; the local computation is a fallback for
@@ -71,7 +97,7 @@ const percent = computed(() => {
71
97
  onMounted(async () => {
72
98
  try {
73
99
  const response = await fetchGamificationSummary();
74
- summary.value = response?.data?.data ?? response?.data ?? null;
100
+ summary.value = unwrapSummary(response?.data);
75
101
  } catch (error) {
76
102
  // Never let a gamification hiccup break the header it sits in — but say
77
103
  // so. Swallowing this silently made a deployed bar that renders nothing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mundogamernetwork/shared-ui",
3
- "version": "1.13.3",
3
+ "version": "1.13.4",
4
4
  "description": "Mundo Gamer Network - Shared UI Layer (Nuxt 3)",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",
@@ -18,7 +18,8 @@ export interface XpLevel {
18
18
 
19
19
  export interface GamificationSummary {
20
20
  level: XpLevel;
21
- wallet: { balance: number; lifetime_earned: number };
21
+ /** The API serialises these as decimal strings, not numbers. */
22
+ wallet: { balance: number | string; lifetime_earned: number | string };
22
23
  missions: { active: any[]; claimable_count: number };
23
24
  achievements: { total_unlocked: number; recent: any[] };
24
25
  }