feat: sustituir header móvil por tabbar y añadir logout en móvil

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
webui
brobert 2 weeks ago
parent ff7197a15c
commit 2184eb277c

@ -1,6 +1,13 @@
<script lang="ts">
import { page } from '$app/stores';
import Toast from '$lib/ui/feedback/Toast.svelte';
$: pathname = $page.url.pathname;
$: currentTitle =
pathname === '/app' ? 'Tareas' :
pathname.startsWith('/app/groups') ? 'Grupos' :
pathname.startsWith('/app/preferences') ? 'Recordatorios' :
pathname.startsWith('/app/integrations') ? 'Calendarios' :
'Tareas';
</script>
<header class="app-header">
@ -18,6 +25,11 @@
</div>
</header>
<!-- Barra superior móvil (solo título) -->
<div class="mobile-topbar" aria-hidden="true">
<div class="container topbar-inner">{currentTitle}</div>
</div>
<svelte:head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</svelte:head>
@ -43,6 +55,12 @@
<span class="icon">📅</span>
<span class="label">Calendarios</span>
</a>
<form method="POST" action="/api/logout" class="logout-tab" aria-label="Salir">
<button type="submit">
<span class="icon">🚪</span>
<span class="label">Salir</span>
</button>
</form>
</nav>
<Toast />
@ -123,6 +141,11 @@
padding-bottom: var(--space-4);
}
/* Barra superior móvil oculta por defecto */
.mobile-topbar {
display: none;
}
/* Barra de pestañas inferior (solo móvil) */
.tabbar {
position: fixed;
@ -139,10 +162,11 @@
@media (max-width: 768px) {
.tabbar {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(5, 1fr);
align-items: center;
}
.tabbar a {
.tabbar a,
.tabbar button {
display: inline-flex;
align-items: center;
justify-content: center;
@ -150,6 +174,15 @@
padding: 6px 8px;
color: inherit;
text-decoration: none;
background: transparent;
border: none;
}
.tabbar form.logout-tab {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 0;
}
.tabbar a.active {
color: var(--color-primary);
@ -163,8 +196,9 @@
font-size: 12px;
line-height: 1;
}
/* Reservar espacio en el main para no tapar contenido */
/* Reservar espacio en el main para no tapar contenido y la barra superior */
.main {
padding-top: calc(var(--space-4) + 44px + env(safe-area-inset-top));
padding-bottom: calc(var(--space-4) + 48px + env(safe-area-inset-bottom));
}
}
@ -173,4 +207,25 @@
display: none;
}
}
/* Ocultar header y mostrar topbar en móvil */
@media (max-width: 768px) {
.app-header { display: none; }
.mobile-topbar {
display: block;
position: sticky;
top: 0;
z-index: 12;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
min-height: 44px;
padding-top: env(safe-area-inset-top);
}
.mobile-topbar .topbar-inner {
display: flex;
align-items: center;
min-height: 44px;
font-weight: 600;
}
}
</style>

@ -12,26 +12,36 @@
{#if dev}
<div
class="dev-banner"
role="status"
aria-live="polite"
style="
position: fixed;
bottom: 8px;
left: 8px;
right: 8px;
margin: 0 auto;
max-width: 960px;
background: rgba(255, 221, 87, 0.95);
color: #111;
border: 1px solid rgba(0,0,0,0.15);
border-radius: 6px;
padding: 8px 12px;
font-size: 13px;
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
z-index: 9999;
">
aria-live="polite">
Modo desarrollo: auth bypass activo
</div>
{/if}
<slot />
<style>
.dev-banner {
position: fixed;
left: 8px;
right: 8px;
margin: 0 auto;
max-width: 960px;
background: rgba(255, 221, 87, 0.95);
color: #111;
border: 1px solid rgba(0,0,0,0.15);
border-radius: 6px;
padding: 8px 12px;
font-size: 13px;
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
z-index: 9999;
bottom: 8px;
}
@media (max-width: 768px) {
.dev-banner {
top: 8px;
bottom: auto;
}
}
</style>

Loading…
Cancel
Save