diff --git a/src/Views/SistemasMovil.tsx b/src/Views/SistemasMovil.tsx index 6813f06..3ad1891 100644 --- a/src/Views/SistemasMovil.tsx +++ b/src/Views/SistemasMovil.tsx @@ -1,11 +1,134 @@ 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() { + const [rawData, setRawData] = createSignal([]); + + // Obtener cursos seleccionados del servidor + (async() => { + const cursos: Array = JSON.parse(localStorage.getItem("cursos-seleccionados") ?? "[]"); + const data = await getHorariosMock({ + cursos: cursos.map((x) => parseInt(x, 10)), + }); + setRawData(data); + })(); + return (
- +
); } + +/* +{ + 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]; +} + + diff --git a/src/Views/SistemasMovil/Table.tsx b/src/Views/SistemasMovil/Table.tsx index 582bd54..6f1d9be 100644 --- a/src/Views/SistemasMovil/Table.tsx +++ b/src/Views/SistemasMovil/Table.tsx @@ -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"]; -type Output = { - curso: string, +export type GrupoDia = { + id_horario: number, + id_laboratorio: number, + abreviado: string, grupo: string, - idxHoraInicio: number, + offsetVertical: number, // 07:00 -> 0, 07:50 -> 1 nroHoras: number, - offset: number, // 0, 1, 2 + offsetHorizontal: number, // 0, 1, 2 fraccion: number, // por cuanto dividir la celda. 1, 2, 3, ... } -function Grupo(props: {data: Output}) { +function Grupo(props: {data: GrupoDia}) { const ss = StyleSheet.create({ button: { display: "inline-block", @@ -48,16 +50,24 @@ function Grupo(props: {data: Output}) { 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 ( - ); } -function Dia(props: {dia: string}) { +function Dia(props: {dia: string, grupos: Array}) { const ss = StyleSheet.create({ contenedorDia: { position: "relative", @@ -67,41 +77,33 @@ function Dia(props: {dia: string}) {
{props.dia}
- - - + + {(grupo) => ( + + )} +
); } -export function Table() { +export type TableInput = { + lunes: Array, + martes: Array, + miercoles: Array, + jueves: Array, + viernes: Array, +} + +export function Table(props: {datos: TableInput}) { const [currentDay, setCurrentDay] = createSignal(0); + const lunes = ; + const martes = ; + const miercoles = ; + const jueves = ; + const viernes = ; + return (
@@ -110,8 +112,8 @@ export function Table() { {(hora) =>
{hora.substring(0, 5)}
}
- - + {martes} + {miercoles}
); } diff --git a/src/Views/SistemasMovil/mapaCeldas.ts b/src/Views/SistemasMovil/mapaCeldas.ts new file mode 100644 index 0000000..12153ff --- /dev/null +++ b/src/Views/SistemasMovil/mapaCeldas.ts @@ -0,0 +1,89 @@ +import { GrupoDia } from "./Table"; + +export class MapaCeldas { + // Almacena referencias a input + private mapa: Map> = 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 { + if (!this.mapa.has(nro)) { + const m = new Map(); + 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 { + const mapa = new MapaCeldas(); + const salida: Array = []; + + // 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; +}