feat: update Alumnos schema to clarify type selection and enhance data loading in AlumnosVista and AlumnosManual
This commit is contained in:
parent
814354baac
commit
d7562fa4ab
|
@ -11,7 +11,6 @@ import {
|
|||
} from "@/components/ui/select";
|
||||
import {
|
||||
Dialog,
|
||||
DialogTrigger,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
|
@ -24,61 +23,99 @@ import { alumnoSchema } from "@/schemas/AlumnosSchema";
|
|||
|
||||
export default function AlumnosManual() {
|
||||
const [cursos, setCursos] = useState([]);
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false); // Estado para controlar el diálogo
|
||||
const [inyecciones, setInyecciones] = useState([]);
|
||||
const [pildoras, setPildoras] = useState([]);
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
|
||||
// Configurar React Hook Form con zod
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
watch,
|
||||
formState: { errors },
|
||||
reset,
|
||||
clearErrors,
|
||||
} = useForm({
|
||||
resolver: zodResolver(alumnoSchema),
|
||||
defaultValues: {
|
||||
nombre: "",
|
||||
correo: "",
|
||||
telefono: "",
|
||||
tipo: "",
|
||||
cursoSeleccionado: "",
|
||||
},
|
||||
});
|
||||
|
||||
// Cargar cursos al iniciar el componente
|
||||
const tipo = watch("tipo");
|
||||
const cursoSeleccionado = watch("cursoSeleccionado");
|
||||
|
||||
// Cargar opciones según tipo seleccionado
|
||||
useEffect(() => {
|
||||
const cargarCursos = async () => {
|
||||
const { data, error } = await supabaseClient
|
||||
.from("curso")
|
||||
.select("id, nombre");
|
||||
if (error) {
|
||||
console.error("Error al cargar cursos:", error.message);
|
||||
} else {
|
||||
setCursos(data);
|
||||
}
|
||||
};
|
||||
cargarCursos();
|
||||
}, []);
|
||||
if (!tipo) {
|
||||
setValue("cursoSeleccionado", "");
|
||||
clearErrors("cursoSeleccionado");
|
||||
return;
|
||||
}
|
||||
setValue("cursoSeleccionado", "");
|
||||
clearErrors("cursoSeleccionado");
|
||||
if (tipo === "curso") {
|
||||
cargarCursos();
|
||||
} else if (tipo === "inyeccion") {
|
||||
cargarInyecciones();
|
||||
} else if (tipo === "pildora") {
|
||||
cargarPildoras();
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [tipo]);
|
||||
|
||||
const cargarCursos = async () => {
|
||||
const { data, error } = await supabaseClient
|
||||
.from("curso")
|
||||
.select("id, nombre");
|
||||
if (!error) setCursos(data || []);
|
||||
};
|
||||
const cargarInyecciones = async () => {
|
||||
const { data, error } = await supabaseClient
|
||||
.from("inyeccion")
|
||||
.select("id, nombre");
|
||||
if (!error) setInyecciones(data || []);
|
||||
};
|
||||
const cargarPildoras = async () => {
|
||||
const { data, error } = await supabaseClient
|
||||
.from("pildoras")
|
||||
.select("id, nombre");
|
||||
if (!error) setPildoras(data || []);
|
||||
};
|
||||
|
||||
// Guardar alumno
|
||||
const manejarGuardar = async (data) => {
|
||||
try {
|
||||
const { error } = await supabaseClient.from("alumno").insert([
|
||||
{
|
||||
nombre: data.nombre,
|
||||
correo: data.correo,
|
||||
telefono: data.telefono,
|
||||
curso_id: Number(data.cursoSeleccionado), // Guardar el ID del curso
|
||||
},
|
||||
]);
|
||||
let campos = {
|
||||
nombre: data.nombre,
|
||||
correo: data.correo,
|
||||
telefono: data.telefono,
|
||||
tipo_formacion: data.tipo,
|
||||
curso_id: null,
|
||||
inyeccion_id: null,
|
||||
pildoras_id: null,
|
||||
};
|
||||
if (data.tipo === "curso")
|
||||
campos.curso_id = Number(data.cursoSeleccionado);
|
||||
if (data.tipo === "inyeccion")
|
||||
campos.inyeccion_id = Number(data.cursoSeleccionado);
|
||||
if (data.tipo === "pildora")
|
||||
campos.pildoras_id = Number(data.cursoSeleccionado);
|
||||
|
||||
const { error } = await supabaseClient.from("alumno").insert([campos]);
|
||||
|
||||
if (error) {
|
||||
console.error("Error al guardar:", error.message);
|
||||
setIsDialogOpen(false); // Asegurarse de cerrar el diálogo en caso de error
|
||||
setIsDialogOpen(false);
|
||||
} else {
|
||||
setIsDialogOpen(true); // Mostrar el diálogo al guardar exitosamente
|
||||
reset(); // Reiniciar el formulario
|
||||
setIsDialogOpen(true);
|
||||
reset();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error inesperado:", err);
|
||||
// Manejo de error inesperado
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -118,20 +155,77 @@ export default function AlumnosManual() {
|
|||
{errors.telefono.message}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* Select para tipo de formación */}
|
||||
<Select
|
||||
onValueChange={(value) => setValue("cursoSeleccionado", value)}
|
||||
value={tipo}
|
||||
onValueChange={(value) => setValue("tipo", value)}
|
||||
>
|
||||
<SelectTrigger className="w-full px-3 py-2 border border-gray-300 rounded-md mb-3">
|
||||
<SelectValue placeholder="Selecciona un curso" />
|
||||
<SelectValue placeholder="Selecciona tipo de formación" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{cursos.map((curso) => (
|
||||
<SelectItem key={curso.id} value={curso.id.toString()}>
|
||||
{curso.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
<SelectItem value="curso">Curso</SelectItem>
|
||||
<SelectItem value="inyeccion">Inyección</SelectItem>
|
||||
<SelectItem value="pildora">Píldora</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.tipo && (
|
||||
<p className="text-red-500 text-sm mt-1">{errors.tipo.message}</p>
|
||||
)}
|
||||
|
||||
{/* Select para la opción según tipo */}
|
||||
{tipo === "curso" && (
|
||||
<Select
|
||||
value={cursoSeleccionado}
|
||||
onValueChange={(value) => setValue("cursoSeleccionado", value)}
|
||||
>
|
||||
<SelectTrigger className="w-full px-3 py-2 border border-gray-300 rounded-md mb-3">
|
||||
<SelectValue placeholder="Selecciona un curso" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{cursos.map((curso) => (
|
||||
<SelectItem key={curso.id} value={curso.id.toString()}>
|
||||
{curso.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
{tipo === "inyeccion" && (
|
||||
<Select
|
||||
value={cursoSeleccionado}
|
||||
onValueChange={(value) => setValue("cursoSeleccionado", value)}
|
||||
>
|
||||
<SelectTrigger className="w-full px-3 py-2 border border-gray-300 rounded-md mb-3">
|
||||
<SelectValue placeholder="Selecciona una inyección" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{inyecciones.map((iny) => (
|
||||
<SelectItem key={iny.id} value={iny.id.toString()}>
|
||||
{iny.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
{tipo === "pildora" && (
|
||||
<Select
|
||||
value={cursoSeleccionado}
|
||||
onValueChange={(value) => setValue("cursoSeleccionado", value)}
|
||||
>
|
||||
<SelectTrigger className="w-full px-3 py-2 border border-gray-300 rounded-md mb-3">
|
||||
<SelectValue placeholder="Selecciona una píldora" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{pildoras.map((p) => (
|
||||
<SelectItem key={p.id} value={p.id.toString()}>
|
||||
{p.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
{errors.cursoSeleccionado && (
|
||||
<p className="text-red-500 text-sm mt-1">
|
||||
{errors.cursoSeleccionado.message}
|
||||
|
|
|
@ -45,6 +45,9 @@ export default function AlumnosVista() {
|
|||
useEffect(() => {
|
||||
cargarAlumnos();
|
||||
// ...cargar cursos, inyecciones, pildoras...
|
||||
cargarCursos();
|
||||
cargarInyecciones();
|
||||
cargarPildoras();
|
||||
}, []);
|
||||
|
||||
const cargarCursos = async () => {
|
||||
|
@ -56,10 +59,21 @@ export default function AlumnosVista() {
|
|||
}
|
||||
};
|
||||
|
||||
const cargarInyecciones = async () => {
|
||||
const { data, error } = await supabaseClient.from("inyeccion").select("*");
|
||||
if (!error) setInyecciones(data || []);
|
||||
};
|
||||
|
||||
const cargarPildoras = async () => {
|
||||
const { data, error } = await supabaseClient.from("pildoras").select("*");
|
||||
if (!error) setPildoras(data || []);
|
||||
};
|
||||
|
||||
const cargarAlumnos = async () => {
|
||||
const { data, error } = await supabaseClient
|
||||
.from("alumno")
|
||||
.select(`
|
||||
.select(
|
||||
`
|
||||
id,
|
||||
nombre,
|
||||
correo,
|
||||
|
@ -71,7 +85,8 @@ export default function AlumnosVista() {
|
|||
inyeccion(nombre),
|
||||
pildoras_id,
|
||||
pildoras(nombre)
|
||||
`)
|
||||
`
|
||||
)
|
||||
.order("id", { ascending: true });
|
||||
setAlumnos(data || []);
|
||||
};
|
||||
|
@ -100,9 +115,12 @@ export default function AlumnosVista() {
|
|||
setNuevoNumero(alumno.telefono || "");
|
||||
setNuevoTipo(alumno.tipo_formacion || "");
|
||||
// Detecta la formación actual según el tipo
|
||||
if (alumno.tipo_formacion === "curso") setNuevaFormacion(alumno.curso_id ? String(alumno.curso_id) : "");
|
||||
else if (alumno.tipo_formacion === "inyeccion") setNuevaFormacion(alumno.inyeccion_id ? String(alumno.inyeccion_id) : "");
|
||||
else if (alumno.tipo_formacion === "pildora") setNuevaFormacion(alumno.pildoras_id ? String(alumno.pildoras_id) : "");
|
||||
if (alumno.tipo_formacion === "curso")
|
||||
setNuevaFormacion(alumno.curso_id ? String(alumno.curso_id) : "");
|
||||
else if (alumno.tipo_formacion === "inyeccion")
|
||||
setNuevaFormacion(alumno.inyeccion_id ? String(alumno.inyeccion_id) : "");
|
||||
else if (alumno.tipo_formacion === "pildora")
|
||||
setNuevaFormacion(alumno.pildoras_id ? String(alumno.pildoras_id) : "");
|
||||
else setNuevaFormacion("");
|
||||
};
|
||||
|
||||
|
@ -126,7 +144,8 @@ export default function AlumnosVista() {
|
|||
};
|
||||
|
||||
if (nuevoTipo === "curso") updateObj.curso_id = Number(nuevaFormacion);
|
||||
if (nuevoTipo === "inyeccion") updateObj.inyeccion_id = Number(nuevaFormacion);
|
||||
if (nuevoTipo === "inyeccion")
|
||||
updateObj.inyeccion_id = Number(nuevaFormacion);
|
||||
if (nuevoTipo === "pildora") updateObj.pildoras_id = Number(nuevaFormacion);
|
||||
|
||||
const { error } = await supabaseClient
|
||||
|
@ -188,25 +207,37 @@ export default function AlumnosVista() {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{alumnos.map(alumno =>
|
||||
{alumnos.map((alumno) =>
|
||||
alumnoEditando === alumno.id ? (
|
||||
<tr key={alumno.id}>
|
||||
<td className="py-2 px-4 border-b text-center">
|
||||
{alumno.id}
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
<input value={nuevoNombre} onChange={e => setNuevoNombre(e.target.value)} className="border rounded px-2 py-1 text-black" />
|
||||
<input
|
||||
value={nuevoNombre}
|
||||
onChange={(e) => setNuevoNombre(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-black"
|
||||
/>
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
<input value={nuevoCorreo} onChange={e => setNuevoCorreo(e.target.value)} className="border rounded px-2 py-1 text-black" />
|
||||
<input
|
||||
value={nuevoCorreo}
|
||||
onChange={(e) => setNuevoCorreo(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-black"
|
||||
/>
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
<input value={nuevoNumero} onChange={e => setNuevoNumero(e.target.value)} className="border rounded px-2 py-1 text-black" />
|
||||
<input
|
||||
value={nuevoNumero}
|
||||
onChange={(e) => setNuevoNumero(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-black"
|
||||
/>
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
<select
|
||||
value={nuevoTipo}
|
||||
onChange={e => {
|
||||
onChange={(e) => {
|
||||
setNuevoTipo(e.target.value);
|
||||
setNuevaFormacion("");
|
||||
}}
|
||||
|
@ -222,12 +253,12 @@ export default function AlumnosVista() {
|
|||
{nuevoTipo === "curso" && (
|
||||
<select
|
||||
value={nuevaFormacion}
|
||||
onChange={e => setNuevaFormacion(e.target.value)}
|
||||
onChange={(e) => setNuevaFormacion(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-black"
|
||||
required
|
||||
>
|
||||
<option value="">Selecciona curso</option>
|
||||
{cursos.map(curso => (
|
||||
{cursos.map((curso) => (
|
||||
<option key={curso.id} value={curso.id}>
|
||||
{curso.nombre}
|
||||
</option>
|
||||
|
@ -237,12 +268,12 @@ export default function AlumnosVista() {
|
|||
{nuevoTipo === "inyeccion" && (
|
||||
<select
|
||||
value={nuevaFormacion}
|
||||
onChange={e => setNuevaFormacion(e.target.value)}
|
||||
onChange={(e) => setNuevaFormacion(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-black"
|
||||
required
|
||||
>
|
||||
<option value="">Selecciona inyección</option>
|
||||
{inyecciones.map(inyeccion => (
|
||||
{inyecciones.map((inyeccion) => (
|
||||
<option key={inyeccion.id} value={inyeccion.id}>
|
||||
{inyeccion.nombre}
|
||||
</option>
|
||||
|
@ -252,12 +283,12 @@ export default function AlumnosVista() {
|
|||
{nuevoTipo === "pildora" && (
|
||||
<select
|
||||
value={nuevaFormacion}
|
||||
onChange={e => setNuevaFormacion(e.target.value)}
|
||||
onChange={(e) => setNuevaFormacion(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-black"
|
||||
required
|
||||
>
|
||||
<option value="">Selecciona píldora</option>
|
||||
{pildoras.map(pildora => (
|
||||
{pildoras.map((pildora) => (
|
||||
<option key={pildora.id} value={pildora.id}>
|
||||
{pildora.nombre}
|
||||
</option>
|
||||
|
@ -266,8 +297,18 @@ export default function AlumnosVista() {
|
|||
)}
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
<button onClick={() => guardarEdicion(alumno.id)} className="bg-green-500 hover:bg-green-700 text-white px-3 py-1 rounded mr-2">Guardar</button>
|
||||
<button onClick={() => setAlumnoEditando(null)} className="bg-gray-400 hover:bg-gray-600 text-white px-3 py-1 rounded">Cancelar</button>
|
||||
<button
|
||||
onClick={() => guardarEdicion(alumno.id)}
|
||||
className="bg-green-500 hover:bg-green-700 text-white px-3 py-1 rounded mr-2"
|
||||
>
|
||||
Guardar
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setAlumnoEditando(null)}
|
||||
className="bg-gray-400 hover:bg-gray-600 text-white px-3 py-1 rounded"
|
||||
>
|
||||
Cancelar
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
) : (
|
||||
|
@ -286,9 +327,12 @@ export default function AlumnosVista() {
|
|||
: ""}
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
{alumno.tipo_formacion === "curso" && alumno.curso?.nombre}
|
||||
{alumno.tipo_formacion === "inyeccion" && alumno.inyeccion?.nombre}
|
||||
{alumno.tipo_formacion === "pildora" && alumno.pildoras?.nombre}
|
||||
{alumno.tipo_formacion === "curso" &&
|
||||
alumno.curso?.nombre}
|
||||
{alumno.tipo_formacion === "inyeccion" &&
|
||||
alumno.inyeccion?.nombre}
|
||||
{alumno.tipo_formacion === "pildora" &&
|
||||
alumno.pildoras?.nombre}
|
||||
</td>
|
||||
<td className="py-2 px-4 border-b">
|
||||
<button
|
||||
|
|
|
@ -12,6 +12,6 @@ export const alumnoSchema = z.object({
|
|||
.regex(/^\d+$/, "El número de teléfono solo puede contener dígitos")
|
||||
.min(10, "El número de teléfono debe tener al menos 10 dígitos")
|
||||
.max(10, "El número de teléfono no puede tener más de 10 dígitos"),
|
||||
//tipo: z.string().nonempty("Selecciona un tipo de asignación"),
|
||||
tipo: z.string().nonempty("Selecciona un tipo de formación"),
|
||||
cursoSeleccionado: z.string().nonempty("Selecciona una opción"),
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue