Agregar sección Contactos con UTabs y conexión a Metabase
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 2m37s

- Implementar UTabs (Contactos, Aplicaciones, Perfil) en app.vue
- Crear componentes ContactsList, ContactsFilters, ContactItem
- Agregar server routes para obtener contactos via Metabase API
- Sistema de aliases por usuario guardados en archivos JSON
- Filtros: nombre (fuzzy search), ID, teléfono, empleado
- Click en contacto abre WhatsApp
- Estilo glassmorphism consistente con la app
This commit is contained in:
2025-12-05 11:41:26 -06:00
parent 00596bd6df
commit 59f25adabe
13 changed files with 1512 additions and 17 deletions

View File

@@ -0,0 +1,51 @@
import { readFile, mkdir } from 'fs/promises'
import { existsSync } from 'fs'
import { join } from 'path'
/**
* API endpoint para obtener los aliases de contactos del usuario actual
* Los aliases se guardan en archivos JSON por usuario
*/
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const headers = getRequestHeaders(event)
// Verificar autenticación
const uid = headers['x-authentik-uid']
if (!uid) {
throw createError({
statusCode: 401,
message: 'Usuario no autenticado'
})
}
// Sanitizar UID para usar como nombre de archivo
const safeUid = uid.replace(/[^a-zA-Z0-9-_]/g, '_')
// Ruta del archivo de aliases
const dataDir = config.dataDir || './data'
const aliasesDir = join(dataDir, 'contact-aliases')
const aliasesFile = join(aliasesDir, `${safeUid}.json`)
try {
// Crear directorio si no existe
if (!existsSync(aliasesDir)) {
await mkdir(aliasesDir, { recursive: true })
}
// Leer archivo de aliases si existe
if (existsSync(aliasesFile)) {
const content = await readFile(aliasesFile, 'utf-8')
return JSON.parse(content)
}
// Si no existe, retornar objeto vacío
return {}
} catch (error: any) {
console.error('Error al leer aliases:', error)
throw createError({
statusCode: 500,
message: 'Error al obtener los aliases'
})
}
})