Fix post-registration 404, add speaker management, and simplify event creation.
Deploy Ladill Events / deploy (push) Successful in 28s
Deploy Ladill Events / deploy (push) Successful in 28s
Proxy registration transaction paths on Events, add a join button on the confirmation page, introduce speaker roster management, and replace the QR design wizard with merchant-style create/show flows. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<x-user-layout>
|
||||
<x-slot name="title">Create event</x-slot>
|
||||
|
||||
<div class="mx-auto max-w-2xl space-y-6" x-data="{ type: 'event' }">
|
||||
<div>
|
||||
<a href="{{ route('events.index') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5"/></svg>
|
||||
Events
|
||||
</a>
|
||||
<h1 class="mt-2 text-xl font-semibold text-slate-900">Create event</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">Set up registration, ticketing, and your event page. A Ladill Link QR code is generated automatically — customize it later in QR Plus if needed.</p>
|
||||
</div>
|
||||
|
||||
@if(session('error'))
|
||||
<div class="rounded-xl border border-red-100 bg-red-50 px-4 py-3 text-sm text-red-700">{{ session('error') }}</div>
|
||||
@endif
|
||||
@if($errors->any())
|
||||
<div class="rounded-xl border border-red-100 bg-red-50 px-4 py-3 text-sm text-red-700">
|
||||
<ul class="list-inside list-disc space-y-0.5">
|
||||
@foreach($errors->all() as $error)<li>{{ $error }}</li>@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="post" action="{{ route('events.store') }}" enctype="multipart/form-data" class="space-y-5 rounded-2xl border border-slate-200 bg-white p-6">
|
||||
@csrf
|
||||
<input type="hidden" name="type" value="event">
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Dashboard label</label>
|
||||
<input type="text" name="label" value="{{ old('label') }}" required maxlength="120"
|
||||
placeholder="e.g. Tech summit 2026"
|
||||
class="mt-1 w-full rounded-xl border-slate-200 text-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
<p class="mt-1 text-xs text-slate-400">Private name to find this event in your dashboard.</p>
|
||||
</div>
|
||||
|
||||
<div x-data="{
|
||||
slug: @js(old('custom_short_code', '')),
|
||||
status: '',
|
||||
timer: null,
|
||||
checkUrl: @js(route('events.check-slug')),
|
||||
check() {
|
||||
clearTimeout(this.timer);
|
||||
const s = this.slug.trim();
|
||||
if (s === '') { this.status = ''; return; }
|
||||
if (!/^[a-z0-9][a-z0-9-]{1,18}[a-z0-9]$/.test(s)) { this.status = 'invalid'; return; }
|
||||
this.status = 'checking';
|
||||
this.timer = setTimeout(() => {
|
||||
fetch(this.checkUrl + '?code=' + encodeURIComponent(s))
|
||||
.then(r => r.json())
|
||||
.then(d => { this.status = d.available ? 'available' : 'taken'; })
|
||||
.catch(() => { this.status = ''; });
|
||||
}, 400);
|
||||
},
|
||||
}">
|
||||
<label class="block text-sm font-medium text-slate-700">Custom link <span class="font-normal text-slate-400">(optional)</span></label>
|
||||
<div class="mt-1 flex items-stretch rounded-xl border focus-within:border-indigo-500 focus-within:ring-1 focus-within:ring-indigo-500"
|
||||
:class="status === 'available' ? 'border-green-400' : status === 'taken' || status === 'invalid' ? 'border-red-400' : 'border-slate-200'">
|
||||
<span class="flex items-center rounded-l-xl border-r border-slate-200 bg-slate-50 px-3 text-xs text-slate-400 whitespace-nowrap select-none">{{ \App\Support\LadillLink::baseUrl() }}/</span>
|
||||
<input type="text" name="custom_short_code" x-model="slug" @input="check()" maxlength="20" autocomplete="off"
|
||||
class="min-w-0 flex-1 rounded-r-xl bg-white px-3 py-2.5 text-sm focus:outline-none" placeholder="my-event">
|
||||
</div>
|
||||
<p class="mt-1 text-xs text-slate-400">Leave blank to auto-generate your Ladill Link.</p>
|
||||
</div>
|
||||
|
||||
@include('qr-codes.partials.type-fields-create', ['accountEventDefaults' => $accountEventDefaults ?? []])
|
||||
|
||||
<p class="rounded-xl bg-slate-50 px-3.5 py-2.5 text-xs leading-5 text-slate-500">
|
||||
GHS {{ number_format($pricePerQr, 2) }} will be charged from your QR balance when you create this event.
|
||||
</p>
|
||||
|
||||
<button type="submit" class="btn-primary w-full">Create event</button>
|
||||
</form>
|
||||
</div>
|
||||
</x-user-layout>
|
||||
@@ -0,0 +1,114 @@
|
||||
<x-user-layout>
|
||||
<x-slot name="title">{{ $qrCode->label }}</x-slot>
|
||||
@php
|
||||
$content = $qrCode->content();
|
||||
$publicUrl = \App\Support\LadillLink::url($qrCode->short_code);
|
||||
@endphp
|
||||
|
||||
<div class="mx-auto max-w-5xl space-y-6" x-data="{ type: @js($qrCode->type) }">
|
||||
<div class="flex flex-wrap items-start justify-between gap-4">
|
||||
<div>
|
||||
<a href="{{ route('events.index') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5"/></svg>
|
||||
Events
|
||||
</a>
|
||||
<h1 class="mt-2 text-xl font-semibold text-slate-900">{{ $content['name'] ?? $qrCode->label }}</h1>
|
||||
<p class="mt-1 inline-flex flex-wrap items-center gap-2 text-sm text-slate-500">
|
||||
<span class="rounded-full bg-indigo-50 px-2 py-0.5 text-xs font-semibold text-indigo-700">Event</span>
|
||||
@if($qrCode->is_active)
|
||||
<span class="text-emerald-600">● Live</span>
|
||||
@else
|
||||
<span class="text-slate-400">● Inactive</span>
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ $publicUrl }}" target="_blank" rel="noopener"
|
||||
class="inline-flex items-center gap-1.5 rounded-xl border border-slate-200 bg-white px-3.5 py-2 text-sm font-semibold text-slate-700 shadow-sm hover:bg-slate-50">
|
||||
View registration page
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@foreach(['success', 'error'] as $flash)
|
||||
@if(session($flash))
|
||||
<div class="rounded-xl border px-4 py-3 text-sm {{ $flash === 'success' ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-red-200 bg-red-50 text-red-700' }}">
|
||||
{{ session($flash) }}
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
@if($errors->any())
|
||||
<div class="rounded-xl border border-red-100 bg-red-50 px-4 py-3 text-sm text-red-700">
|
||||
<ul class="list-inside list-disc space-y-0.5">@foreach($errors->all() as $error)<li>{{ $error }}</li>@endforeach</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="grid gap-3 sm:grid-cols-3">
|
||||
<a href="{{ route('events.attendees', $qrCode) }}" class="rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-700 hover:bg-slate-50">Attendees</a>
|
||||
<a href="{{ route('speakers.show', $qrCode) }}" class="rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-700 hover:bg-slate-50">Speakers</a>
|
||||
<a href="{{ route('events.badge-printing', $qrCode) }}" class="rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-700 hover:bg-slate-50">Badge printing</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 lg:grid-cols-[320px_1fr]">
|
||||
<div class="space-y-4 lg:sticky lg:top-6 lg:self-start">
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-5 text-center">
|
||||
@if($previewDataUri)
|
||||
<img src="{{ $previewDataUri }}" alt="QR code" class="mx-auto h-44 w-44">
|
||||
@endif
|
||||
<p class="mt-3 break-all text-xs text-slate-400">{{ $publicUrl }}</p>
|
||||
<div class="mt-4 flex flex-wrap justify-center gap-2">
|
||||
@foreach(['png' => 'PNG', 'svg' => 'SVG', 'pdf' => 'PDF'] as $fmt => $flabel)
|
||||
<a href="{{ route('events.download', [$qrCode, $fmt]) }}"
|
||||
class="rounded-lg border border-slate-200 px-3 py-1.5 text-xs font-semibold text-slate-600 hover:bg-slate-50">{{ $flabel }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
<p class="mt-3 text-[11px] leading-5 text-slate-400">System-generated QR code. Customize colors, logos, and frames in QR Plus.</p>
|
||||
</div>
|
||||
|
||||
@if(!empty($customDomainsEnabled))
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-5">
|
||||
<h3 class="text-sm font-semibold text-slate-900">Custom domain</h3>
|
||||
<p class="mt-1 text-xs text-slate-500">Optional — your Ladill Link always works.</p>
|
||||
@forelse($customDomains as $cd)
|
||||
<div class="mt-3 rounded-xl border border-slate-200 p-3 text-xs text-slate-600">
|
||||
<span class="font-medium text-slate-900">{{ $cd->host }}</span>
|
||||
</div>
|
||||
@empty
|
||||
<form method="post" action="{{ route('events.custom-domain.store', $qrCode) }}" class="mt-3 flex items-end gap-2">
|
||||
@csrf
|
||||
<input type="text" name="host" placeholder="myevent.com" required class="mt-1 w-full rounded-xl border-slate-200 text-sm">
|
||||
<button class="rounded-xl bg-slate-900 px-3 py-2 text-xs font-semibold text-white">Add</button>
|
||||
</form>
|
||||
@endforelse
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<form method="post" action="{{ route('events.update', $qrCode) }}" enctype="multipart/form-data" class="space-y-5 rounded-2xl border border-slate-200 bg-white p-6">
|
||||
@csrf @method('PATCH')
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Dashboard label</label>
|
||||
<input type="text" name="label" value="{{ old('label', $qrCode->label) }}" required maxlength="120"
|
||||
class="mt-1 w-full rounded-xl border-slate-200 text-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
</div>
|
||||
|
||||
<label class="flex cursor-pointer items-center justify-between rounded-xl border border-slate-200 bg-white px-4 py-3 shadow-sm">
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-slate-900">Registration page live</p>
|
||||
<p class="mt-0.5 text-xs text-slate-500">Turn off to pause registrations without deleting the event.</p>
|
||||
</div>
|
||||
<div class="relative ml-4 shrink-0">
|
||||
<input type="hidden" name="is_active" value="0">
|
||||
<input type="checkbox" name="is_active" value="1" class="sr-only peer" @checked(old('is_active', $qrCode->is_active))>
|
||||
<div class="h-6 w-11 rounded-full bg-slate-200 transition-colors duration-200 peer-checked:bg-indigo-600"></div>
|
||||
<div class="absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-white shadow transition-transform duration-200 peer-checked:translate-x-5"></div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
@include('qr-codes.partials.type-fields-edit', ['itineraryOptions' => $itineraryOptions])
|
||||
|
||||
<button type="submit" class="btn-primary w-full">Save changes</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</x-user-layout>
|
||||
@@ -0,0 +1,46 @@
|
||||
<x-user-layout>
|
||||
<x-slot name="title">Speakers</x-slot>
|
||||
|
||||
<div class="mx-auto max-w-5xl space-y-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-slate-900">Speakers</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">Manage speaker rosters and programme assignments for each event.</p>
|
||||
</div>
|
||||
|
||||
<form method="GET" class="flex items-center gap-2">
|
||||
<input type="text" name="search" value="{{ $search }}" placeholder="Search events…"
|
||||
class="w-full max-w-sm rounded-xl border border-slate-200 px-3.5 py-2 text-sm focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400/30">
|
||||
<button type="submit" class="rounded-xl border border-slate-200 px-4 py-2 text-sm font-semibold text-slate-600 hover:bg-slate-50 transition">Search</button>
|
||||
</form>
|
||||
|
||||
<div class="overflow-hidden rounded-2xl border border-slate-200 bg-white">
|
||||
@if($events->isEmpty())
|
||||
<div class="px-6 py-14 text-center">
|
||||
<p class="text-sm text-slate-500">{{ $search ? 'No events match your search.' : 'No events yet.' }}</p>
|
||||
@unless($search)
|
||||
<a href="{{ route('events.create') }}" class="mt-4 btn-primary">Create your first event</a>
|
||||
@endunless
|
||||
</div>
|
||||
@else
|
||||
<div class="divide-y divide-slate-100">
|
||||
@foreach($events as $event)
|
||||
@php $content = $event->content(); @endphp
|
||||
<a href="{{ route('speakers.show', $event) }}" class="flex items-center gap-4 px-6 py-4 transition hover:bg-slate-50">
|
||||
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-violet-50 text-violet-600">
|
||||
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 0 1 6 0v8.25a3 3 0 0 1-3 3Z"/></svg>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="truncate text-sm font-semibold text-slate-900">{{ $content['name'] ?? $event->label }}</p>
|
||||
<p class="truncate text-xs text-slate-500">{{ $event->label }}</p>
|
||||
</div>
|
||||
<div class="hidden text-right text-xs text-slate-500 sm:block">
|
||||
<p class="font-semibold text-slate-900">{{ number_format($event->speaker_count) }} speakers</p>
|
||||
</div>
|
||||
<svg class="h-4 w-4 shrink-0 text-slate-300" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5"/></svg>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</x-user-layout>
|
||||
@@ -0,0 +1,89 @@
|
||||
<x-user-layout>
|
||||
<x-slot name="title">Speakers — {{ $qrCode->label }}</x-slot>
|
||||
|
||||
<div class="mx-auto max-w-3xl space-y-6">
|
||||
@foreach(['success', 'error'] as $flash)
|
||||
@if(session($flash))
|
||||
<div class="rounded-xl border px-4 py-3 text-sm {{ $flash === 'success' ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-red-200 bg-red-50 text-red-700' }}">
|
||||
{{ session($flash) }}
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
<div>
|
||||
<a href="{{ route('speakers.index') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5"/></svg>
|
||||
Speakers
|
||||
</a>
|
||||
<h1 class="mt-1.5 text-2xl font-bold text-slate-900">Speaker management</h1>
|
||||
<p class="mt-0.5 text-sm text-slate-500">{{ $qrCode->content()['name'] ?? $qrCode->label }}</p>
|
||||
</div>
|
||||
|
||||
@if($programme)
|
||||
<div class="rounded-2xl border border-indigo-100 bg-indigo-50/60 px-4 py-3 text-sm text-indigo-950">
|
||||
Linked programme: <a href="{{ route('events.show', $programme) }}" class="font-semibold hover:underline">{{ $programme->label }}</a>.
|
||||
Hosts assigned on programme sessions appear below and sync to virtual sessions.
|
||||
</div>
|
||||
@else
|
||||
<div class="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600">
|
||||
Attach a programme on the <a href="{{ route('events.show', $qrCode) }}" class="font-semibold text-indigo-600 hover:underline">event settings</a> page to pull session hosts into this roster.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('speakers.update', $qrCode) }}" class="space-y-5 rounded-2xl border border-slate-200 bg-white p-6"
|
||||
x-data="{
|
||||
speakers: {{ Illuminate\Support\Js::from(array_values(old('speakers', $roster ?: [['name' => '', 'email' => '', 'role' => '', 'bio' => '']]))) }},
|
||||
addSpeaker() { this.speakers.push({ name: '', email: '', role: '', bio: '' }); },
|
||||
removeSpeaker(i) { this.speakers.splice(i, 1); if (this.speakers.length === 0) this.addSpeaker(); },
|
||||
}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<h2 class="text-sm font-semibold text-slate-900">Event speaker roster</h2>
|
||||
<p class="mt-0.5 text-xs text-slate-500">Add keynote speakers, panelists, and hosts. Use email when you want to invite them to virtual sessions.</p>
|
||||
</div>
|
||||
<button type="button" @click="addSpeaker()" class="text-xs font-semibold text-indigo-600 hover:text-indigo-800">+ Add speaker</button>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<template x-for="(speaker, index) in speakers" :key="index">
|
||||
<div class="rounded-xl border border-slate-200 p-4 space-y-3">
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<input type="text" :name="'speakers[' + index + '][name]'" x-model="speaker.name" placeholder="Name *"
|
||||
class="rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400/30">
|
||||
<input type="email" :name="'speakers[' + index + '][email]'" x-model="speaker.email" placeholder="Email (optional)"
|
||||
class="rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400/30">
|
||||
</div>
|
||||
<input type="text" :name="'speakers[' + index + '][role]'" x-model="speaker.role" placeholder="Role / session (optional)"
|
||||
class="w-full rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400/30">
|
||||
<textarea :name="'speakers[' + index + '][bio]'" x-model="speaker.bio" rows="2" placeholder="Short bio (optional)"
|
||||
class="w-full rounded-xl border border-slate-200 px-3 py-2 text-sm focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400/30"></textarea>
|
||||
<button type="button" @click="removeSpeaker(index)" class="text-xs font-medium text-red-600 hover:text-red-700">Remove</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-primary w-full">Save speakers</button>
|
||||
</form>
|
||||
|
||||
@if(count($programmeAssignments))
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-6">
|
||||
<h2 class="text-sm font-semibold text-slate-900">From programme schedule</h2>
|
||||
<p class="mt-0.5 text-xs text-slate-500">These hosts are assigned on programme sessions. Edit them on the linked programme.</p>
|
||||
<div class="mt-4 divide-y divide-slate-100">
|
||||
@foreach($programmeAssignments as $assignment)
|
||||
<div class="flex flex-wrap items-start justify-between gap-2 py-3 text-sm">
|
||||
<div>
|
||||
<p class="font-semibold text-slate-900">{{ $assignment['name'] }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $assignment['session'] ?: 'Session' }}@if($assignment['day']) · {{ $assignment['day'] }}@endif@if($assignment['time']) · {{ $assignment['time'] }}@endif</p>
|
||||
</div>
|
||||
<span class="rounded-full bg-slate-100 px-2 py-0.5 text-[11px] font-medium text-slate-600">Programme</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</x-user-layout>
|
||||
@@ -16,6 +16,8 @@
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.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.25Z" />'],
|
||||
['name' => 'Programmes', 'route' => route('programmes.index'), 'active' => request()->routeIs('programmes.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.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.25Z" />'],
|
||||
['name' => 'Speakers', 'route' => route('speakers.index'), 'active' => request()->routeIs('speakers.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 0 1 6 0v8.25a3 3 0 0 1-3 3Z" />'],
|
||||
['name' => 'Payments & Payouts', 'route' => route('events.payouts'), 'active' => request()->routeIs('events.payouts'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 8.25h19.5M2.25 9h19.5m-16.5 5.25h6m-6 2.25h3m-3.75 3h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25v10.5A2.25 2.25 0 0 0 4.5 19.5Z" />'],
|
||||
];
|
||||
|
||||
@@ -4,6 +4,15 @@
|
||||
$evName = $c['name'] ?? $qrCode->label;
|
||||
$isContribution = ($c['mode'] ?? 'ticketing') === 'contributions';
|
||||
$badgeUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=' . urlencode($registration->badge_code);
|
||||
$joinUrl = '';
|
||||
if (in_array($c['format'] ?? 'in_person', ['virtual', 'hybrid'], true)) {
|
||||
foreach ($c['virtual_sessions'] ?? [] as $session) {
|
||||
if (is_array($session) && filled($session['join_url'] ?? '')) {
|
||||
$joinUrl = trim((string) $session['join_url']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -71,6 +80,14 @@
|
||||
@else
|
||||
<p class="mt-5 text-xs text-slate-400">Show this badge code at check-in.</p>
|
||||
@endif
|
||||
|
||||
@if($joinUrl !== '')
|
||||
<a href="{{ $joinUrl }}"
|
||||
class="mt-6 inline-flex w-full items-center justify-center rounded-xl px-4 py-3 text-sm font-bold text-white shadow-sm transition hover:opacity-90"
|
||||
style="background:{{ $evColor }}">
|
||||
Join webinar
|
||||
</a>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user