Pull Lino
This commit is contained in:
@@ -1 +0,0 @@
|
||||
NEXT_PUBLIC_API_URL=
|
||||
Generated
+972
-370
File diff suppressed because it is too large
Load Diff
+8
-7
@@ -10,23 +10,24 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ericblade/quagga2": "^1.8.4",
|
||||
"@zxing/browser": "^0.1.5",
|
||||
"@zxing/library": "^0.21.3",
|
||||
"axios": "^1.13.1",
|
||||
"axios": "^1.13.2",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "15.5.6",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"next": "16.0.2",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-hot-toast": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "^20",
|
||||
"@types/node": "^24",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "15.5.6",
|
||||
"sass": "^1.93.2",
|
||||
"eslint-config-next": "16.0.2",
|
||||
"sass": "^1.94.0",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import Pregunta1 from "@/components/Equipo_Computo/Pregunta1";
|
||||
import Pregunta1_1 from "@/components/Equipo_Computo/Pregunta1_1";
|
||||
import Pregunta2_1 from "@/components/Equipo_Computo/Pregunta2_1";
|
||||
import Pregunta3 from "@/components/Equipo_Computo/Pregunta3";
|
||||
import Pregunta3_1 from "@/components/Equipo_Computo/Pregunta3_1";
|
||||
import Pregunta3_2 from "@/components/Equipo_Computo/Pregunta3_2";
|
||||
import Pregunta3_3 from "@/components/Equipo_Computo/Pregunta3_3";
|
||||
import Pregunta3_4 from "@/components/Equipo_Computo/Pregunta3_4";
|
||||
import Pregunta3_5 from "@/components/Equipo_Computo/Pregunta3_5";
|
||||
import Pregunta7 from "@/components/Equipo_Computo/Pregunta7";
|
||||
import Pregunta1EP from "@/components/Perifericos/Pregunta1EP";
|
||||
import Pregunta2EP from "@/components/Perifericos/Pregunta2EP";
|
||||
import Pregunta4EP from "@/components/Perifericos/Pregunta4EP";
|
||||
import Pregunta7EP from "@/components/Perifericos/Pregunta7EP";
|
||||
import Pregunta9 from "@/components/Equipo_Computo/Pregunta9";
|
||||
import "../../styles/layout/reporte.scss";
|
||||
|
||||
type PreguntaKey =
|
||||
| "pregunta1EP"
|
||||
| "pregunta2EP"
|
||||
| "pregunta4EP"
|
||||
| "pregunta7"
|
||||
|
||||
const LABELS: Record<PreguntaKey, string> = {
|
||||
pregunta1EP: "Pregunta 1 EP",
|
||||
pregunta2EP: "Pregunta 2 EP",
|
||||
pregunta4EP: "Pregunta 4 EP",
|
||||
pregunta7: "Pregunta 7",
|
||||
};
|
||||
|
||||
// Mapeo de fondo por pregunta (puedes personalizarlo)
|
||||
const TAB_BACKGROUNDS: Record<PreguntaKey, string> = {
|
||||
pregunta1EP: "bg-gray",
|
||||
pregunta2EP: "bg-gray",
|
||||
pregunta4EP: "bg-gray",
|
||||
pregunta7: "bg-gray",
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
const [activeTab, setActiveTab] = useState<PreguntaKey>("pregunta1EP");
|
||||
|
||||
const renderPregunta = () => {
|
||||
switch (activeTab) {
|
||||
case "pregunta1EP":
|
||||
return <Pregunta1EP />;
|
||||
case "pregunta2EP":
|
||||
return <Pregunta2EP />;
|
||||
case "pregunta4EP":
|
||||
return <Pregunta4EP />;
|
||||
case "pregunta7":
|
||||
return <Pregunta7 />;
|
||||
default:
|
||||
return (
|
||||
<div className="p-6 text-center text-gray-500">
|
||||
Contenido no disponible aún.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const currentBgClass = TAB_BACKGROUNDS[activeTab] || "bg-gray";
|
||||
|
||||
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 ${currentBgClass}`}>
|
||||
{renderPregunta()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
import { useState } from "react";
|
||||
import Pregunta1 from "@/components/Equipo_Computo/Pregunta1";
|
||||
import Pregunta1_1 from "@/components/Equipo_Computo/Pregunta1_1";
|
||||
import Pregunta2 from "@/components/Equipo_Computo/Pregunta2";
|
||||
import Pregunta2_1 from "@/components/Equipo_Computo/Pregunta2_1";
|
||||
import Pregunta3 from "@/components/Equipo_Computo/Pregunta3";
|
||||
import Pregunta3_1 from "@/components/Equipo_Computo/Pregunta3_1";
|
||||
@@ -16,7 +15,6 @@ import Pregunta9 from "@/components/Equipo_Computo/Pregunta9";
|
||||
import "../../styles/layout/reporte.scss";
|
||||
|
||||
type PreguntaKey =
|
||||
| "pregunta1_1"
|
||||
| "pregunta1"
|
||||
| "pregunta2_1"
|
||||
| "pregunta3"
|
||||
@@ -29,8 +27,7 @@ type PreguntaKey =
|
||||
| "pregunta9";
|
||||
|
||||
const LABELS: Record<PreguntaKey, string> = {
|
||||
pregunta1_1: "Pregunta 1 ",
|
||||
pregunta1: "Pregunta 2",
|
||||
pregunta1: "Pregunta 1 ",
|
||||
pregunta2_1: "Pregunta 2.1",
|
||||
pregunta3: "Pregunta 3",
|
||||
pregunta3_1: "Pregunta 3.1",
|
||||
@@ -44,8 +41,7 @@ const LABELS: Record<PreguntaKey, string> = {
|
||||
|
||||
// Mapeo de fondo por pregunta (puedes personalizarlo)
|
||||
const TAB_BACKGROUNDS: Record<PreguntaKey, string> = {
|
||||
pregunta1: "bg-blue",
|
||||
pregunta1_1: "bg-gray",
|
||||
pregunta1: "bg-gray",
|
||||
pregunta2_1: "bg-gray",
|
||||
pregunta3: "bg-gray",
|
||||
pregunta3_1: "bg-gray",
|
||||
@@ -57,13 +53,13 @@ const TAB_BACKGROUNDS: Record<PreguntaKey, string> = {
|
||||
pregunta9: "bg-blue",
|
||||
};
|
||||
|
||||
export default function Reporte() {
|
||||
export default function Page() {
|
||||
const [activeTab, setActiveTab] = useState<PreguntaKey>("pregunta1");
|
||||
|
||||
const renderPregunta = () => {
|
||||
switch (activeTab) {
|
||||
case "pregunta1_1":
|
||||
return <Pregunta1_1 />;
|
||||
case "pregunta1":
|
||||
return <Pregunta1 />;
|
||||
case "pregunta1":
|
||||
return <Pregunta1 />;
|
||||
case "pregunta2_1":
|
||||
|
||||
@@ -67,7 +67,10 @@ export default function Page() {
|
||||
<h3>Escanear Inventario</h3>
|
||||
|
||||
{isScanning ? (
|
||||
<BarcodeScanner onScan={handleScan} />
|
||||
<BarcodeScanner
|
||||
key="scanner"
|
||||
onScan={handleScan}
|
||||
/>
|
||||
) : (
|
||||
<div className="scannerFrame">
|
||||
<Image
|
||||
|
||||
@@ -11,12 +11,15 @@ import toast from "react-hot-toast";
|
||||
export default function Login() {
|
||||
const [nombre, setNombre] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${process.env.NEXT_PUBLIC_API_URL}/auth/login`,
|
||||
@@ -43,13 +46,15 @@ export default function Login() {
|
||||
} else {
|
||||
toast.error("Ocurrió un error inesperado");
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="containerGrid">
|
||||
<div className="login-container">
|
||||
<h2>Inicio de sesión</h2>
|
||||
<h2>Sistema de censo</h2>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div>
|
||||
<label>Usuario</label>
|
||||
@@ -71,7 +76,9 @@ export default function Login() {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type="submit">Iniciar sesión</button>
|
||||
<button type="submit" disabled={loading}>
|
||||
{loading ? "Buscando..." : "Iniciar sesión"}
|
||||
</button>
|
||||
|
||||
{/* <Link href={"/forgotPassword"}>Olvidaste Contraseña?</Link> */}
|
||||
{/* <Link href={"/crearCuenta"}>Crear Cuenta</Link> */}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "variables";
|
||||
@use "./variables" as *;
|
||||
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
|
||||
@@ -6,7 +6,6 @@ import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
import { AREAS } from "@/data/areas";
|
||||
import { SO_POR_EQUIPO } from "@/data/so_por_equipo";
|
||||
import { PROCESADORES_POR_EQUIPO } from "@/data/procesadores";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -133,7 +132,6 @@ export default function Page() {
|
||||
setAdscripciones(adscripcionesRes.data);
|
||||
setTiposEquipo(tiposEquipoRes.data);
|
||||
setSistemasOperativos(sistemasOperativosRes.data);
|
||||
console.log(adscripciones);
|
||||
} catch (err) {
|
||||
if (axios.isAxiosError(err)) {
|
||||
if (err.response) {
|
||||
@@ -200,9 +198,15 @@ export default function Page() {
|
||||
const textValue = value as string;
|
||||
setAdscripcionLabel(textValue);
|
||||
|
||||
const matches = AREAS.filter((a) =>
|
||||
a.label.toLowerCase().includes(textValue.toLowerCase())
|
||||
).map((a) => a.label);
|
||||
const normalize = (str: string) =>
|
||||
str
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.toLowerCase();
|
||||
|
||||
const matches = adscripciones
|
||||
.filter((a) => normalize(a.adscripcion).includes(normalize(textValue)))
|
||||
.map((a) => a.adscripcion);
|
||||
|
||||
setSuggestions((prev) => ({
|
||||
...prev,
|
||||
@@ -234,7 +238,6 @@ export default function Page() {
|
||||
};
|
||||
|
||||
const handleGuardar = async () => {
|
||||
|
||||
if (!formData.inventario) {
|
||||
toast.error("Inventario no encontrado");
|
||||
return;
|
||||
@@ -272,7 +275,11 @@ export default function Page() {
|
||||
}
|
||||
}
|
||||
|
||||
if(formData.id_tipo_equipo != 8 && formData.id_tipo_equipo != 7 && formData.id_tipo_equipo != 9){
|
||||
if (
|
||||
formData.id_tipo_equipo != 8 &&
|
||||
formData.id_tipo_equipo != 7 &&
|
||||
formData.id_tipo_equipo != 9
|
||||
) {
|
||||
if (!formData.id_sistema_operativo) {
|
||||
toast.error("Sistema operativo no encontrado ");
|
||||
return;
|
||||
@@ -422,13 +429,17 @@ export default function Page() {
|
||||
<div className="formGroup">
|
||||
<label>Procesador</label>
|
||||
<select
|
||||
disabled={formData.id_tipo_equipo ==0}
|
||||
disabled={formData.id_tipo_equipo == 0}
|
||||
value={formData.id_procesador}
|
||||
onChange={(e) =>
|
||||
handleInputChange("id_procesador", e.target.value)
|
||||
}
|
||||
>
|
||||
<option value="">{formData.id_tipo_equipo ? "Selecciona procesador":"Selecciona primero el tipo de equipo"}</option>
|
||||
<option value="">
|
||||
{formData.id_tipo_equipo
|
||||
? "Selecciona procesador"
|
||||
: "Selecciona primero el tipo de equipo"}
|
||||
</option>
|
||||
{PROCESADORES_POR_EQUIPO[formData.id_tipo_equipo]?.map(
|
||||
(p) => (
|
||||
<option key={p.id_procesador} value={p.id_procesador}>
|
||||
@@ -442,7 +453,7 @@ export default function Page() {
|
||||
<div className="formGroup">
|
||||
<label>Sistema operativo</label>
|
||||
<select
|
||||
disabled={formData.id_tipo_equipo ==0}
|
||||
disabled={formData.id_tipo_equipo == 0}
|
||||
value={formData.id_sistema_operativo}
|
||||
onChange={(e) =>
|
||||
handleInputChange(
|
||||
@@ -451,7 +462,11 @@ export default function Page() {
|
||||
)
|
||||
}
|
||||
>
|
||||
<option value="">{formData.id_tipo_equipo ? "Selecciona sistema operativo":"Selecciona primero el tipo de equipo"}</option>
|
||||
<option value="">
|
||||
{formData.id_tipo_equipo
|
||||
? "Selecciona sistema operativo"
|
||||
: "Selecciona primero el tipo de equipo"}
|
||||
</option>
|
||||
{SO_POR_EQUIPO[formData.id_tipo_equipo]?.map((so) => (
|
||||
<option
|
||||
key={so.id_sistema_operativo}
|
||||
@@ -502,13 +517,15 @@ export default function Page() {
|
||||
<li
|
||||
key={s}
|
||||
onClick={() => {
|
||||
const selected = AREAS.find((a) => a.label === s);
|
||||
const selected = adscripciones.find(
|
||||
(a) => a.adscripcion === s
|
||||
);
|
||||
if (selected) {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
id_adscripcion: selected.id,
|
||||
id_adscripcion: selected.id_adscripcion,
|
||||
}));
|
||||
setAdscripcionLabel(selected.label);
|
||||
setAdscripcionLabel(selected.adscripcion);
|
||||
setSuggestions((prev) => ({
|
||||
...prev,
|
||||
adscripcion: [],
|
||||
|
||||
@@ -1,99 +1,171 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import Quagga from "@ericblade/quagga2";
|
||||
|
||||
// Tipos para la configuración (opcional, pero mejora legibilidad)
|
||||
interface QuaggaConfig {
|
||||
inputStream: {
|
||||
name: string;
|
||||
type: string;
|
||||
target: HTMLElement;
|
||||
constraints: MediaTrackConstraints;
|
||||
};
|
||||
decoder: {
|
||||
readers: string[];
|
||||
};
|
||||
locate: boolean;
|
||||
}
|
||||
import { useEffect, useRef } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { BrowserMultiFormatReader } from "@zxing/browser";
|
||||
import { NotFoundException } from "@zxing/library";
|
||||
|
||||
interface BarcodeScannerProps {
|
||||
onScan: (code: string) => void;
|
||||
}
|
||||
|
||||
export default function BarcodeScanner({ onScan }: BarcodeScannerProps) {
|
||||
const scannerRef = useRef<HTMLDivElement>(null);
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const lastScan = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scannerRef.current) return;
|
||||
let stream: MediaStream | null = null;
|
||||
let animationFrame: number;
|
||||
let zxingReader: BrowserMultiFormatReader | null = null;
|
||||
let detector: any = null;
|
||||
|
||||
const config: QuaggaConfig = {
|
||||
inputStream: {
|
||||
name: "Live",
|
||||
type: "LiveStream",
|
||||
target: scannerRef.current,
|
||||
constraints: {
|
||||
width: 300,
|
||||
height: 500,
|
||||
facingMode: "environment",
|
||||
},
|
||||
},
|
||||
decoder: {
|
||||
readers: ["code_128_reader"],
|
||||
},
|
||||
locate: true,
|
||||
};
|
||||
|
||||
// El callback de error: tipamos `err` como `unknown`
|
||||
const initCallback = (err: unknown) => {
|
||||
if (err) {
|
||||
console.error("Error al iniciar el escáner:", err);
|
||||
return;
|
||||
/** 🚀 Intentar usar BarcodeDetector API (moderno) */
|
||||
const startBarcodeDetector = async () => {
|
||||
const supported = "BarcodeDetector" in window;
|
||||
if (!supported) {
|
||||
console.warn("BarcodeDetector no soportado, usando ZXing...");
|
||||
return startZXing();
|
||||
}
|
||||
|
||||
try {
|
||||
stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: { ideal: "environment" } }, // 👈 fuerza cámara trasera
|
||||
});
|
||||
|
||||
if (!videoRef.current) return;
|
||||
videoRef.current.srcObject = stream;
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
videoRef.current!.onloadedmetadata = async () => {
|
||||
try {
|
||||
await videoRef.current!.play();
|
||||
resolve();
|
||||
} catch {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
detector = new (window as any).BarcodeDetector({
|
||||
formats: ["code_128", "ean_13", "qr_code"],
|
||||
});
|
||||
|
||||
const detect = async () => {
|
||||
if (!videoRef.current) return;
|
||||
|
||||
if (videoRef.current.readyState < 2) {
|
||||
animationFrame = requestAnimationFrame(detect);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const barcodes = await detector.detect(videoRef.current);
|
||||
if (barcodes.length > 0) {
|
||||
const raw = barcodes[0].rawValue.trim();
|
||||
if (raw && raw !== lastScan.current) {
|
||||
lastScan.current = raw;
|
||||
const processed = raw.startsWith("0") ? raw.slice(1) : raw;
|
||||
onScan(processed);
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (
|
||||
err.message?.includes("Invalid element") ||
|
||||
err.name === "InvalidStateError"
|
||||
) {
|
||||
// ignorar mientras no haya frame válido
|
||||
} else {
|
||||
console.error("Error detectando código:", err);
|
||||
}
|
||||
}
|
||||
|
||||
animationFrame = requestAnimationFrame(detect);
|
||||
};
|
||||
|
||||
detect();
|
||||
} catch (err) {
|
||||
console.error("Error con BarcodeDetector:", err);
|
||||
toast.error("No se pudo acceder a la cámara");
|
||||
startZXing();
|
||||
}
|
||||
Quagga.start();
|
||||
};
|
||||
|
||||
Quagga.init(config as unknown as Record<string, unknown>, initCallback);
|
||||
const startZXing = async () => {
|
||||
try {
|
||||
zxingReader = new BrowserMultiFormatReader();
|
||||
const devices = await BrowserMultiFormatReader.listVideoInputDevices();
|
||||
|
||||
// Handler de detección: `data` es `unknown`, lo validamos
|
||||
const handleDetected = (data: unknown) => {
|
||||
// Validación segura
|
||||
if (
|
||||
data != null &&
|
||||
typeof data === "object" &&
|
||||
"codeResult" in data &&
|
||||
data.codeResult != null &&
|
||||
typeof data.codeResult === "object" &&
|
||||
"code" in data.codeResult &&
|
||||
typeof data.codeResult.code === "string"
|
||||
) {
|
||||
const code = data.codeResult.code.trim();
|
||||
if (code !== "") {
|
||||
onScan(code);
|
||||
Quagga.stop(); // Opcional
|
||||
if (devices.length === 0) {
|
||||
toast.error("No se detectó cámara disponible");
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔍 Intentar encontrar la cámara trasera
|
||||
const backCamera =
|
||||
devices.find((d) =>
|
||||
d.label.toLowerCase().includes("back")
|
||||
) || devices.find((d) =>
|
||||
d.label.toLowerCase().includes("rear")
|
||||
) || devices[devices.length - 1]; // fallback
|
||||
|
||||
const selectedDeviceId = backCamera.deviceId;
|
||||
|
||||
console.log("Usando cámara:", backCamera.label || selectedDeviceId);
|
||||
|
||||
await zxingReader.decodeFromVideoDevice(
|
||||
selectedDeviceId,
|
||||
videoRef.current!,
|
||||
(result, err) => {
|
||||
if (result) {
|
||||
const code = result.getText().trim();
|
||||
if (code && code !== lastScan.current) {
|
||||
lastScan.current = code;
|
||||
const processed = code.startsWith("0") ? code.slice(1) : code;
|
||||
onScan(processed);
|
||||
}
|
||||
} else if (err && !(err instanceof NotFoundException)) {
|
||||
console.error("Error ZXing:", err);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error al iniciar ZXing:", error);
|
||||
toast.error("Error al iniciar escáner");
|
||||
}
|
||||
};
|
||||
|
||||
Quagga.onDetected(handleDetected);
|
||||
startBarcodeDetector();
|
||||
|
||||
|
||||
return () => {
|
||||
Quagga.offDetected(handleDetected);
|
||||
Quagga.stop();
|
||||
if (animationFrame) cancelAnimationFrame(animationFrame);
|
||||
if (stream) stream.getTracks().forEach((t) => t.stop());
|
||||
|
||||
if (zxingReader) {
|
||||
if (typeof (zxingReader as any).stopContinuousDecode === "function") {
|
||||
(zxingReader as any).stopContinuousDecode();
|
||||
} else if (typeof (zxingReader as any).reset === "function") {
|
||||
(zxingReader as any).reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
}, [onScan]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={scannerRef}
|
||||
<video
|
||||
ref={videoRef}
|
||||
style={{
|
||||
width: "100%",
|
||||
maxWidth: "500px",
|
||||
maxWidth: "480px",
|
||||
height: "300px",
|
||||
borderRadius: "12px",
|
||||
overflow: "hidden",
|
||||
border: "2px solid #0056b3",
|
||||
borderRadius: "12px",
|
||||
objectFit: "cover",
|
||||
}}
|
||||
muted
|
||||
playsInline
|
||||
/>
|
||||
);
|
||||
}
|
||||
//Chatgpt
|
||||
//Gemini
|
||||
+43
-27
@@ -7,7 +7,6 @@ import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
import toast from "react-hot-toast";
|
||||
import { SO_POR_EQUIPO } from "@/data/so_por_equipo";
|
||||
import { AREAS } from "@/data/areas";
|
||||
import { PROCESADORES_POR_EQUIPO } from "@/data/procesadores";
|
||||
|
||||
import "../app/styles/layout/agregarEquipo.scss";
|
||||
@@ -34,7 +33,7 @@ export default function Editar() {
|
||||
observaciones: "",
|
||||
responsable: "",
|
||||
id_periferico: 0,
|
||||
fechaFactura: "",
|
||||
fechaMovimiento: "",
|
||||
});
|
||||
|
||||
interface TipoUso {
|
||||
@@ -159,7 +158,7 @@ export default function Editar() {
|
||||
inventario: string;
|
||||
serie: string;
|
||||
lugar: string;
|
||||
fechaFactura: string;
|
||||
fechaMovimiento: string;
|
||||
antiguedad: string;
|
||||
modelo: string;
|
||||
estado: { id_estado: number; estado: string };
|
||||
@@ -213,20 +212,20 @@ export default function Editar() {
|
||||
|
||||
setFormData({
|
||||
inventario: equipo.inventario || "",
|
||||
serie: equipo.serie || "",
|
||||
serie: (equipo.serie || "").toUpperCase(),
|
||||
id_marca: equipo.marca?.id_marca || 0,
|
||||
modelo: equipo.modelo || "",
|
||||
id_tipo_equipo: equipo.tipoEquipo?.id_tipo_de_equipo || 0,
|
||||
id_estado: equipo.estado?.id_estado || 0,
|
||||
id_sistema_operativo:
|
||||
equipo.sistemaOperativo?.id_sistema_operativo || 0,
|
||||
id_procesador:equipo.procesador?.id_procesador || 0,
|
||||
id_procesador: equipo.procesador?.id_procesador || 0,
|
||||
id_uso: equipo.tipoUso?.id_uso || 0,
|
||||
observaciones: equipo.observaciones || "",
|
||||
id_adscripcion: equipo.adscripcion?.id_adscripcion || 0,
|
||||
lugar: equipo.lugar || "",
|
||||
id_periferico: equipo.periferico?.id_periferico || 0,
|
||||
fechaFactura: equipo.fechaFactura || "",
|
||||
fechaMovimiento: equipo.fechaMovimiento || "",
|
||||
responsable,
|
||||
});
|
||||
|
||||
@@ -280,8 +279,6 @@ export default function Editar() {
|
||||
}, [formData.id_tipo_equipo]);
|
||||
|
||||
const handleGuardar = async () => {
|
||||
|
||||
|
||||
if (!formData.inventario) {
|
||||
toast.error("Inventario no encontrado");
|
||||
return;
|
||||
@@ -319,7 +316,11 @@ export default function Editar() {
|
||||
}
|
||||
}
|
||||
|
||||
if (formData.id_tipo_equipo != 8 && formData.id_tipo_equipo != 7 && formData.id_tipo_equipo != 9) {
|
||||
if (
|
||||
formData.id_tipo_equipo != 8 &&
|
||||
formData.id_tipo_equipo != 7 &&
|
||||
formData.id_tipo_equipo != 9
|
||||
) {
|
||||
if (!formData.id_sistema_operativo) {
|
||||
toast.error("Sistema operativo no encontrado ");
|
||||
return;
|
||||
@@ -350,14 +351,11 @@ export default function Editar() {
|
||||
};
|
||||
|
||||
try {
|
||||
await axios.patch(
|
||||
`${api_url}/equipos/update/${id}`,
|
||||
data,
|
||||
{
|
||||
headers,
|
||||
}
|
||||
);
|
||||
await axios.patch(`${api_url}/equipos/update/${id}`, data, {
|
||||
headers,
|
||||
});
|
||||
toast.success("Equipo actualizado correctamente");
|
||||
router.push("/escaner");
|
||||
} catch (error) {
|
||||
console.error("Error al guardar:", error);
|
||||
toast.error("Hubo un error al guardar el equipo.");
|
||||
@@ -372,9 +370,15 @@ export default function Editar() {
|
||||
const textValue = value as string;
|
||||
setAdscripcionLabel(textValue);
|
||||
|
||||
const matches = AREAS.filter((a) =>
|
||||
a.label.toLowerCase().includes(textValue.toLowerCase())
|
||||
).map((a) => a.label);
|
||||
const normalize = (str: string) =>
|
||||
str
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.toLowerCase();
|
||||
|
||||
const matches = adscripciones
|
||||
.filter((a) => normalize(a.adscripcion).includes(normalize(textValue)))
|
||||
.map((a) => a.adscripcion);
|
||||
|
||||
setSuggestions((prev) => ({
|
||||
...prev,
|
||||
@@ -425,8 +429,9 @@ export default function Editar() {
|
||||
const first = data[0];
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
responsable: `${first.nombre ?? ""} ${first.apellidos ?? ""
|
||||
}`.trim(),
|
||||
responsable: `${first.nombre ?? ""} ${
|
||||
first.apellidos ?? ""
|
||||
}`.trim(),
|
||||
}));
|
||||
} else {
|
||||
toast.error(
|
||||
@@ -460,7 +465,9 @@ export default function Editar() {
|
||||
<span>Inventario: {formData.inventario}</span>
|
||||
<span>
|
||||
Fecha de censo:{" "}
|
||||
{new Date(formData.fechaFactura).toLocaleDateString("es-MX")}
|
||||
{formData.fechaMovimiento
|
||||
? new Date(formData.fechaMovimiento).toLocaleDateString("es-MX")
|
||||
: "Sin fecha"}
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
@@ -474,7 +481,10 @@ export default function Editar() {
|
||||
value={formData.serie}
|
||||
placeholder="Ingresa serie"
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, serie: e.target.value })
|
||||
setFormData({
|
||||
...formData,
|
||||
serie: e.target.value.toUpperCase(),
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
@@ -578,7 +588,11 @@ export default function Editar() {
|
||||
handleInputChange("id_procesador", e.target.value)
|
||||
}
|
||||
>
|
||||
<option value="">{formData.id_tipo_equipo ? "Selecciona procesador" : "Selecciona primero el tipo de equipo"}</option>
|
||||
<option value="">
|
||||
{formData.id_tipo_equipo
|
||||
? "Selecciona procesador"
|
||||
: "Selecciona primero el tipo de equipo"}
|
||||
</option>
|
||||
{PROCESADORES_POR_EQUIPO[formData.id_tipo_equipo]?.map(
|
||||
(p) => (
|
||||
<option key={p.id_procesador} value={p.id_procesador}>
|
||||
@@ -648,13 +662,15 @@ export default function Editar() {
|
||||
<li
|
||||
key={s}
|
||||
onClick={() => {
|
||||
const selected = AREAS.find((a) => a.label === s);
|
||||
const selected = adscripciones.find(
|
||||
(a) => a.adscripcion === s
|
||||
);
|
||||
if (selected) {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
id_adscripcion: selected.id,
|
||||
id_adscripcion: selected.id_adscripcion,
|
||||
}));
|
||||
setAdscripcionLabel(selected.label);
|
||||
setAdscripcionLabel(selected.adscripcion);
|
||||
setSuggestions((prev) => ({
|
||||
...prev,
|
||||
adscripcion: [],
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ export function middleware(request: NextRequest) {
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: [],
|
||||
matcher: ["/escaner","/agregarEquipo","/editar"],
|
||||
};
|
||||
//IO
|
||||
|
||||
+19
-5
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
@@ -11,7 +15,7 @@
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
@@ -19,9 +23,19 @@
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user