@props(['active' => 'dashboard'])
@php
// Workspace-role gate for the top nav. Mirrors the route-level
// `workspace.role:*` middleware so the UI never shows a button
// that would 403/redirect when clicked.
// - agent/viewer: Team Inbox only
// - manager: + Chat, Templates, Analytics
// - admin/owner: everything
$wsRole = auth()->user()?->workspaceRole();
$minTier = match ($wsRole) {
'owner', 'admin' => 'admin',
'manager' => 'manager',
'agent', 'viewer' => 'agent',
default => 'admin', // platform-only users with no workspace role: keep legacy view
};
$rank = ['agent' => 1, 'manager' => 2, 'admin' => 3];
$userRank = $rank[$minTier] ?? 3;
// Meta Ads (Click-to-WhatsApp Ads) is shown in ALL engine modes —
// the page collects its own Meta Marketing API credentials, so it
// no longer depends on the platform's active send engine.
$activeSendMethod = (string) \App\Models\SystemSetting::get('default_send_method', 'baileys');
$allNavItems = [
[
'key' => 'dashboard',
'tier' => 'manager',
'href' => url('/dashboard'),
'label' => __('Dashboard'),
'icon' =>
'',
'sw' => 1.6,
],
[
'key' => 'metaads',
'tier' => 'admin',
'href' => url('/meta-ads'),
'label' => __('Meta Ads'),
'icon' => '',
'sw' => 1.5,
'feature' => 'access_ctwa',
],
[
'key' => 'wa-campaigns',
'tier' => 'admin',
'href' => url('/wa-campaigns'),
'label' => __('Campaigns'),
'icon' =>
'',
'sw' => 1.5,
'feature' => 'campaign',
],
[
'key' => 'flows',
'tier' => 'admin',
'href' => url('/flows'),
'label' => __('Flows'),
'icon' =>
'',
'sw' => 1.5,
'feature' => 'autoflow',
],
[
'key' => 'templates',
'tier' => 'manager',
'href' => url('/templates'),
'label' => __('Templates'),
'icon' => '',
'sw' => 1.5,
'feature' => 'template',
],
[
'key' => 'devices',
'tier' => 'admin',
'href' => url('/devices'),
'label' => __('Devices'),
'icon' => '',
'sw' => 1.6,
],
[
'key' => 'more',
'tier' => 'admin',
'href' => url('/more'),
'label' => __('More'),
'icon' => '',
'sw' => 1.6,
],
];
$navItems = array_values(
array_filter($allNavItems, function ($it) use ($rank, $userRank, $activeSendMethod) {
$needed = $rank[$it['tier']] ?? 3;
if ($userRank < $needed) {
return false;
}
// Engine gate: items with `requires_provider` only show when
// that provider is the active platform engine.
if (!empty($it['requires_provider']) && $it['requires_provider'] !== $activeSendMethod) {
return false;
}
return true;
}),
);
@endphp
@php
// Resolve brand logo for the current user's selected theme.
// Same fallback chain as the admin sidebar.
$brandTheme = \App\Support\Brand::activeTheme();
$brandLogo = \App\Support\Brand::logoUrl($brandTheme);
$brandName = (string) \App\Models\SystemSetting::get('app_name', config('app.name', 'WaDesk'));
@endphp
@if ($brandLogo)
@else
{{ $brandName }}
@endif
@php
$authUser = auth()->user();
$allWorkspaces = $authUser ? $authUser->workspaces()->orderByDesc('last_active_at')->get() : collect();
$currentWs = $authUser ? $authUser->current_workspace : null;
@endphp
@if ($authUser && $currentWs)
{{-- Hidden on mobile/tablet — the lone avatar circle confused users
("what is this?"). Below lg the workspace switcher lives inside
the hamburger menu instead (see [data-mobile-nav-pane]). --}}
{{-- Workspace switcher: BO tile + workspace name + chevron.
The name is capped (max-w + truncate) so a long workspace
name clips with an ellipsis instead of overflowing the
header / pushing the nav off its row. --}}
@php
$wsColor = $currentWs->brand_color ?: null;
// The default workspace name is "{owner}'s workspace" (e.g.
// "Bohecil's workspace"). On the compact button we drop that
// possessive owner prefix → just "Workspace". Custom names
// (no "'s ") show unchanged. Full real name stays in the
// tooltip + dropdown so workspaces are still distinguishable.
$wsStripped = preg_replace('/^.+?[\'\x{2019}]s\s+/u', '', (string) $currentWs->name);
$wsLabel =
$wsStripped !== '' && $wsStripped !== (string) $currentWs->name
? \Illuminate\Support\Str::ucfirst($wsStripped)
: $currentWs->name;
@endphp
{{-- Workspace switcher — moved here from the header so phones
don't show a mystery avatar circle. Labelled clearly. --}}
@if ($authUser && $currentWs)
{{-- Language switcher dropdown. Single source: lang/.json.
POSTs to /locale → persists to users.locale + session. --}}
{{-- Notification bell + dropdown. Feed is fetched from
/notifications/recent on toggle and refreshed every 60s
in the background. Mark-all-read + clear hit the
existing controller endpoints. --}}
{{-- Mobile: pin to the viewport so the panel can't clip off the
screen edge. Desktop: the normal anchored dropdown. --}}