Files
NEXTJS_AcademicoEmp/src/app/Informes/ContratosAnulados/page.tsx
T
2026-09-07 15:17:43 +00:00

349 lines
13 KiB
TypeScript
Executable File

"use client";
import React, { useState } from "react";
import Link from "next/link";
import { User } from "@boxicons/react";
// Interface para mapear la estructura de la lista de contratos anulados
interface ContratoAnuladoItem {
idEmpresas: string;
empresa: string;
Contrato: string;
Fecha: string;
DescripcionActividad: string;
usuarioResponsable: string;
}
export default function ContratosHistorialPage() {
// --- ESTADOS DE CONTROLES Y SECCIONES ---
const [mes, setMes] = useState("");
const [agno, setAgno] = useState("");
const [showSearch, setShowSearch] = useState(false);
const [mensajeLabel, setMensajeLabel] = useState("");
// --- ESTADOS DE MODALES Y CARGA ---
const [isLoading, setIsLoading] = useState(false);
const [modalAlerta, setModalAlerta] = useState({ show: false, message: "" });
// --- DATOS SIMULADOS (DataList / Grid) ---
const [contratosAnulados, setContratosAnulados] = useState<ContratoAnuladoItem[]>([
{
idEmpresas: "76.123.456-7",
empresa: "Empresa Ejemplo S.A.",
Contrato: "1002",
Fecha: "2026-02-10",
DescripcionActividad: "Anulación solicitada por el cliente por cambio de presupuesto",
usuarioResponsable: "AdminUser",
},
]);
// --- MANEJADORES DE EVENTOS ---
const handleBuscar = (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
// Simulación de respuesta de backend
setTimeout(() => {
setIsLoading(false);
if (!mes || !agno) {
setModalAlerta({
show: true,
message: "Por favor seleccione un mes e ingrese un año válido.",
});
return;
}
setShowSearch(true);
setMensajeLabel("");
}, 800);
};
const handleExportarExcel = (e: React.MouseEvent) => {
e.preventDefault();
setIsLoading(true);
setTimeout(() => {
setIsLoading(false);
setModalAlerta({
show: true,
message: "Informe mensual exportado correctamente a Excel.",
});
}, 1000);
};
return (
<div className="container-fluid py-3">
<div className="row">
<div className="col-md-12">
<div className="row">
{/* CABECERA IZQUIERDA */}
<div className="col-md-5">
<div className="alert alert-light text-dark shadow-sm" role="alert">
<div className="row align-items-center">
<div className="col-8 d-flex align-items-center">
<strong>
<User style={{ fontSize: "24px" }} />
</strong>
<strong>
<span className="ms-2">Contratos anulados por mes</span>
</strong>
</div>
<div className="col text-end">
<Link
href="/Clientes/Index"
className="btn btn-warning text-dark btn-sm fw-bold"
>
Volver
</Link>
</div>
</div>
</div>
</div>
{/* CABECERA DERECHA / FILTROS DE BÚSQUEDA */}
<div className="col-md-7">
<div className="alert alert-light text-dark shadow-sm" role="alert">
<form onSubmit={handleBuscar} className="row align-items-center">
<div className="col text-end">
<span className="fw-bold">Mes</span>
</div>
<div className="col">
<select
className="form-select form-select-sm"
value={mes}
onChange={(e) => setMes(e.target.value)}
>
<option value="">-- Seleccione --</option>
<option value="1">Enero</option>
<option value="2">Febrero</option>
<option value="3">Marzo</option>
<option value="4">Abril</option>
<option value="5">Mayo</option>
<option value="6">Junio</option>
<option value="7">Julio</option>
<option value="8">Agosto</option>
<option value="9">Septiembre</option>
<option value="10">Octubre</option>
<option value="11">Noviembre</option>
<option value="12">Diciembre</option>
</select>
</div>
<div className="col text-end">
<span className="fw-bold">Agno</span>
</div>
<div className="col">
<input
type="number"
className="form-control form-control-sm"
value={agno}
onChange={(e) => setAgno(e.target.value)}
placeholder="AAAA"
/>
</div>
<div className="col">
<button
type="submit"
className="btn btn-primary btn-sm d-grid w-100"
>
Buscar
</button>
</div>
</form>
</div>
</div>
{/* BOTÓN EXPORTAR EXCEL */}
<div className="col-md-12 mx-auto">
<button
type="button"
className="btn p-0 text-start w-100 text-decoration-none border-0 bg-transparent"
onClick={handleExportarExcel}
>
<div className="alert alert-success shadow" role="alert">
<div className="row align-items-center">
<div className="col-md-3">
<h1 className="mb-0">
{/* <Export /> */}
</h1>
</div>
<div className="col text-center">
<span className="text-muted">
<strong>Excel</strong>
</span>
<h5 className="mb-0">
<strong>Exportar Mensual</strong>
</h5>
</div>
</div>
</div>
</button>
</div>
{/* TABLA DE RESULTADOS */}
{showSearch && (
<div className="col-md-12 mt-3" id="div_search">
<div className="alert alert-light text-dark shadow-sm" role="alert">
<div className="table-responsive">
<table
className="table table-sm mb-0"
style={{ fontSize: "12px" }}
>
<thead>
<tr>
<th className="text-start" style={{ width: "3%" }}></th>
<th className="text-start" style={{ width: "7%" }}>
RUT Empresa
</th>
<th className="text-start" style={{ width: "20%" }}>
Empresa
</th>
<th className="text-start" style={{ width: "7%" }}>
Contrato
</th>
<th className="text-start" style={{ width: "12%" }}>
Fecha
</th>
<th className="text-start" style={{ width: "40%" }}>
Observacion
</th>
<th className="text-start" style={{ width: "11%" }}>
Responsable
</th>
</tr>
</thead>
<tbody>
{contratosAnulados.map((item, index) => (
<tr key={index}>
<td className="text-start" style={{ width: "3%" }}></td>
<td className="text-start" style={{ width: "7%" }}>
{item.idEmpresas}
</td>
<td className="text-start" style={{ width: "20%" }}>
{item.empresa}
</td>
<td className="text-start" style={{ width: "7%" }}>
{item.Contrato}
</td>
<td className="text-start" style={{ width: "12%" }}>
{item.Fecha}
</td>
<td className="text-start" style={{ width: "40%" }}>
{item.DescripcionActividad}
</td>
<td className="text-start" style={{ width: "11%" }}>
{item.usuarioResponsable}
</td>
</tr>
))}
</tbody>
</table>
{mensajeLabel && (
<h4 className="mt-2">
<span>{mensajeLabel}</span>
</h4>
)}
</div>
</div>
</div>
)}
</div>
</div>
</div>
{/* --- MODAL ALERTA / ERRORES --- */}
{modalAlerta.show && (
<div
className="modal fade show d-block bg-dark bg-opacity-50"
tabIndex={-1}
role="dialog"
>
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div className="modal-content text-dark">
<div className="modal-header alert alert-secondary mb-0">
<h5 className="float-start mt-2">
<strong>Módulo Académico - Empresa</strong>
</h5>
<button
type="button"
className="btn-close float-end mt-1"
onClick={() => setModalAlerta({ show: false, message: "" })}
aria-label="Close"
></button>
</div>
<div
className="modal-body alert mb-0"
style={{ textAlign: "justify" }}
>
<div className="row mb-2">
<div className="col-md-12 text-center">
<h5>
<strong>{modalAlerta.message}</strong>
</h5>
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-primary"
onClick={() => setModalAlerta({ show: false, message: "" })}
>
Cerrar
</button>
</div>
</div>
</div>
</div>
)}
{/* --- MODAL CARGANDO (LOADING SPINNER) --- */}
{isLoading && (
<div
className="modal fade show d-block bg-dark bg-opacity-50"
tabIndex={-1}
role="dialog"
>
<div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div className="modal-content text-dark">
<div className="modal-header alert alert-secondary mb-0">
<h5 className="float-start mt-2">
<strong>Procesando</strong>
</h5>
</div>
<div
className="modal-body alert mb-0"
style={{ textAlign: "justify" }}
>
<div className="row mb-2">
<div className="col-md-12 text-center">
<h5>
<strong>Espere un momento, por favor...</strong>
</h5>
<div className="d-flex justify-content-center gap-1 mt-3">
<div
className="spinner-grow spinner-grow-sm text-primary"
role="status"
></div>
<div
className="spinner-grow spinner-grow-sm text-danger"
role="status"
></div>
<div
className="spinner-grow spinner-grow-sm text-primary"
role="status"
></div>
<div
className="spinner-grow spinner-grow-sm text-danger"
role="status"
></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}