Compare commits
4 Commits
a96fa20ac0
...
2948743625
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2948743625 | ||
|
|
9bc96e6f41 | ||
|
|
2ae617797c | ||
|
|
d036b2119a |
BIN
frontend/public/open-bokeron-logo.png
Normal file
BIN
frontend/public/open-bokeron-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
@@ -80,12 +80,10 @@
|
|||||||
|
|
||||||
const pricesInterval = setInterval(fetchPrices, 8000);
|
const pricesInterval = setInterval(fetchPrices, 8000);
|
||||||
const ciInterval = setInterval(fetchCiStatus, 10000);
|
const ciInterval = setInterval(fetchCiStatus, 10000);
|
||||||
const historyInterval = setInterval(fetchBuildHistory, 15000);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(pricesInterval);
|
clearInterval(pricesInterval);
|
||||||
clearInterval(ciInterval);
|
clearInterval(ciInterval);
|
||||||
clearInterval(historyInterval);
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -101,8 +99,8 @@
|
|||||||
está inspirada en la de nuestra querida escuela.
|
está inspirada en la de nuestra querida escuela.
|
||||||
</p>
|
</p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button on:click={() => fetchMenu()} class="ghost">Refrescar menú</button>
|
<button on:click={() => fetchMenu()}>Refrescar menú</button>
|
||||||
<button on:click={() => fetchPrices()}>Recalcular desayunos</button>
|
<button on:click={() => fetchPrices()} class="ghost">Recalcular desayunos</button>
|
||||||
</div>
|
</div>
|
||||||
<p class="meta">
|
<p class="meta">
|
||||||
Backend: {API_BASE} · Endpoints: /menu · /prices · /prices/:item · /health
|
Backend: {API_BASE} · Endpoints: /menu · /prices · /prices/:item · /health
|
||||||
@@ -257,11 +255,42 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="card">
|
||||||
|
<div class="card-head">
|
||||||
|
<div class="label">Desayunos</div>
|
||||||
|
{#if loadingPrices}
|
||||||
|
<span class="tag">cargando...</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if prices.length}
|
||||||
|
<div class="price-grid">
|
||||||
|
{#each prices as price}
|
||||||
|
<div class="price-card">
|
||||||
|
<p class="item">{prettify(price.item)}</p>
|
||||||
|
<p class="value">{price.price} €</p>
|
||||||
|
<p class="timestamp">{price.generated_at}</p>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<p class="meta">
|
||||||
|
Dependiendo de si vas por la mañana o por la tarde los precios cambian. No sé,
|
||||||
|
como no ponen los precios al público... :p
|
||||||
|
</p>
|
||||||
|
{:else if !loadingPrices}
|
||||||
|
<p>No hay precios que mostrar.</p>
|
||||||
|
{/if}
|
||||||
|
</article>
|
||||||
|
|
||||||
<article class="card ci-card">
|
<article class="card ci-card">
|
||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div>
|
<div>
|
||||||
<p class="label">Estado del sistema</p>
|
<p class="label">Estado del sistema</p>
|
||||||
<p class="sub">Información de build y backend</p>
|
<p class="sub">
|
||||||
|
Información de build y backend. Tanto el Build, Commit y Autor lo
|
||||||
|
recuperamos gracias a Jenkins, inyectando ciertas variables a la hora de
|
||||||
|
hacer despliegue del backend.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{#if loadingCiStatus}
|
{#if loadingCiStatus}
|
||||||
<span class="tag">comprobando...</span>
|
<span class="tag">comprobando...</span>
|
||||||
@@ -311,7 +340,11 @@
|
|||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div>
|
<div>
|
||||||
<p class="label">Historial</p>
|
<p class="label">Historial</p>
|
||||||
<p class="sub">Builds recientes en Jenkins</p>
|
<p class="sub">
|
||||||
|
Builds recientes en Jenkins. Esto lo conseguimos gracias a que Jenkins nos
|
||||||
|
expone una API REST muy maja para consultar información de los jobs y
|
||||||
|
builds.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{#if loadingHistory}
|
{#if loadingHistory}
|
||||||
<span class="tag">actualizando...</span>
|
<span class="tag">actualizando...</span>
|
||||||
@@ -365,31 +398,60 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="card">
|
<article class="card openbokeron-card">
|
||||||
<div class="card-head">
|
<div class="card-head">
|
||||||
<div class="label">Desayunos</div>
|
<div>
|
||||||
{#if loadingPrices}
|
<p class="label">Open Bokeron</p>
|
||||||
<span class="tag">cargando...</span>
|
<p class="sub">Quiénes estamos detrás del taller</p>
|
||||||
{/if}
|
</div>
|
||||||
|
<a
|
||||||
|
class="tag link-tag"
|
||||||
|
href="https://openbokeron.org"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
openbokeron.org
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if prices.length}
|
<div class="openbokeron-body">
|
||||||
<div class="price-grid">
|
<div class="openbokeron-copy">
|
||||||
{#each prices as price}
|
<p class="openbokeron-text">
|
||||||
<div class="price-card">
|
Somos Open Bokeron, la asociación de software libre de la ETSII.
|
||||||
<p class="item">{prettify(price.item)}</p>
|
|
||||||
<p class="value">{price.price} €</p>
|
|
||||||
<p class="timestamp">{price.generated_at}</p>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
<p class="meta">
|
|
||||||
Dependiendo de si vas por la mañana o por la tarde los precios cambian. No sé,
|
|
||||||
como no ponen los precios al público... :p
|
|
||||||
</p>
|
</p>
|
||||||
{:else if !loadingPrices}
|
|
||||||
<p>No hay precios que mostrar.</p>
|
<p class="openbokeron-text subtle">
|
||||||
{/if}
|
Este tinglado lo hemos montado nosotros, así que sí: esta tarjeta se queda
|
||||||
|
todo el taller
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul class="openbokeron-list">
|
||||||
|
<li>Usamos Linux y te juzgamos severamente si vienes con Windows.</li>
|
||||||
|
<li>A veces hacemos cosas. #HazCosas dicen por aquí en la ETSII.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="openbokeron-actions">
|
||||||
|
<a
|
||||||
|
class="button-link subtle"
|
||||||
|
href="https://openbokeron.org"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Conócenos
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="openbokeron-logo">
|
||||||
|
<div class="logo-bubble">
|
||||||
|
<img
|
||||||
|
src="/open-bokeron-logo.png"
|
||||||
|
alt="Logo de Open Bokeron"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -184,6 +184,23 @@ button.outline {
|
|||||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.openbokeron-card {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 12% 18%, rgba(34, 211, 238, 0.22), transparent 26%),
|
||||||
|
radial-gradient(circle at 85% -5%, rgba(124, 58, 237, 0.2), transparent 28%),
|
||||||
|
linear-gradient(180deg, #0b1224, #0e1530);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-card::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.02), transparent 55%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.card-head {
|
.card-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -211,6 +228,21 @@ button.outline {
|
|||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag.link-tag {
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid rgba(165, 180, 252, 0.4);
|
||||||
|
transition:
|
||||||
|
border-color 120ms ease,
|
||||||
|
color 120ms ease,
|
||||||
|
background 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag.link-tag:hover {
|
||||||
|
border-color: rgba(165, 180, 252, 0.8);
|
||||||
|
background: rgba(165, 180, 252, 0.16);
|
||||||
|
color: #c7d2fe;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-grid {
|
.menu-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
@@ -368,6 +400,109 @@ li {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.openbokeron-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1.4fr) minmax(180px, 0.6fr);
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-copy {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-copy > * + * {
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-text {
|
||||||
|
margin: 0;
|
||||||
|
color: #e2e8f0;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-text.subtle {
|
||||||
|
opacity: 0.75;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-list {
|
||||||
|
margin: 0.2rem 0 0;
|
||||||
|
padding-left: 1.1rem;
|
||||||
|
color: #cbd5f5;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
opacity: 0.85;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.6rem;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
background: linear-gradient(120deg, #22d3ee, #38bdf8);
|
||||||
|
color: #0b1224;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 800;
|
||||||
|
padding: 0.65rem 1rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 12px 26px rgba(34, 211, 238, 0.25);
|
||||||
|
transition:
|
||||||
|
transform 120ms ease,
|
||||||
|
box-shadow 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-link:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 14px 28px rgba(56, 189, 248, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-link.subtle {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
color: #e2e8f0;
|
||||||
|
box-shadow: none;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-link.subtle:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-bubble {
|
||||||
|
min-height: 120px;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px dashed rgba(148, 163, 184, 0.35);
|
||||||
|
background: rgba(255, 255, 255, 0.04);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-bubble img {
|
||||||
|
max-width: 120px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
.price-grid {
|
.price-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
@@ -455,6 +590,16 @@ li {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 780px) {
|
||||||
|
.openbokeron-body {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openbokeron-actions {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 980px) {
|
@media (min-width: 980px) {
|
||||||
.menu-card {
|
.menu-card {
|
||||||
grid-column: span 2;
|
grid-column: span 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user