Agregar funcionalidad para agregar cursos a Mi Horario

master
Araozu 2021-03-11 08:52:21 -05:00
parent 8d36e54a5b
commit 34a3402388
7 changed files with 116 additions and 51 deletions

View File

@ -2,9 +2,9 @@ import YAML from "yaml";
import { StyleSheet, css } from "aphrodite";
import { MiHorario } from "./MiHorario";
import { Horarios } from "./Horarios";
import { DatosHorario } from "../types/DatosHorario";
import { Curso, CursoUsuario, DatosHorario, DatosVarianteUsuario, ListaCursosUsuario } from "../types/DatosHorario";
import { estilosGlobales } from "../Estilos";
import { Show, createSignal, createEffect, createMemo, batch } from "solid-js";
import { Show, createSignal, createEffect, createMemo, batch, createState } from "solid-js";
const datosPromise = (async () => {
const file = await fetch("/horarios/2020_2_fps_ingenieriadesistemas.yaml");
@ -19,6 +19,37 @@ const ElemCargando = () =>
export type EstadoLayout = "MaxPersonal" | "Normal" | "MaxHorarios";
const [cursosUsuario, setCursosUsuarios] = createState<ListaCursosUsuario>({
cursos: []
});
const agregarCursoUsuario = (curso: Curso) => {
if (cursosUsuario.cursos.find(x => x.nombre === curso.nombre)) {
return;
}
const gruposTeoria: { [k: string]: DatosVarianteUsuario } = {};
for (const [key, data] of Object.entries(curso.Teoria)) {
gruposTeoria[key] = Object.assign({seleccionado: false}, data);
}
const gruposLab: { [k: string]: DatosVarianteUsuario } = {};
for (const [key, data] of Object.entries(curso.Laboratorio ?? {})) {
gruposLab[key] = Object.assign({seleccionado: false}, data);
}
const cursoUsuario: CursoUsuario = {
...curso,
oculto: false,
Teoria: gruposTeoria,
Laboratorio: gruposLab
};
setCursosUsuarios("cursos", a => [...a, cursoUsuario]);
};
export function ContenedorHorarios() {
const [datosCargados, setDatosCargados] = createSignal(false);
const [datos, setDatos] = createSignal<DatosHorario | null>(null);
@ -62,11 +93,14 @@ export function ContenedorHorarios() {
return <div className={css(e().contenedor)}>
<div>
<MiHorario estadoLayout={estadoLayout()} setEstadoLayout={setEstadoLayout}/>
<MiHorario estadoLayout={estadoLayout()} setEstadoLayout={setEstadoLayout} cursosUsuario={cursosUsuario}/>
</div>
<div>
<Show when={datosCargados()}>
<Horarios data={datos()!!} estadoLayout={estadoLayout()} setEstadoLayout={setEstadoLayout}/>
<Horarios data={datos()!!}
estadoLayout={estadoLayout()}
setEstadoLayout={setEstadoLayout}
fnAgregarCurso={agregarCursoUsuario}/>
</Show>
</div>
</div>;

View File

@ -1,4 +1,4 @@
import { AnioData } from "../types/DatosHorario";
import { AnioData, Curso } from "../types/DatosHorario";
import { For } from "solid-js";
import { StyleSheet, css } from "aphrodite";
import { estilosGlobales } from "../Estilos";
@ -10,7 +10,7 @@ const e = StyleSheet.create({
}
});
export function Cursos(props: { dataAnio: AnioData }) {
export function Cursos(props: { dataAnio: AnioData, fnAgregarCurso: (c: Curso) => void }) {
return <>
<For each={Object.entries(props.dataAnio)}>
{([_, datosCurso]) => {
@ -20,6 +20,7 @@ export function Cursos(props: { dataAnio: AnioData }) {
estilosGlobales.contenedorCursor,
estilosGlobales.contenedorCursorSoft
)}
onClick={() => props.fnAgregarCurso(datosCurso)}
>
<i className="ph-plus"/>
{datosCurso.abreviado} - {datosCurso.nombre}

View File

@ -1,5 +1,5 @@
import { DatosHorario } from "../types/DatosHorario";
import { For, createSignal, createMemo } from "solid-js";
import { Curso, DatosHorario } from "../types/DatosHorario";
import { For, createSignal, createMemo} from "solid-js";
import { css } from "aphrodite";
import { estilosGlobales } from "../Estilos";
import { Tabla } from "./Tabla";
@ -11,7 +11,8 @@ import { Switch, Match } from "solid-js";
interface HorariosProps {
data: DatosHorario,
estadoLayout: EstadoLayout,
setEstadoLayout: (v: EstadoLayout) => EstadoLayout
setEstadoLayout: (v: EstadoLayout) => EstadoLayout,
fnAgregarCurso: (c: Curso) => void
}
export function Horarios(props: HorariosProps) {
@ -61,7 +62,7 @@ export function Horarios(props: HorariosProps) {
<Tabla data={dataTabla()} version={props.data.version} anio={anioActual()}/>
</div>
<div>
<Cursos dataAnio={dataTabla()}/>
<Cursos dataAnio={dataTabla()} fnAgregarCurso={props.fnAgregarCurso}/>
</div>
</Match>
<Match when={props.estadoLayout === "MaxPersonal"}>

View File

@ -3,16 +3,29 @@ import { StyleSheet, css } from "aphrodite";
import { Tabla } from "./Tabla";
import { mostrarDescansos } from "../Store";
import { EstadoLayout } from "./ContenedorHorarios";
import { Switch, Match } from "solid-js";
import { Switch, Match, For, createMemo } from "solid-js";
import { BotonMaxMin } from "./BotonMaxMin";
import { AnioData, ListaCursosUsuario } from "../types/DatosHorario";
interface MiHorarioProps {
estadoLayout: EstadoLayout,
setEstadoLayout: (v: EstadoLayout) => EstadoLayout
setEstadoLayout: (v: EstadoLayout) => EstadoLayout,
cursosUsuario: ListaCursosUsuario
}
export function MiHorario(props: MiHorarioProps) {
const e = StyleSheet.create({
function Horario(props: { cursosUsuario: ListaCursosUsuario }) {
return <div>
<For each={props.cursosUsuario.cursos}>
{c => {
return <div>
<p>{c.abreviado} - {c.nombre}</p>
</div>
}}
</For>
</div>
}
const e = StyleSheet.create({
horario: {},
boton: {
textDecoration: "none",
@ -23,6 +36,16 @@ export function MiHorario(props: MiHorarioProps) {
textDecoration: "none"
}
}
});
export function MiHorario(props: MiHorarioProps) {
const datosMiHorario = createMemo(() => {
const obj: AnioData = {};
props.cursosUsuario.cursos.forEach(x => {
obj[x.nombre] = {...x};
});
return obj;
});
const claseBotonMostrarDescansos = () =>
@ -51,28 +74,16 @@ export function MiHorario(props: MiHorarioProps) {
estadoActualLayout={estadoActualLayout}
estadoLayoutMax={"MaxPersonal"}
/>
{/*
<div
className={css(
estilosGlobales.inlineBlock,
estilosGlobales.contenedor,
estilosGlobales.contenedorCursor,
estilosGlobales.contenedorCursorSoft
)}
onClick={() => setMostrarDescansos(!mostrarDescansos())}
>
<i className={claseBotonMostrarDescansos()}/>
&nbsp;Mostrar descansos
</div>
*/}
</div>
<div className={css(
e.horario,
estilosGlobales.contenedor
)}>
<Tabla data={{}} anio={"Mi horario"} version={1}/>
<Tabla data={datosMiHorario()} anio={"Mi horario"} version={1}/>
<Horario cursosUsuario={props.cursosUsuario}/>
</div>
</Match>
<Match when={props.estadoLayout === "MaxHorarios"}>

View File

@ -149,10 +149,11 @@ export function Tabla(props: { data: AnioData, anio: string, version: number })
const [idHover, setIdHover] = createSignal("");
const celdas = createMemo(() => {
console.log("Renderizar tabla", props.anio);
// Hace reaccionar a la reactividad de Solid
props.data;
return <For each={horas}>
{hora => {
return <FilaTabla data={data} hora={hora} idHover={idHover} setIdHover={setIdHover}/>
return <FilaTabla data={data()} hora={hora} idHover={idHover} setIdHover={setIdHover}/>
}}
</For>
});

View File

@ -62,7 +62,7 @@ const [diasResaltados, setDiasResaltados] = createState({
interface Props {
hora: string,
data: () => DataProcesada,
data: DataProcesada,
idHover: () => string,
setIdHover: (v: string) => string
}
@ -130,7 +130,7 @@ export function FilaTabla(props: Props) {
const diaStr = dia.substring(0, 2);
const horaStr = hora.substring(0, 5);
const datos = data()?.[horaStr]?.[diaStr] ?? [];
const datos = data?.[horaStr]?.[diaStr] ?? [];
return <CeldaFila
datos={datos}

View File

@ -1,18 +1,35 @@
export interface DatosVariante {
Docente: string,
Horas: string[]
}
export interface DatosVarianteUsuario extends DatosVariante {
seleccionado: boolean
}
export interface Curso {
nombre: string,
abreviado: string,
Teoria: {
[grupo: string]: {
Docente: string,
Horas: string[]
}
[grupo: string]: DatosVariante
}
Laboratorio?: {
[grupo: string]: {
Docente: string,
Horas: string[]
[grupo: string]: DatosVariante
}
}
export interface CursoUsuario extends Curso {
oculto: boolean,
Teoria: {
[grupo: string]: DatosVarianteUsuario
}
Laboratorio?: {
[grupo: string]: DatosVarianteUsuario
}
}
export interface ListaCursosUsuario {
cursos: CursoUsuario[]
}
export interface AnioData {