graficas meh. pueden mejorar, pueden desaparecer

This commit is contained in:
2025-10-01 02:19:29 -06:00
parent 19a77bc69c
commit a2eae3e2bf
5 changed files with 1470 additions and 2 deletions

View File

@@ -134,7 +134,7 @@
<!-- Fila 3: Filtros Avanzados -->
<div class="flex items-end justify-between gap-4">
<div class="flex-1 grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="flex-1 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<!-- Tipos de Café -->
<div class="flex flex-col">
<h3 class="text-sm font-semibold text-[var(--brand-text-muted)] uppercase tracking-wide mb-3">
@@ -185,6 +185,23 @@
class="w-full"
/>
</div>
<!-- Calidad -->
<div class="flex flex-col">
<h3 class="text-sm font-semibold text-[var(--brand-text-muted)] uppercase tracking-wide mb-3">
Calidad
</h3>
<UInputMenu
v-model="selectedCalidades"
:items="calidadesOptions"
value-key="value"
multiple
placeholder="Todas las calidades"
size="sm"
icon="i-lucide-star"
class="w-full"
/>
</div>
</div>
<UButton
@@ -446,6 +463,44 @@
<!-- Top 10 Clientes -->
<IngresosTopClientes :ingresos="ingresosFiltrados" :clientes="clientesFiltrados" />
<!-- Sección de Gráficas: Acumuladores -->
<div class="space-y-6 w-full">
<div class="flex items-center gap-3 mb-4">
<div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
<h2 class="text-2xl font-bold brand-section-title">Acumuladores en el Tiempo</h2>
<div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
</div>
<!-- Gráfica de Acumulación -->
<div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
<IngresosGraficaAcumuladoresUva :ingresos="ingresosFiltrados" />
</div>
<!-- Gráfica de Pagado vs Depósito -->
<div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
<IngresosGraficaDinamicaPagadoDeposito :ingresos="ingresosFiltrados" />
</div>
</div>
<!-- Sección de Gráficas: Series Temporales -->
<div class="space-y-6 w-full">
<div class="flex items-center gap-3 mb-4">
<div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
<h2 class="text-2xl font-bold brand-section-title">Series Temporales</h2>
<div class="h-px flex-1 bg-gradient-to-r from-transparent via-[var(--brand-border)] to-transparent"></div>
</div>
<!-- Serie de Ingresos Diarios -->
<div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
<IngresosGraficaSerieIngresos :ingresos="ingresosFiltrados" />
</div>
<!-- Serie de Inversión Diaria -->
<div v-if="ingresosFiltrados && ingresosFiltrados.length > 0" class="w-full">
<IngresosGraficaSerieInversion :ingresos="ingresosFiltrados" />
</div>
</div>
</template>
</div>
</template>
@@ -622,6 +677,7 @@ const selectedClienteIds = ref<number[]>([])
const selectedTipos = ref<string[]>([])
const selectedEstados = ref<string[]>([])
const selectedUbicaciones = ref<string[]>([])
const selectedCalidades = ref<string[]>([])
// Opciones para filtros avanzados
const tiposCafeOptions = [
@@ -647,6 +703,17 @@ const ubicacionesOptions = computed(() => {
return Array.from(ubicaciones).sort().map(u => ({ value: u, label: u }))
})
// Calidades dinámicas basadas en los ingresos
const calidadesOptions = computed(() => {
const calidades = new Set<string>()
ingresos.value?.forEach(i => {
if (i.calidad) {
calidades.add(i.calidad)
}
})
return Array.from(calidades).sort().map(c => ({ value: c, label: c }))
})
// Labels for selected filters
const selectedTiposLabels = computed(() => {
return selectedTipos.value
@@ -662,11 +729,16 @@ const selectedEstadosLabels = computed(() => {
.join(', ')
})
const selectedCalidadesLabels = computed(() => {
return selectedCalidades.value.join(', ')
})
// Check if advanced filters are active
const hasAdvancedFilters = computed(() => {
return selectedTipos.value.length > 0 ||
selectedEstados.value.length > 0 ||
selectedUbicaciones.value.length > 0
selectedUbicaciones.value.length > 0 ||
selectedCalidades.value.length > 0
})
// Clear advanced filters
@@ -674,6 +746,7 @@ function clearAdvancedFilters() {
selectedTipos.value = []
selectedEstados.value = []
selectedUbicaciones.value = []
selectedCalidades.value = []
}
async function onToggleAnulados(newValue: boolean | 'indeterminate') {
@@ -749,6 +822,11 @@ function matchesUbicacion(ingreso: IngresoRecord): boolean {
return cliente?.ubicacion ? selectedUbicaciones.value.includes(cliente.ubicacion) : false
}
function matchesCalidad(ingreso: IngresoRecord): boolean {
if (selectedCalidades.value.length === 0) return true
return ingreso.calidad ? selectedCalidades.value.includes(ingreso.calidad) : false
}
// Get selected clientes for display cards
const clientesSeleccionados = computed((): ClienteRecord[] => {
if (selectedClienteIds.value.length === 0) return []
@@ -769,6 +847,7 @@ const ingresosFiltrados = computed(() => {
.filter(r => matchesTipoCafe(r))
.filter(r => matchesEstado(r))
.filter(r => matchesUbicacion(r))
.filter(r => matchesCalidad(r))
})
const clientesFiltrados = computed((): ClienteRecord[] => {