Files
analiticaNucleo/nuxt4-app/app/components/comercios/TotalesPesoComercio.vue
josedario87 400b0ae5b4
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 53s
Refactor: Reorganizar componentes de comercios en carpeta específica
- Mover TotalesMonetariosComercio a components/comercios/
- Mover TotalesPesoComercio a components/comercios/
- Mover TablaComerciosResumen a components/comercios/
- Actualizar referencias en informe-comercios.vue con prefijos de carpeta
2025-11-06 13:46:18 -06:00

238 lines
10 KiB
Vue

<template>
<UCard class="brand-card border border-transparent">
<template #header>
<div class="flex items-center justify-between">
<h2 class="text-xl font-bold brand-section-title">Totales de Peso</h2>
<div class="flex items-center gap-2">
<UButton
size="xs"
color="gray"
variant="soft"
icon="i-lucide-copy"
@click="copiarTexto"
>
Copiar Texto
</UButton>
<UButton
size="xs"
color="gray"
variant="soft"
icon="i-lucide-braces"
@click="copiarJSON"
>
Copiar JSON
</UButton>
</div>
</div>
</template>
<div class="space-y-6">
<!-- Totales por Tipo de Café -->
<div>
<h3 class="text-lg font-semibold text-[var(--brand-primary)] mb-3">Quintales Seco por Tipo</h3>
<div class="grid grid-cols-1 md:grid-cols-5 gap-3">
<!-- Uva -->
<div class="rounded-lg border border-[var(--brand-border)] px-4 py-3"
style="background: linear-gradient(135deg, var(--brand-surface) 0%, rgba(139, 69, 19, 0.1) 100%);">
<div class="flex items-center gap-2 mb-2">
<div class="w-3 h-3 rounded-full" style="background-color: var(--coffee-uva, #8B4513);"></div>
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Uva</div>
</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatNumber(data.qq_seco_uva) }}
</div>
<div class="text-xs text-[var(--brand-text-muted)] mt-1">
QQ Seco
</div>
</div>
<!-- Mojado -->
<div class="rounded-lg border border-[var(--brand-border)] px-4 py-3"
style="background: linear-gradient(135deg, var(--brand-surface) 0%, rgba(30, 144, 255, 0.1) 100%);">
<div class="flex items-center gap-2 mb-2">
<div class="w-3 h-3 rounded-full" style="background-color: var(--coffee-mojado, #1E90FF);"></div>
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Mojado</div>
</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatNumber(data.qq_seco_mojado) }}
</div>
<div class="text-xs text-[var(--brand-text-muted)] mt-1">
QQ Seco
</div>
</div>
<!-- Oreado -->
<div class="rounded-lg border border-[var(--brand-border)] px-4 py-3"
style="background: linear-gradient(135deg, var(--brand-surface) 0%, rgba(255, 140, 0, 0.1) 100%);">
<div class="flex items-center gap-2 mb-2">
<div class="w-3 h-3 rounded-full" style="background-color: var(--coffee-oreado, #FF8C00);"></div>
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Oreado</div>
</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatNumber(data.qq_seco_oreado) }}
</div>
<div class="text-xs text-[var(--brand-text-muted)] mt-1">
QQ Seco
</div>
</div>
<!-- Verde -->
<div class="rounded-lg border border-[var(--brand-border)] px-4 py-3"
style="background: linear-gradient(135deg, var(--brand-surface) 0%, rgba(34, 139, 34, 0.1) 100%);">
<div class="flex items-center gap-2 mb-2">
<div class="w-3 h-3 rounded-full" style="background-color: var(--coffee-verde, #228B22);"></div>
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide">Verde</div>
</div>
<div class="text-2xl font-bold text-[var(--brand-text)]">
{{ formatNumber(data.qq_verde) }}
</div>
<div class="text-xs text-[var(--brand-text-muted)] mt-1">
QQ
</div>
</div>
<!-- Total -->
<div class="rounded-lg border-2 border-[var(--brand-primary)] bg-[var(--brand-surface)] px-4 py-3">
<div class="text-xs text-[var(--brand-text-muted)] uppercase tracking-wide mb-2">Total</div>
<div class="text-2xl font-bold text-[var(--brand-primary)]">
{{ formatNumber(data.total_qq_seco) }}
</div>
<div class="text-xs text-[var(--brand-text-muted)] mt-1">
QQ Seco
</div>
</div>
</div>
</div>
<!-- Visualización de Distribución por Tipo -->
<div v-if="showChart" class="mt-6">
<h4 class="text-sm font-semibold text-[var(--brand-text)] mb-3">Distribución de Peso por Tipo</h4>
<div class="space-y-2">
<div class="flex items-center gap-3">
<span class="text-xs w-20 text-[var(--brand-text-muted)]">Uva</span>
<div class="flex-1 h-8 bg-[var(--brand-surface)] rounded-lg overflow-hidden border border-[var(--brand-border)]">
<div
class="h-full flex items-center justify-end px-2 transition-all duration-500"
style="background-color: var(--coffee-uva, #8B4513);"
:style="{ width: `${calcularPorcentaje(data.qq_seco_uva)}%` }"
>
<span class="text-xs font-semibold text-white">{{ calcularPorcentaje(data.qq_seco_uva) }}%</span>
</div>
</div>
<span class="text-xs w-32 text-right text-[var(--brand-text)]">{{ formatNumber(data.qq_seco_uva) }} QQ</span>
</div>
<div class="flex items-center gap-3">
<span class="text-xs w-20 text-[var(--brand-text-muted)]">Mojado</span>
<div class="flex-1 h-8 bg-[var(--brand-surface)] rounded-lg overflow-hidden border border-[var(--brand-border)]">
<div
class="h-full flex items-center justify-end px-2 transition-all duration-500"
style="background-color: var(--coffee-mojado, #1E90FF);"
:style="{ width: `${calcularPorcentaje(data.qq_seco_mojado)}%` }"
>
<span class="text-xs font-semibold text-white">{{ calcularPorcentaje(data.qq_seco_mojado) }}%</span>
</div>
</div>
<span class="text-xs w-32 text-right text-[var(--brand-text)]">{{ formatNumber(data.qq_seco_mojado) }} QQ</span>
</div>
<div class="flex items-center gap-3">
<span class="text-xs w-20 text-[var(--brand-text-muted)]">Oreado</span>
<div class="flex-1 h-8 bg-[var(--brand-surface)] rounded-lg overflow-hidden border border-[var(--brand-border)]">
<div
class="h-full flex items-center justify-end px-2 transition-all duration-500"
style="background-color: var(--coffee-oreado, #FF8C00);"
:style="{ width: `${calcularPorcentaje(data.qq_seco_oreado)}%` }"
>
<span class="text-xs font-semibold text-white">{{ calcularPorcentaje(data.qq_seco_oreado) }}%</span>
</div>
</div>
<span class="text-xs w-32 text-right text-[var(--brand-text)]">{{ formatNumber(data.qq_seco_oreado) }} QQ</span>
</div>
<div class="flex items-center gap-3">
<span class="text-xs w-20 text-[var(--brand-text-muted)]">Verde</span>
<div class="flex-1 h-8 bg-[var(--brand-surface)] rounded-lg overflow-hidden border border-[var(--brand-border)]">
<div
class="h-full flex items-center justify-end px-2 transition-all duration-500"
style="background-color: var(--coffee-verde, #228B22);"
:style="{ width: `${calcularPorcentaje(data.qq_verde)}%` }"
>
<span class="text-xs font-semibold text-white">{{ calcularPorcentaje(data.qq_verde) }}%</span>
</div>
</div>
<span class="text-xs w-32 text-right text-[var(--brand-text)]">{{ formatNumber(data.qq_verde) }} QQ</span>
</div>
</div>
</div>
</div>
</UCard>
</template>
<script setup lang="ts">
const props = defineProps<{
data: {
qq_seco_uva: number
qq_seco_mojado: number
qq_seco_oreado: number
qq_verde: number
total_qq_seco: number
}
contadores?: {
total_comercios?: number
comercios_filtrados?: number
total_clientes?: number
clientes_con_comercios_filtrados?: number
}
rangoLegible: string
lastUpdated: string
}>()
const showChart = ref(true)
const formatNumber = (value: number) => {
if (!value) return '0.00'
return new Intl.NumberFormat('es-HN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(value)
}
const calcularPorcentaje = (parte: number): string => {
if (!props.data.total_qq_seco || props.data.total_qq_seco === 0) return '0.0'
const porcentaje = (parte / props.data.total_qq_seco) * 100
return porcentaje.toFixed(1)
}
async function copiarTexto() {
const footer = `
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 RESUMEN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📅 Rango: ${props.rangoLegible}
📦 Comercios: ${props.contadores?.comercios_filtrados || 0} de ${props.contadores?.total_comercios || 0} registros
👥 Clientes: ${props.contadores?.clientes_con_comercios_filtrados || 0} de ${props.contadores?.total_clientes || 0} clientes
🕐 Generado: ${props.lastUpdated}`
const texto = `⚖️ TOTALES DE PESO POR TIPO
☕ QUINTALES SECO POR TIPO:
Uva: ${formatNumber(props.data.qq_seco_uva)} QQ (${calcularPorcentaje(props.data.qq_seco_uva)}%)
Mojado: ${formatNumber(props.data.qq_seco_mojado)} QQ (${calcularPorcentaje(props.data.qq_seco_mojado)}%)
Oreado: ${formatNumber(props.data.qq_seco_oreado)} QQ (${calcularPorcentaje(props.data.qq_seco_oreado)}%)
Verde: ${formatNumber(props.data.qq_verde)} QQ (${calcularPorcentaje(props.data.qq_verde)}%)
📊 TOTAL:
Total QQ Seco: ${formatNumber(props.data.total_qq_seco)} QQ${footer}`
await navigator.clipboard.writeText(texto)
alert('✅ Totales de Peso copiados al portapapeles')
}
async function copiarJSON() {
const json = JSON.stringify(props.data, null, 2)
await navigator.clipboard.writeText(json)
alert('✅ JSON copiado al portapapeles')
}
</script>