@mundogamernetwork/shared-ui 1.17.10 → 1.17.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/locales/de.json CHANGED
@@ -255,6 +255,9 @@
255
255
  "title_not_open": "Diese Kampagne",
256
256
  "title_span_not_open": "ist noch nicht gestartet",
257
257
  "obs_not_open": "Anfragen werden erst ab dem Startdatum der Kampagne angenommen. Schau dann wieder vorbei.",
258
+ "title_lookup_failed": "Wir konnten deine Anfrage nicht prüfen",
259
+ "obs_lookup_failed": "Beim Prüfen, ob du bereits eine Anfrage für diese Kampagne hast, ist etwas schiefgelaufen. Versuche es erneut.",
260
+ "retry_lookup": "Erneut versuchen",
258
261
  "title_0": "Campaign",
259
262
  "title_span_0": "ended",
260
263
  "obs_0": "The redemption period for the key has expired.",
package/locales/en.json CHANGED
@@ -255,6 +255,9 @@
255
255
  "title_not_open": "This campaign",
256
256
  "title_span_not_open": "hasn't opened yet",
257
257
  "obs_not_open": "Requests aren't accepted until the campaign's start date. Come back then.",
258
+ "title_lookup_failed": "We couldn't check your request",
259
+ "obs_lookup_failed": "Something went wrong while checking whether you already have a request for this campaign. Try again.",
260
+ "retry_lookup": "Try again",
258
261
  "title_0": "Campaign",
259
262
  "title_span_0": "ended",
260
263
  "obs_0": "The redemption period for the key has expired.",
package/locales/es.json CHANGED
@@ -255,6 +255,9 @@
255
255
  "title_not_open": "Esta campaña",
256
256
  "title_span_not_open": "aún no ha comenzado",
257
257
  "obs_not_open": "Las solicitudes solo se aceptan a partir de la fecha de inicio de la campaña. Vuelve entonces.",
258
+ "title_lookup_failed": "No pudimos comprobar tu solicitud",
259
+ "obs_lookup_failed": "Algo salió mal al comprobar si ya tienes una solicitud para esta campaña. Inténtalo de nuevo.",
260
+ "retry_lookup": "Reintentar",
258
261
  "title_0": "Campaña",
259
262
  "title_span_0": "finalizada",
260
263
  "obs_0": "El período de canje de la clave ha expirado.",
@@ -255,6 +255,9 @@
255
255
  "title_not_open": "Esta campanha",
256
256
  "title_span_not_open": "ainda não abriu",
257
257
  "obs_not_open": "Os pedidos só são aceitos a partir da data de início da campanha. Volte lá.",
258
+ "title_lookup_failed": "Não conseguimos verificar seu pedido",
259
+ "obs_lookup_failed": "Algo deu errado ao verificar se você já tem um pedido para esta campanha. Tente novamente.",
260
+ "retry_lookup": "Tentar novamente",
258
261
  "title_0": "Campaign",
259
262
  "title_span_0": "ended",
260
263
  "obs_0": "The redemption period for the key has expired.",
package/locales/ro.json CHANGED
@@ -255,6 +255,9 @@
255
255
  "title_not_open": "Această campanie",
256
256
  "title_span_not_open": "nu s-a deschis încă",
257
257
  "obs_not_open": "Cererile sunt acceptate abia de la data de început a campaniei. Revino atunci.",
258
+ "title_lookup_failed": "Nu am putut verifica cererea ta",
259
+ "obs_lookup_failed": "A apărut o eroare la verificarea existenței unei cereri pentru această campanie. Încearcă din nou.",
260
+ "retry_lookup": "Încearcă din nou",
258
261
  "title_0": "Campaign",
259
262
  "title_span_0": "ended",
260
263
  "obs_0": "The redemption period for the key has expired.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mundogamernetwork/shared-ui",
3
- "version": "1.17.10",
3
+ "version": "1.17.11",
4
4
  "description": "Mundo Gamer Network - Shared UI Layer (Nuxt 3)",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",
@@ -353,6 +353,16 @@ const userRequestStatus = ref<number | null | undefined>(undefined)
353
353
  const userRequestId = ref<number | null>(null)
354
354
  const userKeyItemId = ref<number | null>(null)
355
355
 
