diff --git a/frontend/src/certs/NewRegister/RegisterPresets.tsx b/frontend/src/certs/NewRegister/RegisterPresets.tsx index 82a56ae..a062acd 100644 --- a/frontend/src/certs/NewRegister/RegisterPresets.tsx +++ b/frontend/src/certs/NewRegister/RegisterPresets.tsx @@ -1,53 +1,11 @@ -import { Accessor, For, createSignal } from "solid-js"; +import { For, createMemo, createSignal } from "solid-js"; import { Chip } from "../../components/Chip"; -import { getCourseMemo } from "../../utils/allCourses"; import { Course } from "../../types/Course"; import { RegistrationPreview } from "."; +import { useCourses } from ".."; type PresetName = "None" | "2 Matpel" | "3 Matpel" | "4 Escolta" | "MD, 2 Matpel" | "3 4x4" | "2 4x4" | "6 Sibia"; -function genPresets(): {[k: string]: Array>} { - return { - "2 Matpel": [ - getCourseMemo("Matpel 2"), - getCourseMemo("Matpel 1"), - ], - "3 Matpel": [ - getCourseMemo("Matpel 3"), - getCourseMemo("Matpel 2"), - getCourseMemo("Matpel 1"), - ], - "4 Escolta": [ - getCourseMemo("Sup. Escolta"), - getCourseMemo("Matpel 3"), - getCourseMemo("Matpel 2"), - getCourseMemo("Matpel 1"), - ], - "MD, 2 Matpel": [ - getCourseMemo("Matpel 2"), - getCourseMemo("Matpel 1"), - getCourseMemo("Manejo Defensivo"), - ], - "3 4x4": [ - getCourseMemo("4x4"), - getCourseMemo("Mecanica Basica"), - getCourseMemo("Manejo Defensivo"), - ], - "2 4x4": [ - getCourseMemo("4x4"), - getCourseMemo("Manejo Defensivo"), - ], - "6 Sibia": [ - getCourseMemo("Matpel 2"), - getCourseMemo("Matpel 1"), - getCourseMemo("Manejo Defensivo"), - getCourseMemo("Primeros Auxilios"), - getCourseMemo("IPERC"), - getCourseMemo("Lucha contra Incendios"), - ], - }; -} - export function RegisterPresets(props: { disableCreation: boolean, onAdd: (v: RegistrationPreview) => void @@ -56,7 +14,46 @@ export function RegisterPresets(props: { const [selectedPreset, setSelectedPreset] = createSignal("None"); const [isPreview, setIsPreview] = createSignal(false); const [error, setError] = createSignal(""); - const presets = genPresets(); + const courses = useCourses(); + + const presets = createMemo<{[key: string]: Array}>(() => { + if (courses === undefined) { + return {}; + } + + const coursesMap = courses.map(); + + const matpel1 = coursesMap["Matpel 1"]; + const matpel2 = coursesMap["Matpel 2"]; + const matpel3 = coursesMap["Matpel 3"]; + const escolta = coursesMap["Sup. Escolta"]; + const mecanica = coursesMap["Mecanica Basica"]; + const manejo = coursesMap["Manejo Defensivo"]; + const primerosAuxilios = coursesMap["Primeros Auxilios"]; + const iperc = coursesMap.IPERC; + const luchaIncendios = coursesMap["Lucha contra Incendios"]; + const cuatroXcuatro = coursesMap["4x4"]; + + if (matpel1 === undefined || matpel2 === undefined || matpel3 === undefined || escolta === undefined || + mecanica === undefined || manejo === undefined || primerosAuxilios === undefined || iperc === undefined || + luchaIncendios === undefined || cuatroXcuatro === undefined + ) { + setError("Un curso de los presets no existe. Error fatal."); + return {}; + } + + const data: {[key: string]: Array} = { + "2 Matpel": [matpel2, matpel1], + "3 Matpel": [matpel3,matpel2, matpel1], + "4 Escolta": [escolta, matpel3,matpel2, matpel1], + "MD, 2 Matpel": [matpel2, matpel1, manejo], + "3 4x4": [cuatroXcuatro, mecanica, manejo], + "2 4x4": [cuatroXcuatro, manejo], + "6 Sibia": [matpel2, matpel1, manejo, primerosAuxilios, iperc, luchaIncendios], + }; + + return data; + }); const add = () => { if (datePicker === undefined) { @@ -76,11 +73,9 @@ export function RegisterPresets(props: { return; } - const presetIds = presets[preset]; + const presetIds = presets()[preset]; const currentDate = new Date(date); - for (const courseMemo of presetIds) { - // Get course and course duration from the memo - const course = courseMemo(); + for (const course of presetIds) { if (course === null) { setError(`Un curso no existe. Error fatal. (${preset})`); return; @@ -112,7 +107,7 @@ export function RegisterPresets(props: {

Las fechas se colocan automáticamente según la duración del curso y su jeraquía.


- + {(key) => ( void, isPreview: boolean, }) { - const courseName = () => { - const courses = allCourses(); - return courses.find((course) => course.course_id === props.courseId)?.course_name ?? `Curso invalido! (${props.courseId})`; + const courses = useCourses(); + + const courseName = (): string => { + if (courses === undefined || courses?.data.state !== "ready") { + return "~~Cursos cargando~~"; + } + + return courses + .data() + .find((course) => course.course_id === props.courseId) + ?.course_name ?? + `~~Curso invalido! (${props.courseId})~~`; }; return ( diff --git a/frontend/src/certs/NewRegister/SearchableSelect.tsx b/frontend/src/certs/NewRegister/SearchableSelect.tsx index 6bfdac5..e95d024 100644 --- a/frontend/src/certs/NewRegister/SearchableSelect.tsx +++ b/frontend/src/certs/NewRegister/SearchableSelect.tsx @@ -1,7 +1,5 @@ -import { createEffect, createSignal, For } from "solid-js"; -// import type {CursoGIE} from "../../../model/CursoGIE/cursoGIE.entity"; -import { isServer } from "solid-js/web"; -import { allCourses } from "../../utils/allCourses"; +import { createEffect, createSignal, For, onMount } from "solid-js"; +import { useCourses } from ".."; export function SearchableSelect(props: { onChange: (id: number | null) => void, @@ -11,6 +9,8 @@ export function SearchableSelect(props: { const [selected, setSelected] = createSignal(null); const [inputValue, setInputValue] = createSignal(""); + const courses = useCourses(); + const iHandler = (ev: KeyboardEvent & {currentTarget: HTMLInputElement, target: Element}) => { const inputEl = ev.target as HTMLInputElement; // Clear current selection @@ -58,18 +58,22 @@ export function SearchableSelect(props: { /> ); - if (!isServer) { + onMount(() => { (inputElement as HTMLInputElement).addEventListener("keydown", (ev) => { if (ev.code === "Enter") { ev.preventDefault(); } }); - } + }); const filteredOptions = () => { const filterText = filter(); - return allCourses().filter((course) => { + if (courses === undefined || courses?.data.state !== "ready") { + return []; + } + + return courses.data().filter((course) => { let courseText = course.course_name.toLowerCase(); courseText = courseText.replace("á", "a"); courseText = courseText.replace("é", "e"); diff --git a/frontend/src/certs/index.tsx b/frontend/src/certs/index.tsx index 817e5f6..dd15690 100644 --- a/frontend/src/certs/index.tsx +++ b/frontend/src/certs/index.tsx @@ -1,21 +1,80 @@ -import { createSignal } from "solid-js"; +import { JSX, Resource, 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"; export function Certs() { const [person, setPerson] = createSignal(null); const [count, setCount] = createSignal(0); + const [courses] = createResource(fetchAllCourses); + + const coursesReady = createMemo(() => courses.state === "ready"); + return ( -
- - setCount((x) => x + 1)} - /> - -
+ <> +
+
+
+
+
+ +
+ + setCount((x) => x + 1)} + /> + +
+
+ ); } + + +const CoursesContext = createContext<{ + data: Resource, + map: () => {[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 = {[k: string]: Course}; + const map: CourseMap = {}; + for (const course of data) { + map[course.course_name] = course; + } + + return map; + }); + + const coursesData = { + data: props.courses, + map: courseMapMemo, + }; + + return ( + + {props.children} + + ); +} + +async function fetchAllCourses(): Promise> { + const result = await axios.get>(`${import.meta.env.VITE_BACKEND_URL}/api/course`); + return result.data; +} + +export function useCourses() { + return useContext(CoursesContext); +} diff --git a/frontend/src/index.css b/frontend/src/index.css index 3ac7b8f..a063eeb 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -28,4 +28,24 @@ body { @tailwind base; @tailwind components; -@tailwind utilities; \ No newline at end of file +@tailwind utilities; + +.progress { + animation: progress 1s infinite linear; + } + + .left-right { + transform-origin: 0% 50%; + } + @keyframes progress { + 0% { + transform: translateX(0) scaleX(0); + } + 40% { + transform: translateX(0) scaleX(0.4); + } + 100% { + transform: translateX(100%) scaleX(0.5); + } + } + diff --git a/frontend/src/utils/allCourses.ts b/frontend/src/utils/allCourses.ts index 7397973..08a7a64 100644 --- a/frontend/src/utils/allCourses.ts +++ b/frontend/src/utils/allCourses.ts @@ -3,7 +3,7 @@ import { Course } from "../types/Course"; type CourseMap = {[k: number]: Course}; -export const [allCourses, setAllCourses] = createSignal>([]); +const [allCourses, setAllCourses] = createSignal>([]); export const [courseMap, setCourseMap] = createSignal({}); (() => { diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 8dfe5e7..84a49b8 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -8,6 +8,20 @@ module.exports = { fontFamily: { "mono": ["Inconsolata", "monospace"], }, + animation: { + progress: "progress 1s infinite linear", + }, + keyframes: { + progress: { + "0%": { transform: " translateX(0) scaleX(0)" }, + "40%": { transform: "translateX(0) scaleX(0.4)" }, + "100%": { transform: "translateX(100%) scaleX(0.5)" }, + }, + }, + transformOrigin: { + "left-right": "0% 50%", + }, + }, colors: { "c-primary": "var(--c-primary)",