diff --git a/diplomas/package-lock.json b/diplomas/package-lock.json index 0b84187..ea6449a 100644 --- a/diplomas/package-lock.json +++ b/diplomas/package-lock.json @@ -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", diff --git a/diplomas/package.json b/diplomas/package.json index 3784ab0..ee31fc7 100644 --- a/diplomas/package.json +++ b/diplomas/package.json @@ -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:", diff --git a/diplomas/src/pages/alumnosManual.jsx b/diplomas/src/pages/alumnosManual.jsx index 58d7eb7..d8c40b6 100644 --- a/diplomas/src/pages/alumnosManual.jsx +++ b/diplomas/src/pages/alumnosManual.jsx @@ -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" diff --git a/diplomas/src/pages/cursosManual.jsx b/diplomas/src/pages/cursosManual.jsx index 71d9a15..95dbbb5 100644 --- a/diplomas/src/pages/cursosManual.jsx +++ b/diplomas/src/pages/cursosManual.jsx @@ -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> diff --git a/diplomas/src/pages/index.js b/diplomas/src/pages/index.js index 251d108..010c71b 100644 --- a/diplomas/src/pages/index.js +++ b/diplomas/src/pages/index.js @@ -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 ); } \ No newline at end of file