Réglages : préférences (langue, notifications push + test), gestion complète des tokens d'accès (liste/création/révocation, garde anti lock-out sur le dernier token), URL Gitea configurable, infos serveur en lecture seule (port/bind/origines/VAPID + flags CLI). Aide : documentation bilingue EN/FR de toutes les fonctionnalités, avec recherche. Icône Gitea (lien externe) dans la nav (sidebar + MoreSheet mobile). Backend : routes /api/v1/auth/tokens (GET/POST/DELETE) + tokenId dans /me ; routes/settings.ts (GET/PATCH, allow-list stricte gitea_url, aucun secret exposé, URL validée http/https anti-XSS) ; AuthService.listTokens/revokeToken (transaction). Front : NavItem gère les liens externes, nav primaire/secondaire, store settings, vues SettingsView/HelpView. 236 tests verts (+15 nouveaux : auth-tokens, settings-routes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.4 KiB
Vue
44 lines
1.4 KiB
Vue
<template>
|
|
<nav
|
|
class="fixed inset-x-0 bottom-0 z-40 flex border-t border-zinc-800 bg-zinc-950/95 backdrop-blur md:hidden"
|
|
style="padding-bottom: env(safe-area-inset-bottom)"
|
|
>
|
|
<NavItem
|
|
v-for="item in primary"
|
|
:key="item.key"
|
|
:to="item.to"
|
|
:icon="item.icon"
|
|
:label="item.label"
|
|
:badge="item.badge"
|
|
:active="isActive(item.match)"
|
|
orientation="col"
|
|
class="flex-1"
|
|
/>
|
|
<button
|
|
type="button"
|
|
class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500 transition-colors hover:text-zinc-300 focus-visible:outline-none"
|
|
:class="moreActive ? 'text-emerald-400' : ''"
|
|
@click="showMore = true"
|
|
>
|
|
<Menu :size="20" :stroke-width="1.75" />
|
|
<span class="text-[10px]">{{ t('nav.more') }}</span>
|
|
</button>
|
|
<MoreSheet v-if="showMore" @close="showMore = false" />
|
|
</nav>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { Menu } from '@lucide/vue';
|
|
import { useNav } from '../../composables/useNav';
|
|
import NavItem from './NavItem.vue';
|
|
import MoreSheet from './MoreSheet.vue';
|
|
|
|
const { t } = useI18n();
|
|
const { primary, secondary, isActive } = useNav();
|
|
const showMore = ref(false);
|
|
// « More » est actif quand la route courante appartient aux items secondaires (Réglages/Aide).
|
|
const moreActive = computed(() => secondary.value.some((i) => isActive(i.match)));
|
|
</script>
|