Polish Queue Devices empty state and align sidebar with other apps.
Deploy Ladill Queue / deploy (push) Successful in 38s

Match Care/Frontdesk nav icon styling, admin icons, and settings footer; add proper table layouts and empty states for Devices and Displays.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-06-29 21:22:44 +00:00
co-authored by Cursor
parent 660cc8d351
commit 051372672b
6 changed files with 199 additions and 50 deletions
+13 -2
View File
@@ -9,6 +9,8 @@ use App\Models\Device;
use App\Models\ServiceQueue;
use App\Services\Qms\AuditLogger;
use App\Services\Qms\DeviceService;
use App\Services\Qms\OrganizationResolver;
use App\Services\Qms\QmsPermissions;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
@@ -23,16 +25,25 @@ class DeviceController extends Controller
public function index(Request $request): View
{
$this->authorizeAbility($request, 'displays.manage');
$this->authorizeAbility($request, 'displays.view');
$owner = $this->ownerRef($request);
$organization = $this->organization($request);
$member = app(OrganizationResolver::class)->memberFor($request->user());
$permissions = app(QmsPermissions::class);
$devices = Device::owned($owner)
->where('organization_id', $organization->id)
->with('branch')
->orderBy('name')
->paginate(20);
return view('qms.devices.index', compact('devices', 'organization'));
return view('qms.devices.index', [
'devices' => $devices,
'organization' => $organization,
'deviceTypes' => config('qms.device_types'),
'canManage' => $permissions->can($member, 'displays.manage'),
]);
}
public function create(Request $request): View
@@ -8,6 +8,8 @@ use App\Models\Branch;
use App\Models\DisplayScreen;
use App\Models\ServiceQueue;
use App\Services\Qms\AuditLogger;
use App\Services\Qms\OrganizationResolver;
use App\Services\Qms\QmsPermissions;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
@@ -22,12 +24,20 @@ class DisplayScreenController extends Controller
$owner = $this->ownerRef($request);
$organization = $this->organization($request);
$member = app(OrganizationResolver::class)->memberFor($request->user());
$permissions = app(QmsPermissions::class);
$screens = DisplayScreen::owned($owner)
->where('organization_id', $organization->id)
->with('branch')
->orderBy('name')
->paginate(20);
return view('qms.displays.index', compact('screens', 'organization'));
return view('qms.displays.index', [
'screens' => $screens,
'organization' => $organization,
'canManage' => $permissions->can($member, 'displays.manage'),
]);
}
public function show(Request $request, DisplayScreen $display): View
@@ -0,0 +1,16 @@
@props(['title', 'description' => null])
<div {{ $attributes->merge(['class' => 'flex flex-col items-center justify-center px-6 py-14 text-center']) }}>
@if (isset($icon))
<div class="mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-slate-100 text-slate-400">
{{ $icon }}
</div>
@endif
<h3 class="text-sm font-semibold text-slate-900">{{ $title }}</h3>
@if ($description)
<p class="mt-1 max-w-sm text-sm text-slate-500">{{ $description }}</p>
@endif
@if (isset($action))
<div class="mt-5">{{ $action }}</div>
@endif
</div>
+35 -17
View File
@@ -1,5 +1,5 @@
<div class="flex h-full flex-col bg-white border-r border-slate-200 text-slate-700 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300">
<div class="flex h-16 shrink-0 items-center border-b border-slate-200 px-6 dark:border-slate-700">
<div class="flex h-full flex-col bg-white border-r border-slate-200 text-slate-700">
<div class="flex h-16 shrink-0 items-center border-b border-slate-200 px-6">
<a href="{{ route('qms.dashboard') }}" class="flex items-center">
<img src="{{ asset('images/logo/ladillqueue-logo.svg') }}?v={{ @filemtime(public_path('images/logo/ladillqueue-logo.svg')) ?: '1' }}" alt="Ladill Queue" class="h-6 w-auto">
</a>
@@ -29,7 +29,7 @@
$nav[] = ['name' => 'Displays', 'route' => route('qms.displays.index'), 'active' => request()->routeIs('qms.displays.*'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M6 20.25h12m-7.5-3v3m3-3v3m-10.125-3H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z" />'];
$nav[] = ['name' => 'Devices', 'route' => route('qms.devices.index'), 'active' => request()->routeIs('qms.devices.*'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 0 0 6 3.75v16.5a2.25 2.25 0 0 0 2.25 2.25h7.5A2.25 2.25 0 0 0 18 20.25V3.75a2.25 2.25 0 0 0-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" />'];
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21" />'];
}
if ($permissions->can($member, 'appointments.view')) {
$nav[] = ['name' => 'Appointments', 'route' => route('qms.appointments.index'), 'active' => request()->routeIs('qms.appointments.*'),
@@ -49,37 +49,55 @@
$nav[] = ['name' => 'Feedback', 'route' => route('qms.feedback.admin'), 'active' => request()->routeIs('qms.feedback.admin'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 0 1 .778-.332 48.294 48.294 0 0 0 5.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />'];
}
$adminItems = [];
$adminNav = [];
if ($permissions->can($member, 'admin.branches.view')) {
$adminItems[] = ['name' => 'Branches', 'route' => route('qms.branches.index'), 'active' => request()->routeIs('qms.branches.*')];
$adminNav[] = ['name' => 'Branches', 'route' => route('qms.branches.index'), 'active' => request()->routeIs('qms.branches.*'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 21h16.5M4.5 3h15M5.25 3v18m13.5-18v18M9 6.75h1.5m-1.5 3h1.5m-1.5 3h1.5m-1.5 3h1.5m3-9H15m-1.5 3H15m-1.5 3H15m-1.5 3H15M9 21v-3.375c0-.621.504-1.125 1.125-1.125h3.75c.621 0 1.125.504 1.125 1.125V21" />'];
}
if ($permissions->can($member, 'admin.departments.view')) {
$adminItems[] = ['name' => 'Departments', 'route' => route('qms.departments.index'), 'active' => request()->routeIs('qms.departments.*')];
$adminNav[] = ['name' => 'Departments', 'route' => route('qms.departments.index'), 'active' => request()->routeIs('qms.departments.*'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 0 1 6 3.75h2.25A2.25 2.25 0 0 1 10.5 6v2.25a2.25 2.25 0 0 1-2.25 2.25H6a2.25 2.25 0 0 1-2.25-2.25V6ZM3.75 15.75A2.25 2.25 0 0 1 6 13.5h2.25a2.25 2.25 0 0 1 2.25 2.25V18a2.25 2.25 0 0 1-2.25 2.25H6A2.25 2.25 0 0 1 3.75 18v-2.25ZM13.5 6a2.25 2.25 0 0 1 2.25-2.25H18A2.25 2.25 0 0 1 20.25 6v2.25A2.25 2.25 0 0 1 18 10.5h-2.25a2.25 2.25 0 0 1-2.25-2.25V6ZM13.5 15.75a2.25 2.25 0 0 1 2.25-2.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-2.25A2.25 2.25 0 0 1 13.5 18v-2.25Z" />'];
}
if ($permissions->can($member, 'admin.members.view')) {
$adminItems[] = ['name' => 'Team', 'route' => route('qms.members.index'), 'active' => request()->routeIs('qms.members.*')];
$adminNav[] = ['name' => 'Team', 'route' => route('qms.members.index'), 'active' => request()->routeIs('qms.members.*'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z" />'];
}
if ($permissions->can($member, 'audit.view')) {
$adminItems[] = ['name' => 'Audit log', 'route' => route('qms.audit.index'), 'active' => request()->routeIs('qms.audit.*')];
}
if ($permissions->can($member, 'settings.view')) {
$adminItems[] = ['name' => 'Settings', 'route' => route('qms.settings.edit'), 'active' => request()->routeIs('qms.settings.*')];
$adminNav[] = ['name' => 'Audit log', 'route' => route('qms.audit.index'), 'active' => request()->routeIs('qms.audit.*'),
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />'];
}
$settingsActive = request()->routeIs('qms.settings.*');
@endphp
<nav class="flex-1 space-y-0.5 overflow-y-auto px-3 py-4">
@foreach ($nav as $item)
<a href="{{ $item['route'] }}" class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $item['active'] ? 'bg-indigo-50 text-indigo-700 font-semibold dark:bg-indigo-950 dark:text-indigo-300' : 'text-slate-600 hover:bg-slate-50 dark:text-slate-400 dark:hover:bg-slate-800' }}">
<svg class="h-[18px] w-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">{!! $item['icon'] !!}</svg>
<a href="{{ $item['route'] }}" class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $item['active'] ? 'bg-indigo-50 text-indigo-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
<svg class="{{ $item['iconSizeClass'] ?? 'h-[18px] w-[18px]' }} shrink-0 {{ $item['active'] ? 'text-indigo-600' : 'text-slate-400' }}" viewBox="{{ $item['iconViewBox'] ?? '0 0 24 24' }}" fill="none" stroke="currentColor" stroke-width="{{ $item['iconStrokeWidth'] ?? 1.5 }}">{!! $item['icon'] !!}</svg>
<span>{{ $item['name'] }}</span>
</a>
@endforeach
@if (!empty($adminItems))
<div class="pt-4 pb-1 px-3 text-[10px] font-semibold uppercase tracking-wider text-slate-400">Administration</div>
@foreach ($adminItems as $item)
<a href="{{ $item['route'] }}" class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $item['active'] ? 'bg-indigo-50 text-indigo-700 font-semibold dark:bg-indigo-950 dark:text-indigo-300' : 'text-slate-600 hover:bg-slate-50 dark:text-slate-400 dark:hover:bg-slate-800' }}">
@if (count($adminNav))
<p class="mb-1 mt-4 px-3 text-[10px] font-semibold uppercase tracking-wider text-slate-400">Administration</p>
@foreach ($adminNav as $item)
<a href="{{ $item['route'] }}" class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $item['active'] ? 'bg-indigo-50 text-indigo-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
<svg class="{{ $item['iconSizeClass'] ?? 'h-[18px] w-[18px]' }} shrink-0 {{ $item['active'] ? 'text-indigo-600' : 'text-slate-400' }}" viewBox="{{ $item['iconViewBox'] ?? '0 0 24 24' }}" fill="none" stroke="currentColor" stroke-width="{{ $item['iconStrokeWidth'] ?? 1.5 }}">{!! $item['icon'] !!}</svg>
<span>{{ $item['name'] }}</span>
</a>
@endforeach
@endif
</nav>
@if ($permissions->can($member, 'settings.view'))
<div class="shrink-0 border-t border-slate-200 px-3 py-3">
<a href="{{ route('qms.settings.edit') }}"
class="group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $settingsActive ? 'bg-indigo-50 text-indigo-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
<svg class="h-[18px] w-[18px] shrink-0 {{ $settingsActive ? 'text-indigo-600' : 'text-slate-400' }}" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.281Z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
</svg>
<span>Settings</span>
</a>
</div>
@endif
</div>
+70 -17
View File
@@ -1,22 +1,75 @@
<x-app-layout title="Devices">
<div class="mb-6 flex justify-between">
<h1 class="text-2xl font-semibold">Devices</h1>
<a href="{{ route('qms.devices.create') }}" class="btn-primary">Register device</a>
<div class="flex items-center justify-between gap-3">
<div>
<h1 class="text-xl font-semibold text-slate-900">Devices</h1>
<p class="text-sm text-slate-500">Kiosks and ticket printers for self-service and reception</p>
</div>
@if ($canManage)
<a href="{{ route('qms.devices.create') }}" class="btn-primary">Register device</a>
@endif
</div>
@if (session('success'))<p class="mb-4 rounded-lg bg-emerald-50 px-3 py-2 text-sm text-emerald-800">{{ session('success') }}</p>@endif
<div class="space-y-3">
@foreach ($devices as $device)
<div class="flex items-center justify-between rounded-2xl border bg-white p-4 dark:border-slate-700 dark:bg-slate-900">
<div>
<p class="font-semibold">{{ $device->name }}</p>
<p class="text-sm text-slate-500">{{ config('qms.device_types.'.$device->type) }} · {{ $device->status }}</p>
@if ($device->type === 'kiosk' && $device->device_token)
<p class="mt-1 text-xs text-slate-400">Kiosk URL: {{ route('qms.kiosk.device', $device->device_token) }}</p>
@endif
</div>
<form method="POST" action="{{ route('qms.devices.regenerate-token', $device) }}">@csrf<button class="btn-secondary text-sm">Regenerate token</button></form>
@if (session('success'))
<div class="mt-4 rounded-lg bg-emerald-50 px-4 py-3 text-sm text-emerald-800">{{ session('success') }}</div>
@endif
<div class="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-white">
@if ($devices->isEmpty())
<x-empty-state
title="No devices registered yet"
description="Register a kiosk tablet or ticket printer so customers can join queues without staff assistance."
>
<x-slot:icon>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21" />
</svg>
</x-slot:icon>
@if ($canManage)
<x-slot:action>
<a href="{{ route('qms.devices.create') }}" class="btn-primary">Register your first device</a>
</x-slot:action>
@endif
</x-empty-state>
@else
<table class="min-w-full divide-y divide-slate-100 text-sm">
<thead class="bg-slate-50 text-left text-xs uppercase text-slate-500">
<tr>
<th class="px-4 py-3">Name</th>
<th class="px-4 py-3">Type</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3">Branch</th>
<th class="px-4 py-3"></th>
</tr>
</thead>
<tbody class="divide-y divide-slate-50">
@foreach ($devices as $device)
<tr>
<td class="px-4 py-3 font-medium text-slate-900">{{ $device->name }}</td>
<td class="px-4 py-3 text-slate-600">{{ $deviceTypes[$device->type] ?? $device->type }}</td>
<td class="px-4 py-3">
<span class="inline-flex rounded-full px-2 py-0.5 text-xs font-medium {{ $device->status === 'online' ? 'bg-emerald-100 text-emerald-800' : 'bg-slate-100 text-slate-600' }}">
{{ ucfirst($device->status) }}
</span>
</td>
<td class="px-4 py-3 text-slate-600">{{ $device->branch?->name ?? '—' }}</td>
<td class="px-4 py-3 text-right">
@if ($device->type === 'kiosk' && $device->device_token)
<a href="{{ route('qms.kiosk.device', $device->device_token) }}" target="_blank" class="text-indigo-700 hover:underline">Open kiosk</a>
@endif
@if ($canManage)
<form method="POST" action="{{ route('qms.devices.regenerate-token', $device) }}" class="ml-3 inline">
@csrf
<button type="submit" class="text-indigo-700 hover:underline">Regenerate token</button>
</form>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="border-t border-slate-200 px-4 py-3">
{{ $devices->links() }}
</div>
@endforeach
@endif
</div>
{{ $devices->links() }}
</x-app-layout>
+54 -13
View File
@@ -1,18 +1,59 @@
<x-app-layout title="Displays">
<div class="mb-6 flex justify-between">
<h1 class="text-2xl font-semibold">Display screens</h1>
<a href="{{ route('qms.displays.create') }}" class="btn-primary">New display</a>
<div class="flex items-center justify-between gap-3">
<div>
<h1 class="text-xl font-semibold text-slate-900">Display screens</h1>
<p class="text-sm text-slate-500">Waiting-area screens and voice announcements for called tickets</p>
</div>
@if ($canManage)
<a href="{{ route('qms.displays.create') }}" class="btn-primary">New display</a>
@endif
</div>
<div class="space-y-3">
@foreach ($screens as $screen)
<div class="flex items-center justify-between rounded-2xl border bg-white p-4 dark:border-slate-700 dark:bg-slate-900">
<div>
<p class="font-semibold">{{ $screen->name }}</p>
<p class="text-sm text-slate-500">{{ config('qms.display_layouts.'.$screen->layout) }}</p>
</div>
<a href="{{ route('qms.display.public', $screen->access_token) }}" target="_blank" class="btn-secondary text-sm">Open display</a>
<div class="mt-4 overflow-hidden rounded-2xl border border-slate-200 bg-white">
@if ($screens->isEmpty())
<x-empty-state
title="No display screens yet"
description="Create a display for your waiting area so customers can see the queue and hear ticket calls."
>
<x-slot:icon>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 20.25h12m-7.5-3v3m3-3v3m-10.125-3H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z" />
</svg>
</x-slot:icon>
@if ($canManage)
<x-slot:action>
<a href="{{ route('qms.displays.create') }}" class="btn-primary">Create your first display</a>
</x-slot:action>
@endif
</x-empty-state>
@else
<table class="min-w-full divide-y divide-slate-100 text-sm">
<thead class="bg-slate-50 text-left text-xs uppercase text-slate-500">
<tr>
<th class="px-4 py-3">Name</th>
<th class="px-4 py-3">Layout</th>
<th class="px-4 py-3">Branch</th>
<th class="px-4 py-3"></th>
</tr>
</thead>
<tbody class="divide-y divide-slate-50">
@foreach ($screens as $screen)
<tr>
<td class="px-4 py-3 font-medium text-slate-900">
<a href="{{ route('qms.displays.show', $screen) }}" class="hover:text-indigo-600">{{ $screen->name }}</a>
</td>
<td class="px-4 py-3 text-slate-600">{{ config('qms.display_layouts.'.$screen->layout, $screen->layout) }}</td>
<td class="px-4 py-3 text-slate-600">{{ $screen->branch?->name ?? '—' }}</td>
<td class="px-4 py-3 text-right">
<a href="{{ route('qms.display.public', $screen->access_token) }}" target="_blank" class="text-indigo-700 hover:underline">Open display</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="border-t border-slate-200 px-4 py-3">
{{ $screens->links() }}
</div>
@endforeach
@endif
</div>
{{ $screens->links() }}
</x-app-layout>