Vista de seleccion de cursos
This commit is contained in:
parent
16f2e71430
commit
57a96ce28c
217
API.md
Normal file
217
API.md
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
# Inicio de sesion
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// HTTP POST
|
||||||
|
// Url: /login
|
||||||
|
|
||||||
|
// Frontend envia el correo del usuario
|
||||||
|
{
|
||||||
|
correo_usuario: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend responde con una lista de matriculas
|
||||||
|
// Si el correo es valido y el usuario tiene alguna matricula
|
||||||
|
{
|
||||||
|
matriculas: Array<number> // Un array de id_laboratorio
|
||||||
|
}
|
||||||
|
// Si el correo es valido pero el usuario no tiene matriculas
|
||||||
|
{
|
||||||
|
matriculas: [] // Un array vacio
|
||||||
|
}
|
||||||
|
// Si el correo es invalido: Se envia HTTP 401
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Lista cursos
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// HTTP GET
|
||||||
|
// Url: /cursos
|
||||||
|
|
||||||
|
// El frontend pide una lista de la informacion de todos los cursos
|
||||||
|
|
||||||
|
// Backend responde con una lista de todos los cursos
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id_curso: number,
|
||||||
|
id_datos_carrera: any, // Opcional
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: number | string, // Numero o string, dependiendo de como este en DB
|
||||||
|
abreviado: string,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Carga de horarios
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// HTTP GET
|
||||||
|
// Url: /horarios?cursos=...
|
||||||
|
|
||||||
|
// El frontend envia una lista de cursos, de los cuales recuperar sus datos
|
||||||
|
{
|
||||||
|
cursos: Array<number> // Un array de id_curso
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend responde con los cursos especificados y sus horarios
|
||||||
|
[
|
||||||
|
// Cada objeto dentro del array sera un Curso
|
||||||
|
{
|
||||||
|
id_curso: number,
|
||||||
|
id_datos_carrera: any, // Opcional
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: number | string,
|
||||||
|
abreviado: string,
|
||||||
|
// Un array de objetos, estos objetos son de la entidad Laboratorio
|
||||||
|
laboratorios: [
|
||||||
|
{
|
||||||
|
id_laboratorio: number,
|
||||||
|
id_curso: number,
|
||||||
|
id_horario: number,
|
||||||
|
grupo: string,
|
||||||
|
docente: string,
|
||||||
|
// Array de objetos de la entidad Horario
|
||||||
|
horario: [
|
||||||
|
{
|
||||||
|
id_horario: number,
|
||||||
|
dia: string,
|
||||||
|
hora_inicio: string,
|
||||||
|
hora_fin: string,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Matricula
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// HTTP POST
|
||||||
|
// Url: /matricula
|
||||||
|
|
||||||
|
// Frontend envia una lista de horarios en los cuales se matricula y el usuario
|
||||||
|
{
|
||||||
|
correo_usuario: string, // Correo del usuario
|
||||||
|
horarios: Array<number> // Array de id_laboratorio
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend devuelve HTTP 200 si exitoso, HTTP 400 si hay error (no hay cupos)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Recuperacion de matricula
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// HTTP POST
|
||||||
|
// Url: /recuperacion
|
||||||
|
|
||||||
|
// Frontend envia una lista de id_laboratorio
|
||||||
|
{
|
||||||
|
matriculas: Array<number> // Array de id_laboratorio
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend devuelve:
|
||||||
|
// Por cada id_laboratorio: datos del curso y el laboratorio
|
||||||
|
[
|
||||||
|
// Un objeto asi por cada id_laboratorio
|
||||||
|
{
|
||||||
|
nombre_curso: string, // Este es el campo `nombre_curso` de la entidad Curso
|
||||||
|
grupo: string, // Campo `grupo` de la entidad Laboratorio
|
||||||
|
docente: string, // Campo `docente` de la entidad Laboratorio
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Creacion de datos
|
||||||
|
|
||||||
|
Endpoints para insertar datos a la db
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// POST /crear-carrera
|
||||||
|
|
||||||
|
// Front
|
||||||
|
{
|
||||||
|
nombre_carrera: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend
|
||||||
|
{
|
||||||
|
id_carrera: number // id de la carrera creada
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// POST /crear-curso
|
||||||
|
|
||||||
|
// Front
|
||||||
|
{
|
||||||
|
id_datos_carrera: number,
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: string, // Ejm: "1er", "2do", etc
|
||||||
|
abreviado: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend
|
||||||
|
{
|
||||||
|
id_curso: number // id del curso creado
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// POST /crear-laboratorio
|
||||||
|
|
||||||
|
// Front
|
||||||
|
{
|
||||||
|
id_curso: number,
|
||||||
|
grupo: string, // Una letra
|
||||||
|
docente: string,
|
||||||
|
max_estudiantes: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend
|
||||||
|
{
|
||||||
|
id_laboratorio: number // id del lab creado
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// POST /crear-horario
|
||||||
|
|
||||||
|
// Front
|
||||||
|
{
|
||||||
|
id_laboratorio: number,
|
||||||
|
dia: string, // "Lunes", "Martes", etc
|
||||||
|
hora_inicio: string, // "07:00"
|
||||||
|
hora_fin: string, // "08:50"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backend
|
||||||
|
{
|
||||||
|
id_horario: number // id del horario creado
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
5
jest.config.js
Normal file
5
jest.config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
preset: "ts-jest",
|
||||||
|
testEnvironment: "node",
|
||||||
|
};
|
82
src/API/ListaCursos.ts
Normal file
82
src/API/ListaCursos.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
// HTTP GET
|
||||||
|
// Url: /cursos
|
||||||
|
|
||||||
|
// El frontend pide una lista de la informacion de todos los cursos
|
||||||
|
|
||||||
|
// Backend responde con una lista de todos los cursos
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id_curso: number,
|
||||||
|
id_datos_carrera: any, // Opcional
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: number | string, // Numero o string, dependiendo de como este en DB
|
||||||
|
abreviado: string,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { SERVER_PATH } from "../Store";
|
||||||
|
|
||||||
|
export type InfoCurso = {
|
||||||
|
id_curso: number,
|
||||||
|
nombre_curso: string,
|
||||||
|
curso_anio: string,
|
||||||
|
abreviado: string,
|
||||||
|
}
|
||||||
|
// `"1er"`, `"2do"`, etc
|
||||||
|
type NombreAnio = string
|
||||||
|
export type RespuestaListaCursos = {[key: NombreAnio]: Array<InfoCurso>}
|
||||||
|
type ListaCursosFn = () => Promise<RespuestaListaCursos>
|
||||||
|
|
||||||
|
export const getAllListaCursos: ListaCursosFn = async() => {
|
||||||
|
const response = await fetch(`${SERVER_PATH}/cursos`);
|
||||||
|
const data = await response.json() as Array<InfoCurso>;
|
||||||
|
|
||||||
|
const resultMap: RespuestaListaCursos = {};
|
||||||
|
data.forEach((curso) => {
|
||||||
|
if (resultMap[curso.curso_anio] === undefined) {
|
||||||
|
resultMap[curso.curso_anio] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
resultMap[curso.curso_anio]?.push(curso);
|
||||||
|
});
|
||||||
|
|
||||||
|
return resultMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAllListaCursosMock: ListaCursosFn = async() => {
|
||||||
|
const arr5to: Array<InfoCurso> = [
|
||||||
|
{
|
||||||
|
id_curso: 0,
|
||||||
|
nombre_curso: "Gestion de Sistemas y Tecnologias de Informacion",
|
||||||
|
curso_anio: "5to",
|
||||||
|
abreviado: "GSTI",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id_curso: 1,
|
||||||
|
nombre_curso: "Practicas Pre Profesionales",
|
||||||
|
curso_anio: "5to",
|
||||||
|
abreviado: "PPP",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const arr4to: Array<InfoCurso> = [
|
||||||
|
{
|
||||||
|
id_curso: 2,
|
||||||
|
nombre_curso: "Diseño y Arquitectura de Software",
|
||||||
|
curso_anio: "4to",
|
||||||
|
abreviado: "DAS",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id_curso: 3,
|
||||||
|
nombre_curso: "Gestion de Proyectos de Software",
|
||||||
|
curso_anio: "4to",
|
||||||
|
abreviado: "GPS",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
"5to": arr5to,
|
||||||
|
"4to": arr4to,
|
||||||
|
};
|
||||||
|
};
|
@ -5,6 +5,7 @@ import { useRouter } from "./Router";
|
|||||||
import { Switch, Match, Show } from "solid-js";
|
import { Switch, Match, Show } from "solid-js";
|
||||||
import { Wallpaper } from "./Wallpaper";
|
import { Wallpaper } from "./Wallpaper";
|
||||||
import { SistemasMovil } from "./Views/SistemasMovil";
|
import { SistemasMovil } from "./Views/SistemasMovil";
|
||||||
|
import { SeleccionCursos } from "./Views/SeleccionCursos";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const route = useRouter();
|
const route = useRouter();
|
||||||
@ -22,6 +23,9 @@ function App() {
|
|||||||
<Match when={route() === "/editor/"}>
|
<Match when={route() === "/editor/"}>
|
||||||
<Editor />
|
<Editor />
|
||||||
</Match>
|
</Match>
|
||||||
|
<Match when={route() === "/seleccion-cursos/"}>
|
||||||
|
<SeleccionCursos />
|
||||||
|
</Match>
|
||||||
<Match when={route() === "/sistemas-movil/"}>
|
<Match when={route() === "/sistemas-movil/"}>
|
||||||
<SistemasMovil />
|
<SistemasMovil />
|
||||||
</Match>
|
</Match>
|
||||||
|
@ -28,6 +28,7 @@ export const horasDescanso = [
|
|||||||
"15:40 - 15:50",
|
"15:40 - 15:50",
|
||||||
"17:30 - 17:40",
|
"17:30 - 17:40",
|
||||||
];
|
];
|
||||||
|
export const SERVER_PATH = "";
|
||||||
|
|
||||||
const numImgGuardado = Number(localStorage.getItem("num-img") ?? "0");
|
const numImgGuardado = Number(localStorage.getItem("num-img") ?? "0");
|
||||||
const tamanoLetraGuardado = Number(/* localStorage.getItem("tamano-letra") ?? */ "16");
|
const tamanoLetraGuardado = Number(/* localStorage.getItem("tamano-letra") ?? */ "16");
|
||||||
|
@ -3,6 +3,7 @@ import { StyleSheet, css } from "aphrodite/no-important";
|
|||||||
import { RouterLink } from "../Router";
|
import { RouterLink } from "../Router";
|
||||||
import { Show } from "solid-js";
|
import { Show } from "solid-js";
|
||||||
import { isMobile } from "../Store";
|
import { isMobile } from "../Store";
|
||||||
|
import { MobileIndex } from "./MobileIndex";
|
||||||
|
|
||||||
const e = StyleSheet.create({
|
const e = StyleSheet.create({
|
||||||
contenedorGlobal: {
|
contenedorGlobal: {
|
||||||
@ -31,46 +32,7 @@ const e = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function MobileIndex() {
|
|
||||||
const s = StyleSheet.create({
|
|
||||||
boton: {
|
|
||||||
backgroundColor: "var(--color-primario)",
|
|
||||||
color: "white",
|
|
||||||
padding: "1rem 5rem",
|
|
||||||
borderRadius: "25px",
|
|
||||||
margin: "1.5rem 0",
|
|
||||||
boxShadow: "2px 2px 2px 0 gray",
|
|
||||||
cursor: "pointer",
|
|
||||||
},
|
|
||||||
entrada: {
|
|
||||||
borderTop: "none",
|
|
||||||
borderRight: "none",
|
|
||||||
borderLeft: "none",
|
|
||||||
borderBottom: "solid 2px gray",
|
|
||||||
padding: "0.75rem 1rem",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputElement = <input type="email" placeholder="Correo electronico" className={css(s.entrada)} />;
|
|
||||||
|
|
||||||
const login = () => {
|
|
||||||
console.log((inputElement as HTMLInputElement).value);
|
|
||||||
window.location.href = "#/sistemas-movil/";
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={css(e.contenedorGlobal)}>
|
|
||||||
<div style="text-align: center;">
|
|
||||||
<h1>Iniciar sesión</h1>
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{inputElement}
|
|
||||||
<br />
|
|
||||||
<button className={css(s.boton)} onClick={login}>Iniciar Sesion</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Index() {
|
export function Index() {
|
||||||
return (
|
return (
|
||||||
|
113
src/Views/MobileIndex.tsx
Normal file
113
src/Views/MobileIndex.tsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { css, StyleSheet } from "aphrodite/no-important";
|
||||||
|
import { createSignal } from "solid-js";
|
||||||
|
import { SERVER_PATH } from "../Store";
|
||||||
|
|
||||||
|
const e = StyleSheet.create({
|
||||||
|
contenedorGlobal: {
|
||||||
|
width: "100vw",
|
||||||
|
height: "100vh",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
cont: {
|
||||||
|
width: "30rem",
|
||||||
|
},
|
||||||
|
parrafo: {
|
||||||
|
textAlign: "justify",
|
||||||
|
lineHeight: "1.4rem",
|
||||||
|
},
|
||||||
|
botonAccion: {
|
||||||
|
width: "30rem",
|
||||||
|
display: "inline-block",
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
iconoGitHub: {
|
||||||
|
fontSize: "1.25rem",
|
||||||
|
verticalAlign: "bottom",
|
||||||
|
marginRight: "0.5rem",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
type IdLaboratorio = number;
|
||||||
|
type LoginData = {correo_usuario: string};
|
||||||
|
type LoginResponse = Promise<{matriculas: Array<IdLaboratorio>} | null>;
|
||||||
|
type LoginFunction = (data: LoginData) => LoginResponse;
|
||||||
|
|
||||||
|
// Mock for a login without courses
|
||||||
|
const mockLoginEmpty: LoginFunction = async(data) => ({matriculas: []});
|
||||||
|
|
||||||
|
// Mock for a login with courses
|
||||||
|
const mockLoginNotEmpty: LoginFunction = async(_) => ({
|
||||||
|
matriculas: [0, 1, 2, 3],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Error login mock
|
||||||
|
const mockLoginWithError: LoginFunction = async(_) => null;
|
||||||
|
|
||||||
|
// Standard login
|
||||||
|
const loginFn: LoginFunction = async(data) => {
|
||||||
|
const petition = await fetch(`${SERVER_PATH}/login`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
correo_usuario: data.correo_usuario,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (!petition.ok) return null;
|
||||||
|
return await petition.json() as {matriculas: Array<IdLaboratorio>};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function MobileIndex() {
|
||||||
|
const s = StyleSheet.create({
|
||||||
|
boton: {
|
||||||
|
backgroundColor: "var(--color-primario)",
|
||||||
|
color: "white",
|
||||||
|
padding: "1rem 5rem",
|
||||||
|
borderRadius: "25px",
|
||||||
|
margin: "1.5rem 0",
|
||||||
|
boxShadow: "2px 2px 2px 0 gray",
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
entrada: {
|
||||||
|
borderTop: "none",
|
||||||
|
borderRight: "none",
|
||||||
|
borderLeft: "none",
|
||||||
|
borderBottom: "solid 2px gray",
|
||||||
|
padding: "0.75rem 1rem",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const [msgErrorVisible, setMsgErrorVisible] = createSignal(false);
|
||||||
|
|
||||||
|
const inputElement = <input required type="email" placeholder="Correo electronico" className={css(s.entrada)} />;
|
||||||
|
|
||||||
|
const login = async(ev: Event) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
const email = (inputElement as HTMLInputElement).value;
|
||||||
|
const response = await mockLoginEmpty({correo_usuario: email});
|
||||||
|
|
||||||
|
if (response === null) {
|
||||||
|
setMsgErrorVisible(true);
|
||||||
|
setTimeout(() => setMsgErrorVisible(false), 2500);
|
||||||
|
} else if (response.matriculas.length === 0) {
|
||||||
|
window.location.href = "#/seleccion-cursos/";
|
||||||
|
} else if (response.matriculas.length > 0) {
|
||||||
|
alert("TODO");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={css(e.contenedorGlobal)}>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<h1>Iniciar sesión</h1>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<form onSubmit={(ev) => login(ev)}>
|
||||||
|
{inputElement}
|
||||||
|
<br />
|
||||||
|
<button type="submit" className={css(s.boton)}>Iniciar Sesion</button>
|
||||||
|
</form>
|
||||||
|
<span style={{opacity: msgErrorVisible() ? 1 : 0}}>El correo es invalido</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
79
src/Views/SeleccionCursos.tsx
Normal file
79
src/Views/SeleccionCursos.tsx
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { TopBar } from "./SistemasMovil/TopBar";
|
||||||
|
import { StyleSheet, css } from "aphrodite/no-important";
|
||||||
|
import { Card } from "../components/Card";
|
||||||
|
import { createSignal, For } from "solid-js";
|
||||||
|
import { getAllListaCursosMock, RespuestaListaCursos } from "../API/ListaCursos";
|
||||||
|
import { Button } from "../components/Button";
|
||||||
|
|
||||||
|
const s = StyleSheet.create({
|
||||||
|
checkbox: {
|
||||||
|
width: "1.25rem",
|
||||||
|
height: "1.25rem",
|
||||||
|
margin: "0 0.5rem",
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "3rem auto",
|
||||||
|
gridRowGap: "1rem",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function SeleccionCursos() {
|
||||||
|
const [cursos, setCursos] = createSignal<RespuestaListaCursos>({});
|
||||||
|
|
||||||
|
// Recuperar cursos de back
|
||||||
|
(async() => setCursos(await getAllListaCursosMock()))();
|
||||||
|
|
||||||
|
const submit = (ev: Event) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
const form = ev.target as HTMLFormElement;
|
||||||
|
// Los checkboxes
|
||||||
|
const elements = form.elements;
|
||||||
|
const idsAEnviar: Array<number> = [];
|
||||||
|
for (let i = 0; i < elements.length; i += 1) {
|
||||||
|
const inputBox = elements[i] as HTMLInputElement;
|
||||||
|
if (inputBox.checked) {
|
||||||
|
idsAEnviar.push(parseInt(inputBox.value, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(idsAEnviar);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TopBar tituloBarra="Selección de Cursos" />
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<p>Escoge los cursos en los que matricularte</p>
|
||||||
|
</Card>
|
||||||
|
<form onSubmit={(ev) => submit(ev)}>
|
||||||
|
<For each={Object.entries(cursos())}>
|
||||||
|
{([nombreAnio, infoCurso]) => (
|
||||||
|
<Card>
|
||||||
|
<h2>{nombreAnio} año</h2>
|
||||||
|
<div className={css(s.grid)}>
|
||||||
|
<For each={infoCurso}>
|
||||||
|
{(curso) => (
|
||||||
|
<>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
value={curso.id_curso}
|
||||||
|
className={css(s.checkbox)}
|
||||||
|
/>
|
||||||
|
<span>{curso.nombre_curso}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
<div style="text-align: center">
|
||||||
|
<Button texto={"Continuar"} />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { Table } from "./SistemasMovil/Table";
|
|||||||
export function SistemasMovil() {
|
export function SistemasMovil() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<TopBar />
|
<TopBar tituloBarra="Mi Horario" />
|
||||||
<Table />
|
<Table />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {StyleSheet, css} from "aphrodite/no-important";
|
import {StyleSheet, css} from "aphrodite/no-important";
|
||||||
import { createSignal, For, JSX } from "solid-js";
|
import { createSignal, For } from "solid-js";
|
||||||
import { horas } from "../../Store";
|
import { horas } from "../../Store";
|
||||||
|
|
||||||
const s = StyleSheet.create({
|
const s = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
display: "grid",
|
display: "grid",
|
||||||
gridTemplateColumns: "14vw 1fr 1fr",
|
gridTemplateColumns: "13vw 1fr 1fr",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
fontSize: "0.9rem",
|
fontSize: "0.9rem",
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ const s = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export function TopBar() {
|
export function TopBar(props: {tituloBarra: string}) {
|
||||||
return (
|
return (
|
||||||
<nav className={css(s.bar)}>
|
<nav className={css(s.bar)}>
|
||||||
<button>
|
<button>
|
||||||
@ -34,7 +34,7 @@ export function TopBar() {
|
|||||||
title={"Cambiar imagen de fondo"}
|
title={"Cambiar imagen de fondo"}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<p className={css(s.barLabel)}>Mi horario</p>
|
<p className={css(s.barLabel)}>{props.tituloBarra}</p>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
20
src/components/Button.tsx
Normal file
20
src/components/Button.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { StyleSheet, css } from "aphrodite/no-important";
|
||||||
|
|
||||||
|
export function Button(props: {texto: string}) {
|
||||||
|
const s = StyleSheet.create({
|
||||||
|
boton: {
|
||||||
|
backgroundColor: "var(--color-primario)",
|
||||||
|
color: "white",
|
||||||
|
padding: "1rem 5rem",
|
||||||
|
borderRadius: "25px",
|
||||||
|
margin: "1.5rem 0",
|
||||||
|
boxShadow: "2px 2px 2px 0 gray",
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<button type="submit" className={css(s.boton)}>
|
||||||
|
{props.texto}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
19
src/components/Card.tsx
Normal file
19
src/components/Card.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { JSX } from "solid-js";
|
||||||
|
import { StyleSheet, css } from "aphrodite/no-important";
|
||||||
|
|
||||||
|
const s = StyleSheet.create({
|
||||||
|
card: {
|
||||||
|
padding: "0.5rem",
|
||||||
|
border: "solid 2px var(--color-borde)",
|
||||||
|
borderRadius: "10px",
|
||||||
|
margin: "0.5rem",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function Card(props: {children?: JSX.Element}) {
|
||||||
|
return (
|
||||||
|
<div className={css(s.card)}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user