119 lines
8.1 KiB
HTML
119 lines
8.1 KiB
HTML
|
|
<header class="bg-slate-800/50 backdrop-blur-sm fixed top-0 left-0 right-0 z-50 shadow-lg w-full border-b border-slate-700/60">
|
|
<div class="w-full px-0 py-3 grid items-center gap-4 relative grid-cols-[auto_1fr_auto]">
|
|
<!-- Left: burger + logo -->
|
|
<div class="flex items-center gap-3 shrink-0 pl-3 md:pl-4">
|
|
<button (click)="menuToggle.emit()" class="p-2 rounded-full hover:bg-slate-700 focus:outline-none" aria-label="Toggle menu">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-slate-200" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M3 6h18v2H3V6zm0 5h18v2H3v-2zm0 5h18v2H3v-2z"/>
|
|
</svg>
|
|
</button>
|
|
<a routerLink="/" class="flex items-center space-x-2 shrink-0">
|
|
<img src="images/NewTube.png" alt="" class="h-8 w-auto" />
|
|
<h1 class="text-2xl font-bold tracking-tight text-white">NewTube</h1>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Center: search box with providers -->
|
|
<div class="justify-self-center mx-auto w-full max-w-2xl md:max-w-3xl lg:max-w-4xl px-4 relative">
|
|
<app-search-box [placeholder]="('search.placeholder' | t)" (submitted)="onSearchBoxSubmit($event)"></app-search-box>
|
|
</div>
|
|
|
|
<!-- Right: user -->
|
|
<div class="justify-self-end flex items-center gap-3 pr-3 md:pr-4">
|
|
<!-- Provider context indicator placed between search and user area -->
|
|
<div *ngIf="providerContextLabel()" class="flex items-center gap-1 text-xs">
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded border shadow-sm gap-1"
|
|
[ngStyle]="getProviderColors(providerContext())">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
|
|
</svg>
|
|
<span>{{ providerContextLabel() }}</span>
|
|
</span>
|
|
</div>
|
|
<div class="h-6 w-px bg-slate-700/60 mx-2"></div>
|
|
|
|
<!-- Auth / User Menu Area -->
|
|
<div *ngIf="!user(); else userMenu" class="flex items-center gap-2">
|
|
<a routerLink="/auth/login" class="px-3 py-1 rounded bg-slate-700 hover:bg-slate-600 text-white">{{ 'btn.login' | t }}</a>
|
|
<a routerLink="/auth/register" class="px-3 py-1 rounded bg-red-600 hover:bg-red-500 text-white">{{ 'btn.register' | t }}</a>
|
|
</div>
|
|
<ng-template #userMenu>
|
|
<div class="relative" #userMenuContainer>
|
|
<!-- Avatar Button -->
|
|
<button (click)="toggleUserMenu()" class="flex items-center gap-2 p-1 rounded-full hover:bg-slate-700">
|
|
<div class="h-8 w-8 rounded-full flex items-center justify-center text-sm font-semibold border"
|
|
[ngClass]="{
|
|
'bg-slate-200 text-slate-800 border-slate-300': isLightTheme(),
|
|
'bg-slate-600 text-white border-slate-500': isDarkTheme(),
|
|
'bg-slate-800 text-slate-200 border-slate-700': isBlackTheme(),
|
|
'bg-blue-900 text-blue-100 border-blue-800': isBlueTheme()
|
|
}">
|
|
{{ (user()?.username || user()?.email || 'U') | slice:0:1 | uppercase }}
|
|
</div>
|
|
</button>
|
|
<!-- Dropdown Menu -->
|
|
@if (userMenuOpen()) {
|
|
<div class="absolute right-0 mt-2 w-64 bg-slate-900 border border-slate-700 rounded-xl shadow-xl overflow-hidden z-50">
|
|
<div class="px-4 py-3 border-b border-slate-700">
|
|
<div class="font-semibold text-slate-100">{{ user()?.username || user()?.email }}</div>
|
|
<div class="text-xs text-slate-400 truncate">{{ user()?.email }}</div>
|
|
</div>
|
|
<div class="py-1">
|
|
<a routerLink="/account/preferences" class="block px-4 py-2 text-sm text-slate-200 hover:bg-slate-800">{{ 'menu.preferences' | t }}</a>
|
|
<div class="px-4 py-2 text-xs uppercase tracking-wide text-slate-500">{{ 'menu.appearance' | t }}</div>
|
|
<div class="px-3 pb-2 grid grid-cols-4 gap-2">
|
|
<!-- Black -->
|
|
<button (click)="setTheme('black')"
|
|
[ngClass]="{ 'ring-2': currentTheme() === 'black', 'ring-red-500': currentTheme() === 'black' }"
|
|
class="px-2 py-2 text-xs rounded bg-slate-800 hover:bg-slate-700 flex items-center justify-center gap-1">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="9"/></svg>
|
|
<span>{{ 'theme.black' | t }}</span>
|
|
</button>
|
|
<!-- Dark -->
|
|
<button (click)="setTheme('dark')"
|
|
[ngClass]="{ 'ring-2': currentTheme() === 'dark', 'ring-red-500': currentTheme() === 'dark' }"
|
|
class="px-2 py-2 text-xs rounded bg-slate-800 hover:bg-slate-700 flex items-center justify-center gap-1">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor"><path d="M21 12.79A9 9 0 1 1 11.21 3a7 7 0 1 0 9.79 9.79Z"/></svg>
|
|
<span>{{ 'theme.dark' | t }}</span>
|
|
</button>
|
|
<!-- Blue -->
|
|
<button (click)="setTheme('blue')"
|
|
[ngClass]="{ 'ring-2': currentTheme() === 'blue', 'ring-red-500': currentTheme() === 'blue' }"
|
|
class="px-2 py-2 text-xs rounded bg-slate-800 hover:bg-slate-700 flex items-center justify-center gap-1">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2s7 7.58 7 12a7 7 0 1 1-14 0C5 9.58 12 2 12 2Z"/></svg>
|
|
<span>{{ 'theme.blue' | t }}</span>
|
|
</button>
|
|
<!-- Light -->
|
|
<button (click)="setTheme('light')"
|
|
[ngClass]="{ 'ring-2': currentTheme() === 'light', 'ring-red-500': currentTheme() === 'light' }"
|
|
class="px-2 py-2 text-xs rounded bg-slate-800 hover:bg-slate-700 flex items-center justify-center gap-1">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="currentColor"><path d="M12 18a6 6 0 1 0 0-12 6 6 0 0 0 0 12Zm0-16a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm0 18a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1Zm9-9a1 1 0 0 1 1 1h-2a1 1 0 1 1 0-2h2a1 1 0 0 1-1 1ZM4 12a1 1 0 0 1 1-1H3a1 1 0 1 1 0 2h2a1 1 0 0 1-1-1Zm12.95 6.364a1 1 0 0 1 1.414 1.414l-1.415 1.415a1 1 0 1 1-1.414-1.415l1.415-1.414ZM7.05 4.222a1 1 0 1 1 1.414-1.415L9.88 4.222A1 1 0 0 1 8.465 5.636L7.05 4.222zm9.9-1.415a1 1 0 1 1 1.414 1.415L17.95 5.636A1 1 0 0 1 16.536 4.22l1.414-1.414ZM7.05 19.778 5.636 21.19a1 1 0 0 1-1.414-1.414L5.636 18.364A1 1 0 0 1 7.05 19.78Z"/></svg>
|
|
<span>{{ 'theme.light' | t }}</span>
|
|
</button>
|
|
</div>
|
|
<button (click)="onLogout()" class="w-full text-left px-4 py-2 text-sm text-red-300 hover:bg-red-900/30">{{ 'menu.logout' | t }}</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</ng-template>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- PeerTube Instance Editor Modal -->
|
|
<div *ngIf="editingPeerTubeInstances()" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50">
|
|
<div class="bg-gray-800 rounded-lg p-6 w-full max-w-md">
|
|
<h2 class="text-xl font-bold mb-4">Edit PeerTube Instances</h2>
|
|
<p class="text-sm text-gray-400 mb-4">Enter one instance domain per line.</p>
|
|
<textarea [(ngModel)]="peerTubeInstancesInput" class="w-full h-48 bg-gray-900 text-white rounded p-2 focus:outline-none focus:ring-2 focus:ring-red-500"></textarea>
|
|
<div class="mt-4 flex justify-end gap-3">
|
|
<button (click)="editingPeerTubeInstances.set(false)" class="px-4 py-2 rounded bg-gray-600 hover:bg-gray-500">Cancel</button>
|
|
<button (click)="savePeerTubeInstances()" class="px-4 py-2 rounded bg-red-600 hover:bg-red-500">Save</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|