added new grafics
This commit is contained in:
Generated
+762
-33
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -18,7 +18,9 @@
|
||||
"next": "^16.0.7",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-hot-toast": "^2.6.0"
|
||||
"react-hot-toast": "^2.6.0",
|
||||
"react-select": "^5.10.2",
|
||||
"recharts": "^3.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3",
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import "../../styles/layout/reporte.scss";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="scanView_reporte">
|
||||
<div className="container_reporte">
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import DownloadReporteXLSX from "@/components/Dowload/Reporte";
|
||||
import Reporte from "@/components/reporteGraficas/reporte";
|
||||
import Antiguedad from "@/components/AntiguedadEquipo/Antiguedad";
|
||||
|
||||
import "../../styles/layout/reporte.scss";
|
||||
|
||||
type PreguntaKey = "antiguedad" | "adscripcion";
|
||||
|
||||
const LABELS: Record<PreguntaKey, string> = {
|
||||
antiguedad: "Antigüedad",
|
||||
adscripcion: "Antigüedad por Adscripcion"
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
const [activeTab, setActiveTab] = useState<PreguntaKey>("antiguedad");
|
||||
|
||||
const renderPregunta = () => {
|
||||
switch (activeTab) {
|
||||
case "antiguedad":
|
||||
return (
|
||||
<Antiguedad />
|
||||
);
|
||||
case "adscripcion":
|
||||
return (
|
||||
<Reporte />
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<div className="p-6 text-center text-gray-500">
|
||||
Contenido no disponible aún.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="scanView_reporte">
|
||||
<div className="container_reporte">
|
||||
<div className="main-content_reporte">
|
||||
<div className="tabs_reporte">
|
||||
{Object.entries(LABELS).map(([key, label]) => (
|
||||
<button
|
||||
key={key}
|
||||
className={`tab_reporte ${activeTab === key ? "active" : ""}`}
|
||||
onClick={() => setActiveTab(key as PreguntaKey)}
|
||||
aria-selected={activeTab === key}
|
||||
role="tab"
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className={`data-table_reporte`}>{renderPregunta()}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
'use client'
|
||||
|
||||
import axios from "axios";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Bar, BarChart, CartesianGrid, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
|
||||
|
||||
interface antiguedad{
|
||||
antiguedad:string;
|
||||
total:number;
|
||||
}
|
||||
|
||||
export default function Antiguedad() {
|
||||
const [antiguedad,setAntiguedad]=useState<antiguedad[]>([])
|
||||
|
||||
useEffect(()=>{
|
||||
const getAntiguedad = async()=>{
|
||||
const response = await axios.get("http://localhost:3001/equipos/grafica")
|
||||
|
||||
setAntiguedad(response.data)
|
||||
}
|
||||
getAntiguedad()
|
||||
},[])
|
||||
|
||||
return (
|
||||
<ResponsiveContainer width="100%" aspect={2}>
|
||||
<BarChart data={antiguedad}
|
||||
width={500}
|
||||
height={300}
|
||||
margin={{
|
||||
top:20,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3"/>
|
||||
<XAxis dataKey="antiguedad"/>
|
||||
<YAxis/>
|
||||
<Tooltip/>
|
||||
<Legend/>
|
||||
<Bar dataKey="total" fill="#0d6efd"/>
|
||||
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
export default function FormEquipo() {
|
||||
return (
|
||||
<form>
|
||||
<label >Selecciona la antiguedad</label>
|
||||
<select>
|
||||
<option value=""></option>
|
||||
</select>
|
||||
<label>Selecciona la adscripcion</label>
|
||||
<select>
|
||||
<option value=""></option>
|
||||
</select>
|
||||
<label >Selecciona el edificio</label>
|
||||
<select>
|
||||
<option value=""></option>
|
||||
</select>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -49,6 +49,11 @@ function BarNavigation() {
|
||||
<span>Perifericos</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="subMenu" onClick={toggleMenu}>
|
||||
<Link href="/reportesGraficas" className="links">
|
||||
<span>Reportes y Graficas</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="subMenu">
|
||||
<button className="logout-button" onClick={cerrarSesion}>
|
||||
Cerrar sesión
|
||||
|
||||
@@ -40,19 +40,19 @@ export default function Pregunta7() {
|
||||
const antig = item.antiguedad?.toLowerCase().trim();
|
||||
|
||||
switch (antig) {
|
||||
case "Menor a 2 años":
|
||||
case "menor a 2 años":
|
||||
menor2 += total;
|
||||
break;
|
||||
|
||||
case "Entre 2 y 3 años":
|
||||
case "entre 2 y 3 años":
|
||||
entre2_3 += total;
|
||||
break;
|
||||
|
||||
case "Entre 4 y 5 años":
|
||||
case "entre 4 y 5 años":
|
||||
entre4_5 += total;
|
||||
break;
|
||||
|
||||
case "Mayor a 6 años":
|
||||
case "mayor a 6 años":
|
||||
mayor6 += total;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ function Header() {
|
||||
"/ranking",
|
||||
];
|
||||
|
||||
const privateNav = ["/equipoComputo", "/crearCuenta", "/perifericos"];
|
||||
const privateNav = ["/equipoComputo", "/crearCuenta", "/perifericos","/reportesGraficas"];
|
||||
|
||||
return (
|
||||
<header className={header.header}>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
.container{
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding:20px;
|
||||
background:white;
|
||||
border-radius:10px;
|
||||
box-shadow:0 2px 8px rgba(0,0,0,0.08);
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.title{
|
||||
font-size:18px;
|
||||
margin-bottom:15px;
|
||||
}
|
||||
|
||||
.label{
|
||||
font-size:13px;
|
||||
color:#444;
|
||||
}
|
||||
|
||||
.listaContainer{
|
||||
margin-top:20px;
|
||||
}
|
||||
|
||||
.subtitle{
|
||||
font-size:14px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
.empty{
|
||||
font-size:13px;
|
||||
color:#777;
|
||||
}
|
||||
|
||||
.lista{
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.chip{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
background:#f1f3f5;
|
||||
border-radius:20px;
|
||||
padding:5px 10px;
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
.remove{
|
||||
border:none;
|
||||
background:none;
|
||||
margin-left:6px;
|
||||
cursor:pointer;
|
||||
color:#777;
|
||||
}
|
||||
|
||||
.remove:hover{
|
||||
color:#c0392b;
|
||||
}
|
||||
|
||||
.button{
|
||||
margin-top:20px;
|
||||
padding:8px 14px;
|
||||
border:none;
|
||||
border-radius:6px;
|
||||
background:#2563eb;
|
||||
color:white;
|
||||
font-size:13px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.button:hover{
|
||||
background:#1d4ed8;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
"use client"
|
||||
|
||||
import Select from "react-select"
|
||||
import { useState } from "react"
|
||||
import styles from "./Reporte.module.css"
|
||||
|
||||
type AdscripcionOption = {
|
||||
value: string
|
||||
label: string
|
||||
}
|
||||
|
||||
export default function Reporte() {
|
||||
|
||||
const [adscripcionesSeleccionadas, setAdscripcionesSeleccionadas] = useState<AdscripcionOption[]>([])
|
||||
|
||||
const adscripciones: AdscripcionOption[] = [
|
||||
{ value: "informatica", label: "Informática" },
|
||||
{ value: "rh", label: "Recursos Humanos" },
|
||||
{ value: "finanzas", label: "Finanzas" },
|
||||
{ value: "juridico", label: "Jurídico" }
|
||||
]
|
||||
|
||||
const agregarAdscripcion = (option: AdscripcionOption | null) => {
|
||||
|
||||
if (!option) return
|
||||
|
||||
const existe = adscripcionesSeleccionadas.some(a => a.value === option.value)
|
||||
|
||||
if (!existe) {
|
||||
setAdscripcionesSeleccionadas([...adscripcionesSeleccionadas, option])
|
||||
}
|
||||
}
|
||||
|
||||
const eliminarAdscripcion = (value: string) => {
|
||||
setAdscripcionesSeleccionadas(
|
||||
adscripcionesSeleccionadas.filter(a => a.value !== value)
|
||||
)
|
||||
}
|
||||
|
||||
const generarReporte = () => {
|
||||
console.log("Adscripciones seleccionadas:", adscripcionesSeleccionadas)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<div className={styles.container}>
|
||||
|
||||
<h2 className={styles.title}>Reporte de Antigüedad de Equipos</h2>
|
||||
|
||||
<label className={styles.label}>Buscar adscripción</label>
|
||||
|
||||
<Select
|
||||
options={adscripciones}
|
||||
placeholder="Escribe para buscar..."
|
||||
onChange={(value) => agregarAdscripcion(value)}
|
||||
/>
|
||||
|
||||
<div className={styles.listaContainer}>
|
||||
|
||||
<h4 className={styles.subtitle}>
|
||||
Adscripciones seleccionadas ({adscripcionesSeleccionadas.length})
|
||||
</h4>
|
||||
|
||||
{adscripcionesSeleccionadas.length === 0 && (
|
||||
<p className={styles.empty}>No hay adscripciones seleccionadas</p>
|
||||
)}
|
||||
|
||||
<div className={styles.lista}>
|
||||
|
||||
{adscripcionesSeleccionadas.map((ads) => (
|
||||
<div key={ads.value} className={styles.chip}>
|
||||
|
||||
<span>{ads.label}</span>
|
||||
|
||||
<button
|
||||
className={styles.remove}
|
||||
onClick={() => eliminarAdscripcion(ads.value)}
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
|
||||
</div>
|
||||
))}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button
|
||||
className={styles.button}
|
||||
onClick={generarReporte}
|
||||
>
|
||||
Generar reporte
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { NextRequest } from "next/server";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
|
||||
const permisos: Record<number, string[]> = {
|
||||
1: ["/crearCuenta", "/equipoComputo", "/perifericos","/escaner", "/agregarEquipo", "/editar","/historial","/ranking","/cambiarPass"],
|
||||
1: ["/crearCuenta", "/equipoComputo", "/perifericos","/escaner", "/agregarEquipo", "/editar","/historial","/ranking","/cambiarPass","/reportesGraficas"],
|
||||
2: ["/escaner", "/agregarEquipo", "/editar","/historial","/ranking","/cambiarPass"],
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user