Deploy Ladill Transfer / deploy (push) Successful in 41s
Remove desktop header search, wire mobile search to the transfers and files page, refine file icons and Shared badge, and align Transfers toolbar with Files. Co-authored-by: Cursor <cursoragent@cursor.com>
143 lines
9.1 KiB
PHP
143 lines
9.1 KiB
PHP
@php
|
|
$user = auth()->user();
|
|
$initials = collect(explode(' ', trim((string) $user?->name)))
|
|
->filter()
|
|
->take(2)
|
|
->map(fn ($part) => strtoupper(substr($part, 0, 1)))
|
|
->implode('');
|
|
@endphp
|
|
|
|
<header class="flex h-16 items-center justify-between border-b border-slate-200 bg-white px-6">
|
|
<div class="flex min-w-0 flex-1 items-center gap-3">
|
|
<button @click="sidebarOpen = !sidebarOpen" class="shrink-0 text-slate-500 hover:text-slate-700 lg:hidden">
|
|
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
|
|
</button>
|
|
@include('partials.mobile-topbar-title')
|
|
</div>
|
|
|
|
<div class="flex items-center gap-3">
|
|
@if (isset($accessibleAccounts) && $accessibleAccounts->count() > 1)
|
|
<div x-data="{ open: false }" class="relative hidden lg:block">
|
|
<button @click="open = !open" class="inline-flex items-center gap-1.5 rounded-full border border-slate-200 px-3 py-2 text-sm text-slate-700 hover:bg-slate-50">
|
|
<span class="max-w-[120px] truncate">{{ $actingAccount->name ?? $actingAccount->email }}</span>
|
|
<svg class="h-4 w-4 text-slate-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m19 9-7 7-7-7"/></svg>
|
|
</button>
|
|
<div x-show="open" x-cloak @click.outside="open = false" class="absolute right-0 z-30 mt-2 w-60 rounded-xl border border-slate-200 bg-white p-1 shadow-lg">
|
|
<p class="px-3 py-1.5 text-[10px] font-bold uppercase tracking-widest text-slate-400">Switch account</p>
|
|
@foreach ($accessibleAccounts as $acctOption)
|
|
<form method="POST" action="{{ route('account.switch') }}">
|
|
@csrf
|
|
<input type="hidden" name="account" value="{{ $acctOption->id }}">
|
|
<button type="submit" class="flex w-full items-center justify-between rounded-lg px-3 py-2 text-left text-sm hover:bg-slate-50 {{ $acctOption->id === $actingAccount->id ? 'font-semibold text-indigo-700' : 'text-slate-700' }}">
|
|
<span class="truncate">{{ $acctOption->id === auth()->id() ? 'My account' : ($acctOption->name ?? $acctOption->email) }}</span>
|
|
@if ($acctOption->id === $actingAccount->id)<span class="text-indigo-600">✓</span>@endif
|
|
</button>
|
|
</form>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="relative hidden lg:block"
|
|
x-data="notificationDropdown({
|
|
unreadUrl: {{ \Illuminate\Support\Js::from(route('notifications.unread')) }},
|
|
markReadUrl: {{ \Illuminate\Support\Js::from(route('notifications.mark-read', ['id' => '__ID__'])) }},
|
|
markAllReadUrl: {{ \Illuminate\Support\Js::from(route('notifications.mark-all-read')) }},
|
|
indexUrl: {{ \Illuminate\Support\Js::from(route('notifications.index')) }},
|
|
csrfToken: {{ \Illuminate\Support\Js::from(csrf_token()) }},
|
|
})"
|
|
@click.outside="open = false">
|
|
<button type="button"
|
|
@click="toggle()"
|
|
class="relative inline-flex items-center justify-center rounded-full border border-slate-200 p-2 text-slate-600 transition hover:bg-slate-50"
|
|
aria-label="Notifications">
|
|
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9a6 6 0 1 0-12 0v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.08 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
|
|
</svg>
|
|
<span x-show="unreadCount > 0"
|
|
x-cloak
|
|
x-text="unreadCount > 9 ? '9+' : unreadCount"
|
|
class="absolute -right-1 -top-1 inline-flex min-w-5 items-center justify-center rounded-full bg-rose-500 px-1.5 py-0.5 text-[10px] font-semibold text-white"></span>
|
|
</button>
|
|
|
|
<div x-show="open"
|
|
x-cloak
|
|
x-transition
|
|
class="absolute right-0 z-50 mt-2 w-80 origin-top-right rounded-xl border border-slate-200 bg-white shadow-lg">
|
|
<div class="flex items-center justify-between border-b border-slate-100 px-4 py-3">
|
|
<h3 class="text-sm font-semibold text-slate-900">Notifications</h3>
|
|
<button type="button"
|
|
x-show="unreadCount > 0"
|
|
@click="markAllRead()"
|
|
class="text-xs font-medium text-indigo-600 hover:text-indigo-700">
|
|
Mark all read
|
|
</button>
|
|
</div>
|
|
|
|
<div class="max-h-80 overflow-y-auto">
|
|
<template x-if="loading">
|
|
<div class="px-4 py-6 text-center text-xs text-slate-400">Loading…</div>
|
|
</template>
|
|
<template x-if="!loading && notifications.length === 0">
|
|
<div class="px-4 py-8 text-center text-sm text-slate-500">No notifications yet</div>
|
|
</template>
|
|
<template x-if="!loading && notifications.length > 0">
|
|
<div class="divide-y divide-slate-100">
|
|
<template x-for="notification in notifications" :key="notification.id">
|
|
<a :href="notification.url || '#'"
|
|
@click="markRead(notification.id)"
|
|
class="flex items-start gap-3 px-4 py-3 transition hover:bg-slate-50">
|
|
<div class="min-w-0 flex-1">
|
|
<p class="truncate text-sm font-medium text-slate-900" x-text="notification.title"></p>
|
|
<p class="line-clamp-2 text-xs text-slate-500" x-text="notification.message"></p>
|
|
<p class="mt-1 text-[11px] text-slate-400" x-text="notification.created_at"></p>
|
|
</div>
|
|
</a>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<div class="border-t border-slate-100 px-4 py-2.5">
|
|
<a :href="indexUrl" class="block text-center text-xs font-medium text-slate-600 hover:text-slate-900">
|
|
View all notifications
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="relative hidden lg:block" x-data="{ profileOpen: false }" @click.outside="profileOpen = false">
|
|
<button type="button"
|
|
@click="profileOpen = !profileOpen"
|
|
class="inline-flex items-center gap-2 rounded-full border border-slate-200 px-2 py-1.5 text-slate-700 hover:bg-slate-50">
|
|
@if ($user?->avatarUrl())
|
|
<img src="{{ $user->avatarUrl() }}" alt="Avatar" class="h-8 w-8 rounded-full object-cover ring-1 ring-slate-200">
|
|
@else
|
|
<span class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-slate-900 text-xs font-semibold text-white">
|
|
{{ $initials !== '' ? $initials : 'U' }}
|
|
</span>
|
|
@endif
|
|
<svg class="h-4 w-4 text-slate-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m19 9-7 7-7-7" />
|
|
</svg>
|
|
</button>
|
|
|
|
<div x-show="profileOpen" x-cloak x-transition @click.outside="profileOpen = false"
|
|
class="absolute right-0 z-20 mt-2 w-48 rounded-xl border border-slate-200 bg-white p-1 shadow-lg">
|
|
<a href="{{ route('account.settings') }}" class="block rounded-lg px-3 py-2 text-sm text-slate-700 hover:bg-slate-100">Settings</a>
|
|
<a href="{{ ladill_account_url('account-settings') }}" class="block rounded-lg px-3 py-2 text-sm text-slate-700 hover:bg-slate-100">Account Settings</a>
|
|
<a href="{{ route('transfer.dashboard') }}" class="block rounded-lg px-3 py-2 text-sm text-slate-700 hover:bg-slate-100">Dashboard</a>
|
|
<form method="POST" action="{{ route('logout') }}">
|
|
@csrf
|
|
<button type="submit" class="w-full rounded-lg px-3 py-2 text-left text-sm text-rose-600 hover:bg-rose-50">Logout</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@auth
|
|
@include('partials.afia-button', ['compact' => true])
|
|
@endauth
|
|
|
|
@include('partials.launcher')
|
|
</div>
|
|
</header>
|