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";
|
} from "@/components/ui/select";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTrigger,
|
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
|
@ -24,61 +23,99 @@ import { alumnoSchema } from "@/schemas/AlumnosSchema";
|
||||||
|
|
||||||
export default function AlumnosManual() {
|
export default function AlumnosManual() {
|
||||||
const [cursos, setCursos] = useState([]);
|
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 {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
setValue,
|
setValue,
|
||||||
|
watch,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
reset,
|
reset,
|
||||||
|
clearErrors,
|
||||||
} = useForm({
|
} = useForm({
|
||||||
resolver: zodResolver(alumnoSchema),
|
resolver: zodResolver(alumnoSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
nombre: "",
|
nombre: "",
|
||||||
correo: "",
|
correo: "",
|
||||||
telefono: "",
|
telefono: "",
|
||||||
|
tipo: "",
|
||||||
cursoSeleccionado: "",
|
cursoSeleccionado: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cargar cursos al iniciar el componente
|
const tipo = watch("tipo");
|
||||||
|
const cursoSeleccionado = watch("cursoSeleccionado");
|
||||||
|
|
||||||
|
// Cargar opciones según tipo seleccionado
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const cargarCursos = async () => {
|
if (!tipo) {
|
||||||
const { data, error } = await supabaseClient
|
setValue("cursoSeleccionado", "");
|
||||||
.from("curso")
|
clearErrors("cursoSeleccionado");
|
||||||
.select("id, nombre");
|
return;
|
||||||
if (error) {
|
}
|
||||||
console.error("Error al cargar cursos:", error.message);
|
setValue("cursoSeleccionado", "");
|
||||||
} else {
|
clearErrors("cursoSeleccionado");
|
||||||
setCursos(data);
|
if (tipo === "curso") {
|
||||||
}
|
cargarCursos();
|
||||||
};
|
} else if (tipo === "inyeccion") {
|
||||||
cargarCursos();
|
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
|
// Guardar alumno
|
||||||
const manejarGuardar = async (data) => {
|
const manejarGuardar = async (data) => {
|
||||||
try {
|
try {
|
||||||
const { error } = await supabaseClient.from("alumno").insert([
|
let campos = {
|
||||||
{
|
nombre: data.nombre,
|
||||||
nombre: data.nombre,
|
correo: data.correo,
|
||||||
correo: data.correo,
|
telefono: data.telefono,
|
||||||
telefono: data.telefono,
|
tipo_formacion: data.tipo,
|
||||||
curso_id: Number(data.cursoSeleccionado), // Guardar el ID del curso
|
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) {
|
if (error) {
|
||||||
console.error("Error al guardar:", error.message);
|
setIsDialogOpen(false);
|
||||||
setIsDialogOpen(false); // Asegurarse de cerrar el diálogo en caso de error
|
|
||||||
} else {
|
} else {
|
||||||
setIsDialogOpen(true); // Mostrar el diálogo al guardar exitosamente
|
setIsDialogOpen(true);
|
||||||
reset(); // Reiniciar el formulario
|
reset();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error inesperado:", err);
|
// Manejo de error inesperado
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,20 +155,77 @@ export default function AlumnosManual() {
|
||||||
{errors.telefono.message}
|
{errors.telefono.message}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Select para tipo de formación */}
|
||||||
<Select
|
<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">
|
<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>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{cursos.map((curso) => (
|
<SelectItem value="curso">Curso</SelectItem>
|
||||||
<SelectItem key={curso.id} value={curso.id.toString()}>
|
<SelectItem value="inyeccion">Inyección</SelectItem>
|
||||||
{curso.nombre}
|
<SelectItem value="pildora">Píldora</SelectItem>
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</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 && (
|
{errors.cursoSeleccionado && (
|
||||||
<p className="text-red-500 text-sm mt-1">
|
<p className="text-red-500 text-sm mt-1">
|
||||||
{errors.cursoSeleccionado.message}
|
{errors.cursoSeleccionado.message}
|
||||||
|
|
|
@ -45,6 +45,9 @@ export default function AlumnosVista() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
cargarAlumnos();
|
cargarAlumnos();
|
||||||
// ...cargar cursos, inyecciones, pildoras...
|
// ...cargar cursos, inyecciones, pildoras...
|
||||||
|
cargarCursos();
|
||||||
|
cargarInyecciones();
|
||||||
|
cargarPildoras();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const cargarCursos = async () => {
|
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 cargarAlumnos = async () => {
|
||||||
const { data, error } = await supabaseClient
|
const { data, error } = await supabaseClient
|
||||||
.from("alumno")
|
.from("alumno")
|
||||||
.select(`
|
.select(
|
||||||
|
`
|
||||||
id,
|
id,
|
||||||
nombre,
|
nombre,
|
||||||
correo,
|
correo,
|
||||||
|
@ -71,7 +85,8 @@ export default function AlumnosVista() {
|
||||||
inyeccion(nombre),
|
inyeccion(nombre),
|
||||||
pildoras_id,
|
pildoras_id,
|
||||||
pildoras(nombre)
|
pildoras(nombre)
|
||||||
`)
|
`
|
||||||
|
)
|
||||||
.order("id", { ascending: true });
|
.order("id", { ascending: true });
|
||||||
setAlumnos(data || []);
|
setAlumnos(data || []);
|
||||||
};
|
};
|
||||||
|
@ -100,9 +115,12 @@ export default function AlumnosVista() {
|
||||||
setNuevoNumero(alumno.telefono || "");
|
setNuevoNumero(alumno.telefono || "");
|
||||||
setNuevoTipo(alumno.tipo_formacion || "");
|
setNuevoTipo(alumno.tipo_formacion || "");
|
||||||
// Detecta la formación actual según el tipo
|
// Detecta la formación actual según el tipo
|
||||||
if (alumno.tipo_formacion === "curso") setNuevaFormacion(alumno.curso_id ? String(alumno.curso_id) : "");
|
if (alumno.tipo_formacion === "curso")
|
||||||
else if (alumno.tipo_formacion === "inyeccion") setNuevaFormacion(alumno.inyeccion_id ? String(alumno.inyeccion_id) : "");
|
setNuevaFormacion(alumno.curso_id ? String(alumno.curso_id) : "");
|
||||||
else if (alumno.tipo_formacion === "pildora") setNuevaFormacion(alumno.pildoras_id ? String(alumno.pildoras_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("");
|
else setNuevaFormacion("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,7 +144,8 @@ export default function AlumnosVista() {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (nuevoTipo === "curso") updateObj.curso_id = Number(nuevaFormacion);
|
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);
|
if (nuevoTipo === "pildora") updateObj.pildoras_id = Number(nuevaFormacion);
|
||||||
|
|
||||||
const { error } = await supabaseClient
|
const { error } = await supabaseClient
|
||||||
|
@ -188,25 +207,37 @@ export default function AlumnosVista() {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{alumnos.map(alumno =>
|
{alumnos.map((alumno) =>
|
||||||
alumnoEditando === alumno.id ? (
|
alumnoEditando === alumno.id ? (
|
||||||
<tr key={alumno.id}>
|
<tr key={alumno.id}>
|
||||||
<td className="py-2 px-4 border-b text-center">
|
<td className="py-2 px-4 border-b text-center">
|
||||||
{alumno.id}
|
{alumno.id}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-2 px-4 border-b">
|
<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>
|
||||||
<td className="py-2 px-4 border-b">
|
<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>
|
||||||
<td className="py-2 px-4 border-b">
|
<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>
|
||||||
<td className="py-2 px-4 border-b">
|
<td className="py-2 px-4 border-b">
|
||||||
<select
|
<select
|
||||||
value={nuevoTipo}
|
value={nuevoTipo}
|
||||||
onChange={e => {
|
onChange={(e) => {
|
||||||
setNuevoTipo(e.target.value);
|
setNuevoTipo(e.target.value);
|
||||||
setNuevaFormacion("");
|
setNuevaFormacion("");
|
||||||
}}
|
}}
|
||||||
|
@ -222,12 +253,12 @@ export default function AlumnosVista() {
|
||||||
{nuevoTipo === "curso" && (
|
{nuevoTipo === "curso" && (
|
||||||
<select
|
<select
|
||||||
value={nuevaFormacion}
|
value={nuevaFormacion}
|
||||||
onChange={e => setNuevaFormacion(e.target.value)}
|
onChange={(e) => setNuevaFormacion(e.target.value)}
|
||||||
className="border rounded px-2 py-1 text-black"
|
className="border rounded px-2 py-1 text-black"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Selecciona curso</option>
|
<option value="">Selecciona curso</option>
|
||||||
{cursos.map(curso => (
|
{cursos.map((curso) => (
|
||||||
<option key={curso.id} value={curso.id}>
|
<option key={curso.id} value={curso.id}>
|
||||||
{curso.nombre}
|
{curso.nombre}
|
||||||
</option>
|
</option>
|
||||||
|
@ -237,12 +268,12 @@ export default function AlumnosVista() {
|
||||||
{nuevoTipo === "inyeccion" && (
|
{nuevoTipo === "inyeccion" && (
|
||||||
<select
|
<select
|
||||||
value={nuevaFormacion}
|
value={nuevaFormacion}
|
||||||
onChange={e => setNuevaFormacion(e.target.value)}
|
onChange={(e) => setNuevaFormacion(e.target.value)}
|
||||||
className="border rounded px-2 py-1 text-black"
|
className="border rounded px-2 py-1 text-black"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Selecciona inyección</option>
|
<option value="">Selecciona inyección</option>
|
||||||
{inyecciones.map(inyeccion => (
|
{inyecciones.map((inyeccion) => (
|
||||||
<option key={inyeccion.id} value={inyeccion.id}>
|
<option key={inyeccion.id} value={inyeccion.id}>
|
||||||
{inyeccion.nombre}
|
{inyeccion.nombre}
|
||||||
</option>
|
</option>
|
||||||
|
@ -252,12 +283,12 @@ export default function AlumnosVista() {
|
||||||
{nuevoTipo === "pildora" && (
|
{nuevoTipo === "pildora" && (
|
||||||
<select
|
<select
|
||||||
value={nuevaFormacion}
|
value={nuevaFormacion}
|
||||||
onChange={e => setNuevaFormacion(e.target.value)}
|
onChange={(e) => setNuevaFormacion(e.target.value)}
|
||||||
className="border rounded px-2 py-1 text-black"
|
className="border rounded px-2 py-1 text-black"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Selecciona píldora</option>
|
<option value="">Selecciona píldora</option>
|
||||||
{pildoras.map(pildora => (
|
{pildoras.map((pildora) => (
|
||||||
<option key={pildora.id} value={pildora.id}>
|
<option key={pildora.id} value={pildora.id}>
|
||||||
{pildora.nombre}
|
{pildora.nombre}
|
||||||
</option>
|
</option>
|
||||||
|
@ -266,8 +297,18 @@ export default function AlumnosVista() {
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-2 px-4 border-b">
|
<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
|
||||||
<button onClick={() => setAlumnoEditando(null)} className="bg-gray-400 hover:bg-gray-600 text-white px-3 py-1 rounded">Cancelar</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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
|
@ -286,9 +327,12 @@ export default function AlumnosVista() {
|
||||||
: ""}
|
: ""}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-2 px-4 border-b">
|
<td className="py-2 px-4 border-b">
|
||||||
{alumno.tipo_formacion === "curso" && alumno.curso?.nombre}
|
{alumno.tipo_formacion === "curso" &&
|
||||||
{alumno.tipo_formacion === "inyeccion" && alumno.inyeccion?.nombre}
|
alumno.curso?.nombre}
|
||||||
{alumno.tipo_formacion === "pildora" && alumno.pildoras?.nombre}
|
{alumno.tipo_formacion === "inyeccion" &&
|
||||||
|
alumno.inyeccion?.nombre}
|
||||||
|
{alumno.tipo_formacion === "pildora" &&
|
||||||
|
alumno.pildoras?.nombre}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-2 px-4 border-b">
|
<td className="py-2 px-4 border-b">
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -12,6 +12,6 @@ export const alumnoSchema = z.object({
|
||||||
.regex(/^\d+$/, "El número de teléfono solo puede contener dígitos")
|
.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")
|
.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"),
|
.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"),
|
cursoSeleccionado: z.string().nonempty("Selecciona una opción"),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue