Files
ladill-frontdesk/resources/views/frontdesk/dashboard.blade.php
T
isaaccladandCursor 6bc52d9ef3
Deploy Ladill Frontdesk / deploy (push) Successful in 1m13s
Add dashboard upgrade banner for free Frontdesk plans.
Show the Pro upsell CTA on the reception dashboard so free orgs can discover plans without opening the sidebar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 18:13:18 +00:00

117 lines
7.4 KiB
PHP

<x-app-layout title="Reception Dashboard">
@php
$cards = [
['label' => 'Visitors Today', 'value' => number_format($stats['visitors_today']), 'href' => route('frontdesk.visits.index')],
['label' => 'Currently Inside', 'value' => number_format($stats['currently_inside']), 'href' => route('frontdesk.visits.index', ['status' => 'checked_in'])],
['label' => 'Staff On Site', 'value' => number_format($stats['staff_on_site']), 'href' => route('frontdesk.employees.index')],
['label' => 'Staff Stepped Out', 'value' => number_format($stats['staff_stepped_out']), 'href' => route('frontdesk.employees.index')],
['label' => 'Expected Arrivals', 'value' => number_format($stats['expected_arrivals']), 'href' => route('frontdesk.visits.index', ['status' => 'expected'])],
['label' => 'Waiting', 'value' => number_format($stats['waiting']), 'href' => route('frontdesk.visits.index', ['status' => 'waiting'])],
['label' => 'Overdue', 'value' => number_format($stats['overdue']), 'href' => route('frontdesk.visits.index', ['status' => 'overdue'])],
['label' => 'Pending Approval', 'value' => number_format($stats['pending_approvals']), 'href' => route('frontdesk.visits.index', ['status' => 'waiting'])],
];
@endphp
<div class="mb-6 flex items-center justify-between gap-3">
<div class="min-w-0 flex-1">
<h1 class="truncate text-lg font-semibold tracking-tight text-slate-900 lg:text-xl">{{ $organization->name }}</h1>
<p class="hidden text-sm text-slate-500 lg:block">Reception dashboard</p>
</div>
@include('frontdesk.partials.reception-quick-actions')
</div>
@include('partials.upgrade-banner')
<div class="grid grid-cols-2 gap-4 lg:grid-cols-4">
@foreach ($cards as $card)
<a href="{{ $card['href'] }}" class="rounded-2xl border border-slate-200 bg-white p-5 transition hover:border-indigo-300 hover:shadow-sm">
<p class="text-xs font-medium uppercase tracking-wide text-slate-500">{{ $card['label'] }}</p>
<p class="mt-2 text-2xl font-semibold text-slate-900">{{ $card['value'] }}</p>
</a>
@endforeach
</div>
<div class="mt-6 grid gap-6 lg:grid-cols-2">
<section class="rounded-2xl border border-slate-200 bg-white">
<div class="flex items-center justify-between border-b border-slate-100 px-5 py-4">
<h2 class="text-sm font-semibold text-slate-900">Currently inside</h2>
@include('partials.mobile-icon-link', [
'href' => route('frontdesk.security.index'),
'label' => 'Security view',
'icon' => 'shield',
])
</div>
@forelse ($currentVisitors as $visit)
<a href="{{ route('frontdesk.visits.show', $visit) }}" class="flex items-center gap-3 border-b border-slate-50 px-5 py-3 last:border-0 hover:bg-slate-50">
<span class="flex h-10 w-10 items-center justify-center rounded-full bg-indigo-50 text-sm font-semibold text-indigo-700">{{ strtoupper(substr($visit->visitor->full_name, 0, 1)) }}</span>
<div class="min-w-0 flex-1">
<p class="truncate text-sm font-medium text-slate-800">{{ $visit->visitor->full_name }}</p>
<p class="truncate text-xs text-slate-400">Host: {{ $visit->host?->name ?? '—' }} · {{ $visit->checked_in_at?->diffForHumans() }}</p>
</div>
</a>
@empty
<p class="px-5 py-8 text-center text-sm text-slate-400">No visitors currently inside.</p>
@endforelse
</section>
<section class="rounded-2xl border border-slate-200 bg-white">
<div class="flex items-center justify-between border-b border-slate-100 px-5 py-4">
<h2 class="text-sm font-semibold text-slate-900">Expected today</h2>
@include('partials.mobile-icon-link', [
'href' => route('frontdesk.visits.calendar'),
'label' => 'Calendar',
'icon' => 'calendar',
])
</div>
@forelse ($expectedVisitors as $visit)
<a href="{{ route('frontdesk.visits.show', $visit) }}" class="flex items-center gap-3 border-b border-slate-50 px-5 py-3 last:border-0 hover:bg-slate-50 @if($visit->status === 'overdue') bg-amber-50/50 @endif">
<div class="min-w-0 flex-1">
<p class="truncate text-sm font-medium text-slate-800">{{ $visit->visitor->full_name }}</p>
<p class="truncate text-xs text-slate-400">{{ $visit->scheduled_at?->format('g:i A') ?? 'TBD' }} · {{ $visit->host?->name }} · {{ str_replace('_', ' ', $visit->status) }}</p>
</div>
</a>
@empty
<p class="px-5 py-8 text-center text-sm text-slate-400">No expected arrivals today.</p>
@endforelse
</section>
@if ($staffSteppedOut->isNotEmpty())
<section class="rounded-2xl border border-slate-200 bg-white lg:col-span-2">
<div class="flex items-center justify-between border-b border-slate-100 px-5 py-4">
<h2 class="text-sm font-semibold text-slate-900">Staff stepped out</h2>
@include('partials.mobile-icon-link', [
'href' => route('frontdesk.employees.index'),
'label' => 'Employees',
'icon' => 'arrow',
])
</div>
@foreach ($staffSteppedOut as $presence)
<div class="flex items-center gap-3 border-b border-slate-50 px-5 py-3 last:border-0">
<span class="flex h-10 w-10 items-center justify-center rounded-full bg-amber-50 text-sm font-semibold text-amber-800">{{ strtoupper(substr($presence->employee->full_name, 0, 1)) }}</span>
<div class="min-w-0 flex-1">
<p class="truncate text-sm font-medium text-slate-800">{{ $presence->employee->full_name }}</p>
<p class="truncate text-xs text-slate-400">{{ $presence->destination ?? 'Stepped out' }} · {{ $presence->last_event_at?->diffForHumans() }}</p>
</div>
</div>
@endforeach
</section>
@endif
@if ($pendingApprovals->isNotEmpty())
<section class="rounded-2xl border border-amber-200 bg-white lg:col-span-2">
<div class="border-b border-amber-100 px-5 py-4">
<h2 class="text-sm font-semibold text-amber-900">Pending approval</h2>
</div>
@foreach ($pendingApprovals as $visit)
<a href="{{ route('frontdesk.visits.show', $visit) }}" class="flex items-center gap-3 border-b border-slate-50 px-5 py-3 last:border-0 hover:bg-amber-50/50">
<div class="min-w-0 flex-1">
<p class="truncate text-sm font-medium text-slate-800">{{ $visit->visitor->full_name }}</p>
<p class="truncate text-xs text-slate-400">{{ ucfirst(str_replace('_', ' ', $visit->visitor_type)) }} · {{ $visit->host?->name }}</p>
</div>
</a>
@endforeach
</section>
@endif
</div>
</x-app-layout>