@mundogamernetwork/shared-ui 1.1.76 → 1.1.78

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
@@ -133,7 +133,9 @@
133
133
  "who_redeem": "Who redeemed",
134
134
  "created_by": "Published by",
135
135
  "no_data": "Campaign not found",
136
- "title": "Kampagne"
136
+ "title": "Kampagne",
137
+ "about": "Über das Spiel",
138
+ "screenshot_alt": "Spiel-Screenshot"
137
139
  },
138
140
  "other_campaigns": "Andere Kampagnen",
139
141
  "available": "verfügbar",
@@ -191,5 +193,9 @@
191
193
  "success_message": "Your material was sent for review. Thank you!",
192
194
  "success_close": "Close"
193
195
  }
196
+ },
197
+ "common": {
198
+ "video_thumbnail": "Video-Vorschaubild",
199
+ "expanded_image": "Vergrößertes Bild"
194
200
  }
195
201
  }
package/locales/en.json CHANGED
@@ -133,7 +133,9 @@
133
133
  "who_redeem": "Who redeemed",
134
134
  "created_by": "Published by",
135
135
  "no_data": "Campaign not found",
136
- "title": "Campaign"
136
+ "title": "Campaign",
137
+ "about": "About the game",
138
+ "screenshot_alt": "Game screenshot"
137
139
  },
138
140
  "other_campaigns": "Other campaigns",
139
141
  "available": "available",
@@ -191,5 +193,9 @@
191
193
  "success_message": "Your material was sent for review. Thank you!",
192
194
  "success_close": "Close"
193
195
  }
196
+ },
197
+ "common": {
198
+ "video_thumbnail": "Video thumbnail",
199
+ "expanded_image": "Expanded image"
194
200
  }
195
201
  }
@@ -133,7 +133,9 @@
133
133
  "who_redeem": "Who redeemed",
134
134
  "created_by": "Published by",
135
135
  "no_data": "Campaign not found",
136
- "title": "Campanha"
136
+ "title": "Campanha",
137
+ "about": "Sobre o jogo",
138
+ "screenshot_alt": "Captura de tela do jogo"
137
139
  },
138
140
  "other_campaigns": "Outras campanhas",
139
141
  "available": "disponível",
@@ -191,5 +193,9 @@
191
193
  "success_message": "Your material was sent for review. Thank you!",
192
194
  "success_close": "Close"
193
195
  }
196
+ },
197
+ "common": {
198
+ "video_thumbnail": "Miniatura do vídeo",
199
+ "expanded_image": "Imagem ampliada"
194
200
  }
195
201
  }
package/locales/ro.json CHANGED
@@ -133,7 +133,9 @@
133
133
  "who_redeem": "Who redeemed",
134
134
  "created_by": "Published by",
135
135
  "no_data": "Campaign not found",
136
- "title": "Campanie"
136
+ "title": "Campanie",
137
+ "about": "Despre joc",
138
+ "screenshot_alt": "Captură de ecran a jocului"
137
139
  },
138
140
  "other_campaigns": "Alte campanii",
139
141
  "available": "disponibil",
@@ -191,5 +193,9 @@
191
193
  "success_message": "Your material was sent for review. Thank you!",
192
194
  "success_close": "Close"
193
195
  }
196
+ },
197
+ "common": {
198
+ "video_thumbnail": "Miniatură video",
199
+ "expanded_image": "Imagine mărită"
194
200
  }
195
201
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mundogamernetwork/shared-ui",
3
- "version": "1.1.76",
3
+ "version": "1.1.78",
4
4
  "description": "Mundo Gamer Network - Shared UI Layer (Nuxt 3)",
5
5
  "type": "module",
6
6
  "main": "./nuxt.config.ts",
@@ -111,6 +111,34 @@ const { data: redeemedUsers } = await useAsyncData(
111
111
  { watch: [campaign] },
112
112
  )
113
113
 
