import { computed, type Component } from 'vue'; import { useRoute, type RouteLocationRaw } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { Boxes, Coffee, GitBranch, LifeBuoy, Settings, TerminalSquare } from '@lucide/vue'; import { useSessionsStore } from '../stores/sessions'; import GiteaIcon from '../components/ui/GiteaIcon.vue'; import { BUYMEACOFFEE_URL, REPO_SOURCE_URL } from '../lib/constants'; export interface NavEntry { key: string; /** route interne (exclusif avec `href`). */ to?: RouteLocationRaw; /** lien externe ouvert dans un nouvel onglet (exclusif avec `to`). */ href?: string; icon: Component; label: string; match: string[]; // noms de routes considérés actifs pour cet item badge: number; } /** Définition unique de la navigation, partagée par la sidebar et la barre d'onglets. */ export function useNav() { const { t } = useI18n(); const route = useRoute(); const sessions = useSessionsStore(); // sessions vivantes bloquées sur un dialogue (le cœur de la supervision mobile). const waitingCount = computed( () => sessions.sessions.filter((s) => s.live && s.activity === 'waiting').length, ); // Onglets principaux : barre du bas mobile + haut de sidebar. const primary = computed(() => [ { key: 'worktrees', to: { name: 'dashboard' }, icon: GitBranch, label: t('nav.worktrees'), match: ['dashboard'], badge: 0 }, { key: 'sessions', to: { name: 'sessions' }, icon: TerminalSquare, label: t('nav.sessions'), match: ['sessions', 'session'], badge: waitingCount.value }, { key: 'groups', to: { name: 'groups' }, icon: Boxes, label: t('nav.groups'), match: ['groups', 'group'], badge: 0 }, ]); // Onglets secondaires : réglages, aide, et lien externe « Code source » (en dur, toujours présent). const secondary = computed(() => [ { key: 'settings', to: { name: 'settings' }, icon: Settings, label: t('nav.settings'), match: ['settings'], badge: 0 }, { key: 'help', to: { name: 'help' }, icon: LifeBuoy, label: t('nav.help'), match: ['help'], badge: 0 }, { key: 'gitea', href: REPO_SOURCE_URL, icon: GiteaIcon, label: t('nav.gitea'), match: [], badge: 0 }, { key: 'buymeacoffee', href: BUYMEACOFFEE_URL, icon: Coffee, label: t('nav.buymeacoffee'), match: [], badge: 0 }, ]); const isActive = (match: string[]): boolean => match.includes(String(route.name)); return { primary, secondary, isActive, waitingCount }; }