Mostrar horarios cargados
This commit is contained in:
parent
93eb18cd6d
commit
93db894306
@ -1,11 +1,134 @@
|
|||||||
import { TopBar } from "./SistemasMovil/TopBar";
|
import { TopBar } from "./SistemasMovil/TopBar";
|
||||||
import { Table } from "./SistemasMovil/Table";
|
import { GrupoDia, Table, TableInput } from "./SistemasMovil/Table";
|
||||||
|
import { getHorariosMock, ListaCursosCompleto } from "../API/CargaHorarios";
|
||||||
|
import { createSignal } from "solid-js";
|
||||||
|
import { generarMapaCeldas } from "./SistemasMovil/mapaCeldas";
|
||||||
|
|
||||||
export function SistemasMovil() {
|
export function SistemasMovil() {
|
||||||
|
const [rawData, setRawData] = createSignal<ListaCursosCompleto>([]);
|
||||||
|
|
||||||
|
// Obtener cursos seleccionados del servidor
|
||||||
|
(async() => {
|
||||||
|
const cursos: Array<string> = JSON.parse(localStorage.getItem("cursos-seleccionados") ?? "[]");
|
||||||
|
const data = await getHorariosMock({
|
||||||
|
cursos: cursos.map((x) => parseInt(x, 10)),
|
||||||
|
});
|
||||||
|
setRawData(data);
|
||||||
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<TopBar tituloBarra="Mi Horario" />
|
<TopBar tituloBarra="Mi Horario" />
|
||||||
<Table />
|
<Table datos={transformar(rawData())} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
id_horario: number,
|
||||||
|
id_laboratorio: number,
|
||||||
|
abreviado: string,
|
||||||
|
grupo: string,
|
||||||
|
offsetVertical: number, // 07:00 -> 0, 07:50 -> 1
|
||||||
|
nroHoras: number,
|
||||||
|
offsetHorizontal: number, // 0, 1, 2
|
||||||
|
fraccion: number, // por cuanto dividir la celda. 1, 2, 3, ...
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function transformar(input: ListaCursosCompleto): TableInput {
|
||||||
|
const data: TableInput = {
|
||||||
|
lunes: [],
|
||||||
|
martes: [],
|
||||||
|
miercoles: [],
|
||||||
|
jueves: [],
|
||||||
|
viernes: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Organizar por dias
|
||||||
|
for (const curso of input) {
|
||||||
|
for (const lab of curso.laboratorios) {
|
||||||
|
for (const horas of lab.horario) {
|
||||||
|
const dia = horas.dia;
|
||||||
|
const [idx, nroHoras] = infoDiaAOffsets(horas.hora_inicio, horas.hora_fin);
|
||||||
|
const datos = {
|
||||||
|
id_horario: horas.id_horario,
|
||||||
|
id_laboratorio: lab.id_laboratorio,
|
||||||
|
abreviado: curso.abreviado,
|
||||||
|
grupo: lab.grupo,
|
||||||
|
offsetVertical: idx,
|
||||||
|
nroHoras: nroHoras,
|
||||||
|
offsetHorizontal: 0,
|
||||||
|
fraccion: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dia === "Lunes") {
|
||||||
|
data.lunes.push(datos);
|
||||||
|
} else if (dia === "Martes") {
|
||||||
|
data.martes.push(datos);
|
||||||
|
} else if (dia === "Miercoles") {
|
||||||
|
data.miercoles.push(datos);
|
||||||
|
} else if (dia === "Jueves") {
|
||||||
|
data.jueves.push(datos);
|
||||||
|
} else if (dia === "Viernes") {
|
||||||
|
data.viernes.push(datos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Procesar cada dia y devolver
|
||||||
|
return {
|
||||||
|
lunes: generarMapaCeldas(data.lunes),
|
||||||
|
martes: generarMapaCeldas(data.martes),
|
||||||
|
miercoles: generarMapaCeldas(data.miercoles),
|
||||||
|
jueves: generarMapaCeldas(data.jueves),
|
||||||
|
viernes: generarMapaCeldas(data.viernes),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const horas = [
|
||||||
|
700,
|
||||||
|
750,
|
||||||
|
850,
|
||||||
|
940,
|
||||||
|
1040,
|
||||||
|
1130,
|
||||||
|
1220,
|
||||||
|
1310,
|
||||||
|
1400,
|
||||||
|
1450,
|
||||||
|
1550,
|
||||||
|
1640,
|
||||||
|
1740,
|
||||||
|
1830,
|
||||||
|
1920,
|
||||||
|
2010,
|
||||||
|
2100,
|
||||||
|
2150,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convierte horas en texto a offsets
|
||||||
|
*/
|
||||||
|
// Ejm: 0700, 0850 -> 0, 2
|
||||||
|
function infoDiaAOffsets(horaInicio: string, horaFinal: string): [number, number] {
|
||||||
|
const inicio = parseInt(horaInicio, 10);
|
||||||
|
const final = parseInt(horaFinal, 10);
|
||||||
|
|
||||||
|
const idxInicio = horas.findIndex((x) => x === inicio);
|
||||||
|
let nroHoras = 0;
|
||||||
|
|
||||||
|
for (let i = idxInicio; i < horas.length; i += 1) {
|
||||||
|
if (final > horas[i]) {
|
||||||
|
nroHoras += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [idxInicio, nroHoras];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,19 +25,21 @@ const s = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
type DayIndex = 0 | 1 | 2 | 3;
|
type DayIndex = 0 | 1 | 2 | 3 | 4;
|
||||||
const days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes"];
|
const days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes"];
|
||||||
|
|
||||||
type Output = {
|
export type GrupoDia = {
|
||||||
curso: string,
|
id_horario: number,
|
||||||
|
id_laboratorio: number,
|
||||||
|
abreviado: string,
|
||||||
grupo: string,
|
grupo: string,
|
||||||
idxHoraInicio: number,
|
offsetVertical: number, // 07:00 -> 0, 07:50 -> 1
|
||||||
nroHoras: number,
|
nroHoras: number,
|
||||||
offset: number, // 0, 1, 2
|
offsetHorizontal: number, // 0, 1, 2
|
||||||
fraccion: number, // por cuanto dividir la celda. 1, 2, 3, ...
|
fraccion: number, // por cuanto dividir la celda. 1, 2, 3, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
function Grupo(props: {data: Output}) {
|
function Grupo(props: {data: GrupoDia}) {
|
||||||
const ss = StyleSheet.create({
|
const ss = StyleSheet.create({
|
||||||
button: {
|
button: {
|
||||||
display: "inline-block",
|
display: "inline-block",
|
||||||
@ -48,16 +50,24 @@ function Grupo(props: {data: Output}) {
|
|||||||
position: "absolute",
|
position: "absolute",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const estilo = () => {
|
||||||
|
const fraccion = props.data.fraccion;
|
||||||
|
const offsetHorizontal = props.data.offsetHorizontal + 1;
|
||||||
|
const offsetVertical = props.data.offsetVertical;
|
||||||
|
const nroHoras = props.data.nroHoras;
|
||||||
|
return `left: calc((43vw / ${fraccion}) * ${offsetHorizontal} - 14vw); top: ${offsetVertical * 3}rem;` +
|
||||||
|
`height: ${nroHoras * 3}rem; width: calc(100% / ${fraccion})`;
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<button className={css(ss.button)} style={`left: calc((43vw / ${props.data.fraccion}) * ${props.data.offset} - 14vw); top: ${props.data.idxHoraInicio * 3}rem; height: ${props.data.nroHoras * 3}rem; width: calc(100% / ${props.data.fraccion})`}>
|
<button className={css(ss.button)} style={estilo()}>
|
||||||
{props.data.curso}
|
{props.data.abreviado}
|
||||||
<br />
|
<br />
|
||||||
{props.data.grupo}
|
{props.data.grupo}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Dia(props: {dia: string}) {
|
function Dia(props: {dia: string, grupos: Array<GrupoDia>}) {
|
||||||
const ss = StyleSheet.create({
|
const ss = StyleSheet.create({
|
||||||
contenedorDia: {
|
contenedorDia: {
|
||||||
position: "relative",
|
position: "relative",
|
||||||
@ -67,41 +77,33 @@ function Dia(props: {dia: string}) {
|
|||||||
<div className={css(s.columna)}>
|
<div className={css(s.columna)}>
|
||||||
<div className={css(s.tableIndex)}>{props.dia}</div>
|
<div className={css(s.tableIndex)}>{props.dia}</div>
|
||||||
<div className={css(ss.contenedorDia)}>
|
<div className={css(ss.contenedorDia)}>
|
||||||
<Grupo data={{
|
<For each={props.grupos}>
|
||||||
curso: "TAIS",
|
{(grupo) => (
|
||||||
grupo: "LA",
|
<Grupo data={grupo} />
|
||||||
idxHoraInicio: 0,
|
)}
|
||||||
nroHoras: 3,
|
</For>
|
||||||
offset: 1,
|
|
||||||
fraccion: 3,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Grupo data={{
|
|
||||||
curso: "PPP",
|
|
||||||
grupo: "LB",
|
|
||||||
idxHoraInicio: 2,
|
|
||||||
nroHoras: 2,
|
|
||||||
offset: 2,
|
|
||||||
fraccion: 3,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Grupo data={{
|
|
||||||
curso: "FC",
|
|
||||||
grupo: "LC",
|
|
||||||
idxHoraInicio: 1,
|
|
||||||
nroHoras: 4,
|
|
||||||
offset: 3,
|
|
||||||
fraccion: 3,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Table() {
|
export type TableInput = {
|
||||||
|
lunes: Array<GrupoDia>,
|
||||||
|
martes: Array<GrupoDia>,
|
||||||
|
miercoles: Array<GrupoDia>,
|
||||||
|
jueves: Array<GrupoDia>,
|
||||||
|
viernes: Array<GrupoDia>,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Table(props: {datos: TableInput}) {
|
||||||
const [currentDay, setCurrentDay] = createSignal<DayIndex>(0);
|
const [currentDay, setCurrentDay] = createSignal<DayIndex>(0);
|
||||||
|
|
||||||
|
const lunes = <Dia dia={"Lunes"} grupos={props.datos.lunes} />;
|
||||||
|
const martes = <Dia dia={"Martes"} grupos={props.datos.martes} />;
|
||||||
|
const miercoles = <Dia dia={"Miercoles"} grupos={props.datos.miercoles} />;
|
||||||
|
const jueves = <Dia dia={"Jueves"} grupos={props.datos.jueves} />;
|
||||||
|
const viernes = <Dia dia={"Viernes"} grupos={props.datos.viernes} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={css(s.container)}>
|
<div className={css(s.container)}>
|
||||||
<div className={css(s.columna)}>
|
<div className={css(s.columna)}>
|
||||||
@ -110,8 +112,8 @@ export function Table() {
|
|||||||
{(hora) => <div className={css(s.celdaHora)}>{hora.substring(0, 5)}</div>}
|
{(hora) => <div className={css(s.celdaHora)}>{hora.substring(0, 5)}</div>}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
<Dia dia={days[currentDay()]} />
|
{martes}
|
||||||
<Dia dia={days[currentDay() + 1]} />
|
{miercoles}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
89
src/Views/SistemasMovil/mapaCeldas.ts
Normal file
89
src/Views/SistemasMovil/mapaCeldas.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { GrupoDia } from "./Table";
|
||||||
|
|
||||||
|
export class MapaCeldas {
|
||||||
|
// Almacena referencias a input
|
||||||
|
private mapa: Map<number, Map<number, null>> = new Map();
|
||||||
|
|
||||||
|
private disponible(nroFila: number, nroColumna: number): boolean {
|
||||||
|
if (!this.mapa.has(nroFila)) return true;
|
||||||
|
|
||||||
|
const fila = this.mapa.get(nroFila)!;
|
||||||
|
|
||||||
|
return fila.has(nroColumna) === false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private obtenerFilaOCrear(nro: number): Map<number, null> {
|
||||||
|
if (!this.mapa.has(nro)) {
|
||||||
|
const m = new Map<number, null>();
|
||||||
|
this.mapa.set(nro, m);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.mapa.get(nro)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Devuelve el offset
|
||||||
|
public solicitar(inicio: number, cantidad: number): number {
|
||||||
|
const filas = [];
|
||||||
|
for (let i = 0; i < cantidad; i += 1) filas.push(inicio + i);
|
||||||
|
|
||||||
|
for (let offsetActual = 0; offsetActual < 8; offsetActual += 1) {
|
||||||
|
let todasCeldasDisponibles = true;
|
||||||
|
for (const fila of filas) {
|
||||||
|
if (!this.disponible(fila, offsetActual)) {
|
||||||
|
todasCeldasDisponibles = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (todasCeldasDisponibles) {
|
||||||
|
// Crear estas celdas y almacenar
|
||||||
|
filas.forEach((nroFila) => {
|
||||||
|
const fila = this.obtenerFilaOCrear(nroFila);
|
||||||
|
fila.set(offsetActual, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Devolver nro de offset
|
||||||
|
return offsetActual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Limite de celdas alcanzado");
|
||||||
|
}
|
||||||
|
|
||||||
|
public generarFraccion(nroFila: number, nroColumna: number, cantidad: number): number {
|
||||||
|
let fraccionActual = 1;
|
||||||
|
for (let i = 0; i < cantidad; i += 1) {
|
||||||
|
const nroFilaActual = nroFila + i;
|
||||||
|
const filaActual = this.mapa.get(nroFilaActual)!;
|
||||||
|
const numeroColumnas = filaActual.size;
|
||||||
|
if (numeroColumnas > fraccionActual) {
|
||||||
|
fraccionActual = numeroColumnas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fraccionActual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generarMapaCeldas(entrada: Readonly<Array<GrupoDia>>): Array<GrupoDia> {
|
||||||
|
const mapa = new MapaCeldas();
|
||||||
|
const salida: Array<GrupoDia> = [];
|
||||||
|
|
||||||
|
// Obtener los offsets de cada curso
|
||||||
|
for (const input of entrada) {
|
||||||
|
const offset = mapa.solicitar(input.offsetVertical, input.nroHoras);
|
||||||
|
salida.push({
|
||||||
|
...input,
|
||||||
|
offsetHorizontal: offset,
|
||||||
|
fraccion: -1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generar las fracciones de cada curso
|
||||||
|
for (const output of salida) {
|
||||||
|
output.fraccion = mapa.generarFraccion(output.offsetVertical, output.offsetHorizontal, output.nroHoras);
|
||||||
|
}
|
||||||
|
|
||||||
|
return salida;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user