Remove redundant type picker from event and programme creation.
Deploy Ladill Events / deploy (push) Failing after 23s
Deploy Ladill Events / deploy (push) Failing after 23s
Events is a single-product app — type is implicit on create, so drop the Type card, default-type setting, and rebrand the create flow copy. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,7 +8,6 @@ use App\Services\Billing\BillingClient;
|
||||
use App\Support\Qr\QrCornerStyleCatalog;
|
||||
use App\Support\Qr\QrFrameStyleCatalog;
|
||||
use App\Support\Qr\QrModuleStyleCatalog;
|
||||
use App\Support\Qr\QrTypeCatalog;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
@@ -71,7 +70,6 @@ class AccountController extends Controller
|
||||
'account' => $account,
|
||||
'settings' => $settings,
|
||||
'style' => $style,
|
||||
'types' => QrTypeCatalog::all(),
|
||||
'moduleStyles' => QrModuleStyleCatalog::visible(),
|
||||
'cornerOuterStyles' => QrCornerStyleCatalog::outerStyles(),
|
||||
'cornerInnerStyles' => QrCornerStyleCatalog::innerStyles(),
|
||||
@@ -87,7 +85,6 @@ class AccountController extends Controller
|
||||
'notify_email' => ['nullable', 'email', 'max:255'],
|
||||
'product_updates' => ['nullable', 'boolean'],
|
||||
'low_balance_alerts' => ['nullable', 'boolean'],
|
||||
'default_type' => ['nullable', 'in:'.implode(',', QrTypeCatalog::eventsTypes())],
|
||||
'default_style' => ['nullable', 'array'],
|
||||
'default_style.foreground' => ['nullable', 'regex:/^#[0-9a-fA-F]{6}$/'],
|
||||
'default_style.background' => ['nullable', 'regex:/^#[0-9a-fA-F]{6}$/'],
|
||||
@@ -111,7 +108,6 @@ class AccountController extends Controller
|
||||
'notify_email' => $data['notify_email'] ?? null,
|
||||
'product_updates' => $request->boolean('product_updates'),
|
||||
'low_balance_alerts' => $request->boolean('low_balance_alerts'),
|
||||
'default_type' => $data['default_type'] ?? null,
|
||||
'default_style' => QrSetting::sanitizeDefaultStyle($data['default_style'] ?? null),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -79,7 +79,6 @@ class QrCodeController extends Controller
|
||||
|
||||
return view('qr-codes.create', [
|
||||
'wallet' => $wallet,
|
||||
'types' => collect(QrTypeCatalog::all())->only([$requestedType])->all(),
|
||||
'requestedType' => $requestedType,
|
||||
'moduleStyles' => QrModuleStyleCatalog::visible(),
|
||||
'cornerOuterStyles' => QrCornerStyleCatalog::outerStyles(),
|
||||
@@ -89,7 +88,6 @@ class QrCodeController extends Controller
|
||||
'minTopup' => QrWallet::minTopupGhs(),
|
||||
'ladillWalletBalance' => $this->platformBilling->balanceMinor($account->public_id) / 100,
|
||||
'topupUrl' => 'https://'.config('app.account_domain').'/wallet',
|
||||
'defaultType' => $qrSettings->resolvedDefaultType(),
|
||||
'accountDefaultStyle' => $qrSettings->resolvedDefaultStyle(),
|
||||
]);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.8 KiB |
@@ -1,9 +1,10 @@
|
||||
<x-user-layout>
|
||||
<x-slot name="title">Create QR Code</x-slot>
|
||||
|
||||
@php
|
||||
$createType = old('type', $requestedType ?? \App\Models\QrCode::TYPE_EVENT);
|
||||
$isProgramme = $createType === \App\Models\QrCode::TYPE_ITINERARY;
|
||||
$defaultStyle = \App\Support\Qr\QrStyleDefaults::merge(old('style') ?: ($accountDefaultStyle ?? null));
|
||||
@endphp
|
||||
<x-slot name="title">{{ $isProgramme ? 'New programme' : 'Create event' }}</x-slot>
|
||||
|
||||
<div class="mx-auto max-w-6xl space-y-6"
|
||||
x-data="qrCustomizer({
|
||||
@@ -14,7 +15,7 @@
|
||||
balance: @js((float) $wallet->spendableBalance()),
|
||||
price: @js((float) $pricePerQr),
|
||||
topupUrl: @js($topupUrl),
|
||||
type: @js(old('type', $defaultType ?? 'url')),
|
||||
type: @js($createType),
|
||||
})">
|
||||
|
||||
@if(session('error'))
|
||||
@@ -23,29 +24,30 @@
|
||||
|
||||
{{-- Mobile page header --}}
|
||||
<div class="flex items-center gap-3 py-1 lg:hidden">
|
||||
<a href="{{ route('events.index') }}"
|
||||
<a href="{{ $isProgramme ? route('programmes.index') : route('events.index') }}"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-xl border border-slate-200 bg-white shadow-sm text-slate-500 hover:text-slate-900 transition">
|
||||
<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="M6 18 18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</a>
|
||||
<span class="text-sm font-semibold text-slate-900">Create QR code</span>
|
||||
<span class="text-sm font-semibold text-slate-900">{{ $isProgramme ? 'New programme' : 'Create event' }}</span>
|
||||
</div>
|
||||
|
||||
{{-- Desktop page header --}}
|
||||
<div class="hidden lg:block">
|
||||
<a href="{{ route('events.index') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
||||
<a href="{{ $isProgramme ? route('programmes.index') : 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>
|
||||
QR Codes
|
||||
{{ $isProgramme ? 'Programmes' : 'Events' }}
|
||||
</a>
|
||||
<h1 class="mt-2 text-2xl font-bold text-slate-900">Create QR code</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">Customize your code, then create.</p>
|
||||
<h1 class="mt-2 text-2xl font-bold text-slate-900">{{ $isProgramme ? 'New programme' : 'Create event' }}</h1>
|
||||
<p class="mt-1 text-sm text-slate-500">{{ $isProgramme ? 'Build a schedule outline and share it with attendees.' : 'Set up ticketing, registration, and your event QR.' }}</p>
|
||||
</div>
|
||||
|
||||
<form x-ref="createForm" action="{{ route('events.store') }}" method="POST" enctype="multipart/form-data"
|
||||
class="grid grid-cols-1 gap-8 lg:grid-cols-[380px_1fr]"
|
||||
@submit="submitOrTopup($event)">
|
||||
@csrf
|
||||
<input type="hidden" name="type" value="{{ $createType }}">
|
||||
|
||||
{{-- Left: Sticky preview (desktop only) --}}
|
||||
<div class="hidden lg:block lg:sticky lg:top-6 lg:self-start">
|
||||
@@ -58,8 +60,8 @@
|
||||
{{-- Content first --}}
|
||||
<div class="overflow-hidden rounded-2xl border border-slate-200/80 bg-white shadow-sm">
|
||||
<div class="border-b border-slate-100 bg-slate-50/70 px-5 py-4">
|
||||
<h2 class="text-sm font-semibold text-slate-900">Content</h2>
|
||||
<p class="mt-0.5 text-xs text-slate-400">What should this QR code link to?</p>
|
||||
<h2 class="text-sm font-semibold text-slate-900">{{ $isProgramme ? 'Programme details' : 'Event details' }}</h2>
|
||||
<p class="mt-0.5 text-xs text-slate-400">{{ $isProgramme ? 'Title, schedule, and venue for this outline.' : 'Name, dates, ticketing, and registration settings.' }}</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4 p-5">
|
||||
@@ -67,7 +69,7 @@
|
||||
<label class="block text-xs font-semibold text-slate-600">Label</label>
|
||||
<input type="text" name="label" value="{{ old('label') }}" required maxlength="120"
|
||||
class="mt-1.5 w-full rounded-xl border border-slate-200 bg-white px-3.5 py-2.5 text-sm placeholder:text-slate-400 focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400/30"
|
||||
placeholder="e.g. Shop flyer, WiFi guest, Menu">
|
||||
placeholder="{{ $isProgramme ? 'e.g. Annual conference programme' : 'e.g. Tech summit 2026' }}">
|
||||
</div>
|
||||
|
||||
{{-- Custom link --}}
|
||||
@@ -131,29 +133,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-semibold text-slate-600">Type</label>
|
||||
<div class="mt-2 grid grid-cols-2 gap-2">
|
||||
@foreach($types as $key => $meta)
|
||||
<label class="cursor-pointer rounded-xl border-2 p-3 transition-all"
|
||||
:class="type === '{{ $key }}' ? 'border-indigo-500 bg-indigo-50/60' : 'border-slate-200 hover:border-slate-300'">
|
||||
<input type="radio" name="type" value="{{ $key }}" x-model="type" class="sr-only">
|
||||
@if(!empty($meta['icon']))
|
||||
<img src="{{ \App\Support\Qr\QrTypeCatalog::iconUrl($meta['icon']) }}" alt="" class="mb-1.5 h-5 w-5 text-slate-900">
|
||||
@endif
|
||||
<p class="text-sm font-semibold text-slate-900">{{ $meta['label'] }}</p>
|
||||
<p class="mt-0.5 text-[11px] leading-4 text-slate-400">{{ $meta['description'] }}</p>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
@include('qr-codes.partials.type-fields-create')
|
||||
</div>
|
||||
|
||||
<p class="rounded-xl bg-slate-50 px-3.5 py-2.5 text-xs leading-5 text-slate-400">
|
||||
Your QR always points to a Ladill short link. Change the destination any time without reprinting.
|
||||
Attendees scan your Ladill event link — update details anytime without reprinting the QR.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -171,7 +156,7 @@
|
||||
<button type="button"
|
||||
@click="submitOrTopup($event)"
|
||||
class="hidden lg:block w-full rounded-xl bg-indigo-600 py-3 text-sm font-semibold text-white shadow-sm transition hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
|
||||
Create QR code
|
||||
{{ $isProgramme ? 'Create programme' : 'Create event' }}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -50,19 +50,6 @@
|
||||
<h2 class="text-sm font-semibold text-slate-900">New code defaults</h2>
|
||||
<p class="mt-1 text-xs text-slate-500">Pre-fill the create screen so every new QR starts with your brand look.</p>
|
||||
|
||||
<div class="mt-4">
|
||||
<label for="default_type" class="block text-[11px] font-medium text-slate-500">Default type</label>
|
||||
<select id="default_type" name="default_type"
|
||||
class="mt-1 w-full rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none focus:ring-2 focus:ring-indigo-100">
|
||||
@foreach ($types as $key => $meta)
|
||||
<option value="{{ $key }}" @selected(old('default_type', $settings->default_type ?? 'url') === $key)>
|
||||
{{ $meta['label'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('default_type') <p class="mt-1 text-xs text-rose-600">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label for="foreground" class="block text-[11px] font-medium text-slate-500">Foreground</label>
|
||||
|
||||
@@ -43,7 +43,6 @@ class QrSettingsTest extends TestCase
|
||||
'notify_email' => 'alerts@example.com',
|
||||
'product_updates' => '1',
|
||||
'low_balance_alerts' => '0',
|
||||
'default_type' => QrCode::TYPE_EVENT,
|
||||
'default_style' => [
|
||||
'foreground' => '#112233',
|
||||
'background' => '#ffffff',
|
||||
@@ -61,7 +60,6 @@ class QrSettingsTest extends TestCase
|
||||
$this->assertSame('alerts@example.com', $settings->notify_email);
|
||||
$this->assertTrue($settings->product_updates);
|
||||
$this->assertFalse($settings->low_balance_alerts);
|
||||
$this->assertSame(QrCode::TYPE_EVENT, $settings->default_type);
|
||||
$this->assertSame('#112233', $settings->resolvedDefaultStyle()['foreground']);
|
||||
$this->assertSame('scan_me', $settings->resolvedDefaultStyle()['frame_style']);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user