@mundogamernetwork/shared-ui 1.1.92 → 1.1.94
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/assets/kit/kit-base.css +7 -0
- package/locales/de.json +3 -0
- package/locales/en.json +3 -0
- package/locales/pt-BR.json +3 -0
- package/locales/ro.json +3 -0
- package/package.json +1 -1
- package/pages/key-campaigns/[slug].vue +3 -3
- package/pages/key-campaigns/key-materials.vue +51 -3
- package/pages/key-campaigns/redeem-key-approved.vue +2 -2
- package/pages/key-campaigns/redeem-key.vue +2 -2
- package/pages/presskit/game/[slug].vue +11 -1
package/assets/kit/kit-base.css
CHANGED
|
@@ -756,6 +756,13 @@ body:has(.kit-press) {
|
|
|
756
756
|
scrollbar-width: none;
|
|
757
757
|
}
|
|
758
758
|
.kit-anchornav-inner::-webkit-scrollbar { display: none; }
|
|
759
|
+
/* Trailing spacer so the last item isn't clipped by the overflow container */
|
|
760
|
+
.kit-anchornav-inner::after {
|
|
761
|
+
content: '';
|
|
762
|
+
display: block;
|
|
763
|
+
min-width: 24px;
|
|
764
|
+
flex-shrink: 0;
|
|
765
|
+
}
|
|
759
766
|
.kit-anchornav-item {
|
|
760
767
|
display: inline-block;
|
|
761
768
|
padding: 14px 16px;
|
package/locales/de.json
CHANGED
|
@@ -218,6 +218,9 @@
|
|
|
218
218
|
"type_article": "Article / Review",
|
|
219
219
|
"type_web": "Website / Blog",
|
|
220
220
|
"type_print": "Screenshot / Print",
|
|
221
|
+
"deadline_days_left": "Noch {days} Tage, um dein Material einzureichen",
|
|
222
|
+
"deadline_today": "Letzter Tag, um dein Material einzureichen",
|
|
223
|
+
"deadline_overdue": "Die Einreichungsfrist ist abgelaufen",
|
|
221
224
|
"required_fields": "Fill in all required fields",
|
|
222
225
|
"url_error": "Invalid URL",
|
|
223
226
|
"submit_error": "Error submitting. Try again.",
|
package/locales/en.json
CHANGED
|
@@ -218,6 +218,9 @@
|
|
|
218
218
|
"type_article": "Article / Review",
|
|
219
219
|
"type_web": "Website / Blog",
|
|
220
220
|
"type_print": "Screenshot / Print",
|
|
221
|
+
"deadline_days_left": "{days} days left to submit your material",
|
|
222
|
+
"deadline_today": "Last day to submit your material",
|
|
223
|
+
"deadline_overdue": "The submission deadline has passed",
|
|
221
224
|
"required_fields": "Fill in all required fields",
|
|
222
225
|
"url_error": "Invalid URL",
|
|
223
226
|
"submit_error": "Error submitting. Try again.",
|
package/locales/pt-BR.json
CHANGED
|
@@ -218,6 +218,9 @@
|
|
|
218
218
|
"type_article": "Article / Review",
|
|
219
219
|
"type_web": "Website / Blog",
|
|
220
220
|
"type_print": "Screenshot / Print",
|
|
221
|
+
"deadline_days_left": "Faltam {days} dias para enviar seu material",
|
|
222
|
+
"deadline_today": "Último dia para enviar seu material",
|
|
223
|
+
"deadline_overdue": "O prazo de envio já passou",
|
|
221
224
|
"required_fields": "Fill in all required fields",
|
|
222
225
|
"url_error": "Invalid URL",
|
|
223
226
|
"submit_error": "Error submitting. Try again.",
|
package/locales/ro.json
CHANGED
|
@@ -218,6 +218,9 @@
|
|
|
218
218
|
"type_article": "Article / Review",
|
|
219
219
|
"type_web": "Website / Blog",
|
|
220
220
|
"type_print": "Screenshot / Print",
|
|
221
|
+
"deadline_days_left": "Mai ai {days} zile pentru a trimite materialul",
|
|
222
|
+
"deadline_today": "Ultima zi pentru a trimite materialul",
|
|
223
|
+
"deadline_overdue": "Termenul de trimitere a expirat",
|
|
221
224
|
"required_fields": "Fill in all required fields",
|
|
222
225
|
"url_error": "Invalid URL",
|
|
223
226
|
"submit_error": "Error submitting. Try again.",
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { ref, computed, inject, onMounted } from "vue"
|
|
2
|
+
import { ref, computed, inject, onMounted, unref } from "vue"
|
|
3
3
|
import { useNuxtApp, useRoute, useAsyncData, navigateTo } from "#app"
|
|
4
4
|
import {
|
|
5
5
|
fetchCampaignBySlug,
|
|
@@ -476,7 +476,7 @@ const tierLabel = computed(() => {
|
|
|
476
476
|
// Auth guard for CTA actions
|
|
477
477
|
// ------------------------------------------------------------------
|
|
478
478
|
function requireAuth(targetPath: string) {
|
|
479
|
-
if (currentUser) {
|
|
479
|
+
if (unref(currentUser)) {
|
|
480
480
|
navigateTo(targetPath)
|
|
481
481
|
return
|
|
482
482
|
}
|
|
@@ -497,7 +497,7 @@ const showUsersModal = ref(false)
|
|
|
497
497
|
onMounted(async () => {
|
|
498
498
|
updateCountdown()
|
|
499
499
|
|
|
500
|
-
if (currentUser && campaign.value?.id) {
|
|
500
|
+
if (unref(currentUser) && campaign.value?.id) {
|
|
501
501
|
try {
|
|
502
502
|
const response = await fetchMyRequests({ "filter[key_id]": campaign.value.id })
|
|
503
503
|
const requests = response?.data?.data
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
|
+
<div v-if="deadlineText" class="deadline-banner" :class="{ overdue: daysRemaining !== null && daysRemaining < 0 }">
|
|
19
|
+
<MGIcon size="1x" icon="others" />
|
|
20
|
+
<span>{{ deadlineText }}</span>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
18
23
|
<div class="boxes">
|
|
19
24
|
<!-- Submission form -->
|
|
20
25
|
<div class="box-container">
|
|
@@ -187,10 +192,10 @@
|
|
|
187
192
|
</template>
|
|
188
193
|
|
|
189
194
|
<script setup lang="ts">
|
|
190
|
-
import { ref, inject, onMounted } from "vue"
|
|
195
|
+
import { ref, computed, inject, onMounted, unref } from "vue"
|
|
191
196
|
import { useRoute, useRouter } from "vue-router"
|
|
192
197
|
import { useI18n } from "#imports"
|
|
193
|
-
import { submitMaterial, fetchMaterialsByRequest } from "../../services/campaignService"
|
|
198
|
+
import { submitMaterial, fetchMaterialsByRequest, fetchKeyRequestById } from "../../services/campaignService"
|
|
194
199
|
|
|
195
200
|
definePageMeta({
|
|
196
201
|
middleware: [
|
|
@@ -241,6 +246,30 @@ const urlError = ref<string | null>(null)
|
|
|
241
246
|
const formError = ref<string | null>(null)
|
|
242
247
|
const showSuccessModal = ref(false)
|
|
243
248
|
|
|
249
|
+
// Submission deadline — counts down from the request's approval date, using
|
|
250
|
+
// the campaign's configured window (defaults to 30 days server-side).
|
|
251
|
+
const daysRemaining = ref<number | null>(null)
|
|
252
|
+
const deadlineText = computed(() => {
|
|
253
|
+
if (daysRemaining.value === null) return ""
|
|
254
|
+
if (daysRemaining.value < 0) return t("keys.materials.deadline_overdue")
|
|
255
|
+
if (daysRemaining.value === 0) return t("keys.materials.deadline_today")
|
|
256
|
+
return t("keys.materials.deadline_days_left", { days: daysRemaining.value })
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
async function loadDeadline() {
|
|
260
|
+
try {
|
|
261
|
+
const res = await fetchKeyRequestById(requestId.value)
|
|
262
|
+
const data = res?.data?.data ?? res?.data
|
|
263
|
+
const approvedAt = data?.approved_at
|
|
264
|
+
const deadlineDays = Number(data?.material_deadline_days ?? 30)
|
|
265
|
+
if (!approvedAt) return
|
|
266
|
+
const deadline = new Date(approvedAt)
|
|
267
|
+
deadline.setDate(deadline.getDate() + deadlineDays)
|
|
268
|
+
const diffMs = deadline.getTime() - Date.now()
|
|
269
|
+
daysRemaining.value = Math.ceil(diffMs / (1000 * 60 * 60 * 24))
|
|
270
|
+
} catch { /* deadline is informational only, ignore failures */ }
|
|
271
|
+
}
|
|
272
|
+
|
|
244
273
|
function toggleType(formIndex: number, type: ContentType) {
|
|
245
274
|
const currentTypes = forms.value[formIndex].content_types
|
|
246
275
|
const idx = currentTypes.indexOf(type)
|
|
@@ -312,7 +341,7 @@ const submitForm = async () => {
|
|
|
312
341
|
for (const form of forms.value) {
|
|
313
342
|
await submitMaterial({
|
|
314
343
|
key_request_id: requestId.value,
|
|
315
|
-
user_id: currentUserId,
|
|
344
|
+
user_id: unref(currentUserId),
|
|
316
345
|
content_types: form.content_types.map((type) => contentTypesMap[type]),
|
|
317
346
|
material_url: form.material_url,
|
|
318
347
|
description: form.description,
|
|
@@ -343,6 +372,7 @@ onMounted(async () => {
|
|
|
343
372
|
const res = await fetchMaterialsByRequest(requestId.value)
|
|
344
373
|
submittedMaterials.value = res?.data?.data ?? []
|
|
345
374
|
} catch { /* silent */ }
|
|
375
|
+
loadDeadline()
|
|
346
376
|
}
|
|
347
377
|
})
|
|
348
378
|
</script>
|
|
@@ -434,6 +464,24 @@ onMounted(async () => {
|
|
|
434
464
|
}
|
|
435
465
|
}
|
|
436
466
|
|
|
467
|
+
.deadline-banner {
|
|
468
|
+
display: flex;
|
|
469
|
+
align-items: center;
|
|
470
|
+
gap: 8px;
|
|
471
|
+
padding: 10px 16px;
|
|
472
|
+
background: rgba(210, 151, 255, 0.1);
|
|
473
|
+
border-left: 2px solid #d297ff;
|
|
474
|
+
color: var(--card-cover-title);
|
|
475
|
+
font-size: 13px;
|
|
476
|
+
i { color: #d297ff; }
|
|
477
|
+
|
|
478
|
+
&.overdue {
|
|
479
|
+
background: rgba(248, 60, 60, 0.1);
|
|
480
|
+
border-left-color: rgb(248, 60, 60);
|
|
481
|
+
i { color: rgb(248, 60, 60); }
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
437
485
|
.disabled {
|
|
438
486
|
cursor: not-allowed;
|
|
439
487
|
pointer-events: none;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { ref, inject, onMounted } from "vue"
|
|
2
|
+
import { ref, inject, onMounted, unref } from "vue"
|
|
3
3
|
import { useRoute, navigateTo } from "#app"
|
|
4
4
|
import { useNuxtApp } from "#app"
|
|
5
5
|
import { revealKey, fetchKeyRequestById } from "../../services/campaignService"
|
|
@@ -47,7 +47,7 @@ const redeemUrl = computed(() => {
|
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
onMounted(async () => {
|
|
50
|
-
if (!currentUser) {
|
|
50
|
+
if (!unref(currentUser)) {
|
|
51
51
|
const returnTo = typeof window !== "undefined" ? window.location.href : ""
|
|
52
52
|
navigateTo(`${loginUrl}?redirect_to=${encodeURIComponent(returnTo)}`, { external: true })
|
|
53
53
|
return
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { ref, computed, inject, onMounted } from "vue"
|
|
2
|
+
import { ref, computed, inject, onMounted, unref } from "vue"
|
|
3
3
|
import { useRoute, navigateTo } from "#app"
|
|
4
4
|
import { useNuxtApp } from "#app"
|
|
5
5
|
import {
|
|
@@ -46,7 +46,7 @@ function clampQuantity() {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
onMounted(async () => {
|
|
49
|
-
if (!currentUser) {
|
|
49
|
+
if (!unref(currentUser)) {
|
|
50
50
|
const returnTo = typeof window !== "undefined" ? window.location.href : ""
|
|
51
51
|
navigateTo(`${loginUrl}?redirect_to=${encodeURIComponent(returnTo)}`, { external: true })
|
|
52
52
|
return
|
|
@@ -96,6 +96,15 @@ function scrollToTop() {
|
|
|
96
96
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
function scrollToSection(id: string) {
|
|
100
|
+
const el = document.getElementById(id);
|
|
101
|
+
if (!el) return;
|
|
102
|
+
const nav = document.querySelector('.kit-anchornav') as HTMLElement | null;
|
|
103
|
+
const offset = nav ? nav.offsetHeight : 52;
|
|
104
|
+
const top = el.getBoundingClientRect().top + window.scrollY - offset;
|
|
105
|
+
window.scrollTo({ top, behavior: 'smooth' });
|
|
106
|
+
}
|
|
107
|
+
|
|
99
108
|
onMounted(() => {
|
|
100
109
|
const hero = document.querySelector('.kit-cover') as HTMLElement | null;
|
|
101
110
|
heroHeight = hero ? hero.offsetHeight : 300;
|
|
@@ -119,7 +128,7 @@ const navSections = computed(() => {
|
|
|
119
128
|
if (coverage.value.length) s.push({ id: 'creators', label: 'kit.press.coverage' });
|
|
120
129
|
if (awards.value.length) s.push({ id: 'awards', label: 'kit.press.awards' });
|
|
121
130
|
if (team.value.length) s.push({ id: 'team', label: 'kit.press.team' });
|
|
122
|
-
if (
|
|
131
|
+
if (hasEcosystem.value) s.push({ id: 'events', label: 'kit.press.showcases' });
|
|
123
132
|
if (k.press_contact_email) s.push({ id: 'contact', label: 'kit.press.contact' });
|
|
124
133
|
return s;
|
|
125
134
|
});
|
|
@@ -221,6 +230,7 @@ useSeoMeta({
|
|
|
221
230
|
:key="s.id"
|
|
222
231
|
:href="`#${s.id}`"
|
|
223
232
|
class="kit-anchornav-item"
|
|
233
|
+
@click.prevent="scrollToSection(s.id)"
|
|
224
234
|
>{{ $te(s.label) ? $t(s.label) : s.label }}</a>
|
|
225
235
|
</div>
|
|
226
236
|
</nav>
|