Refactor: Adaptar todos los componentes al sistema de temas

- Reemplazar colores hardcoded del tema café con variables --brand-*
  - #c08040 → var(--brand-primary-strong)
  - #d99a56 → var(--brand-primary)
  - #f0c07c → var(--brand-accent)
  - #1c140c → var(--brand-surface)
  - #3a2a16 → var(--brand-border)
  - #1b1209, #14100b → var(--brand-bg)

- Reemplazar colores de tipos de café con variables --coffee-*
  - #a855f7 → var(--coffee-uva)
  - #f97316 → var(--coffee-oreado)
  - #06b6d4 → var(--coffee-mojado)
  - #22c55e → var(--coffee-verde)

- Reemplazar clases gray-scale de Tailwind con variables de tema
  - text-gray-400, text-gray-500 → text-[var(--brand-text-muted)]
  - bg-gray-700/30 → bg-[var(--brand-surface)]

- Todos los componentes ahora responden dinámicamente a cambios de tema

Archivos adaptados:
- Páginas: error, informe-ingresos, panorama, explorer, metabase-debug, profile, notifications, settings
- Componentes de ingresos: GraficaSerieIngresos, GraficaSerieInversion, GraficaDinamicaPagadoDeposito, GraficaAcumuladoresUva, TotalesIngresoCompra, TotalesMonetarios, TotalesVerde, SecosVendidos, TopClientes, VistaTablaIngresos, VistaTablaIngresosConClientes, FiltrosActivos
- Componentes de comparativa: CosechasHeatmap, CosechasPorTipo, CosechasEvolucion, CosechasTotales
- Componentes de UI: ClienteSelector, DateRangeSelector, MetadatosCard, MaintenanceMode
- Componentes de auth: UserAvatar, UserMetadata
- Componentes de clientes: ClienteCard, VistaTablaClientes
- Componentes de rechazos: RechazoCard, RechazosRechazoCard, RechazosSubproductos
- Componentes de metabase: MetabaseCardDisplay, MetabaseCardsTable
This commit is contained in:
2025-10-30 17:54:42 -06:00
parent 1df10db4a0
commit aa76fea286
42 changed files with 190 additions and 190 deletions

View File

@@ -28,7 +28,7 @@
<div class="flex items-end">
<UButton
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c]' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)]' }"
@click="clearSelection"
size="sm"
>

View File

@@ -36,7 +36,7 @@
<div class="flex items-end">
<UButton
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c]' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)]' }"
@click="setToday"
size="sm"
>

View File

@@ -14,7 +14,7 @@
<h2 class="text-3xl font-bold text-gray-900 dark:text-white mb-2">
{{ title }}
</h2>
<p class="text-lg text-gray-600 dark:text-gray-400 mb-4">
<p class="text-lg text-[var(--brand-text-muted)] mb-4">
Esta funcionalidad está temporalmente en mantenimiento
</p>
<p class="text-sm text-gray-500 dark:text-gray-500 max-w-md mx-auto">
@@ -46,7 +46,7 @@
<summary class="text-sm font-semibold text-gray-700 dark:text-gray-300 cursor-pointer hover:text-gray-900 dark:hover:text-white">
Información técnica
</summary>
<div class="mt-3 p-4 bg-gray-50 dark:bg-gray-800/50 rounded-lg text-sm text-gray-600 dark:text-gray-400">
<div class="mt-3 p-4 bg-[var(--brand-surface)] rounded-lg text-sm text-[var(--brand-text-muted)]">
{{ technicalInfo }}
</div>
</details>

View File

@@ -37,7 +37,7 @@
<UButton
:loading="isLoadingLatest"
:disabled="isLoadingAll"
:ui="{ base: tableStore?.isStale ? 'bg-yellow-500 text-black border-0 hover:bg-yellow-400 font-bold' : 'bg-[#c08040] text-[#1b1209] border-0 hover:bg-[#d99a56]' }"
:ui="{ base: tableStore?.isStale ? 'bg-yellow-500 text-black border-0 hover:bg-yellow-400 font-bold' : 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border-0 hover:bg-[var(--brand-primary)]' }"
size="xs"
icon="i-lucide-clock"
@click.stop="loadLatestData"
@@ -47,7 +47,7 @@
<UButton
:loading="isLoadingAll"
:disabled="isLoadingLatest"
:ui="{ base: tableStore?.isStale ? 'bg-yellow-500 text-black border-0 hover:bg-yellow-400 font-bold' : 'bg-[#c08040] text-[#1b1209] border-0 hover:bg-[#d99a56]' }"
:ui="{ base: tableStore?.isStale ? 'bg-yellow-500 text-black border-0 hover:bg-yellow-400 font-bold' : 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border-0 hover:bg-[var(--brand-primary)]' }"
size="xs"
icon="i-lucide-database"
@click.stop="loadAllData"
@@ -150,7 +150,7 @@
<UButton
:loading="isLoadingLatest"
:disabled="isLoadingAll"
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c]' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)]' }"
size="sm"
@click.stop="loadLatestData"
>
@@ -163,7 +163,7 @@
<UButton
:loading="isLoadingAll"
:disabled="isLoadingLatest"
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c]' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)]' }"
size="sm"
@click.stop="loadAllData"
>

View File

@@ -34,7 +34,7 @@
<div v-if="data && data.length > 0" class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="border-b border-[#3a2a16]">
<tr class="border-b border-[var(--brand-border)]">
<th class="text-left py-3 px-4 text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Tipo</th>
<th class="text-right py-3 px-4 text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Registros</th>
<th class="text-right py-3 px-4 text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Cantidad Total</th>
@@ -46,7 +46,7 @@
<tr
v-for="(rechazo, index) in data"
:key="rechazo.tipo"
class="border-b border-[#3a2a16] hover:bg-[#2a1f0f] transition-colors"
class="border-b border-[var(--brand-border)] hover:bg-[#2a1f0f] transition-colors"
>
<td class="py-3 px-4 text-[var(--brand-text)] capitalize font-medium">
{{ rechazo.tipo }}
@@ -65,7 +65,7 @@
</td>
</tr>
</tbody>
<tfoot class="border-t-2 border-[#3a2a16] bg-[#1c140c]">
<tfoot class="border-t-2 border-[var(--brand-border)] bg-[var(--brand-surface)]">
<tr>
<td class="py-3 px-4 text-[var(--brand-text)] font-bold uppercase text-sm">Total</td>
<td class="py-3 px-4 text-right text-[var(--brand-text)] font-bold">

View File

@@ -27,14 +27,14 @@
</template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">QQ Seco por Vender</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatNumber(data.total_qq_seco_por_vender) }} QQ
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Precio Venta Promedio/QQ</div>
<div class="text-2xl font-bold text-green-400">
{{ formatCurrency(data.precio_venta_promedio_por_qq) }}
@@ -44,14 +44,14 @@
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Precio Compra Promedio/QQ</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatCurrency(data.precio_compra_promedio_por_qq) }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Margen de Ganancia/QQ</div>
<div class="text-2xl font-bold" :class="margenColor">
{{ formatCurrency(data.margen_ganancia_por_qq) }}

View File

@@ -63,7 +63,7 @@
<!-- Ambos -->
<div v-else class="grid grid-cols-1 md:grid-cols-3 gap-3">
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Uva Ingresada</div>
<div class="text-lg font-bold text-[var(--brand-text)]">
{{ formatNumber(data.total_lb_uva_ingresada) }} lb
@@ -73,7 +73,7 @@
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Uva Pagada</div>
<div class="text-lg font-bold text-green-400">
{{ formatNumber(data.total_lb_uva_pagada) }} lb
@@ -83,7 +83,7 @@
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Uva en Depósito</div>
<div class="text-lg font-bold text-yellow-400">
{{ formatNumber(data.total_lb_uva_deposito) }} lb
@@ -116,7 +116,7 @@
</div>
<!-- Totales Generales -->
<div class="pt-4 border-t border-[#3a2a16]">
<div class="pt-4 border-t border-[var(--brand-border)]">
<h3 class="text-lg font-semibold text-[var(--brand-primary)] mb-3">Totales Generales</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-3">
<MetricBox label="QQ Seco Ingresado" :value="formatNumber(data.total_qq_seco_ingresado) + ' QQ'" />

View File