356
+ // The campaign payload comes from an anonymous client (no credentials, and the
357
+ // SSR pass never knows the session — the auth store lives in localStorage), so
358
+ // it cannot say whether *this* viewer already has a request. Until the
359
+ // credentialed my-requests lookup below has answered, the banner must not
360
+ // commit to a state: it used to show "Request a key" to everyone first, and
361
+ // kept showing it when the lookup failed — a button the API answers 409 to for
362
+ // anyone who already asked, whatever the status.
363
+ const lookupSettled = ref(false)
364
+ const lookupFailed = ref(false)
365
+
356
366
  const effectiveKeyStatus = computed(() => {
357
367
  if (userRequestStatus.value !== undefined) return userRequestStatus.value
358
368
  return campaign.value?.request_status
@@ -410,6 +420,14 @@ type StatusConfig = {
410
420
  }
411
421
 
412
422
  const statusConfigs: Record<string, StatusConfig> = {
423
+ // The viewer is signed in but we could not tell whether they already have a
424
+ // request — say so and let them retry, rather than offering to request.
425
+ lookup_failed: {
426
+ titleParts: [{ text: "keys.campaigns.status_key.title_lookup_failed" }],
427
+ obs: "keys.campaigns.status_key.obs_lookup_failed",
428
+ obsColor: "yellow",
429
+ actions: [{ type: "retry-lookup" }],
430
+ },
413
431
  not_yet_open: {
414
432
  titleParts: [
415
433
  { text: "keys.campaigns.status_key.title_not_open" },
@@ -559,6 +577,9 @@ const statusConfigs: Record<string, StatusConfig> = {
559
577
  }
560
578
 
561
579
  const currentConfig = computed((): StatusConfig | null => {
580
+ if (!lookupSettled.value) return null
581
+ if (lookupFailed.value) return statusConfigs.lookup_failed
582
+
562
583
  const status = effectiveKeyStatus.value
563
584
  const campaignExpired = !hasNoDateLimit.value && parseTimeToExpire(campaign.value?.time_to_expire) <= 0
564
585
  const campaignExhausted = (campaign.value?.available_count ?? 0) < 1
@@ -621,26 +642,46 @@ const showUsersModal = ref(false)
621
642
  // ------------------------------------------------------------------
622
643
  // Lifecycle
623
644
  // ------------------------------------------------------------------
624
- onMounted(async () => {
625
- updateCountdown()
645
+ async function loadMyRequest() {
646
+ if (!isSignedIn() || !campaign.value?.id) {
647
+ lookupSettled.value = true
648
+ return
649
+ }
626
650
 
627
- if (isSignedIn() && campaign.value?.id) {
628
- try {
629
- const response = await fetchMyRequests({ "filter[key_id]": campaign.value.id })
630
- const requests = response?.data?.data
631
- if (requests && requests.length > 0) {
632
- const slugStatus = requests[0]?.status_request?.slug
633
- userRequestStatus.value = slugStatus ? (statusSlugToNumeric[slugStatus] ?? null) : null
634
- userRequestId.value = requests[0]?.id ?? null
635
- userKeyItemId.value = requests[0]?.key_item_id ?? null
636
- } else {
637
- userRequestStatus.value = null
638
- }
639
- } catch {
651
+ lookupSettled.value = false
652
+ lookupFailed.value = false
653
+ try {
654
+ const response = await fetchMyRequests({ "filter[key_id]": campaign.value.id })
655
+ const requests = response?.data?.data
656
+ if (requests && requests.length > 0) {
657
+ const slugStatus = requests[0]?.status_request?.slug
658
+ userRequestStatus.value = slugStatus ? (statusSlugToNumeric[slugStatus] ?? null) : null
659
+ userRequestId.value = requests[0]?.id ?? null
660
+ userKeyItemId.value = requests[0]?.key_item_id ?? null
661
+ } else {
640
662
  userRequestStatus.value = null
641
663
  }
664
+ } catch {
665
+ lookupFailed.value = true
666
+ } finally {
667
+ lookupSettled.value = true
642
668
  }
669
+ }
670
+
671
+ onMounted(async () => {
672
+ updateCountdown()
673
+ await loadMyRequest()
643
674
  })
675
+
676
+ // Some fronts fill the auth store after this page has mounted (it is read from
677
+ // storage, not from the SSR pass), so a viewer who is signed in but not yet
678
+ // known at mount time would otherwise never be looked up.
679
+ watch(
680
+ () => !!unref(currentUser)?.id,
681
+ (signedIn) => {
682
+ if (signedIn && lookupSettled.value && userRequestStatus.value === undefined) loadMyRequest()
683
+ },
684
+ )
644
685
  </script>
645
686
 
646
687
  <template>
@@ -701,6 +742,12 @@ onMounted(async () => {
701
742
  </button>
702
743
  </template>
703
744
 
745
+ <template v-else-if="currentConfig.actions?.[0]?.type === 'retry-lookup'">
746
+ <button class="btn" @click="loadMyRequest">
747
+ {{ $t("keys.campaigns.status_key.retry_lookup") }}
748
+ </button>
749
+ </template>
750
+
704
751
  <template v-else-if="currentConfig.actions?.[0]?.type === 'reveal-key'">
705
752
  <button class="btn" @click="requireAuth(`/${locale}/key-campaigns/redeem-key-approved?requestId=${effectiveRequestId}${effectiveKeyItems ? '&keyItems=' + effectiveKeyItems : ''}`)">
706
753
  {{ $t("keys.campaigns.status_key.reveal_key") }}
@@ -729,6 +776,14 @@ onMounted(async () => {
729
776
  </a>
730
777
  </div>
731
778
  </div>
779
+ <!-- Same footprint as the banner while my-requests is in flight: no
780
+ committing to "Request a key" before we know, and no layout jump. -->
781
+ <div class="rescue rescue--loading" v-else-if="!lookupSettled" aria-hidden="true">
782
+ <div class="rescue-texts">
783
+ <span class="sk sk--title" />
784
+ <span class="sk sk--info" />
785
+ </div>
786
+ </div>
732
787
  </div>
733
788
 
734
789
  <div v-if="!campaign" class="state error">{{ $t("keys.campaigns.error_loading") }}</div>
@@ -1173,6 +1228,18 @@ onMounted(async () => {
1173
1228
  &.disabled { opacity: 0.5; pointer-events: none; }
1174
1229
  }
1175
1230
 
1231
+ &.rescue--loading {
1232
+ min-height: 68px;
1233
+
1234
+ .sk {
1235
+ display: block;
1236
+ background-color: var(--bg-app-badge);
1237
+ opacity: 0.6;
1238
+ }
1239
+ .sk--title { width: 180px; max-width: 60%; height: 14px; }
1240
+ .sk--info { width: 280px; max-width: 90%; height: 12px; }
1241
+ }
1242
+
1176
1243
  .rescue-actions {
1177
1244
  display: flex;
1178
1245
  flex-direction: column;