@mundogamernetwork/shared-ui 1.1.67 → 1.1.69

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.
@@ -190,7 +190,7 @@
190
190
  <div class="days" v-else></div>
191
191
  <span>
192
192
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
193
- <path d="M13.3333 4.1112L12.8666 3.64453L11.9333 4.57786L10.9333 3.64453L8.33329 4.1112L2.66663 9.77786L7.19996 14.3112L12.8666 8.64453L13.3333 6.04453L12.4 5.1112L13.3333 4.1112ZM12.6 6.24453L12.2666 8.3112L7.19996 13.3779L3.59996 9.77786L8.66663 4.7112L10.7333 4.3112L11.4666 5.04453L11 5.5112L10.5333 5.04453L9.99996 5.57786L11.4 6.97786L11.8666 6.5112L11.4 6.04453L11.8666 5.57786L12.6 6.24453Z" fill="var(--key-accent, #D297FF)" />
193
+ <path d="M13.3333 4.1112L12.8666 3.64453L11.9333 4.57786L10.9333 3.64453L8.33329 4.1112L2.66663 9.77786L7.19996 14.3112L12.8666 8.64453L13.3333 6.04453L12.4 5.1112L13.3333 4.1112ZM12.6 6.24453L12.2666 8.3112L7.19996 13.3779L3.59996 9.77786L8.66663 4.7112L10.7333 4.3112L11.4666 5.04453L11 5.5112L10.5333 5.04453L9.99996 5.57786L11.4 6.97786L11.8666 6.5112L11.4 6.04453L11.8666 5.57786L12.6 6.24453Z" fill="var(--key-accent, var(--key-accent, var(--primary, #D297FF)))" />
194
194
  </svg>
195
195
  {{ card.type }}
196
196
  </span>
