Split attendees and badge printing; add a 3-step event create flow.
Deploy Ladill Events / deploy (push) Successful in 35s
Deploy Ladill Events / deploy (push) Successful in 35s
Give each area its own sidebar entry and hub pages, and walk new events through details, QR design, then review before publish. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -18,6 +18,93 @@ class AttendeeController extends Controller
|
||||
{
|
||||
public function __construct(private readonly SmsService $sms) {}
|
||||
|
||||
public function hub(Request $request): View
|
||||
{
|
||||
$account = ladill_account();
|
||||
$search = trim((string) $request->query('search', ''));
|
||||
|
||||
$events = $account->qrCodes()
|
||||
->where('type', QrCode::TYPE_EVENT)
|
||||
->when($search !== '', fn ($q) => $q->where('label', 'like', "%{$search}%"))
|
||||
->latest()
|
||||
->get()
|
||||
->map(function (QrCode $event) {
|
||||
$event->confirmed_count = $event->eventRegistrations()
|
||||
->where('status', QrEventRegistration::STATUS_CONFIRMED)
|
||||
->count();
|
||||
$event->checked_in_count = $event->eventRegistrations()
|
||||
->whereNotNull('checked_in_at')
|
||||
->count();
|
||||
|
||||
return $event;
|
||||
});
|
||||
|
||||
return view('events.attendees-hub', [
|
||||
'events' => $events,
|
||||
'search' => $search,
|
||||
]);
|
||||
}
|
||||
|
||||
public function badgesHub(Request $request): View
|
||||
{
|
||||
$account = ladill_account();
|
||||
$search = trim((string) $request->query('search', ''));
|
||||
|
||||
$events = $account->qrCodes()
|
||||
->where('type', QrCode::TYPE_EVENT)
|
||||
->when($search !== '', fn ($q) => $q->where('label', 'like', "%{$search}%"))
|
||||
->latest()
|
||||
->get()
|
||||
->map(function (QrCode $event) {
|
||||
$event->printable_count = $event->eventRegistrations()
|
||||
->where('status', QrEventRegistration::STATUS_CONFIRMED)
|
||||
->count();
|
||||
|
||||
return $event;
|
||||
});
|
||||
|
||||
return view('events.badges-hub', [
|
||||
'events' => $events,
|
||||
'search' => $search,
|
||||
]);
|
||||
}
|
||||
|
||||
public function badgePrinting(Request $request, QrCode $event): View
|
||||
{
|
||||
$this->authorize('view', $event);
|
||||
abort_unless($event->type === QrCode::TYPE_EVENT, 404);
|
||||
|
||||
$isContribution = ($event->content()['mode'] ?? 'ticketing') === 'contributions';
|
||||
if ($isContribution) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$query = $event->eventRegistrations()
|
||||
->where('status', QrEventRegistration::STATUS_CONFIRMED)
|
||||
->latest();
|
||||
|
||||
if ($search = trim((string) $request->query('search', ''))) {
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('attendee_name', 'like', "%{$search}%")
|
||||
->orWhere('attendee_email', 'like', "%{$search}%")
|
||||
->orWhere('badge_code', 'like', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
$registrations = $query->paginate(40)->withQueryString();
|
||||
$badgeSize = $event->content()['badge_size'] ?? '4x3';
|
||||
|
||||
return view('events.badge-printing', [
|
||||
'qrCode' => $event,
|
||||
'event' => $event,
|
||||
'registrations' => $registrations,
|
||||
'badgeSize' => $badgeSize,
|
||||
'printableCount' => $event->eventRegistrations()
|
||||
->where('status', QrEventRegistration::STATUS_CONFIRMED)
|
||||
->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function index(Request $request, QrCode $event): View
|
||||
{
|
||||
$this->authorize('view', $event);
|
||||
|
||||
Reference in New Issue
Block a user