Conecctado Alumno y Curso con Supabase (agregado manualmente)
This commit is contained in:
parent
567efccc06
commit
b658bf9496
|
@ -15,6 +15,7 @@
|
|||
"@radix-ui/react-slot": "^1.2.0",
|
||||
"@radix-ui/react-tabs": "^1.1.9",
|
||||
"@radix-ui/react-tooltip": "^1.2.4",
|
||||
"@supabase/supabase-js": "^2.49.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"diplomas": "file:",
|
||||
|
@ -1958,6 +1959,73 @@
|
|||
"integrity": "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@supabase/auth-js": {
|
||||
"version": "2.69.1",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.69.1.tgz",
|
||||
"integrity": "sha512-FILtt5WjCNzmReeRLq5wRs3iShwmnWgBvxHfqapC/VoljJl+W8hDAyFmf1NVw3zH+ZjZ05AKxiKxVeb0HNWRMQ==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/functions-js": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.4.tgz",
|
||||
"integrity": "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/node-fetch": {
|
||||
"version": "2.6.15",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
|
||||
"integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/postgrest-js": {
|
||||
"version": "1.19.4",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.19.4.tgz",
|
||||
"integrity": "sha512-O4soKqKtZIW3olqmbXXbKugUtByD2jPa8kL2m2c1oozAO11uCcGrRhkZL0kVxjBLrXHE0mdSkFsMj7jDSfyNpw==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/realtime-js": {
|
||||
"version": "2.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.2.tgz",
|
||||
"integrity": "sha512-u/XeuL2Y0QEhXSoIPZZwR6wMXgB+RQbJzG9VErA3VghVt7uRfSVsjeqd7m5GhX3JR6dM/WRmLbVR8URpDWG4+w==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14",
|
||||
"@types/phoenix": "^1.5.4",
|
||||
"@types/ws": "^8.5.10",
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/storage-js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz",
|
||||
"integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/supabase-js": {
|
||||
"version": "2.49.4",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.49.4.tgz",
|
||||
"integrity": "sha512-jUF0uRUmS8BKt37t01qaZ88H9yV1mbGYnqLeuFWLcdV+x1P4fl0yP9DGtaEhFPZcwSom7u16GkLEH9QJZOqOkw==",
|
||||
"dependencies": {
|
||||
"@supabase/auth-js": "2.69.1",
|
||||
"@supabase/functions-js": "2.4.4",
|
||||
"@supabase/node-fetch": "2.6.15",
|
||||
"@supabase/postgrest-js": "1.19.4",
|
||||
"@supabase/realtime-js": "2.11.2",
|
||||
"@supabase/storage-js": "2.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/counter": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
|
||||
|
@ -2252,6 +2320,27 @@
|
|||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.2.tgz",
|
||||
"integrity": "sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/phoenix": {
|
||||
"version": "1.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz",
|
||||
"integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A=="
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.18.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
||||
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.30.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz",
|
||||
|
@ -6370,6 +6459,11 @@
|
|||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
||||
|
@ -6525,6 +6619,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
|
||||
},
|
||||
"node_modules/unrs-resolver": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.5.0.tgz",
|
||||
|
@ -6602,6 +6701,20 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
@ -6711,6 +6824,26 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
|
||||
"integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"@radix-ui/react-slot": "^1.2.0",
|
||||
"@radix-ui/react-tabs": "^1.1.9",
|
||||
"@radix-ui/react-tooltip": "^1.2.4",
|
||||
"@supabase/supabase-js": "^2.49.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"diplomas": "file:",
|
||||
|
|
|
@ -1,23 +1,65 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Layout from "@/components/layout/Layout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
} from "@/components/ui/select";
|
||||
import { supabase } from "@/lib/supabaseClient";
|
||||
|
||||
export default function AlumnosManual() {
|
||||
const [nombre, setNombre] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [curso, setCurso] = useState("");
|
||||
const manejarGuardar = () => {
|
||||
console.log({ nombre, email, curso });
|
||||
const [cursoSeleccionado, setCursoSeleccionado] = useState("");
|
||||
const [cursos, setCursos] = useState([]);
|
||||
|
||||
// Cargar cursos al iniciar el componente
|
||||
useEffect(() => {
|
||||
const cargarCursos = async () => {
|
||||
const { data, error } = await supabase.from("curso").select("id, nombre");
|
||||
if (error) {
|
||||
console.error("Error al cargar cursos:", error.message);
|
||||
} else {
|
||||
setCursos(data);
|
||||
}
|
||||
};
|
||||
cargarCursos();
|
||||
}, []);
|
||||
|
||||
// Guardar alumno
|
||||
const manejarGuardar = async () => {
|
||||
try {
|
||||
const { data, error } = await supabase.from("alumno").insert([
|
||||
{
|
||||
nombre: nombre,
|
||||
correo: email,
|
||||
},
|
||||
]);
|
||||
|
||||
if (error) {
|
||||
console.error("Error al guardar:", error.message);
|
||||
alert("Error al guardar: " + error.message);
|
||||
} else {
|
||||
console.log("Alumno guardado:", data);
|
||||
alert("Alumno guardado con éxito");
|
||||
setNombre("");
|
||||
setEmail("");
|
||||
setCursoSeleccionado("");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error inesperado:", err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="w-[60vw] pt-10 flex flex-col items-end justify-center">
|
||||
<div className="bg-white p-8 font-sans text-center w-[70%]">
|
||||
<h1 className="text-xl font-semibold mb-4 text-black">
|
||||
Nuevo alumno
|
||||
</h1>
|
||||
<h1 className="text-xl font-semibold mb-4 text-black">Nuevo alumno</h1>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Nombre"
|
||||
|
@ -32,13 +74,22 @@ export default function AlumnosManual() {
|
|||
onChange={(e) => setEmail(e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md mb-3"
|
||||
/>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Curso"
|
||||
value={curso}
|
||||
onChange={(e) => setCurso(e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md mb-3"
|
||||
/>
|
||||
<Select
|
||||
onValueChange={(value) => setCursoSeleccionado(value)}
|
||||
value={cursoSeleccionado}
|
||||
>
|
||||
<SelectTrigger className="w-full px-3 py-2 border border-gray-300 rounded-md mb-4">
|
||||
<SelectValue placeholder="Selecciona un curso" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{cursos.map((curso) => (
|
||||
<SelectItem key={curso.id} value={curso.id.toString()}>
|
||||
{curso.nombre}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Button
|
||||
onClick={manejarGuardar}
|
||||
className="bg-green-400 hover:bg-green-500 text-white font-bold py-2 px-4 rounded-md"
|
||||
|
|
|
@ -10,13 +10,34 @@ import {
|
|||
} from "@/components/ui/select";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import React, { useState } from "react";
|
||||
import { supabase } from "@/lib/supabaseClient";
|
||||
|
||||
const CursosManual = () => {
|
||||
const [nombre, setNombre] = useState("");
|
||||
const [descripcion, setDescripcion] = useState("");
|
||||
const [descripcion, setDescripcion] = useState("");
|
||||
const [competencia, setCompetencia] = useState("");
|
||||
const manejarGuardar = () => {
|
||||
console.log({ nombre, descripcion, competencia });
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const manejarGuardar = async () => {
|
||||
setLoading(true);
|
||||
const { error } = await supabase.from("curso").insert([
|
||||
{
|
||||
nombre,
|
||||
descripcion,
|
||||
horas: 10, // o usa otro input para personalizar
|
||||
competencias: [competencia], // si es una sola, usa string. Si son varias, un array.
|
||||
},
|
||||
]);
|
||||
setLoading(false);
|
||||
|
||||
if (error) {
|
||||
alert("Error al guardar: " + error.message);
|
||||
} else {
|
||||
alert("Curso guardado correctamente");
|
||||
setNombre("");
|
||||
setDescripcion("");
|
||||
setCompetencia("");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -49,8 +70,9 @@ const CursosManual = () => {
|
|||
<Button
|
||||
onClick={manejarGuardar}
|
||||
className="bg-green-400 hover:bg-green-500 text-white font-bold py-2 px-4 rounded-md"
|
||||
disabled={loading}
|
||||
>
|
||||
Guardar
|
||||
{loading ? "Guardando..." : "Guardar"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
<<<<<<< HEAD
|
||||
import Link from 'next/link';
|
||||
import React from 'react';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Welcome to the Diploma Generator</h1>
|
||||
<Link href="/alumnos" className="text-blue-500 hover:underline">
|
||||
Go to Alumnos Page
|
||||
</Link>
|
||||
<br></br>
|
||||
<Link href="/diplomas" className="text-blue-500 hover:underline">
|
||||
Go to Diplomas Page
|
||||
</Link>
|
||||
</div>
|
||||
=======
|
||||
import Layout from "@/components/layout/Layout";
|
||||
|
||||
export default function Home() {
|
||||
|
@ -24,6 +7,5 @@ export default function Home() {
|
|||
<h1 className="text-3xl font-bold text-black">¡Bienvenido a SIDAC!</h1>
|
||||
</div>
|
||||
</Layout>
|
||||
>>>>>>> 493b05750bcfa46ff9d030c3f0a85d596f403d28
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue