i18n: UsersView completamente traducido (headers, labels, empty/error states)
This commit is contained in:
+21
-19
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { AgGridVue } from 'ag-grid-vue3'
|
||||
import type { ColDef } from 'ag-grid-community'
|
||||
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community'
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
|
||||
ModuleRegistry.registerModules([AllCommunityModule])
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useUsersStore()
|
||||
const gridReady = ref(false)
|
||||
|
||||
@@ -63,10 +65,10 @@ const stats = computed(() => ({
|
||||
}, {} as Record<string, number>),
|
||||
}))
|
||||
|
||||
const columnDefs: ColDef[] = [
|
||||
const columnDefs = computed<ColDef[]>(() => [
|
||||
{
|
||||
field: 'full_name',
|
||||
headerName: 'Nombre',
|
||||
headerName: t('users.name'),
|
||||
flex: 2,
|
||||
minWidth: 180,
|
||||
filter: true,
|
||||
@@ -78,10 +80,10 @@ const columnDefs: ColDef[] = [
|
||||
</div>`
|
||||
},
|
||||
},
|
||||
{ field: 'email', headerName: 'Email', flex: 2, minWidth: 200, filter: true },
|
||||
{ field: 'email', headerName: t('users.email'), flex: 2, minWidth: 200, filter: true },
|
||||
{
|
||||
field: 'role',
|
||||
headerName: 'Rol',
|
||||
headerName: t('users.role'),
|
||||
width: 90,
|
||||
filter: true,
|
||||
cellRenderer: (params: any) => {
|
||||
@@ -90,11 +92,11 @@ const columnDefs: ColDef[] = [
|
||||
return `<span class="inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${cls}">${params.value}</span>`
|
||||
},
|
||||
},
|
||||
{ field: 'cell', headerName: 'Célula', width: 110, filter: true, cellRenderer: (p: any) => p.value || '—' },
|
||||
{ field: 'seniority', headerName: 'Seniority', width: 100, filter: true, cellRenderer: (p: any) => p.value || '—' },
|
||||
{ field: 'cell', headerName: t('users.cell'), width: 110, filter: true, cellRenderer: (p: any) => p.value || '—' },
|
||||
{ field: 'seniority', headerName: t('users.seniority'), width: 100, filter: true, cellRenderer: (p: any) => p.value || '—' },
|
||||
{
|
||||
field: 'projects_count',
|
||||
headerName: 'Proyectos',
|
||||
headerName: t('users.projects'),
|
||||
width: 100,
|
||||
filter: 'agNumberColumnFilter',
|
||||
cellRenderer: (params: any) => {
|
||||
@@ -105,7 +107,7 @@ const columnDefs: ColDef[] = [
|
||||
},
|
||||
{
|
||||
field: 'projects',
|
||||
headerName: 'Asignaciones',
|
||||
headerName: t('users.assignments'),
|
||||
flex: 3,
|
||||
minWidth: 200,
|
||||
cellRenderer: (params: any) => {
|
||||
@@ -114,7 +116,7 @@ const columnDefs: ColDef[] = [
|
||||
return p.map((n: string) => `<span class="inline-flex rounded-full bg-muted px-2 py-0.5 text-xs mr-1">${n}</span>`).join('')
|
||||
},
|
||||
},
|
||||
]
|
||||
])
|
||||
|
||||
onMounted(() => {
|
||||
store.fetchAll()
|
||||
@@ -126,13 +128,13 @@ onMounted(() => {
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold tracking-tight">Equipo</h2>
|
||||
<h2 class="text-2xl font-bold tracking-tight">{{ t('users.teamTitle') }}</h2>
|
||||
<p class="text-muted-foreground">
|
||||
{{ store.users.length }} miembros · {{ store.employees.length }} asignaciones en KAPPA
|
||||
{{ t('users.teamSubtitle', { users: store.users.length, emps: store.employees.length }) }}
|
||||
</p>
|
||||
</div>
|
||||
<Badge variant="outline" class="text-sm">
|
||||
{{ stats.active }} activos
|
||||
{{ t('users.activeCount', { count: stats.active }) }}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
@@ -150,13 +152,13 @@ onMounted(() => {
|
||||
<template v-else-if="store.error">
|
||||
<div class="flex flex-col items-center gap-3 py-12 text-center">
|
||||
<IconExclamationCircle class="size-10 text-destructive" />
|
||||
<p class="text-lg font-medium">Error al cargar usuarios</p>
|
||||
<p class="text-lg font-medium">{{ t('users.loadError') }}</p>
|
||||
<p class="text-sm text-muted-foreground">{{ store.error }}</p>
|
||||
<button
|
||||
class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90"
|
||||
@click="store.fetchAll()"
|
||||
>
|
||||
Reintentar
|
||||
{{ t('common.retry') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -165,8 +167,8 @@ onMounted(() => {
|
||||
<template v-else-if="store.users.length === 0">
|
||||
<div class="flex flex-col items-center gap-3 py-12 text-center">
|
||||
<IconUsers class="size-10 text-muted-foreground" />
|
||||
<p class="text-lg font-medium">Sin usuarios</p>
|
||||
<p class="text-sm text-muted-foreground">No se encontraron usuarios en KAPPA.</p>
|
||||
<p class="text-lg font-medium">{{ t('users.emptyTitle') }}</p>
|
||||
<p class="text-sm text-muted-foreground">{{ t('users.emptyDescription') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -194,7 +196,7 @@ onMounted(() => {
|
||||
<!-- Team Member Cards -->
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-muted-foreground uppercase tracking-wider mb-3">
|
||||
Miembros del equipo · {{ teamMembers.length }}
|
||||
{{ t('users.teamMembers', { count: teamMembers.length }) }}
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 gap-3 @xl:grid-cols-2 @3xl:grid-cols-3">
|
||||
<Card
|
||||
@@ -232,7 +234,7 @@ onMounted(() => {
|
||||
{{ user.cell }}
|
||||
</span>
|
||||
<span v-if="user.seniority" class="capitalize">{{ user.seniority }}</span>
|
||||
<span class="font-medium text-foreground">{{ user.projects_count }} proyecto{{ user.projects_count !== 1 ? 's' : '' }}</span>
|
||||
<span class="font-medium text-foreground">{{ t('users.projectCount', { count: user.projects_count }) }}</span>
|
||||
</div>
|
||||
<div v-if="user.projects.length" class="flex flex-wrap gap-1 mt-2">
|
||||
<span
|
||||
@@ -254,7 +256,7 @@ onMounted(() => {
|
||||
<!-- AG Grid table -->
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-muted-foreground uppercase tracking-wider mb-3">
|
||||
Todos los usuarios
|
||||
{{ t('users.allUsers') }}
|
||||
</h3>
|
||||
<div
|
||||
class="ag-theme-alpha-shadcn w-full rounded-lg border overflow-hidden"
|
||||
|
||||
Reference in New Issue
Block a user