Modificaciones y se agrego
This commit is contained in:
Generated
+100
@@ -10,9 +10,12 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.12.2",
|
||||
"bootstrap": "^5.3.8",
|
||||
"file-saver": "^2.0.5",
|
||||
"moment": "^2.30.1",
|
||||
"next": "15.5.3",
|
||||
"react": "19.1.0",
|
||||
"react-bootstrap": "^2.10.10",
|
||||
"react-datepicker": "^8.7.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-hot-toast": "^2.6.0",
|
||||
"react-icons": "^5.5.0",
|
||||
@@ -210,6 +213,54 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
|
||||
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
|
||||
"integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.7.3",
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/react": {
|
||||
"version": "0.27.16",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.16.tgz",
|
||||
"integrity": "sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==",
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^2.1.6",
|
||||
"@floating-ui/utils": "^0.2.10",
|
||||
"tabbable": "^6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=17.0.0",
|
||||
"react-dom": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/react-dom": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
|
||||
"integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.7.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
|
||||
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||
@@ -2382,6 +2433,14 @@
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
@@ -2527,6 +2586,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
||||
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
@@ -3343,6 +3411,11 @@
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/file-saver": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
@@ -4442,6 +4515,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@@ -4943,6 +5024,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker": {
|
||||
"version": "8.7.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-8.7.0.tgz",
|
||||
"integrity": "sha512-r5OJbiLWc3YiVNy69Kau07/aVgVGsFVMA6+nlqCV7vyQ8q0FUOnJ+wAI4CgVxHejG3i5djAEiebrF8/Eip4rIw==",
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "^0.27.15",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc",
|
||||
"react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
|
||||
@@ -5647,6 +5742,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tabbable": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
|
||||
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.15",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||
|
||||
@@ -11,9 +11,12 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.12.2",
|
||||
"bootstrap": "^5.3.8",
|
||||
"file-saver": "^2.0.5",
|
||||
"moment": "^2.30.1",
|
||||
"next": "15.5.3",
|
||||
"react": "19.1.0",
|
||||
"react-bootstrap": "^2.10.10",
|
||||
"react-datepicker": "^8.7.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-hot-toast": "^2.6.0",
|
||||
"react-icons": "^5.5.0",
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import Cuestionario from "@/components/administrador/cuestionario";
|
||||
import Reporte from "@/components/administrador/reporte";
|
||||
import BotonRegresar from "@/components/boton-regresar";
|
||||
|
||||
export default function Registro() {
|
||||
const years = [2020, 2021, 2022, 2023, 2024, 2025];
|
||||
const admin = { token: "mi_token_de_prueba" };
|
||||
|
||||
//const updateIsLoading = (loading: boolean) => {
|
||||
// console.log("Loading:", loading);
|
||||
//};
|
||||
|
||||
return (
|
||||
<main>
|
||||
<BotonRegresar />
|
||||
<h3 className="title">Reportes</h3>
|
||||
<Cuestionario
|
||||
years={years}
|
||||
admin={admin}
|
||||
//updateIsLoading={updateIsLoading}
|
||||
/>
|
||||
|
||||
<Reporte admin={admin}/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
"use client"
|
||||
import { axiosInstance } from "@/api/config";
|
||||
import { useState } from "react";
|
||||
import { Button, Col, FormGroup, FormLabel, FormSelect, InputGroup } from "react-bootstrap";
|
||||
|
||||
interface Props {
|
||||
years: number[];
|
||||
admin: {token: string};
|
||||
updateIsLoading?: {loading: boolean};
|
||||
}
|
||||
|
||||
export default function Cuestionario({ years, admin, updateIsLoading }: Props) {
|
||||
const [selectedCuestionario, setSelectedCuestionario] = useState("");
|
||||
const [version, setVersion] = useState("");
|
||||
const [selectedYear, setSelectedYear] = useState("");
|
||||
|
||||
const downloadExcel = async () => {
|
||||
try {
|
||||
//updateIsLoading(true);
|
||||
const res = await axiosInstance.get(`/${selectedCuestionario}`, {
|
||||
params: { year: selectedYear, version },
|
||||
headers: { Authorization: `Bearer ${admin.token}` },
|
||||
responseType: "blob",
|
||||
});
|
||||
|
||||
//saveAs(res.data, `${selectedYear}_${selectedCuestionario}_${version}.csv`);
|
||||
|
||||
// reset
|
||||
setSelectedYear("");
|
||||
setSelectedCuestionario("");
|
||||
setVersion("");
|
||||
//updateIsLoading(false);
|
||||
} catch (err: any) {
|
||||
//updateIsLoading(false);
|
||||
//imprimirError(err.response?.data || "Error al descargar");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4 className="mb-2">Descargar Cuestionario</h4>
|
||||
|
||||
<div>
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel>Cuestionario:</FormLabel>
|
||||
<InputGroup>
|
||||
<FormSelect>
|
||||
<option value="cuestionario_alumno">Cuestionario de Alumnos</option>
|
||||
<option value="cuestionario_programa">Cuestionario de Programas</option>
|
||||
</FormSelect>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel>Version:</FormLabel>
|
||||
<InputGroup>
|
||||
<FormSelect>
|
||||
<option value="v1">V1</option>
|
||||
<option value="v2">V2</option>
|
||||
</FormSelect>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel>Año:</FormLabel>
|
||||
<InputGroup>
|
||||
<FormSelect value={selectedYear} onChange={(e) => setSelectedYear(e.target.value)}>
|
||||
<option value="">Seleccione un año:</option>
|
||||
{years.map((y, i) => (
|
||||
<option key={i} value={y}>
|
||||
{y}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<div>
|
||||
<Button
|
||||
variant="info"
|
||||
onClick={downloadExcel}
|
||||
>
|
||||
Enviar archivo
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import { axiosInstance } from "@/api/config";
|
||||
import { Button, Col, FormGroup, FormLabel, InputGroup } from "react-bootstrap";
|
||||
import DatePicker from "react-datepicker";
|
||||
import moment from "moment";
|
||||
//import { saveAs } from "file-saver";
|
||||
|
||||
interface Props {
|
||||
admin: { token: string };
|
||||
imprimirError?: (msg: string) => void;
|
||||
updateIsLoading?: (loading: boolean) => void;
|
||||
}
|
||||
|
||||
export default function Reporte({ admin }: Props) {
|
||||
const [selectedInicio, setSelectedInicio] = useState<Date | null>(null);
|
||||
const [selectedFin, setSelectedFin] = useState<Date | null>(null);
|
||||
|
||||
const minDate = new Date("2020-01-01");
|
||||
const maxDate = new Date();
|
||||
|
||||
const validarFechas = () => {
|
||||
const fechaInicio = moment(selectedInicio);
|
||||
const fechaFin = moment(selectedFin);
|
||||
|
||||
if (!fechaInicio.isValid() || !fechaFin.isValid()) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
const descargar = async () => {
|
||||
try {
|
||||
//updateIsLoading(true);
|
||||
|
||||
const res = await axiosInstance.get("/servicio/reporte", {
|
||||
params: {
|
||||
inicio: moment(selectedInicio).format("YYYY-MM-DD"),
|
||||
fin: moment(selectedFin).format("YYYY-MM-DD"),
|
||||
},
|
||||
headers: {
|
||||
Authorization: `Bearer ${admin.token}`,
|
||||
},
|
||||
responseType: "blob",
|
||||
});
|
||||
|
||||
//saveAs(res.data, "reporte.csv");
|
||||
|
||||
// reset
|
||||
setSelectedInicio(null);
|
||||
setSelectedFin(null);
|
||||
//updateIsLoading(false);
|
||||
} catch (err: any) {
|
||||
//updateIsLoading(false);
|
||||
//imprimirError(err.response?.data || "Error al descargar");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4 className="mb-2">Descargar reporte</h4>
|
||||
<label htmlFor="fecha" className="text-sm font-medium">
|
||||
Selecciona una fecha de inicio
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
id="fecha"
|
||||
className="w-[280px] rounded-md border border-gray-300 p-2 text-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
|
||||
/>
|
||||
<p className="text-xs text-gray-500">fecha seleccionada: </p>
|
||||
{/*
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel>Seleccione una fecha de inicio:</FormLabel>
|
||||
<InputGroup>
|
||||
<DatePicker
|
||||
selected={selectedInicio}
|
||||
onChange={(date) => setSelectedInicio(date)}
|
||||
minDate={minDate}
|
||||
maxDate={maxDate}
|
||||
placeholderText="Seleccione una fecha de inicio"
|
||||
dateFormat="yyyy-MM-dd"
|
||||
className="form-control"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel>Seleccione una fecha de fin:</FormLabel>
|
||||
<InputGroup>
|
||||
<DatePicker
|
||||
selected={selectedFin}
|
||||
onChange={(date) => setSelectedFin(date)}
|
||||
minDate={minDate}
|
||||
maxDate={maxDate}
|
||||
placeholderText="Seleccione una fecha de fin"
|
||||
dateFormat="yyyy-MM-dd"
|
||||
className="form-control"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
*/}
|
||||
|
||||
<div>
|
||||
<Button variant="info" onClick={descargar} disabled={validarFechas()}>
|
||||
Descargar Excel
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user