diff --git a/frontend/src/certs/CertsImpl.tsx b/frontend/src/certs/CertsImpl.tsx new file mode 100644 index 0000000..fb13ea5 --- /dev/null +++ b/frontend/src/certs/CertsImpl.tsx @@ -0,0 +1,44 @@ +import { Show, createSignal } from "solid-js"; +import { NewRegister } from "./NewRegister"; +import { Registers } from "./Registers"; +import { Search } from "./Search"; +import { Person } from "../types/Person"; +import { useCourses } from "./CourseContext"; + +export function CertsImpl() { + const [person, setPerson] = createSignal(null); + const [count, setCount] = createSignal(0); + const courses = useCourses()!; + + return ( + <> +
+
+
+
+
+ +
+ + setCount((x) => x + 1)} + /> + +
+
+ +
+
+ Error al cargar recursos vitales del sistema (lista de cursos) +
+ Recargue la página para intentar de nuevo +
+
+ {courses?.errorMessage()} +
+
+
+ + ); +} diff --git a/frontend/src/certs/CourseContext.tsx b/frontend/src/certs/CourseContext.tsx new file mode 100644 index 0000000..1e9d981 --- /dev/null +++ b/frontend/src/certs/CourseContext.tsx @@ -0,0 +1,81 @@ +import { JSX, Resource, createContext, createMemo, createResource, useContext } from "solid-js"; +import axios from "axios"; +import { Course } from "../types/Course"; + +const CoursesContext = createContext<{ + data: Resource, + nameMap: () => {[course_name: string]: Course}, + idMap: () => {[course_name: string]: Course}, + loading: () => boolean, + ready: () => boolean, + errored: () => boolean, + errorMessage: () => string, +}>(); + +export function CoursesProvider(props: {children: JSX.Element}) { + const [courses] = createResource(fetchAllCourses); + + const courseMapMemo = createMemo(() => { + if (courses === undefined || courses?.state !== "ready") { + return {}; + } + + const data = courses(); + + type CourseMap = {[course_name: string]: Course}; + const map: CourseMap = {}; + for (const course of data) { + map[course.course_name] = course; + } + + return map; + }); + + const courseIdMapMemo = createMemo(() => { + if (courses === undefined || courses?.state !== "ready") { + return {}; + } + + const data = courses(); + + type CourseMap = {[course_id: number]: Course}; + const map: CourseMap = {}; + for (const course of data) { + map[course.course_id] = course; + } + + return map; + }); + + const coursesData = { + data: courses, + nameMap: courseMapMemo, + idMap: courseIdMapMemo, + loading: createMemo(() => courses.state === "pending"), + ready: createMemo(() => courses.state === "ready"), + errored: createMemo(() => courses.state === "errored"), + errorMessage: createMemo(() => courses.error?.message ?? ""), + }; + + return ( + + {props.children} + + ); +} + +let cachedCourses: Array | null = null; + +async function fetchAllCourses(): Promise> { + if (cachedCourses !== null) { + return cachedCourses; + } + + const result = await axios.get>(`${import.meta.env.VITE_BACKEND_URL}/api/course`); + cachedCourses = result.data; + return result.data; +} + +export function useCourses() { + return useContext(CoursesContext); +} diff --git a/frontend/src/certs/NewRegister/ManualRegistration.tsx b/frontend/src/certs/NewRegister/ManualRegistration.tsx index ee822d9..dd376f3 100644 --- a/frontend/src/certs/NewRegister/ManualRegistration.tsx +++ b/frontend/src/certs/NewRegister/ManualRegistration.tsx @@ -3,7 +3,7 @@ import { SearchableSelect } from "./SearchableSelect"; import { CustomLabelSelect } from "./CustomLabelSelect"; import { RegistrationPreview } from "."; import { customLabelsMap } from "../../utils/allCustomLabels"; -import { useCourses } from ".."; +import { useCourses } from "../CourseContext"; type HTMLEventFn = JSX.EventHandlerUnion void, diff --git a/frontend/src/certs/Registers/RegisterElement.tsx b/frontend/src/certs/Registers/RegisterElement.tsx index 2fffd49..5c4155d 100644 --- a/frontend/src/certs/Registers/RegisterElement.tsx +++ b/frontend/src/certs/Registers/RegisterElement.tsx @@ -12,8 +12,8 @@ import QR from "qrcode"; import saveAs from "file-saver"; import { genMatpelCarnet } from "../../carnetGenerator/matpel"; import { genMachineryCarnet } from "../../carnetGenerator/machinery"; -import { useCourses } from ".."; import { Course } from "../../types/Course"; +import { useCourses } from "../CourseContext"; const carnetEnabled = [ "Matpel 3", diff --git a/frontend/src/certs/Registers/RegisterSidebar.tsx b/frontend/src/certs/Registers/RegisterSidebar.tsx index 4ad07a6..0419cee 100644 --- a/frontend/src/certs/Registers/RegisterSidebar.tsx +++ b/frontend/src/certs/Registers/RegisterSidebar.tsx @@ -1,7 +1,7 @@ import { createMemo } from "solid-js"; -import { useCourses } from ".."; import { Register } from "../../types/Register"; import { formatDate } from "../../utils/functions"; +import { useCourses } from "../CourseContext"; export function RegisterSidebar(props: { register: Register, diff --git a/frontend/src/certs/Registers/index.tsx b/frontend/src/certs/Registers/index.tsx index a5ecffb..2665319 100644 --- a/frontend/src/certs/Registers/index.tsx +++ b/frontend/src/certs/Registers/index.tsx @@ -7,7 +7,7 @@ import { backend, wait } from "../../utils/functions"; import { JsonResult } from "../../types/JsonResult"; import { LoadingIcon } from "../../icons/LoadingIcon"; import { RegisterElement, generateCert } from "./RegisterElement"; -import { useCourses } from ".."; +import { useCourses } from "../CourseContext"; export function Registers(props: {person: Person | null, count: number}) { const [registers, setRegisters] = createSignal>([]); diff --git a/frontend/src/certs/index.tsx b/frontend/src/certs/index.tsx index 24d35d9..4f30b19 100644 --- a/frontend/src/certs/index.tsx +++ b/frontend/src/certs/index.tsx @@ -1,120 +1,10 @@ -import { JSX, Resource, Show, createContext, createMemo, createResource, createSignal, useContext } from "solid-js"; -import { NewRegister } from "./NewRegister"; -import { Registers } from "./Registers"; -import { Search } from "./Search"; -import { Person } from "../types/Person"; -import axios from "axios"; -import { Course } from "../types/Course"; +import { CertsImpl } from "./CertsImpl"; +import { CoursesProvider } from "./CourseContext"; export function Certs() { - const [person, setPerson] = createSignal(null); - const [count, setCount] = createSignal(0); - - const [courses] = createResource(fetchAllCourses); - - const coursesReady = createMemo(() => courses.state === "ready"); - const coursesLoading = createMemo(() => courses.state === "pending"); - return ( - <> -
-
-
-
-
- - -
- - setCount((x) => x + 1)} - /> - -
-
-
- -
-
- Error al cargar recursos vitales del sistema (lista de cursos) -
- Recargue la página para intentar de nuevo -
-
- {courses.error?.message} -
-
-
- + + + ); } - - -const CoursesContext = createContext<{ - data: Resource, - nameMap: () => {[course_name: string]: Course}, - idMap: () => {[course_name: string]: Course}, -}>(); - -function CoursesProvider(props: {courses: Resource, children: JSX.Element}) { - const courseMapMemo = createMemo(() => { - if (props.courses === undefined || props.courses?.state !== "ready") { - return {}; - } - - const data = props.courses(); - - type CourseMap = {[course_name: string]: Course}; - const map: CourseMap = {}; - for (const course of data) { - map[course.course_name] = course; - } - - return map; - }); - - const courseIdMapMemo = createMemo(() => { - if (props.courses === undefined || props.courses?.state !== "ready") { - return {}; - } - - const data = props.courses(); - - type CourseMap = {[course_id: number]: Course}; - const map: CourseMap = {}; - for (const course of data) { - map[course.course_id] = course; - } - - return map; - }); - - const coursesData = { - data: props.courses, - nameMap: courseMapMemo, - idMap: courseIdMapMemo, - }; - - return ( - - {props.children} - - ); -} - -let cachedCourses: Array | null = null; - -async function fetchAllCourses(): Promise> { - if (cachedCourses !== null) { - return cachedCourses; - } - - const result = await axios.get>(`${import.meta.env.VITE_BACKEND_URL}/api/course`); - cachedCourses = result.data; - return result.data; -} - -export function useCourses() { - return useContext(CoursesContext); -}