This commit is contained in:
2026-01-16 14:50:36 -06:00
10 changed files with 175 additions and 52 deletions
+1 -1
View File
@@ -50,4 +50,4 @@ export default async function Page(props: {
</section>
);
}
//IO
//IO
+1 -1
View File
@@ -48,7 +48,7 @@ export default function ReportesClient({
setHasta(h);
}}
/>
{/* <PorServicios desde={desde} hasta={hasta} /> */}
<PorServicios desde={desde} hasta={hasta} />
</>
),
},
@@ -115,4 +115,4 @@ export default function ProgramSelector() {
</button>
</form>
);
}
}
View File
+76 -32
View File
@@ -1,42 +1,86 @@
"use client";
import { useState } from "react";
interface servicios {
folio_recibo: "100255";
monto: "40.00";
fecha_recibo: "10/10/2025";
fecha_registro: "10/10/2025 05:32:20 pm";
usuario: "modulo1";
import { useEffect, useState } from "react";
import axios from "axios";
import DownloadReporteXLSX from "../Dowload/Reporte";
interface ServicioReporte {
id_servicio: number;
servicio: string;
total: string;
}
function PorServicios() {
const [recibos, setRecibos] = useState<servicios[]>([]);
interface Props {
desde: string | null;
hasta: string | null;
}
function PorServicio({ desde, hasta }: Props) {
const [servicios, setServicios] = useState<ServicioReporte[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (!desde || !hasta) return;
const fetchServicios = async () => {
setLoading(true);
try {
const res = await axios.post(
`${process.env.NEXT_PUBLIC_API_URL}/detalle-servicio/rango`,
{ desde, hasta }
);
setServicios(res.data);
} catch (error) {
console.error("Error al obtener reporte por servicio", error);
} finally {
setLoading(false);
}
};
fetchServicios();
}, [desde, hasta]);
return (
<div>
<table>
<thead>
<tr>
<th>Folio Recibo</th>
<th>Monto</th>
<th>Fecha Recibo</th>
<th>Fecha Registro</th>
<th>Usuario</th>
</tr>
</thead>
<tbody>
{recibos.map((recibo, index) => (
<tr key={index}>
<td>{recibo.folio_recibo}</td>
<td>{recibo.monto}</td>
<td>{recibo.fecha_recibo}</td>
<td>{recibo.fecha_registro}</td>
<td>{recibo.usuario}</td>
<div style={{ position: "relative" }}>
{servicios.length > 0 && <DownloadReporteXLSX />}
<div
style={{
overflow: "auto",
height: "270px",
scrollbarColor: "#2563eb white",
}}
>
{loading && <p>Cargando...</p>}
<table>
<thead>
<tr>
<th>Servicio</th>
<th>Monto total</th>
</tr>
))}
</tbody>
</table>
</thead>
<tbody>
{!loading && servicios.length === 0 && (
<tr>
<td colSpan={2}>No hay servicios en este rango</td>
</tr>
)}
{servicios.map((servicio) => (
<tr key={servicio.id_servicio}>
<td>{servicio.servicio}</td>
<td>${Number(servicio.total).toFixed(2)}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
export default PorServicios;
export default PorServicio;
+5 -2
View File
@@ -7,7 +7,11 @@ if (!envConfig.apiUrl) {
console.error("API URL is not defined in envConfig");
}
export default function SelectAreas() {
interface proms {
url: string;
}
export default function SelectAreas(props: proms) {
const [areas, setAreas] = useState([]);
const [selectedArea, setSelectedArea] = useState("");
@@ -40,4 +44,3 @@ export default function SelectAreas() {
</div>
);
}
//IO
+37
View File
@@ -0,0 +1,37 @@
"use client";
import axios from "axios";
import { useEffect, useState } from "react";
interface proms {
url: string;
}
export default function SelectEquipo(props: proms) {
const [areas, setAreas] = useState([]);
const [selectedArea, setSelectedArea] = useState("");
useEffect(() => {
axios
.get(props.url)
.then((data) => setAreas(data.data))
.catch((error) => console.error("Error al traer las áreas:", error));
}, []);
return (
<div>
<label htmlFor="areaSelect">Selecciona un equipo:</label>
<select
id="areaSelect"
value={selectedArea}
onChange={(e) => setSelectedArea(e.target.value)}
>
<option value="">-- Selecciona una opción --</option>
{areas.map((area: any, index) => (
<option key={index} value={area.nombre_equipo}>
{area.nombre_equipo}
</option>
))}
</select>
</div>
);
}
+44
View File
@@ -0,0 +1,44 @@
.notfound {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #f3f4f5, #f3f4f5);
color: #fff;
text-align: center;
font-family: "Inter", sans-serif;
padding: 2rem;
}
.notfound h1 {
font-size: 6rem;
color: #ff4d4d;
margin-bottom: 0.5rem;
}
.notfound h2 {
font-size: 2rem;
margin-bottom: 1rem;
}
.notfound p {
color: #050505;
max-width: 500px;
margin-bottom: 2rem;
}
.notfound button {
background: #ff4d4d;
border: none;
color: white;
padding: 0.8rem 2rem;
border-radius: 10px;
font-size: 1rem;
cursor: pointer;
transition: background 0.3s ease;
}
.notfound button:hover {
background: #e60000;
}
+9 -14
View File
@@ -1,25 +1,20 @@
"use client";
import { useRouter } from "next/navigation";
import "./NotFound.css";
export default function NotFound() {
const router = useRouter();
const handleButton = () => {
router.push("/Impresiones");
};
return (
<section>
<img src="/404-bg.png" alt="Página no encontrada" />
{/* Título */}
<h1>404 - Página no encontrada</h1>
{/* Texto */}
<p>Lo sentimos, la página que buscas no existe.</p>
<p>Por favor, verifica la URL o regresa a la página principal.</p>
<button className="button buttonSearch"> regresa al inicio</button>
<section className="notfound">
<h1>404</h1>
<h2>Página no encontrada</h2>
<p>
Lo sentimos, la página que buscas no existe o ha sido movida. Verifica
la URL o regresa a la página principal.
</p>
<button onClick={() => router.push("/")}>Regresar al inicio</button>
</section>
);
}
+1 -1
View File
@@ -15,7 +15,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{