added equipo by student
This commit is contained in:
@@ -24,7 +24,7 @@ export default async function Page(props: {
|
|||||||
errorMessage = `${result.error}`;
|
errorMessage = `${result.error}`;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
student = result;
|
student = result[0]?.alumno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import { envConfig } from "@/app/lib/config";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
inscripcion: any[];
|
||||||
|
idCuenta: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function PlaticaGate({ inscripcion, idCuenta }: Props) {
|
||||||
|
const [puedeContinuar, setPuedeContinuar] = useState(false);
|
||||||
|
const [equipos, setEquipos] = useState<any[]>([]);
|
||||||
|
const [loadingEquipos, setLoadingEquipos] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!Array.isArray(inscripcion) || inscripcion.length === 0) return;
|
||||||
|
|
||||||
|
const todasAsistieron = inscripcion.every(
|
||||||
|
(ins) => ins.platica?.data?.[0] === 1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!todasAsistieron) {
|
||||||
|
toast.error("El alumno no asistió a todas las pláticas", {
|
||||||
|
position: "top-right",
|
||||||
|
autoClose: 4000,
|
||||||
|
});
|
||||||
|
setPuedeContinuar(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPuedeContinuar(true);
|
||||||
|
}, [inscripcion]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!puedeContinuar || !idCuenta) return;
|
||||||
|
|
||||||
|
const fetchEquipos = async () => {
|
||||||
|
try {
|
||||||
|
setLoadingEquipos(true);
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
`${envConfig.apiUrl}/equipo/student/${idCuenta}`,
|
||||||
|
{
|
||||||
|
cache: "no-store",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error("No se pudieron cargar los equipos");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
setEquipos(data);
|
||||||
|
} catch (error) {
|
||||||
|
toast.error("Error al cargar equipos disponibles");
|
||||||
|
} finally {
|
||||||
|
setLoadingEquipos(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchEquipos();
|
||||||
|
}, [puedeContinuar, idCuenta]);
|
||||||
|
|
||||||
|
if (!puedeContinuar) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="containerForm">
|
||||||
|
<label style={{ marginTop: "1rem" }}>
|
||||||
|
Seleccionar tiempo
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<select>
|
||||||
|
<option>6 minutos</option>
|
||||||
|
<option>15 minutos</option>
|
||||||
|
<option>30 minutos</option>
|
||||||
|
<option>40 minutos</option>
|
||||||
|
<option>60 minutos</option>
|
||||||
|
<option>90 minutos</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label style={{ marginTop: "1rem" }}>
|
||||||
|
Seleccione un equipo
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div className="groupInput">
|
||||||
|
<select disabled={loadingEquipos || equipos.length === 0}>
|
||||||
|
{loadingEquipos && (
|
||||||
|
<option>Cargando equipos...</option>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!loadingEquipos && equipos.length === 0 && (
|
||||||
|
<option>No hay equipos disponibles</option>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!loadingEquipos &&
|
||||||
|
equipos.map((eq) => (
|
||||||
|
<option key={eq.id_equipo} value={eq.id_equipo}>
|
||||||
|
{eq.ubicacion} {eq.nombre_equipo} ({eq.plataforma?.nombre})
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="button buttonSearch"
|
||||||
|
disabled={loadingEquipos || equipos.length === 0}
|
||||||
|
>
|
||||||
|
Asignar Equipo
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
|
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
|
||||||
import Toggle from "@/app/Components/Global/Toggle/Toggle";
|
import Toggle from "@/app/Components/Global/Toggle/Toggle";
|
||||||
import { GetStudent } from "@/app/lib/getStudent";
|
|
||||||
|
|
||||||
import CheckBoxEquipo from "@/app/Components/CheckBoxEquipo";
|
import CheckBoxEquipo from "@/app/Components/CheckBoxEquipo";
|
||||||
import Information from "@/app/Components/Global/Information/information";
|
import Information from "@/app/Components/Global/Information/information";
|
||||||
import ShowError from "@/app/Components/Global/ShowError";
|
import ShowError from "@/app/Components/Global/ShowError";
|
||||||
|
|
||||||
import "@/app/globals.css";
|
|
||||||
import Table from "@/app/Components/Global/table";
|
import Table from "@/app/Components/Global/table";
|
||||||
|
|
||||||
import { envConfig } from "@/app/lib/config";
|
import { envConfig } from "@/app/lib/config";
|
||||||
|
import { GetRegisterStudent } from "@/app/lib/getRegisterStudent";
|
||||||
|
import "@/app/globals.css";
|
||||||
|
import PlaticaGate from "./PlaticaGate";
|
||||||
|
|
||||||
async function getInscripcion(idCuenta: number) {
|
async function getInscripcion(idCuenta: number) {
|
||||||
try {
|
try {
|
||||||
@@ -45,17 +46,24 @@ export default async function Page(props: {
|
|||||||
const machine = params?.machine ? params.machine : null;
|
const machine = params?.machine ? params.machine : null;
|
||||||
|
|
||||||
let student: any = null;
|
let student: any = null;
|
||||||
|
let platica: any = null;
|
||||||
let inscripcion: any = null;
|
let inscripcion: any = null;
|
||||||
let errorMessage = "";
|
let errorMessage = "";
|
||||||
|
|
||||||
if (numAcount) {
|
if (numAcount) {
|
||||||
const idCuenta = parseInt(numAcount);
|
const idCuenta = parseInt(numAcount);
|
||||||
|
|
||||||
const result = await GetStudent(idCuenta);
|
const result = await GetRegisterStudent(idCuenta);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
errorMessage = `${result.error}`;
|
errorMessage = `${result.error}`;
|
||||||
} else {
|
} else {
|
||||||
student = result as Student;
|
student = result[0]?.alumno as Student;
|
||||||
|
const rawPlatica = result[0]?.platica;
|
||||||
|
platica =
|
||||||
|
rawPlatica?.type === "Buffer"
|
||||||
|
? Boolean(rawPlatica.data[0])
|
||||||
|
: Boolean(rawPlatica);
|
||||||
|
console.log(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const inscResult = await getInscripcion(idCuenta);
|
const inscResult = await getInscripcion(idCuenta);
|
||||||
@@ -72,7 +80,7 @@ export default async function Page(props: {
|
|||||||
Tiempo: ins.tiempo_disponible
|
Tiempo: ins.tiempo_disponible
|
||||||
? `${ins.tiempo_disponible} minutos`
|
? `${ins.tiempo_disponible} minutos`
|
||||||
: "—",
|
: "—",
|
||||||
Confirmó: ins.platica.data === 1 ? "sí" : "no",
|
Confirmó: ins.platica.data?.[0] === 1 ? "sí" : "no",
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
@@ -99,21 +107,8 @@ export default async function Page(props: {
|
|||||||
nombre={student.nombre}
|
nombre={student.nombre}
|
||||||
/>
|
/>
|
||||||
<Table headers={headers} data={tableData} />
|
<Table headers={headers} data={tableData} />
|
||||||
<div className="containerForm">
|
|
||||||
<label style={{ marginTop: "1rem" }}>
|
<PlaticaGate inscripcion={inscripcion} idCuenta={student.id_cuenta}/>
|
||||||
Seleccionar tiempo
|
|
||||||
</label>
|
|
||||||
<select></select>
|
|
||||||
<label style={{ marginTop: "1rem" }}>
|
|
||||||
Seleccione un equipo
|
|
||||||
</label>
|
|
||||||
<div className="groupInput">
|
|
||||||
<select></select>
|
|
||||||
<button className="button buttonSearch">
|
|
||||||
Asignar Equipo
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
'use client'
|
"use client";
|
||||||
|
|
||||||
import Toggle from "@/app/Components/Global/Toggle/Toggle";
|
import Toggle from "@/app/Components/Global/Toggle/Toggle";
|
||||||
import Equipos from "@/app/Components/Equipos/equipos";
|
import Equipos from "@/app/Components/Equipos/equipos";
|
||||||
@@ -7,6 +7,7 @@ import SelectorSala from "@/app/Components/InformacionEquipos/SelectorSala";
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import "./informacionequipo.css";
|
import "./informacionequipo.css";
|
||||||
|
import SelectorEquipo from "@/app/Components/InformacionEquipos/SelectorEquipo";
|
||||||
|
|
||||||
export default function InformacionEquipo({
|
export default function InformacionEquipo({
|
||||||
defaultKey,
|
defaultKey,
|
||||||
@@ -30,7 +31,16 @@ export default function InformacionEquipo({
|
|||||||
{
|
{
|
||||||
key: "Equipo",
|
key: "Equipo",
|
||||||
label: "Programa por equipo",
|
label: "Programa por equipo",
|
||||||
content: <ProgramSelector />,
|
content: (
|
||||||
|
<>
|
||||||
|
<SelectorEquipo
|
||||||
|
onSearch={(sala) => {
|
||||||
|
setId(sala);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProgramSelector />,
|
||||||
|
</>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Sala",
|
key: "Sala",
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default async function Page(props: {
|
|||||||
Tiempo: ins.tiempo_disponible
|
Tiempo: ins.tiempo_disponible
|
||||||
? `${ins.tiempo_disponible} minutos`
|
? `${ins.tiempo_disponible} minutos`
|
||||||
: "—",
|
: "—",
|
||||||
Confirmó: ins.platica.data === 1 ? "sí" : "no",
|
Confirmó: ins.platica.data?.[0] === 1 ? "sí" : "no",
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
|||||||
@@ -5,29 +5,36 @@ import SearchUser from "./Global/SearchUser/searchUser";
|
|||||||
import SearchBoxEquipo from "./SearchEquipo";
|
import SearchBoxEquipo from "./SearchEquipo";
|
||||||
|
|
||||||
export default function CheckBoxEquipo() {
|
export default function CheckBoxEquipo() {
|
||||||
const [Checkbox, setChecbox] = useState<string | null>(null);
|
const [modo, setModo] = useState<"Equipo" | "Cuenta" | null>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="checkbox-grid">
|
<div className="radio-grid">
|
||||||
<label>
|
<label className="radio-card">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="radio"
|
||||||
onChange={() => setChecbox(Checkbox === "Equipo" ? null : "Equipo")}
|
name="modo"
|
||||||
checked={Checkbox === "Mesa"}
|
checked={modo === "Equipo"}
|
||||||
/>{" "}
|
onChange={() => setModo("Equipo")}
|
||||||
Equipo
|
/>
|
||||||
|
<span className="radio-ui"></span>
|
||||||
|
<span className="radio-text">Equipo</span>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
|
||||||
|
<label className="radio-card">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="radio"
|
||||||
onChange={() => setChecbox(Checkbox === "Cuenta" ? null : "Cuenta")}
|
name="modo"
|
||||||
checked={Checkbox === "Cuenta"}
|
checked={modo === "Cuenta"}
|
||||||
/>{" "}
|
onChange={() => setModo("Cuenta")}
|
||||||
Cuenta
|
/>
|
||||||
|
<span className="radio-ui"></span>
|
||||||
|
<span className="radio-text">Cuenta</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{Checkbox === "Cuenta" ? <SearchUser value={"3"} /> : <></>}
|
|
||||||
{Checkbox === "Equipo" ? <SearchBoxEquipo /> : <></>}
|
{modo === "Cuenta" && <SearchUser value={"3"} />}
|
||||||
|
{modo === "Equipo" && <SearchBoxEquipo />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
"use client";
|
||||||
|
import { envConfig } from "@/app/lib/config";
|
||||||
|
import axios from "axios";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
interface Equipos {
|
||||||
|
id_equipo: number;
|
||||||
|
id_plataforma: number;
|
||||||
|
id_area_ubicacion: number;
|
||||||
|
nombre_equipo: string;
|
||||||
|
ubicacion: string;
|
||||||
|
activo: boolean;
|
||||||
|
ip: string;
|
||||||
|
areaUbicacion:{area:string}
|
||||||
|
plataforma:{nombre:string}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
onSearch: (id: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SelectorEquipo({ onSearch }: Props) {
|
||||||
|
const [sala, setSala] = useState<Equipos[]>();
|
||||||
|
const [selected, setSelected] = useState<number>();
|
||||||
|
|
||||||
|
const handleChangeEquipo = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
setSelected(Number(e.target.value));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!selected) return;
|
||||||
|
onSearch(selected);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
|
||||||
|
|
||||||
|
setSala(response.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="form-container" onSubmit={handleSubmit}>
|
||||||
|
<select value={selected} onChange={handleChangeEquipo}>
|
||||||
|
<option value="">-- Selecciona una equipo --</option>
|
||||||
|
{sala &&
|
||||||
|
sala.map((eq) => (
|
||||||
|
<option key={eq.id_equipo} value={eq.id_equipo}>
|
||||||
|
{eq.ubicacion } {eq.nombre_equipo} {eq.plataforma.nombre} {eq.areaUbicacion.area}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { envConfig } from "@/app/lib/config";
|
import { envConfig } from "@/app/lib/config";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { use, useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
interface Area {
|
interface Area {
|
||||||
id_area_ubicacion: number;
|
id_area_ubicacion: number;
|
||||||
|
|||||||
@@ -160,6 +160,79 @@ input[type="checkbox"] {
|
|||||||
min-width: 3rem;
|
min-width: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio-grid {
|
||||||
|
display: flex;
|
||||||
|
gap: 2rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1.2rem 1.8rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 2px solid #e5e7eb;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #fff;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-card:hover {
|
||||||
|
border-color: #002b7f;
|
||||||
|
background: rgba(0, 43, 127, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-card input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-ui {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
border: 2px solid #002b7f;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-ui::after {
|
||||||
|
content: "";
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: #c9a227;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-card input:checked + .radio-ui::after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-card input:checked ~ .radio-text {
|
||||||
|
color: #002b7f;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-card input:checked {
|
||||||
|
+ .radio-ui {
|
||||||
|
border-color: #002b7f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.radio-grid {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
Reference in New Issue
Block a user