@mundogamernetwork/shared-ui 1.2.1 → 1.2.6
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 +2 -1
- package/locales/en.json +2 -1
- package/locales/pt-BR.json +2 -1
- package/locales/ro.json +2 -1
- package/nuxt.config.ts +74 -23
- package/package.json +1 -1
- package/pages/key-campaigns/index.vue +33 -2
- package/services/campaignService.ts +1 -1
package/locales/de.json
CHANGED
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"restriction": {
|
|
52
52
|
"exclusive_official": "Official streamers only",
|
|
53
53
|
"level_official": "Official",
|
|
54
|
-
"level_affiliate": "Affiliate"
|
|
54
|
+
"level_affiliate": "Affiliate",
|
|
55
|
+
"tier_locked": "Exklusiv für den Plan {tier} oder höher"
|
|
55
56
|
},
|
|
56
57
|
"status_key": {
|
|
57
58
|
"see_key": "View key",
|
package/locales/en.json
CHANGED
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"restriction": {
|
|
52
52
|
"exclusive_official": "Official streamers only",
|
|
53
53
|
"level_official": "Official",
|
|
54
|
-
"level_affiliate": "Affiliate"
|
|
54
|
+
"level_affiliate": "Affiliate",
|
|
55
|
+
"tier_locked": "Exclusive to {tier} plan or higher"
|
|
55
56
|
},
|
|
56
57
|
"status_key": {
|
|
57
58
|
"see_key": "View key",
|
package/locales/pt-BR.json
CHANGED
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"restriction": {
|
|
52
52
|
"exclusive_official": "Official streamers only",
|
|
53
53
|
"level_official": "Official",
|
|
54
|
-
"level_affiliate": "Affiliate"
|
|
54
|
+
"level_affiliate": "Affiliate",
|
|
55
|
+
"tier_locked": "Exclusiva para o plano {tier} ou superior"
|
|
55
56
|
},
|
|
56
57
|
"status_key": {
|
|
57
58
|
"see_key": "View key",
|
package/locales/ro.json
CHANGED
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"restriction": {
|
|
52
52
|
"exclusive_official": "Official streamers only",
|
|
53
53
|
"level_official": "Official",
|
|
54
|
-
"level_affiliate": "Affiliate"
|
|
54
|
+
"level_affiliate": "Affiliate",
|
|
55
|
+
"tier_locked": "Exclusiv pentru planul {tier} sau superior"
|
|
55
56
|
},
|
|
56
57
|
"status_key": {
|
|
57
58
|
"see_key": "View key",
|
package/nuxt.config.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { dirname } from "node:path";
|
|
2
3
|
|
|
3
4
|
// Nuxt's built-in `components` module resolves cross-layer name collisions by
|
|
4
5
|
// picking the highest `priority` directory (see `scanComponents` in
|
|
@@ -13,33 +14,83 @@ import { addComponentsDir, createResolver, defineNuxtModule } from "@nuxt/kit";
|
|
|
13
14
|
// (MgBanners, MgLoginModal, MgAppInstallBanner, Playtest components, etc.) to
|
|
14
15
|
// silently fail to resolve.
|
|
15
16
|
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
17
|
+
// A second, separate footgun discovered while fixing this: `~/components`
|
|
18
|
+
// (a bare alias string) in *this* config is NOT resolved relative to
|
|
19
|
+
// shared-ui's own directory when loaded as an extended layer — Nuxt resolves
|
|
20
|
+
// `~` against the *consuming app's* srcDir (aliases are global, not
|
|
21
|
+
// per-layer), so a plain `"~/components"` entry here silently pointed at
|
|
22
|
+
// community-frontend's own `components/` directory and never scanned
|
|
23
|
+
// shared-ui's components at all. An absolute path is required instead.
|
|
24
|
+
//
|
|
25
|
+
// IMPORTANT: do NOT import anything from `@nuxt/kit` (e.g. `createResolver`,
|
|
26
|
+
// `resolveModule`) at the top of this file, and do NOT reference
|
|
27
|
+
// `import.meta` anywhere in it. Older Nuxt/c12 toolchains (e.g. Nuxt 3.13.x,
|
|
28
|
+
// still used by agency-frontend) load layer `nuxt.config.ts` files through an
|
|
29
|
+
// older jiti (1.x) that evaluates them via `vm.Script` in a non-ESM context.
|
|
30
|
+
// Any `import.meta` reference is a hard SyntaxError there ("Cannot use
|
|
31
|
+
// 'import.meta' outside a module") — and critically, importing *anything*
|
|
32
|
+
// from `@nuxt/kit`'s bundle drags jiti into re-transpiling that whole bundle
|
|
33
|
+
// in the same non-ESM vm context too, which itself uses `import.meta.url` /
|
|
34
|
+
// `import.meta.dev` internally and throws the same error, even though none
|
|
35
|
+
// of @nuxt/kit's own `import.meta` usage has anything to do with the specific
|
|
36
|
+
// export being imported. Only Node.js builtins (`node:module`, `node:path`)
|
|
37
|
+
// are safe to import here — jiti 1.x and 2.x both transpile plain builtin
|
|
38
|
+
// imports into `require()` trivially without walking into this trap.
|
|
39
|
+
//
|
|
40
|
+
// Fix: declare shared-ui's own components dir with an absolute path (resolved
|
|
41
|
+
// via `createRequire` + `require.resolve`, no @nuxt/kit, no import.meta) and
|
|
42
|
+
// an explicit `priority` far above anything `layerCount - i` could ever
|
|
43
|
+
// produce (realistic layer counts are single digits), so shared-ui always
|
|
44
|
+
// wins regardless of the consuming app's layer ordering/count.
|
|
45
|
+
//
|
|
46
|
+
// NOTE: do NOT also call `addComponentsDir` for this same path — Nuxt's
|
|
47
|
+
// `scanComponents` dedups purely by `dir.path` via a `scannedPaths` guard, so
|
|
48
|
+
// a *second* dir entry pointing at an already-scanned path is silently
|
|
49
|
+
// skipped (its files never even get globbed), regardless of priority.
|
|
50
|
+
// Declaring the dir once, correctly, is required.
|
|
21
51
|
const SHARED_UI_COMPONENT_PRIORITY = 1000;
|
|
22
52
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// pattern (`createResolver(import.meta.url)`) and keeps registration
|
|
31
|
-
// correct no matter which app extends this layer.
|
|
32
|
-
const resolver = createResolver(import.meta.url);
|
|
33
|
-
addComponentsDir({
|
|
34
|
-
path: resolver.resolve("./components"),
|
|
53
|
+
const require = createRequire(`${process.cwd()}/`);
|
|
54
|
+
const packageRoot = dirname(require.resolve("@mundogamernetwork/shared-ui/package.json"));
|
|
55
|
+
|
|
56
|
+
export default defineNuxtConfig({
|
|
57
|
+
components: [
|
|
58
|
+
{
|
|
59
|
+
path: `${packageRoot}/components`,
|
|
35
60
|
pathPrefix: false,
|
|
36
61
|
priority: SHARED_UI_COMPONENT_PRIORITY,
|
|
37
|
-
}
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
// @pinia/nuxt only auto-scans the top-level app's own storesDirs by
|
|
65
|
+
// default — it does NOT pick up an extended layer's stores/ directory on
|
|
66
|
+
// its own. Every consuming app previously had to hand-list these specific
|
|
67
|
+
// files in its own nuxt.config.ts pinia.storesDirs (see tv-frontend/
|
|
68
|
+
// community-frontend/agency-frontend history) — easy to forget for new
|
|
69
|
+
// apps and a real cause of a production 500 (useAnnouncementStore /
|
|
70
|
+
// useAppInstallBannerStore "is not defined") when tv-frontend's list
|
|
71
|
+
// went stale relative to shared-ui.
|
|
72
|
+
//
|
|
73
|
+
// Nuxt/c12 merges extended-layer config via defu, which concatenates
|
|
74
|
+
// arrays, so declaring these here gets picked up by every consumer
|
|
75
|
+
// automatically without they having to list them — consumers can still
|
|
76
|
+
// add their own storesDirs entries and this list just gets appended.
|
|
77
|
+
//
|
|
78
|
+
// Deliberately an explicit file list, NOT "${packageRoot}/stores/**" —
|
|
79
|
+
// shared-ui also ships auth/chat/contact/institutional/index stores that
|
|
80
|
+
// collide by name with consuming apps' own, more full-featured local
|
|
81
|
+
// versions; a full glob would silently override them.
|
|
82
|
+
//
|
|
83
|
+
// Absolute paths (via packageRoot), same reasoning as the components dir
|
|
84
|
+
// above: a relative path here resolves against the *consuming app's*
|
|
85
|
+
// srcDir when this file is loaded as an extended layer, not shared-ui's
|
|
86
|
+
// own directory.
|
|
87
|
+
pinia: {
|
|
88
|
+
storesDirs: [
|
|
89
|
+
`${packageRoot}/stores/announcement.ts`,
|
|
90
|
+
`${packageRoot}/stores/appInstallBanner.ts`,
|
|
91
|
+
`${packageRoot}/stores/promotion.ts`,
|
|
92
|
+
],
|
|
38
93
|
},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
export default defineNuxtConfig({
|
|
42
|
-
modules: [registerSharedUiComponents],
|
|
43
94
|
css: [
|
|
44
95
|
"@mundogamernetwork/shared-ui/assets/kit/kit-base.css",
|
|
45
96
|
"@mundogamernetwork/shared-ui/assets/kit/kit-theme.css",
|
package/package.json
CHANGED
|
@@ -361,6 +361,10 @@ const campaignsStore = useCampaignsStore()
|
|
|
361
361
|
|
|
362
362
|
const currentStep = ref(1)
|
|
363
363
|
const searchTerm = ref("")
|
|
364
|
+
// Guards against out-of-order responses — e.g. clearing the search box right
|
|
365
|
+
// after typing could let the (slower) filtered response resolve after the
|
|
366
|
+
// (faster) unfiltered one, silently reverting the list to stale results.
|
|
367
|
+
let loadRequestToken = 0
|
|
364
368
|
const currentSlide = ref(0)
|
|
365
369
|
const slider = ref<HTMLElement | null>(null)
|
|
366
370
|
let slideInterval: ReturnType<typeof setInterval> | null = null
|
|
@@ -499,6 +503,8 @@ async function loadFeaturedCampaigns() {
|
|
|
499
503
|
}
|
|
500
504
|
|
|
501
505
|
async function loadCampaigns(page = 1) {
|
|
506
|
+
const requestToken = ++loadRequestToken
|
|
507
|
+
|
|
502
508
|
if (page === 1) {
|
|
503
509
|
loading.value = true
|
|
504
510
|
cards.value = []
|
|
@@ -515,9 +521,18 @@ async function loadCampaigns(page = 1) {
|
|
|
515
521
|
|
|
516
522
|
if (activeFilter.value !== null) params["filter[type_id]"] = activeFilter.value
|
|
517
523
|
if (activePlatformFilter.value !== null) params["filter[platform_id]"] = activePlatformFilter.value
|
|
524
|
+
// Server-side search — the campaign list is paginated by id desc, so a
|
|
525
|
+
// campaign not on the first page(s) would never match a client-side-only
|
|
526
|
+
// filter over whatever happens to already be loaded.
|
|
527
|
+
if (searchTerm.value.trim()) params["filter[name]"] = searchTerm.value.trim()
|
|
518
528
|
|
|
519
529
|
try {
|
|
520
530
|
const response = await campaignsStore.fetchCampaigns(params, mgPlatform)
|
|
531
|
+
|
|
532
|
+
// A newer request already started (e.g. user kept typing/cleared the
|
|
533
|
+
// box) — discard this now-stale response instead of overwriting cards.
|
|
534
|
+
if (requestToken !== loadRequestToken) return
|
|
535
|
+
|
|
521
536
|
const keysData = response.data || []
|
|
522
537
|
const pagination = response.meta?.pagination || {}
|
|
523
538
|
|
|
@@ -564,11 +579,14 @@ async function loadCampaigns(page = 1) {
|
|
|
564
579
|
loadError.value = false
|
|
565
580
|
applyUserRequestStatuses()
|
|
566
581
|
} catch {
|
|
582
|
+
if (requestToken !== loadRequestToken) return
|
|
567
583
|
hasMoreItems.value = false
|
|
568
584
|
if (page === 1) loadError.value = true
|
|
569
585
|
} finally {
|
|
570
|
-
|
|
571
|
-
|
|
586
|
+
if (requestToken === loadRequestToken) {
|
|
587
|
+
loading.value = false
|
|
588
|
+
loadingMore.value = false
|
|
589
|
+
}
|
|
572
590
|
}
|
|
573
591
|
}
|
|
574
592
|
|
|
@@ -704,6 +722,19 @@ const resetAutoplay = () => {
|
|
|
704
722
|
// ------------------------------------------------------------------
|
|
705
723
|
// Step watcher
|
|
706
724
|
// ------------------------------------------------------------------
|
|
725
|
+
// Debounced server-side search — re-queries the backend by name instead of
|
|
726
|
+
// only filtering whatever page(s) happen to already be loaded client-side.
|
|
727
|
+
let searchDebounce: ReturnType<typeof setTimeout> | null = null
|
|
728
|
+
watch(searchTerm, () => {
|
|
729
|
+
if (currentStep.value !== 1) return
|
|
730
|
+
if (searchDebounce) clearTimeout(searchDebounce)
|
|
731
|
+
searchDebounce = setTimeout(() => {
|
|
732
|
+
currentPage.value = 1
|
|
733
|
+
hasMoreItems.value = true
|
|
734
|
+
loadCampaigns(1)
|
|
735
|
+
}, 400)
|
|
736
|
+
})
|
|
737
|
+
|
|
707
738
|
watch(currentStep, (newVal) => {
|
|
708
739
|
activeFilter.value = null
|
|
709
740
|
activePlatformFilter.value = null
|