Agregar linter
This commit is contained in:
parent
e2503967cf
commit
f325f08fc8
89
.eslintrc.yml
Normal file
89
.eslintrc.yml
Normal file
@ -0,0 +1,89 @@
|
||||
env:
|
||||
browser: true
|
||||
es2021: true
|
||||
extends:
|
||||
- 'eslint:recommended'
|
||||
- 'plugin:@typescript-eslint/recommended'
|
||||
parser: '@typescript-eslint/parser'
|
||||
parserOptions:
|
||||
ecmaVersion: 12
|
||||
sourceType: module
|
||||
plugins:
|
||||
- '@typescript-eslint'
|
||||
- react
|
||||
rules:
|
||||
"@typescript-eslint/ban-ts-comment": off
|
||||
"@typescript-eslint/no-empty-function": off
|
||||
indent:
|
||||
- error
|
||||
- 4
|
||||
- SwitchCase: 1
|
||||
linebreak-style:
|
||||
- error
|
||||
- unix
|
||||
quotes:
|
||||
- error
|
||||
- double
|
||||
semi:
|
||||
- error
|
||||
- never
|
||||
react/jsx-pascal-case: error
|
||||
react/jsx-closing-bracket-location: error
|
||||
react/jsx-closing-tag-location: error
|
||||
no-multi-spaces: error
|
||||
react/jsx-tag-spacing: error
|
||||
react/jsx-boolean-value: error
|
||||
react/jsx-wrap-multilines: error
|
||||
react/self-closing-comp: error
|
||||
prefer-const: error
|
||||
no-const-assign: error
|
||||
no-var: error
|
||||
array-callback-return: error
|
||||
prefer-template: error
|
||||
template-curly-spacing: error
|
||||
no-useless-escape: error
|
||||
wrap-iife: error
|
||||
no-loop-func: error
|
||||
default-param-last: error
|
||||
space-before-function-paren:
|
||||
- error
|
||||
- never
|
||||
space-before-blocks: error
|
||||
no-param-reassign: error
|
||||
function-paren-newline: error
|
||||
comma-dangle:
|
||||
- error
|
||||
- always-multiline
|
||||
arrow-spacing: error
|
||||
arrow-parens: error
|
||||
arrow-body-style: error
|
||||
no-confusing-arrow: error
|
||||
implicit-arrow-linebreak: error
|
||||
no-duplicate-imports: error
|
||||
object-curly-newline: error
|
||||
dot-notation: error
|
||||
one-var:
|
||||
- error
|
||||
- never
|
||||
no-multi-assign: error
|
||||
no-plusplus: error
|
||||
operator-linebreak: error
|
||||
eqeqeq: error
|
||||
no-case-declarations: error
|
||||
no-nested-ternary: error
|
||||
no-unneeded-ternary: error
|
||||
no-mixed-operators: error
|
||||
nonblock-statement-body-position: error
|
||||
brace-style: error
|
||||
keyword-spacing: error
|
||||
space-infix-ops: error
|
||||
eol-last: error
|
||||
newline-per-chained-call: error
|
||||
no-whitespace-before-property: error
|
||||
space-in-parens: error
|
||||
array-bracket-spacing: error
|
||||
key-spacing: error
|
||||
no-trailing-spaces: error
|
||||
comma-style: error
|
||||
radix: error
|
||||
no-new-wrappers: error
|
@ -5,7 +5,11 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "26.0.20",
|
||||
"@types/node": "14.14.20",
|
||||
"@typescript-eslint/eslint-plugin": "^4.19.0",
|
||||
"@typescript-eslint/parser": "^4.19.0",
|
||||
"aphrodite": "^2.4.0",
|
||||
"eslint": "^7.22.0",
|
||||
"eslint-plugin-react": "^7.23.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"solid-js": "^0.23.11",
|
||||
"solid-scripts": "0.0.50",
|
||||
|
821
pnpm-lock.yaml
821
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
45
src/App.tsx
45
src/App.tsx
@ -1,43 +1,44 @@
|
||||
import { BarraSuperior } from "./BarraSuperior";
|
||||
import { ContenedorHorarios } from "./ContenedorHorarios/ContenedorHorarios";
|
||||
import { Wallpaper } from "./Wallpaper";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { css } from "aphrodite";
|
||||
import { estilosGlobales } from "./Estilos";
|
||||
import { Creditos } from "./Creditos";
|
||||
import { BarraSuperior } from "./BarraSuperior"
|
||||
import { ContenedorHorarios } from "./ContenedorHorarios/ContenedorHorarios"
|
||||
import { Wallpaper } from "./Wallpaper"
|
||||
import { Show, createSignal } from "solid-js"
|
||||
import { css } from "aphrodite"
|
||||
import { estilosGlobales } from "./Estilos"
|
||||
import { Creditos } from "./Creditos"
|
||||
|
||||
function App() {
|
||||
/// @ts-ignore
|
||||
const soportaBackdropFilter = document.body.style.backdropFilter !== undefined;
|
||||
const mostrarMensajeBackdropFilterRaw = localStorage.getItem("mensaje-backdrop-filter-oculto") !== undefined;
|
||||
const soportaBackdropFilter = document.body.style.backdropFilter !== undefined
|
||||
const mostrarMensajeBackdropFilterRaw = localStorage.getItem("mensaje-backdrop-filter-oculto") !== undefined
|
||||
|
||||
const [mostrarMensajeBackdropFilter, setMostrarMensaje] = createSignal(mostrarMensajeBackdropFilterRaw);
|
||||
const [mostrarMensajeBackdropFilter, setMostrarMensaje] = createSignal(mostrarMensajeBackdropFilterRaw)
|
||||
|
||||
const ocultarMensajeBackdropFilter = () => {
|
||||
setMostrarMensaje(false);
|
||||
localStorage.setItem("mensaje-backdrop-filter-oculto", "true");
|
||||
};
|
||||
setMostrarMensaje(false)
|
||||
localStorage.setItem("mensaje-backdrop-filter-oculto", "true")
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="App">
|
||||
<Wallpaper/>
|
||||
<BarraSuperior/>
|
||||
<Wallpaper />
|
||||
<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}
|
||||
<span
|
||||
className={css(estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
onClick={ocultarMensajeBackdropFilter}
|
||||
>
|
||||
No volver a mostrar.
|
||||
</span>
|
||||
</div>
|
||||
</Show>
|
||||
<div style={{width: "100%", height: "0.5rem"}}/>
|
||||
<ContenedorHorarios/>
|
||||
<Creditos/>
|
||||
<div style={{width: "100%", height: "0.5rem"}} />
|
||||
<ContenedorHorarios />
|
||||
<Creditos />
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
@ -1,101 +1,107 @@
|
||||
import { estilosGlobales } from "./Estilos";
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { numWallpaper, setNumWallpaper } from "./Store";
|
||||
import { estilosGlobales } from "./Estilos"
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { numWallpaper, setNumWallpaper } from "./Store"
|
||||
|
||||
const totalWallpapers = 5;
|
||||
const totalWallpapers = 5
|
||||
|
||||
const e = StyleSheet.create({
|
||||
contCambiador: {
|
||||
userSelect: "none"
|
||||
userSelect: "none",
|
||||
},
|
||||
boton: {
|
||||
cursor: "pointer",
|
||||
textDecoration: "underline",
|
||||
"::before": {
|
||||
fontSize: "1rem",
|
||||
transform: "translateY(0.2rem)"
|
||||
}
|
||||
transform: "translateY(0.2rem)",
|
||||
},
|
||||
},
|
||||
botonDesactivado: {
|
||||
cursor: "not-allowed",
|
||||
textDecoration: "none"
|
||||
textDecoration: "none",
|
||||
},
|
||||
botonLeft: {
|
||||
paddingRight: "0.5rem",
|
||||
marginRight: "0.25rem"
|
||||
marginRight: "0.25rem",
|
||||
},
|
||||
botonRight: {
|
||||
paddingLeft: "0.5rem",
|
||||
marginRight: "0.25rem"
|
||||
}
|
||||
});
|
||||
marginRight: "0.25rem",
|
||||
},
|
||||
})
|
||||
|
||||
const retrocederWallpaper = () => {
|
||||
const num = numWallpaper();
|
||||
const num = numWallpaper()
|
||||
if (num > 0) {
|
||||
setNumWallpaper(num - 1);
|
||||
localStorage.setItem("num-img", (num - 1).toString());
|
||||
setNumWallpaper(num - 1)
|
||||
localStorage.setItem("num-img", (num - 1).toString())
|
||||
} else {
|
||||
setNumWallpaper(totalWallpapers);
|
||||
localStorage.setItem("num-img", (totalWallpapers).toString());
|
||||
setNumWallpaper(totalWallpapers)
|
||||
localStorage.setItem("num-img", (totalWallpapers).toString())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const avanzarWallpaper = () => {
|
||||
const num = numWallpaper();
|
||||
const num = numWallpaper()
|
||||
if (num < totalWallpapers) {
|
||||
setNumWallpaper(num + 1);
|
||||
localStorage.setItem("num-img", (num + 1).toString());
|
||||
setNumWallpaper(num + 1)
|
||||
localStorage.setItem("num-img", (num + 1).toString())
|
||||
} else {
|
||||
setNumWallpaper(0);
|
||||
localStorage.setItem("num-img", (0).toString());
|
||||
setNumWallpaper(0)
|
||||
localStorage.setItem("num-img", (0).toString())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function CambiadorImg() {
|
||||
return <div className={css(estilosGlobales.inlineBlock, e.contCambiador)}>
|
||||
<span className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>
|
||||
<i
|
||||
className={"ph-arrow-left " + css(e.boton, e.botonLeft, estilosGlobales.contenedorCursorSoft)}
|
||||
onClick={retrocederWallpaper}
|
||||
title={"Cambiar imagen de fondo"}
|
||||
/>
|
||||
Img. {numWallpaper() + 1}
|
||||
<i
|
||||
className={"ph-arrow-right " + css(e.boton, e.botonRight, estilosGlobales.contenedorCursorSoft)}
|
||||
onClick={avanzarWallpaper}
|
||||
title={"Cambiar imagen de fondo"}
|
||||
/>
|
||||
</span>
|
||||
</div>;
|
||||
return (
|
||||
<div className={css(estilosGlobales.inlineBlock, e.contCambiador)}>
|
||||
<span className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>
|
||||
<i
|
||||
className={`ph-arrow-left ${css(e.boton, e.botonLeft, estilosGlobales.contenedorCursorSoft)}`}
|
||||
onClick={retrocederWallpaper}
|
||||
title={"Cambiar imagen de fondo"}
|
||||
/>
|
||||
Img. {numWallpaper() + 1}
|
||||
<i
|
||||
className={`ph-arrow-right ${css(e.boton, e.botonRight, estilosGlobales.contenedorCursorSoft)}`}
|
||||
onClick={avanzarWallpaper}
|
||||
title={"Cambiar imagen de fondo"}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const estilos = StyleSheet.create({
|
||||
tituloPrincipal: {
|
||||
fontWeight: "bold"
|
||||
}
|
||||
});
|
||||
fontWeight: "bold",
|
||||
},
|
||||
})
|
||||
|
||||
export function BarraSuperior() {
|
||||
return <header>
|
||||
<span className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilos.tituloPrincipal
|
||||
)}>
|
||||
Horarios Unsa
|
||||
</span>
|
||||
<a href="https://github.com/Araozu/horarios-unsa-2/" target="_blank" title={"Ver codigo fuente en GitHub"}
|
||||
className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor
|
||||
)}>
|
||||
GitHub
|
||||
<i class="ph-arrow-up-right"/>
|
||||
</a>
|
||||
<CambiadorImg/>
|
||||
<span className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>2021-A</span>
|
||||
<span className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>Ingeniería de Sistemas</span>
|
||||
</header>;
|
||||
return (
|
||||
<header>
|
||||
<span className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilos.tituloPrincipal,
|
||||
)}
|
||||
>
|
||||
Horarios Unsa
|
||||
</span>
|
||||
<a href="https://github.com/Araozu/horarios-unsa-2/" target="_blank" title={"Ver codigo fuente en GitHub"}
|
||||
className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
)}
|
||||
>
|
||||
GitHub
|
||||
<i class="ph-arrow-up-right" />
|
||||
</a>
|
||||
<CambiadorImg />
|
||||
<span className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>2021-A</span>
|
||||
<span className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>Ingeniería de Sistemas</span>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { css } from "aphrodite";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { css } from "aphrodite"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
|
||||
interface BotonMaxMinProps {
|
||||
icono: string,
|
||||
@ -8,16 +8,18 @@ interface BotonMaxMinProps {
|
||||
}
|
||||
|
||||
export function BotonIcono(props: BotonMaxMinProps) {
|
||||
return <div title={props.titulo}
|
||||
onClick={props.onClick}
|
||||
className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
estilosGlobales.contenedorPhospor
|
||||
)}
|
||||
>
|
||||
<i className={css(estilosGlobales.botonPhospor) + " " + props.icono}/>
|
||||
</div>
|
||||
return (
|
||||
<div title={props.titulo}
|
||||
onClick={props.onClick}
|
||||
className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
estilosGlobales.contenedorPhospor,
|
||||
)}
|
||||
>
|
||||
<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,30 +10,33 @@ 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 <div title={tituloBoton()}
|
||||
onClick={funcionBoton}
|
||||
className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
estilosGlobales.contenedorPhospor
|
||||
)}
|
||||
>
|
||||
<i className={css(estilosGlobales.botonPhospor) + " " + iconoBoton()}/>
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
title={tituloBoton()}
|
||||
onClick={funcionBoton}
|
||||
className={css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
estilosGlobales.contenedorPhospor,
|
||||
)}
|
||||
>
|
||||
<i className={`${css(estilosGlobales.botonPhospor)} ${iconoBoton()}`} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
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 "./MiHorario"
|
||||
import { Horarios } from "./Horarios"
|
||||
import {
|
||||
Anios,
|
||||
Cursos,
|
||||
@ -10,126 +10,131 @@ import {
|
||||
DatosHorario,
|
||||
DatosHorarioRaw,
|
||||
DatosGrupo,
|
||||
ListaCursosUsuario
|
||||
} from "../types/DatosHorario";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { batch, createEffect, createMemo, createSignal, createState, Show } from "solid-js";
|
||||
import { useListaCursos } from "./useListaCursos";
|
||||
ListaCursosUsuario,
|
||||
} from "../types/DatosHorario"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { batch, createEffect, createMemo, createSignal, createState, Show } from "solid-js"
|
||||
import { useListaCursos } from "./useListaCursos"
|
||||
|
||||
const datosPromise = (async () => {
|
||||
const file = await fetch("/horarios/2020_2_fps_ingenieriadesistemas.yaml");
|
||||
const text = await file.text();
|
||||
const datosRaw = YAML.parse(text) as DatosHorarioRaw;
|
||||
const datosPromise = (async() => {
|
||||
const file = await fetch("/horarios/2020_2_fps_ingenieriadesistemas.yaml")
|
||||
const text = await file.text()
|
||||
const datosRaw = YAML.parse(text) as DatosHorarioRaw
|
||||
|
||||
// Agregar los campos faltantes a DatosHorarioRaw para que sea DatosHorario
|
||||
const datos: DatosHorario = {
|
||||
...datosRaw,
|
||||
años: {}
|
||||
};
|
||||
años: {},
|
||||
}
|
||||
|
||||
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] = {
|
||||
...curso,
|
||||
oculto: false,
|
||||
Teoria: gruposTeoria,
|
||||
Laboratorio: gruposLab
|
||||
};
|
||||
Laboratorio: gruposLab,
|
||||
}
|
||||
}
|
||||
|
||||
anios[nombreAnio] = anioData;
|
||||
anios[nombreAnio] = anioData
|
||||
}
|
||||
|
||||
datos.años = anios;
|
||||
return datos;
|
||||
})();
|
||||
datos.años = anios
|
||||
return datos
|
||||
})()
|
||||
|
||||
const ElemCargando = () =>
|
||||
const ElemCargando = () => (
|
||||
<div className={css(estilosGlobales.contenedor, estilosGlobales.inlineBlock)}>
|
||||
Recuperando horarios...
|
||||
</div>
|
||||
)
|
||||
|
||||
export type EstadoLayout = "MaxPersonal" | "Normal" | "MaxHorarios";
|
||||
|
||||
const {
|
||||
listaCursos: cursosUsuario,
|
||||
setListaCursos: setCursosUsuarios,
|
||||
agregarCursoALista: agregarCursoUsuario
|
||||
} = useListaCursos();
|
||||
agregarCursoALista: agregarCursoUsuario,
|
||||
} = useListaCursos()
|
||||
|
||||
export function ContenedorHorarios() {
|
||||
const [datosCargados, setDatosCargados] = createSignal(false);
|
||||
const [datos, setDatos] = createSignal<DatosHorario | null>(null);
|
||||
const [estadoLayout, setEstadoLayout] = createSignal<EstadoLayout>(
|
||||
localStorage.getItem("estadoLayout") as EstadoLayout || "Normal"
|
||||
);
|
||||
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 = "4rem auto";
|
||||
break;
|
||||
templateColumns = "4rem auto"
|
||||
break
|
||||
}
|
||||
case "MaxPersonal": {
|
||||
templateColumns = "auto 4rem";
|
||||
break;
|
||||
templateColumns = "auto 4rem"
|
||||
break
|
||||
}
|
||||
case "Normal": {
|
||||
templateColumns = "50% 50%"
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem("estadoLayout", estadoLayout());
|
||||
localStorage.setItem("estadoLayout", estadoLayout())
|
||||
|
||||
return StyleSheet.create({
|
||||
contenedor: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: templateColumns
|
||||
}
|
||||
});
|
||||
});
|
||||
gridTemplateColumns: templateColumns,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
createEffect(async () => {
|
||||
const datos = await datosPromise;
|
||||
createEffect(async() => {
|
||||
const datos = await datosPromise
|
||||
batch(() => {
|
||||
setDatos(datos);
|
||||
setDatosCargados(true);
|
||||
});
|
||||
});
|
||||
setDatos(datos)
|
||||
setDatosCargados(true)
|
||||
})
|
||||
})
|
||||
|
||||
return <div className={css(e().contenedor)}>
|
||||
<div>
|
||||
<MiHorario estadoLayout={estadoLayout()}
|
||||
setEstadoLayout={setEstadoLayout}
|
||||
cursosUsuario={cursosUsuario}
|
||||
fnAgregarCurso={agregarCursoUsuario}
|
||||
setCursosUsuarios={setCursosUsuarios}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Show when={datosCargados()}>
|
||||
<Horarios data={datos()!!}
|
||||
estadoLayout={estadoLayout()}
|
||||
setEstadoLayout={setEstadoLayout}
|
||||
fnAgregarCurso={(c) => agregarCursoUsuario(JSON.parse(JSON.stringify(c)))}
|
||||
listaCursosUsuario={cursosUsuario}
|
||||
setCursosUsuarios={setCursosUsuarios}
|
||||
return (
|
||||
<div className={css(e().contenedor)}>
|
||||
<div>
|
||||
<MiHorario
|
||||
estadoLayout={estadoLayout()}
|
||||
setEstadoLayout={setEstadoLayout}
|
||||
cursosUsuario={cursosUsuario}
|
||||
fnAgregarCurso={agregarCursoUsuario}
|
||||
setCursosUsuarios={setCursosUsuarios}
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
<div>
|
||||
<Show when={datosCargados()}>
|
||||
<Horarios
|
||||
data={datos()!}
|
||||
estadoLayout={estadoLayout()}
|
||||
setEstadoLayout={setEstadoLayout}
|
||||
fnAgregarCurso={(c) => agregarCursoUsuario(JSON.parse(JSON.stringify(c)))}
|
||||
listaCursosUsuario={cursosUsuario}
|
||||
setCursosUsuarios={setCursosUsuarios}
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
)
|
||||
}
|
||||
|
@ -1,32 +1,32 @@
|
||||
import { Cursos, CursoRaw, DatosGrupo, ListaCursosUsuario, Curso } from "../types/DatosHorario";
|
||||
import { createEffect, createMemo, For, SetStateFunction } from "solid-js";
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { Cursos, CursoRaw, DatosGrupo, ListaCursosUsuario, Curso } from "../types/DatosHorario"
|
||||
import { createEffect, createMemo, For, SetStateFunction } from "solid-js"
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
|
||||
const e = StyleSheet.create({
|
||||
inline: {
|
||||
display: "inline-block"
|
||||
display: "inline-block",
|
||||
},
|
||||
lineaTexto: {
|
||||
marginBottom: "0.5rem"
|
||||
marginBottom: "0.5rem",
|
||||
},
|
||||
tablaGrupos: {
|
||||
whiteSpace: "pre",
|
||||
borderCollapse: "collapse",
|
||||
borderSpacing: 0
|
||||
borderSpacing: 0,
|
||||
},
|
||||
contenedorCurso: {
|
||||
display: "inline-block",
|
||||
verticalAlign: "top"
|
||||
verticalAlign: "top",
|
||||
},
|
||||
cursoOculto: {
|
||||
display: "none"
|
||||
display: "none",
|
||||
},
|
||||
botonTexto: {
|
||||
padding: "0.25rem 0.35rem",
|
||||
borderRadius: "5px"
|
||||
}
|
||||
});
|
||||
borderRadius: "5px",
|
||||
},
|
||||
})
|
||||
|
||||
interface Props {
|
||||
dataAnio: Cursos,
|
||||
@ -50,23 +50,30 @@ interface PropsIndicadorGrupo {
|
||||
}
|
||||
|
||||
function IndicadorGrupo(props: PropsIndicadorGrupo) {
|
||||
const id = `${props.idParcial}_${props.esLab ? 'L' : 'T'}_${props.nombre}`;
|
||||
return <span className={css(e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
style={props.esLab ? {"font-style": "italic"} : {"font-weight": "bold"}}
|
||||
onMouseEnter={() => props.setIdHover(id)}
|
||||
onMouseLeave={() => props.setIdHover("")}
|
||||
onClick={props.onClick}
|
||||
>
|
||||
{props.esLab ? "L" : ""}{props.nombre}
|
||||
</span>
|
||||
const id = `${props.idParcial}_${props.esLab ? "L" : "T"}_${props.nombre}`
|
||||
return (
|
||||
<span className={css(e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
style={props.esLab ? {"font-style": "italic"} : {"font-weight": "bold"}}
|
||||
onMouseEnter={() => props.setIdHover(id)}
|
||||
onMouseLeave={() => props.setIdHover("")}
|
||||
onClick={props.onClick}
|
||||
>
|
||||
{props.esLab ? "L" : ""}{props.nombre}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
const agruparProfesores = (datos: { [k: string]: DatosGrupo }, indiceCurso: number, esLab: boolean, setCursosUsuarios: FnSetCursosUsuarios) => {
|
||||
const profesores: { [k: string]: [string, () => void][] } = {};
|
||||
const agruparProfesores = (
|
||||
datos: { [k: string]: DatosGrupo },
|
||||
indiceCurso: number,
|
||||
esLab: boolean,
|
||||
setCursosUsuarios: FnSetCursosUsuarios,
|
||||
) => {
|
||||
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,
|
||||
@ -78,133 +85,136 @@ const agruparProfesores = (datos: { [k: string]: DatosGrupo }, indiceCurso: numb
|
||||
/// @ts-ignore
|
||||
grupo,
|
||||
"seleccionado",
|
||||
x => !x
|
||||
);
|
||||
}
|
||||
]);
|
||||
(x) => !x,
|
||||
)
|
||||
},
|
||||
])
|
||||
}
|
||||
return profesores;
|
||||
};
|
||||
return profesores
|
||||
}
|
||||
|
||||
export function CursosElem(props: Props) {
|
||||
const anio = () => props.anioActual().substring(0, props.anioActual().indexOf(" "));
|
||||
const anio = () => props.anioActual().substring(0, props.anioActual().indexOf(" "))
|
||||
|
||||
const claseCursoNoAgregado = css(
|
||||
e.contenedorCurso,
|
||||
estilosGlobales.contenedor
|
||||
);
|
||||
estilosGlobales.contenedor,
|
||||
)
|
||||
|
||||
const claseCursoAgregado = css(
|
||||
e.contenedorCurso,
|
||||
estilosGlobales.contenedor,
|
||||
!props.esCursoMiHorario && estilosGlobales.contenedorCursorActivo,
|
||||
);
|
||||
)
|
||||
|
||||
const claseCursoOculto = css(e.cursoOculto);
|
||||
const claseCursoOculto = css(e.cursoOculto)
|
||||
|
||||
return <>
|
||||
<For each={Object.entries(props.dataAnio)}>
|
||||
{([indiceCurso, datosCurso]) => {
|
||||
return (
|
||||
<>
|
||||
<For each={Object.entries(props.dataAnio)}>
|
||||
{([indiceCurso, datosCurso]) => {
|
||||
|
||||
const idCurso = `${anio()}_${datosCurso.abreviado}`;
|
||||
const idCurso = `${anio()}_${datosCurso.abreviado}`
|
||||
|
||||
const cursoAgregadoMemo = createMemo(
|
||||
() => props.listaCursosUsuario.cursos.find(x => {
|
||||
return x.nombre === datosCurso.nombre && !x.oculto
|
||||
}) !== undefined,
|
||||
undefined,
|
||||
(x, y) => x === y
|
||||
);
|
||||
const cursoAgregadoMemo = createMemo(
|
||||
() => props.listaCursosUsuario.cursos.find((x) => x.nombre === datosCurso.nombre && !x.oculto) !== undefined,
|
||||
undefined,
|
||||
(x, y) => x === y,
|
||||
)
|
||||
|
||||
const tituloMemo = createMemo(() => cursoAgregadoMemo()
|
||||
? `Remover de mi horario`
|
||||
: `Agregar a mi horario`
|
||||
);
|
||||
const tituloMemo = createMemo(() => (cursoAgregadoMemo()
|
||||
? "Remover de mi horario"
|
||||
: "Agregar a mi horario"))
|
||||
|
||||
const claseMemo = createMemo(() => {
|
||||
if (props.esCursoMiHorario && datosCurso.oculto) {
|
||||
return claseCursoOculto
|
||||
}
|
||||
return cursoAgregadoMemo()
|
||||
? claseCursoAgregado
|
||||
: claseCursoNoAgregado
|
||||
});
|
||||
const claseMemo = createMemo(() => {
|
||||
if (props.esCursoMiHorario && datosCurso.oculto) {
|
||||
return claseCursoOculto
|
||||
}
|
||||
return cursoAgregadoMemo()
|
||||
? claseCursoAgregado
|
||||
: claseCursoNoAgregado
|
||||
})
|
||||
|
||||
const profesoresTeoria = createMemo(() => agruparProfesores(
|
||||
datosCurso.Teoria,
|
||||
parseInt(indiceCurso),
|
||||
false,
|
||||
props.setCursosUsuarios
|
||||
));
|
||||
const profesoresLab = createMemo(() => agruparProfesores(
|
||||
datosCurso.Laboratorio ?? {},
|
||||
parseInt(indiceCurso),
|
||||
true,
|
||||
props.setCursosUsuarios
|
||||
));
|
||||
const profesoresTeoria = createMemo(() => agruparProfesores(
|
||||
datosCurso.Teoria,
|
||||
Number(indiceCurso),
|
||||
false,
|
||||
props.setCursosUsuarios,
|
||||
))
|
||||
const profesoresLab = createMemo(() => agruparProfesores(
|
||||
datosCurso.Laboratorio ?? {},
|
||||
Number(indiceCurso),
|
||||
true,
|
||||
props.setCursosUsuarios,
|
||||
))
|
||||
|
||||
return <div className={claseMemo()}>
|
||||
<div
|
||||
className={css(e.inline, e.lineaTexto, e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
onMouseEnter={() => props.setIdHover(idCurso)}
|
||||
onMouseLeave={() => props.setIdHover("")}
|
||||
>
|
||||
{datosCurso.abreviado} - {datosCurso.nombre}
|
||||
</div>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<For each={Object.entries(profesoresTeoria())}>
|
||||
{([profesor, grupos]) => {
|
||||
return <td style={{"padding-bottom": "0.5rem", "padding-right": "0.75rem"}}>
|
||||
<span>
|
||||
{profesor}
|
||||
</span>
|
||||
<For each={grupos}>
|
||||
{([x, fnOnClick]) =>
|
||||
<IndicadorGrupo nombre={x}
|
||||
return (
|
||||
<div className={claseMemo()}>
|
||||
<div
|
||||
className={css(e.inline, e.lineaTexto, e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
onMouseEnter={() => props.setIdHover(idCurso)}
|
||||
onMouseLeave={() => props.setIdHover("")}
|
||||
>
|
||||
{datosCurso.abreviado} - {datosCurso.nombre}
|
||||
</div>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<For each={Object.entries(profesoresTeoria())}>
|
||||
{([profesor, grupos]) => (
|
||||
<td style={{"padding-bottom": "0.5rem", "padding-right": "0.75rem"}}>
|
||||
<span>
|
||||
{profesor}
|
||||
</span>
|
||||
<For each={grupos}>
|
||||
{([x, fnOnClick]) => (
|
||||
<IndicadorGrupo nombre={x}
|
||||
esLab={false}
|
||||
idParcial={idCurso}
|
||||
setIdHover={props.setIdHover}
|
||||
onClick={fnOnClick}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</For>
|
||||
</td>
|
||||
)}
|
||||
</For>
|
||||
</td>
|
||||
}}
|
||||
</For>
|
||||
</tr>
|
||||
<tr>
|
||||
<For each={Object.entries(profesoresLab())}>
|
||||
{([profesor, grupos]) => {
|
||||
return <td style={{"padding-bottom": "0.5rem", "padding-right": "0.75rem"}}>
|
||||
<span>
|
||||
{profesor}
|
||||
</span>
|
||||
<For each={grupos}>
|
||||
{([x, fnOnClick]) =>
|
||||
<IndicadorGrupo nombre={x}
|
||||
esLab={true}
|
||||
</tr>
|
||||
<tr>
|
||||
<For each={Object.entries(profesoresLab())}>
|
||||
{([profesor, grupos]) => (
|
||||
<td style={{"padding-bottom": "0.5rem", "padding-right": "0.75rem"}}>
|
||||
<span>
|
||||
{profesor}
|
||||
</span>
|
||||
<For each={grupos}>
|
||||
{([x, fnOnClick]) => (
|
||||
<IndicadorGrupo nombre={x}
|
||||
esLab
|
||||
idParcial={idCurso}
|
||||
setIdHover={props.setIdHover}
|
||||
onClick={fnOnClick}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</For>
|
||||
</td>
|
||||
)}
|
||||
</For>
|
||||
</td>
|
||||
}}
|
||||
</For>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<span
|
||||
className={css(e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
onClick={() => props.fnAgregarCurso(datosCurso)}
|
||||
>
|
||||
{tituloMemo}
|
||||
</span>
|
||||
</div>
|
||||
}}
|
||||
</For>
|
||||
</>;
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<span
|
||||
className={css(e.botonTexto, estilosGlobales.contenedorCursor, estilosGlobales.contenedorCursorSoft)}
|
||||
onClick={() => props.fnAgregarCurso(datosCurso)}
|
||||
>
|
||||
{tituloMemo}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Curso, Cursos, DatosHorario, ListaCursosUsuario } from "../types/DatosHorario";
|
||||
import { batch, createMemo, createSignal, For, Match, SetStateFunction, Switch, untrack } from "solid-js";
|
||||
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 { Curso, Cursos, DatosHorario, ListaCursosUsuario } from "../types/DatosHorario"
|
||||
import { batch, createMemo, createSignal, For, Match, SetStateFunction, Switch, untrack } from "solid-js"
|
||||
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"
|
||||
|
||||
interface HorariosProps {
|
||||
data: DatosHorario,
|
||||
@ -20,107 +20,116 @@ interface HorariosProps {
|
||||
const {
|
||||
setListaCursos,
|
||||
agregarCursoALista,
|
||||
eliminarCursosDeLista
|
||||
} = useListaCursos();
|
||||
eliminarCursosDeLista,
|
||||
} = useListaCursos()
|
||||
|
||||
export function Horarios(props: HorariosProps) {
|
||||
const [anioActual, setAnioActual] = createSignal("1er año");
|
||||
const [anioActual, setAnioActual] = createSignal("1er año")
|
||||
// ID que indica cuales celdas resaltar.
|
||||
const [idHover, setIdHover] = createSignal("");
|
||||
const [idHover, setIdHover] = createSignal("")
|
||||
|
||||
const elAnios = <For each={Object.entries(props.data.años)}>
|
||||
{([nombre]) => {
|
||||
const clases = createMemo(() => {
|
||||
const vAnio = anioActual();
|
||||
return css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
nombre === vAnio && estilosGlobales.contenedorCursorActivo
|
||||
);
|
||||
});
|
||||
const elAnios = (
|
||||
<For each={Object.entries(props.data.años)}>
|
||||
{([nombre]) => {
|
||||
const clases = createMemo(() => {
|
||||
const vAnio = anioActual()
|
||||
return css(
|
||||
estilosGlobales.contenedor,
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedorCursor,
|
||||
estilosGlobales.contenedorCursorSoft,
|
||||
nombre === vAnio && estilosGlobales.contenedorCursorActivo,
|
||||
)
|
||||
})
|
||||
|
||||
return <div className={clases()} title={"Cambiar a " + nombre} onClick={() => setAnioActual(nombre)}>
|
||||
{nombre}
|
||||
</div>
|
||||
}}
|
||||
</For>;
|
||||
return (
|
||||
<div className={clases()} title={`Cambiar a ${nombre}`} onClick={() => setAnioActual(nombre)}>
|
||||
{nombre}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</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++;
|
||||
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>
|
||||
<Switch>
|
||||
<Match when={props.estadoLayout === "Normal" || props.estadoLayout === "MaxHorarios"}>
|
||||
<div>
|
||||
<div className={css(
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedor
|
||||
)}>
|
||||
Horarios disponibles
|
||||
return (
|
||||
<div>
|
||||
<Switch>
|
||||
<Match when={props.estadoLayout === "Normal" || props.estadoLayout === "MaxHorarios"}>
|
||||
<div>
|
||||
<div className={css(
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedor,
|
||||
)}
|
||||
>
|
||||
Horarios disponibles
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{elAnios}
|
||||
|
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxHorarios"}
|
||||
/>
|
||||
<br/>
|
||||
<div className={css(estilosGlobales.contenedor)}>
|
||||
<Tabla data={dataTabla()}
|
||||
version={props.data.version}
|
||||
anio={anioActual()}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
setCursosUsuarios={setListaCursos}
|
||||
{elAnios}
|
||||
|
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxHorarios"}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<CursosElem dataAnio={dataTabla()}
|
||||
anioActual={anioActual}
|
||||
fnAgregarCurso={props.fnAgregarCurso}
|
||||
listaCursosUsuario={props.listaCursosUsuario}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
esCursoMiHorario={false}
|
||||
setCursosUsuarios={setListaCursos}
|
||||
<br />
|
||||
<div className={css(estilosGlobales.contenedor)}>
|
||||
<Tabla
|
||||
data={dataTabla()}
|
||||
version={props.data.version}
|
||||
anio={anioActual()}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
setCursosUsuarios={setListaCursos}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<CursosElem
|
||||
dataAnio={dataTabla()}
|
||||
anioActual={anioActual}
|
||||
fnAgregarCurso={props.fnAgregarCurso}
|
||||
listaCursosUsuario={props.listaCursosUsuario}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
esCursoMiHorario={false}
|
||||
setCursosUsuarios={setListaCursos}
|
||||
/>
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={props.estadoLayout === "MaxPersonal"}>
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxHorarios"}
|
||||
/>
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={props.estadoLayout === "MaxPersonal"}>
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxHorarios"}
|
||||
/>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Match>
|
||||
</Switch>
|
||||
|
||||
</div>;
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { Tabla } from "./Tabla";
|
||||
import { mostrarDescansos } from "../Store";
|
||||
import { EstadoLayout } from "./ContenedorHorarios";
|
||||
import { Switch, Match, For, createMemo, createSignal, SetStateFunction } from "solid-js";
|
||||
import { BotonMaxMin } from "./BotonMaxMin";
|
||||
import { BotonIcono } from "./BotonIcono";
|
||||
import { Curso, Cursos, ListaCursosUsuario } from "../types/DatosHorario";
|
||||
import { CursosElem } from "./CursosElem";
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { Tabla } from "./Tabla"
|
||||
import { mostrarDescansos } from "../Store"
|
||||
import { EstadoLayout } from "./ContenedorHorarios"
|
||||
import { Switch, Match, For, createMemo, createSignal, SetStateFunction } from "solid-js"
|
||||
import { BotonMaxMin } from "./BotonMaxMin"
|
||||
import { BotonIcono } from "./BotonIcono"
|
||||
import { Curso, Cursos, ListaCursosUsuario } from "../types/DatosHorario"
|
||||
import { CursosElem } from "./CursosElem"
|
||||
|
||||
interface MiHorarioProps {
|
||||
estadoLayout: EstadoLayout,
|
||||
@ -25,111 +25,117 @@ const e = StyleSheet.create({
|
||||
"::before": {
|
||||
fontSize: "1rem",
|
||||
// transform: "translateY(0.2rem)",
|
||||
textDecoration: "none"
|
||||
}
|
||||
}
|
||||
});
|
||||
textDecoration: "none",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export function MiHorario(props: MiHorarioProps) {
|
||||
const [idHover, setIdHover] = createSignal("");
|
||||
const [idHover, setIdHover] = createSignal("")
|
||||
|
||||
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.
|
||||
Al hacer click en un horario de la barra superior, llevarlo al inicio de la lista.
|
||||
*/
|
||||
return <div>
|
||||
<Switch>
|
||||
<Match when={props.estadoLayout === "Normal" || props.estadoLayout === "MaxPersonal"}>
|
||||
return (
|
||||
<div>
|
||||
<Switch>
|
||||
<Match when={props.estadoLayout === "Normal" || props.estadoLayout === "MaxPersonal"}>
|
||||
|
||||
<div>
|
||||
<div className={css(
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedor
|
||||
)}>
|
||||
<div>
|
||||
<div className={css(
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedor,
|
||||
)}
|
||||
>
|
||||
Mi horario
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className={css(
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedor
|
||||
)}>
|
||||
Mi horario
|
||||
<div>
|
||||
<div className={css(
|
||||
estilosGlobales.inlineBlock,
|
||||
estilosGlobales.contenedor,
|
||||
)}
|
||||
>
|
||||
Mi horario
|
||||
</div>
|
||||
|
|
||||
<BotonIcono
|
||||
titulo={"Nuevo horario en blanco"}
|
||||
icono={"ph-plus"}
|
||||
onClick={() => {}}
|
||||
/>
|
||||
<BotonIcono
|
||||
titulo={"Reiniciar horario"}
|
||||
icono={"ph-arrow-counter-clockwise"}
|
||||
onClick={() => {}}
|
||||
/>
|
||||
<BotonIcono
|
||||
titulo={"Duplicar horario"}
|
||||
icono={"ph-copy"}
|
||||
onClick={() => {}}
|
||||
/>
|
||||
<BotonIcono titulo={"Eliminar horario"}
|
||||
icono={"ph-trash"}
|
||||
onClick={() => {}}
|
||||
/>
|
||||
|
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxPersonal"}
|
||||
/>
|
||||
</div>
|
||||
|
|
||||
<BotonIcono titulo={"Nuevo horario en blanco"}
|
||||
icono={"ph-plus"}
|
||||
onClick={() => {
|
||||
}}
|
||||
|
||||
<div className={css(
|
||||
e.horario,
|
||||
estilosGlobales.contenedor,
|
||||
)}
|
||||
>
|
||||
<Tabla
|
||||
data={datosMiHorario()}
|
||||
anio={"Mi horario"}
|
||||
version={1}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
setCursosUsuarios={props.setCursosUsuarios}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CursosElem
|
||||
anioActual={() => "Mi horario"}
|
||||
dataAnio={datosMiHorario()}
|
||||
fnAgregarCurso={props.fnAgregarCurso}
|
||||
listaCursosUsuario={props.cursosUsuario}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
esCursoMiHorario
|
||||
setCursosUsuarios={props.setCursosUsuarios}
|
||||
/>
|
||||
<BotonIcono titulo={"Reiniciar horario"}
|
||||
icono={"ph-arrow-counter-clockwise"}
|
||||
onClick={() => {
|
||||
}}
|
||||
/>
|
||||
<BotonIcono titulo={"Duplicar horario"}
|
||||
icono={"ph-copy"}
|
||||
onClick={() => {
|
||||
}}
|
||||
/>
|
||||
<BotonIcono titulo={"Eliminar horario"}
|
||||
icono={"ph-trash"}
|
||||
onClick={() => {
|
||||
}}
|
||||
/>
|
||||
|
|
||||
</Match>
|
||||
<Match when={props.estadoLayout === "MaxHorarios"}>
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxPersonal"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={css(
|
||||
e.horario,
|
||||
estilosGlobales.contenedor
|
||||
)}>
|
||||
<Tabla data={datosMiHorario()}
|
||||
anio={"Mi horario"}
|
||||
version={1}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
setCursosUsuarios={props.setCursosUsuarios}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CursosElem anioActual={() => "Mi horario"}
|
||||
dataAnio={datosMiHorario()}
|
||||
fnAgregarCurso={props.fnAgregarCurso}
|
||||
listaCursosUsuario={props.cursosUsuario}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
esCursoMiHorario={true}
|
||||
setCursosUsuarios={props.setCursosUsuarios}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={props.estadoLayout === "MaxHorarios"}>
|
||||
<BotonMaxMin
|
||||
fnMaximizar={fnMaximizar}
|
||||
fnMinimizar={fnMinimizar}
|
||||
estadoActualLayout={estadoActualLayout}
|
||||
estadoLayoutMax={"MaxPersonal"}
|
||||
/>
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>;
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,31 +1,30 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { createEffect, createMemo, createSignal, createState, For, SetStateFunction } from "solid-js";
|
||||
import { estilosGlobales } from "../Estilos";
|
||||
import { Cursos, Curso, ListaCursosUsuario } from "../types/DatosHorario";
|
||||
import { Dia, dias, horas } from "../Store";
|
||||
import { DataProcesada } from "../types/DatosHorario";
|
||||
import { FilaTabla } from "./Tabla/FilaTabla";
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { createMemo, For, SetStateFunction } from "solid-js"
|
||||
import { estilosGlobales } from "../Estilos"
|
||||
import { Cursos, ListaCursosUsuario, DataProcesada } from "../types/DatosHorario"
|
||||
import { Dia, dias, horas } from "../Store"
|
||||
import { FilaTabla } from "./Tabla/FilaTabla"
|
||||
|
||||
export const coloresBorde = Object.freeze([
|
||||
"rgba(33,150,243,1)",
|
||||
"rgba(255,214,0 ,1)",
|
||||
"rgba(236,64,122 ,1)",
|
||||
"rgba(29,233,182 ,1)",
|
||||
"rgba(244,67,54,1)"
|
||||
]);
|
||||
"rgba(244,67,54,1)",
|
||||
])
|
||||
|
||||
export const diaANum = (d: Dia) => {
|
||||
switch (d) {
|
||||
case "Lunes":
|
||||
return 0;
|
||||
return 0
|
||||
case "Martes":
|
||||
return 1;
|
||||
return 1
|
||||
case "Miercoles":
|
||||
return 2;
|
||||
return 2
|
||||
case "Jueves":
|
||||
return 3;
|
||||
return 3
|
||||
case "Viernes":
|
||||
return 4;
|
||||
return 4
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +39,7 @@ const e = StyleSheet.create({
|
||||
minHeight: "1.5rem",
|
||||
":hover": {
|
||||
// backgroundColor: "rgba(200, 200, 200, 0.25)"
|
||||
}
|
||||
},
|
||||
},
|
||||
filaBorde: {
|
||||
position: "absolute",
|
||||
@ -48,65 +47,65 @@ const e = StyleSheet.create({
|
||||
height: "1px",
|
||||
width: "100%",
|
||||
backgroundColor: "rgba(200, 200, 200, 0.25)",
|
||||
zIndex: 1
|
||||
zIndex: 1,
|
||||
},
|
||||
celdaHora: {
|
||||
textAlign: "center",
|
||||
width: "4rem",
|
||||
padding: "0.25rem 0",
|
||||
position: "absolute",
|
||||
top: "-0.75rem"
|
||||
top: "-0.75rem",
|
||||
},
|
||||
celdaComun: {
|
||||
width: "20%",
|
||||
textAlign: "center",
|
||||
padding: "0 0.5rem",
|
||||
boxSizing: "border-box"
|
||||
boxSizing: "border-box",
|
||||
},
|
||||
celdaDia: {
|
||||
padding: "0.3rem 0"
|
||||
padding: "0.3rem 0",
|
||||
},
|
||||
celdaCurso: {
|
||||
display: "inline-block",
|
||||
padding: "0.25rem 0.35rem",
|
||||
cursor: "pointer",
|
||||
borderRadius: "5px",
|
||||
transition: "background-color 100ms"
|
||||
transition: "background-color 100ms",
|
||||
},
|
||||
celdaCursoActiva: {
|
||||
backgroundColor: "rgba(200, 200, 200, 0.25)"
|
||||
backgroundColor: "rgba(200, 200, 200, 0.25)",
|
||||
},
|
||||
celdaCursoTeoria: {
|
||||
fontWeight: "bold"
|
||||
}
|
||||
});
|
||||
fontWeight: "bold",
|
||||
},
|
||||
})
|
||||
|
||||
type FnSetCursosUsuarios = SetStateFunction<ListaCursosUsuario>;
|
||||
|
||||
const procesarAnio = (data: Cursos, anio: string, version: number, setCursosUsuarios: FnSetCursosUsuarios) => {
|
||||
const obj: DataProcesada = {};
|
||||
const obj: DataProcesada = {}
|
||||
|
||||
for (const [indiceCurso, curso] of Object.entries(data)) {
|
||||
if (curso.oculto) continue;
|
||||
if (curso.oculto) continue
|
||||
|
||||
const nombreAbreviado = curso.abreviado;
|
||||
const nombreAbreviado = curso.abreviado
|
||||
|
||||
for (const [grupoStr, grupo] of Object.entries(curso.Teoria)) {
|
||||
for (const hora of grupo.Horas) {
|
||||
const dia = hora.substring(0, 2);
|
||||
const horas = hora.substring(2, 4);
|
||||
const minutos = hora.substr(4);
|
||||
const dia = hora.substring(0, 2)
|
||||
const horas = hora.substring(2, 4)
|
||||
const minutos = hora.substr(4)
|
||||
|
||||
const horaCompleta = horas + ":" + minutos;
|
||||
const horaCompleta = `${horas}:${minutos}`
|
||||
|
||||
const id = `${version}_${anio}_${nombreAbreviado}_T_${grupoStr}`;
|
||||
const id = `${version}_${anio}_${nombreAbreviado}_T_${grupoStr}`
|
||||
|
||||
if (!(horaCompleta in obj)) {
|
||||
obj[horaCompleta] = {};
|
||||
obj[horaCompleta] = {}
|
||||
}
|
||||
|
||||
if (!(dia in obj[horaCompleta])) {
|
||||
obj[horaCompleta][dia] = [];
|
||||
obj[horaCompleta][dia] = []
|
||||
}
|
||||
|
||||
obj[horaCompleta][dia].push({
|
||||
@ -116,28 +115,28 @@ const procesarAnio = (data: Cursos, anio: string, version: number, setCursosUsua
|
||||
datosGrupo: grupo,
|
||||
fnSeleccionar: () => {
|
||||
/// @ts-ignore
|
||||
setCursosUsuarios("cursos", indiceCurso, "Teoria", grupoStr, "seleccionado", x => !x);
|
||||
}
|
||||
});
|
||||
setCursosUsuarios("cursos", indiceCurso, "Teoria", grupoStr, "seleccionado", (x) => !x)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for (const [grupoStr, grupo] of Object.entries(curso.Laboratorio ?? {})) {
|
||||
for (const hora of grupo.Horas) {
|
||||
const dia = hora.substring(0, 2);
|
||||
const horas = hora.substring(2, 4);
|
||||
const minutos = hora.substr(4);
|
||||
const dia = hora.substring(0, 2)
|
||||
const horas = hora.substring(2, 4)
|
||||
const minutos = hora.substr(4)
|
||||
|
||||
const horaCompleta = horas + ":" + minutos;
|
||||
const horaCompleta = `${horas}:${minutos}`
|
||||
|
||||
const id = `${version}_${anio}_${nombreAbreviado}_L_${grupoStr}`;
|
||||
const id = `${version}_${anio}_${nombreAbreviado}_L_${grupoStr}`
|
||||
|
||||
if (!(horaCompleta in obj)) {
|
||||
obj[horaCompleta] = {};
|
||||
obj[horaCompleta] = {}
|
||||
}
|
||||
|
||||
if (!(dia in obj[horaCompleta])) {
|
||||
obj[horaCompleta][dia] = [];
|
||||
obj[horaCompleta][dia] = []
|
||||
}
|
||||
|
||||
obj[horaCompleta][dia].push({
|
||||
@ -147,14 +146,14 @@ const procesarAnio = (data: Cursos, anio: string, version: number, setCursosUsua
|
||||
datosGrupo: grupo,
|
||||
fnSeleccionar: () => {
|
||||
/// @ts-ignore
|
||||
setCursosUsuarios("cursos", indiceCurso, "Laboratorio", grupoStr, "seleccionado", x => !x);
|
||||
}
|
||||
});
|
||||
setCursosUsuarios("cursos", indiceCurso, "Laboratorio", grupoStr, "seleccionado", (x) => !x)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
return obj
|
||||
}
|
||||
|
||||
interface Props {
|
||||
@ -167,35 +166,40 @@ interface Props {
|
||||
}
|
||||
|
||||
export function Tabla(props: Props) {
|
||||
const anio = () => props.anio.substring(0, props.anio.indexOf(" "));
|
||||
const data = createMemo(() => procesarAnio(props.data, anio(), props.version, props.setCursosUsuarios));
|
||||
const idHover = props.idHover;
|
||||
const setIdHover = props.setIdHover;
|
||||
const anio = () => props.anio.substring(0, props.anio.indexOf(" "))
|
||||
const data = createMemo(() => procesarAnio(props.data, anio(), props.version, props.setCursosUsuarios))
|
||||
const idHover = props.idHover
|
||||
const setIdHover = props.setIdHover
|
||||
|
||||
const celdas = createMemo(() => {
|
||||
// Hace reaccionar a la reactividad de Solid
|
||||
props.data;
|
||||
return <For each={horas}>
|
||||
{hora => {
|
||||
return <FilaTabla data={data()}
|
||||
hora={hora}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
/>
|
||||
}}
|
||||
</For>
|
||||
});
|
||||
|
||||
return <div>
|
||||
<div className={css(e.fila)}>
|
||||
<For each={dias}>
|
||||
{dia =>
|
||||
<div className={css(e.celdaComun, estilosGlobales.inlineBlock, e.celdaDia)}>
|
||||
{dia}
|
||||
</div>
|
||||
}
|
||||
props.data
|
||||
return (
|
||||
<For each={horas}>
|
||||
{(hora) => (
|
||||
<FilaTabla
|
||||
data={data()}
|
||||
hora={hora}
|
||||
idHover={idHover}
|
||||
setIdHover={setIdHover}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={css(e.fila)}>
|
||||
<For each={dias}>
|
||||
{(dia) => (
|
||||
<div className={css(e.celdaComun, estilosGlobales.inlineBlock, e.celdaDia)}>
|
||||
{dia}
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
{celdas()}
|
||||
</div>
|
||||
{celdas()}
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../Estilos";
|
||||
import { For, createSignal, createMemo, createEffect, SetStateFunction } from "solid-js";
|
||||
import { Dia } from "../../Store";
|
||||
import { DatosGrupo, ListaCursosUsuario } from "../../types/DatosHorario";
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { estilosGlobales } from "../../Estilos"
|
||||
import { For, createSignal, createMemo, createEffect, SetStateFunction } from "solid-js"
|
||||
import { Dia } from "../../Store"
|
||||
import { DatosGrupo, ListaCursosUsuario } from "../../types/DatosHorario"
|
||||
|
||||
const e = StyleSheet.create({
|
||||
celdaComun: {
|
||||
@ -10,7 +10,7 @@ const e = StyleSheet.create({
|
||||
textAlign: "center",
|
||||
padding: "0 0.7rem",
|
||||
boxSizing: "border-box",
|
||||
userSelect: "none"
|
||||
userSelect: "none",
|
||||
},
|
||||
celdaCurso: {
|
||||
display: "inline-block",
|
||||
@ -23,39 +23,42 @@ const e = StyleSheet.create({
|
||||
// color: "#151515"
|
||||
},
|
||||
celdaCursoTeoria: {
|
||||
fontWeight: "bold"
|
||||
fontWeight: "bold",
|
||||
},
|
||||
celdaCursoLab: {
|
||||
fontStyle: "italic"
|
||||
}
|
||||
});
|
||||
fontStyle: "italic",
|
||||
},
|
||||
celdaSeleccionada: {
|
||||
textDecoration: "underline",
|
||||
},
|
||||
})
|
||||
|
||||
const eColores = StyleSheet.create({
|
||||
lunes: {
|
||||
backgroundColor: "rgba(33,150,243,1)"
|
||||
backgroundColor: "rgba(33,150,243,1)",
|
||||
},
|
||||
martes: {
|
||||
backgroundColor: "rgba(255,214,0 ,1)",
|
||||
color: "#151515"
|
||||
color: "#151515",
|
||||
},
|
||||
miercoles: {
|
||||
backgroundColor: "rgba(236,64,122 ,1)"
|
||||
backgroundColor: "rgba(236,64,122 ,1)",
|
||||
},
|
||||
jueves: {
|
||||
backgroundColor: "rgba(29,233,182 ,1)",
|
||||
color: "#151515"
|
||||
color: "#151515",
|
||||
},
|
||||
viernes: {
|
||||
backgroundColor: "rgba(244,67,54,1)"
|
||||
}
|
||||
});
|
||||
backgroundColor: "rgba(244,67,54,1)",
|
||||
},
|
||||
})
|
||||
|
||||
const clasesColores = {
|
||||
Lunes: css(eColores.lunes),
|
||||
Martes: css(eColores.martes),
|
||||
Miercoles: css(eColores.miercoles),
|
||||
Jueves: css(eColores.jueves),
|
||||
Viernes: css(eColores.viernes)
|
||||
Viernes: css(eColores.viernes),
|
||||
}
|
||||
|
||||
interface Props {
|
||||
@ -79,64 +82,68 @@ interface Props {
|
||||
setIdHover: (v: string) => string,
|
||||
fnResaltarFila: () => void,
|
||||
fnDesresaltarFila: () => void,
|
||||
dia: Dia
|
||||
dia: Dia,
|
||||
}
|
||||
|
||||
const claseSeldaSeleccionada = css(e.celdaSeleccionada)
|
||||
|
||||
export function CeldaFila(props: Props) {
|
||||
const datos = props.datos;
|
||||
const idHover = props.idHover;
|
||||
const setIdHover = props.setIdHover;
|
||||
const datos = props.datos
|
||||
const idHover = props.idHover
|
||||
const setIdHover = props.setIdHover
|
||||
|
||||
const fnOnMouseEnter = (id: string) => setIdHover(id);
|
||||
const fnOnMouseLeave = () => setIdHover("");
|
||||
const fnOnMouseEnter = (id: string) => setIdHover(id)
|
||||
const fnOnMouseLeave = () => setIdHover("")
|
||||
|
||||
return <div className={css(e.celdaComun, estilosGlobales.inlineBlock)}>
|
||||
<For each={datos}>
|
||||
{datos => {
|
||||
const id = datos.id;
|
||||
const txt = datos.txt;
|
||||
const esLab = datos.esLab;
|
||||
const fnSeleccionar = datos.fnSeleccionar;
|
||||
return (
|
||||
<div className={css(e.celdaComun, estilosGlobales.inlineBlock)}>
|
||||
<For each={datos}>
|
||||
{(datos) => {
|
||||
const id = datos.id
|
||||
const txt = datos.txt
|
||||
const esLab = datos.esLab
|
||||
const fnSeleccionar = datos.fnSeleccionar
|
||||
|
||||
const [estabaResaltado, setEstabaResaltado] = createSignal(false);
|
||||
const [estabaResaltado, setEstabaResaltado] = createSignal(false)
|
||||
|
||||
const estaSeleccionado = createMemo(() => {
|
||||
return datos.datosGrupo.seleccionado;
|
||||
});
|
||||
const estaSeleccionado = createMemo(() => datos.datosGrupo.seleccionado)
|
||||
|
||||
const clases = createMemo(
|
||||
() => {
|
||||
const clases = [
|
||||
e.celdaCurso,
|
||||
esLab ? e.celdaCursoLab : e.celdaCursoTeoria,
|
||||
estaSeleccionado() && estilosGlobales.contenedorCursorActivo
|
||||
];
|
||||
let adicional = "";
|
||||
const idHoverS = idHover();
|
||||
if (idHoverS !== "" && id.search(idHoverS) !== -1) {
|
||||
props.fnResaltarFila();
|
||||
clases.push(e.celdaCursoActiva);
|
||||
adicional = clasesColores[props.dia];
|
||||
const clases = createMemo(
|
||||
() => {
|
||||
const clases = [
|
||||
e.celdaCurso,
|
||||
esLab ? e.celdaCursoLab : e.celdaCursoTeoria,
|
||||
estaSeleccionado() && e.celdaSeleccionada,
|
||||
]
|
||||
let adicional = ""
|
||||
const idHoverS = idHover()
|
||||
if (idHoverS !== "" && id.search(idHoverS) !== -1) {
|
||||
props.fnResaltarFila()
|
||||
clases.push(e.celdaCursoActiva)
|
||||
adicional = clasesColores[props.dia]
|
||||
|
||||
setEstabaResaltado(true);
|
||||
} else if (estabaResaltado()) {
|
||||
props.fnDesresaltarFila();
|
||||
setEstabaResaltado(false);
|
||||
}
|
||||
return css(...clases) + " " + adicional;
|
||||
},
|
||||
undefined,
|
||||
(x, y) => x === y
|
||||
);
|
||||
setEstabaResaltado(true)
|
||||
} else if (estabaResaltado()) {
|
||||
props.fnDesresaltarFila()
|
||||
setEstabaResaltado(false)
|
||||
}
|
||||
return `${css(...clases)} ${adicional}`
|
||||
},
|
||||
undefined,
|
||||
(x, y) => x === y,
|
||||
)
|
||||
|
||||
return <span className={clases()}
|
||||
onMouseEnter={() => fnOnMouseEnter(id)}
|
||||
onMouseLeave={fnOnMouseLeave}
|
||||
onClick={fnSeleccionar}
|
||||
>
|
||||
{txt}
|
||||
</span>;
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
return (
|
||||
<span className={clases()}
|
||||
onMouseEnter={() => fnOnMouseEnter(id)}
|
||||
onMouseLeave={fnOnMouseLeave}
|
||||
onClick={fnSeleccionar}
|
||||
>
|
||||
{txt}
|
||||
</span>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { estilosGlobales } from "../../Estilos";
|
||||
import { For, createSignal, createMemo, createState, createEffect, State, SetStateFunction } from "solid-js";
|
||||
import { Dia, dias } from "../../Store";
|
||||
import { CeldaFila } from "./CeldaFila";
|
||||
import { DataProcesada, ListaCursosUsuario } from "../../types/DatosHorario";
|
||||
import { coloresBorde, diaANum } from "../Tabla";
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { estilosGlobales } from "../../Estilos"
|
||||
import { For, createSignal, createMemo, createState, createEffect, State, SetStateFunction } from "solid-js"
|
||||
import { Dia, dias } from "../../Store"
|
||||
import { CeldaFila } from "./CeldaFila"
|
||||
import { DataProcesada, ListaCursosUsuario } from "../../types/DatosHorario"
|
||||
import { coloresBorde, diaANum } from "../Tabla"
|
||||
|
||||
const e = StyleSheet.create({
|
||||
celdaHora: {
|
||||
@ -12,13 +12,13 @@ const e = StyleSheet.create({
|
||||
width: "3rem",
|
||||
padding: "0.25rem 0",
|
||||
position: "absolute",
|
||||
top: "-0.75rem"
|
||||
top: "-0.75rem",
|
||||
},
|
||||
filaResaltado: {
|
||||
position: "absolute",
|
||||
zIndex: -1,
|
||||
height: "100%",
|
||||
transform: "translateX(-1.5rem)"
|
||||
transform: "translateX(-1.5rem)",
|
||||
},
|
||||
fila: {
|
||||
position: "relative",
|
||||
@ -30,7 +30,7 @@ const e = StyleSheet.create({
|
||||
minHeight: "1.2rem",
|
||||
":hover": {
|
||||
// backgroundColor: "rgba(200, 200, 200, 0.25)"
|
||||
}
|
||||
},
|
||||
},
|
||||
filaBorde: {
|
||||
position: "absolute",
|
||||
@ -38,17 +38,17 @@ const e = StyleSheet.create({
|
||||
height: "1px",
|
||||
width: "100%",
|
||||
backgroundColor: "rgba(200, 200, 200, 0.25)",
|
||||
zIndex: -1
|
||||
zIndex: -1,
|
||||
},
|
||||
celdaResaltado: {
|
||||
height: "101%",
|
||||
width: "5px",
|
||||
display: "inline-block"
|
||||
display: "inline-block",
|
||||
},
|
||||
celdaResaltadoTransparente: {
|
||||
backgroundColor: "transparent"
|
||||
}
|
||||
});
|
||||
backgroundColor: "transparent",
|
||||
},
|
||||
})
|
||||
|
||||
const [diasResaltados, setDiasResaltados] = createState({
|
||||
Lunes: 0,
|
||||
@ -56,7 +56,7 @@ const [diasResaltados, setDiasResaltados] = createState({
|
||||
Miercoles: 0,
|
||||
Jueves: 0,
|
||||
Viernes: 0,
|
||||
} as { [k: string]: number });
|
||||
} as { [k: string]: number })
|
||||
|
||||
interface Props {
|
||||
hora: string,
|
||||
@ -65,12 +65,10 @@ interface Props {
|
||||
setIdHover: (v: string) => string
|
||||
}
|
||||
|
||||
const diasFilter = createMemo(() => {
|
||||
return Object.entries(diasResaltados)
|
||||
.filter(x => x[1] > 0)
|
||||
.map(x => x[0] as Dia)
|
||||
.sort((x, y) => diaANum(x) > diaANum(y) ? 1 : -1);
|
||||
});
|
||||
const diasFilter = createMemo(() => Object.entries(diasResaltados)
|
||||
.filter((x) => x[1] > 0)
|
||||
.map((x) => x[0] as Dia)
|
||||
.sort((x, y) => (diaANum(x) > diaANum(y) ? 1 : -1)))
|
||||
|
||||
const useDiasResaltados: () => [
|
||||
State<{ [k: string]: boolean }>,
|
||||
@ -83,64 +81,76 @@ const useDiasResaltados: () => [
|
||||
Miercoles: false,
|
||||
Jueves: false,
|
||||
Viernes: false,
|
||||
} as { [k: string]: boolean });
|
||||
} as { [k: string]: boolean })
|
||||
|
||||
const fnResaltar = (d: Dia) => {
|
||||
setDiasResaltadosLocal(d, true);
|
||||
setDiasResaltados(d, v => v + 1);
|
||||
};
|
||||
setDiasResaltadosLocal(d, true)
|
||||
setDiasResaltados(d, (v) => v + 1)
|
||||
}
|
||||
|
||||
const fnDesresaltar = (d: Dia) => {
|
||||
setDiasResaltadosLocal(d, false);
|
||||
setDiasResaltados(d, v => v - 1);
|
||||
};
|
||||
setDiasResaltadosLocal(d, false)
|
||||
setDiasResaltados(d, (v) => v - 1)
|
||||
}
|
||||
|
||||
return [diasResaltadosLocal, fnResaltar, fnDesresaltar];
|
||||
};
|
||||
return [diasResaltadosLocal, fnResaltar, fnDesresaltar]
|
||||
}
|
||||
|
||||
export function FilaTabla(props: Props) {
|
||||
const [diasResaltadosLocal, fnResaltar, fnDesresaltar] = useDiasResaltados();
|
||||
const [diasResaltadosLocal, fnResaltar, fnDesresaltar] = useDiasResaltados()
|
||||
|
||||
const hora = props.hora;
|
||||
const data = props.data;
|
||||
const hora = props.hora
|
||||
const data = props.data
|
||||
|
||||
return <div style={{position: "relative"}}>
|
||||
<div className={css(e.celdaHora, estilosGlobales.inlineBlock)}>
|
||||
{hora.substring(0, 5)}
|
||||
</div>
|
||||
<div className={css(e.fila)}>
|
||||
<div className={css(estilosGlobales.inlineBlock, e.filaResaltado)}>
|
||||
<div className={css(e.celdaResaltado, diasResaltadosLocal.Lunes ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[0]}}/>
|
||||
<div className={css(e.celdaResaltado, diasResaltadosLocal.Martes ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[1]}}/>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Miercoles ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[2]}}/>
|
||||
<div className={css(e.celdaResaltado, diasResaltadosLocal.Jueves ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[3]}}/>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Viernes ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[4]}}/>
|
||||
return (
|
||||
<div style={{position: "relative"}}>
|
||||
<div className={css(e.celdaHora, estilosGlobales.inlineBlock)}>
|
||||
{hora.substring(0, 5)}
|
||||
</div>
|
||||
<For each={dias}>
|
||||
{dia => {
|
||||
const diaStr = dia.substring(0, 2);
|
||||
const horaStr = hora.substring(0, 5);
|
||||
|
||||
const datos = data?.[horaStr]?.[diaStr] ?? [];
|
||||
|
||||
return <CeldaFila
|
||||
datos={datos}
|
||||
idHover={props.idHover}
|
||||
setIdHover={props.setIdHover}
|
||||
fnResaltarFila={() => fnResaltar(dia)}
|
||||
fnDesresaltarFila={() => fnDesresaltar(dia)}
|
||||
dia={dia}
|
||||
<div className={css(e.fila)}>
|
||||
<div className={css(estilosGlobales.inlineBlock, e.filaResaltado)}>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Lunes ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[0]}}
|
||||
/>
|
||||
}}
|
||||
</For>
|
||||
<div className={css(e.filaBorde)}/>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Martes ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[1]}}
|
||||
/>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Miercoles ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[2]}}
|
||||
/>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Jueves ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[3]}}
|
||||
/>
|
||||
<div
|
||||
className={css(e.celdaResaltado, diasResaltadosLocal.Viernes ? null : e.celdaResaltadoTransparente)}
|
||||
style={{"background-color": coloresBorde[4]}}
|
||||
/>
|
||||
</div>
|
||||
<For each={dias}>
|
||||
{(dia) => {
|
||||
const diaStr = dia.substring(0, 2)
|
||||
const horaStr = hora.substring(0, 5)
|
||||
|
||||
const datos = data?.[horaStr]?.[diaStr] ?? []
|
||||
|
||||
return (
|
||||
<CeldaFila
|
||||
datos={datos}
|
||||
idHover={props.idHover}
|
||||
setIdHover={props.setIdHover}
|
||||
fnResaltarFila={() => fnResaltar(dia)}
|
||||
fnDesresaltarFila={() => fnDesresaltar(dia)}
|
||||
dia={dia}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
<div className={css(e.filaBorde)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
)
|
||||
}
|
70
src/ContenedorHorarios/TablaObserver.ts
Normal file
70
src/ContenedorHorarios/TablaObserver.ts
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* - Normal
|
||||
* - Oculto - Otro grupo seleccionado
|
||||
* - Seleccionado - Cursor ensima
|
||||
* - Resaltado - Grupo seleccionado
|
||||
* - ResaltadoSeleccionado - Grupo seleccionado y cursor encima
|
||||
* - ResaltadoOculto - Otro grupo seleccionado y cursor encima
|
||||
*/
|
||||
import { createMemo, createState, SetStateFunction, State } from "solid-js";
|
||||
|
||||
type EstadoCelda =
|
||||
| "Normal"
|
||||
| "Oculto"
|
||||
| "Seleccionado"
|
||||
| "Resaltado"
|
||||
| "ResaltadoSeleccionado"
|
||||
| "ResaltadoOculto"
|
||||
|
||||
interface Datos {
|
||||
anio?: string,
|
||||
curso?: string,
|
||||
esLab?: boolean,
|
||||
grupo?: string
|
||||
}
|
||||
|
||||
export class TablaObserver {
|
||||
|
||||
private readonly resaltado: State<Datos>
|
||||
private readonly setResaltado: SetStateFunction<Datos>
|
||||
private gruposSeleccionados = {}
|
||||
|
||||
constructor() {
|
||||
const [resaltado, setResaltado] = createState<Datos>({
|
||||
anio: undefined,
|
||||
curso: undefined,
|
||||
esLab: undefined,
|
||||
grupo: undefined
|
||||
});
|
||||
this.resaltado = resaltado;
|
||||
this.setResaltado = setResaltado;
|
||||
}
|
||||
|
||||
// Cada celda se registra dando estos datos
|
||||
// Devuelve un memo con un valor de EstadoCelda,
|
||||
// el cual cada celda sabra como manejar
|
||||
registrar(anio: string, cursoAbreviado: string, esLab: boolean, grupo: string) {
|
||||
const fn = () => {
|
||||
|
||||
};
|
||||
|
||||
const memo = createMemo(
|
||||
fn,
|
||||
undefined,
|
||||
(x, y) => x === y
|
||||
);
|
||||
}
|
||||
|
||||
resaltar(id: string) {
|
||||
|
||||
}
|
||||
|
||||
quitarResaltado() {
|
||||
this.setResaltado({
|
||||
anio: undefined,
|
||||
curso: undefined,
|
||||
esLab: undefined,
|
||||
grupo: undefined
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { createState, SetStateFunction, State } from "solid-js";
|
||||
import { Curso, ListaCursosUsuario } from "../types/DatosHorario";
|
||||
import { createState, SetStateFunction, State } from "solid-js"
|
||||
import { Curso, ListaCursosUsuario } from "../types/DatosHorario"
|
||||
|
||||
interface ReturnType {
|
||||
listaCursos: State<ListaCursosUsuario>,
|
||||
@ -11,31 +11,31 @@ interface ReturnType {
|
||||
export const useListaCursos = (): ReturnType => {
|
||||
const [listaCursos, setListaCursos] = createState<ListaCursosUsuario>({
|
||||
sigIndice: 0,
|
||||
cursos: []
|
||||
});
|
||||
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
|
||||
};
|
||||
};
|
||||
eliminarCursosDeLista,
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
|
||||
const e = StyleSheet.create({
|
||||
creditos: {
|
||||
textAlign: "center",
|
||||
paddingTop: "7.5rem",
|
||||
paddingBottom: "1rem"
|
||||
}
|
||||
});
|
||||
paddingBottom: "1rem",
|
||||
},
|
||||
})
|
||||
|
||||
export function Creditos() {
|
||||
return <div className={css(e.creditos)}>
|
||||
Desarrollado por Fernando Araoz con TypeScript, JSX y Solid.js.
|
||||
</div>
|
||||
return (
|
||||
<div className={css(e.creditos)}>
|
||||
Desarrollado por Fernando Araoz con TypeScript, JSX y Solid.js.
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import {StyleSheet} from "aphrodite";
|
||||
import {StyleSheet} from "aphrodite"
|
||||
|
||||
export const estilosGlobales = StyleSheet.create({
|
||||
contenedor: {
|
||||
@ -7,7 +7,7 @@ export const estilosGlobales = StyleSheet.create({
|
||||
borderRadius: "10px",
|
||||
backdropFilter: "blur(40px)",
|
||||
backgroundColor: "rgba(100, 100, 100, 0.25)",
|
||||
color: "var(--color-texto)"
|
||||
color: "var(--color-texto)",
|
||||
},
|
||||
contenedorCursor: {
|
||||
cursor: "pointer",
|
||||
@ -15,27 +15,27 @@ export const estilosGlobales = StyleSheet.create({
|
||||
transition: "background-color 200ms",
|
||||
textDecoration: "underline solid white 2px",
|
||||
":hover": {
|
||||
backgroundColor: "rgba(200, 200, 200, 0.3)"
|
||||
}
|
||||
backgroundColor: "rgba(200, 200, 200, 0.3)",
|
||||
},
|
||||
},
|
||||
contenedorCursorSoft: {
|
||||
textDecoration: "underline rgba(255, 255, 255, 0.4)"
|
||||
textDecoration: "underline rgba(255, 255, 255, 0.4)",
|
||||
},
|
||||
contenedorCursorActivo: {
|
||||
backgroundColor: "rgba(200, 200, 200, 0.3)"
|
||||
backgroundColor: "rgba(200, 200, 200, 0.3)",
|
||||
},
|
||||
contenedorPhospor: {
|
||||
padding: "0.5rem 0.65rem",
|
||||
transform: "translateY(0.2rem)"
|
||||
transform: "translateY(0.2rem)",
|
||||
},
|
||||
inlineBlock: {
|
||||
display: "inline-block"
|
||||
display: "inline-block",
|
||||
},
|
||||
botonPhospor: {
|
||||
"::before": {
|
||||
fontSize: "1.25rem",
|
||||
// transform: "translateY(0.2rem)",
|
||||
textDecoration: "underline rgba(255, 255, 255, 0.4)",
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
|
20
src/Store.ts
20
src/Store.ts
@ -1,4 +1,4 @@
|
||||
import { createSignal, createEffect } from "solid-js";
|
||||
import { createSignal} from "solid-js"
|
||||
|
||||
enum ModoColor {
|
||||
Claro,
|
||||
@ -8,7 +8,7 @@ enum ModoColor {
|
||||
|
||||
export type Dia = "Lunes" | "Martes" | "Miercoles" | "Jueves" | "Viernes";
|
||||
|
||||
export const dias: Dia[] = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes"];
|
||||
export const dias: Dia[] = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes"]
|
||||
export const horas = [
|
||||
"07:00 - 07:50",
|
||||
"07:50 - 08:40",
|
||||
@ -30,17 +30,17 @@ export const horas = [
|
||||
"18:30 - 19:20",
|
||||
"19:20 - 20:10",
|
||||
"20:10 - 21:00",
|
||||
"21:00 - 21:00"
|
||||
];
|
||||
"21:00 - 21:00",
|
||||
]
|
||||
export const horasDescanso = [
|
||||
"08:40 - 08:50",
|
||||
"10:30 - 10:40",
|
||||
"15:40 - 15:50",
|
||||
"17:30 - 17:40"
|
||||
];
|
||||
"17:30 - 17:40",
|
||||
]
|
||||
|
||||
const numImgGuardado = parseInt(localStorage.getItem("num-img") ?? "3");
|
||||
const numImgGuardado = Number(localStorage.getItem("num-img") ?? "3")
|
||||
|
||||
export const [modoColor, setModoColor] = createSignal(ModoColor.Oscuro);
|
||||
export const [numWallpaper, setNumWallpaper] = createSignal(numImgGuardado);
|
||||
export const [mostrarDescansos, setMostrarDescansos] = createSignal(true);
|
||||
export const [modoColor, setModoColor] = createSignal(ModoColor.Oscuro)
|
||||
export const [numWallpaper, setNumWallpaper] = createSignal(numImgGuardado)
|
||||
export const [mostrarDescansos, setMostrarDescansos] = createSignal(true)
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { StyleSheet, css } from "aphrodite";
|
||||
import { numWallpaper } from "./Store";
|
||||
import { createEffect, createState } from "solid-js";
|
||||
import { StyleSheet, css } from "aphrodite"
|
||||
import { numWallpaper } from "./Store"
|
||||
import { createEffect, createState } from "solid-js"
|
||||
|
||||
const duracionTransicion = 250;
|
||||
const duracionTransicion = 250
|
||||
|
||||
export function Wallpaper() {
|
||||
/// @ts-ignore
|
||||
const soportaBackdropFilter = document.body.style.backdropFilter !== undefined;
|
||||
const soportaBackdropFilter = document.body.style.backdropFilter !== undefined
|
||||
|
||||
const estilos = StyleSheet.create({
|
||||
contenedorCover: {
|
||||
@ -16,7 +16,7 @@ export function Wallpaper() {
|
||||
top: "0",
|
||||
left: "0",
|
||||
backgroundColor: "#212121",
|
||||
zIndex: -1
|
||||
zIndex: -1,
|
||||
},
|
||||
cover: {
|
||||
width: "100vw",
|
||||
@ -25,43 +25,45 @@ export function Wallpaper() {
|
||||
backgroundSize: "cover",
|
||||
zIndex: -1,
|
||||
transition: `opacity ${duracionTransicion}ms`,
|
||||
filter: soportaBackdropFilter? "": "blur(40px)"
|
||||
filter: soportaBackdropFilter ? "" : "blur(40px)",
|
||||
},
|
||||
coverTransicion: {
|
||||
opacity: 0
|
||||
}
|
||||
});
|
||||
opacity: 0,
|
||||
},
|
||||
})
|
||||
|
||||
const [estilosRaw, setEstilosRaw] = createState({
|
||||
"background-image": `none`,
|
||||
opacity: 1
|
||||
});
|
||||
"background-image": "none",
|
||||
opacity: 1,
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
const numImg = numWallpaper();
|
||||
setEstilosRaw("opacity", 0);
|
||||
const numImg = numWallpaper()
|
||||
setEstilosRaw("opacity", 0)
|
||||
|
||||
const promesa250ms = new Promise(resolve => {
|
||||
setTimeout(resolve, duracionTransicion);
|
||||
});
|
||||
const promesa250ms = new Promise((resolve) => {
|
||||
setTimeout(resolve, duracionTransicion)
|
||||
})
|
||||
|
||||
const url = `/img/wall${numImg}.webp`;
|
||||
const img = new Image();
|
||||
img.addEventListener("load", async () => {
|
||||
await promesa250ms;
|
||||
const url = `/img/wall${numImg}.webp`
|
||||
const img = new Image()
|
||||
img.addEventListener("load", async() => {
|
||||
await promesa250ms
|
||||
setEstilosRaw({
|
||||
"background-image": `url('${url}')`,
|
||||
opacity: 1
|
||||
});
|
||||
});
|
||||
img.src = url;
|
||||
});
|
||||
opacity: 1,
|
||||
})
|
||||
})
|
||||
img.src = url
|
||||
})
|
||||
|
||||
return <div className={css(estilos.contenedorCover)}>
|
||||
<div
|
||||
className={css(estilos.cover)}
|
||||
style={{"background-image": estilosRaw["background-image"], opacity: estilosRaw.opacity}}
|
||||
/>
|
||||
</div>
|
||||
return (
|
||||
<div className={css(estilos.contenedorCover)}>
|
||||
<div
|
||||
className={css(estilos.cover)}
|
||||
style={{"background-image": estilosRaw["background-image"], opacity: estilosRaw.opacity}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import "solid-js";
|
||||
import { render } from 'solid-js/web';
|
||||
import App from './App';
|
||||
import "normalize.css";
|
||||
import "./styles/global.css";
|
||||
import "solid-js"
|
||||
import { render } from "solid-js/web"
|
||||
import App from "./App"
|
||||
import "normalize.css"
|
||||
import "./styles/global.css"
|
||||
|
||||
render(App, document.getElementById('root') as Node);
|
||||
render(App, document.getElementById("root") as Node)
|
||||
|
Loading…
Reference in New Issue
Block a user