[Classroom][FE] Request to enrollment to backend. Improve UI
This commit is contained in:
parent
2f924d875c
commit
f57c200163
@ -27,6 +27,8 @@ pub async fn get_courses(user_id: i32) -> (Status, Json<JsonResult<Vec<Classroom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[options("/classroom/course/<_u>")]
|
||||||
|
pub fn register_course_contr_options(_u: i32) -> Status {Status::Ok}
|
||||||
|
|
||||||
#[post("/classroom/course/<user_id>", format = "json", data = "<data>")]
|
#[post("/classroom/course/<user_id>", format = "json", data = "<data>")]
|
||||||
pub async fn register_course_contr(user_id: i32, data: Json<ClassroomCourseRegistration>) -> (Status, Json<JsonResult<()>>) {
|
pub async fn register_course_contr(user_id: i32, data: Json<ClassroomCourseRegistration>) -> (Status, Json<JsonResult<()>>) {
|
||||||
|
@ -62,6 +62,7 @@ async fn rocket() -> _ {
|
|||||||
controller::classroom::create_user_options,
|
controller::classroom::create_user_options,
|
||||||
controller::classroom::create_user,
|
controller::classroom::create_user,
|
||||||
controller::classroom::get_courses,
|
controller::classroom::get_courses,
|
||||||
|
controller::classroom::register_course_contr_options,
|
||||||
controller::classroom::register_course_contr,
|
controller::classroom::register_course_contr,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,10 @@ import { ClassroomRegistrationPreview } from "./ClassroomRegistrationPreview";
|
|||||||
import { ClassroomSearchableSelect } from "./ClassroomSearchableSelect";
|
import { ClassroomSearchableSelect } from "./ClassroomSearchableSelect";
|
||||||
import { ClassroomCourseValue } from "../types/ClassroomCourse";
|
import { ClassroomCourseValue } from "../types/ClassroomCourse";
|
||||||
|
|
||||||
export function ClassroomRegistration() {
|
export function ClassroomRegistration(props: {
|
||||||
|
surname_first_letter: string, userId: number | null,
|
||||||
|
onSuccess: () => void,
|
||||||
|
}) {
|
||||||
const [selections, setSelections] = createSignal<Array<ClassroomCourseValue>>([]);
|
const [selections, setSelections] = createSignal<Array<ClassroomCourseValue>>([]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -20,8 +23,11 @@ export function ClassroomRegistration() {
|
|||||||
</FilledCard>
|
</FilledCard>
|
||||||
|
|
||||||
<ClassroomRegistrationPreview
|
<ClassroomRegistrationPreview
|
||||||
|
surname_first_letter={props.surname_first_letter}
|
||||||
|
userId={props.userId}
|
||||||
selections={selections()}
|
selections={selections()}
|
||||||
deleteRegister={(course_key) => setSelections((course) => course.filter((v) => v !== course_key))}
|
deleteRegister={(course_key) => setSelections((course) => course.filter((v) => v !== course_key))}
|
||||||
|
onSuccess={props.onSuccess}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,19 +1,52 @@
|
|||||||
import { For, createMemo } from "solid-js";
|
import { For, createMemo } from "solid-js";
|
||||||
import { FilledCard } from "../components/FilledCard";
|
import { FilledCard } from "../components/FilledCard";
|
||||||
import { LoadingIcon } from "../icons/LoadingIcon";
|
import { LoadingIcon } from "../icons/LoadingIcon";
|
||||||
import { LoadingStatus, useLoading } from "../utils/functions";
|
import { LoadingStatus, backend, useLoading, wait } from "../utils/functions";
|
||||||
import { ClassroomCourseValue, allClassrooomCourses } from "../types/ClassroomCourse";
|
import { ClassroomCourseValue, allClassrooomCourses } from "../types/ClassroomCourse";
|
||||||
import { XIcon } from "../icons/XIcon";
|
import { XIcon } from "../icons/XIcon";
|
||||||
|
import { JsonResult } from "../types/JsonResult";
|
||||||
|
import { AxiosError } from "axios";
|
||||||
|
|
||||||
export function ClassroomRegistrationPreview(props: {
|
export function ClassroomRegistrationPreview(props: {
|
||||||
|
surname_first_letter: string,
|
||||||
|
userId: number | null,
|
||||||
selections: Array<ClassroomCourseValue>,
|
selections: Array<ClassroomCourseValue>,
|
||||||
deleteRegister: (k: string) => void,
|
deleteRegister: (k: string) => void,
|
||||||
|
onSuccess: () => void,
|
||||||
}) {
|
}) {
|
||||||
const {status} = useLoading();
|
const {status, setStatus, setError} = useLoading();
|
||||||
|
|
||||||
const loading = createMemo(() => status() === LoadingStatus.Loading);
|
const loading = createMemo(() => status() === LoadingStatus.Loading);
|
||||||
|
|
||||||
const submit = async() => {
|
const submit = async() => {
|
||||||
|
if (props.userId === null) return;
|
||||||
|
|
||||||
|
setStatus(LoadingStatus.Loading);
|
||||||
|
|
||||||
|
if (import.meta.env.DEV) await wait(1500);
|
||||||
|
|
||||||
|
backend.post<JsonResult<null>>(`/api/classroom/course/${props.userId}`, {
|
||||||
|
surname_first_letter: "A",
|
||||||
|
courses: props.selections,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
setStatus(LoadingStatus.Ok);
|
||||||
|
props.onSuccess();
|
||||||
|
} else {
|
||||||
|
console.error(response.data);
|
||||||
|
setError(response.data.Err.reason);
|
||||||
|
setStatus(LoadingStatus.Error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err: AxiosError<JsonResult<null>>) => {
|
||||||
|
console.error(err);
|
||||||
|
if (err.response?.data?.Err?.reason) {
|
||||||
|
setError(err.response.data.Err.reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatus(LoadingStatus.Error);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -40,7 +73,7 @@ export function ClassroomRegistrationPreview(props: {
|
|||||||
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer mt-4
|
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer mt-4
|
||||||
disabled:opacity-50 disabled:cursor-not-allowed relative"
|
disabled:opacity-50 disabled:cursor-not-allowed relative"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={props.selections.length === 0 || loading()}
|
disabled={props.userId === null || props.selections.length === 0 || loading()}
|
||||||
onclick={submit}
|
onclick={submit}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { For, Show, createSignal, onMount } from "solid-js";
|
import { For, Show, createEffect, createSignal, onMount } from "solid-js";
|
||||||
import { LoadingStatus, backend, useLoading, wait } from "../utils/functions";
|
import { LoadingStatus, backend, useLoading, wait } from "../utils/functions";
|
||||||
import { JsonResult } from "../types/JsonResult";
|
import { JsonResult } from "../types/JsonResult";
|
||||||
import { ClassroomCourse } from "../types/ClassroomCourse";
|
import { ClassroomCourse } from "../types/ClassroomCourse";
|
||||||
import { LoadingIcon } from "../icons/LoadingIcon";
|
import { LoadingIcon } from "../icons/LoadingIcon";
|
||||||
|
|
||||||
export function ClassroomUserCourses(props: {userid: number}) {
|
export function ClassroomUserCourses(props: {userid: number, updateSignal: number}) {
|
||||||
const [courses, setCourses] = createSignal<Array<ClassroomCourse>>([]);
|
const [courses, setCourses] = createSignal<Array<ClassroomCourse>>([]);
|
||||||
const {setError, status, setStatus} = useLoading();
|
const {setError, status, setStatus} = useLoading();
|
||||||
|
|
||||||
const loadCourses = async() => {
|
const loadCourses = async() => {
|
||||||
setStatus(LoadingStatus.Loading);
|
setStatus(LoadingStatus.Loading);
|
||||||
setError("");
|
setError("");
|
||||||
|
setCourses([]);
|
||||||
|
|
||||||
if (import.meta.env.DEV) await wait(1500);
|
if (import.meta.env.DEV) await wait(1500);
|
||||||
|
|
||||||
@ -29,6 +30,14 @@ export function ClassroomUserCourses(props: {userid: number}) {
|
|||||||
|
|
||||||
onMount(loadCourses);
|
onMount(loadCourses);
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
// Update courses when updateSignal changes
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const _ = props.updateSignal;
|
||||||
|
|
||||||
|
loadCourses();
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<h2 class="text-2xl">
|
<h2 class="text-2xl">
|
||||||
|
@ -11,12 +11,18 @@ type TabType = "Vinculate" | "Create";
|
|||||||
|
|
||||||
export function OnlineClassroom() {
|
export function OnlineClassroom() {
|
||||||
const [person, setPerson] = createSignal<Person | null>(null);
|
const [person, setPerson] = createSignal<Person | null>(null);
|
||||||
|
// Used to update ClassroomUserCourses
|
||||||
|
const [updateSignal, setUpdateSIgnal] = createSignal(0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="grid grid-cols-[16rem_25rem_1fr]">
|
<div class="grid grid-cols-[16rem_25rem_1fr]">
|
||||||
<Search setPerson={setPerson} />
|
<Search setPerson={setPerson} />
|
||||||
|
|
||||||
<ClassroomRegistration />
|
<ClassroomRegistration
|
||||||
|
surname_first_letter={person()?.person_paternal_surname[0] ?? ""}
|
||||||
|
userId={person()?.person_classroom_id ?? null}
|
||||||
|
onSuccess={() => setUpdateSIgnal((s) => s + 1)}
|
||||||
|
/>
|
||||||
|
|
||||||
<Show when={person() !== null && person()!.person_classroom_id === null}>
|
<Show when={person() !== null && person()!.person_classroom_id === null}>
|
||||||
<ClassroomUser
|
<ClassroomUser
|
||||||
@ -25,7 +31,10 @@ export function OnlineClassroom() {
|
|||||||
/>
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={person() !== null && person()!.person_classroom_id !== null}>
|
<Show when={person() !== null && person()!.person_classroom_id !== null}>
|
||||||
<ClassroomUserCourses userid={person()!.person_classroom_id!} />
|
<ClassroomUserCourses
|
||||||
|
userid={person()!.person_classroom_id!}
|
||||||
|
updateSignal={updateSignal()}
|
||||||
|
/>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user