@@ -737,7 +737,7 @@ onUnmounted(() => {
737
737
  display: inline-block;
738
738
  width: 20px;
739
739
  height: 20px;
740
- border: 2px solid var(--key-accent, #d297ff);
740
+ border: 2px solid var(--key-accent, var(--key-accent, var(--primary, #D297FF)));
741
741
  border-radius: 50%;
742
742
  border-top-color: #fff;
743
743
  animation: spin 1s ease-in-out infinite;
@@ -775,7 +775,7 @@ onUnmounted(() => {
775
775
  position: absolute;
776
776
  bottom: 8px;
777
777
  right: 8px;
778
- background: var(--key-accent-dark, rgba(107, 21, 172, 0.9));
778
+ background: var(--key-accent-dark, var(--key-accent-bg, rgba(107, 21, 172, 0.9)));
779
779
  color: #fff;
780
780
  font-size: 12px;
781
781
  font-weight: 600;
@@ -790,7 +790,7 @@ onUnmounted(() => {
790
790
  position: absolute;
791
791
  top: 8px;
792
792
  left: 8px;
793
- background: rgba(234, 179, 8, 0.9);
793
+ background: var(--exclusive-badge-bg, rgba(234, 179, 8, 0.9));
794
794
  color: #000;
795
795
  font-size: 10px;
796
796
  font-weight: 700;
@@ -806,15 +806,15 @@ onUnmounted(() => {
806
806
  .level-badge {
807
807
  top: auto;
808
808
  bottom: 8px;
809
- background: rgba(210, 151, 255, 0.92);
810
- color: #1c1c1c;
809
+ background: var(--level-badge-bg, rgba(210, 151, 255, 0.92));
810
+ color: var(--key-accent-ink, #13161C);
811
811
  }
812
812
 
813
813
  .early-access-badge {
814
814
  position: absolute;
815
815
  top: 8px;
816
816
  left: 8px;
817
- background: var(--key-accent-dark, rgba(107, 21, 172, 0.9));
817
+ background: var(--key-accent-dark, var(--key-accent-bg, rgba(107, 21, 172, 0.9)));
818
818
  color: #fff;
819
819
  font-size: 10px;
820
820
  font-weight: 700;
@@ -827,13 +827,13 @@ onUnmounted(() => {
827
827
  i { font-size: 10px; }
828
828
  }
829
829
 
830
- .exclusive-lock { background: rgba(234, 179, 8, 0.6) !important; }
830
+ .exclusive-lock { background: var(--exclusive-lock-bg, rgba(234, 179, 8, 0.6)) !important; }
831
831
 
832
832
  .early-access-lock-overlay,
833
833
  .exclusive-lock-overlay {
834
834
  position: absolute;
835
835
  inset: 0;
836
- background: rgba(0, 0, 0, 0.72);
836
+ background: var(--overlay-dark-strong, rgba(0, 0, 0, 0.72));
837
837
  display: flex;
838
838
  flex-direction: column;
839
839
  align-items: center;
@@ -842,13 +842,13 @@ onUnmounted(() => {
842
842
  padding: 12px;
843
843
  text-align: center;
844
844
 
845
- i { font-size: 24px; color: var(--key-accent, #D297FF); }
845
+ i { font-size: 24px; color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
846
846
  .lock-label { color: #fff; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; }
847
- .lock-countdown { color: var(--key-accent, #D297FF); font-size: 12px; font-weight: 600; }
848
- .lock-cta { color: #EAB308; font-size: 11px; font-weight: 600; }
847
+ .lock-countdown { color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); font-size: 12px; font-weight: 600; }
848
+ .lock-cta { color: var(--exclusive-badge-color, #EAB308); font-size: 11px; font-weight: 600; }
849
849
  }
850
850
 
851
- .exclusive-lock-overlay i { color: #EAB308; }
851
+ .exclusive-lock-overlay i { color: var(--exclusive-badge-color, #EAB308); }
852
852
 
853
853
  .upgrade-btn {
854
854
  display: flex;
@@ -952,7 +952,7 @@ onUnmounted(() => {
952
952
  cursor: pointer;
953
953
  }
954
954
 
955
- span.active { background: var(--key-accent, #6b15ac); }
955
+ span.active { background: var(--key-accent, var(--key-accent, var(--primary, #6b15ac))); }
956
956
  }
957
957
  }
958
958
 
@@ -997,8 +997,8 @@ onUnmounted(() => {
997
997
  }
998
998
 
999
999
  .header-left .btn.tertiary.active {
1000
- background-color: var(--key-accent, #D297FF);
1001
- color: #1C1C1C;
1000
+ background-color: var(--key-accent, var(--key-accent, var(--primary, #D297FF)));
1001
+ color: var(--key-accent-ink, #13161C);
1002
1002
  }
1003
1003
 
1004
1004
  .platform-select {
@@ -1012,11 +1012,11 @@ onUnmounted(() => {
1012
1012
  cursor: pointer;
1013
1013
 
1014
1014
  option {
1015
- background: var(--bg-primary, #1c1c1c);
1015
+ background: var(--bg-primary, var(--key-accent-ink, #13161C));
1016
1016
  color: var(--title-fg);
1017
1017
  }
1018
1018
 
1019
- &:focus { outline: none; border-color: var(--key-accent, #D297FF); }
1019
+ &:focus { outline: none; border-color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
1020
1020
  }
1021
1021
 
1022
1022
  .filter-divider {
@@ -1078,7 +1078,7 @@ onUnmounted(() => {
1078
1078
 
1079
1079
  &:not(.unavailable):hover {
1080
1080
  transform: translateY(-4px);
1081
- box-shadow: 0 8px 24px rgba(107, 21, 172, 0.15);
1081
+ box-shadow: 0 8px 24px var(--key-accent-shadow, rgba(107, 21, 172, 0.15));
1082
1082
  }
1083
1083
 
1084
1084
  .card-header {
@@ -1116,7 +1116,7 @@ onUnmounted(() => {
1116
1116
  display: flex;
1117
1117
  align-items: center;
1118
1118
  gap: 4px;
1119
- span { color: var(--key-accent, #d297ff); font-size: 16px; font-weight: 600; }
1119
+ span { color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); font-size: 16px; font-weight: 600; }
1120
1120
  }
1121
1121
 
1122
1122
  span {
@@ -1168,7 +1168,7 @@ onUnmounted(() => {
1168
1168
  justify-content: center;
1169
1169
  cursor: pointer;
1170
1170
  flex-shrink: 0;
1171
- &:hover { border-color: var(--key-accent, #D297FF); color: var(--key-accent, #D297FF); }
1171
+ &:hover { border-color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
1172
1172
  i { font-size: 14px; }
1173
1173
  }
1174
1174
  }
@@ -1187,7 +1187,7 @@ onUnmounted(() => {
1187
1187
  font-size: 12px;
1188
1188
  color: var(--title-fg);
1189
1189
  font-weight: 400;
1190
- span { color: var(--key-accent, #d297ff); }
1190
+ span { color: var(--key-accent, var(--key-accent, var(--primary, #D297FF))); }
1191
1191
  }
1192
1192
  }
1193
1193
  }
@@ -0,0 +1,311 @@
1
+ <script lang="ts" setup>
2
+ import { ref, inject, onMounted } from "vue"
3
+ import { useRoute, navigateTo } from "#app"
4
+ import { useNuxtApp } from "#app"
5
+ import { revealKey, fetchKeyRequestById } from "../../services/campaignService"
6
+
7
+ const route = useRoute()
8
+ const { $i18n } = useNuxtApp()
9
+ const locale = $i18n.locale
10
+
11
+ const currentUser = inject<any>("currentUser", null)
12
+ const loginUrl = inject<string>("loginUrl", "/")
13
+
14
+ const requestId = Number(route.query.requestId)
15
+ const keyItemsParam = route.query.keyItems as string | undefined
16
+
17
+ const loading = ref(true)
18
+ const revealing = ref(false)
19
+ const keyCode = ref<string | null>(null)
20
+ const error = ref("")
21
+ const requestData = ref<any>(null)
22
+ const copied = ref(false)
23
+
24
+ onMounted(async () => {
25
+ if (!currentUser) {
26
+ const returnTo = typeof window !== "undefined" ? window.location.href : ""
27
+ navigateTo(`${loginUrl}?redirect_to=${encodeURIComponent(returnTo)}`, { external: true })
28
+ return
29
+ }
30
+ if (!requestId) {
31
+ navigateTo(`/${locale.value}/key-campaigns`)
32
+ return
33
+ }
34
+ try {
35
+ const res = await fetchKeyRequestById(requestId)
36
+ requestData.value = res?.data?.data || res?.data || null
37
+ } catch {
38
+ error.value = $i18n.t("keys.campaigns.error_loading")
39
+ } finally {
40
+ loading.value = false
41
+ }
42
+ })
43
+
44
+ async function reveal() {
45
+ revealing.value = true
46
+ error.value = ""
47
+ try {
48
+ const res = await revealKey(requestId)
49
+ const data = res?.data?.data || res?.data || null
50
+ keyCode.value = data?.key || data?.code || data?.value || null
51
+ if (!keyCode.value) {
52
+ error.value = $i18n.t("keys.campaigns.error_reveal")
53
+ }
54
+ } catch (e: any) {
55
+ error.value = e?.response?.data?.message || $i18n.t("keys.campaigns.error_reveal")
56
+ } finally {
57
+ revealing.value = false
58
+ }
59
+ }
60
+
61
+ async function copyCode() {
62
+ if (!keyCode.value) return
63
+ try {
64
+ await navigator.clipboard.writeText(keyCode.value)
65
+ copied.value = true
66
+ setTimeout(() => { copied.value = false }, 2000)
67
+ } catch {
68
+ // fallback: select text
69
+ }
70
+ }
71
+
72
+ function goBack() {
73
+ if (typeof window !== "undefined" && window.history.length > 1) {
74
+ window.history.back()
75
+ } else {
76
+ navigateTo(`/${locale.value}/key-campaigns`)
77
+ }
78
+ }
79
+ </script>
80
+
81
+ <template>
82
+ <div id="shared-redeem-key-approved">
83
+ <div class="container">
84
+ <div class="header">
85
+ <NuxtLink @click.prevent="goBack" class="back">
86
+ <MGIcon size="2x" icon="chevron-left" />
87
+ <span>{{ $t("keys.campaigns.back") }}</span>
88
+ </NuxtLink>
89
+ </div>
90
+
91
+ <div v-if="loading" class="state">
92
+ <div class="skeleton" v-for="i in 2" :key="i" />
93
+ </div>
94
+
95
+ <div v-else-if="error && !keyCode" class="state error">{{ error }}</div>
96
+
97
+ <div v-else class="content">
98
+ <div class="title-bar">
99
+ <MGIcon icon="version" size="2x" class="title-icon" />
100
+ <div>
101
+ <h3>{{ $t("keys.campaigns.status_key.reveal_key") }}</h3>
102
+ <p v-if="requestData?.key?.name" class="campaign-name">{{ requestData.key.name }}</p>
103
+ </div>
104
+ </div>
105
+
106
+ <!-- Key not yet revealed -->
107
+ <div v-if="!keyCode" class="reveal-block">
108
+ <p class="hint">{{ $t("keys.campaigns.reveal_hint") }}</p>
109
+ <button
110
+ class="btn"
111
+ :class="{ disabled: revealing }"
112
+ :disabled="revealing"
113
+ @click="reveal"
114
+ >
115
+ {{ revealing ? $t("keys.campaigns.revealing") : $t("keys.campaigns.status_key.reveal_key") }}
116
+ </button>
117
+ <div v-if="error" class="req-error">{{ error }}</div>
118
+ </div>
119
+
120
+ <!-- Key revealed -->
121
+ <div v-else class="key-block">
122
+ <div class="key-label">{{ $t("keys.campaigns.your_key") }}</div>
123
+ <div class="key-code-row">
124
+ <span class="key-code">{{ keyCode }}</span>
125
+ <button class="copy-btn" @click="copyCode">
126
+ <MGIcon :icon="copied ? 'check' : 'copy'" size="1x" />
127
+ {{ copied ? $t("keys.campaigns.copied") : $t("keys.campaigns.copy") }}
128
+ </button>
129
+ </div>
130
+ <p class="redeem-info">{{ $t("keys.campaigns.redeem_on_platform") }}</p>
131
+ </div>
132
+
133
+ <!-- Request info -->
134
+ <div v-if="requestData" class="info-grid">
135
+ <div class="info-row" v-if="requestData.status_request?.name">
136
+ <span class="info-label">{{ $t("keys.campaigns.status") }}</span>
137
+ <span class="info-val">{{ requestData.status_request.name }}</span>
138
+ </div>
139
+ <div class="info-row" v-if="requestData.key?.name">
140
+ <span class="info-label">{{ $t("keys.campaigns.campaign.title") }}</span>
141
+ <span class="info-val">{{ requestData.key.name }}</span>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </template>
148
+
149
+ <style lang="scss" scoped>
150
+ #shared-redeem-key-approved {
151
+ align-items: center;
152
+ width: 100%;
153
+ justify-content: center;
154
+ overflow: auto;
155
+ height: 100%;
156
+
157
+ .container { max-width: 680px !important; padding: 32px 16px 64px; }
158
+
159
+ .header {
160
+ margin-bottom: 24px;
161
+ .back {
162
+ display: inline-flex;
163
+ align-items: center;
164
+ gap: 8px;
165
+ font-size: 14px;
166
+ color: var(--secondary-info-fg);
167
+ cursor: pointer;
168
+ text-decoration: none;
169
+ &:hover { color: var(--card-article-title); }
170
+ }
171
+ }
172
+
173
+ .state {
174
+ display: flex;
175
+ flex-direction: column;
176
+ align-items: center;
177
+ gap: 12px;
178
+ padding: 64px 0;
179
+ text-align: center;
180
+ color: var(--secondary-info-fg);
181
+ &.error { color: var(--danger, #e53935); }
182
+ }
183
+
184
+ .skeleton {
185
+ width: 100%;
186
+ height: 48px;
187
+ background: var(--bg-app-badge);
188
+ animation: pulse 1.4s ease-in-out infinite;
189
+ & + & { margin-top: 8px; }
190
+ }
191
+
192
+ .content { display: flex; flex-direction: column; gap: 28px; }
193
+
194
+ .title-bar {
195
+ display: flex;
196
+ align-items: flex-start;
197
+ gap: 14px;
198
+ .title-icon { color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); margin-top: 2px; }
199
+ h3 { font-size: 20px; font-weight: 700; color: var(--card-article-title); margin: 0 0 4px; }
200
+ .campaign-name { font-size: 13px; color: var(--secondary-info-fg); margin: 0; }
201
+ }
202
+
203
+ .reveal-block {
204
+ display: flex;
205
+ flex-direction: column;
206
+ gap: 16px;
207
+ padding: 24px;
208
+ background: var(--bg-app-badge);
209
+ border: 1px solid var(--button-secondary-default-bg);
210
+
211
+ .hint { font-size: 14px; color: var(--secondary-info-fg); margin: 0; }
212
+ }
213
+
214
+ .key-block {
215
+ display: flex;
216
+ flex-direction: column;
217
+ gap: 12px;
218
+ padding: 24px;
219
+ background: var(--bg-app-badge);
220
+ border: 1px solid var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
221
+ }
222
+
223
+ .key-label {
224
+ font-size: 12px;
225
+ font-weight: 600;
226
+ text-transform: uppercase;
227
+ letter-spacing: 0.5px;
228
+ color: var(--secondary-info-fg);
229
+ }
230
+
231
+ .key-code-row {
232
+ display: flex;
233
+ align-items: center;
234
+ gap: 12px;
235
+ flex-wrap: wrap;
236
+ }
237
+
238
+ .key-code {
239
+ font-size: 20px;
240
+ font-weight: 700;
241
+ font-family: monospace;
242
+ letter-spacing: 2px;
243
+ color: var(--card-article-title);
244
+ word-break: break-all;
245
+ }
246
+
247
+ .copy-btn {
248
+ display: inline-flex;
249
+ align-items: center;
250
+ gap: 6px;
251
+ padding: 6px 14px;
252
+ font-size: 13px;
253
+ font-weight: 600;
254
+ background: transparent;
255
+ border: 1px solid var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
256
+ color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
257
+ cursor: pointer;
258
+ transition: background 0.15s;
259
+ &:hover { background: var(--key-accent-subtle-bg, rgba(210, 151, 255, 0.1)); }
260
+ }
261
+
262
+ .redeem-info {
263
+ font-size: 12px;
264
+ color: var(--secondary-info-fg);
265
+ margin: 0;
266
+ }
267
+
268
+ .req-error { font-size: 13px; color: var(--danger, #e53935); }
269
+
270
+ .info-grid {
271
+ display: flex;
272
+ flex-direction: column;
273
+ gap: 8px;
274
+ padding-top: 8px;
275
+ border-top: 1px solid var(--button-secondary-default-bg);
276
+ }
277
+
278
+ .info-row {
279
+ display: flex;
280
+ gap: 12px;
281
+ font-size: 13px;
282
+ }
283
+
284
+ .info-label {
285
+ color: var(--secondary-info-fg);
286
+ min-width: 100px;
287
+ }
288
+
289
+ .info-val { color: var(--card-article-title); }
290
+
291
+ .btn {
292
+ align-self: flex-start;
293
+ padding: 0 28px;
294
+ height: 44px;
295
+ font-size: 14px;
296
+ font-weight: 700;
297
+ background: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
298
+ color: #fff;
299
+ border: none;
300
+ cursor: pointer;
301
+ transition: opacity 0.15s;
302
+ &.disabled, &:disabled { opacity: 0.45; cursor: not-allowed; }
303
+ &:not(.disabled):hover { opacity: 0.85; }
304
+ }
305
+ }
306
+
307
+ @keyframes pulse {
308
+ 0%, 100% { opacity: 1; }
309
+ 50% { opacity: 0.4; }
310
+ }
311
+ </style>