mejoras UX exquisitas
This commit is contained in:
@@ -54,8 +54,24 @@ const data = computed<(IngresoWithChildren | ClienteWithChildren)[]>(() => {
|
||||
// Clientes as parent, ingresos as children
|
||||
const clientesData = props.clientes.map(cliente => {
|
||||
const clienteIngresos = props.ingresos.filter(i => i.cliente_id === cliente.id)
|
||||
|
||||
// Agregar campos agregados al cliente
|
||||
const peso_seco = clienteIngresos.reduce((sum, i) => sum + (i.peso_seco || 0), 0)
|
||||
const peso_neto = clienteIngresos.reduce((sum, i) => sum + (i.peso_neto || 0), 0)
|
||||
|
||||
// Precio promedio ponderado (por peso_neto)
|
||||
const totalPrecioXPeso = clienteIngresos.reduce((sum, i) => sum + (i.precio * i.peso_neto), 0)
|
||||
const precio = peso_neto > 0 ? totalPrecioXPeso / peso_neto : 0
|
||||
|
||||
// Estados únicos
|
||||
const estados = [...new Set(clienteIngresos.map(i => i.estado))]
|
||||
|
||||
return {
|
||||
...cliente,
|
||||
peso_seco,
|
||||
peso_neto,
|
||||
precio,
|
||||
estado: estados.length > 0 ? estados.join(', ') : '',
|
||||
children: clienteIngresos
|
||||
}
|
||||
})
|
||||
@@ -164,6 +180,14 @@ const columns: TableColumn<IngresoWithChildren | ClienteWithChildren>[] = [
|
||||
cell: ({ row }) => {
|
||||
const original = row.original as any
|
||||
const isIngreso = 'tipo' in original
|
||||
const isCliente = 'name' in original && !('tipo' in original)
|
||||
|
||||
// Si es cliente parent con peso_seco agregado, mostrarlo
|
||||
if (isCliente && row.depth === 0 && original.peso_seco !== undefined) {
|
||||
const peso = Number.parseFloat(original.peso_seco || 0)
|
||||
return h('div', { class: 'text-right font-medium text-yellow-500' }, peso.toFixed(2))
|
||||
}
|
||||
|
||||
if (!isIngreso) return h('div', { class: 'text-right text-gray-500' }, '—')
|
||||
|
||||
const peso = Number.parseFloat(row.getValue('peso_seco') || 0)
|
||||
@@ -176,6 +200,14 @@ const columns: TableColumn<IngresoWithChildren | ClienteWithChildren>[] = [
|
||||
cell: ({ row }) => {
|
||||
const original = row.original as any
|
||||
const isIngreso = 'tipo' in original
|
||||
const isCliente = 'name' in original && !('tipo' in original)
|
||||
|
||||
// Si es cliente parent con peso_neto agregado, mostrarlo
|
||||
if (isCliente && row.depth === 0 && original.peso_neto !== undefined) {
|
||||
const peso = Number.parseFloat(original.peso_neto || 0)
|
||||
return h('div', { class: 'text-right font-medium text-yellow-500' }, peso.toFixed(2))
|
||||
}
|
||||
|
||||
if (!isIngreso) return h('div', { class: 'text-right text-gray-500' }, '—')
|
||||
|
||||
const peso = Number.parseFloat(row.getValue('peso_neto') || 0)
|
||||
@@ -188,6 +220,21 @@ const columns: TableColumn<IngresoWithChildren | ClienteWithChildren>[] = [
|
||||
cell: ({ row }) => {
|
||||
const original = row.original as any
|
||||
const isIngreso = 'tipo' in original
|
||||
const isCliente = 'name' in original && !('tipo' in original)
|
||||
|
||||
// Si es cliente parent con precio agregado, mostrarlo
|
||||
if (isCliente && row.depth === 0 && original.precio !== undefined) {
|
||||
const precio = Number.parseFloat(original.precio || 0)
|
||||
const formatted = new Intl.NumberFormat('es-HN', {
|
||||
style: 'currency',
|
||||
currency: 'HNL',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
}).format(precio).replace('HNL', 'L')
|
||||
|
||||
return h('div', { class: 'text-right font-medium text-yellow-500' }, formatted)
|
||||
}
|
||||
|
||||
if (!isIngreso) return h('div', { class: 'text-right text-gray-500' }, '—')
|
||||
|
||||
const precio = Number.parseFloat(row.getValue('precio') || 0)
|
||||
@@ -210,7 +257,22 @@ const columns: TableColumn<IngresoWithChildren | ClienteWithChildren>[] = [
|
||||
const isIngreso = 'tipo' in original
|
||||
|
||||
if (isCliente) {
|
||||
// Cliente row - show if empleado
|
||||
// Cliente row (parent) - show aggregated estados
|
||||
const isParent = row.depth === 0
|
||||
|
||||
if (isParent && original.estado) {
|
||||
// Si tiene campo estado agregado, mostrarlo como badges múltiples
|
||||
const estados = original.estado.split(', ')
|
||||
return h('div', { class: 'flex flex-wrap gap-1' }, estados.map((estado: string) =>
|
||||
h('span', {
|
||||
class: estado === 'pagado'
|
||||
? 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-green-500/20 text-green-300 border border-green-400/30 text-xs'
|
||||
: 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-yellow-500/20 text-yellow-300 border border-yellow-400/30 text-xs'
|
||||
}, estado === 'pagado' ? '✓ Pagado' : '⏳ Pendiente')
|
||||
))
|
||||
}
|
||||
|
||||
// Cliente row (child) - show if empleado
|
||||
return original.empleado
|
||||
? h('span', { class: 'inline-flex items-center gap-1 px-2 py-0.5 rounded bg-blue-500/20 text-blue-300 border border-blue-400/30 text-xs' }, [
|
||||
h('span', '💼'),
|
||||
|
||||
Reference in New Issue
Block a user