Link classroom user id to a person
This commit is contained in:
parent
b7684e193b
commit
816e26b790
@ -3,7 +3,7 @@ use rocket::http::Status;
|
|||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
use crate::json_result::JsonResult;
|
use crate::json_result::JsonResult;
|
||||||
use crate::model::person::PersonCreate;
|
use crate::model::person::{PersonCreate, PersonLink};
|
||||||
use crate::model::reniec_person::ReniecPerson;
|
use crate::model::reniec_person::ReniecPerson;
|
||||||
use crate::{db, model::person::Person};
|
use crate::{db, model::person::Person};
|
||||||
|
|
||||||
@ -129,10 +129,21 @@ pub async fn get_by_dni(dni: i32) -> (Status, Json<JsonResult<Person>>) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[options("/person")]
|
|
||||||
pub fn options() -> Status {
|
#[options("/person/link")]
|
||||||
Status::Ok
|
pub fn options_p() -> Status { Status::Ok }
|
||||||
|
|
||||||
|
#[put("/person/link", format = "json", data = "<data>")]
|
||||||
|
pub async fn link_person(data: Json<PersonLink>) -> (Status, Json<JsonResult<()>>) {
|
||||||
|
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 = "<person>")]
|
#[post("/person", format = "json", data = "<person>")]
|
||||||
pub async fn create_person(person: Json<PersonCreate>) -> Status {
|
pub async fn create_person(person: Json<PersonCreate>) -> Status {
|
||||||
|
@ -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-Origin", "*"));
|
||||||
response.set_header(Header::new(
|
response.set_header(Header::new(
|
||||||
"Access-Control-Allow-Methods",
|
"Access-Control-Allow-Methods",
|
||||||
"POST, GET, DELETE, OPTIONS",
|
"POST, GET, PUT, DELETE, OPTIONS",
|
||||||
));
|
));
|
||||||
response.set_header(Header::new("Access-Control-Allow-Headers", "Content-Type"));
|
response.set_header(Header::new("Access-Control-Allow-Headers", "Content-Type"));
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ async fn rocket() -> _ {
|
|||||||
controller::person::get_by_dni,
|
controller::person::get_by_dni,
|
||||||
controller::person::options,
|
controller::person::options,
|
||||||
controller::person::create_person,
|
controller::person::create_person,
|
||||||
|
controller::person::options_p,
|
||||||
|
controller::person::link_person,
|
||||||
controller::course::get_all,
|
controller::course::get_all,
|
||||||
controller::register::insert_all,
|
controller::register::insert_all,
|
||||||
controller::register::options,
|
controller::register::options,
|
||||||
|
@ -74,3 +74,32 @@ impl PersonCreate {
|
|||||||
Ok(())
|
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."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ import { SpinnerGapIcon } from "../icons/SpinnerGapIcon";
|
|||||||
import { QuestionIcon } from "../icons/QuestionIcon";
|
import { QuestionIcon } from "../icons/QuestionIcon";
|
||||||
import { JsonResult } from "../types/JsonResult";
|
import { JsonResult } from "../types/JsonResult";
|
||||||
import { XcircleIcon } from "../icons/XCircleIcon";
|
import { XcircleIcon } from "../icons/XCircleIcon";
|
||||||
|
import { LoadingStatus, backend, useLoading, wait } from "../utils/functions";
|
||||||
|
|
||||||
type TabType = "Vinculate" | "Create";
|
type TabType = "Vinculate" | "Create";
|
||||||
|
|
||||||
@ -20,8 +21,14 @@ export function OnlineClassroom() {
|
|||||||
<Search setPerson={setPerson} />
|
<Search setPerson={setPerson} />
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<Show when={person() !== null && !person()!.person_classroom_id}>
|
<Show when={person() !== null && person()!.person_classroom_id === undefined}>
|
||||||
<ClassroomUser person={person()!} />
|
<ClassroomUser
|
||||||
|
person={person()!}
|
||||||
|
onLink={(classroom_id) => setPerson((p) => ({...p!, person_classroom_id: classroom_id}))}
|
||||||
|
/>
|
||||||
|
</Show>
|
||||||
|
<Show when={person() !== null && person()!.person_classroom_id !== undefined}>
|
||||||
|
<p>Person has classroom_id</p>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -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<TabType>("Vinculate");
|
const [active, setActive] = createSignal<TabType>("Vinculate");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -46,6 +53,8 @@ function ClassroomUser(props: {person: Person}) {
|
|||||||
<Show when={active() === "Vinculate"}>
|
<Show when={active() === "Vinculate"}>
|
||||||
<ClassroomVinculation
|
<ClassroomVinculation
|
||||||
person_surname={`${props.person.person_paternal_surname} ${props.person.person_maternal_surname}`}
|
person_surname={`${props.person.person_paternal_surname} ${props.person.person_maternal_surname}`}
|
||||||
|
personId={props.person.person_id}
|
||||||
|
onLink={props.onLink}
|
||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={active() === "Create"}>
|
<Show when={active() === "Create"}>
|
||||||
@ -59,7 +68,7 @@ function ClassroomUser(props: {person: Person}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Status = "Init" | "Ok" | "Loading" | "Error";
|
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<ClassroomRegistrationUser[]>([]);
|
const [classroomUsers, setClassroomUsers] = createSignal<ClassroomRegistrationUser[]>([]);
|
||||||
const [error, setError] = createSignal("");
|
const [error, setError] = createSignal("");
|
||||||
const [status, setStatus] = createSignal<Status>("Init");
|
const [status, setStatus] = createSignal<Status>("Init");
|
||||||
@ -103,7 +112,13 @@ function ClassroomVinculation(props: {person_surname: string}) {
|
|||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
<For each={classroomUsers()}>
|
<For each={classroomUsers()}>
|
||||||
{(u) => <ClassroomSingleUser user={u} />}
|
{(u) => (
|
||||||
|
<ClassroomSingleUser
|
||||||
|
user={u}
|
||||||
|
personId={props.personId}
|
||||||
|
onLink={props.onLink}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</For>
|
</For>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
@ -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<JsonResult<null>>(
|
||||||
|
"/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 (
|
return (
|
||||||
<div
|
<div
|
||||||
class="hover:bg-c-surface-variant hover:text-c-on-surface-variant transition-colors
|
class="hover:bg-c-surface-variant hover:text-c-on-surface-variant transition-colors
|
||||||
@ -145,6 +195,8 @@ function ClassroomSingleUser(props: {user: ClassroomRegistrationUser}) {
|
|||||||
<button
|
<button
|
||||||
title="Vincular usuario"
|
title="Vincular usuario"
|
||||||
class="border-2 border-c-transparent hover:border-c-primary transition-colors rounded"
|
class="border-2 border-c-transparent hover:border-c-primary transition-colors rounded"
|
||||||
|
onclick={linkUser}
|
||||||
|
disabled={status() === LoadingStatus.Loading}
|
||||||
>
|
>
|
||||||
<LinkIcon fill="var(--c-primary)" />
|
<LinkIcon fill="var(--c-primary)" />
|
||||||
</button>
|
</button>
|
||||||
|
@ -5,6 +5,6 @@ export type Person = {
|
|||||||
person_names: string
|
person_names: string
|
||||||
person_paternal_surname: string
|
person_paternal_surname: string
|
||||||
person_maternal_surname: string
|
person_maternal_surname: string
|
||||||
person_classroom_id: string | undefined
|
person_classroom_id: number | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { createSignal } from "solid-js";
|
||||||
|
|
||||||
|
|
||||||
// YYYY-MM-DD to DD/MM/YYYY
|
// YYYY-MM-DD to DD/MM/YYYY
|
||||||
@ -14,3 +15,16 @@ export const backend = axios.create({
|
|||||||
export function wait(ms: number): Promise<void> {
|
export function wait(ms: number): Promise<void> {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
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};
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user