diff --git a/backend/src/controller/person/mod.rs b/backend/src/controller/person/mod.rs index 7c5142b..7ef7570 100644 --- a/backend/src/controller/person/mod.rs +++ b/backend/src/controller/person/mod.rs @@ -3,7 +3,7 @@ use rocket::http::Status; use rocket::serde::json::Json; use crate::json_result::JsonResult; -use crate::model::person::PersonCreate; +use crate::model::person::{PersonCreate, PersonLink}; use crate::model::reniec_person::ReniecPerson; use crate::{db, model::person::Person}; @@ -129,11 +129,22 @@ pub async fn get_by_dni(dni: i32) -> (Status, Json>) { ) } -#[options("/person")] -pub fn options() -> Status { - Status::Ok + +#[options("/person/link")] +pub fn options_p() -> Status { Status::Ok } + +#[put("/person/link", format = "json", data = "")] +pub async fn link_person(data: Json) -> (Status, Json>) { + match data.0.insert().await { + Ok(_) => (Status::Ok, JsonResult::ok(())), + Err(reason) => (Status::Ok, JsonResult::err(reason)) + } } + +#[options("/person")] +pub fn options() -> Status { Status::Ok } + #[post("/person", format = "json", data = "")] pub async fn create_person(person: Json) -> Status { match person.create().await { diff --git a/backend/src/cors.rs b/backend/src/cors.rs index c221a41..f9cc04f 100644 --- a/backend/src/cors.rs +++ b/backend/src/cors.rs @@ -21,7 +21,7 @@ impl Fairing for Cors { response.set_header(Header::new("Access-Control-Allow-Origin", "*")); response.set_header(Header::new( "Access-Control-Allow-Methods", - "POST, GET, DELETE, OPTIONS", + "POST, GET, PUT, DELETE, OPTIONS", )); response.set_header(Header::new("Access-Control-Allow-Headers", "Content-Type")); } diff --git a/backend/src/main.rs b/backend/src/main.rs index 4de6274..c0d3a7d 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -45,6 +45,8 @@ async fn rocket() -> _ { controller::person::get_by_dni, controller::person::options, controller::person::create_person, + controller::person::options_p, + controller::person::link_person, controller::course::get_all, controller::register::insert_all, controller::register::options, diff --git a/backend/src/model/person.rs b/backend/src/model/person.rs index 3f89e6f..bd8afba 100644 --- a/backend/src/model/person.rs +++ b/backend/src/model/person.rs @@ -74,3 +74,32 @@ impl PersonCreate { Ok(()) } } + + +#[derive(Deserialize)] +pub struct PersonLink { + pub person_id: i32, + pub person_classroom_id: i32, +} + +impl PersonLink { + pub async fn insert(&self) -> Result<(), String> { + let db = db(); + + let res = sqlx::query!( + "UPDATE person SET person_classroom_id = ? WHERE person_id = ?", + self.person_classroom_id, + self.person_id, + ) + .execute(db) + .await; + + match res { + Ok(_) => Ok(()), + Err(error) => { + eprintln!("Error linking person to classroom: {:?}", error); + Err(format!("Error vinculando persona.")) + } + } + } +} diff --git a/frontend/src/OnlineClassroom/index.tsx b/frontend/src/OnlineClassroom/index.tsx index 54827d0..e9b7ab0 100644 --- a/frontend/src/OnlineClassroom/index.tsx +++ b/frontend/src/OnlineClassroom/index.tsx @@ -9,6 +9,7 @@ import { SpinnerGapIcon } from "../icons/SpinnerGapIcon"; import { QuestionIcon } from "../icons/QuestionIcon"; import { JsonResult } from "../types/JsonResult"; import { XcircleIcon } from "../icons/XCircleIcon"; +import { LoadingStatus, backend, useLoading, wait } from "../utils/functions"; type TabType = "Vinculate" | "Create"; @@ -20,8 +21,14 @@ export function OnlineClassroom() {
- - + + setPerson((p) => ({...p!, person_classroom_id: classroom_id}))} + /> + + +

Person has classroom_id

@@ -31,7 +38,7 @@ export function OnlineClassroom() { -function ClassroomUser(props: {person: Person}) { +function ClassroomUser(props: {person: Person, onLink: (classroom_id: number) => void,}) { const [active, setActive] = createSignal("Vinculate"); return ( @@ -46,6 +53,8 @@ function ClassroomUser(props: {person: Person}) { @@ -59,7 +68,7 @@ function ClassroomUser(props: {person: Person}) { } type Status = "Init" | "Ok" | "Loading" | "Error"; -function ClassroomVinculation(props: {person_surname: string}) { +function ClassroomVinculation(props: {person_surname: string, personId: number, onLink: (classroom_id: number) => void,}) { const [classroomUsers, setClassroomUsers] = createSignal([]); const [error, setError] = createSignal(""); const [status, setStatus] = createSignal("Init"); @@ -103,7 +112,13 @@ function ClassroomVinculation(props: {person_surname: string}) { - {(u) => } + {(u) => ( + + )} @@ -121,7 +136,42 @@ function ClassroomVinculation(props: {person_surname: string}) { -function ClassroomSingleUser(props: {user: ClassroomRegistrationUser}) { +function ClassroomSingleUser(props: { + user: ClassroomRegistrationUser, + onLink: (classroom_id: number) => void, + personId: number, +}) { + const {setError, status, setStatus} = useLoading(); + + const linkUser = async() => { + setStatus(LoadingStatus.Loading); + + if (import.meta.env.DEV) await wait(1500); + + backend.put>( + "/api/person/link", + { + person_id: props.personId, + person_classroom_id: parseInt(props.user.user_id, 10), + }, + ) + .then((response) => { + if (response.status === 200) { + setStatus(LoadingStatus.Ok); + props.onLink(parseInt(props.user.user_id, 10)); + } else { + console.error(response.data); + setError(response.data.Err.reason); + setStatus(LoadingStatus.Error); + } + }) + .catch((err) => { + setError(`Error fatal: ${err.message}`); + console.error(err); + setStatus(LoadingStatus.Error); + }); + }; + return (
diff --git a/frontend/src/types/Person.ts b/frontend/src/types/Person.ts index cf02532..062ca6d 100644 --- a/frontend/src/types/Person.ts +++ b/frontend/src/types/Person.ts @@ -5,6 +5,6 @@ export type Person = { person_names: string person_paternal_surname: string person_maternal_surname: string - person_classroom_id: string | undefined + person_classroom_id: number | undefined } diff --git a/frontend/src/utils/functions.ts b/frontend/src/utils/functions.ts index a00df62..2d27963 100644 --- a/frontend/src/utils/functions.ts +++ b/frontend/src/utils/functions.ts @@ -1,4 +1,5 @@ import axios from "axios"; +import { createSignal } from "solid-js"; // YYYY-MM-DD to DD/MM/YYYY @@ -14,3 +15,16 @@ export const backend = axios.create({ export function wait(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } + +export enum LoadingStatus { + Init, + Loading, + Ok, + Error, +} +export function useLoading() { + const [status, setStatus] = createSignal(LoadingStatus.Init); + const [error, setError] = createSignal(""); + + return {error, setError, status, setStatus}; +}