[FE] Improve UI for classroom
This commit is contained in:
parent
4d70e7c428
commit
525c72a9f6
1
backend/.gitignore
vendored
1
backend/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
target
|
target
|
||||||
.env
|
.env
|
||||||
aulavirtual
|
aulavirtual
|
||||||
|
scraps
|
||||||
|
@ -5,6 +5,10 @@ import { FilledCard } from "../components/FilledCard";
|
|||||||
import { LinkIcon } from "../icons/LinkIcon";
|
import { LinkIcon } from "../icons/LinkIcon";
|
||||||
import { ClassroomUserCreation } from "./ClassroomUserCreation";
|
import { ClassroomUserCreation } from "./ClassroomUserCreation";
|
||||||
import { ClassroomRegistrationUser } from "../types/ClassroomRegistrationUser";
|
import { ClassroomRegistrationUser } from "../types/ClassroomRegistrationUser";
|
||||||
|
import { SpinnerGapIcon } from "../icons/SpinnerGapIcon";
|
||||||
|
import { QuestionIcon } from "../icons/QuestionIcon";
|
||||||
|
import { JsonResult } from "../types/JsonResult";
|
||||||
|
import { XcircleIcon } from "../icons/XCircleIcon";
|
||||||
|
|
||||||
type TabType = "Vinculate" | "Create";
|
type TabType = "Vinculate" | "Create";
|
||||||
|
|
||||||
@ -54,19 +58,25 @@ function ClassroomUser(props: {person: Person}) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Status = "Init" | "Ok" | "Loading" | "Error";
|
||||||
function ClassroomVinculation(props: {person_surname: string}) {
|
function ClassroomVinculation(props: {person_surname: string}) {
|
||||||
const [classroomUsers, setClassroomUsers] = createSignal<ClassroomRegistrationUser[]>([]);
|
const [classroomUsers, setClassroomUsers] = createSignal<ClassroomRegistrationUser[]>([]);
|
||||||
|
const [error, setError] = createSignal("");
|
||||||
|
const [status, setStatus] = createSignal<Status>("Init");
|
||||||
|
|
||||||
const loadUsers = async() => {
|
const loadUsers = async() => {
|
||||||
|
setStatus("Loading");
|
||||||
const response = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/classroom/users/${encodeURIComponent(props.person_surname)}`);
|
const response = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/classroom/users/${encodeURIComponent(props.person_surname)}`);
|
||||||
const json = await response.json();
|
const json: JsonResult<Array<ClassroomRegistrationUser>> = await response.json();
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
setClassroomUsers(json);
|
setClassroomUsers(json.Ok);
|
||||||
|
setStatus("Ok");
|
||||||
} else {
|
} else {
|
||||||
console.error("Error loading users", json);
|
console.error("Error loading users", json);
|
||||||
|
setError(json.Err.reason);
|
||||||
|
setStatus("Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(loadUsers);
|
onMount(loadUsers);
|
||||||
@ -76,32 +86,58 @@ function ClassroomVinculation(props: {person_surname: string}) {
|
|||||||
<p class="py-2 px-4">
|
<p class="py-2 px-4">
|
||||||
Vincule un usuario existente:
|
Vincule un usuario existente:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<Show when={status() === "Loading"}>
|
||||||
|
<div class="text-center h-12 scale-150">
|
||||||
|
<SpinnerGapIcon class="animate-spin" fill="var(--c-primary)" />
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={status() === "Ok"}>
|
||||||
|
<Show when={classroomUsers().length === 0}>
|
||||||
|
<div class="px-4 pb-2">
|
||||||
|
<div class="text-center pt-6 pb-4">
|
||||||
|
<QuestionIcon class="scale-[200%]" fill="var(--c-outline)" />
|
||||||
|
</div>
|
||||||
|
<p>No se encontraron usuarios en el aula virtual.</p>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
<For each={classroomUsers()}>
|
<For each={classroomUsers()}>
|
||||||
{(_) => <ClassroomSingleUser />}
|
{(u) => <ClassroomSingleUser user={u} />}
|
||||||
</For>
|
</For>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={status() === "Error"}>
|
||||||
|
<div class="px-4 pb-2 text-c-error">
|
||||||
|
<div class="text-center pt-6 pb-4">
|
||||||
|
<XcircleIcon class="scale-[200%]" fill="var(--c-error)" />
|
||||||
|
</div>
|
||||||
|
<p>Error buscando usuarios: {error()}.</p>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function ClassroomSingleUser() {
|
function ClassroomSingleUser(props: {user: ClassroomRegistrationUser}) {
|
||||||
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
|
||||||
grid grid-cols-[auto_3rem] gap-4"
|
grid grid-cols-[auto_3rem] gap-4"
|
||||||
>
|
>
|
||||||
<div class="pl-4 py-2">
|
<div class="pl-4 py-2">
|
||||||
NOMBRE NOMBRE APELLIDO APELLIDO
|
{props.user.name} {props.user.surname}
|
||||||
<br />
|
<br />
|
||||||
<div class="grid grid-cols-[auto_10rem]">
|
<div class="grid grid-cols-[auto_10rem]">
|
||||||
<span class="font-mono">
|
<span class="font-mono">
|
||||||
NNAPELLA
|
{props.user.username}
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
registrado:
|
registrado:
|
||||||
<span class="font-mono">
|
<span class="font-mono">
|
||||||
26/05/2023
|
??/??/????
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
16
frontend/src/icons/QuestionIcon.tsx
Normal file
16
frontend/src/icons/QuestionIcon.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export function QuestionIcon(props: {fill: string, size?: number, class?: string}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class={`inline-block w-6 ${props.class}`}
|
||||||
|
width={props.size ?? 32}
|
||||||
|
height={props.size ?? 32}
|
||||||
|
fill={props.fill}
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
>
|
||||||
|
<path d="M140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180ZM128,72c-22.06,0-40,16.15-40,36v4a8,8,0,0,0,16,0v-4c0-11,10.77-20,24-20s24,9,24,20-10.77,20-24,20a8,8,0,0,0-8,8v8a8,8,0,0,0,16,0v-.72c18.24-3.35,32-17.9,32-35.28C168,88.15,150.06,72,128,72Zm104,56A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
16
frontend/src/icons/SpinnerGapIcon.tsx
Normal file
16
frontend/src/icons/SpinnerGapIcon.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export function SpinnerGapIcon(props: {fill: string, size?: number, class?: string}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class={`inline-block w-6 ${props.class}`}
|
||||||
|
width={props.size ?? 32}
|
||||||
|
height={props.size ?? 32}
|
||||||
|
fill={props.fill}
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
>
|
||||||
|
<path d="M136,32V64a8,8,0,0,1-16,0V32a8,8,0,0,1,16,0Zm37.25,58.75a8,8,0,0,0,5.66-2.35l22.63-22.62a8,8,0,0,0-11.32-11.32L167.6,77.09a8,8,0,0,0,5.65,13.66ZM224,120H192a8,8,0,0,0,0,16h32a8,8,0,0,0,0-16Zm-45.09,47.6a8,8,0,0,0-11.31,11.31l22.62,22.63a8,8,0,0,0,11.32-11.32ZM128,184a8,8,0,0,0-8,8v32a8,8,0,0,0,16,0V192A8,8,0,0,0,128,184ZM77.09,167.6,54.46,190.22a8,8,0,0,0,11.32,11.32L88.4,178.91A8,8,0,0,0,77.09,167.6ZM72,128a8,8,0,0,0-8-8H32a8,8,0,0,0,0,16H64A8,8,0,0,0,72,128ZM65.78,54.46A8,8,0,0,0,54.46,65.78L77.09,88.4A8,8,0,0,0,88.4,77.09Z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
16
frontend/src/icons/XCircleIcon.tsx
Normal file
16
frontend/src/icons/XCircleIcon.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export function XcircleIcon(props: {fill: string, size?: number, class?: string}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class={`inline-block w-6 ${props.class}`}
|
||||||
|
width={props.size ?? 32}
|
||||||
|
height={props.size ?? 32}
|
||||||
|
fill={props.fill}
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
>
|
||||||
|
<path d="M165.66,101.66,139.31,128l26.35,26.34a8,8,0,0,1-11.32,11.32L128,139.31l-26.34,26.35a8,8,0,0,1-11.32-11.32L116.69,128,90.34,101.66a8,8,0,0,1,11.32-11.32L128,116.69l26.34-26.35a8,8,0,0,1,11.32,11.32ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
6
frontend/src/types/JsonResult.ts
Normal file
6
frontend/src/types/JsonResult.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export type JsonResult<T> = {
|
||||||
|
Ok: T,
|
||||||
|
Err: {
|
||||||
|
reason: string
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user