@@ -66,7 +66,7 @@
<MetricBox v-else-if="priceUnitMode === 'qq'" label="Uva por QQ" :value="formatCurrency(data.precio_promedio_uva_por_qq)" />
<!-- Uva: Ambos -->
<div v-else class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div v-else class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Uva</div>
<div class="text-lg font-bold text-[var(--brand-text)]">
{{ formatCurrency(data.precio_promedio_uva_por_lb) }}/lb

View File

@@ -27,42 +27,42 @@
</template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">LB Neto Verde Total</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatNumber(data.total_lb_neto_verde) }} lb
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">LB Neto Comprado</div>
<div class="text-2xl font-bold text-green-400">
{{ formatNumber(data.total_lb_neto_comprado_verde) }} lb
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">LB Neto en Depósito</div>
<div class="text-2xl font-bold text-yellow-400">
{{ formatNumber(data.total_lb_neto_verde_deposito) }} lb
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Precio Promedio Pagado</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatCurrency(data.precio_promedio_verde_pagado) }}/lb
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Inversión Hasta la Fecha</div>
<div class="text-2xl font-bold text-green-400">
{{ formatCurrency(data.inversion_verde_hasta_fecha) }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Inversión Restante</div>
<div class="text-2xl font-bold text-yellow-400">
{{ formatCurrency(data.inversion_restante_verde) }}

View File

@@ -8,8 +8,8 @@
/>
<div class="flex-1">
<h3 class="font-semibold text-lg">{{ user.name || user.username }}</h3>
<p class="text-sm text-gray-500 dark:text-gray-400">{{ user.email }}</p>
<p class="text-xs text-gray-400 dark:text-gray-500 mt-1">ID: {{ user.uid }}</p>
<p class="text-sm text-[var(--brand-text-muted)]">{{ user.email }}</p>
<p class="text-xs text-[var(--brand-text-muted)] mt-1">ID: {{ user.uid }}</p>
</div>
</div>
</UCard>

View File

@@ -10,45 +10,45 @@
<div class="space-y-3">
<!-- Username -->
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-at-symbol" class="text-gray-500 dark:text-gray-400 mt-0.5" />
<UIcon name="i-heroicons-at-symbol" class="text-[var(--brand-text-muted)] mt-0.5" />
<div class="flex-1">
<p class="text-xs text-gray-500 dark:text-gray-400">Username</p>
<p class="text-xs text-[var(--brand-text-muted)]">Username</p>
<p class="font-medium">{{ user.username }}</p>
</div>
</div>
<!-- Email -->
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-envelope" class="text-gray-500 dark:text-gray-400 mt-0.5" />
<UIcon name="i-heroicons-envelope" class="text-[var(--brand-text-muted)] mt-0.5" />
<div class="flex-1">
<p class="text-xs text-gray-500 dark:text-gray-400">Email</p>
<p class="text-xs text-[var(--brand-text-muted)]">Email</p>
<p class="font-medium">{{ user.email }}</p>
</div>
</div>
<!-- Nombre completo -->
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-user" class="text-gray-500 dark:text-gray-400 mt-0.5" />
<UIcon name="i-heroicons-user" class="text-[var(--brand-text-muted)] mt-0.5" />
<div class="flex-1">
<p class="text-xs text-gray-500 dark:text-gray-400">Nombre Completo</p>
<p class="text-xs text-[var(--brand-text-muted)]">Nombre Completo</p>
<p class="font-medium">{{ user.name || 'No especificado' }}</p>
</div>
</div>
<!-- UID -->
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-key" class="text-gray-500 dark:text-gray-400 mt-0.5" />
<UIcon name="i-heroicons-key" class="text-[var(--brand-text-muted)] mt-0.5" />
<div class="flex-1">
<p class="text-xs text-gray-500 dark:text-gray-400">ID Único</p>
<p class="text-xs text-[var(--brand-text-muted)]">ID Único</p>
<p class="font-mono text-sm">{{ user.uid }}</p>
</div>
</div>
<!-- Grupos -->
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-user-group" class="text-gray-500 dark:text-gray-400 mt-0.5" />
<UIcon name="i-heroicons-user-group" class="text-[var(--brand-text-muted)] mt-0.5" />
<div class="flex-1">
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">Grupos</p>
<p class="text-xs text-[var(--brand-text-muted)] mb-2">Grupos</p>
<div class="flex flex-wrap gap-2">
<UBadge
v-for="group in user.groups"
@@ -67,15 +67,15 @@
<!-- Metadata de la Aplicación (si está disponible) -->
<div v-if="user.appSlug || user.outpostName" class="pt-3 mt-3 border-t border-gray-200 dark:border-gray-700">
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">Información de Conexión</p>
<p class="text-xs text-[var(--brand-text-muted)] mb-2">Información de Conexión</p>
<div class="space-y-2">
<div v-if="user.appSlug" class="flex items-center gap-2 text-sm">
<UIcon name="i-heroicons-cube" class="text-gray-400" />
<UIcon name="i-heroicons-cube" class="text-[var(--brand-text-muted)]" />
<span class="text-gray-600 dark:text-gray-300">App: </span>
<code class="text-xs bg-gray-100 dark:bg-gray-800 px-2 py-0.5 rounded">{{ user.appSlug }}</code>
</div>
<div v-if="user.outpostName" class="flex items-center gap-2 text-sm">
<UIcon name="i-heroicons-server" class="text-gray-400" />
<UIcon name="i-heroicons-server" class="text-[var(--brand-text-muted)]" />
<span class="text-gray-600 dark:text-gray-300">Outpost: </span>
<code class="text-xs bg-gray-100 dark:bg-gray-800 px-2 py-0.5 rounded">{{ user.outpostName }}</code>
</div>

View File

@@ -24,7 +24,7 @@
<!-- 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"
class="flex-shrink-0 p-1.5 rounded-full hover:bg-red-500/20 text-[var(--brand-text-muted)] hover:text-red-400 transition-colors"
title="Quitar cliente"
>
<UIcon name="i-lucide-x" class="w-4 h-4" />
@@ -34,7 +34,7 @@
<!-- 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" />
<UIcon name="i-lucide-map-pin" class="w-4 h-4 text-[var(--brand-text-muted)] 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>
@@ -42,7 +42,7 @@
</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" />
<UIcon name="i-lucide-phone" class="w-4 h-4 text-[var(--brand-text-muted)] 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>
@@ -50,7 +50,7 @@
</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" />
<UIcon name="i-lucide-users" class="w-4 h-4 text-[var(--brand-text-muted)] 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>
@@ -58,7 +58,7 @@
</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" />
<UIcon name="i-lucide-hash" class="w-4 h-4 text-[var(--brand-text-muted)] 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>

View File

@@ -440,7 +440,7 @@ function formatCellValue(value: unknown, column: string, row: any, depth: number
size: 'xs'
}) : h(UIcon, {
name: 'i-lucide-user-circle',
class: 'w-6 h-6 text-gray-400'
class: 'w-6 h-6 text-[var(--brand-text-muted)]'
}),
h('span', { class: 'font-medium' }, value)
])
@@ -450,7 +450,7 @@ function formatCellValue(value: unknown, column: string, row: any, depth: number
if (column === 'empleado' && typeof value === 'boolean') {
return h(UIcon, {
name: value ? 'i-lucide-briefcase' : 'i-lucide-user',
class: value ? 'text-purple-600 w-5 h-5' : 'text-gray-400 w-5 h-5'
class: value ? 'text-purple-600 w-5 h-5' : 'text-[var(--brand-text-muted)] w-5 h-5'
})
}

View File

@@ -3,7 +3,7 @@
<template #header>
<div class="flex flex-col gap-3">
<div class="flex items-center gap-2">
<UIcon name="i-lucide-trending-up" class="size-5 text-[#c08040]" />
<UIcon name="i-lucide-trending-up" class="size-5 text-[var(--brand-primary-strong)]" />
<h3 class="text-base font-semibold text-[var(--brand-text)]">Evolución Temporal Comparada</h3>
</div>
<div class="flex items-center gap-3">
@@ -13,7 +13,7 @@
@click="metrica = 'acumulado'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'acumulado'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Acumulado
@@ -22,7 +22,7 @@
@click="metrica = 'diario'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'diario'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Diario
@@ -35,7 +35,7 @@
@click="tipoSeleccionado = 'todos'"
class="px-3 py-1 rounded text-xs transition-all"
:class="tipoSeleccionado === 'todos'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Todos
@@ -46,7 +46,7 @@
@click="tipoSeleccionado = tipo"
class="px-3 py-1 rounded text-xs transition-all capitalize"
:class="tipoSeleccionado === tipo
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
{{ tipo }}
@@ -182,7 +182,7 @@ const cosechasDisponibles = inject<any[]>('cosechasDisponibles', [])
// Obtener configuración de estilos
const estilosGraficas = inject<any>('estilosGraficas', ref({
coloresCosechas: ['#c08040', '#d99a56', '#8b6f47', '#a0826e', '#b89968', '#f0c07c']
coloresCosechas: ['var(--brand-primary-strong)', 'var(--brand-primary)', '#8b6f47', '#a0826e', '#b89968', 'var(--brand-accent)']
}))
// Dimensiones del SVG

View File

@@ -8,7 +8,7 @@
<div class="flex flex-col gap-3">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<UIcon name="i-lucide-activity" class="size-5 text-[#c08040]" />
<UIcon name="i-lucide-activity" class="size-5 text-[var(--brand-primary-strong)]" />
<h3 class="text-base font-semibold text-[var(--brand-text)]">Vista de Calor por Día</h3>
</div>
<div class="flex items-center gap-2">
@@ -66,7 +66,7 @@
@click="vistaMode = 'heatmap'"
class="px-3 py-1 rounded text-xs transition-all"
:class="vistaMode === 'heatmap'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Heatmap
@@ -75,7 +75,7 @@
@click="vistaMode = 'barras'"
class="px-3 py-1 rounded text-xs transition-all"
:class="vistaMode === 'barras'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Barras
@@ -85,7 +85,7 @@
<label class="text-xs text-[var(--brand-text-muted)] ml-4">Selección:</label>
<div class="flex gap-2 items-center">
<!-- Rango completo seleccionado -->
<div v-if="rangoSeleccionado" class="flex items-center gap-2 px-3 py-1 rounded-lg bg-[#c08040]/20 border border-[#c08040]/50">
<div v-if="rangoSeleccionado" class="flex items-center gap-2 px-3 py-1 rounded-lg bg-[var(--brand-primary-strong)]/20 border border-[var(--brand-primary-strong)]/50">
<span class="text-xs text-[var(--brand-text)]">
{{ formatRangoFecha(rangoSeleccionado.diaDesde) }} - {{ formatRangoFecha(rangoSeleccionado.diaHasta) }}
</span>
@@ -126,7 +126,7 @@
@click="metrica = 'total_peso_seco'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'total_peso_seco'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Peso Seco (qq)
@@ -135,7 +135,7 @@
@click="metrica = 'peso_neto_uva'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'peso_neto_uva'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Peso Neto Uva (qq)
@@ -144,7 +144,7 @@
@click="metrica = 'peso_neto_verde'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'peso_neto_verde'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Peso Neto Verde (qq)
@@ -153,7 +153,7 @@
@click="metrica = 'sacos_total_dia'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'sacos_total_dia'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Sacos Total
@@ -162,7 +162,7 @@
@click="metrica = 'total_lempiras_uva'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'total_lempiras_uva'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Lempiras Uva
@@ -171,7 +171,7 @@
@click="metrica = 'total_lempiras_verde'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'total_lempiras_verde'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Lempiras Verde
@@ -180,7 +180,7 @@
@click="metrica = 'total_lempiras_mojado_oreado'"
class="px-3 py-1 rounded text-xs transition-all"
:class="metrica === 'total_lempiras_mojado_oreado'
? 'bg-[#c08040] text-[#1b1209]'
? 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)]'
: 'bg-[var(--brand-bg-secondary)] text-[var(--brand-text-muted)] hover:text-[var(--brand-text)]'"
>
Lempiras Mojado+Oreado
@@ -198,7 +198,7 @@
<div class="flex items-center gap-3 mb-3 px-2 py-2 rounded-lg bg-[var(--brand-bg-secondary)]/50 border border-[var(--brand-border)]/30">
<span class="text-[10px] text-[var(--brand-text-muted)] uppercase font-semibold">Leyenda:</span>
<div class="flex items-center gap-1.5">
<div class="w-2 h-2 rounded-full bg-[#c08040]"></div>
<div class="w-2 h-2 rounded-full bg-[var(--brand-primary-strong)]"></div>
<span class="text-[10px] text-[var(--brand-text-muted)]">Total completo de la cosecha</span>
</div>
<div class="flex items-center gap-1.5">
@@ -220,7 +220,7 @@
{{ cosecha.label }}
</div>
<div class="flex flex-col items-center gap-0.5">
<div class="text-xs font-medium text-[#c08040]" :title="`Total completo de ${cosecha.label}`">
<div class="text-xs font-medium text-[var(--brand-primary-strong)]" :title="`Total completo de ${cosecha.label}`">
{{ formatTotal(cosecha.total) }}
</div>
<div
@@ -232,7 +232,7 @@
</div>
<div
v-else
class="text-[10px] text-gray-500 italic"
class="text-[10px] text-[var(--brand-text-muted)] italic"
title="Sin datos hasta la fecha [actual]"
>
0
@@ -274,12 +274,12 @@
:class="[
// Rango seleccionado (naranja)
isInSelectedRange(dia - 1)
? 'ring-2 ring-[#c08040] border-[#c08040] z-10'
? 'ring-2 ring-[var(--brand-primary-strong)] border-[var(--brand-primary-strong)] z-10'
: // Primera celda seleccionada (azul)
primerDiaSeleccionado === dia - 1 && rangoSeleccionado === null
? 'ring-2 ring-blue-500 border-blue-500 z-10'
: // Default
'border-[var(--brand-border)]/30 hover:ring-1 hover:ring-[#c08040]/50'
'border-[var(--brand-border)]/30 hover:ring-1 hover:ring-[var(--brand-primary-strong)]/50'
]"
:style="{
width: `${cellWidth}px`,
@@ -294,7 +294,7 @@
<!-- Overlay gris para días ya transcurridos -->
<div
v-if="isDiaPasado(cosecha.id, dia - 1)"
class="absolute inset-0 bg-gray-400/15 pointer-events-none"
class="absolute inset-0 bg-[var(--brand-surface)] pointer-events-none"
/>
<!-- Marcador visual para primera celda seleccionada -->
@@ -314,7 +314,7 @@
<div class="flex items-center gap-3 mb-3 px-2 py-2 rounded-lg bg-[var(--brand-bg-secondary)]/50 border border-[var(--brand-border)]/30">
<span class="text-[10px] text-[var(--brand-text-muted)] uppercase font-semibold">Leyenda:</span>
<div class="flex items-center gap-1.5">
<div class="w-2 h-2 rounded-full bg-[#c08040]"></div>
<div class="w-2 h-2 rounded-full bg-[var(--brand-primary-strong)]"></div>
<span class="text-[10px] text-[var(--brand-text-muted)]">Total completo de la cosecha</span>
</div>
<div class="flex items-center gap-1.5">
@@ -336,7 +336,7 @@
{{ cosecha.label }}
</div>
<div class="flex flex-col items-center gap-0.5">
<div class="text-xs font-medium text-[#c08040]" :title="`Total completo de ${cosecha.label}`">
<div class="text-xs font-medium text-[var(--brand-primary-strong)]" :title="`Total completo de ${cosecha.label}`">
{{ formatTotal(cosecha.total) }}
</div>
<div
@@ -348,7 +348,7 @@
</div>
<div
v-else
class="text-[10px] text-gray-500 italic"
class="text-[10px] text-[var(--brand-text-muted)] italic"
title="Sin datos hasta la fecha actual"
>
{{ formatTotal(cosecha.totalALaFecha || 0) }}
@@ -391,7 +391,7 @@
:class="[
// Rango seleccionado (naranja)
isInSelectedRange(dia - 1)
? 'border-[#c08040] border-2 bg-[#c08040]/10'
? 'border-[var(--brand-primary-strong)] border-2 bg-[var(--brand-primary-strong)]/10'
: // Primera celda seleccionada (azul)
primerDiaSeleccionado === dia - 1 && rangoSeleccionado === null
? 'border-blue-500 border-2 bg-blue-500/10'
@@ -407,7 +407,7 @@
<!-- Overlay gris para días ya transcurridos -->
<div
v-if="isDiaPasado(cosecha.id, dia - 1)"
class="absolute inset-0 bg-gray-400/15 pointer-events-none"
class="absolute inset-0 bg-[var(--brand-surface)] pointer-events-none"
/>
<!-- Barra horizontal -->
@@ -489,7 +489,7 @@
<!-- Panel de Comparación Detallada (solo visible cuando hay rango seleccionado) -->
<div v-if="rangoSeleccionado" class="mt-6 pt-6 border-t border-[var(--brand-border)]">
<div class="flex items-center gap-2 mb-4">
<UIcon name="i-lucide-bar-chart-3" class="size-5 text-[#c08040]" />
<UIcon name="i-lucide-bar-chart-3" class="size-5 text-[var(--brand-primary-strong)]" />
<h4 class="text-sm font-semibold text-[var(--brand-text)]">
Comparativa del Rango Seleccionado
</h4>
@@ -578,7 +578,7 @@ const cosechasDisponibles = inject<any[]>('cosechasDisponibles', [])
// Obtener configuración de estilos
const estilosGraficas = inject<any>('estilosGraficas', ref({
coloresCosechas: ['#c08040', '#d99a56', '#8b6f47', '#a0826e', '#b89968', '#f0c07c'],
coloresCosechas: ['var(--brand-primary-strong)', 'var(--brand-primary)', '#8b6f47', '#a0826e', '#b89968', 'var(--brand-accent)'],
anchoCelda: 80,
altoCelda: 6,
anchoMaxBarra: 300,

View File

@@ -2,7 +2,7 @@
<UCard class="brand-card border border-transparent">
<template #header>
<div class="flex items-center gap-2">
<UIcon name="i-lucide-layers" class="size-5 text-[#c08040]" />
<UIcon name="i-lucide-layers" class="size-5 text-[var(--brand-primary-strong)]" />
<h3 class="text-base font-semibold text-[var(--brand-text)]">Comparativa por Tipo de Café</h3>
</div>
</template>
@@ -190,7 +190,7 @@ const cosechasDisponibles = inject<any[]>('cosechasDisponibles', [])
// Obtener configuración de estilos
const estilosGraficas = inject<any>('estilosGraficas', ref({
coloresCosechas: ['#c08040', '#d99a56', '#8b6f47', '#a0826e', '#b89968', '#f0c07c']
coloresCosechas: ['var(--brand-primary-strong)', 'var(--brand-primary)', '#8b6f47', '#a0826e', '#b89968', 'var(--brand-accent)']
}))
// Dimensiones del SVG

View File

@@ -2,7 +2,7 @@
<UCard class="brand-card border border-transparent">
<template #header>
<div class="flex items-center gap-2">
<UIcon name="i-lucide-bar-chart-3" class="size-5 text-[#c08040]" />
<UIcon name="i-lucide-bar-chart-3" class="size-5 text-[var(--brand-primary-strong)]" />
<h3 class="text-base font-semibold text-[var(--brand-text)]">Totales por Cosecha</h3>
</div>
</template>
@@ -173,7 +173,7 @@ const cosechasDisponibles = inject<any[]>('cosechasDisponibles', [])
// Obtener configuración de estilos
const estilosGraficas = inject<any>('estilosGraficas', ref({
coloresCosechas: ['#c08040', '#d99a56', '#8b6f47', '#a0826e', '#b89968', '#f0c07c']
coloresCosechas: ['var(--brand-primary-strong)', 'var(--brand-primary)', '#8b6f47', '#a0826e', '#b89968', 'var(--brand-accent)']
}))
// Dimensiones del SVG

View File

@@ -3,7 +3,7 @@
<template #header>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<UIcon name="i-lucide-filter" class="size-4 text-[#c08040]" />
<UIcon name="i-lucide-filter" class="size-4 text-[var(--brand-primary-strong)]" />
<h3 class="text-sm font-semibold text-[var(--brand-text)]">Filtros Activos</h3>
<span class="text-xs text-[var(--brand-text-muted)]">({{ totalFiltros }})</span>
</div>
@@ -160,7 +160,7 @@
<!-- Sin Filtros -->
<div
v-if="noFilter"
class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium bg-gray-500/10 text-gray-400 border border-gray-500/30 transition-all hover:bg-gray-500/20"
class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium bg-gray-500/10 text-[var(--brand-text-muted)] border border-gray-500/30 transition-all hover:bg-gray-500/20"
>
<UIcon name="i-lucide-ban" class="size-3" />
<span>Sin filtros</span>

View File

@@ -35,7 +35,7 @@
'inline-flex items-center gap-1.5 px-2.5 py-1 rounded text-xs font-medium transition-all',
selectedGranularity === option.value
? 'bg-[var(--brand-primary)] text-white shadow-sm'
: 'bg-gray-700/30 text-gray-400 hover:bg-gray-700/50 hover:text-gray-300'
: 'bg-[var(--brand-surface)] text-[var(--brand-text-muted)] hover:bg-[var(--brand-primary)]/10 hover:text-[var(--brand-text)]'
]"
>
<UIcon :name="option.icon" class="w-3.5 h-3.5" />
@@ -148,10 +148,10 @@ interface Props {
const props = defineProps<Props>()
const tipos = [
{ value: 'uva', label: 'Uva', color: '#a855f7', unidad: 'lb' },
{ value: 'oreado', label: 'Oreado', color: '#f97316', unidad: 'qq' },
{ value: 'mojado', label: 'Mojado', color: '#06b6d4', unidad: 'qq' },
{ value: 'verde', label: 'Verde', color: '#22c55e', unidad: 'lb' }
{ value: 'uva', label: 'Uva', color: 'var(--coffee-uva)', unidad: 'lb' },
{ value: 'oreado', label: 'Oreado', color: 'var(--coffee-oreado)', unidad: 'qq' },
{ value: 'mojado', label: 'Mojado', color: 'var(--coffee-mojado)', unidad: 'qq' },
{ value: 'verde', label: 'Verde', color: 'var(--coffee-verde)', unidad: 'lb' }
]
const tiposSeleccionados = ref(['uva'])

View File

@@ -35,7 +35,7 @@
'inline-flex items-center gap-1.5 px-2.5 py-1 rounded text-xs font-medium transition-all',
selectedGranularity === option.value
? 'bg-[var(--brand-primary)] text-white shadow-sm'
: 'bg-gray-700/30 text-gray-400 hover:bg-gray-700/50 hover:text-gray-300'
: 'bg-[var(--brand-surface)] text-[var(--brand-text-muted)] hover:bg-[var(--brand-primary)]/10 hover:text-[var(--brand-text)]'
]"
>
<UIcon :name="option.icon" class="w-3.5 h-3.5" />
@@ -555,9 +555,9 @@ const maxValue = computed(() => {
function getTipoColor(tipo: string) {
const tipoConfig = tipos.find(t => t.value === tipo)
return tipoConfig?.value === 'uva' ? '#a855f7' :
tipoConfig?.value === 'oreado' ? '#f97316' :
tipoConfig?.value === 'mojado' ? '#06b6d4' : '#22c55e'
return tipoConfig?.value === 'uva' ? 'var(--coffee-uva)' :
tipoConfig?.value === 'oreado' ? 'var(--coffee-oreado)' :
tipoConfig?.value === 'mojado' ? 'var(--coffee-mojado)' : 'var(--coffee-verde)'
}
function getPointsPagadoForTipo(tipo: string) {

View File

@@ -35,7 +35,7 @@
'inline-flex items-center gap-1.5 px-2.5 py-1 rounded text-xs font-medium transition-all',
selectedGranularity === option.value
? 'bg-[var(--brand-primary)] text-white shadow-sm'
: 'bg-gray-700/30 text-gray-400 hover:bg-gray-700/50 hover:text-gray-300'
: 'bg-[var(--brand-surface)] text-[var(--brand-text-muted)] hover:bg-[var(--brand-primary)]/10 hover:text-[var(--brand-text)]'
]"
>
<UIcon :name="option.icon" class="w-3.5 h-3.5" />
@@ -132,10 +132,10 @@ interface Props {
const props = defineProps<Props>()
const tipos = [
{ value: 'uva', label: 'Uva', color: '#a855f7', unidad: 'lb' },
{ value: 'oreado', label: 'Oreado', color: '#f97316', unidad: 'qq' },
{ value: 'mojado', label: 'Mojado', color: '#06b6d4', unidad: 'qq' },
{ value: 'verde', label: 'Verde', color: '#22c55e', unidad: 'lb' }
{ value: 'uva', label: 'Uva', color: 'var(--coffee-uva)', unidad: 'lb' },
{ value: 'oreado', label: 'Oreado', color: 'var(--coffee-oreado)', unidad: 'qq' },
{ value: 'mojado', label: 'Mojado', color: 'var(--coffee-mojado)', unidad: 'qq' },
{ value: 'verde', label: 'Verde', color: 'var(--coffee-verde)', unidad: 'lb' }
]
const tiposSeleccionados = ref(['uva'])

View File

@@ -35,7 +35,7 @@
'inline-flex items-center gap-1.5 px-2.5 py-1 rounded text-xs font-medium transition-all',
selectedGranularity === option.value
? 'bg-[var(--brand-primary)] text-white shadow-sm'
: 'bg-gray-700/30 text-gray-400 hover:bg-gray-700/50 hover:text-gray-300'
: 'bg-[var(--brand-surface)] text-[var(--brand-text-muted)] hover:bg-[var(--brand-primary)]/10 hover:text-[var(--brand-text)]'
]"
>
<UIcon :name="option.icon" class="w-3.5 h-3.5" />
@@ -137,10 +137,10 @@ interface Props {
const props = defineProps<Props>()
const tipos = [
{ value: 'uva', label: 'Uva', color: '#a855f7' },
{ value: 'oreado', label: 'Oreado', color: '#f97316' },
{ value: 'mojado', label: 'Mojado', color: '#06b6d4' },
{ value: 'verde', label: 'Verde', color: '#22c55e' }
{ value: 'uva', label: 'Uva', color: 'var(--coffee-uva)' },
{ value: 'oreado', label: 'Oreado', color: 'var(--coffee-oreado)' },
{ value: 'mojado', label: 'Mojado', color: 'var(--coffee-mojado)' },
{ value: 'verde', label: 'Verde', color: 'var(--coffee-verde)' }
]
const tiposSeleccionados = ref(['uva', 'verde', 'oreado', 'mojado'])

View File

@@ -5,7 +5,7 @@
</template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-purple-900/40 text-purple-300">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-purple-900/40 text-purple-300">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Total qq Secos por Vender</span>
<div class="flex items-baseline gap-2">
@@ -14,7 +14,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-purple-800/40 text-purple-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-purple-800/40 text-purple-400">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Precio de Venta Promedio por qq</span>
<div class="flex items-baseline gap-2">
@@ -22,7 +22,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-purple-700/40 text-purple-500">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-purple-700/40 text-purple-500">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Precio de Compra Promedio por qq</span>
<div class="flex items-baseline gap-2">
@@ -30,7 +30,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] text-purple-600" :class="data.margen_ganancia_por_qq > 0 ? 'border-purple-600/40' : 'border-red-600/40'">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] text-purple-600" :class="data.margen_ganancia_por_qq > 0 ? 'border-purple-600/40' : 'border-red-600/40'">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Margen de Ganancia por qq</span>
<div class="flex items-baseline gap-2">

View File

@@ -21,10 +21,10 @@
</div>
<div v-if="rankingStats.clientesAbajo > 0" class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-gray-500/10 border border-gray-500/30">
<UIcon name="i-lucide-arrow-down" class="w-3 h-3 text-gray-400" />
<UIcon name="i-lucide-arrow-down" class="w-3 h-3 text-[var(--brand-text-muted)]" />
<span class="text-gray-300 font-semibold">{{ rankingStats.clientesAbajo }}</span>
<span class="text-[var(--brand-text-muted)]">abajo</span>
<span class="text-gray-400 font-mono">({{ rankingStats.porcentajeAbajo.toFixed(1) }}%)</span>
<span class="text-[var(--brand-text-muted)] font-mono">({{ rankingStats.porcentajeAbajo.toFixed(1) }}%)</span>
</div>
<div class="inline-flex items-center gap-1.5 px-2 py-1 rounded bg-[var(--brand-primary)]/10 border border-[var(--brand-primary)]/30">
@@ -332,7 +332,7 @@ function getRankingBadgeClass(index: number): string {
if (normalizedDistance < 0.2) {
return `${baseClass} bg-gray-400/20 text-gray-300 border border-gray-400/40`
} else if (normalizedDistance < 0.4) {
return `${baseClass} bg-gray-500/15 text-gray-400 border border-gray-500/35`
return `${baseClass} bg-gray-500/15 text-[var(--brand-text-muted)] border border-gray-500/35`
} else if (normalizedDistance < 0.6) {
return `${baseClass} bg-gray-600/10 text-gray-500 border border-gray-600/25`
} else if (normalizedDistance < 0.8) {

View File

@@ -11,7 +11,7 @@
Totales Generales (Pagado + Pendiente)
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-red-600/40 text-red-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-red-600/40 text-red-400">
<div class="flex items-center justify-between mb-1">
<span class="text-xs uppercase tracking-wide opacity-80">Total Uva Ingresada</span>
<UButton
@@ -54,7 +54,7 @@
Solo Pagados
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-red-600/40 text-red-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-red-600/40 text-red-400">
<div class="flex items-center justify-between mb-1">
<span class="text-xs uppercase tracking-wide opacity-80">Total Uva Pagada</span>
<UButton
@@ -97,7 +97,7 @@
Inventario en Depósito
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-red-600/40 text-red-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-red-600/40 text-red-400">
<div class="flex items-center justify-between mb-1">
<span class="text-xs uppercase tracking-wide opacity-80">Total Uva en Depósito</span>
<UButton

View File

@@ -40,7 +40,7 @@
Precios Promedio Ponderados
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-red-600/40 text-red-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-red-600/40 text-red-400">
<div class="flex items-center justify-between mb-1">
<span class="text-xs uppercase tracking-wide opacity-80">Precio Promedio Ponderado Uva</span>
<UButton

View File

@@ -5,7 +5,7 @@
</template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-green-700/40 text-green-300">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-green-700/40 text-green-300">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Total Lb Neto de Verde</span>
<div class="flex items-baseline gap-2">
@@ -14,7 +14,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-green-600/40 text-green-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-green-600/40 text-green-400">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Precio Promedio Ponderado Pagado</span>
<div class="flex items-baseline gap-2">
@@ -23,7 +23,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-green-500/40 text-green-500">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-green-500/40 text-green-500">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Total Lb Neto de Verde en Depósito</span>
<div class="flex items-baseline gap-2">
@@ -32,7 +32,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-emerald-600/40 text-emerald-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-emerald-600/40 text-emerald-400">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Inversión en Verde Hasta la Fecha</span>
<div class="flex items-baseline gap-2">
@@ -40,7 +40,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-lime-600/40 text-lime-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-lime-600/40 text-lime-400">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Inversión Restante a Realizar en Verde</span>
<div class="flex items-baseline gap-2">
@@ -48,7 +48,7 @@
</div>
</div>
</div>
<div class="p-4 rounded-lg border transition-all bg-[#1c140c] border-teal-600/40 text-teal-400">
<div class="p-4 rounded-lg border transition-all bg-[var(--brand-surface)] border-teal-600/40 text-teal-400">
<div class="flex flex-col">
<span class="text-xs uppercase tracking-wide opacity-80 mb-1">Total Lb Neto Comprado de Verde</span>
<div class="flex items-baseline gap-2">

View File

@@ -350,8 +350,8 @@ function formatCellValue(value: unknown, column: string, row: any, depth: number
if (column === 'created_at') {
return h('div', { class: 'flex flex-col gap-1' }, [
h('span', { class: 'font-semibold text-yellow-500' }, row.name),
row.ubicacion && h('span', { class: 'text-xs text-gray-400' }, `📍 ${row.ubicacion}`),
row.telefono && h('span', { class: 'text-xs text-gray-400' }, `📞 ${row.telefono}`)
row.ubicacion && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `📍 ${row.ubicacion}`),
row.telefono && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `📞 ${row.telefono}`)
])
}
if (column === 'tipo' && row.cedula) {
@@ -371,7 +371,7 @@ function formatCellValue(value: unknown, column: string, row: any, depth: number
})
: h(UIcon, {
name: 'i-lucide-user',
class: 'text-gray-400 w-5 h-5'
class: 'text-[var(--brand-text-muted)] w-5 h-5'
})
}
}
@@ -451,21 +451,21 @@ function formatCellValue(value: unknown, column: string, row: any, depth: number
if (column === 'lectorTarjeta' && typeof value === 'boolean') {
return h(UIcon, {
name: value ? 'i-lucide-credit-card' : 'i-lucide-ban',
class: value ? 'text-green-600 w-5 h-5' : 'text-gray-400 w-5 h-5'
class: value ? 'text-green-600 w-5 h-5' : 'text-[var(--brand-text-muted)] w-5 h-5'
})
}
if (column === 'traido' && typeof value === 'boolean') {
return h(UIcon, {
name: value ? 'i-lucide-package-check' : 'i-lucide-package-x',
class: value ? 'text-blue-600 w-5 h-5' : 'text-gray-400 w-5 h-5'
class: value ? 'text-blue-600 w-5 h-5' : 'text-[var(--brand-text-muted)] w-5 h-5'
})
}
if (column === 'autoPeso' && typeof value === 'boolean') {
return h(UIcon, {
name: value ? 'i-lucide-scale-3d' : 'i-lucide-minus-circle',
class: value ? 'text-purple-600 w-5 h-5' : 'text-gray-400 w-5 h-5'
class: value ? 'text-purple-600 w-5 h-5' : 'text-[var(--brand-text-muted)] w-5 h-5'
})
}

View File

@@ -164,9 +164,9 @@ const columns = computed((): TableColumn<IngresoWithChildren | ClienteWithChildr
if (isCliente) {
return h('div', { class: 'flex flex-col gap-1' }, [
h('span', { class: 'font-semibold text-yellow-500' }, original.name),
original.ubicacion && h('span', { class: 'text-xs text-gray-400' }, `📍 ${original.ubicacion}`),
original.telefono && h('span', { class: 'text-xs text-gray-400' }, `📞 ${original.telefono}`),
original.cedula && h('span', { class: 'text-xs text-gray-400' }, `🆔 ${original.cedula}`)
original.ubicacion && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `📍 ${original.ubicacion}`),
original.telefono && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `📞 ${original.telefono}`),
original.cedula && h('span', { class: 'text-xs text-[var(--brand-text-muted)]' }, `🆔 ${original.cedula}`)
])
}

View File

@@ -41,7 +41,7 @@
<summary class="cursor-pointer text-sm font-medium text-[var(--brand-primary)]">
Ver SQL
</summary>
<pre class="mt-2 p-3 rounded-lg border border-[#3a2a16] bg-[#1c140c] text-xs overflow-x-auto whitespace-pre-wrap break-words text-[var(--brand-text)]">{{ card.dataset_query.native.query }}</pre>
<pre class="mt-2 p-3 rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] text-xs overflow-x-auto whitespace-pre-wrap break-words text-[var(--brand-text)]">{{ card.dataset_query.native.query }}</pre>
</details>
</div>
@@ -54,7 +54,7 @@
<UIcon name="i-heroicons-chevron-down-20-solid" class="w-4 h-4 transition-transform group-open:rotate-180" />
</summary>
<div class="mt-3 p-4 rounded-lg border border-[#3a2a16] bg-[#1c140c] space-y-3">
<div class="mt-3 p-4 rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] space-y-3">
<div v-for="(param, key) in parameterValues" :key="key" class="flex flex-col gap-1">
<label class="text-xs font-medium text-[var(--brand-text-muted)]">
{{ getParameterLabel(key) }}
@@ -104,7 +104,7 @@
<UButton
@click="executeQuery"
:loading="executing"
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c] disabled:opacity-50 disabled:cursor-not-allowed' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)] disabled:opacity-50 disabled:cursor-not-allowed' }"
size="sm"
>
Ejecutar Query
@@ -154,7 +154,7 @@
</div>
<!-- Empty State -->
<div v-if="!queryResult.data?.rows || queryResult.data.rows.length === 0" class="p-8 text-center rounded-lg border border-[#3a2a16] bg-[#1c140c]">
<div v-if="!queryResult.data?.rows || queryResult.data.rows.length === 0" class="p-8 text-center rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)]">
<div class="mx-auto w-16 h-16 mb-4 flex items-center justify-center bg-[#3a2a16] rounded-full">
<svg class="w-8 h-8 text-[var(--brand-text-muted)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
@@ -167,9 +167,9 @@
<!-- Data Display -->
<div v-else>
<!-- Table View -->
<div v-if="queryResult.data.cols && queryResult.data.rows" class="overflow-x-auto mb-4 rounded-lg border border-[#3a2a16]">
<div v-if="queryResult.data.cols && queryResult.data.rows" class="overflow-x-auto mb-4 rounded-lg border border-[var(--brand-border)]">
<table class="min-w-full divide-y divide-[var(--brand-border)]">
<thead class="bg-[#1c140c]">
<thead class="bg-[var(--brand-surface)]">
<tr>
<th
v-for="col in queryResult.data.cols"
@@ -200,7 +200,7 @@
<span>Ver JSON completo</span>
<UIcon name="i-heroicons-chevron-down-20-solid" class="w-4 h-4 transition-transform group-open:rotate-180" />
</summary>
<pre class="mt-2 p-3 rounded-lg border border-[#3a2a16] bg-[#1c140c] text-xs whitespace-pre-wrap break-words text-[var(--brand-text)]">{{ JSON.stringify(queryResult.data, null, 2) }}</pre>
<pre class="mt-2 p-3 rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] text-xs whitespace-pre-wrap break-words text-[var(--brand-text)]">{{ JSON.stringify(queryResult.data, null, 2) }}</pre>
</details>
</div>
</div>

View File

@@ -8,7 +8,7 @@
icon="i-heroicons-magnifying-glass"
class="flex-1"
:ui="{
base: 'bg-[var(--brand-bg)] text-[var(--brand-text)] border border-[var(--brand-border)] focus:ring-2 focus:ring-[#c08040] focus:border-[#c08040]',
base: 'bg-[var(--brand-bg)] text-[var(--brand-text)] border border-[var(--brand-border)] focus:ring-2 focus:ring-[var(--brand-primary-strong)] focus:border-[var(--brand-primary-strong)]',
placeholder: 'placeholder-[var(--brand-text-muted)]',
icon: {
base: 'text-[var(--brand-text-muted)]'
@@ -58,7 +58,7 @@
<UButton
@click.stop="executeCard(row)"
:loading="executingCards.has(row.id)"
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c] disabled:opacity-50 disabled:cursor-not-allowed' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)] disabled:opacity-50 disabled:cursor-not-allowed' }"
size="xs"
>
Ejecutar
@@ -120,7 +120,7 @@
</div>
<!-- Empty State -->
<div v-if="!currentResult.data?.rows || currentResult.data.rows.length === 0" class="p-8 text-center rounded-lg border border-[#3a2a16] bg-[#1c140c]">
<div v-if="!currentResult.data?.rows || currentResult.data.rows.length === 0" class="p-8 text-center rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)]">
<div class="mx-auto w-16 h-16 mb-4 flex items-center justify-center bg-[#3a2a16] rounded-full">
<svg class="w-8 h-8 text-[var(--brand-text-muted)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
@@ -132,7 +132,7 @@
<!-- Data Display -->
<div v-else class="overflow-x-auto max-h-96">
<pre class="p-3 rounded-lg border border-[#3a2a16] bg-[#1c140c] text-xs whitespace-pre-wrap break-words text-[var(--brand-text)]">{{ JSON.stringify(currentResult.data, null, 2) }}</pre>
<pre class="p-3 rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] text-xs whitespace-pre-wrap break-words text-[var(--brand-text)]">{{ JSON.stringify(currentResult.data, null, 2) }}</pre>
</div>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<div class="bg-[#1c140c] rounded-lg p-4 border-l-4" :class="borderColor">
<div class="bg-[var(--brand-surface)] rounded-lg p-4 border-l-4" :class="borderColor">
<h3 class="text-lg font-semibold mb-3 capitalize text-[var(--brand-text)]">{{ title }}</h3>
<div class="space-y-2">
<div class="flex justify-between items-center">
@@ -10,7 +10,7 @@
<span class="text-[var(--brand-text-muted)] text-sm">Precio promedio:</span>
<span class="font-medium text-[var(--brand-text)]">{{ formatCurrency(metrics.value.precioPromedio) }}</span>
</div>
<div class="flex justify-between items-center pt-2 border-t border-[#3a2a16]">
<div class="flex justify-between items-center pt-2 border-t border-[var(--brand-border)]">
<span class="text-[var(--brand-text)] font-semibold">Total cobrado:</span>
<span class="font-bold text-white-400">{{ formatCurrency(metrics.value.totalCobrado) }}</span>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] p-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] p-4">
<div class="flex items-center justify-between mb-3">
<h3 class="text-lg font-semibold text-[var(--brand-text)]">{{ title }}</h3>
<div :class="colorClasses" class="w-3 h-3 rounded-full"></div>
@@ -27,7 +27,7 @@
</span>
</div>
<div class="flex justify-between items-center pt-2 border-t border-[#3a2a16]">
<div class="flex justify-between items-center pt-2 border-t border-[var(--brand-border)]">
<span class="text-xs text-[var(--brand-text-muted)]">Registros</span>
<span class="text-xs font-medium text-[var(--brand-text)]">
{{ data.num_registros }}

