se agrego la vista para el monto total por periodo y tipo de servicio
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { envConfig } from "@/app/lib/config";
|
||||
import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
interface TotalServicioPeriodo {
|
||||
nombre_servicio: string;
|
||||
periodo: string;
|
||||
monto_total: number;
|
||||
}
|
||||
|
||||
interface Servicio {
|
||||
id_servicio: number;
|
||||
servicio: string;
|
||||
}
|
||||
|
||||
interface Periodo {
|
||||
id_periodo: number;
|
||||
semestre: string;
|
||||
}
|
||||
|
||||
export default function ReporteTotalesPage() {
|
||||
const [totales, setTotales] = useState<TotalServicioPeriodo[]>([]);
|
||||
const [servicios, setServicios] = useState<Servicio[]>([]);
|
||||
const [periodos, setPeriodos] = useState<Periodo[]>([]);
|
||||
const [cargando, setCargando] = useState(true);
|
||||
|
||||
// Estados para los filtros
|
||||
const [periodoInicio, setPeriodoInicio] = useState<string>("");
|
||||
const [periodoFin, setPeriodoFin] = useState<string>("");
|
||||
const [servicioId, setServicioId] = useState<string>("");
|
||||
|
||||
const token = Cookies.get("token");
|
||||
const headers = { Authorization: `Bearer ${token}` };
|
||||
|
||||
// Obtener lista de servicios y periodos para los selects
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const [serviciosRes, periodosRes] = await Promise.all([
|
||||
axios.get(`${envConfig.apiUrl}/servicio`, { headers }),
|
||||
axios.get(`${envConfig.apiUrl}/periodo`, { headers }),
|
||||
]);
|
||||
setServicios(serviciosRes.data);
|
||||
setPeriodos(periodosRes.data);
|
||||
} catch (error) {
|
||||
console.error("Error al cargar servicios o periodos", error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const obtenerTotales = async () => {
|
||||
setCargando(true);
|
||||
try {
|
||||
// Construir query params
|
||||
const params = new URLSearchParams();
|
||||
if (periodoInicio) params.append("periodoInicio", periodoInicio);
|
||||
if (periodoFin) params.append("periodoFin", periodoFin);
|
||||
if (servicioId) params.append("servicioId", servicioId);
|
||||
|
||||
const url = `${envConfig.apiUrl}/detalle-servicio/totales-por-periodo?${params.toString()}`;
|
||||
const res = await axios.get(url, { headers });
|
||||
setTotales(res.data);
|
||||
} catch (error) {
|
||||
console.error("Error al obtener totales", error);
|
||||
} finally {
|
||||
setCargando(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Llamar cuando cambien los filtros (podría ser con un botón o automático con debounce)
|
||||
const aplicarFiltros = () => {
|
||||
obtenerTotales();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 style={{ color: "rgb(3, 1, 72)" }}>REPORTE DE TOTALES POR SERVICIO Y PERIODO</h1>
|
||||
|
||||
{/* Filtros */}
|
||||
<div style={{ marginBottom: "20px", display: "flex", gap: "10px", flexWrap: "wrap" }}>
|
||||
<select
|
||||
value={periodoInicio}
|
||||
onChange={(e) => setPeriodoInicio(e.target.value)}
|
||||
>
|
||||
<option value="">Periodo inicio (todos)</option>
|
||||
{periodos.map((p) => (
|
||||
<option key={p.id_periodo} value={p.id_periodo}>
|
||||
{p.semestre}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<select
|
||||
value={periodoFin}
|
||||
onChange={(e) => setPeriodoFin(e.target.value)}
|
||||
>
|
||||
<option value="">Periodo fin (todos)</option>
|
||||
{periodos.map((p) => (
|
||||
<option key={p.id_periodo} value={p.id_periodo}>
|
||||
{p.semestre}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<select
|
||||
value={servicioId}
|
||||
onChange={(e) => setServicioId(e.target.value)}
|
||||
>
|
||||
<option value="">Todos los servicios</option>
|
||||
{servicios.map((s) => (
|
||||
<option key={s.id_servicio} value={s.id_servicio}>
|
||||
{s.servicio}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<button onClick={aplicarFiltros}>Filtrar</button>
|
||||
</div>
|
||||
|
||||
{cargando ? (
|
||||
<p>Cargando...</p>
|
||||
) : (
|
||||
<div style={{ overflow: "auto", maxHeight: "500px" }}>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Servicio</th>
|
||||
<th>Periodo</th>
|
||||
<th>Monto Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{totales.map((item, index) => (
|
||||
<tr key={index}>
|
||||
<td>{item.nombre_servicio}</td>
|
||||
<td>{item.periodo}</td>
|
||||
<td>${item.monto_total.toFixed(2)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user