Reestructurar codigo de vista de pc
This commit is contained in:
parent
314a57d01a
commit
678f266946
33
src/API/Login.ts
Normal file
33
src/API/Login.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { SERVER_PATH } from "../Store";
|
||||
|
||||
type IdLaboratorio = number;
|
||||
type LoginData = {correo_usuario: string};
|
||||
type LoginResponse = Promise<{matriculas: Array<IdLaboratorio>} | null>;
|
||||
export type LoginFunction = (data: LoginData) => LoginResponse;
|
||||
|
||||
// Mock for a login without courses
|
||||
export const mockLoginEmpty: LoginFunction = async(data) => ({matriculas: []});
|
||||
|
||||
// Mock for a login with courses
|
||||
export const mockLoginNotEmpty: LoginFunction = async(_) => ({
|
||||
matriculas: [0, 1, 2, 3],
|
||||
});
|
||||
|
||||
// Error login mock
|
||||
export const mockLoginWithError: LoginFunction = async(_) => null;
|
||||
|
||||
// Standard login
|
||||
export const loginFn: LoginFunction = async(data) => {
|
||||
const petition = await fetch(`${SERVER_PATH}/login`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
correo_usuario: data.correo_usuario,
|
||||
}),
|
||||
});
|
||||
if (!petition.ok) return null;
|
||||
return await petition.json() as {matriculas: Array<IdLaboratorio>};
|
||||
};
|
||||
|
11
src/App.tsx
11
src/App.tsx
@ -1,4 +1,4 @@
|
||||
import { Main } from "./Views/Main";
|
||||
import { Sistemas } from "./Views/pc/Sistemas";
|
||||
import { Index } from "./Views/Index";
|
||||
import { Editor } from "./Views/Editor";
|
||||
import { useRouter } from "./Router";
|
||||
@ -7,6 +7,7 @@ import { Wallpaper } from "./Wallpaper";
|
||||
import { SistemasMovil } from "./Views/SistemasMovil";
|
||||
import { SeleccionCursos } from "./Views/SeleccionCursos";
|
||||
import { VerMatricula } from "./Views/VerMatricula";
|
||||
import {SeleccionCursos as SeleccionCursosPC} from "./Views/pc/SeleccionCursos";
|
||||
|
||||
function App() {
|
||||
const route = useRouter();
|
||||
@ -33,8 +34,12 @@ function App() {
|
||||
<Match when={route() === "/ver-matricula/"}>
|
||||
<VerMatricula />
|
||||
</Match>
|
||||
<Match when={route() === "/sistemas/"}>
|
||||
<Main />
|
||||
|
||||
<Match when={route() === "/pc/seleccion-cursos/"}>
|
||||
<SeleccionCursosPC />
|
||||
</Match>
|
||||
<Match when={route() === "/pc/sistemas/"}>
|
||||
<Sistemas />
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
|
@ -2,8 +2,8 @@ import { BarraSuperior } from "../BarraSuperior";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { Separador } from "../Separador";
|
||||
import { Tabla } from "../ContenedorHorarios/Tabla";
|
||||
import { TablaObserver } from "../ContenedorHorarios/TablaObserver";
|
||||
import { Tabla } from "./pc/Sistemas/ContenedorHorarios/Tabla";
|
||||
import { TablaObserver } from "./pc/Sistemas/ContenedorHorarios/TablaObserver";
|
||||
import { Curso, Cursos } from "../types/DatosHorario";
|
||||
import { For, createMemo } from "solid-js";
|
||||
import {createStore} from "solid-js/store";
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { StyleSheet, css } from "aphrodite/no-important";
|
||||
import { RouterLink } from "../Router";
|
||||
import { Show } from "solid-js";
|
||||
import { isMobile } from "../Store";
|
||||
import { batch, createSignal, Show } from "solid-js";
|
||||
import { isMobile, setGruposSeleccionados } from "../Store";
|
||||
import { MobileIndex } from "./MobileIndex";
|
||||
import { mockLoginEmpty, mockLoginNotEmpty, mockLoginWithError } from "../API/Login";
|
||||
|
||||
const e = StyleSheet.create({
|
||||
contenedorGlobal: {
|
||||
@ -30,11 +31,45 @@ const e = StyleSheet.create({
|
||||
verticalAlign: "bottom",
|
||||
marginRight: "0.5rem",
|
||||
},
|
||||
inputCorreo: {
|
||||
width: "100%",
|
||||
backgroundColor: "rgba(159,159,159,0.44)",
|
||||
border: "none",
|
||||
borderBottom: "solid 2px var(--color-texto)",
|
||||
padding: "0.5rem 1rem",
|
||||
boxSizing: "border-box",
|
||||
marginTop: "1rem",
|
||||
borderRadius: "5px",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
export function Index() {
|
||||
const [msgErrorVisible, setMsgErrorVisible] = createSignal(false);
|
||||
const inputElement = <input className={css(e.inputCorreo)} type="email" required placeholder="correo@unsa.edu.pe" />;
|
||||
|
||||
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) {
|
||||
localStorage.setItem("correo", email);
|
||||
window.location.href = "#/pc/seleccion-cursos/";
|
||||
} else if (response.matriculas.length > 0) {
|
||||
localStorage.setItem("correo", email);
|
||||
batch(() => {
|
||||
for (const id_lab of response.matriculas) {
|
||||
setGruposSeleccionados(id_lab, true);
|
||||
}
|
||||
});
|
||||
window.location.href = "#/pc/ver-matricula/";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Show when={!isMobile()}>
|
||||
@ -49,36 +84,19 @@ export function Index() {
|
||||
Horarios UNSA
|
||||
</h1>
|
||||
<p className={css(e.parrafo)}>
|
||||
Esta página te permite crear tu horario fácilmente, sin importar de que
|
||||
año son los cursos.
|
||||
</p>
|
||||
<p className={css(e.parrafo)}>
|
||||
Por ahora solo está disponible para ing. de sistemas. Proximamente se habilitarán
|
||||
otras carreras.
|
||||
</p>
|
||||
<p className={css(e.parrafo)}>
|
||||
Se recomienda usar un computador/laptop y un navegador actualizado (Firefox, Chrome,
|
||||
Qutebrowser).
|
||||
Inicia sesión con tu correo institucional.
|
||||
<br />
|
||||
{inputElement}
|
||||
</p>
|
||||
<span style={msgErrorVisible() ? "opacity: 1; color: red;" : "opacity: 0;"}>
|
||||
El correo es invalido
|
||||
</span>
|
||||
</div>
|
||||
<RouterLink
|
||||
to={"/sistemas/"}
|
||||
className={css(estilosGlobales.contenedor, estilosGlobales.contenedorCursor, e.botonAccion)}
|
||||
>
|
||||
Ing. de Sistemas
|
||||
</RouterLink>
|
||||
{/*
|
||||
<button disabled className={css(estilosGlobales.contenedor, estilosGlobales.contenedorCursor, e.botonAccion)}>
|
||||
Otras carreras
|
||||
<button onClick={login} className={css(estilosGlobales.contenedor, estilosGlobales.contenedorCursor, e.botonAccion)}>
|
||||
Iniciar sesion
|
||||
</button>
|
||||
*/}
|
||||
<RouterLink
|
||||
to={"/editor/"}
|
||||
className={css(estilosGlobales.contenedor, estilosGlobales.contenedorCursor, e.botonAccion)}
|
||||
>
|
||||
<i className={`${css(e.iconoGitHub)} ph-pencil`} />
|
||||
Editor
|
||||
</RouterLink>
|
||||
<br />
|
||||
<br />
|
||||
<a
|
||||
className={css(estilosGlobales.contenedor, estilosGlobales.contenedorCursor, e.botonAccion)}
|
||||
href="https://github.com/Araozu/horarios-unsa-2/"
|
||||
|
@ -1,49 +0,0 @@
|
||||
import { BarraSuperior } from "../BarraSuperior";
|
||||
import { ContenedorHorarios } from "../ContenedorHorarios/ContenedorHorarios";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { css } from "aphrodite";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { Creditos } from "../Creditos";
|
||||
import { Separador } from "../Separador";
|
||||
|
||||
export function Main() {
|
||||
/// @ts-ignore
|
||||
const soportaBackdropFilter = document.body.style.backdropFilter !== undefined;
|
||||
const mostrarMensajeBackdropFilterRaw = !localStorage.getItem("mensaje-backdrop-filter-oculto");
|
||||
|
||||
const [mostrarMensajeBackdropFilter, setMostrarMensaje] = createSignal(mostrarMensajeBackdropFilterRaw);
|
||||
|
||||
const ocultarMensajeBackdropFilter = () => {
|
||||
setMostrarMensaje(false);
|
||||
localStorage.setItem("mensaje-backdrop-filter-oculto", "true");
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<BarraSuperior />
|
||||
<Show when={!soportaBackdropFilter && mostrarMensajeBackdropFilter()}>
|
||||
<div className={css(estilosGlobales.contenedor)}>
|
||||
Tu navegador no soporta "backdrop-filter". Este es solo un efecto
|
||||
visual, no afecta la funcionalidad de la página.
|
||||
<span
|
||||
className={css(estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
onClick={ocultarMensajeBackdropFilter}
|
||||
>
|
||||
No volver a mostrar.
|
||||
</span>
|
||||
</div>
|
||||
</Show>
|
||||
{/*
|
||||
<div className={css(estilosGlobales.contenedor)}>
|
||||
Solo teoria por ahora. Actualizado el 2021/03/28. Fuente:
|
||||
<a className={css(estilosGlobales.linkGenerico)} target="_blank" href="https://www.facebook.com/Escuela-Profesional-de-Ingenieria-de-Sistemas-171720913528/photos/pcb.10159175240878529/10159175239403529">
|
||||
Página de Facebook de la escuela.
|
||||
</a>
|
||||
</div>
|
||||
*/}
|
||||
<Separador />
|
||||
<ContenedorHorarios />
|
||||
<Creditos />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { css, StyleSheet } from "aphrodite/no-important";
|
||||
import { batch, createSignal } from "solid-js";
|
||||
import { SERVER_PATH, setGruposSeleccionados } from "../Store";
|
||||
import { mockLoginEmpty } from "../API/Login";
|
||||
|
||||
const e = StyleSheet.create({
|
||||
contenedorGlobal: {
|
||||
@ -29,34 +30,6 @@ const e = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
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: {
|
||||
@ -78,7 +51,7 @@ export function MobileIndex() {
|
||||
});
|
||||
const [msgErrorVisible, setMsgErrorVisible] = createSignal(false);
|
||||
|
||||
const inputElement = <input required type="email" placeholder="Correo electronico" className={css(s.entrada)} />;
|
||||
const inputElement = <input required type="email" placeholder="correo@unsa.edu.pe" className={css(s.entrada)} />;
|
||||
|
||||
const login = async(ev: Event) => {
|
||||
ev.preventDefault();
|
||||
@ -89,13 +62,16 @@ export function MobileIndex() {
|
||||
setMsgErrorVisible(true);
|
||||
setTimeout(() => setMsgErrorVisible(false), 2500);
|
||||
} else if (response.matriculas.length === 0) {
|
||||
localStorage.setItem("correo", email);
|
||||
window.location.href = "#/seleccion-cursos/";
|
||||
} else if (response.matriculas.length > 0) {
|
||||
localStorage.setItem("correo", email);
|
||||
batch(() => {
|
||||
for (const id_lab of response.matriculas) {
|
||||
setGruposSeleccionados(id_lab, true);
|
||||
}
|
||||
});
|
||||
window.location.href = "#/ver-matricula/";
|
||||
}
|
||||
};
|
||||
|
||||
|
135
src/Views/pc/SeleccionCursos.tsx
Normal file
135
src/Views/pc/SeleccionCursos.tsx
Normal file
@ -0,0 +1,135 @@
|
||||
import { css, StyleSheet } from "aphrodite/no-important";
|
||||
import { estilosGlobales } from "../../Estilos";
|
||||
import { createSignal, For } from "solid-js";
|
||||
import { getAllListaCursosMock, RespuestaListaCursos } from "../../API/ListaCursos";
|
||||
|
||||
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",
|
||||
},
|
||||
inputCorreo: {
|
||||
width: "100%",
|
||||
backgroundColor: "rgba(159,159,159,0.44)",
|
||||
border: "none",
|
||||
borderBottom: "solid 2px var(--color-texto)",
|
||||
padding: "0.5rem 1rem",
|
||||
boxSizing: "border-box",
|
||||
marginTop: "1rem",
|
||||
borderRadius: "5px",
|
||||
},
|
||||
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>({});
|
||||
const [msgErr, setMsgError] = createSignal(false);
|
||||
|
||||
// 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<string> = [];
|
||||
for (let i = 0; i < elements.length; i += 1) {
|
||||
const inputBox = elements[i] as HTMLInputElement;
|
||||
if (inputBox.checked) {
|
||||
idsAEnviar.push(inputBox.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (idsAEnviar.length === 0) {
|
||||
setMsgError(true);
|
||||
setTimeout(() => setMsgError(false), 2500);
|
||||
return;
|
||||
}
|
||||
|
||||
// Almacenar en localStorage
|
||||
localStorage.setItem("cursos-seleccionados", JSON.stringify(idsAEnviar));
|
||||
// Ir a sig pantalla
|
||||
window.location.href = "#/pc/sistemas/";
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={css(e.contenedorGlobal)}>
|
||||
<div className={css(e.cont)}>
|
||||
<form onSubmit={submit}>
|
||||
<div className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock, e.cont)}>
|
||||
<h1 style={{
|
||||
"text-align": "center",
|
||||
"font-size": "1.75rem",
|
||||
}}
|
||||
>
|
||||
Seleccion de cursos
|
||||
</h1>
|
||||
<p>Selecciona los cursos en los que matricularte</p>
|
||||
|
||||
<For each={Object.entries(cursos())}>
|
||||
{([nombreAnio, infoCurso]) => (
|
||||
<>
|
||||
<h2>{nombreAnio} año</h2>
|
||||
<div className={css(e.grid)}>
|
||||
<For each={infoCurso}>
|
||||
{(curso) => (
|
||||
<>
|
||||
<input
|
||||
type="checkbox"
|
||||
value={curso.id_curso}
|
||||
className={css(e.checkbox)}
|
||||
/>
|
||||
<span>{curso.nombre_curso}</span>
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
<br />
|
||||
<span style={msgErr() ? "opacity: 1; color: red;" : "opacity: 0;"}>
|
||||
Selecciona al menos un curso
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className={css(estilosGlobales.contenedor, estilosGlobales.contenedorCursor, e.botonAccion)}
|
||||
>
|
||||
Iniciar sesion
|
||||
</button >
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
18
src/Views/pc/Sistemas.tsx
Normal file
18
src/Views/pc/Sistemas.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { BarraSuperior } from "../../BarraSuperior";
|
||||
import { ContenedorHorarios } from "./Sistemas/ContenedorHorarios";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../Estilos";
|
||||
import { Creditos } from "../../Creditos";
|
||||
import { Separador } from "../../Separador";
|
||||
|
||||
export function Sistemas() {
|
||||
return (
|
||||
<div>
|
||||
<BarraSuperior />
|
||||
<Separador />
|
||||
<ContenedorHorarios />
|
||||
<Creditos />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,42 +1,43 @@
|
||||
import YAML from "yaml"
|
||||
import { css, StyleSheet } from "aphrodite"
|
||||
import { MiHorario } from "./MiHorario"
|
||||
import { Horarios } from "./Horarios"
|
||||
import YAML from "yaml";
|
||||
import { css, StyleSheet } from "aphrodite";
|
||||
import { MiHorario } from "./ContenedorHorarios/MiHorario";
|
||||
import { Horarios } from "./ContenedorHorarios/Horarios";
|
||||
import {
|
||||
Anios,
|
||||
Cursos,
|
||||
DatosHorario,
|
||||
DatosHorarioRaw,
|
||||
DatosGrupo,
|
||||
} from "../types/DatosHorario"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { batch, createEffect, createMemo, createSignal, Show } from "solid-js"
|
||||
import { useListaCursos } from "./useListaCursos"
|
||||
} from "../../../types/DatosHorario";
|
||||
import { estilosGlobales } from "../../../Estilos";
|
||||
import { batch, createEffect, createMemo, createSignal, Show } from "solid-js";
|
||||
import { useListaCursos } from "./ContenedorHorarios/useListaCursos";
|
||||
|
||||
const datosPromise = (async() => {
|
||||
const file = await fetch("/horarios/2022_2_fps_ingenieriadesistemas.yaml")
|
||||
const text = await file.text()
|
||||
const datosRaw = YAML.parse(text) as DatosHorarioRaw
|
||||
const file = await fetch("/horarios/2022_2_fps_ingenieriadesistemas.yaml");
|
||||
const text = await file.text();
|
||||
const datosRaw = YAML.parse(text) as DatosHorarioRaw;
|
||||
console.log(datosRaw);
|
||||
|
||||
// Agregar los campos faltantes a DatosHorarioRaw para que sea DatosHorario
|
||||
const datos: DatosHorario = {
|
||||
...datosRaw,
|
||||
años: {},
|
||||
}
|
||||
};
|
||||
|
||||
const anios: Anios = {}
|
||||
const anios: Anios = {};
|
||||
for (const [nombreAnio, anio] of Object.entries(datosRaw.años)) {
|
||||
const anioData: Cursos = {}
|
||||
const anioData: Cursos = {};
|
||||
for (const [nombreCurso, curso] of Object.entries(anio)) {
|
||||
|
||||
const gruposTeoria: { [k: string]: DatosGrupo } = {}
|
||||
const gruposTeoria: { [k: string]: DatosGrupo } = {};
|
||||
for (const [key, data] of Object.entries(curso.Teoria)) {
|
||||
gruposTeoria[key] = Object.assign({seleccionado: false}, data)
|
||||
gruposTeoria[key] = Object.assign({seleccionado: false}, data);
|
||||
}
|
||||
|
||||
const gruposLab: { [k: string]: DatosGrupo } = {}
|
||||
const gruposLab: { [k: string]: DatosGrupo } = {};
|
||||
for (const [key, data] of Object.entries(curso.Laboratorio ?? {})) {
|
||||
gruposLab[key] = Object.assign({seleccionado: false}, data)
|
||||
gruposLab[key] = Object.assign({seleccionado: false}, data);
|
||||
}
|
||||
|
||||
anioData[nombreCurso] = {
|
||||
@ -44,21 +45,21 @@ const datosPromise = (async() => {
|
||||
oculto: false,
|
||||
Teoria: gruposTeoria,
|
||||
Laboratorio: gruposLab,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
anios[nombreAnio] = anioData
|
||||
anios[nombreAnio] = anioData;
|
||||
}
|
||||
|
||||
datos.años = anios
|
||||
return datos
|
||||
})()
|
||||
datos.años = anios;
|
||||
return datos;
|
||||
})();
|
||||
|
||||
const ElemCargando = () => (
|
||||
<div className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>
|
||||
Recuperando horarios...
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
export type EstadoLayout = "MaxPersonal" | "Normal" | "MaxHorarios";
|
||||
|
||||
@ -66,48 +67,48 @@ const {
|
||||
listaCursos: cursosUsuario,
|
||||
setListaCursos: setCursosUsuarios,
|
||||
agregarCursoALista: agregarCursoUsuario,
|
||||
} = useListaCursos()
|
||||
} = useListaCursos();
|
||||
|
||||
export function ContenedorHorarios() {
|
||||
const [datosCargados, setDatosCargados] = createSignal(false)
|
||||
const [datos, setDatos] = createSignal<DatosHorario | null>(null)
|
||||
const [datosCargados, setDatosCargados] = createSignal(false);
|
||||
const [datos, setDatos] = createSignal<DatosHorario | null>(null);
|
||||
const [estadoLayout, setEstadoLayout] = (
|
||||
createSignal<EstadoLayout>(localStorage.getItem("estadoLayout") as EstadoLayout || "Normal")
|
||||
)
|
||||
);
|
||||
|
||||
const e = createMemo(() => {
|
||||
let templateColumns = ""
|
||||
let templateColumns = "";
|
||||
switch (estadoLayout()) {
|
||||
case "MaxHorarios": {
|
||||
templateColumns = "0 auto"
|
||||
break
|
||||
templateColumns = "0 auto";
|
||||
break;
|
||||
}
|
||||
case "MaxPersonal": {
|
||||
templateColumns = "auto 0m"
|
||||
break
|
||||
templateColumns = "auto 0m";
|
||||
break;
|
||||
}
|
||||
case "Normal": {
|
||||
templateColumns = "50% 50%"
|
||||
templateColumns = "50% 50%";
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem("estadoLayout", estadoLayout())
|
||||
localStorage.setItem("estadoLayout", estadoLayout());
|
||||
|
||||
return StyleSheet.create({
|
||||
contenedor: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: templateColumns,
|
||||
},
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
createEffect(async() => {
|
||||
const datos = await datosPromise
|
||||
const datos = await datosPromise;
|
||||
batch(() => {
|
||||
setDatos(datos)
|
||||
setDatosCargados(true)
|
||||
})
|
||||
})
|
||||
setDatos(datos);
|
||||
setDatosCargados(true);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={css(e().contenedor)}>
|
||||
@ -133,5 +134,5 @@ export function ContenedorHorarios() {
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { css } from "aphrodite"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { css } from "aphrodite";
|
||||
import {estilosGlobales} from "../../../../Estilos";
|
||||
|
||||
interface BotonMaxMinProps {
|
||||
icono: string,
|
||||
@ -21,5 +21,5 @@ export function BotonIcono(props: BotonMaxMinProps) {
|
||||
>
|
||||
<i className={`${css(estilosGlobales.botonPhospor)} ${props.icono}`} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { css } from "aphrodite"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { EstadoLayout } from "./ContenedorHorarios"
|
||||
import { css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../../../Estilos";
|
||||
import {EstadoLayout} from "../ContenedorHorarios";
|
||||
|
||||
interface BotonMaxMinProps {
|
||||
fnMaximizar: () => void,
|
||||
@ -10,19 +10,19 @@ interface BotonMaxMinProps {
|
||||
}
|
||||
|
||||
export function BotonMaxMin(props: BotonMaxMinProps) {
|
||||
const horariosMax = () => props.estadoActualLayout() === props.estadoLayoutMax
|
||||
const horariosMax = () => props.estadoActualLayout() === props.estadoLayoutMax;
|
||||
|
||||
const tituloBoton = () => (horariosMax() ? "Minimizar" : "Maximizar")
|
||||
const iconoBoton = () => (horariosMax() ? "ph-arrows-in" : "ph-arrows-out")
|
||||
const tituloBoton = () => (horariosMax() ? "Minimizar" : "Maximizar");
|
||||
const iconoBoton = () => (horariosMax() ? "ph-arrows-in" : "ph-arrows-out");
|
||||
|
||||
const funcionBoton = () => {
|
||||
const estaMaximizado = horariosMax()
|
||||
const estaMaximizado = horariosMax();
|
||||
if (estaMaximizado) {
|
||||
props.fnMinimizar()
|
||||
props.fnMinimizar();
|
||||
} else {
|
||||
props.fnMaximizar()
|
||||
}
|
||||
props.fnMaximizar();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
@ -38,5 +38,5 @@ export function BotonMaxMin(props: BotonMaxMinProps) {
|
||||
>
|
||||
<i className={`${css(estilosGlobales.botonPhospor)} ${iconoBoton()}`} />
|
||||
</button>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { Cursos, DatosGrupo, ListaCursosUsuario, Curso } from "../types/DatosHorario"
|
||||
import { createMemo, For } from "solid-js"
|
||||
import { produce, SetStoreFunction } from "solid-js/store"
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { TablaObserver } from "./TablaObserver"
|
||||
import { Cursos, DatosGrupo, ListaCursosUsuario, Curso } from "../../../../types/DatosHorario";
|
||||
import { createMemo, For } from "solid-js";
|
||||
import { produce, SetStoreFunction } from "solid-js/store";
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../../../Estilos";
|
||||
import { TablaObserver } from "./TablaObserver";
|
||||
|
||||
const e = StyleSheet.create({
|
||||
inline: {
|
||||
@ -33,14 +33,14 @@ const e = StyleSheet.create({
|
||||
border: "none",
|
||||
color: "var(--color)",
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
const claseCursoNoAgregado = css(
|
||||
e.contenedorCurso,
|
||||
estilosGlobales.contenedor,
|
||||
)
|
||||
);
|
||||
|
||||
const claseCursoOculto = css(e.cursoOculto)
|
||||
const claseCursoOculto = css(e.cursoOculto);
|
||||
|
||||
interface Props {
|
||||
version: number,
|
||||
@ -64,7 +64,7 @@ interface PropsIndicadorGrupo {
|
||||
}
|
||||
|
||||
function IndicadorGrupo(props: PropsIndicadorGrupo) {
|
||||
const id = `${props.idParcial}_${props.esLab ? "L" : "T"}_${props.nombre}`
|
||||
const id = `${props.idParcial}_${props.esLab ? "L" : "T"}_${props.nombre}`;
|
||||
return (
|
||||
<span
|
||||
className={css(e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
@ -75,7 +75,7 @@ function IndicadorGrupo(props: PropsIndicadorGrupo) {
|
||||
>
|
||||
{props.esLab ? "L" : ""}{props.nombre}
|
||||
</span>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const agruparProfesores = (
|
||||
@ -84,31 +84,31 @@ const agruparProfesores = (
|
||||
esLab: boolean,
|
||||
setCursosUsuarios: FnSetCursosUsuarios,
|
||||
) => {
|
||||
const profesores: { [k: string]: [string, () => void][] } = {}
|
||||
const profesores: { [k: string]: [string, () => void][] } = {};
|
||||
for (const [grupo, datosGrupo] of Object.entries(datos)) {
|
||||
const nombreProfesor = datosGrupo.Docente
|
||||
const nombreProfesor = datosGrupo.Docente;
|
||||
if (!profesores[nombreProfesor]) {
|
||||
profesores[nombreProfesor] = []
|
||||
profesores[nombreProfesor] = [];
|
||||
}
|
||||
profesores[nombreProfesor].push([
|
||||
grupo,
|
||||
() => {
|
||||
setCursosUsuarios("cursos", Number(indiceCurso), "Teoria", produce<{ [p: string]: DatosGrupo }>((x) => {
|
||||
const grupoActualSeleccionado = x[grupo].seleccionado
|
||||
const grupoActualSeleccionado = x[grupo].seleccionado;
|
||||
|
||||
if (grupoActualSeleccionado) {
|
||||
x[grupo].seleccionado = false
|
||||
x[grupo].seleccionado = false;
|
||||
} else {
|
||||
for (const xKey in x) {
|
||||
x[xKey].seleccionado = xKey === grupo
|
||||
x[xKey].seleccionado = xKey === grupo;
|
||||
}
|
||||
}
|
||||
}))
|
||||
}));
|
||||
},
|
||||
])
|
||||
}
|
||||
return profesores
|
||||
]);
|
||||
}
|
||||
return profesores;
|
||||
};
|
||||
|
||||
function CursoE(
|
||||
indiceCurso: string,
|
||||
@ -117,7 +117,7 @@ function CursoE(
|
||||
claseCursoAgregado: string,
|
||||
props: Props,
|
||||
) {
|
||||
const idCurso = `${props.version}_${anio()}_${datosCurso.abreviado}`
|
||||
const idCurso = `${props.version}_${anio()}_${datosCurso.abreviado}`;
|
||||
|
||||
const cursoAgregadoMemo = createMemo(
|
||||
() => props.listaCursosUsuario.cursos.find((x) => x.nombre === datosCurso.nombre && !x.oculto) !== undefined,
|
||||
@ -126,33 +126,33 @@ function CursoE(
|
||||
equals:
|
||||
(x, y) => x === y,
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
const tituloMemo = createMemo(() => (cursoAgregadoMemo()
|
||||
? "Remover de mi horario"
|
||||
: "Agregar a mi horario"))
|
||||
: "Agregar a mi horario"));
|
||||
|
||||
const claseMemo = createMemo(() => {
|
||||
if (props.esCursoMiHorario && datosCurso.oculto) {
|
||||
return claseCursoOculto
|
||||
return claseCursoOculto;
|
||||
}
|
||||
return cursoAgregadoMemo()
|
||||
? claseCursoAgregado
|
||||
: claseCursoNoAgregado
|
||||
})
|
||||
: claseCursoNoAgregado;
|
||||
});
|
||||
|
||||
const profesoresTeoria = createMemo(() => agruparProfesores(
|
||||
datosCurso.Teoria,
|
||||
Number(indiceCurso),
|
||||
false,
|
||||
props.setCursosUsuarios,
|
||||
))
|
||||
));
|
||||
const profesoresLab = createMemo(() => agruparProfesores(
|
||||
datosCurso.Laboratorio ?? {},
|
||||
Number(indiceCurso),
|
||||
true,
|
||||
props.setCursosUsuarios,
|
||||
))
|
||||
));
|
||||
|
||||
const IndicadorGrupos = (profesor: string, grupos: [string, () => void][], esLab: boolean) => (
|
||||
<td style={{"padding-bottom": "0.5rem", "padding-right": "0.75rem"}}>
|
||||
@ -172,7 +172,7 @@ function CursoE(
|
||||
}
|
||||
</For>
|
||||
</td>
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={claseMemo()}>
|
||||
@ -204,17 +204,17 @@ function CursoE(
|
||||
{tituloMemo}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function CursosElem(props: Props) {
|
||||
const anio = () => props.anioActual().substring(0, props.anioActual().indexOf(" "))
|
||||
const anio = () => props.anioActual().substring(0, props.anioActual().indexOf(" "));
|
||||
|
||||
const claseCursoAgregado = css(
|
||||
e.contenedorCurso,
|
||||
estilosGlobales.contenedor,
|
||||
!props.esCursoMiHorario && estilosGlobales.contenedorCursorActivo,
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -222,5 +222,5 @@ export function CursosElem(props: Props) {
|
||||
{([indiceCurso, datosCurso]) => CursoE(indiceCurso, datosCurso, anio, claseCursoAgregado, props)}
|
||||
</For>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { Curso, Cursos, DatosHorario, ListaCursosUsuario } from "../types/DatosHorario"
|
||||
import { batch, createMemo, createSignal, For, Match, Switch, untrack } from "solid-js"
|
||||
import {SetStoreFunction} from "solid-js/store"
|
||||
import { css } from "aphrodite"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { Tabla } from "./Tabla"
|
||||
import { CursosElem } from "./CursosElem"
|
||||
import { EstadoLayout } from "./ContenedorHorarios"
|
||||
import { BotonMaxMin } from "./BotonMaxMin"
|
||||
import { useListaCursos } from "./useListaCursos"
|
||||
import { TablaObserver } from "./TablaObserver"
|
||||
import { Curso, Cursos, DatosHorario, ListaCursosUsuario } from "../../../../types/DatosHorario";
|
||||
import { batch, createMemo, createSignal, For, Match, Switch, untrack } from "solid-js";
|
||||
import {SetStoreFunction} from "solid-js/store";
|
||||
import { css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../../../Estilos";
|
||||
import { Tabla } from "./Tabla";
|
||||
import { CursosElem } from "./CursosElem";
|
||||
import { EstadoLayout } from "../ContenedorHorarios";
|
||||
import { BotonMaxMin } from "./BotonMaxMin";
|
||||
import { useListaCursos } from "./useListaCursos";
|
||||
import { TablaObserver } from "./TablaObserver";
|
||||
|
||||
interface HorariosProps {
|
||||
data: DatosHorario,
|
||||
@ -23,59 +23,59 @@ const {
|
||||
setListaCursos,
|
||||
agregarCursoALista,
|
||||
eliminarCursosDeLista,
|
||||
} = useListaCursos()
|
||||
} = useListaCursos();
|
||||
|
||||
export function Horarios(props: HorariosProps) {
|
||||
const [anioActual, setAnioActual] = createSignal("1er año")
|
||||
const [anioActual, setAnioActual] = createSignal("1er año");
|
||||
|
||||
const tablaObserver = new TablaObserver()
|
||||
const tablaObserver = new TablaObserver();
|
||||
|
||||
const elAnios = (
|
||||
<For each={Object.entries(props.data.años)}>
|
||||
{([nombre]) => {
|
||||
const clases = createMemo(() => {
|
||||
const vAnio = anioActual()
|
||||
const vAnio = anioActual();
|
||||
return css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
nombre === vAnio && estilosGlobales.contenedorCursorActivo,
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<button className={clases()} title={`Cambiar a ${nombre}`} onClick={() => setAnioActual(nombre)}>
|
||||
{nombre}
|
||||
</button>
|
||||
)
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
)
|
||||
);
|
||||
|
||||
const dataTabla = createMemo(() => {
|
||||
const anio = anioActual()
|
||||
const obj: Cursos = {}
|
||||
const anio = anioActual();
|
||||
const obj: Cursos = {};
|
||||
untrack(() => {
|
||||
const cursos = props.data.años[anio]
|
||||
const cursos = props.data.años[anio];
|
||||
batch(() => {
|
||||
eliminarCursosDeLista()
|
||||
eliminarCursosDeLista();
|
||||
|
||||
let i = 0
|
||||
let i = 0;
|
||||
for (const [, curso] of Object.entries(cursos)) {
|
||||
// El curso devuelto por esta fun. es reactivo
|
||||
obj[i] = agregarCursoALista(curso)
|
||||
i += 1
|
||||
obj[i] = agregarCursoALista(curso);
|
||||
i += 1;
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
return obj
|
||||
})
|
||||
return obj;
|
||||
});
|
||||
|
||||
const fnMaximizar = () => props.setEstadoLayout("MaxHorarios")
|
||||
const fnMinimizar = () => props.setEstadoLayout("Normal")
|
||||
const estadoActualLayout = () => props.estadoLayout
|
||||
const fnMaximizar = () => props.setEstadoLayout("MaxHorarios");
|
||||
const fnMinimizar = () => props.setEstadoLayout("Normal");
|
||||
const estadoActualLayout = () => props.estadoLayout;
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -135,5 +135,5 @@ export function Horarios(props: HorariosProps) {
|
||||
</Switch>
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { Tabla } from "./Tabla"
|
||||
import { EstadoLayout } from "./ContenedorHorarios"
|
||||
import { Switch, Match, createMemo } from "solid-js"
|
||||
import {SetStoreFunction} from "solid-js/store"
|
||||
import { BotonMaxMin } from "./BotonMaxMin"
|
||||
import { BotonIcono } from "./BotonIcono"
|
||||
import { Curso, Cursos, ListaCursosUsuario } from "../types/DatosHorario"
|
||||
import { CursosElem } from "./CursosElem"
|
||||
import { TablaObserver } from "./TablaObserver"
|
||||
import { estilosGlobales } from "../../../../Estilos";
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import {Tabla} from "./Tabla";
|
||||
import { EstadoLayout } from "../ContenedorHorarios";
|
||||
import { Switch, Match, createMemo } from "solid-js";
|
||||
import {SetStoreFunction} from "solid-js/store";
|
||||
import { BotonMaxMin } from "./BotonMaxMin";
|
||||
import { BotonIcono } from "./BotonIcono";
|
||||
import { Curso, Cursos, ListaCursosUsuario } from "../../../../types/DatosHorario";
|
||||
import { CursosElem } from "./CursosElem";
|
||||
import { TablaObserver } from "./TablaObserver";
|
||||
|
||||
interface MiHorarioProps {
|
||||
estadoLayout: EstadoLayout,
|
||||
@ -29,22 +29,22 @@ const e = StyleSheet.create({
|
||||
textDecoration: "none",
|
||||
},
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
export function MiHorario(props: MiHorarioProps) {
|
||||
const tablaObserver = new TablaObserver()
|
||||
const tablaObserver = new TablaObserver();
|
||||
|
||||
const datosMiHorario = createMemo(() => {
|
||||
const obj: Cursos = {}
|
||||
const obj: Cursos = {};
|
||||
props.cursosUsuario.cursos.forEach((x, i) => {
|
||||
obj[i] = x
|
||||
})
|
||||
return obj
|
||||
})
|
||||
obj[i] = x;
|
||||
});
|
||||
return obj;
|
||||
});
|
||||
|
||||
const fnMaximizar = () => props.setEstadoLayout("MaxPersonal")
|
||||
const fnMinimizar = () => props.setEstadoLayout("Normal")
|
||||
const estadoActualLayout = () => props.estadoLayout
|
||||
const fnMaximizar = () => props.setEstadoLayout("MaxPersonal");
|
||||
const fnMinimizar = () => props.setEstadoLayout("Normal");
|
||||
const estadoActualLayout = () => props.estadoLayout;
|
||||
|
||||
/* TODO: En barra superior colocar todos los horarios. En barra inferior el horario
|
||||
actual.
|
||||
@ -142,5 +142,5 @@ export function MiHorario(props: MiHorarioProps) {
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { batch, createMemo, For } from "solid-js";
|
||||
import { produce, SetStoreFunction } from "solid-js/store";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { Cursos, ListaCursosUsuario, DataProcesada, DatosGrupo } from "../types/DatosHorario";
|
||||
import { Dia, dias, horas } from "../Store";
|
||||
import {estilosGlobales} from "../../../../Estilos";
|
||||
import { Cursos, ListaCursosUsuario, DataProcesada, DatosGrupo } from "../../../../types/DatosHorario";
|
||||
import { Dia, dias, horas } from "../../../../Store";
|
||||
import { FilaTabla } from "./Tabla/FilaTabla";
|
||||
import { TablaObserver } from "./TablaObserver";
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../Estilos";
|
||||
import { estilosGlobales } from "../../../../../Estilos";
|
||||
import { For, createSignal, createMemo, createEffect, onCleanup } from "solid-js";
|
||||
import { Dia } from "../../Store";
|
||||
import { DatosGrupo } from "../../types/DatosHorario";
|
||||
import { Dia } from "../../../../../Store";
|
||||
import { DatosGrupo } from "../../../../../types/DatosHorario";
|
||||
import {TablaObserver} from "../TablaObserver";
|
||||
|
||||
const e = StyleSheet.create({
|
||||
@ -179,7 +179,9 @@ function RenderFila(datos: DatosProps, props: Props) {
|
||||
return `${css(...clases)} ${adicional}`;
|
||||
},
|
||||
undefined,
|
||||
(x, y) => x === y,
|
||||
{
|
||||
equals: (x, y) => x === y,
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
@ -1,10 +1,10 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../Estilos";
|
||||
import { estilosGlobales } from "../../../../../Estilos";
|
||||
import { For, createMemo } from "solid-js";
|
||||
import {createStore, Store} from "solid-js/store";
|
||||
import { Dia, dias } from "../../Store";
|
||||
import { Dia, dias } from "../../../../../Store";
|
||||
import { CeldaFila } from "./CeldaFila";
|
||||
import { DataProcesada } from "../../types/DatosHorario";
|
||||
import { DataProcesada } from "../../../../../types/DatosHorario";
|
||||
import { coloresBorde, diaANum } from "../Tabla";
|
||||
import { TablaObserver } from "../TablaObserver";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createMemo, createEffect, untrack } from "solid-js"
|
||||
import {createStore, SetStoreFunction, Store, produce} from "solid-js/store"
|
||||
import { DatosGrupo } from "../types/DatosHorario"
|
||||
import { createMemo, createEffect, untrack } from "solid-js";
|
||||
import {createStore, SetStoreFunction, Store, produce} from "solid-js/store";
|
||||
import { DatosGrupo } from "../../../../types/DatosHorario";
|
||||
|
||||
const createMemoDefault = <T>(f: () => T) => createMemo<T>(
|
||||
f,
|
||||
@ -8,7 +8,7 @@ const createMemoDefault = <T>(f: () => T) => createMemo<T>(
|
||||
{
|
||||
equals: (x, y) => x === y,
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* - Normal
|
||||
@ -62,13 +62,13 @@ export class TablaObserver {
|
||||
curso: undefined,
|
||||
esLab: undefined,
|
||||
grupo: undefined,
|
||||
})
|
||||
this.resaltado = resaltado
|
||||
this.setResaltado = setResaltado
|
||||
});
|
||||
this.resaltado = resaltado;
|
||||
this.setResaltado = setResaltado;
|
||||
|
||||
const [seleccionado, setSeleccionado] = createStore<ISeleccionado>({})
|
||||
this.seleccionado = seleccionado
|
||||
this.setSeleccionado = setSeleccionado
|
||||
const [seleccionado, setSeleccionado] = createStore<ISeleccionado>({});
|
||||
this.seleccionado = seleccionado;
|
||||
this.setSeleccionado = setSeleccionado;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,83 +86,83 @@ export class TablaObserver {
|
||||
grupo: string,
|
||||
datosGrupo: DatosGrupo,
|
||||
): () => EstadoCelda {
|
||||
const resaltado = this.resaltado
|
||||
const resaltado = this.resaltado;
|
||||
const resaltadoMemo = createMemoDefault(() => {
|
||||
if (resaltado.anio === anio && resaltado.curso === curso) {
|
||||
if (resaltado.esLab === undefined) {
|
||||
return true
|
||||
return true;
|
||||
} else if (resaltado.esLab !== esLab) {
|
||||
return false
|
||||
return false;
|
||||
} else {
|
||||
if (resaltado.grupo === undefined) {
|
||||
return true
|
||||
} else return resaltado.grupo === grupo
|
||||
return true;
|
||||
} else return resaltado.grupo === grupo;
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Registrar curso en `seleccionado`
|
||||
this.setSeleccionado((obj: Store<ISeleccionado>) => {
|
||||
const nuevoObj = {...obj}
|
||||
const nuevoObj = {...obj};
|
||||
|
||||
if (!nuevoObj[anio]) {
|
||||
nuevoObj[anio] = {}
|
||||
nuevoObj[anio] = {};
|
||||
}
|
||||
|
||||
if (!nuevoObj[anio][curso]) {
|
||||
nuevoObj[anio][curso] = {
|
||||
Laboratorio: [],
|
||||
Teoria: [],
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return nuevoObj
|
||||
})
|
||||
return nuevoObj;
|
||||
});
|
||||
|
||||
// Crear un effect para que cada vez que la celda se seleccione se actualize `seleccionado`
|
||||
createEffect(() => {
|
||||
const seleccionado = datosGrupo.seleccionado
|
||||
const seleccionado = datosGrupo.seleccionado;
|
||||
if (seleccionado) {
|
||||
this.setSeleccionado(anio, curso, esLab ? "Laboratorio" : "Teoria", (x) => [...x, grupo])
|
||||
this.setSeleccionado(anio, curso, esLab ? "Laboratorio" : "Teoria", (x) => [...x, grupo]);
|
||||
} else {
|
||||
this.setSeleccionado(anio, curso, esLab ? "Laboratorio" : "Teoria", (x) => x.filter((x) => x !== grupo))
|
||||
this.setSeleccionado(anio, curso, esLab ? "Laboratorio" : "Teoria", (x) => x.filter((x) => x !== grupo));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const seleccionadoMemo = createMemoDefault<EstadoSeleccionado>(() => {
|
||||
const gruposSeleccionados = this.seleccionado[anio][curso][esLab ? "Laboratorio" : "Teoria"]
|
||||
const gruposSeleccionados = this.seleccionado[anio][curso][esLab ? "Laboratorio" : "Teoria"];
|
||||
|
||||
if (gruposSeleccionados.length > 0) {
|
||||
return gruposSeleccionados.find((x) => x === grupo) ? "Seleccionado" : "Oculto"
|
||||
return gruposSeleccionados.find((x) => x === grupo) ? "Seleccionado" : "Oculto";
|
||||
} else {
|
||||
return "Normal"
|
||||
return "Normal";
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return createMemoDefault((): EstadoCelda => {
|
||||
const resaltado = resaltadoMemo()
|
||||
const seleccionado = seleccionadoMemo()
|
||||
const resaltado = resaltadoMemo();
|
||||
const seleccionado = seleccionadoMemo();
|
||||
|
||||
switch (seleccionado) {
|
||||
case "Normal": {
|
||||
return resaltado ? "Resaltado" : "Normal"
|
||||
return resaltado ? "Resaltado" : "Normal";
|
||||
}
|
||||
case "Oculto": {
|
||||
return resaltado ? "ResaltadoOculto" : "Oculto"
|
||||
return resaltado ? "ResaltadoOculto" : "Oculto";
|
||||
}
|
||||
case "Seleccionado": {
|
||||
return resaltado ? "ResaltadoSeleccionado" : "Seleccionado"
|
||||
return resaltado ? "ResaltadoSeleccionado" : "Seleccionado";
|
||||
}
|
||||
default: {
|
||||
let _: never
|
||||
let _: never;
|
||||
// eslint-disable-next-line prefer-const
|
||||
_ = seleccionado
|
||||
return _
|
||||
_ = seleccionado;
|
||||
return _;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,13 +172,13 @@ export class TablaObserver {
|
||||
*/
|
||||
registrarConId(id: string, datosGrupo: DatosGrupo): () => EstadoCelda {
|
||||
if (this.memos[id]) {
|
||||
return this.memos[id]
|
||||
return this.memos[id];
|
||||
}
|
||||
|
||||
const [, anio, curso, lab, grupo] = id.split("_")
|
||||
const memo = this.registrar(anio, curso, lab === "L", grupo, datosGrupo)
|
||||
this.memos[id] = memo
|
||||
return memo
|
||||
const [, anio, curso, lab, grupo] = id.split("_");
|
||||
const memo = this.registrar(anio, curso, lab === "L", grupo, datosGrupo);
|
||||
this.memos[id] = memo;
|
||||
return memo;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,24 +186,24 @@ export class TablaObserver {
|
||||
* @param id Id a resaltar - YYYYMMDD_Año_Curso[\_Lab[_Grupo]]
|
||||
*/
|
||||
resaltar(id: string) {
|
||||
const [, anio, curso, lab, grupo] = id.split("_")
|
||||
const [, anio, curso, lab, grupo] = id.split("_");
|
||||
if (anio === undefined || curso === undefined) {
|
||||
console.error("Error al intentar resaltar celda: anio o curso son undefined:", anio, curso)
|
||||
return
|
||||
console.error("Error al intentar resaltar celda: anio o curso son undefined:", anio, curso);
|
||||
return;
|
||||
}
|
||||
|
||||
let esLab: boolean | undefined
|
||||
let esLab: boolean | undefined;
|
||||
if (lab === undefined) {
|
||||
esLab = undefined
|
||||
esLab = undefined;
|
||||
} else {
|
||||
esLab = lab === "L"
|
||||
esLab = lab === "L";
|
||||
}
|
||||
this.setResaltado({
|
||||
anio,
|
||||
curso,
|
||||
esLab,
|
||||
grupo,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
quitarResaltado() {
|
||||
@ -212,10 +212,10 @@ export class TablaObserver {
|
||||
curso: undefined,
|
||||
esLab: undefined,
|
||||
grupo: undefined,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
limpiar(id: string) {
|
||||
delete this.memos[id]
|
||||
delete this.memos[id];
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import {createStore, SetStoreFunction, Store} from "solid-js/store"
|
||||
import { Curso, ListaCursosUsuario } from "../types/DatosHorario"
|
||||
import {createStore, SetStoreFunction, Store} from "solid-js/store";
|
||||
import { Curso, ListaCursosUsuario } from "../../../../types/DatosHorario";
|
||||
|
||||
interface ReturnType {
|
||||
listaCursos: Store<ListaCursosUsuario>,
|
||||
@ -12,30 +12,30 @@ export const useListaCursos = (): ReturnType => {
|
||||
const [listaCursos, setListaCursos] = createStore<ListaCursosUsuario>({
|
||||
sigIndice: 0,
|
||||
cursos: [],
|
||||
})
|
||||
});
|
||||
|
||||
const agregarCursoALista = (curso: Curso): Curso => {
|
||||
// Si el horario ya se habia agregado, ocultarlo
|
||||
const cursoActualIndex = listaCursos.cursos.findIndex((x) => x.nombre === curso.nombre)
|
||||
const cursoActualIndex = listaCursos.cursos.findIndex((x) => x.nombre === curso.nombre);
|
||||
if (cursoActualIndex !== -1) {
|
||||
setListaCursos("cursos", cursoActualIndex, "oculto", (x) => !x)
|
||||
return listaCursos.cursos[cursoActualIndex]
|
||||
setListaCursos("cursos", cursoActualIndex, "oculto", (x) => !x);
|
||||
return listaCursos.cursos[cursoActualIndex];
|
||||
} else {
|
||||
setListaCursos("cursos", listaCursos.sigIndice, curso)
|
||||
setListaCursos("sigIndice", (x) => x + 1)
|
||||
return listaCursos.cursos[listaCursos.sigIndice - 1]
|
||||
}
|
||||
setListaCursos("cursos", listaCursos.sigIndice, curso);
|
||||
setListaCursos("sigIndice", (x) => x + 1);
|
||||
return listaCursos.cursos[listaCursos.sigIndice - 1];
|
||||
}
|
||||
};
|
||||
|
||||
const eliminarCursosDeLista = () => {
|
||||
setListaCursos("cursos", [])
|
||||
setListaCursos("sigIndice", 0)
|
||||
}
|
||||
setListaCursos("cursos", []);
|
||||
setListaCursos("sigIndice", 0);
|
||||
};
|
||||
|
||||
return {
|
||||
listaCursos,
|
||||
setListaCursos,
|
||||
agregarCursoALista,
|
||||
eliminarCursosDeLista,
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user