import type { VueI18n } from "vue-i18n"; import type { RouteLocation, Router } from "vue-router"; import type { CookieData, GenericResponse } from "~/types"; // Extend the NuxtApp type declare module '#app' { interface NuxtApp { $session: Session; } } declare module 'vue' { interface ComponentCustomProperties { $session: Session; } } export class Session { cookieData = ref({} as CookieData); urlParams = new URLSearchParams() currentLanguageIso = ref("" as string) currentCountryIso = ref("" as string) currentCurrencyIso = ref("" as string) route = {} as RouteLocation router = {} as Router i18n = {} as VueI18n sessionOngoing: boolean = false constructor(i18n: VueI18n, router: Router) { this.route = router.currentRoute.value this.router = router this.i18n = i18n this.setLanguage(this.route.query?.lang_iso ? this.route.query?.lang_iso as string : unref(i18n.locale)) this.setCountry(this.route.query?.country_iso ? this.route.query?.country_iso as string : "") this.setCurrency(this.route.query?.currency_iso ? this.route.query?.currency_iso as string : "") } async loadSession() { if (this.sessionOngoing) return this.sessionOngoing = true this.setQueryParams() const { data } = await useMyFetch>(`/api/public/cookie?${this.urlParams.toString()}`, { headers: { "Content-Type": "application/json", }, onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`); }, }); this.cookieData.value = data; this.currentCountryIso.value = this.cookieData.value.country.iso_code this.currentLanguageIso.value = this.cookieData.value.language.iso_code this.currentCurrencyIso.value = this.cookieData.value.currency.iso_code setTimeout(() => this.sessionOngoing = false, 2000) } setLanguage(iso: string) { this.currentLanguageIso.value = iso } setCurrency(iso: string) { this.currentCurrencyIso.value = iso } setCountry(iso: string) { this.currentCountryIso.value = iso } setQueryParams() { if (this.currentLanguageIso.value.length > 0) { this.urlParams.set("lang_iso", this.currentLanguageIso.value) } else { this.urlParams.delete("lang_iso") } if (this.currentCountryIso.value.length > 0) { this.urlParams.set("country_iso", this.currentCountryIso.value) } else { this.urlParams.delete("country_iso") } if (this.currentCurrencyIso.value.length > 0) { this.urlParams.set("currency_iso", this.currentCurrencyIso.value) } else { this.urlParams.delete("currency_iso") } } } export default defineNuxtPlugin(async (nuxtApp) => { const loaded = [] as Array; const { $i18n: i18n } = nuxtApp as unknown as { $i18n: VueI18n }; const { $router: router } = nuxtApp as unknown as { $router: Router }; i18n.onBeforeLanguageSwitch = async (_, newLocale) => { if (loaded.includes(newLocale)) return; try { loaded.push(newLocale); const { data } = await useMyFetch>( "/api/public/front/translation" ); i18n.setLocaleMessage(newLocale, data); } catch (err) { console.error("❌ Failed to load translation for locale:", newLocale); throw err; } }; const session = new Session(i18n, router) await session.loadSession(); nuxtApp.provide("session", session); });