Add hero sections to Queue index pages and soften analytics cards.
Deploy Ladill Queue / deploy (push) Successful in 36s

Introduce shared x-qms.page-hero with summary stats across queues,
tickets, counters, admin pages, and insights; remove bordered cards on
Analytics, Reports, Feedback, and Branches list views.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-06 07:32:10 +00:00
co-authored by Cursor
parent 29bf896f21
commit bf879d6abe
26 changed files with 850 additions and 526 deletions
@@ -38,7 +38,17 @@ class AppointmentController extends Controller
->orderBy('scheduled_at')
->paginate(30);
return view('qms.appointments.index', compact('appointments', 'organization'));
$appointmentQuery = QueueAppointment::owned($owner)
->where('organization_id', $organization->id)
->when($branchScope, fn ($q) => $q->where('branch_id', $branchScope));
$heroStats = [
'today' => (clone $appointmentQuery)->whereDate('scheduled_at', today())->count(),
'scheduled' => (clone $appointmentQuery)->where('status', 'scheduled')->count(),
'checked_in' => (clone $appointmentQuery)->where('status', 'checked_in')->count(),
];
return view('qms.appointments.index', compact('appointments', 'organization', 'heroStats'));
}
public function create(Request $request): View
@@ -26,7 +26,13 @@ class BranchController extends Controller
->orderBy('name')
->get();
return view('qms.admin.branches.index', compact('branches', 'organization'));
$heroStats = [
'total' => $branches->count(),
'active' => $branches->where('is_active', true)->count(),
'departments' => $branches->sum('departments_count'),
];
return view('qms.admin.branches.index', compact('branches', 'organization', 'heroStats'));
}
public function create(Request $request): View
+12 -1
View File
@@ -29,7 +29,18 @@ class CounterController extends Controller
->orderBy('name')
->paginate(20);
return view('qms.counters.index', compact('counters', 'organization'));
$counterStats = Counter::owned($owner)
->where('organization_id', $organization->id)
->when(true, fn ($q) => $this->scopeToBranch($request, $q))
->get();
$heroStats = [
'total' => $counterStats->count(),
'available' => $counterStats->where('status', 'available')->count(),
'busy' => $counterStats->where('status', 'busy')->count(),
];
return view('qms.counters.index', compact('counters', 'organization', 'heroStats'));
}
public function show(Request $request, Counter $counter): View
@@ -27,10 +27,17 @@ class DepartmentController extends Controller
->orderBy('name')
->get();
$heroStats = [
'total' => $departments->count(),
'active' => $departments->where('is_active', true)->count(),
'branches' => $departments->pluck('branch_id')->unique()->count(),
];
return view('qms.admin.departments.index', [
'departments' => $departments,
'organization' => $organization,
'types' => config('qms.department_types'),
'heroStats' => $heroStats,
]);
}
@@ -38,11 +38,22 @@ class DeviceController extends Controller
->orderBy('name')
->paginate(20);
$deviceStats = Device::owned($owner)
->where('organization_id', $organization->id)
->get();
$heroStats = [
'total' => $deviceStats->count(),
'online' => $deviceStats->where('status', 'online')->count(),
'kiosks' => $deviceStats->where('type', 'kiosk')->count(),
];
return view('qms.devices.index', [
'devices' => $devices,
'organization' => $organization,
'deviceTypes' => config('qms.device_types'),
'canManage' => $permissions->can($member, 'displays.manage'),
'heroStats' => $heroStats,
]);
}
@@ -33,10 +33,21 @@ class DisplayScreenController extends Controller
->orderBy('name')
->paginate(20);
$screenStats = DisplayScreen::owned($owner)
->where('organization_id', $organization->id)
->get();
$heroStats = [
'total' => $screenStats->count(),
'active' => $screenStats->where('is_active', true)->count(),
'branches' => $screenStats->pluck('branch_id')->filter()->unique()->count(),
];
return view('qms.displays.index', [
'screens' => $screens,
'organization' => $organization,
'canManage' => $permissions->can($member, 'displays.manage'),
'heroStats' => $heroStats,
]);
}
@@ -32,10 +32,21 @@ class FeedbackAdminController extends Controller
->when($branchScope, fn ($q) => $q->whereHas('ticket', fn ($t) => $t->where('branch_id', $branchScope)))
->avg('rating');
$feedbackQuery = CustomerFeedback::owned($owner)
->where('organization_id', $organization->id)
->when($branchScope, fn ($q) => $q->whereHas('ticket', fn ($t) => $t->where('branch_id', $branchScope)));
$heroStats = [
'total' => (clone $feedbackQuery)->count(),
'avg_rating' => round((float) $avgRating, 1),
'this_month' => (clone $feedbackQuery)->where('created_at', '>=', now()->startOfMonth())->count(),
];
return view('qms.feedback.index', [
'feedback' => $feedback,
'organization' => $organization,
'avgRating' => round((float) $avgRating, 1),
'heroStats' => $heroStats,
]);
}
}
@@ -27,10 +27,19 @@ class MemberController extends Controller
->orderBy('created_at')
->get();
$operatorRoles = ['queue_operator', 'counter_staff', 'receptionist'];
$heroStats = [
'total' => $members->count(),
'operators' => $members->whereIn('role', $operatorRoles)->count(),
'branches' => $members->whereNotNull('branch_id')->pluck('branch_id')->unique()->count(),
];
return view('qms.admin.members.index', [
'members' => $members,
'organization' => $organization,
'roles' => config('qms.roles'),
'heroStats' => $heroStats,
]);
}
@@ -36,6 +36,10 @@ class ReportController extends Controller
'organization' => $organization,
'branches' => $branches,
'reports' => config('qms.report_types'),
'heroStats' => [
'reports' => count(config('qms.report_types')),
'branches' => $branches->count(),
],
]);
}
@@ -30,7 +30,18 @@ class ServiceQueueController extends Controller
->orderBy('name')
->paginate(20);
return view('qms.queues.index', compact('queues', 'organization'));
$queueStats = ServiceQueue::owned($owner)
->where('organization_id', $organization->id)
->when(true, fn ($q) => $this->scopeToBranch($request, $q))
->get();
$heroStats = [
'total' => $queueStats->count(),
'active' => $queueStats->where('is_active', true)->where('is_paused', false)->count(),
'paused' => $queueStats->where('is_paused', true)->count(),
];
return view('qms.queues.index', compact('queues', 'organization', 'heroStats'));
}
public function show(Request $request, ServiceQueue $serviceQueue): View
@@ -37,7 +37,15 @@ class TicketController extends Controller
$queues = ServiceQueue::owned($owner)->where('organization_id', $organization->id)->orderBy('name')->get();
return view('qms.tickets.index', compact('tickets', 'queues', 'organization'));
$ticketQuery = Ticket::owned($owner)->where('organization_id', $organization->id);
$heroStats = [
'today' => (clone $ticketQuery)->whereDate('issued_at', today())->count(),
'waiting' => (clone $ticketQuery)->where('status', 'waiting')->count(),
'serving' => (clone $ticketQuery)->whereIn('status', ['called', 'serving', 'on_hold'])->count(),
];
return view('qms.tickets.index', compact('tickets', 'queues', 'organization', 'heroStats'));
}
public function create(Request $request): View
@@ -34,7 +34,13 @@ class WorkflowController extends Controller
->orderBy('name')
->get();
return view('qms.workflows.index', compact('workflows', 'organization'));
$heroStats = [
'total' => $workflows->count(),
'active' => $workflows->where('is_active', true)->count(),
'steps' => $workflows->sum('steps_count'),
];
return view('qms.workflows.index', compact('workflows', 'organization', 'heroStats'));
}
public function create(Request $request): View