diff --git a/app/(private)/Reportes/Page.module.css b/app/(private)/Reportes/Page.module.css index d48a3c1..7c33f48 100644 --- a/app/(private)/Reportes/Page.module.css +++ b/app/(private)/Reportes/Page.module.css @@ -67,3 +67,9 @@ .resetButton:hover { background-color: #cc0000; } + +.download{ + display: flex; + align-items: end; + justify-content: end; +} \ No newline at end of file diff --git a/app/(private)/Reportes/ReportesClient.tsx b/app/(private)/Reportes/ReportesClient.tsx index 4bca173..9d7fc17 100644 --- a/app/(private)/Reportes/ReportesClient.tsx +++ b/app/(private)/Reportes/ReportesClient.tsx @@ -1,12 +1,17 @@ -'use client'; +"use client"; -import { useState } from 'react'; -import Toggle from '@/app/Components/Global/Toggle/Toggle'; -import SearchDateBetween from '@/app/Components/SearchDateBetween/SearchDateBetween'; -import PorServicios from '@/app/Components/Reportes/porServicio'; -import PorRecibos from '@/app/Components/Reportes/porRecibo'; +import { useState } from "react"; +import Toggle from "@/app/Components/Global/Toggle/Toggle"; +import SearchDateBetween from "@/app/Components/SearchDateBetween/SearchDateBetween"; +import PorServicios from "@/app/Components/Reportes/porServicio"; +import PorRecibos from "@/app/Components/Reportes/porRecibo"; +import DownloadReporteXLSX from "@/app/Components/Dowload/Reporte"; -export default function ReportesClient({ defaultKey }: { defaultKey?: string }) { +export default function ReportesClient({ + defaultKey, +}: { + defaultKey?: string; +}) { const [desde, setDesde] = useState(null); const [hasta, setHasta] = useState(null); @@ -18,8 +23,8 @@ export default function ReportesClient({ defaultKey }: { defaultKey?: string }) defaultView={defaultKey} options={[ { - key: 'Por recibo', - label: 'Por recibo', + key: "Por recibo", + label: "Por recibo", content: ( <> { + setLoading(true); + const token = Cookies.get("token"); + const headers = { Authorization: `Bearer ${token}` }; + + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/equipos/reporteXLSX`,//Modificar + { headers } + ); + + if (!response.ok) { + toast.error("Error al descargar el archivo"); + return; + } + + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + + const a = document.createElement("a"); + a.href = url; + a.download = "Reporte Recibos.xlsx"; + document.body.appendChild(a); + a.click(); + a.remove(); + + window.URL.revokeObjectURL(url); + } catch (error) { + console.error(error); + toast.error("Hubo un problema al descargar el archivo."); + } finally { + setLoading(false); + } + }; + + return ( + + ); +} diff --git a/app/Components/Dowload/style.module.css b/app/Components/Dowload/style.module.css new file mode 100644 index 0000000..936347b --- /dev/null +++ b/app/Components/Dowload/style.module.css @@ -0,0 +1,46 @@ +.downloadBtn { + position: absolute; + right: 15px; + top:-35px; + display: flex; + justify-content: center; + align-items: center; + gap: 8px; + background: #ffffff; + border: 1px solid #ddd; + border-bottom: none; + padding: 5px 5px; + cursor: pointer; + border-radius: 10px 10px 0 0; + font-size: 14px; + font-weight: 600; + transition: background 0.2s ease; + min-width: 50px; +} + +.downloadBtn:hover { + background: #95d2b0; +} + +.downloadBtn:disabled { + background: #a5a5a5; + cursor: not-allowed; +} + +.loader { + border: 3px solid #ffffff55; + border-top: 3px solid white; + border-radius: 50%; + width: 16px; + height: 16px; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/app/Components/Reportes/porRecibo.tsx b/app/Components/Reportes/porRecibo.tsx index bb44118..39da5a2 100644 --- a/app/Components/Reportes/porRecibo.tsx +++ b/app/Components/Reportes/porRecibo.tsx @@ -1,7 +1,8 @@ -'use client'; +"use client"; -import { useEffect, useState } from 'react'; -import axios from 'axios'; +import { useEffect, useState } from "react"; +import axios from "axios"; +import DownloadReporteXLSX from "../Dowload/Reporte"; interface Recibo { id_recibo: number; @@ -9,9 +10,9 @@ interface Recibo { fecha_recibo: string; fecha_registro: string; monto: string; - user:{ - nombre:string; - } + user: { + nombre: string; + }; } interface Props { @@ -36,7 +37,7 @@ function PorRecibos({ desde, hasta }: Props) { setRecibos(res.data); } catch (error) { - console.error('Error al obtener recibos', error); + console.error("Error al obtener recibos", error); } finally { setLoading(false); } @@ -46,38 +47,47 @@ function PorRecibos({ desde, hasta }: Props) { }, [desde, hasta]); return ( -
- {loading &&

Cargando...

} +
+ {recibos.length > 0 && } +
+ {loading &&

Cargando...

} - - - - - - - - - - - - - {!loading && recibos.length === 0 && ( +
FolioMontofecha recibofecha registroUsuario
+ - + + + + + - )} + - {recibos.map((recibo) => ( - - - - - - - - ))} - -
No hay recibos en este rangoFolioMontofecha recibofecha registroUsuario
{recibo.folio_recibo}${Number(recibo.monto).toFixed(2)}{recibo.fecha_recibo}{recibo.fecha_registro}{recibo.user.nombre}
+ + {!loading && recibos.length === 0 && ( + + No hay recibos en este rango + + )} + + {recibos.map((recibo) => ( + + {recibo.folio_recibo} + ${Number(recibo.monto).toFixed(2)} + {recibo.fecha_recibo} + {recibo.fecha_registro} + {recibo.user.nombre} + + ))} + + +
); } diff --git a/public/excel.svg b/public/excel.svg new file mode 100644 index 0000000..1d47514 --- /dev/null +++ b/public/excel.svg @@ -0,0 +1 @@ + \ No newline at end of file