View File

@@ -3,7 +3,7 @@
<template #header>
<div class="flex items-center justify-between">
<h2 class="text-xl font-bold brand-section-title">Rechazos y Subproductos</h2>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-2">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-2">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Total Rechazos</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">{{ formatCurrency(totalRechazos) }}</div>
</div>

View File

@@ -37,20 +37,20 @@ const errorMessage = computed(() => {
<!-- Error Code -->
<div>
<h1 class="text-6xl font-bold text-gray-900 dark:text-white mb-2">
<h1 class="text-6xl font-bold text-[var(--brand-text)] mb-2">
{{ error.statusCode || '500' }}
</h1>
<h2 class="text-2xl font-semibold text-gray-700 dark:text-gray-300 mb-3">
<h2 class="text-2xl font-semibold text-[var(--brand-text)] mb-3">
{{ errorMessage.title }}
</h2>
<p class="text-gray-600 dark:text-gray-400">
<p class="text-[var(--brand-text-muted)]">
{{ errorMessage.description }}
</p>
</div>
<!-- Error Details (dev mode) -->
<div v-if="error.message && $config.public.dev" class="mt-4 p-4 bg-gray-50 dark:bg-gray-900 rounded-lg text-left">
<p class="text-xs font-mono text-gray-600 dark:text-gray-400 break-all">
<div v-if="error.message && $config.public.dev" class="mt-4 p-4 bg-[var(--brand-surface)] rounded-lg text-left border border-[var(--brand-border)]">
<p class="text-xs font-mono text-[var(--brand-text-muted)] break-all">
{{ error.message }}
</p>
</div>

View File

@@ -60,7 +60,7 @@
<!-- Loading State -->
<UCard v-if="loadingData" class="brand-card border border-transparent">
<div class="flex items-center justify-center gap-3 py-10 text-[var(--brand-text-muted)]">
<span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[#c08040] border-t-transparent align-middle" aria-hidden="true" />
<span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[var(--brand-primary-strong)] border-t-transparent align-middle" aria-hidden="true" />
<span class="text-sm uppercase tracking-[0.3em]">Cargando datos...</span>
</div>
</UCard>

View File

@@ -4,7 +4,7 @@
<UCard v-if="loading && !data" class="brand-card border border-transparent">
<div class="flex flex-col items-center justify-center gap-4 py-10 text-[var(--brand-text-muted)]">
<div class="flex items-center gap-3">
<span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[#c08040] border-t-transparent align-middle" aria-hidden="true" />
<span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[var(--brand-primary-strong)] border-t-transparent align-middle" aria-hidden="true" />
<span class="text-sm uppercase tracking-[0.3em]">Cargando datos...</span>
</div>
</div>
@@ -134,7 +134,7 @@
<UButton
:loading="loading"
:disabled="loading"
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c] disabled:opacity-50 disabled:cursor-not-allowed' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)] disabled:opacity-50 disabled:cursor-not-allowed' }"
size="sm"
@click="loadData"
>
@@ -150,8 +150,8 @@
<!-- Mensaje de bienvenida -->
<UCard class="brand-card border border-transparent">
<div class="flex flex-col items-center justify-center gap-4 py-16 text-center">
<div class="rounded-full bg-[#c08040]/10 p-6">
<UIcon name="i-lucide-file-text" class="w-12 h-12 text-[#c08040]" />
<div class="rounded-full bg-[var(--brand-primary-strong)]/10 p-6">
<UIcon name="i-lucide-file-text" class="w-12 h-12 text-[var(--brand-primary-strong)]" />
</div>
<div class="flex flex-col gap-2">
<h3 class="text-lg font-semibold text-[var(--brand-text)]">
@@ -308,7 +308,7 @@
:ui="{
base: hasPendingChanges
? 'bg-yellow-500 text-black border border-yellow-600 hover:bg-yellow-400 hover:border-yellow-500 disabled:opacity-50 disabled:cursor-not-allowed'
: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c] disabled:opacity-50 disabled:cursor-not-allowed'
: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)] disabled:opacity-50 disabled:cursor-not-allowed'
}"
size="sm"
@click="loadData"
@@ -329,25 +329,25 @@
</template>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Ingresos Filtrados</div>
<div class="text-2xl font-bold text-[var(--brand-primary)]">
{{ data.contadores.ingresos_filtrados || 0 }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Total Ingresos</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ data.contadores.total_ingresos || 0 }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Clientes Activos</div>
<div class="text-2xl font-bold text-[var(--brand-primary)]">
{{ data.contadores.clientes_con_ingresos_filtrados || 0 }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-4 py-3">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Total Clientes</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ data.contadores.total_clientes || 0 }}
@@ -422,7 +422,7 @@
<div v-if="data.listaIngresos && data.listaIngresos.length > 0" class="overflow-x-auto max-h-[600px] overflow-y-auto">
<table class="w-full text-sm">
<thead class="sticky top-0 bg-[#1c140c] z-10">
<thead class="sticky top-0 bg-[var(--brand-surface)] z-10">
<tr class="border-b border-[var(--brand-border)]">
<th class="text-left py-3 px-2 font-semibold text-[var(--brand-text-muted)]">ID</th>
<th class="text-left py-3 px-2 font-semibold text-[var(--brand-text-muted)]">Fecha</th>
@@ -438,7 +438,7 @@
<tr
v-for="ingreso in data.listaIngresos"
:key="ingreso.id"
class="border-b border-[var(--brand-border)]/50 hover:bg-[#1c140c] transition-colors"
class="border-b border-[var(--brand-border)]/50 hover:bg-[var(--brand-surface)] transition-colors"
>
<td class="py-2 px-2 text-[var(--brand-text-muted)]">{{ ingreso.id }}</td>
<td class="py-2 px-2 text-[var(--brand-text)]">
@@ -525,7 +525,7 @@
<div
v-for="(cliente, index) in data.listaClientes.slice(0, 10)"
:key="cliente.cliente_id"
class="flex items-center gap-3 p-3 rounded-lg border border-[var(--brand-border)] hover:border-[#c08040]/50 transition-colors"
class="flex items-center gap-3 p-3 rounded-lg border border-[var(--brand-border)] hover:border-[var(--brand-primary)]/50 transition-colors"
>
<div class="flex items-center justify-center w-8 h-8 rounded-full bg-[var(--brand-primary)]/20 text-[var(--brand-primary)] font-bold text-sm">
{{ index + 1 }}
@@ -593,7 +593,7 @@
<!-- Tabla de serie temporal -->
<div class="overflow-x-auto max-h-96">
<table class="w-full text-xs">
<thead class="sticky top-0 bg-[#1c140c]">
<thead class="sticky top-0 bg-[var(--brand-surface)]">
<tr class="border-b border-[var(--brand-border)]">
<th class="text-left py-2 px-2 font-semibold text-[var(--brand-text-muted)]">Fecha</th>
<th class="text-left py-2 px-2 font-semibold text-[var(--brand-text-muted)]">Tipo</th>
@@ -609,7 +609,7 @@
<tr
v-for="(punto, idx) in data.serieTemporal"
:key="`${punto.fecha_grupo}-${punto.tipo}-${punto.estado}-${idx}`"
class="border-b border-[var(--brand-border)]/30 hover:bg-[#1c140c] transition-colors"
class="border-b border-[var(--brand-border)]/30 hover:bg-[var(--brand-surface)] transition-colors"
>
<td class="py-2 px-2 text-[var(--brand-text)]">
{{ punto.fecha_grupo ? new Date(punto.fecha_grupo).toLocaleDateString('es-ES') : '-' }}

View File

@@ -5,7 +5,7 @@
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-4">
<div class="flex-1">
<h1 class="text-2xl sm:text-3xl font-bold">Metabase Debug</h1>
<p class="text-sm sm:text-base text-gray-600 dark:text-gray-400 mt-1">
<p class="text-sm sm:text-base text-gray-600 dark:text-[var(--brand-text-muted)] mt-1">
Herramienta de debugging para queries de Metabase
</p>
</div>
@@ -32,27 +32,27 @@
</template>
<div class="grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-3 sm:gap-4">
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Total Cards</div>
<div class="text-3xl font-bold text-[var(--brand-primary)]">{{ cards.length }}</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">SQL Nativo</div>
<div class="text-3xl font-bold text-[var(--brand-primary)]">{{ nativeQueries }}</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Query Builder</div>
<div class="text-3xl font-bold text-green-400">{{ queryBuilderQueries }}</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Queries Panorama</div>
<div class="text-3xl font-bold" :class="panoramaQueries.length === 9 ? 'text-green-400' : 'text-orange-400'">{{ panoramaQueries.length }}/9</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Queries Informe</div>
<div class="text-3xl font-bold" :class="informeQueries.length === 8 ? 'text-green-400' : 'text-orange-400'">{{ informeQueries.length }}/8</div>
</div>
@@ -75,11 +75,11 @@
:items="tabs"
:ui="{
root: 'space-y-4',
list: 'bg-[#1c140c]',
indicator: 'bg-[#c08040] z-10',
trigger: 'relative data-[state=active]:text-[#1b1209] data-[state=active]:hover:text-black data-[state=inactive]:text-[var(--brand-text-muted)] data-[state=inactive]:bg-transparent data-[state=inactive]:hover:text-[var(--brand-text)] data-[state=inactive]:hover:bg-[#2a1f14]/50 focus-visible:ring-2 focus-visible:ring-[#c08040] transition-colors duration-200',
list: 'bg-[var(--brand-surface)]',
indicator: 'bg-[var(--brand-primary-strong)] z-10',
trigger: 'relative data-[state=active]:text-[var(--brand-bg)] data-[state=active]:hover:text-black data-[state=inactive]:text-[var(--brand-text-muted)] data-[state=inactive]:bg-transparent data-[state=inactive]:hover:text-[var(--brand-text)] data-[state=inactive]:hover:bg-[#2a1f14]/50 focus-visible:ring-2 focus-visible:ring-[var(--brand-primary-strong)] transition-colors duration-200',
label: 'font-medium text-sm relative z-20',
leadingIcon: 'relative z-20 data-[state=active]:text-[#1b1209] data-[state=inactive]:text-[var(--brand-text-muted)] transition-colors duration-200',
leadingIcon: 'relative z-20 data-[state=active]:text-[var(--brand-bg)] data-[state=inactive]:text-[var(--brand-text-muted)] transition-colors duration-200',
content: 'py-4'
}"
>

