You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.0 KiB
125 lines
3.0 KiB
<!--
|
|
Bottom-tab navigation for the product surface (Discover, Matches,
|
|
Profile, Safety, plus a logout). Pages opt-in by mounting it; the
|
|
operator-style header is rendered by the layout only on
|
|
admin/devtools, so this is the regular user's only cross-section
|
|
nav.
|
|
|
|
Bottom-fixed on mobile, sticky on desktop. Tab labels stay short
|
|
so the bar is finger-sized on phones.
|
|
-->
|
|
<script lang="ts">
|
|
import { page } from '$app/state';
|
|
import { goto } from '$app/navigation';
|
|
import { getNexoContext } from '../_lib/context';
|
|
|
|
const nexo = getNexoContext();
|
|
|
|
const items = [
|
|
{ href: '/dating/discover', label: 'Descubre', icon: '✦' },
|
|
{ href: '/dating/matches', label: 'Matches', icon: '♡' },
|
|
{ href: '/dating/profile', label: 'Perfil', icon: '◔' },
|
|
{ href: '/dating/safety', label: 'Seguridad', icon: '⚐' }
|
|
] as const;
|
|
|
|
function isCurrent(href: string): boolean {
|
|
return page.url.pathname === href || page.url.pathname.startsWith(`${href}/`);
|
|
}
|
|
|
|
async function logout() {
|
|
try {
|
|
await nexo.api.logout();
|
|
} finally {
|
|
nexo.setSession({ authenticated: false });
|
|
await goto('/dating/login', { replaceState: true });
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<nav class="appnav" aria-label="Nexo">
|
|
<ul>
|
|
{#each items as item (item.href)}
|
|
<li>
|
|
<a href={item.href} aria-current={isCurrent(item.href) ? 'page' : undefined}>
|
|
<span class="icon" aria-hidden="true">{item.icon}</span>
|
|
<span class="label">{item.label}</span>
|
|
</a>
|
|
</li>
|
|
{/each}
|
|
<li class="spacer" aria-hidden="true"></li>
|
|
<li>
|
|
<button type="button" class="logout" onclick={logout}>
|
|
<span class="icon" aria-hidden="true">⏻</span>
|
|
<span class="label">Salir</span>
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<style>
|
|
.appnav {
|
|
position: sticky;
|
|
bottom: 0;
|
|
z-index: 20;
|
|
margin: 1.5rem -1rem -1rem;
|
|
background: color-mix(in srgb, canvas 92%, currentColor 8%);
|
|
border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
|
|
}
|
|
.appnav ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0.4rem 0.6rem;
|
|
display: flex;
|
|
gap: 0.15rem;
|
|
max-width: 40rem;
|
|
margin-inline: auto;
|
|
}
|
|
.spacer {
|
|
flex: 1;
|
|
}
|
|
.appnav a,
|
|
.appnav button {
|
|
font: inherit;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
background: transparent;
|
|
border: none;
|
|
cursor: pointer;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 0.1rem;
|
|
padding: 0.45rem 0.7rem;
|
|
border-radius: 8px;
|
|
font-size: 0.78rem;
|
|
min-width: 3.6rem;
|
|
}
|
|
.appnav a[aria-current='page'] {
|
|
background: color-mix(in srgb, currentColor 10%, transparent);
|
|
font-weight: 600;
|
|
}
|
|
.appnav .icon {
|
|
font-size: 1.1rem;
|
|
line-height: 1;
|
|
}
|
|
.appnav .logout {
|
|
opacity: 0.7;
|
|
}
|
|
.appnav .logout:hover {
|
|
opacity: 1;
|
|
}
|
|
@media (min-width: 800px) {
|
|
.appnav {
|
|
position: static;
|
|
margin: 1.5rem 0 0;
|
|
border-top: none;
|
|
border: 1px solid color-mix(in srgb, currentColor 10%, transparent);
|
|
border-radius: 12px;
|
|
background: color-mix(in srgb, canvas 96%, currentColor 4%);
|
|
}
|
|
.appnav ul {
|
|
padding: 0.4rem 0.5rem;
|
|
}
|
|
}
|
|
</style>
|