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) })