feat: add telefono field to AlumnosManual and AlumnosVista, update CursosVista to include competencias in course data

This commit is contained in:
BenitoBB 2025-05-12 08:47:29 -06:00
parent 502dc21401
commit 30dffd85e1
3 changed files with 67 additions and 12 deletions

View File

@ -38,6 +38,7 @@ export default function AlumnosManual() {
defaultValues: { defaultValues: {
nombre: "", nombre: "",
correo: "", correo: "",
telefono: "",
cursoSeleccionado: "", cursoSeleccionado: "",
}, },
}); });
@ -64,6 +65,7 @@ export default function AlumnosManual() {
{ {
nombre: data.nombre, nombre: data.nombre,
correo: data.correo, correo: data.correo,
telefono: data.telefono,
nombreCurso: data.cursoSeleccionado, // Guardar el nombre del curso nombreCurso: data.cursoSeleccionado, // Guardar el nombre del curso
}, },
]); ]);
@ -114,6 +116,19 @@ export default function AlumnosManual() {
</p> </p>
)} )}
</div> </div>
<div className="mb-3">
<Input
type="text"
placeholder="Teléfono"
{...register("telefono")}
className="w-full px-3 py-2 border border-gray-300 rounded-md"
/>
{errors.telefono && (
<p className="text-red-500 text-sm mt-1">
{errors.telefono.message}
</p>
)}
</div>
<div className="mb-4"> <div className="mb-4">
<Select <Select
onValueChange={(value) => setValue("cursoSeleccionado", value)} onValueChange={(value) => setValue("cursoSeleccionado", value)}

View File

