feat(sidebar): accordeon unique strict, Plus/Moins, scroll au survol
CI / build-and-test (push) Failing after 8m17s

This commit is contained in:
2026-09-26 11:20:54 -04:00
parent 49c3b5dfdf
commit 1b0a7eb3ce
4 changed files with 272 additions and 137 deletions
+168 -135
View File
@@ -1,4 +1,4 @@
<nav class="h-full w-full bg-slate-900 md:bg-transparent text-slate-200 p-3 md:p-0 overflow-y-auto">
<nav tabindex="0" class="sidebar-scroll h-full w-full bg-slate-900 md:bg-transparent text-slate-200 p-3 md:p-0">
<div class="space-y-6">
<!-- Brand (small only) -->
<div class="md:hidden flex items-center gap-2 px-3 py-2">
@@ -6,7 +6,7 @@
<span class="text-xl font-bold">NewTube</span>
</div>
<!-- Main -->
<!-- Main : toujours visible, hors accordeon -->
<div>
<ul class="space-y-1">
<li>
@@ -33,161 +33,194 @@
<!-- Vous -->
@if (isLoggedIn()) {
<div>
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400" [class.hidden]="collapsed">{{ 'nav.you' | t }}</div>
<ul class="space-y-1">
<li>
<a routerLink="/library/subscriptions" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.subscriptions' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zm0 2v12h16V6H4zm3 3h10v2H7V9zm0 4h7v2H7v-2z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.subscriptions' | t }}</span>
</a>
</li>
<li>
<a routerLink="/account/history" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.history' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 8a1 1 0 0 1 1 1v3.38l2.32 1.34a1 1 0 1 1-1 1.74l-2.82-1.63A1 1 0 0 1 11 13V9a1 1 0 0 1 1-1zm0-6a10 10 0 1 0 10 10 10.011 10.011 0 0 0-10-10z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.history' | t }}</span>
</a>
</li>
<li>
<a routerLink="/library/liked" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.liked' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 21s-6.716-4.248-9.193-6.725A6 6 0 0 1 12 5.414 6 6 0 0 1 21.193 14.275C18.716 16.752 12 21 12 21z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.liked' | t }}</span>
</a>
</li>
<li>
<a routerLink="/library/downloads" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.downloads' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.17l3.59-3.58L17 11l-5 5-5-5 1.41-1.41L12 13.17V3h0zm-7 15h14v2H5v-2z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.downloads' | t }}</span>
</a>
</li>
</ul>
<button type="button" (click)="toggleSection('you')" [attr.aria-expanded]="isOpen('you')" aria-controls="sidebar-section-you" class="flex w-full items-center justify-between px-3 py-2 text-xs uppercase tracking-wide text-slate-400 hover:text-slate-200 transition" [class.hidden]="collapsed">
<span>{{ 'nav.you' | t }}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform" [class.rotate-180]="isOpen('you')" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 10l5 5 5-5z"/></svg>
</button>
<div id="sidebar-section-you" [hidden]="!collapsed && !isOpen('you')">
<ul class="space-y-1">
<li>
<a routerLink="/library/subscriptions" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.subscriptions' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2zm0 2v12h16V6H4zm3 3h10v2H7V9zm0 4h7v2H7v-2z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.subscriptions' | t }}</span>
</a>
</li>
<li>
<a routerLink="/account/history" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.history' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 8a1 1 0 0 1 1 1v3.38l2.32 1.34a1 1 0 1 1-1 1.74l-2.82-1.63A1 1 0 0 1 11 13V9a1 1 0 0 1 1-1zm0-6a10 10 0 1 0 10 10 10.011 10.011 0 0 0-10-10z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.history' | t }}</span>
</a>
</li>
<li>
<a routerLink="/library/liked" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.liked' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 21s-6.716-4.248-9.193-6.725A6 6 0 0 1 12 5.414 6 6 0 0 1 21.193 14.275C18.716 16.752 12 21 12 21z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.liked' | t }}</span>
</a>
</li>
<li>
<a routerLink="/library/downloads" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.downloads' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.17l3.59-3.58L17 11l-5 5-5-5 1.41-1.41L12 13.17V3h0zm-7 15h14v2H5v-2z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.downloads' | t }}</span>
</a>
</li>
</ul>
</div>
</div>
<!-- Groupes d'abonnements (façon PocketTube) -->
<div *ngIf="!collapsed && subscriptionGroups().length > 0">
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400">{{ 'nav.groups' | t : 'Groupes' }}</div>
<ul class="space-y-1">
<li *ngFor="let group of subscriptionGroups()">
<a [routerLink]="['/library/subscriptions']" [queryParams]="{ group: group.id, tab: 'channels' }" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition gap-3">
<span class="flex h-6 w-6 items-center justify-center rounded text-base" [style.background-color]="group.color + '26'">{{ group.icon }}</span>
<span class="flex-1 truncate text-sm">{{ group.name }}</span>
<span class="text-xs text-slate-500">{{ group.channelCount }}</span>
</a>
</li>
</ul>
<button type="button" (click)="toggleSection('groups')" [attr.aria-expanded]="isOpen('groups')" aria-controls="sidebar-section-groups" class="flex w-full items-center justify-between px-3 py-2 text-xs uppercase tracking-wide text-slate-400 hover:text-slate-200 transition">
<span>{{ 'nav.groups' | t }} <span class="text-slate-500">({{ subscriptionGroups().length }})</span></span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform" [class.rotate-180]="isOpen('groups')" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 10l5 5 5-5z"/></svg>
</button>
<div id="sidebar-section-groups" [hidden]="!isOpen('groups')">
<ul class="space-y-1">
<li *ngFor="let group of displayedGroups()">
<a [routerLink]="['/library/subscriptions']" [queryParams]="{ group: group.id, tab: 'channels' }" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition gap-3">
<span class="flex h-6 w-6 items-center justify-center rounded text-base" [style.background-color]="group.color + '26'">{{ group.icon }}</span>
<span class="flex-1 truncate text-sm">{{ group.name }}</span>
<span class="text-xs text-slate-500">{{ group.channelCount }}</span>
</a>
</li>
</ul>
<button *ngIf="subscriptionGroups().length > 5" type="button" class="flex items-center gap-2 px-3 py-2 text-sm text-slate-300 hover:text-white" (click)="toggleGroups()">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 transition-transform" [class.rotate-180]="showAllGroups()" viewBox="0 0 24 24" fill="currentColor"><path d="M7 10l5 5 5-5z"/></svg>
<span>{{ showAllGroups() ? ('common.less' | t) : ('common.more' | t) }}</span>
</button>
</div>
</div>
}
<!-- Fournisseurs -->
<div>
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400" [class.hidden]="collapsed">Fournisseurs</div>
<ul class="space-y-1">
<!-- All providers except PeerTube (order handled in TS so PT is last) -->
<ng-container *ngFor="let p of providersList()">
<li *ngIf="p.id !== 'peertube'">
<a [routerLink]="['/p', p.id, 't', 'trending']" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? (p.label) : null">
<span class="h-6 w-6 flex items-center justify-center">
<ng-container [ngSwitch]="p.id">
<!-- YouTube -->
<svg *ngSwitchCase="'youtube'" class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<rect x="3" y="6" width="18" height="12" rx="3" class="text-red-600" fill="currentColor"/>
<polygon points="10,9 16,12 10,15" fill="white"/>
</svg>
<!-- Dailymotion -->
<svg *ngSwitchCase="'dailymotion'" class="h-5 w-5 text-blue-500" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="11,8 16,12 11,16" fill="white"/>
</svg>
<!-- Twitch -->
<svg *ngSwitchCase="'twitch'" class="h-5 w-5 text-purple-500" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M4 3h16v11l-4 4h-3l-2 2H9v-2H6V3zm3 2v9h6l2-2h3V5H7z" fill="currentColor"/>
</svg>
<!-- Rumble -->
<svg *ngSwitchCase="'rumble'" class="h-5 w-5 text-green-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="10,8 16,12 10,16" fill="white"/>
</svg>
<!-- Odysee -->
<svg *ngSwitchCase="'odysee'" class="h-5 w-5 text-pink-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<circle cx="12" cy="12" r="5" fill="white"/>
</svg>
<!-- Fallback generic play icon -->
<svg *ngSwitchDefault class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<polygon points="9,7 17,12 9,17" fill="currentColor"/>
</svg>
</ng-container>
</span>
<span [class.hidden]="collapsed">{{ p.label }}</span>
</a>
</li>
</ng-container>
<button type="button" (click)="toggleSection('providers')" [attr.aria-expanded]="isOpen('providers')" aria-controls="sidebar-section-providers" class="flex w-full items-center justify-between px-3 py-2 text-xs uppercase tracking-wide text-slate-400 hover:text-slate-200 transition" [class.hidden]="collapsed">
<span>{{ 'nav.providers' | t }} <span class="text-slate-500">({{ providersList().length }})</span></span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform" [class.rotate-180]="isOpen('providers')" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 10l5 5 5-5z"/></svg>
</button>
<div id="sidebar-section-providers" [hidden]="!collapsed && !isOpen('providers')">
<ul class="space-y-1">
<!-- All providers except PeerTube (order handled in TS so PT is last) -->
<ng-container *ngFor="let p of providersList()">
<li *ngIf="p.id !== 'peertube'">
<a [routerLink]="['/p', p.id, 't', 'trending']" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? (p.label) : null">
<span class="h-6 w-6 flex items-center justify-center">
<ng-container [ngSwitch]="p.id">
<!-- YouTube -->
<svg *ngSwitchCase="'youtube'" class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<rect x="3" y="6" width="18" height="12" rx="3" class="text-red-600" fill="currentColor"/>
<polygon points="10,9 16,12 10,15" fill="white"/>
</svg>
<!-- Dailymotion -->
<svg *ngSwitchCase="'dailymotion'" class="h-5 w-5 text-blue-500" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="11,8 16,12 11,16" fill="white"/>
</svg>
<!-- Twitch -->
<svg *ngSwitchCase="'twitch'" class="h-5 w-5 text-purple-500" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M4 3h16v11l-4 4h-3l-2 2H9v-2H6V3zm3 2v9h6l2-2h3V5H7z" fill="currentColor"/>
</svg>
<!-- Rumble -->
<svg *ngSwitchCase="'rumble'" class="h-5 w-5 text-green-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="10,8 16,12 10,16" fill="white"/>
</svg>
<!-- Odysee -->
<svg *ngSwitchCase="'odysee'" class="h-5 w-5 text-pink-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<circle cx="12" cy="12" r="5" fill="white"/>
</svg>
<!-- Fallback generic play icon -->
<svg *ngSwitchDefault class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<polygon points="9,7 17,12 9,17" fill="currentColor"/>
</svg>
</ng-container>
</span>
<span [class.hidden]="collapsed">{{ p.label }}</span>
</a>
</li>
</ng-container>
<!-- PeerTube group with instances as sub-items -->
<ng-container *ngFor="let p of providersList()">
<li [ngClass]="{ 'mt-2': true }" *ngIf="p.id === 'peertube'">
<a [routerLink]="['/p', 'peertube', 't', 'trending']" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? (p.label) : null">
<span class="h-6 w-6 flex items-center justify-center">
<!-- PeerTube logo style (orange play) -->
<svg class="h-5 w-5 text-orange-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="10,8 16,12 10,16" fill="white"/>
</svg>
</span>
<span [class.hidden]="collapsed">{{ p.label }}</span>
</a>
<!-- Sub-list of instances (visible when not collapsed) -->
<ul class="ml-8 mt-1 space-y-1" [class.hidden]="collapsed">
<li *ngFor="let inst of peerTubeInstances()">
<a [routerLink]="['/p', 'peertube', 't', 'trending']"
(click)="$event.preventDefault(); selectPeerTubeInstance(inst)"
class="flex items-center px-3 py-1.5 rounded hover:bg-slate-800 transition gap-2">
<svg class="h-4 w-4 text-orange-500" viewBox="0 0 24 24" aria-hidden="true">
<!-- PeerTube group with instances as sub-items -->
<ng-container *ngFor="let p of providersList()">
<li [ngClass]="{ 'mt-2': true }" *ngIf="p.id === 'peertube'">
<a [routerLink]="['/p', 'peertube', 't', 'trending']" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? (p.label) : null">
<span class="h-6 w-6 flex items-center justify-center">
<!-- PeerTube logo style (orange play) -->
<svg class="h-5 w-5 text-orange-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="10,8 16,12 10,16" fill="white"/>
</svg>
<span class="text-xs" [ngClass]="{ 'text-sky-400': inst === activePeerTubeInstance(), 'text-slate-300': inst !== activePeerTubeInstance() }">{{ inst }}</span>
</a>
</li>
</ul>
</li>
</ng-container>
</ul>
</span>
<span [class.hidden]="collapsed">{{ p.label }}</span>
</a>
<!-- Sub-list of instances (visible when not collapsed) -->
<ul class="ml-8 mt-1 space-y-1" [class.hidden]="collapsed">
<li *ngFor="let inst of displayedInstances()">
<a [routerLink]="['/p', 'peertube', 't', 'trending']"
(click)="$event.preventDefault(); selectPeerTubeInstance(inst)"
class="flex items-center px-3 py-1.5 rounded hover:bg-slate-800 transition gap-2">
<svg class="h-4 w-4 text-orange-500" viewBox="0 0 24 24" aria-hidden="true">
<circle cx="12" cy="12" r="10" fill="currentColor"/>
<polygon points="10,8 16,12 10,16" fill="white"/>
</svg>
<span class="text-xs" [ngClass]="{ 'text-sky-400': inst === activePeerTubeInstance(), 'text-slate-300': inst !== activePeerTubeInstance() }">{{ inst }}</span>
</a>
</li>
</ul>
<button *ngIf="!collapsed && peerTubeInstances().length > 3" type="button" class="ml-8 flex items-center gap-2 px-3 py-2 text-sm text-slate-300 hover:text-white" (click)="toggleInstances()">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 transition-transform" [class.rotate-180]="showAllInstances()" viewBox="0 0 24 24" fill="currentColor"><path d="M7 10l5 5 5-5z"/></svg>
<span>{{ showAllInstances() ? ('common.less' | t) : ('common.more' | t) }}</span>
</button>
</li>
</ng-container>
</ul>
</div>
</div>
<!-- Explorer (themes list with more/less) -->
<div>
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400" [class.hidden]="collapsed">{{ 'nav.explore' | t }}</div>
<ul class="space-y-1">
<li *ngFor="let t of displayedThemes()">
<a [routerLink]="['/t', t.slug]" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? (t.label) : null">
<span class="h-6 w-6 flex items-center justify-center text-lg">{{ t.emoji }}</span>
<span [class.hidden]="collapsed">{{ t.label }}</span>
</a>
</li>
</ul>
<button class="flex items-center gap-2 px-3 py-2 text-sm text-slate-300 hover:text-white" (click)="toggleThemes()" [class.hidden]="collapsed">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor"><path d="M12 5l7 7-7 7-1.41-1.41L15.17 13H5v-2h10.17l-4.58-4.59L12 5z"/></svg>
<span>{{ showAllThemes() ? ('common.less' | t) : ('common.more' | t) }}</span>
<button type="button" (click)="toggleSection('explore')" [attr.aria-expanded]="isOpen('explore')" aria-controls="sidebar-section-explore" class="flex w-full items-center justify-between px-3 py-2 text-xs uppercase tracking-wide text-slate-400 hover:text-slate-200 transition" [class.hidden]="collapsed">
<span>{{ 'nav.explore' | t }} <span class="text-slate-500">({{ themes.themes().length }})</span></span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform" [class.rotate-180]="isOpen('explore')" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 10l5 5 5-5z"/></svg>
</button>
<div id="sidebar-section-explore" [hidden]="!collapsed && !isOpen('explore')">
<ul class="space-y-1">
<li *ngFor="let t of displayedThemes()">
<a [routerLink]="['/t', t.slug]" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? (t.label) : null">
<span class="h-6 w-6 flex items-center justify-center text-lg">{{ t.emoji }}</span>
<span [class.hidden]="collapsed">{{ t.label }}</span>
</a>
</li>
</ul>
<button type="button" class="flex items-center gap-2 px-3 py-2 text-sm text-slate-300 hover:text-white" (click)="toggleThemes()" [class.hidden]="collapsed">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 transition-transform" [class.rotate-180]="showAllThemes()" viewBox="0 0 24 24" fill="currentColor"><path d="M7 10l5 5 5-5z"/></svg>
<span>{{ showAllThemes() ? ('common.less' | t) : ('common.more' | t) }}</span>
</button>
</div>
</div>
<!-- Informations -->
<div>
<div class="px-3 py-2 text-xs uppercase tracking-wide text-slate-400" [class.hidden]="collapsed">{{ 'nav.info' | t : 'Informations' }}</div>
<ul class="space-y-1">
<li>
<a routerLink="/info/utilisation" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.usage' | t : 'Utilisation') : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2zm1 15h-2v-6h2zm0-8h-2V7h2z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.usage' | t : 'Utilisation' }}</span>
</a>
</li>
<li>
<a href="https://git.dracodev.net/Projets/NewTube" target="_blank" rel="noopener noreferrer" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? 'Gitea' : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2zm1 14.59V20h-2v-3.41a4.994 4.994 0 0 1-4-4.9V7h2v4.69A3 3 0 0 0 12 14a3 3 0 0 0 3-2.31V7h2v4.69a4.994 4.994 0 0 1-4 4.9z"/></svg>
<span [class.hidden]="collapsed">Gitea</span>
</a>
</li>
</ul>
<button type="button" (click)="toggleSection('info')" [attr.aria-expanded]="isOpen('info')" aria-controls="sidebar-section-info" class="flex w-full items-center justify-between px-3 py-2 text-xs uppercase tracking-wide text-slate-400 hover:text-slate-200 transition" [class.hidden]="collapsed">
<span>{{ 'nav.info' | t }}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 transition-transform" [class.rotate-180]="isOpen('info')" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M7 10l5 5 5-5z"/></svg>
</button>
<div id="sidebar-section-info" [hidden]="!collapsed && !isOpen('info')">
<ul class="space-y-1">
<li>
<a routerLink="/info/utilisation" routerLinkActive="bg-slate-800" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? ('nav.usage' | t) : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2zm1 15h-2v-6h2zm0-8h-2V7h2z"/></svg>
<span [class.hidden]="collapsed">{{ 'nav.usage' | t }}</span>
</a>
</li>
<li>
<a href="https://git.dracodev.net/Projets/NewTube" target="_blank" rel="noopener noreferrer" class="flex items-center px-3 py-2 rounded hover:bg-slate-800 transition" [ngClass]="{ 'gap-0 justify-center': collapsed, 'gap-3': !collapsed }" [attr.title]="collapsed ? 'Gitea' : null">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2zm1 14.59V20h-2v-3.41a4.994 4.994 0 0 1-4-4.9V7h2v4.69A3 3 0 0 0 12 14a3 3 0 0 0 3-2.31V7h2v4.69a4.994 4.994 0 0 1-4 4.9z"/></svg>
<span [class.hidden]="collapsed">Gitea</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</nav>