@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.
- package/components/keys/KeyBrowser.vue +2 -2
- package/components/keys/KeyCampaignDashboardCard.vue +7 -7
- package/components/keys/KeyCampaignsCarousel.vue +190 -0
- package/locales/de.json +22 -2
- package/locales/en.json +22 -2
- package/locales/pt-BR.json +22 -2
- package/locales/ro.json +22 -2
- package/package.json +1 -1
- package/pages/key-campaign/[slug].vue +16 -1
- package/pages/key-campaigns/[slug].vue +44 -38
- package/pages/key-campaigns/index.vue +22 -22
- package/pages/key-campaigns/redeem-key-approved.vue +311 -0
- package/pages/key-campaigns/redeem-key.vue +320 -0
- package/services/campaignService.ts +12 -4
|
@@ -403,7 +403,7 @@ function statusColor(slug: string): string {
|
|
|
403
403
|
&__login-btn {
|
|
404
404
|
padding: 10px 24px;
|
|
405
405
|
background: var(--accent, #00d4ff);
|
|
406
|
-
color: #
|
|
406
|
+
color: var(--key-accent-ink, var(--accent-ink, #13161C));
|
|
407
407
|
border: none;
|
|
408
408
|
font-weight: 600;
|
|
409
409
|
font-size: 0.9rem;
|
|
@@ -528,7 +528,7 @@ function statusColor(slug: string): string {
|
|
|
528
528
|
&__request-btn {
|
|
529
529
|
padding: 8px 16px;
|
|
530
530
|
background: var(--accent, #00d4ff);
|
|
531
|
-
color: #
|
|
531
|
+
color: var(--key-accent-ink, var(--accent-ink, #13161C));
|
|
532
532
|
border: none;
|
|
533
533
|
font-weight: 600;
|
|
534
534
|
font-size: 0.85rem;
|
|
@@ -262,8 +262,8 @@ const detailRoute = computed(() =>
|
|
|
262
262
|
position: absolute;
|
|
263
263
|
bottom: 6px;
|
|
264
264
|
left: 6px;
|
|
265
|
-
background: rgba(0, 0, 0, 0.75);
|
|
266
|
-
color: #D297FF;
|
|
265
|
+
background: var(--overlay-dark-strong, rgba(0, 0, 0, 0.75));
|
|
266
|
+
color: var(--key-accent, var(--primary, #D297FF));
|
|
267
267
|
font-size: 10px;
|
|
268
268
|
font-weight: 700;
|
|
269
269
|
padding: 3px 7px;
|
|
@@ -272,7 +272,7 @@ const detailRoute = computed(() =>
|
|
|
272
272
|
gap: 4px;
|
|
273
273
|
text-transform: uppercase;
|
|
274
274
|
|
|
275
|
-
&.kc-card__exclusive-lock { color: #fff; }
|
|
275
|
+
&.kc-card__exclusive-lock { color: var(--card-article-title, #fff); }
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
&__early-access-badge {
|
|
@@ -300,7 +300,7 @@ const detailRoute = computed(() =>
|
|
|
300
300
|
&__lock-overlay {
|
|
301
301
|
position: absolute;
|
|
302
302
|
inset: 0;
|
|
303
|
-
background: rgba(0, 0, 0, 0.65);
|
|
303
|
+
background: var(--overlay-dark, rgba(0, 0, 0, 0.65));
|
|
304
304
|
display: flex;
|
|
305
305
|
flex-direction: column;
|
|
306
306
|
align-items: center;
|
|
@@ -310,10 +310,10 @@ const detailRoute = computed(() =>
|
|
|
310
310
|
text-align: center;
|
|
311
311
|
|
|
312
312
|
i { font-size: 1.5rem; color: var(--primary); }
|
|
313
|
-
.lock-label { font-size: 11px; font-weight: 700; color: #fff; text-transform: uppercase; }
|
|
314
|
-
.lock-countdown { font-size: 10px; color: rgba(255,255,255,0.7); }
|
|
313
|
+
.lock-label { font-size: 11px; font-weight: 700; color: var(--card-article-title, #fff); text-transform: uppercase; }
|
|
314
|
+
.lock-countdown { font-size: 10px; color: var(--secondary-info-fg, rgba(255,255,255,0.7)); }
|
|
315
315
|
|
|
316
|
-
&--exclusive i { color: #D297FF; }
|
|
316
|
+
&--exclusive i { color: var(--key-accent, var(--primary, #D297FF)); }
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
&__meta-bar {
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref, onMounted, inject } from "vue"
|
|
3
|
+
import { fetchCampaigns } from "../../services/campaignService"
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
excludeId?: number | null
|
|
7
|
+
mgPlatform?: string
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
const mgPlatform = props.mgPlatform || (inject<string>("mgPlatform", "MGTV"))
|
|
11
|
+
|
|
12
|
+
const items = ref<any[]>([])
|
|
13
|
+
const loading = ref(true)
|
|
14
|
+
|
|
15
|
+
onMounted(async () => {
|
|
16
|
+
try {
|
|
17
|
+
const res = await fetchCampaigns(
|
|
18
|
+
{
|
|
19
|
+
filter: { is_open: 1 },
|
|
20
|
+
per_page: 10,
|
|
21
|
+
sort: "id",
|
|
22
|
+
order: "desc",
|
|
23
|
+
},
|
|
24
|
+
mgPlatform,
|
|
25
|
+
)
|
|
26
|
+
const data: any[] = res?.data?.data || res?.data || []
|
|
27
|
+
items.value = props.excludeId
|
|
28
|
+
? data.filter((c: any) => c.id !== props.excludeId)
|
|
29
|
+
: data
|
|
30
|
+
} catch {
|
|
31
|
+
// silently ignore — carousel is non-critical
|
|
32
|
+
} finally {
|
|
33
|
+
loading.value = false
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div v-if="loading || items.length > 0" class="kc-carousel">
|
|
40
|
+
<div class="kc-carousel__header">
|
|
41
|
+
<span class="kc-carousel__title">{{ $t("keys.campaigns.other_campaigns") }}</span>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div v-if="loading" class="kc-carousel__track">
|
|
45
|
+
<div v-for="i in 4" :key="i" class="kc-carousel__skeleton" />
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div v-else class="kc-carousel__track">
|
|
49
|
+
<NuxtLink
|
|
50
|
+
v-for="item in items"
|
|
51
|
+
:key="item.id"
|
|
52
|
+
:to="`/key-campaigns/${item.slug}`"
|
|
53
|
+
class="kc-carousel__card"
|
|
54
|
+
>
|
|
55
|
+
<div class="kc-carousel__thumb">
|
|
56
|
+
<img
|
|
57
|
+
v-if="item.cover_src || item.cover"
|
|
58
|
+
:src="item.cover_src || item.cover"
|
|
59
|
+
:alt="item.name"
|
|
60
|
+
/>
|
|
61
|
+
<div v-else class="kc-carousel__thumb-placeholder">
|
|
62
|
+
<i class="mg-icon mg-icon-game-key" />
|
|
63
|
+
</div>
|
|
64
|
+
<span v-if="!item.is_open" class="kc-carousel__closed">{{ $t("keys.campaigns.closed") }}</span>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="kc-carousel__info">
|
|
67
|
+
<div class="kc-carousel__name">{{ item.name }}</div>
|
|
68
|
+
<div class="kc-carousel__avail">
|
|
69
|
+
{{ item.available_count ?? 0 }}/{{ item.total_count ?? item.quantity ?? "?" }}
|
|
70
|
+
{{ $t("keys.campaigns.available") }}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</NuxtLink>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<style scoped lang="scss">
|
|
79
|
+
.kc-carousel {
|
|
80
|
+
margin-top: 40px;
|
|
81
|
+
padding-top: 24px;
|
|
82
|
+
border-top: 1px solid var(--button-secondary-default-bg);
|
|
83
|
+
|
|
84
|
+
&__header {
|
|
85
|
+
margin-bottom: 16px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&__title {
|
|
89
|
+
font-size: 16px;
|
|
90
|
+
font-weight: 700;
|
|
91
|
+
color: var(--card-article-title);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&__track {
|
|
95
|
+
display: flex;
|
|
96
|
+
gap: 12px;
|
|
97
|
+
overflow-x: auto;
|
|
98
|
+
padding-bottom: 8px;
|
|
99
|
+
scrollbar-width: thin;
|
|
100
|
+
scrollbar-color: var(--button-secondary-default-bg) transparent;
|
|
101
|
+
|
|
102
|
+
&::-webkit-scrollbar { height: 4px; }
|
|
103
|
+
&::-webkit-scrollbar-track { background: transparent; }
|
|
104
|
+
&::-webkit-scrollbar-thumb { background: var(--button-secondary-default-bg); }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
&__skeleton {
|
|
108
|
+
flex: 0 0 180px;
|
|
109
|
+
height: 140px;
|
|
110
|
+
background: var(--bg-app-badge);
|
|
111
|
+
animation: pulse 1.4s ease-in-out infinite;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&__card {
|
|
115
|
+
flex: 0 0 180px;
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-direction: column;
|
|
118
|
+
text-decoration: none;
|
|
119
|
+
color: inherit;
|
|
120
|
+
border: 1px solid var(--button-secondary-default-bg);
|
|
121
|
+
transition: border-color 0.15s;
|
|
122
|
+
|
|
123
|
+
&:hover { border-color: var(--key-accent, var(--primary, #D297FF)); }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
&__thumb {
|
|
127
|
+
position: relative;
|
|
128
|
+
width: 100%;
|
|
129
|
+
height: 101px;
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
background: var(--bg-app-badge);
|
|
132
|
+
|
|
133
|
+
img {
|
|
134
|
+
width: 100%;
|
|
135
|
+
height: 100%;
|
|
136
|
+
object-fit: cover;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
&__thumb-placeholder {
|
|
141
|
+
width: 100%;
|
|
142
|
+
height: 100%;
|
|
143
|
+
display: flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
justify-content: center;
|
|
146
|
+
color: var(--secondary-info-fg);
|
|
147
|
+
font-size: 24px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
&__closed {
|
|
151
|
+
position: absolute;
|
|
152
|
+
inset: 0;
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
justify-content: center;
|
|
156
|
+
background: var(--overlay-dark, rgba(0, 0, 0, 0.55));
|
|
157
|
+
font-size: 11px;
|
|
158
|
+
font-weight: 700;
|
|
159
|
+
color: var(--card-article-title, #fff);
|
|
160
|
+
letter-spacing: 0.5px;
|
|
161
|
+
text-transform: uppercase;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&__info {
|
|
165
|
+
padding: 8px 10px;
|
|
166
|
+
display: flex;
|
|
167
|
+
flex-direction: column;
|
|
168
|
+
gap: 4px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
&__name {
|
|
172
|
+
font-size: 12px;
|
|
173
|
+
font-weight: 600;
|
|
174
|
+
color: var(--card-article-title);
|
|
175
|
+
overflow: hidden;
|
|
176
|
+
text-overflow: ellipsis;
|
|
177
|
+
white-space: nowrap;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
&__avail {
|
|
181
|
+
font-size: 11px;
|
|
182
|
+
color: var(--secondary-info-fg);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@keyframes pulse {
|
|
187
|
+
0%, 100% { opacity: 1; }
|
|
188
|
+
50% { opacity: 0.4; }
|
|
189
|
+
}
|
|
190
|
+
</style>
|
package/locales/de.json
CHANGED
|
@@ -133,7 +133,27 @@
|
|
|
133
133
|
"who_redeem": "Who redeemed",
|
|
134
134
|
"created_by": "Published by",
|
|
135
135
|
"no_data": "Campaign not found"
|
|
136
|
-
}
|
|
136
|
+
},
|
|
137
|
+
"other_campaigns": "Andere Kampagnen",
|
|
138
|
+
"available": "verfügbar",
|
|
139
|
+
"closed": "Beendet",
|
|
140
|
+
"platform": "Plattform",
|
|
141
|
+
"region": "Region",
|
|
142
|
+
"description_optional": "Beschreibung (optional)",
|
|
143
|
+
"description_placeholder": "Erzähl uns etwas über deinen Kanal...",
|
|
144
|
+
"sending": "Wird gesendet...",
|
|
145
|
+
"request_sent": "Anfrage gesendet! Weiterleitung...",
|
|
146
|
+
"error_loading": "Kampagnendaten konnten nicht geladen werden.",
|
|
147
|
+
"error_request": "Anfrage konnte nicht gesendet werden. Bitte erneut versuchen.",
|
|
148
|
+
"error_reveal": "Schlüssel konnte nicht enthüllt werden.",
|
|
149
|
+
"redeem_title": "Schlüssel anfordern",
|
|
150
|
+
"reveal_hint": "Klicke unten, um deinen Schlüsselcode zu enthüllen.",
|
|
151
|
+
"your_key": "Dein Schlüssel",
|
|
152
|
+
"copy": "Kopieren",
|
|
153
|
+
"copied": "Kopiert!",
|
|
154
|
+
"redeem_on_platform": "Löse diesen Schlüssel auf der entsprechenden Plattform ein.",
|
|
155
|
+
"revealing": "Enthülle...",
|
|
156
|
+
"status": "Status"
|
|
137
157
|
},
|
|
138
158
|
"materials": {
|
|
139
159
|
"title": "Submit material",
|
|
@@ -158,4 +178,4 @@
|
|
|
158
178
|
"success_close": "Close"
|
|
159
179
|
}
|
|
160
180
|
}
|
|
161
|
-
}
|
|
181
|
+
}
|
package/locales/en.json
CHANGED
|
@@ -133,7 +133,27 @@
|
|
|
133
133
|
"who_redeem": "Who redeemed",
|
|
134
134
|
"created_by": "Published by",
|
|
135
135
|
"no_data": "Campaign not found"
|
|
136
|
-
}
|
|
136
|
+
},
|
|
137
|
+
"other_campaigns": "Other campaigns",
|
|
138
|
+
"available": "available",
|
|
139
|
+
"closed": "Closed",
|
|
140
|
+
"platform": "Platform",
|
|
141
|
+
"region": "Region",
|
|
142
|
+
"description_optional": "Description (optional)",
|
|
143
|
+
"description_placeholder": "Tell us a bit about your channel or content plans...",
|
|
144
|
+
"sending": "Sending...",
|
|
145
|
+
"request_sent": "Request sent! Redirecting...",
|
|
146
|
+
"error_loading": "Failed to load campaign data.",
|
|
147
|
+
"error_request": "Could not submit request. Please try again.",
|
|
148
|
+
"error_reveal": "Could not reveal key. Please try again.",
|
|
149
|
+
"redeem_title": "Request a Key",
|
|
150
|
+
"reveal_hint": "Click the button below to reveal your key code.",
|
|
151
|
+
"your_key": "Your Key",
|
|
152
|
+
"copy": "Copy",
|
|
153
|
+
"copied": "Copied!",
|
|
154
|
+
"redeem_on_platform": "Redeem this key on the platform where you received it.",
|
|
155
|
+
"revealing": "Revealing...",
|
|
156
|
+
"status": "Status"
|
|
137
157
|
},
|
|
138
158
|
"materials": {
|
|
139
159
|
"title": "Submit material",
|
|
@@ -158,4 +178,4 @@
|
|
|
158
178
|
"success_close": "Close"
|
|
159
179
|
}
|
|
160
180
|
}
|
|
161
|
-
}
|
|
181
|
+
}
|
package/locales/pt-BR.json
CHANGED
|
@@ -133,7 +133,27 @@
|
|
|
133
133
|
"who_redeem": "Who redeemed",
|
|
134
134
|
"created_by": "Published by",
|
|
135
135
|
"no_data": "Campaign not found"
|
|
136
|
-
}
|
|
136
|
+
},
|
|
137
|
+
"other_campaigns": "Outras campanhas",
|
|
138
|
+
"available": "disponível",
|
|
139
|
+
"closed": "Encerrada",
|
|
140
|
+
"platform": "Plataforma",
|
|
141
|
+
"region": "Região",
|
|
142
|
+
"description_optional": "Descrição (opcional)",
|
|
143
|
+
"description_placeholder": "Conte um pouco sobre seu canal ou planos de conteúdo...",
|
|
144
|
+
"sending": "Enviando...",
|
|
145
|
+
"request_sent": "Solicitação enviada! Redirecionando...",
|
|
146
|
+
"error_loading": "Falha ao carregar dados da campanha.",
|
|
147
|
+
"error_request": "Não foi possível enviar a solicitação. Tente novamente.",
|
|
148
|
+
"error_reveal": "Não foi possível revelar a chave. Tente novamente.",
|
|
149
|
+
"redeem_title": "Solicitar uma Chave",
|
|
150
|
+
"reveal_hint": "Clique no botão abaixo para revelar o código da sua chave.",
|
|
151
|
+
"your_key": "Sua Chave",
|
|
152
|
+
"copy": "Copiar",
|
|
153
|
+
"copied": "Copiado!",
|
|
154
|
+
"redeem_on_platform": "Resgate esta chave na plataforma correspondente.",
|
|
155
|
+
"revealing": "Revelando...",
|
|
156
|
+
"status": "Status"
|
|
137
157
|
},
|
|
138
158
|
"materials": {
|
|
139
159
|
"title": "Submit material",
|
|
@@ -158,4 +178,4 @@
|
|
|
158
178
|
"success_close": "Close"
|
|
159
179
|
}
|
|
160
180
|
}
|
|
161
|
-
}
|
|
181
|
+
}
|
package/locales/ro.json
CHANGED
|
@@ -133,7 +133,27 @@
|
|
|
133
133
|
"who_redeem": "Who redeemed",
|
|
134
134
|
"created_by": "Published by",
|
|
135
135
|
"no_data": "Campaign not found"
|
|
136
|
-
}
|
|
136
|
+
},
|
|
137
|
+
"other_campaigns": "Alte campanii",
|
|
138
|
+
"available": "disponibil",
|
|
139
|
+
"closed": "Închis",
|
|
140
|
+
"platform": "Platformă",
|
|
141
|
+
"region": "Regiune",
|
|
142
|
+
"description_optional": "Descriere (opțional)",
|
|
143
|
+
"description_placeholder": "Spune-ne puțin despre canalul tău...",
|
|
144
|
+
"sending": "Se trimite...",
|
|
145
|
+
"request_sent": "Cerere trimisă! Redirecționare...",
|
|
146
|
+
"error_loading": "Eroare la încărcarea datelor campaniei.",
|
|
147
|
+
"error_request": "Nu s-a putut trimite cererea. Încearcă din nou.",
|
|
148
|
+
"error_reveal": "Nu s-a putut dezvălui cheia.",
|
|
149
|
+
"redeem_title": "Solicită o Cheie",
|
|
150
|
+
"reveal_hint": "Apasă butonul de mai jos pentru a dezvălui codul cheii.",
|
|
151
|
+
"your_key": "Cheia Ta",
|
|
152
|
+
"copy": "Copiază",
|
|
153
|
+
"copied": "Copiat!",
|
|
154
|
+
"redeem_on_platform": "Activează această cheie pe platforma corespunzătoare.",
|
|
155
|
+
"revealing": "Se dezvăluie...",
|
|
156
|
+
"status": "Status"
|
|
137
157
|
},
|
|
138
158
|
"materials": {
|
|
139
159
|
"title": "Submit material",
|
|
@@ -158,4 +178,4 @@
|
|
|
158
178
|
"success_close": "Close"
|
|
159
179
|
}
|
|
160
180
|
}
|
|
161
|
-
}
|
|
181
|
+
}
|
package/package.json
CHANGED
|
@@ -41,6 +41,19 @@ const key = computed(() => keyData.value?.data || null);
|
|
|
41
41
|
const loading = pending;
|
|
42
42
|
const error = computed(() => !!fetchError.value || (!pending.value && !key.value));
|
|
43
43
|
|
|
44
|
+
const { $i18n } = useNuxtApp()
|
|
45
|
+
const t = $i18n.t.bind($i18n)
|
|
46
|
+
|
|
47
|
+
useSeoMeta({
|
|
48
|
+
title: () => key.value?.name ? t('keys.campaigns.seo.title', { game: key.value.name }) : t('keys.campaigns.seo.title_generic'),
|
|
49
|
+
description: () => key.value?.name ? t('keys.campaigns.seo.description', { game: key.value.name }) : t('keys.campaigns.seo.title_generic'),
|
|
50
|
+
ogTitle: () => key.value?.name ? t('keys.campaigns.seo.title', { game: key.value.name }) : t('keys.campaigns.seo.title_generic'),
|
|
51
|
+
ogDescription: () => key.value?.name ? t('keys.campaigns.seo.description', { game: key.value.name }) : t('keys.campaigns.seo.title_generic'),
|
|
52
|
+
ogImage: () => key.value?.cover_src || key.value?.cover || undefined,
|
|
53
|
+
ogType: 'website',
|
|
54
|
+
twitterCard: 'summary_large_image',
|
|
55
|
+
})
|
|
56
|
+
|
|
44
57
|
const restriction = computed(() => {
|
|
45
58
|
const k = key.value;
|
|
46
59
|
if (!k) return '';
|
|
@@ -76,6 +89,8 @@ const restriction = computed(() => {
|
|
|
76
89
|
:game-id="key.game?.id || key.game_id"
|
|
77
90
|
/>
|
|
78
91
|
</div>
|
|
92
|
+
|
|
93
|
+
<KeyCampaignsCarousel :exclude-id="key.id ?? null" />
|
|
79
94
|
</template>
|
|
80
95
|
</div>
|
|
81
96
|
</template>
|
|
@@ -125,7 +140,7 @@ const restriction = computed(() => {
|
|
|
125
140
|
padding: 4px 10px;
|
|
126
141
|
font-size: 0.8rem;
|
|
127
142
|
font-weight: 600;
|
|
128
|
-
color: #
|
|
143
|
+
color: var(--key-accent, var(--primary, #D297FF));
|
|
129
144
|
border: 1px solid rgba(210, 151, 255, 0.35);
|
|
130
145
|
background: rgba(210, 151, 255, 0.12);
|
|
131
146
|
}
|
|
@@ -224,9 +224,9 @@ const restrictionBadges = computed(() => {
|
|
|
224
224
|
// UserRequestsValidation inline state (ported from TV component)
|
|
225
225
|
// ------------------------------------------------------------------
|
|
226
226
|
type StatusConfig = {
|
|
227
|
-
titleParts: { text: string; color?: "default" | "yellow" | "
|
|
227
|
+
titleParts: { text: string; color?: "default" | "yellow" | "var(--danger, #e53935)" }[]
|
|
228
228
|
obs: string
|
|
229
|
-
obsColor?: "default" | "yellow" | "
|
|
229
|
+
obsColor?: "default" | "yellow" | "var(--danger, #e53935)"
|
|
230
230
|
progress?: { percent: number; step: number; total: number; color?: "default" | "yellow" | "complete" }
|
|
231
231
|
actions?: Array<{ type: string; disabled?: boolean }>
|
|
232
232
|
canViewCode?: boolean
|
|
@@ -236,18 +236,18 @@ const statusConfigs: Record<string, StatusConfig> = {
|
|
|
236
236
|
expired: {
|
|
237
237
|
titleParts: [
|
|
238
238
|
{ text: "keys.campaigns.status_key.title_0" },
|
|
239
|
-
{ text: "keys.campaigns.status_key.title_span_0", color: "
|
|
239
|
+
{ text: "keys.campaigns.status_key.title_span_0", color: "var(--danger, #e53935)" },
|
|
240
240
|
],
|
|
241
241
|
obs: "keys.campaigns.status_key.obs_0",
|
|
242
|
-
obsColor: "
|
|
242
|
+
obsColor: "var(--danger, #e53935)",
|
|
243
243
|
},
|
|
244
244
|
exhausted: {
|
|
245
245
|
titleParts: [
|
|
246
246
|
{ text: "keys.campaigns.status_key.title_exhausted" },
|
|
247
|
-
{ text: "keys.campaigns.status_key.title_span_exhausted", color: "
|
|
247
|
+
{ text: "keys.campaigns.status_key.title_span_exhausted", color: "var(--danger, #e53935)" },
|
|
248
248
|
],
|
|
249
249
|
obs: "keys.campaigns.status_key.obs_exhausted",
|
|
250
|
-
obsColor: "
|
|
250
|
+
obsColor: "var(--danger, #e53935)",
|
|
251
251
|
},
|
|
252
252
|
locked_exclusive: {
|
|
253
253
|
titleParts: [
|
|
@@ -343,34 +343,34 @@ const statusConfigs: Record<string, StatusConfig> = {
|
|
|
343
343
|
"6": {
|
|
344
344
|
titleParts: [
|
|
345
345
|
{ text: "keys.campaigns.status_key.title_5" },
|
|
346
|
-
{ text: "keys.campaigns.status_key.title_span_5", color: "
|
|
346
|
+
{ text: "keys.campaigns.status_key.title_span_5", color: "var(--danger, #e53935)" },
|
|
347
347
|
],
|
|
348
348
|
obs: "keys.campaigns.status_key.obs_5",
|
|
349
|
-
obsColor: "
|
|
349
|
+
obsColor: "var(--danger, #e53935)",
|
|
350
350
|
},
|
|
351
351
|
"7": {
|
|
352
352
|
titleParts: [
|
|
353
353
|
{ text: "keys.campaigns.status_key.title_6" },
|
|
354
|
-
{ text: "keys.campaigns.status_key.title_span_6", color: "
|
|
354
|
+
{ text: "keys.campaigns.status_key.title_span_6", color: "var(--danger, #e53935)" },
|
|
355
355
|
],
|
|
356
356
|
obs: "keys.campaigns.status_key.obs_6",
|
|
357
|
-
obsColor: "
|
|
357
|
+
obsColor: "var(--danger, #e53935)",
|
|
358
358
|
},
|
|
359
359
|
"8": {
|
|
360
360
|
titleParts: [
|
|
361
361
|
{ text: "keys.campaigns.status_key.title_7" },
|
|
362
|
-
{ text: "keys.campaigns.status_key.title_span_7", color: "
|
|
362
|
+
{ text: "keys.campaigns.status_key.title_span_7", color: "var(--danger, #e53935)" },
|
|
363
363
|
],
|
|
364
364
|
obs: "keys.campaigns.status_key.obs_7",
|
|
365
|
-
obsColor: "
|
|
365
|
+
obsColor: "var(--danger, #e53935)",
|
|
366
366
|
},
|
|
367
367
|
"9": {
|
|
368
368
|
titleParts: [
|
|
369
369
|
{ text: "keys.campaigns.status_key.title_8" },
|
|
370
|
-
{ text: "keys.campaigns.status_key.title_span_8", color: "
|
|
370
|
+
{ text: "keys.campaigns.status_key.title_span_8", color: "var(--danger, #e53935)" },
|
|
371
371
|
],
|
|
372
372
|
obs: "keys.campaigns.status_key.obs_8",
|
|
373
|
-
obsColor: "
|
|
373
|
+
obsColor: "var(--danger, #e53935)",
|
|
374
374
|
},
|
|
375
375
|
}
|
|
376
376
|
|
|
@@ -681,8 +681,9 @@ onMounted(async () => {
|
|
|
681
681
|
<img
|
|
682
682
|
v-for="(u, index) in redeemedUsers?.users?.slice(0, 4)"
|
|
683
683
|
:key="index"
|
|
684
|
-
:src="u.avatar_url"
|
|
684
|
+
:src="u.avatar_url || '/imgs/avatar-default.jpg'"
|
|
685
685
|
:alt="u.nickname"
|
|
686
|
+
@error="(e: Event) => { const t = e.target as HTMLImageElement; if (t && t.src !== '/imgs/avatar-default.jpg') t.src = '/imgs/avatar-default.jpg' }"
|
|
686
687
|
/>
|
|
687
688
|
</div>
|
|
688
689
|
<div class="text">
|
|
@@ -719,6 +720,11 @@ onMounted(async () => {
|
|
|
719
720
|
</div>
|
|
720
721
|
</div>
|
|
721
722
|
</div>
|
|
723
|
+
<KeyCampaignsCarousel
|
|
724
|
+
:exclude-id="campaign?.id ?? null"
|
|
725
|
+
:mg-platform="mgPlatform"
|
|
726
|
+
class="container"
|
|
727
|
+
/>
|
|
722
728
|
</div>
|
|
723
729
|
</template>
|
|
724
730
|
|
|
@@ -761,7 +767,7 @@ onMounted(async () => {
|
|
|
761
767
|
justify-content: space-between;
|
|
762
768
|
|
|
763
769
|
.btn {
|
|
764
|
-
background: var(--key-accent, #D297FF);
|
|
770
|
+
background: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
765
771
|
display: flex;
|
|
766
772
|
height: 44px;
|
|
767
773
|
padding: 0 14px;
|
|
@@ -787,7 +793,7 @@ onMounted(async () => {
|
|
|
787
793
|
align-items: center;
|
|
788
794
|
gap: 6px;
|
|
789
795
|
font-size: 13px;
|
|
790
|
-
color: var(--key-accent, #D297FF);
|
|
796
|
+
color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
791
797
|
cursor: pointer;
|
|
792
798
|
text-decoration: none;
|
|
793
799
|
white-space: nowrap;
|
|
@@ -806,9 +812,9 @@ onMounted(async () => {
|
|
|
806
812
|
font-size: 14px;
|
|
807
813
|
font-weight: 600;
|
|
808
814
|
color: var(--card-article-title);
|
|
809
|
-
span { color: var(--key-accent, #
|
|
810
|
-
.yellow { color: #FFD600; }
|
|
811
|
-
.
|
|
815
|
+
span { color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); }
|
|
816
|
+
.yellow { color: var(--status-pending, #FFD600); }
|
|
817
|
+
.var(--danger, #e53935) { color: var(--danger, #e53935); }
|
|
812
818
|
}
|
|
813
819
|
|
|
814
820
|
.bar {
|
|
@@ -819,7 +825,7 @@ onMounted(async () => {
|
|
|
819
825
|
|
|
820
826
|
.progress {
|
|
821
827
|
height: 24px;
|
|
822
|
-
background-color: var(--key-accent, #
|
|
828
|
+
background-color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
823
829
|
span {
|
|
824
830
|
position: absolute;
|
|
825
831
|
right: 5px;
|
|
@@ -829,15 +835,15 @@ onMounted(async () => {
|
|
|
829
835
|
}
|
|
830
836
|
}
|
|
831
837
|
.complete span { color: #272930; }
|
|
832
|
-
.yellow { background-color: #FFD600; }
|
|
838
|
+
.yellow { background-color: var(--status-pending, #FFD600); }
|
|
833
839
|
}
|
|
834
840
|
|
|
835
841
|
.info {
|
|
836
842
|
font-size: 12px;
|
|
837
843
|
color: var(--secondary-info-fg);
|
|
838
|
-
i { color: var(--key-accent, #
|
|
839
|
-
.yellow { color: #FFD600; }
|
|
840
|
-
.
|
|
844
|
+
i { color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); }
|
|
845
|
+
.yellow { color: var(--status-pending, #FFD600); }
|
|
846
|
+
.var(--danger, #e53935) { color: var(--danger, #e53935); }
|
|
841
847
|
}
|
|
842
848
|
}
|
|
843
849
|
|
|
@@ -882,9 +888,9 @@ onMounted(async () => {
|
|
|
882
888
|
padding: 4px 10px;
|
|
883
889
|
font-size: 12px;
|
|
884
890
|
font-weight: 600;
|
|
885
|
-
color: var(--key-accent, #D297FF);
|
|
886
|
-
background: rgba(210, 151, 255, 0.12);
|
|
887
|
-
border: 1px solid rgba(210, 151, 255, 0.35);
|
|
891
|
+
color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
892
|
+
background: var(--key-accent-subtle-bg, rgba(210, 151, 255, 0.12));
|
|
893
|
+
border: 1px solid var(--key-accent-subtle-border, rgba(210, 151, 255, 0.35));
|
|
888
894
|
i { font-size: 13px; }
|
|
889
895
|
}
|
|
890
896
|
}
|
|
@@ -960,9 +966,9 @@ onMounted(async () => {
|
|
|
960
966
|
height: 32px;
|
|
961
967
|
font-size: 12px;
|
|
962
968
|
font-weight: 400;
|
|
963
|
-
span.active { color: #
|
|
964
|
-
span.inactive { color:
|
|
965
|
-
span.ending { color: #ffa600; }
|
|
969
|
+
span.active { color: var(--success, #22c55e); }
|
|
970
|
+
span.inactive { color: var(--danger, #e53935); }
|
|
971
|
+
span.ending { color: var(--status-ending, #ffa600); }
|
|
966
972
|
}
|
|
967
973
|
}
|
|
968
974
|
}
|
|
@@ -981,7 +987,7 @@ onMounted(async () => {
|
|
|
981
987
|
gap: 6px;
|
|
982
988
|
background-color: var(--button-secondary-default-bg);
|
|
983
989
|
font-size: 28px;
|
|
984
|
-
color: var(--key-accent, #D297FF);
|
|
990
|
+
color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
985
991
|
font-weight: 700;
|
|
986
992
|
width: -webkit-fill-available;
|
|
987
993
|
span { font-size: 10px; color: var(--secondary-info-fg); font-weight: 400; }
|
|
@@ -1015,9 +1021,9 @@ onMounted(async () => {
|
|
|
1015
1021
|
width: -webkit-fill-available;
|
|
1016
1022
|
cursor: pointer;
|
|
1017
1023
|
&:hover, &.active {
|
|
1018
|
-
background-color: var(--key-accent, #D297FF);
|
|
1019
|
-
color: #
|
|
1020
|
-
i { color: #
|
|
1024
|
+
background-color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF))));
|
|
1025
|
+
color: var(--key-accent-ink, #13161C);
|
|
1026
|
+
i { color: var(--key-accent-ink, #13161C); }
|
|
1021
1027
|
}
|
|
1022
1028
|
}
|
|
1023
1029
|
.tag-bg {
|
|
@@ -1060,7 +1066,7 @@ onMounted(async () => {
|
|
|
1060
1066
|
flex-shrink: 0;
|
|
1061
1067
|
border-radius: 100%;
|
|
1062
1068
|
text-align-last: center;
|
|
1063
|
-
i { color: var(--key-accent, #D297FF); }
|
|
1069
|
+
i { color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); }
|
|
1064
1070
|
}
|
|
1065
1071
|
.texts {
|
|
1066
1072
|
display: flex;
|
|
@@ -1081,7 +1087,7 @@ onMounted(async () => {
|
|
|
1081
1087
|
width: 100%;
|
|
1082
1088
|
}
|
|
1083
1089
|
|
|
1084
|
-
.reward span { color: var(--key-accent, #D297FF); }
|
|
1090
|
+
.reward span { color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); }
|
|
1085
1091
|
|
|
1086
1092
|
.data {
|
|
1087
1093
|
display: flex;
|
|
@@ -1114,7 +1120,7 @@ onMounted(async () => {
|
|
|
1114
1120
|
font-size: 12px;
|
|
1115
1121
|
color: var(--secondary-info-fg);
|
|
1116
1122
|
width: -webkit-fill-available;
|
|
1117
|
-
span { font-size: 16px; color: var(--key-accent, #D297FF); font-weight: 600; }
|
|
1123
|
+
span { font-size: 16px; color: var(--key-accent, var(--primary, var(--key-accent, var(--primary, #D297FF)))); font-weight: 600; }
|
|
1118
1124
|
}
|
|
1119
1125
|
}
|
|
1120
1126
|
|