@ -19,12 +19,14 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { set } from "react-hook-form";
export default function AlumnosVista() { export default function AlumnosVista() {
const [alumnos, setAlumnos] = useState([]); const [alumnos, setAlumnos] = useState([]);
const [alumnoEditando, setAlumnoEditando] = useState(null); const [alumnoEditando, setAlumnoEditando] = useState(null);
const [nuevoNombre, setNuevoNombre] = useState(""); const [nuevoNombre, setNuevoNombre] = useState("");
const [nuevoCorreo, setNuevoCorreo] = useState(""); const [nuevoCorreo, setNuevoCorreo] = useState("");
const [nuevoNumero, setNuevoNumero] = useState("");
const [mostrarModal, setMostrarModal] = useState(false); const [mostrarModal, setMostrarModal] = useState(false);
const [modalMensaje, setModalMensaje] = useState(""); const [modalMensaje, setModalMensaje] = useState("");
const [nuevoCurso, setNuevoCurso] = useState(""); const [nuevoCurso, setNuevoCurso] = useState("");
@ -49,7 +51,10 @@ export default function AlumnosVista() {
}; };
const cargarAlumnos = async () => { const cargarAlumnos = async () => {
const { data, error } = await supabaseClient.from("alumno").select("*"); const { data, error } = await supabaseClient
.from("alumno")
.select("id, nombre, correo, telefono, curso_id, curso(nombre)")
.order("id", { ascending: true });
if (error) { if (error) {
console.error("Error al cargar alumnos:", error.message); console.error("Error al cargar alumnos:", error.message);
} else { } else {
@ -62,7 +67,8 @@ export default function AlumnosVista() {
setAlumnoEditando(alumno.id); setAlumnoEditando(alumno.id);
setNuevoNombre(alumno.nombre); setNuevoNombre(alumno.nombre);
setNuevoCorreo(alumno.correo); setNuevoCorreo(alumno.correo);
setNuevoCurso(alumno.nombreCurso); setNuevoNumero(alumno.telefono);
setNuevoCurso(alumno.curso_id);
}; };
// Cancelar edición // Cancelar edición
@ -70,6 +76,7 @@ export default function AlumnosVista() {
setAlumnoEditando(null); setAlumnoEditando(null);
setNuevoNombre(""); setNuevoNombre("");
setNuevoCorreo(""); setNuevoCorreo("");
setNuevoNumero("");
setNuevoCurso(""); setNuevoCurso("");
}; };
@ -80,7 +87,8 @@ export default function AlumnosVista() {
.update({ .update({
nombre: nuevoNombre, nombre: nuevoNombre,
correo: nuevoCorreo, correo: nuevoCorreo,
nombreCurso: nuevoCurso, telefono: nuevoNumero,
curso_id: nuevoCurso,
}) })
.eq("id", id); .eq("id", id);
@ -127,6 +135,7 @@ export default function AlumnosVista() {
<th className="py-2 border-b">ID</th> <th className="py-2 border-b">ID</th>
<th className="py-2 border-b">Nombre</th> <th className="py-2 border-b">Nombre</th>
<th className="py-2 border-b">Correo</th> <th className="py-2 border-b">Correo</th>
<th className="py-2 border-b">Teléfono</th>
<th className="py-2 border-b">Curso</th> <th className="py-2 border-b">Curso</th>
<th className="py-2 border-b">Acciones</th> <th className="py-2 border-b">Acciones</th>
</tr> </tr>
@ -152,6 +161,13 @@ export default function AlumnosVista() {
onChange={(e) => setNuevoCorreo(e.target.value)} onChange={(e) => setNuevoCorreo(e.target.value)}
/> />
</td> </td>
<td className="py-2 px-4 border-b">
<Input
type="text"
value={nuevoNumero}
onChange={(e) => setNuevoNumero(e.target.value)}
/>
</td>
<td className="py-2 px-4 border-b"> <td className="py-2 px-4 border-b">
<Select <Select
value={nuevoCurso} value={nuevoCurso}
@ -162,7 +178,7 @@ export default function AlumnosVista() {
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{cursos.map((curso) => ( {cursos.map((curso) => (
<SelectItem key={curso.id} value={curso.nombre}> <SelectItem key={curso.id} value={curso.id.toString()}>
{curso.nombre} {curso.nombre}
</SelectItem> </SelectItem>
))} ))}
@ -189,7 +205,8 @@ export default function AlumnosVista() {
<td className="py-2 px-4 border-b">{alumno.id}</td> <td className="py-2 px-4 border-b">{alumno.id}</td>
<td className="py-2 px-4 border-b">{alumno.nombre}</td> <td className="py-2 px-4 border-b">{alumno.nombre}</td>
<td className="py-2 px-4 border-b">{alumno.correo}</td> <td className="py-2 px-4 border-b">{alumno.correo}</td>
<td className="py-2 px-4 border-b">{alumno.nombreCurso}</td> <td className="py-2 px-4 border-b">{alumno.telefono}</td>
<td className="py-2 px-4 border-b">{alumno.curso?.nombre || "Sin curso"}</td>
<td className="py-2 px-4 border-b space-x-2"> <td className="py-2 px-4 border-b space-x-2">
<Button <Button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-3 rounded" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-3 rounded"

View File

@ -31,11 +31,30 @@ export default function CursosVista() {
}, []); }, []);
const cargarCursos = async () => { const cargarCursos = async () => {
const { data, error } = await supabaseClient.from("curso").select("*"); const { data, error } = await supabaseClient
.from("curso")
.select(`
id,
nombre,
descripcion,
horas,
curso_competencia (
competencia (
id,
nombre
)
)
`)
.order("id", { ascending: true });
if (error) { if (error) {
console.error("Error al cargar cursos:", error.message); console.error("Error al cargar cursos:", error.message);
} else { } else {
setCursos(data); // Transformar los datos para que las competencias estén directamente en el objeto curso
const cursosConCompetencias = data.map((curso) => ({
...curso,
competencias: curso.curso_competencia.map((cc) => cc.competencia),
}));
setCursos(cursosConCompetencias);
} }
}; };
@ -62,7 +81,7 @@ export default function CursosVista() {
nombre: nuevoNombre, nombre: nuevoNombre,
descripcion: nuevaDescripcion, descripcion: nuevaDescripcion,
horas: nuevaHoras, horas: nuevaHoras,
competencias: competenciasGuardadas, //competencias: competenciasGuardadas,
}) })
.eq("id", id); .eq("id", id);
@ -105,6 +124,7 @@ export default function CursosVista() {
<table className="min-w-full bg-white border"> <table className="min-w-full bg-white border">
<thead> <thead>
<tr className="bg-gray-100"> <tr className="bg-gray-100">
<th className="py-2 border-b">ID</th>
<th className="py-2 border-b">Nombre</th> <th className="py-2 border-b">Nombre</th>
<th className="py-2 border-b">Descripción</th> <th className="py-2 border-b">Descripción</th>
<th className="py-2 border-b">Horas</th> <th className="py-2 border-b">Horas</th>
@ -116,6 +136,7 @@ export default function CursosVista() {
{cursos.map((curso) => {cursos.map((curso) =>
cursoEditando === curso.id ? ( cursoEditando === curso.id ? (
<tr key={curso.id}> <tr key={curso.id}>
<td className="py-2 px-4 border-b text-center">{curso.id}</td>
<td className="py-2 px-4 border-b"> <td className="py-2 px-4 border-b">
<Input <Input
value={nuevoNombre} value={nuevoNombre}
@ -166,17 +187,19 @@ export default function CursosVista() {
<td className="py-2 px-4 border-b">{curso.descripcion}</td> <td className="py-2 px-4 border-b">{curso.descripcion}</td>
<td className="py-2 px-4 border-b">{curso.horas}</td> <td className="py-2 px-4 border-b">{curso.horas}</td>
<td className="py-2 px-4 border-b"> <td className="py-2 px-4 border-b">
{curso.competencias.join(", ")} {Array.isArray(curso.competencias) && curso.competencias.length > 0
? curso.competencias.map((comp) => comp.nombre).join(", ")
: "Sin competencias"}
</td> </td>
<td className="py-2 border-b flex"> <td className="py-2 px-4 border-b space-x-2">
<Button <Button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-3 rounded m-1" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-3 rounded"
onClick={() => iniciarEdicion(curso)} onClick={() => iniciarEdicion(curso)}
> >
Editar Editar
</Button> </Button>
<Button <Button
className="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-3 rounded m-1" className="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-3 rounded"
onClick={() => confirmarEliminacion(curso.id)} onClick={() => confirmarEliminacion(curso.id)}
> >
Eliminar Eliminar