205 lines
7.2 KiB
Vue

<script setup>
import { ref, computed } from 'vue';
import GoogleIcon from '@Shared/GoogleIcon.vue';
// Datos de ejemplo de gastos
const expenses = ref([
{
id: 1,
date: '2024-08-15',
concept: 'Catering para evento X',
reason: 'Servicio de comida para 50 asistentes.',
amount: 1500.00,
justificationFile: 'catering_evento_x.pdf'
},
{
id: 2,
date: '2024-08-14',
concept: 'Renta de equipo de audio',
reason: 'Micrófonos y bocinas para el auditorio.',
amount: 800.00,
justificationFile: 'renta_audio.pdf'
},
{
id: 3,
date: '2024-08-10',
concept: 'Viáticos para conferencista',
reason: 'Vuelo y hospedaje para Dr. Smith.',
amount: 1250.00,
justificationFile: 'viaticos_dr_smith.pdf'
}
]);
// Computed para calcular el total
const totalExpenses = computed(() => {
return expenses.value.reduce((total, expense) => {
return total + expense.amount;
}, 0);
});
// Función para ver PDF
const viewPDF = (fileName) => {
console.log('Ver PDF:', fileName);
// Aquí implementarías la lógica para abrir el PDF
// Por ejemplo: window.open(`/pdfs/${fileName}`, '_blank');
alert(`Abriendo archivo: ${fileName}`);
};
// Función para formatear moneda
const formatCurrency = (amount) => {
return new Intl.NumberFormat('es-MX', {
style: 'currency',
currency: 'USD'
}).format(amount);
};
// Función para formatear fecha
const formatDate = (dateString) => {
const date = new Date(dateString);
return date.toLocaleDateString('es-MX', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
};
// Función para exportar reporte
const exportReport = () => {
console.log('Exportar reporte:', expenses.value);
// Aquí implementarías la lógica para exportar el reporte
alert('Reporte exportado correctamente');
};
// Función para filtrar por fecha
const filterByDate = () => {
// Aquí podrías implementar filtros por fecha
console.log('Filtrar por fecha');
};
</script>
<template>
<div class="p-6 max-w-auto mx-auto">
<!-- Header -->
<div class="flex items-start justify-between gap-4">
<div>
<h1 class="text-4xl font-extrabold text-gray-900 dark:text-primary-dt">Reporte de Gastos de Eventos</h1>
<p class="mt-1 text-sm text-gray-500 dark:text-primary-dt/70">Consulta y gestiona los gastos realizados en eventos</p>
</div>
<div class="flex gap-3">
<button
@click="filterByDate"
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg border border-gray-300 bg-white text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-[#2563eb] focus:border-transparent dark:bg-primary-d dark:border-primary/20 dark:text-primary-dt dark:hover:bg-primary/10"
>
<GoogleIcon class="text-gray-600 dark:text-primary-dt text-xl" name="filter_list" />
Filtrar
</button>
<button
@click="exportReport"
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-[#2563eb] hover:bg-[#1e40af] text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-[#2563eb] focus:ring-offset-2"
>
<GoogleIcon class="text-white text-xl" name="download" />
Exportar
</button>
</div>
</div>
<!-- Card principal -->
<section class="mt-6 bg-white rounded-lg shadow-sm p-6 dark:bg-primary-d dark:border-primary/20 dark:text-primary-dt">
<!-- Tabla de gastos -->
<div class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="border-b border-gray-100 dark:border-primary/20">
<th class="text-left py-3 px-4 font-semibold text-gray-800 dark:text-primary-dt">FECHA</th>
<th class="text-left py-3 px-4 font-semibold text-gray-800 dark:text-primary-dt">CONCEPTO</th>
<th class="text-left py-3 px-4 font-semibold text-gray-800 dark:text-primary-dt">RAZÓN</th>
<th class="text-right py-3 px-4 font-semibold text-gray-800 dark:text-primary-dt">MONTO</th>
<th class="text-left py-3 px-4 font-semibold text-gray-800 dark:text-primary-dt">JUSTIFICANTE</th>
</tr>
</thead>
<tbody>
<tr
v-for="expense in expenses"
:key="expense.id"
class="border-b border-gray-50 dark:border-primary/10 hover:bg-gray-50 dark:hover:bg-primary/5"
>
<!-- Fecha -->
<td class="py-4 px-4">
<div class="text-sm text-gray-900 dark:text-primary-dt">
{{ formatDate(expense.date) }}
</div>
</td>
<!-- Concepto -->
<td class="py-4 px-4">
<div class="font-medium text-gray-900 dark:text-primary-dt">
{{ expense.concept }}
</div>
</td>
<!-- Razón -->
<td class="py-4 px-4">
<div class="text-sm text-gray-600 dark:text-primary-dt/70">
{{ expense.reason }}
</div>
</td>
<!-- Monto -->
<td class="py-4 px-4 text-right">
<div class="text-lg font-bold text-[#2563eb] dark:text-primary-dt">
{{ formatCurrency(expense.amount) }}
</div>
</td>
<!-- Justificante -->
<td class="py-4 px-4">
<button
@click="viewPDF(expense.justificationFile)"
class="text-blue-600 hover:text-blue-800 underline text-sm font-medium dark:text-blue-400 dark:hover:text-blue-300 transition-colors"
>
Ver PDF
</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Resumen de gastos -->
<div class="mt-6 p-4 bg-gray-50 rounded-lg dark:bg-primary/5">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<GoogleIcon class="text-gray-600 dark:text-primary-dt text-xl" name="account_balance_wallet" />
<span class="text-lg font-medium text-gray-800 dark:text-primary-dt">Total de Gastos:</span>
</div>
<div class="text-2xl font-bold text-[#2563eb] dark:text-primary-dt">
{{ formatCurrency(totalExpenses) }}
</div>
</div>
</div>
<!-- Footer con estadísticas -->
<div class="mt-6 border-t border-gray-100 pt-4 flex items-center justify-between dark:border-primary/20">
<div class="text-sm text-gray-500 dark:text-primary-dt/70">
Mostrando {{ expenses.length }} gastos registrados
</div>
<div class="flex items-center gap-4">
<div class="flex items-center gap-2 text-sm">
<span class="w-3 h-3 bg-blue-400 rounded-full"></span>
<span class="text-gray-600 dark:text-primary-dt/70">Total: {{ expenses.length }} registros</span>
</div>
<div class="flex items-center gap-2 text-sm">
<span class="w-3 h-3 bg-green-400 rounded-full"></span>
<span class="text-gray-600 dark:text-primary-dt/70">Justificados: {{ expenses.length }}</span>
</div>
</div>
</div>
</section>
</div>
</template>