114
+ // ------------------------------------------------------------------
115
+ // Game gallery (images/videos) — already embedded in the campaign payload
116
+ // ------------------------------------------------------------------
117
+ const gameDetailsImages = computed(() => campaign.value?.game_images || [])
118
+ const gameDetailsVideos = computed(() => campaign.value?.game_videos || [])
119
+
120
+ const showVideoModal = ref(false)
121
+ const selectedVideoUrl = ref("")
122
+ const showImageModal = ref(false)
123
+ const selectedImageUrl = ref("")
124
+
125
+ const openVideoPlayer = (videoUrl: string) => {
126
+ selectedVideoUrl.value = videoUrl
127
+ showVideoModal.value = true
128
+ }
129
+
130
+ const openImagePreview = (imageUrl: string) => {
131
+ selectedImageUrl.value = imageUrl
132
+ showImageModal.value = true
133
+ }
134
+
135
+ const closeMediaModal = () => {
136
+ showVideoModal.value = false
137
+ showImageModal.value = false
138
+ selectedVideoUrl.value = ""
139
+ selectedImageUrl.value = ""
140
+ }
141
+
114
142
  // ------------------------------------------------------------------
115
143
  // Countdown
116
144
  // ------------------------------------------------------------------
@@ -570,6 +598,73 @@ onMounted(async () => {
570
598
  <span>{{ $t("keys.campaigns.campaign.no_data") }}</span>
571
599
  </div>
572
600
  </div>
601
+
602
+ <div class="gallery" v-if="(gameDetailsImages && gameDetailsImages.length) || (gameDetailsVideos && gameDetailsVideos.length)">
603
+ <template v-if="gameDetailsVideos && gameDetailsVideos.length > 0">
604
+ <div
605
+ v-if="gameDetailsImages"
606
+ v-for="(image, index) in gameDetailsImages.slice(0, 3)"
607
+ :key="'image-' + index"
608
+ class="image-thumbnail"
609
+ @click="openImagePreview('https:' + image.url_image_src)"
610
+ >
611
+ <img :src="'https:' + image.url_image_src" :alt="$t('keys.campaigns.campaign.screenshot_alt')" />
612
+ </div>
613
+ <div
614
+ v-for="(video, index) in gameDetailsVideos.slice(0, 1)"
615
+ :key="'video-' + index"
616
+ class="video-thumbnail"
617
+ @click="openVideoPlayer('https://www.youtube.com/embed/' + video.external_id)"
618
+ >
619
+ <img
620
+ :src="'https://img.youtube.com/vi/' + video.external_id + '/hqdefault.jpg'"
621
+ :alt="$t('common.video_thumbnail')"
622
+ />
623
+ <div class="play-icon">
624
+ <MGIcon size="2x" icon="youtube" />
625
+ </div>
626
+ </div>
627
+ </template>
628
+
629
+ <template v-else-if="gameDetailsImages && gameDetailsImages.length > 0">
630
+ <div
631
+ v-for="(image, index) in gameDetailsImages.slice(0, 4)"
632
+ :key="'image-' + index"
633
+ class="image-thumbnail"
634
+ @click="openImagePreview('https:' + image.url_image_src)"
635
+ >
636
+ <img :src="'https:' + image.url_image_src" :alt="$t('keys.campaigns.campaign.screenshot_alt')" />
637
+ </div>
638
+ </template>
639
+ </div>
640
+
641
+ <div class="media-modal" v-if="showVideoModal" @click.self="closeMediaModal">
642
+ <div class="media-modal-content">
643
+ <button class="close-button" @click="closeMediaModal">
644
+ <MGIcon size="1x" icon="close" />
645
+ </button>
646
+ <iframe
647
+ :src="selectedVideoUrl"
648
+ frameborder="0"
649
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
650
+ allowfullscreen
651
+ ></iframe>
652
+ </div>
653
+ </div>
654
+
655
+ <div class="media-modal" v-if="showImageModal" @click.self="closeMediaModal">
656
+ <div class="media-modal-content">
657
+ <button class="close-button" @click="closeMediaModal">
658
+ <MGIcon size="1x" icon="close" />
659
+ </button>
660
+ <img :src="selectedImageUrl" :alt="$t('common.expanded_image')" class="expanded-image" />
661
+ </div>
662
+ </div>
663
+
664
+ <div class="game-summary" v-if="campaign?.game_summary">
665
+ <div class="title">{{ $t("keys.campaigns.campaign.about") }}</div>
666
+ <div class="description" v-html="campaign.game_summary"></div>
667
+ </div>
573
668
  </div>
574
669
  </div>
575
670
 
@@ -932,6 +1027,71 @@ onMounted(async () => {
932
1027
  span { color: var(--card-article-title); }
933
1028
  }
934
1029
  }
1030
+
1031
+ .gallery {
1032
+ display: grid;
1033
+ grid-template-columns: repeat(4, 1fr);
1034
+ gap: 8px;
1035
+
1036
+ .image-thumbnail, .video-thumbnail {
1037
+ position: relative;
1038
+ aspect-ratio: 16 / 9;
1039
+ overflow: hidden;
1040
+ cursor: pointer;
1041
+ background-color: var(--button-secondary-default-bg);
1042
+ img { width: 100%; height: 100%; object-fit: cover; }
1043
+ }
1044
+
1045
+ .video-thumbnail {
1046
+ .play-icon {
1047
+ position: absolute;
1048
+ inset: 0;
1049
+ display: flex;
1050
+ align-items: center;
1051
+ justify-content: center;
1052
+ color: #fff;
1053
+ background: var(--overlay-dark, rgba(0, 0, 0, 0.45));
1054
+ }
1055
+ }
1056
+ }
1057
+
1058
+ .media-modal {
1059
+ position: fixed;
1060
+ inset: 0;
1061
+ z-index: 1000;
1062
+ display: flex;
1063
+ align-items: center;
1064
+ justify-content: center;
1065
+ background: var(--overlay-dark-strong, rgba(0, 0, 0, 0.75));
1066
+
1067
+ .media-modal-content {
1068
+ position: relative;
1069
+ max-width: 90vw;
1070
+ max-height: 90vh;
1071
+
1072
+ iframe { width: 80vw; height: 45vw; max-height: 80vh; border: none; }
1073
+ .expanded-image { max-width: 90vw; max-height: 90vh; object-fit: contain; }
1074
+
1075
+ .close-button {
1076
+ position: absolute;
1077
+ top: -40px;
1078
+ right: 0;
1079
+ background: transparent;
1080
+ border: none;
1081
+ color: #fff;
1082
+ cursor: pointer;
1083
+ }
1084
+ }
1085
+ }
1086
+
1087
+ .game-summary {
1088
+ display: flex;
1089
+ flex-direction: column;
1090
+ gap: 8px;
1091
+
1092
+ .title { font-size: 14px; font-weight: 600; color: var(--card-article-title); }
1093
+ .description { font-size: 13px; line-height: 1.6; color: var(--secondary-info-fg); }
1094
+ }
935
1095
  }
936
1096
  }
937
1097
 
@@ -282,6 +282,8 @@ export const fetchCampaignBySlug = async (slug: string) => {
282
282
  available_at_for_user: k.available_at_for_user ?? null,
283
283
  max_keys_for_user: k.max_keys_for_user ?? 1,
284
284
  game_summary: k.game?.summary,
285
+ game_images: (k.game?.images || []) as Array<{ url_image_src: string }>,
286
+ game_videos: (k.game?.videos || []) as Array<{ external_id: string; name?: string }>,
285
287
  request_id: k.requests?.[0]?.id,
286
288
  request_item_id: k.requests?.[0]?.key_item_id,
287
289
  request_admin_notes: k.requests?.[0]?.admin_notes ?? null,