Agregar filtro Solo Presentes y reorganizar filtros
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 57s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 57s
- Reorganizar filtros (ID, Teléfono, Empleados, Presentes) en una fila con wrap - Agregar checkbox 'Presentes' basado en tabla Asistencias de Supabase - Crear endpoint /api/contacts/presentes que consulta última asistencia sin salida - Integrar filtro de presentes en useContacts con carga lazy
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Filtros adicionales -->
|
||||
<!-- Filtros en una fila con wrap -->
|
||||
<div class="filter-row">
|
||||
<!-- Filtro por ID -->
|
||||
<div class="filter-field filter-id">
|
||||
@@ -43,7 +43,13 @@
|
||||
<!-- Checkbox empleados -->
|
||||
<label class="filter-checkbox">
|
||||
<UCheckbox v-model="empleadoFilter" />
|
||||
<span>Solo empleados</span>
|
||||
<span>Empleados</span>
|
||||
</label>
|
||||
|
||||
<!-- Checkbox presentes -->
|
||||
<label class="filter-checkbox">
|
||||
<UCheckbox v-model="presenteFilter" />
|
||||
<span>Presentes</span>
|
||||
</label>
|
||||
|
||||
<!-- Botón limpiar -->
|
||||
@@ -94,12 +100,18 @@ const empleadoFilter = computed({
|
||||
set: (val) => emit('update:modelValue', { ...props.modelValue, empleado: val })
|
||||
})
|
||||
|
||||
const presenteFilter = computed({
|
||||
get: () => props.modelValue.presente,
|
||||
set: (val) => emit('update:modelValue', { ...props.modelValue, presente: val })
|
||||
})
|
||||
|
||||
const hasActiveFilters = computed(() => {
|
||||
return (
|
||||
props.modelValue.search ||
|
||||
props.modelValue.id ||
|
||||
props.modelValue.telefono ||
|
||||
!props.modelValue.empleado
|
||||
!props.modelValue.empleado ||
|
||||
props.modelValue.presente
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ const {
|
||||
error,
|
||||
fetchContacts,
|
||||
fetchAliases,
|
||||
fetchPresentes,
|
||||
updateAlias,
|
||||
getWhatsAppUrl,
|
||||
clearFilters
|
||||
@@ -78,7 +79,7 @@ const {
|
||||
|
||||
// Cargar datos al montar
|
||||
onMounted(async () => {
|
||||
await Promise.all([fetchContacts(), fetchAliases()])
|
||||
await Promise.all([fetchContacts(), fetchAliases(), fetchPresentes()])
|
||||
})
|
||||
|
||||
// Manejar actualización de alias
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface ContactFilters {
|
||||
id: string
|
||||
telefono: string
|
||||
empleado: boolean
|
||||
presente: boolean
|
||||
}
|
||||
|
||||
export const useContacts = () => {
|
||||
@@ -27,6 +28,7 @@ export const useContacts = () => {
|
||||
// Estado
|
||||
const contacts = ref<Contact[]>([])
|
||||
const aliases = ref<Record<string, string>>({})
|
||||
const presentIds = ref<Set<number>>(new Set())
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
@@ -37,7 +39,8 @@ export const useContacts = () => {
|
||||
search: '',
|
||||
id: '',
|
||||
telefono: '',
|
||||
empleado: true
|
||||
empleado: true,
|
||||
presente: false
|
||||
})
|
||||
})
|
||||
|
||||
@@ -87,6 +90,19 @@ export const useContacts = () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cargar IDs de empleados presentes
|
||||
*/
|
||||
const fetchPresentes = async () => {
|
||||
try {
|
||||
const data = await $fetch<number[]>('/api/contacts/presentes')
|
||||
presentIds.value = new Set(data)
|
||||
} catch (err: any) {
|
||||
console.error('Error al cargar presentes:', err)
|
||||
// No es crítico, continuar sin filtro de presentes
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualizar alias de un contacto
|
||||
*/
|
||||
@@ -119,6 +135,11 @@ export const useContacts = () => {
|
||||
// Primero filtrar solo contactos con teléfono
|
||||
let result = contacts.value.filter(c => c.telefono && c.telefono.trim() !== '')
|
||||
|
||||
// Filtro por presentes (solo si está activo)
|
||||
if (filters.value.presente) {
|
||||
result = result.filter(c => presentIds.value.has(c.id))
|
||||
}
|
||||
|
||||
// Filtro por teléfono (parcial)
|
||||
if (filters.value.telefono) {
|
||||
const telFilter = filters.value.telefono.replace(/\D/g, '')
|
||||
@@ -177,7 +198,8 @@ export const useContacts = () => {
|
||||
search: '',
|
||||
id: '',
|
||||
telefono: '',
|
||||
empleado: true
|
||||
empleado: true,
|
||||
presente: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,15 +211,27 @@ export const useContacts = () => {
|
||||
}
|
||||
)
|
||||
|
||||
// Watch para recargar presentes cuando se activa el filtro
|
||||
watch(
|
||||
() => filters.value.presente,
|
||||
(newVal) => {
|
||||
if (newVal && presentIds.value.size === 0) {
|
||||
fetchPresentes()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
contacts,
|
||||
aliases,
|
||||
presentIds,
|
||||
filters,
|
||||
filteredContacts,
|
||||
isLoading,
|
||||
error,
|
||||
fetchContacts,
|
||||
fetchAliases,
|
||||
fetchPresentes,
|
||||
updateAlias,
|
||||
getDisplayName,
|
||||
hasAlias,
|
||||
|
||||
Reference in New Issue
Block a user