Files
analiticaNucleo/nuxt4-app/app/components/clientes/ClienteCard.vue
josedario87 2b252d798b
Some checks failed
deploy-analiticaNucleo / deploy (push) Failing after 2s
preparando el deploy
2025-10-05 12:13:32 -06:00

123 lines
4.6 KiB
Vue

<!-- nuxt4-app/app/components/clientes/ClienteCard.vue -->
<template>
<div class="relative overflow-hidden rounded-lg border border-gray-400/30 bg-gradient-to-br from-gray-100/10 to-gray-300/5 backdrop-blur-sm p-5 shadow-lg transition-all duration-300 hover:border-gray-300/50 hover:shadow-xl">
<!-- Header with Avatar and Name -->
<div class="flex items-start gap-4 mb-4">
<div class="flex-shrink-0">
<div class="h-14 w-14 rounded-full bg-gradient-to-br from-gray-300/40 to-gray-500/20 flex items-center justify-center text-xl font-bold text-gray-200 border border-gray-400/30">
{{ clienteInitials }}
</div>
</div>
<div class="flex-1 min-w-0">
<h3 class="text-lg font-bold text-gray-100 truncate mb-1">{{ cliente.name }}</h3>
<div class="flex flex-wrap gap-2 text-xs">
<span v-if="cliente.cedula" class="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-gray-500/20 text-gray-300 border border-gray-400/20">
<UIcon name="i-lucide-credit-card" class="w-3 h-3" />
{{ cliente.cedula }}
</span>
<span v-if="cliente.empleado" class="inline-flex items-center gap-1 px-2 py-0.5 rounded bg-blue-500/20 text-blue-300 border border-blue-400/30">
<UIcon name="i-lucide-briefcase" class="w-3 h-3" />
Empleado
</span>
</div>
</div>
<!-- Remove Button -->
<button
@click="$emit('remove')"
class="flex-shrink-0 p-1.5 rounded-full hover:bg-red-500/20 text-gray-400 hover:text-red-400 transition-colors"
title="Quitar cliente"
>
<UIcon name="i-lucide-x" class="w-4 h-4" />
</button>
</div>
<!-- Details Grid -->
<div class="grid grid-cols-2 gap-3">
<div v-if="cliente.ubicacion" class="flex items-start gap-2">
<UIcon name="i-lucide-map-pin" class="w-4 h-4 text-gray-400 mt-0.5 flex-shrink-0" />
<div class="min-w-0 flex-1">
<div class="text-xs text-gray-500 uppercase tracking-wide">Ubicación</div>
<div class="text-sm text-gray-200 truncate">{{ cliente.ubicacion }}</div>
</div>
</div>
<div v-if="cliente.telefono" class="flex items-start gap-2">
<UIcon name="i-lucide-phone" class="w-4 h-4 text-gray-400 mt-0.5 flex-shrink-0" />
<div class="min-w-0 flex-1">
<div class="text-xs text-gray-500 uppercase tracking-wide">Teléfono</div>
<div class="text-sm text-gray-200 truncate">{{ cliente.telefono }}</div>
</div>
</div>
<div v-if="cliente.grupo_estudio" class="flex items-start gap-2">
<UIcon name="i-lucide-users" class="w-4 h-4 text-gray-400 mt-0.5 flex-shrink-0" />
<div class="min-w-0 flex-1">
<div class="text-xs text-gray-500 uppercase tracking-wide">Grupo</div>
<div class="text-sm text-gray-200 truncate">{{ cliente.grupo_estudio }}</div>
</div>
</div>
<div v-if="cliente.idciat" class="flex items-start gap-2">
<UIcon name="i-lucide-hash" class="w-4 h-4 text-gray-400 mt-0.5 flex-shrink-0" />
<div class="min-w-0 flex-1">
<div class="text-xs text-gray-500 uppercase tracking-wide">ID CIAT</div>
<div class="text-sm text-gray-200">{{ cliente.idciat }}</div>
</div>
</div>
</div>
<!-- Footer with metadata -->
<div class="mt-4 pt-3 border-t border-gray-400/20 flex items-center justify-between text-xs text-gray-500">
<span>ID: {{ cliente.id }}</span>
<span v-if="cliente.created_at">Desde {{ formatDate(cliente.created_at) }}</span>
</div>
<!-- Decorative gradient overlay -->
<div class="absolute inset-0 bg-gradient-to-tr from-transparent via-transparent to-white/5 pointer-events-none rounded-lg"></div>
</div>
</template>
<script setup lang="ts">
interface ClienteRecord {
id: number
created_at: string
updated_at: string
name: string
cedula?: number
ubicacion?: string
grupo_estudio?: string
empleado?: boolean
avatar_url?: string
telefono?: string
idciat?: number
}
interface Props {
cliente: ClienteRecord
}
const props = defineProps<Props>()
defineEmits<{
remove: []
}>()
// Compute initials from name
const clienteInitials = computed(() => {
const names = props.cliente.name.trim().split(' ')
if (names.length >= 2 && names[0] && names[1]) {
return (names[0][0] + names[1][0]).toUpperCase()
}
return names[0]?.substring(0, 2).toUpperCase() || 'XX'
})
// Format date helper
const formatDate = (dateStr: string) => {
const date = new Date(dateStr)
return date.toLocaleDateString('es-ES', {
year: 'numeric',
month: 'short'
})
}
</script>