From fbac3b1f90914884c54a04c2c78dbffaaec3ae44 Mon Sep 17 00:00:00 2001 From: Araozu Date: Mon, 8 May 2023 22:05:16 -0500 Subject: [PATCH] Register person to subject UI --- src/app.module.ts | 6 +- src/controller/subject/subject.controller.ts | 13 +++ src/controller/subject/subject.service.ts | 16 +++ src/views/Certs.tsx | 4 +- src/views/components/NewRegister.tsx | 107 ++++++++++++++++++ .../NewRegister/SearchableSelect.tsx | 76 +++++++++++++ src/views/components/Registers.tsx | 1 + src/views/components/Search.tsx | 1 + tailwind.config.js | 1 + 9 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 src/controller/subject/subject.controller.ts create mode 100644 src/controller/subject/subject.service.ts create mode 100644 src/views/components/NewRegister.tsx create mode 100644 src/views/components/NewRegister/SearchableSelect.tsx diff --git a/src/app.module.ts b/src/app.module.ts index dc8c2b9..a7736dc 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -7,6 +7,8 @@ import { CursoGIE } from "./model/CursoGIE/cursoGIE.entity"; import { RegistroGIE } from "./model/RegistroGIE/registroGIE.entity"; import { PersonController } from "./controller/person/person.controller"; import { PersonService } from "./controller/person/person.service"; +import { SubjectController } from "./controller/subject/subject.controller"; +import { SubjectService } from "./controller/subject/subject.service"; @Module({ imports: [ @@ -25,7 +27,7 @@ import { PersonService } from "./controller/person/person.service"; synchronize: false, }), ], - controllers: [CertificateController, PersonController], - providers: [CertificateService, PersonService], + controllers: [CertificateController, PersonController, SubjectController], + providers: [CertificateService, PersonService, SubjectService], }) export class AppModule {} diff --git a/src/controller/subject/subject.controller.ts b/src/controller/subject/subject.controller.ts new file mode 100644 index 0000000..5a10f96 --- /dev/null +++ b/src/controller/subject/subject.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from "@nestjs/common"; +import { SubjectService } from "./subject.service"; + +@Controller("subject") +export class SubjectController { + constructor(private subjectService: SubjectService) { + } + + @Get() + async getAll() { + return this.subjectService.getAll(); + } +} diff --git a/src/controller/subject/subject.service.ts b/src/controller/subject/subject.service.ts new file mode 100644 index 0000000..452d9a3 --- /dev/null +++ b/src/controller/subject/subject.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from "@nestjs/common"; +import { DataSource } from "typeorm"; +import { CursoGIE } from "../../model/CursoGIE/cursoGIE.entity"; + +@Injectable() +export class SubjectService { + cursoGIERepository; + + constructor(private dataSource: DataSource) { + this.cursoGIERepository = dataSource.getRepository(CursoGIE); + } + + getAll() { + return this.cursoGIERepository.find(); + } +} diff --git a/src/views/Certs.tsx b/src/views/Certs.tsx index a6a95ed..6fbcb57 100644 --- a/src/views/Certs.tsx +++ b/src/views/Certs.tsx @@ -1,7 +1,8 @@ -import { createEffect, createSignal } from "solid-js"; +import { createSignal } from "solid-js"; import { Search } from "./components/Search"; import { Person } from "../types/Person"; import { Registers } from "./components/Registers"; +import { NewRegister } from "./components/NewRegister"; export function Certs() { const [person, setPerson] = createSignal(null); @@ -14,6 +15,7 @@ export function Certs() { + ); } diff --git a/src/views/components/NewRegister.tsx b/src/views/components/NewRegister.tsx new file mode 100644 index 0000000..b5915e8 --- /dev/null +++ b/src/views/components/NewRegister.tsx @@ -0,0 +1,107 @@ +import { createSignal, onMount } from "solid-js"; +import type { CursoGIE } from "../../model/CursoGIE/cursoGIE.entity"; +import { SearchableSelect } from "./NewRegister/SearchableSelect"; +import { JSX } from "solid-js/jsx-runtime"; + +type HTMLEventFn = JSX.EventHandlerUnion; + +const testSubjects: Array = JSON.parse("[{\"id\":1,\"nombre\":\"Manejo Defensivo\",\"codigo\":302,\"otro\":\"\"},{\"id\":2,\"nombre\":\"Mecanica Basica\",\"codigo\":100,\"otro\":\"\"},{\"id\":3,\"nombre\":\"4x4\",\"codigo\":82,\"otro\":\"\"},{\"id\":4,\"nombre\":\"Cargador Frontal\",\"codigo\":32,\"otro\":\"\"},{\"id\":5,\"nombre\":\"Excavadora\",\"codigo\":7,\"otro\":\"\"},{\"id\":6,\"nombre\":\"Retroexcavadora\",\"codigo\":14,\"otro\":\"\"},{\"id\":7,\"nombre\":\"Volquete\",\"codigo\":63,\"otro\":\"\"},{\"id\":8,\"nombre\":\"Minicargador\",\"codigo\":5,\"otro\":\"\"},{\"id\":9,\"nombre\":\"Montacargas\",\"codigo\":6,\"otro\":\"\"},{\"id\":10,\"nombre\":\"Matpel I\",\"codigo\":616,\"otro\":\"\"},{\"id\":11,\"nombre\":\"Matpel II\",\"codigo\":1,\"otro\":\"\"},{\"id\":12,\"nombre\":\"Matpel III\",\"codigo\":1,\"otro\":\"\"},{\"id\":13,\"nombre\":\"Matpel IV\",\"codigo\":1,\"otro\":\"\"},{\"id\":14,\"nombre\":\"Supervisor Escolta\",\"codigo\":41,\"otro\":\"\"},{\"id\":15,\"nombre\":\"Herramientas de Gestion\",\"codigo\":86,\"otro\":\"\"},{\"id\":16,\"nombre\":\"Primeros Auxilios\",\"codigo\":249,\"otro\":\"\"},{\"id\":17,\"nombre\":\"Lucha contra Incendios\",\"codigo\":69,\"otro\":\"\"},{\"id\":18,\"nombre\":\"Seguridad Minera\",\"codigo\":17,\"otro\":\"\"},{\"id\":19,\"nombre\":\"SBComportamiento\",\"codigo\":5,\"otro\":\"\"},{\"id\":20,\"nombre\":\"Primer Respondedor\",\"codigo\":132,\"otro\":\"\"},{\"id\":21,\"nombre\":\"Operador Multiple\",\"codigo\":15,\"otro\":\"\"},{\"id\":22,\"nombre\":\"IPERC\",\"codigo\":66,\"otro\":\"\"},{\"id\":23,\"nombre\":\"RITRA\",\"codigo\":6,\"otro\":\"\"},{\"id\":24,\"nombre\":\"Rodillo\",\"codigo\":11,\"otro\":\"\"},{\"id\":25,\"nombre\":\"Fatiga y Somnolencia\",\"codigo\":63,\"otro\":\"\"},{\"id\":26,\"nombre\":\"Bioseguridad y la Salud Ocupacional\",\"codigo\":17,\"otro\":\"\"},{\"id\":27,\"nombre\":\"Seguridad y Salud en Mineria\",\"codigo\":26,\"otro\":\"\"},{\"id\":28,\"nombre\":\"Espacios Confinados\",\"codigo\":23,\"otro\":\"\"},{\"id\":29,\"nombre\":\"Manipulación de productos químicos\",\"codigo\":201,\"otro\":\"\"},{\"id\":30,\"nombre\":\"Interpretación del Reglamento Interno de Transito\",\"codigo\":16,\"otro\":\"\"},{\"id\":31,\"nombre\":\"DERRAMES DE HIDROCARBUROS\",\"codigo\":20,\"otro\":\"\"},{\"id\":32,\"nombre\":\"PREVENCIÓN Y CONTROL DE COVID-19\",\"codigo\":18,\"otro\":\"\"},{\"id\":33,\"nombre\":\"BIOSEGURIDAD EN EL TRABAJO\",\"codigo\":18,\"otro\":\"\"},{\"id\":34,\"nombre\":\"Seguridad en la Operación\",\"codigo\":16,\"otro\":\"\"},{\"id\":35,\"nombre\":\"IMPLEMENTACIÓN DE PLAN DE VIGILANCIA \",\"codigo\":121,\"otro\":\"\"},{\"id\":36,\"nombre\":\"ESPECIALIZACION PERFORACION Y VOLADURA\",\"codigo\":102,\"otro\":\"\"},{\"id\":37,\"nombre\":\"SEGURIDAD Y SALUD EN EL TRABAJO frente al COVID-19\",\"codigo\":81,\"otro\":\"\"},{\"id\":38,\"nombre\":\"Telehandler\",\"codigo\":51,\"otro\":\"\"},{\"id\":39,\"nombre\":\"CAMIÓN GRÚA\",\"codigo\":86,\"otro\":\"\"},{\"id\":40,\"nombre\":\"Supervisor de trabajos en alto riesgo\",\"codigo\":51,\"otro\":\"\"},{\"id\":41,\"nombre\":\"Técnicas preventivas en la operación de maquinaria\",\"codigo\":26,\"otro\":\"\"},{\"id\":42,\"nombre\":\"Prevención y protección contra incendios\",\"codigo\":48,\"otro\":\"\"},{\"id\":44,\"nombre\":\"Salud ocupacional y primeros auxilios\",\"codigo\":30,\"otro\":\"\"},{\"id\":43,\"nombre\":\"Manejo defensivo y transporte personal\",\"codigo\":30,\"otro\":\"\"},{\"id\":45,\"nombre\":\"Seguridad con materiales peligrosos\",\"codigo\":51,\"otro\":\"\"},{\"id\":46,\"nombre\":\"Operador CAT\",\"codigo\":25,\"otro\":\"\"},{\"id\":47,\"nombre\":\"Brigada de emergencia\",\"codigo\":25,\"otro\":\"\"},{\"id\":48,\"nombre\":\"Seguridad en trabajos de alto riesgo\",\"codigo\":25,\"otro\":\"\"},{\"id\":49,\"nombre\":\"Supervisor de seguridad minera e industrial\",\"codigo\":50,\"otro\":\"\"},{\"id\":50,\"nombre\":\"Logística, transporte, almacenaje y manutención\",\"codigo\":25,\"otro\":\"\"},{\"id\":51,\"nombre\":\"Operación segura de montacargas\",\"codigo\":25,\"otro\":\"\"},{\"id\":52,\"nombre\":\"PRIMEROS AUXILIOS (BIOSEGURIDAD) frente al COVID -\",\"codigo\":25,\"otro\":\"\"},{\"id\":53,\"nombre\":\"SEGURIDAD Y SALUD EN EL TRABAJO, bajo normativas a\",\"codigo\":25,\"otro\":\"\"},{\"id\":54,\"nombre\":\"Tractor Oruga\",\"codigo\":25,\"otro\":\"\"},{\"id\":55,\"nombre\":\"Operador SCOOPTRAMS\",\"codigo\":50,\"otro\":\"\"},{\"id\":56,\"nombre\":\"Especialización operador de puente grúa\",\"codigo\":25,\"otro\":\"\"},{\"id\":57,\"nombre\":\"Caja Fuller\",\"codigo\":25,\"otro\":\"\"},{\"id\":58,\"nombre\":\"Especialización Cargador Frontal\",\"codigo\":25,\"otro\":\"\"},{\"id\":59,\"nombre\":\"Operador Jumbo\",\"codigo\":25,\"otro\":\"\"},{\"id\":60,\"nombre\":\"Rescatista Industrial\",\"codigo\":25,\"otro\":\"\"},{\"id\":66,\"nombre\":\"Camión Minero 797F CAT\",\"codigo\":25,\"otro\":\"\"},{\"id\":61,\"nombre\":\"Investigación de accidentes e incidentes\",\"codigo\":25,\"otro\":\"\"},{\"id\":62,\"nombre\":\"Uso y Manejo de Extintores\",\"codigo\":32,\"otro\":\"\"},{\"id\":65,\"nombre\":\"Motoniveladora\",\"codigo\":25,\"otro\":\"\"},{\"id\":67,\"nombre\":\"Sistema de Comando de Incidentes SCI\",\"codigo\":25,\"otro\":\"\"},{\"id\":68,\"nombre\":\"Seguridad en la Operación de Camión Minero de Alto\",\"codigo\":25,\"otro\":\"\"},{\"id\":69,\"nombre\":\"Seguridad Minera frente al Covid-19\",\"codigo\":28,\"otro\":\"\"},{\"id\":70,\"nombre\":\"Operador de Camión Lubricador\",\"codigo\":25,\"otro\":\"\"},{\"id\":71,\"nombre\":\"RIGGER O Auxiliar de Operador Grua\",\"codigo\":28,\"otro\":\"\"},{\"id\":72,\"nombre\":\"Seguridad en la Operacion de Maquinaria Pesada\",\"codigo\":61,\"otro\":\"\"},{\"id\":73,\"nombre\":\"Operador de Elevador de Tijera\",\"codigo\":70,\"otro\":\"\"},{\"id\":74,\"nombre\":\"Trabajos en Caliente\",\"codigo\":24,\"otro\":\"\"},{\"id\":75,\"nombre\":\"Operador Grua Articulada ANSI/ASME\",\"codigo\":26,\"otro\":\"\"},{\"id\":76,\"nombre\":\"Operador Calificado KOMATSU\",\"codigo\":26,\"otro\":\"\"},{\"id\":77,\"nombre\":\"Cuidado del Medio AMbiente\",\"codigo\":26,\"otro\":\"\"},{\"id\":78,\"nombre\":\"Campaña \\\"No al exceso de velocidad\\\"\",\"codigo\":26,\"otro\":\"\"},{\"id\":79,\"nombre\":\"INCENDIO EN VEHÍCULOS\",\"codigo\":26,\"otro\":\"\"},{\"id\":80,\"nombre\":\"Sensibilización Primeros Auxilios\",\"codigo\":26,\"otro\":\"\"},{\"id\":81,\"nombre\":\"Inspecciones de Seguridad\",\"codigo\":27,\"otro\":\"\"},{\"id\":82,\"nombre\":\"Transporte de Personal Industrial\",\"codigo\":30,\"otro\":\"\"},{\"id\":83,\"nombre\":\"BIOSEGURIDAD EN INDUSTRIA Y MINERIA EN COVID-19\",\"codigo\":25,\"otro\":\"\"},{\"id\":84,\"nombre\":\"CAMPAÑA DE NO ALCOHOL\",\"codigo\":10,\"otro\":\"\"},{\"id\":102,\"nombre\":\"OPERACIÓN, LOGÍSTICA Y ALMACENES\",\"codigo\":35,\"otro\":\"\"},{\"id\":87,\"nombre\":\"Trabajos en Altura \",\"codigo\":21,\"otro\":\"\"},{\"id\":88,\"nombre\":\"PERFORACIÓN Y VOLADURA\",\"codigo\":0,\"otro\":\"\"},{\"id\":90,\"nombre\":\"SEGURIDAD Y SALUD EN EL TRABAJO\",\"codigo\":35,\"otro\":\"\"},{\"id\":92,\"nombre\":\"PREVENCIÓN DE RIESGOS LABORALES\",\"codigo\":25,\"otro\":\"\"},{\"id\":94,\"nombre\":\"MANEJO DEFENSIVO 4X4\",\"codigo\":0,\"otro\":\"\"},{\"id\":95,\"nombre\":\"MANEJO DEFENSIVO Y TRANSPORTE PERSONAL\",\"codigo\":35,\"otro\":\"\"},{\"id\":96,\"nombre\":\"CONDUCCIÓN SEGURA\",\"codigo\":35,\"otro\":\"\"},{\"id\":97,\"nombre\":\"MANEJO Y MANTENIMIENTO OPERADOR DE SEMITRAILER\",\"codigo\":25,\"otro\":\"\"},{\"id\":98,\"nombre\":\"OPERADOR CAMION CISTERNA\",\"codigo\":25,\"otro\":\"\"},{\"id\":99,\"nombre\":\"SEMITRAILER INTERNATIONAL\",\"codigo\":25,\"otro\":\"\"},{\"id\":100,\"nombre\":\"Procedimientos de carga y descarga de combustibles\",\"codigo\":50,\"otro\":\"\"},{\"id\":101,\"nombre\":\"Transporte seguro de materiales y residuos peligro\",\"codigo\":50,\"otro\":\"\"},{\"id\":103,\"nombre\":\"GESTIÓN DE ALMACENES EN GENERAL\",\"codigo\":35,\"otro\":\"\"},{\"id\":104,\"nombre\":\"Operación Segura para Transporte de Hidrocarburos \",\"codigo\":35,\"otro\":\"\"},{\"id\":105,\"nombre\":\"COMO EVITAR ACTOS SUBESTANDAR DURANTE LA OPERACIÓN\",\"codigo\":35,\"otro\":\"\"},{\"id\":106,\"nombre\":\"MANIOBRAS TEMERARIAS\",\"codigo\":35,\"otro\":\"\"},{\"id\":107,\"nombre\":\"MANIOBRAS EN PARQUEOS Y ZONAS CERCA A PERSONAL QUE\",\"codigo\":35,\"otro\":\"\"},{\"id\":108,\"nombre\":\"LÍMITES DE VELOCIDAD\",\"codigo\":35,\"otro\":\"\"},{\"id\":109,\"nombre\":\"Cargador Frontal 950M CAT\",\"codigo\":50,\"otro\":\"\"},{\"id\":110,\"nombre\":\"CAMPAÑA DE NO ALCOHOL Y DROGAS\",\"codigo\":50,\"otro\":\"\"},{\"id\":112,\"nombre\":\"GESTIÓN DE RESIDUOS SOLIDOS\",\"codigo\":50,\"otro\":\"\"},{\"id\":113,\"nombre\":\"Tractor de Ruedas\",\"codigo\":50,\"otro\":\"\"},{\"id\":114,\"nombre\":\"Manlift\",\"codigo\":50,\"otro\":\"\"},{\"id\":115,\"nombre\":\"ASPECTOS E IMPACTO AMBIENTAL\",\"codigo\":50,\"otro\":\"\"},{\"id\":116,\"nombre\":\"INVESTIGACIÓN DE ACCIDENTES\",\"codigo\":50,\"otro\":\"\"},{\"id\":117,\"nombre\":\"MANEJO DE RESIDUOS\",\"codigo\":50,\"otro\":\"\"},{\"id\":119,\"nombre\":\"OPERADOR DE SCOOPTRANS R1600H\",\"codigo\":50,\"otro\":\"\"}]"); + +export function NewRegister() { + const [subjects, setSubjects] = createSignal>([]); + const [error, setError] = createSignal(""); + const [loading, setLoading] = createSignal(false); + + const [selectedSubject, setSelectedSubject] = createSignal(null); + + const datePicker = ( + + ); + + + // Loads subjects from DB + onMount(async() => { + console.log("Retrieve all subjects"); + + try { + const response = await fetch("/subject/"); + if (response.ok) { + setSubjects(await response.json()); + } else { + setError("No se pudo cargar cursos"); + } + } catch (e) { + setError(`No se pudo cargar cursos. ${JSON.stringify(e)}`); + } + }); + + const register: HTMLEventFn = async(ev) => { + ev.preventDefault(); + + const subject = selectedSubject(); + const date = (datePicker as HTMLInputElement).value; + + if (subject === null) { + setError("Selecciona un curso"); + + setTimeout(() => setError(""), 5000); + return; + } + if (date === "") { + setError("Selecciona una fecha"); + + setTimeout(() => setError(""), 5000); + return; + } + + setLoading(true); + }; + + return ( +
+

3. Crear nuevos registros

+ +

+ {error()}  +

+ +
+
+ +
+ +
+
+ +
+ {datePicker} +
+
+
+
+ +
+
+
+ ); +} diff --git a/src/views/components/NewRegister/SearchableSelect.tsx b/src/views/components/NewRegister/SearchableSelect.tsx new file mode 100644 index 0000000..c42fb23 --- /dev/null +++ b/src/views/components/NewRegister/SearchableSelect.tsx @@ -0,0 +1,76 @@ +import { createEffect, createMemo, createSignal, For, JSX, Show } from "solid-js"; +import type {CursoGIE} from "../../../model/CursoGIE/cursoGIE.entity"; +import { isServer } from "solid-js/web"; + +export function SearchableSelect(props: {subjects: Array, onChange: (id: number | null) => void}) { + const [filter, setFilter] = createSignal(""); + const [selected, setSelected] = createSignal(null); + const [inputValue, setInputValue] = createSignal(""); + + const iHandler = (ev: KeyboardEvent & {currentTarget: HTMLInputElement, target: Element}) => { + const inputEl = ev.target as HTMLInputElement; + // Clear current selection + setSelected(null); + setFilter(inputEl.value.toLowerCase()); + }; + + createEffect(() => { + props.onChange(selected()); + }); + + const inputElement = ( + setInputValue(ev.target.value)} + autocomplete="off" + /> + ); + + if (!isServer) { + (inputElement as HTMLInputElement).addEventListener("keydown", (ev) => { + if (ev.code === "Enter") { + ev.preventDefault(); + } + }); + } + + return ( + <> + {inputElement} +
+
+ + {(s) => ( + + )} + +
+ + ); +} diff --git a/src/views/components/Registers.tsx b/src/views/components/Registers.tsx index dffcf89..1195a0c 100644 --- a/src/views/components/Registers.tsx +++ b/src/views/components/Registers.tsx @@ -8,6 +8,7 @@ export function Registers(props: { person: Person | null }) { createEffect(() => { const person = props.person; + console.log(`Loading registers for ${person?.nombres}`); // Load certificates from DB loadCertificates(); diff --git a/src/views/components/Search.tsx b/src/views/components/Search.tsx index c3ce97e..6398230 100644 --- a/src/views/components/Search.tsx +++ b/src/views/components/Search.tsx @@ -39,6 +39,7 @@ export function Search(props: {setPerson: (p: Person | null) => void}) { console.error(body); setWarning("Persona no encontrada. Se debe insertar manualmente sus datos."); + props.setPerson(null); } else { setError(body); } diff --git a/tailwind.config.js b/tailwind.config.js index 5f4191e..7cdc759 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -21,6 +21,7 @@ module.exports = { "c-outline": "var(--c-outline)", "c-surface-variant": "var(--c-surface-variant)", "c-on-surface-variant": "var(--c-on-surface-variant)", + "c-green": "#006b54", }, }, plugins: [],