google-analytics plugin and plugin review

This commit is contained in:
María
2025-08-22 13:02:48 +02:00
parent 500dd1efbe
commit 541e922ff5
7 changed files with 72 additions and 68 deletions

View File

@@ -1,8 +1,7 @@
import { useAuthStore } from '@/stores/auth'
export default defineNuxtRouteMiddleware((to, from) => {
//TODO: remove logs
console.log('🔍 Middleware ejecutado')
console.log('📦 to.meta:', to.meta)
// console.log('🔍 Middleware ejecutado')
// console.log('📦 to.meta:', to.meta)
const AUTH_ROLES = {
ANON: 0,
SHOP_USER: 1,
@@ -11,12 +10,12 @@ export default defineNuxtRouteMiddleware((to, from) => {
}
const authStore = useAuthStore()
const userRole = authStore.role
console.log('👤 Rol actual:', userRole)
//console.log('👤 Rol actual:', userRole)
const authority = to.meta?.auth?.authority as keyof typeof AUTH_ROLES
const requiredLevel = AUTH_ROLES[authority]
//const required = to.meta.auth?.authority
console.log('⚠️ Autoridad requerida:', authority, requiredLevel)
//console.log('⚠️ Autoridad requerida:', authority, requiredLevel)
// Check if user is connected first
@@ -25,18 +24,18 @@ export default defineNuxtRouteMiddleware((to, from) => {
// Get authorizations for matched routes (with children routes too)
const userLevel = AUTH_ROLES[userRole as keyof typeof AUTH_ROLES]
console.log('🧮 userLevel:', userLevel, 'requiredLevel:', requiredLevel)
//console.log('🧮 userLevel:', userLevel, 'requiredLevel:', requiredLevel)
console.log('[Auth Middleware]', {
to: to.path,
meta: to.meta,
userRole: authStore.role,
requiredLevel,
userLevel,
})
// console.log('[Auth Middleware]', {
// to: to.path,
// meta: to.meta,
// userRole: authStore.role,
// requiredLevel,
// userLevel,
// })
if (userLevel < requiredLevel) {
console.log('🚫 Bloqueando acceso - redirigiendo a /login')
// console.log('🚫 Bloqueando acceso - redirigiendo a /login')
return navigateTo('/login')
}

View File

@@ -5,6 +5,7 @@ import { $fetch } from 'ofetch'
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
components: true,
ssr: true,
devtools: { enabled: true },
modules: [
'@nuxt/eslint',
@@ -37,7 +38,11 @@ export default defineNuxtConfig({
},
},
},
plugins: [
'~/plugins/google-analytics.client.ts',
],
sitemap: {
exclude: ['/admin', '/admin/**', '/editar', '/editar/**'],
urls: async () => {

34
package-lock.json generated
View File

@@ -14,11 +14,13 @@
"@pinia/nuxt": "^0.11.2",
"dompurify": "^3.2.6",
"eslint": "^9.32.0",
"js-cookie": "^3.0.5",
"nuxt": "^3.17.7",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"pinia-plugin-persistedstate": "^4.5.0",
"vue": "^3.5.18",
"vue-advanced-cropper": "^2.8.9",
"vue-gtag": "^3.5.2",
"vue-router": "^4.5.1",
"vue3-carousel": "^0.16.0"
},
@@ -9283,6 +9285,15 @@
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/js-cookie": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
"integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -11069,9 +11080,9 @@
}
},
"node_modules/pinia-plugin-persistedstate": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.4.1.tgz",
"integrity": "sha512-lmuMPpXla2zJKjxEq34e1E9P9jxkWEhcVwwioCCE0izG45kkTOvQfCzvwhW3i38cvnaWC7T1eRdkd15Re59ldw==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.5.0.tgz",
"integrity": "sha512-QTkP1xJVyCdr2I2p3AKUZM84/e+IS+HktRxKGAIuDzkyaKKV48mQcYkJFVVDuvTxlI5j6X3oZObpqoVB8JnWpw==",
"license": "MIT",
"dependencies": {
"deep-pick-omit": "^1.2.1",
@@ -14106,6 +14117,21 @@
"eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/vue-gtag": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/vue-gtag/-/vue-gtag-3.5.2.tgz",
"integrity": "sha512-efTY4yrkNraFSu6CZqhFZLX5LggqCr44d6kcPnPPtzYhvu5ywrTFUnuvM2Vm238QC+YT43HkVEXV/L1OYnHvNg==",
"license": "MIT",
"peerDependencies": {
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"peerDependenciesMeta": {
"vue-router": {
"optional": true
}
}
},
"node_modules/vue-router": {
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz",

View File

@@ -17,11 +17,13 @@
"@pinia/nuxt": "^0.11.2",
"dompurify": "^3.2.6",
"eslint": "^9.32.0",
"js-cookie": "^3.0.5",
"nuxt": "^3.17.7",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"pinia-plugin-persistedstate": "^4.5.0",
"vue": "^3.5.18",
"vue-advanced-cropper": "^2.8.9",
"vue-gtag": "^3.5.2",
"vue-router": "^4.5.1",
"vue3-carousel": "^0.16.0"
},

View File

@@ -1,48 +0,0 @@
// plugins/api.ts
import { useAuthStore } from '~/stores/auth'
export default defineNuxtPlugin((nuxtApp) => {
const auth = useAuthStore()
// Función personalizada para hacer requests
const apiFetch = async (url: string, options: any = {}) => {
try {
const res = await $fetch(url, {
baseURL: useRuntimeConfig().public.apiBase,
credentials: 'include', // para enviar cookies si es necesario
headers: {
...(options.headers || {}),
...(auth.access ? { Authorization: `Bearer ${auth.access}` } : {}),
},
...options,
})
return res
} catch (error: any) {
// Si no es 401, relanzamos el error
if (error?.status !== 401) throw error
// Si es el endpoint de refresh, cerramos sesión
if (url.includes('refresh')) {
auth.logout()
return navigateTo('/login')
}
// Usuario inactivo
if (error?.data?.code === 'user_inactive') {
auth.logout()
return navigateTo('/login')
}
// Intentar refresh
try {
await auth.refresh()
return await apiFetch(url, options) // reintentar la petición original
} catch {
return navigateTo({ name: 'index', query: { redirected: 'true' } })
}
}
}
// Inyectar como $api
nuxtApp.provide('api', apiFetch)
})

View File

@@ -0,0 +1,19 @@
// TODO: Review if its OK. https://matteo-gabriele.gitbook.io/vue-gtag/migration-v2-to-v3
import { configure } from 'vue-gtag'
import { useRouter } from 'vue-router'
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
const router = useRouter()
if (config.public.googleAnalyticsId) {
configure({
tagId: config.public.googleAnalyticsId,
appName: 'latienda.coop',
pageTracker: {
router,
useScreenview: true,
},
})
}
})

View File

@@ -11,6 +11,7 @@ export const useAuthStore = defineStore('auth', {
role: 'ANON' as string,
cookiesAreAccepted: false,
}),
persist: true, // Enable persistence. Cookies will be stored 'auth'
getters: {
isAuthenticated: (state) => !!state.access,
isUser: (state) => state.role === 'SHOP_USER',