View File

@@ -65,7 +65,7 @@ const mockNotifications = [
<h2 class="text-3xl font-bold text-gray-900 dark:text-white mb-2">
Página en construcción
</h2>
<p class="text-lg text-gray-600 dark:text-gray-400 mb-4">
<p class="text-lg text-gray-600 dark:text-[var(--brand-text-muted)] mb-4">
Estamos trabajando en esta funcionalidad
</p>
<p class="text-sm text-gray-500 dark:text-gray-500 max-w-md mx-auto">
@@ -127,7 +127,7 @@ const mockNotifications = [
<h4 :class="[
'font-semibold text-sm',
notification.read
? 'text-gray-600 dark:text-gray-400'
? 'text-gray-600 dark:text-[var(--brand-text-muted)]'
: 'text-gray-900 dark:text-white'
]">
{{ notification.title }}
@@ -136,7 +136,7 @@ const mockNotifications = [
hace {{ notification.time }}
</span>
</div>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
<p class="text-sm text-gray-600 dark:text-[var(--brand-text-muted)] mt-1">
{{ notification.message }}
</p>
</div>

View File

@@ -4,7 +4,7 @@
<UCard v-if="loading && !data" class="brand-card border border-transparent">
<div class="flex flex-col items-center justify-center gap-4 py-10 text-[var(--brand-text-muted)]">
<div class="flex items-center gap-3">
<span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[#c08040] border-t-transparent align-middle" aria-hidden="true" />
<span class="inline-flex h-8 w-8 animate-spin rounded-full border-2 border-[var(--brand-primary-strong)] border-t-transparent align-middle" aria-hidden="true" />
<span class="text-sm uppercase tracking-[0.3em]">Cargando datos...</span>
</div>
</div>
@@ -65,7 +65,7 @@
<UButton
:loading="loading"
:disabled="loading"
:ui="{ base: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c] disabled:opacity-50 disabled:cursor-not-allowed' }"
:ui="{ base: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)] disabled:opacity-50 disabled:cursor-not-allowed' }"
size="sm"
@click="loadData"
>
@@ -81,8 +81,8 @@
<!-- Mensaje de bienvenida -->
<UCard class="brand-card border border-transparent">
<div class="flex flex-col items-center justify-center gap-4 py-16 text-center">
<div class="rounded-full bg-[#c08040]/10 p-6">
<UIcon name="i-lucide-bar-chart-3" class="w-12 h-12 text-[#c08040]" />
<div class="rounded-full bg-[var(--brand-primary-strong)]/10 p-6">
<UIcon name="i-lucide-bar-chart-3" class="w-12 h-12 text-[var(--brand-primary-strong)]" />
</div>
<div class="flex flex-col gap-2">
<h3 class="text-lg font-semibold text-[var(--brand-text)]">
@@ -170,7 +170,7 @@
:ui="{
base: hasPendingChanges
? 'bg-yellow-500 text-black border border-yellow-600 hover:bg-yellow-400 hover:border-yellow-500 disabled:opacity-50 disabled:cursor-not-allowed'
: 'bg-[#c08040] text-[#1b1209] border border-[#d99a56] hover:bg-[#d99a56] hover:border-[#f0c07c] disabled:opacity-50 disabled:cursor-not-allowed'
: 'bg-[var(--brand-primary-strong)] text-[var(--brand-bg)] border border-[var(--brand-primary)] hover:bg-[var(--brand-primary)] hover:border-[var(--brand-accent)] disabled:opacity-50 disabled:cursor-not-allowed'
}"
size="sm"
@click="loadData"
@@ -216,19 +216,19 @@
</template>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Total Invertido en Café</div>
<div class="text-3xl font-bold text-[var(--brand-primary)]">
{{ formatCurrency(data.financieros.total_invertido_cafe) }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Total Rechazos</div>
<div class="text-3xl font-bold text-green-400">
{{ formatCurrency(data.financieros.total_rechazos) }}
</div>
</div>
<div class="rounded-lg border border-[#3a2a16] bg-[#1c140c] px-6 py-4">
<div class="rounded-lg border border-[var(--brand-border)] bg-[var(--brand-surface)] px-6 py-4">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-1">Balance Neto</div>
<div class="text-3xl font-bold text-[var(--brand-text)]">
{{ formatCurrency(data.financieros.balance_neto) }}

View File

@@ -25,7 +25,7 @@ const { user, isAuthenticated } = useAuthentik()
<h2 class="text-3xl font-bold text-gray-900 dark:text-white mb-2">
Página en construcción
</h2>
<p class="text-lg text-gray-600 dark:text-gray-400 mb-4">
<p class="text-lg text-gray-600 dark:text-[var(--brand-text-muted)] mb-4">
Estamos trabajando en esta funcionalidad
</p>
<p class="text-sm text-gray-500 dark:text-gray-500 max-w-md mx-auto">

View File

@@ -276,7 +276,7 @@ watch(() => theme.value, (newTheme) => {
/>
<UInput
v-model="theme.bg"
placeholder="#14100b"
placeholder="var(--brand-bg)"
class="flex-1"
/>
</div>
@@ -354,7 +354,7 @@ watch(() => theme.value, (newTheme) => {
/>
<UInput
v-model="theme.primaryStrong"
placeholder="#c08040"
placeholder="var(--brand-primary-strong)"
class="flex-1"
/>
</div>
@@ -474,7 +474,7 @@ watch(() => theme.value, (newTheme) => {
<UTextarea
v-model="importJsonInput"
:rows="10"
placeholder='{\n "bg": "#14100b",\n "surface": "#1f180f",\n ...\n}'
placeholder='{\n "bg": "var(--brand-bg)",\n "surface": "#1f180f",\n ...\n}'
class="font-mono text-xs"
/>
</div>