From c4e1ac19c6a0d1f74191e4c5d9d8fa562452b493 Mon Sep 17 00:00:00 2001 From: isaacclad Date: Sat, 27 Jun 2026 15:46:27 +0000 Subject: [PATCH] Use ladl.link URLs for all front-facing QR and short-link surfaces. Public landing pages, asset paths, payment callbacks, and redirects now go through QrCode::publicPath() / LadillLink instead of ladill.com/q/* routes. Co-authored-by: Cursor --- .../Controllers/Public/DonationController.php | 7 ++- .../Controllers/Public/QrScanController.php | 4 +- .../views/public/qr/document-viewer.blade.php | 2 +- resources/views/public/qr/landing.blade.php | 57 +++++++++++-------- resources/views/qr-codes/badges.blade.php | 2 +- 5 files changed, 41 insertions(+), 31 deletions(-) diff --git a/app/Http/Controllers/Public/DonationController.php b/app/Http/Controllers/Public/DonationController.php index 99aedbb..6b4c992 100644 --- a/app/Http/Controllers/Public/DonationController.php +++ b/app/Http/Controllers/Public/DonationController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Public; use App\Http\Controllers\Controller; use App\Models\QrCode; use App\Services\Give\GiveDonationService; +use App\Support\LadillLink; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -53,15 +54,15 @@ class DonationController extends Controller { $reference = trim((string) $request->query('reference', '')); if ($reference === '') { - return redirect('/q/'.$shortCode)->with('error', 'Missing payment reference.'); + return redirect()->away(LadillLink::url($shortCode))->with('error', 'Missing payment reference.'); } try { $donation = $this->donations->complete($reference); } catch (RuntimeException $e) { - return redirect('/q/'.$shortCode)->with('order_error', $e->getMessage()); + return redirect()->away(LadillLink::url($shortCode))->with('order_error', $e->getMessage()); } catch (\Throwable) { - return redirect('/q/'.$shortCode)->with('order_error', 'Payment could not be verified. Contact the organisation with reference: '.$reference); + return redirect()->away(LadillLink::url($shortCode))->with('order_error', 'Payment could not be verified. Contact the organisation with reference: '.$reference); } return view('public.qr.donation-confirmed', [ diff --git a/app/Http/Controllers/Public/QrScanController.php b/app/Http/Controllers/Public/QrScanController.php index 7ea86c3..ff35099 100644 --- a/app/Http/Controllers/Public/QrScanController.php +++ b/app/Http/Controllers/Public/QrScanController.php @@ -36,7 +36,7 @@ class QrScanController extends Controller } if ($qrCode->isDocumentType()) { - return redirect()->route('qr.public.view', $shortCode); + return redirect()->away($qrCode->publicPath('view')); } if ($qrCode->isBookType()) { @@ -62,7 +62,7 @@ class QrScanController extends Controller return view('public.qr.document-viewer', [ 'qrCode' => $qrCode, - 'fileUrl' => route('qr.public.file', $shortCode), + 'fileUrl' => $qrCode->publicPath('file'), 'allowDownload' => (bool) ($qrCode->content()['allow_download'] ?? true), ]); } diff --git a/resources/views/public/qr/document-viewer.blade.php b/resources/views/public/qr/document-viewer.blade.php index b5f1845..3b66e75 100644 --- a/resources/views/public/qr/document-viewer.blade.php +++ b/resources/views/public/qr/document-viewer.blade.php @@ -111,7 +111,7 @@ - @@ -32,7 +32,7 @@ View document - @@ -62,7 +62,7 @@ {{-- ===== VCARD ===== --}} @elseif($type === \App\Models\QrCode::TYPE_VCARD) @php - $avatarUrl = !empty($content['avatar_path']) ? route('qr.public.vcard.avatar', $qrCode->short_code) : null; + $avatarUrl = !empty($content['avatar_path']) ? $qrCode->publicPath('avatar') : null; $rawSocial = $content['social'] ?? []; $social = []; foreach ($rawSocial as $platform => $url) { @@ -159,8 +159,8 @@ {{-- Save contact button --}}
- + Save Contact @@ -178,8 +178,8 @@ $bizColor = $content['brand_color'] ?? '#1e3a5f'; $bizHasLogo = !empty($content['logo_path']); $bizHasCover = !empty($content['cover_path']); - $bizLogoUrl = $bizHasLogo ? route('qr.public.business.logo', $qrCode->short_code) : null; - $bizCoverUrl = $bizHasCover ? route('qr.public.business.cover', $qrCode->short_code) : null; + $bizLogoUrl = $bizHasLogo ? $qrCode->publicPath('business-logo') : null; + $bizCoverUrl = $bizHasCover ? $qrCode->publicPath('business-cover') : null; $bizInitials = strtoupper(substr($bizName, 0, 1)); $bizRawSocial = $content['social'] ?? []; $bizSocial = []; @@ -313,10 +313,10 @@ $churchColor = $content['brand_color'] ?? '#1a3a5c'; $churchHasLogo = !empty($content['logo_path']); $churchHasCover = !empty($content['cover_path']); - $churchLogoUrl = $churchHasLogo ? route('qr.public.church.logo', $qrCode->short_code) : null; - $churchCoverUrl = $churchHasCover ? route('qr.public.church.cover', $qrCode->short_code) : null; + $churchLogoUrl = $churchHasLogo ? $qrCode->publicPath('church-logo') : null; + $churchCoverUrl = $churchHasCover ? $qrCode->publicPath('church-cover') : null; $churchInitials = strtoupper(substr($churchName, 0, 2)); - $churchAcceptsPay = true; + $churchAcceptsPay = !empty($content['accepts_payment']); $churchCurrency = $content['currency'] ?? 'GHS'; $churchTypes = $content['collection_types'] ?? ['offering', 'tithe', 'donation', 'harvest']; // Normalise legacy lowercase slugs → display strings @@ -325,7 +325,7 @@ $churchTypes, array_map(fn($t) => $legacyLabels[strtolower(trim($t))] ?? trim($t), $churchTypes) ); - $churchOrderRoute = route('qr.public.order', $qrCode->short_code); + $churchOrderRoute = $qrCode->publicPath('order'); $churchCsrf = csrf_token(); @endphp
+ @@ -627,8 +631,8 @@ $evColor = $content['brand_color'] ?? '#4f46e5'; $evHasLogo = !empty($content['logo_path']); $evHasCover = !empty($content['cover_path']); - $evLogoUrl = $evHasLogo ? route('qr.public.event.logo', $qrCode->short_code) : null; - $evCoverUrl = $evHasCover ? route('qr.public.event.cover', $qrCode->short_code) : null; + $evLogoUrl = $evHasLogo ? $qrCode->publicPath('event-logo') : null; + $evCoverUrl = $evHasCover ? $qrCode->publicPath('event-cover') : null; $evName = $content['name'] ?? $qrCode->label; $evInitials = strtoupper(mb_substr($evName, 0, 2)); $evTiers = $content['tiers'] ?? []; @@ -638,7 +642,7 @@ $evMode = in_array($content['mode'] ?? 'ticketing', ['contributions', 'free'], true) ? ($content['mode'] ?? 'ticketing') : 'ticketing'; $evCategories = $content['contribution_categories'] ?? ['Contribution']; $evHeading = $evMode === 'contributions' ? 'Make a contribution' : 'Register'; - $evRegRoute = route('qr.public.event.register', $qrCode->short_code); + $evRegRoute = $qrCode->publicPath('register'); $evCsrf = csrf_token(); @endphp
Your details

- + @foreach($evFields as $field) short_code) : null; + $itinCoverUrl = $itinHasCover ? $qrCode->publicPath('itinerary-cover') : null; $itinTitle = $content['title'] ?? $qrCode->label; $itinDays = $content['days'] ?? []; $multiDay = count($itinDays) > 1; @@ -1023,7 +1029,7 @@

{{ $qrCode->label }}

@foreach($content['images'] ?? [] as $index => $image) - {{ $image['title'] ?? 'Image ' . ($index + 1) }} @@ -1033,7 +1039,7 @@ {{-- ===== APP ===== --}} @elseif($type === \App\Models\QrCode::TYPE_APP) -@php $appIconUrl = !empty($content['icon_path']) ? route('qr.public.app.icon', $qrCode->short_code) : null; @endphp +@php $appIconUrl = !empty($content['icon_path']) ? $qrCode->publicPath('app-icon') : null; @endphp
@if($appIconUrl) @@ -1126,14 +1132,14 @@ $sections = $content['sections'] ?? []; $title = $content['title'] ?? $qrCode->label; $acceptsPayment = (bool) ($content['accepts_payment'] ?? false); - $orderRoute = route('qr.public.order', $qrCode->short_code); + $orderRoute = $qrCode->publicPath('order'); $csrfToken = csrf_token(); $paystackPublicKey = $acceptsPayment ? app(\App\Services\Billing\PaystackService::class)->publicKey() : ''; $brandColor = $content['brand_color'] ?? ($isShop ? '#7c3aed' : '#f97316'); $hasLogo = !empty($content['logo_path']); $hasCover = !empty($content['cover_path']); - $logoUrl = $hasLogo ? route('qr.public.menu.logo', $qrCode->short_code) : null; - $coverUrl = $hasCover ? route('qr.public.menu.cover', $qrCode->short_code) : null; + $logoUrl = $hasLogo ? $qrCode->publicPath('menu-logo') : null; + $coverUrl = $hasCover ? $qrCode->publicPath('menu-cover') : null; $shippingType = $content['shipping_type'] ?? 'none'; $shippingFee = (float) ($content['shipping_fee'] ?? 0); $freeShippingAbove = (float) ($content['free_shipping_above'] ?? 0); @@ -1180,6 +1186,7 @@ async submitOrder() { if (this.cartCount === 0) { this.errorMsg = 'Add at least one item.'; return } if (!this.name.trim()) { this.errorMsg = 'Enter your name.'; return } + if (!this.email.trim() || !this.email.includes('@')) { this.errorMsg = 'Enter a valid email address.'; return } if (!this.phone.trim()) { this.errorMsg = 'Enter your phone number.'; return } this.errorMsg = ''; this.loading = true; @@ -1284,7 +1291,7 @@
{{-- Item image --}} @if($hasImage) - {{ $item['name'] }} @endif @@ -1444,6 +1451,8 @@

Your details

+
diff --git a/resources/views/qr-codes/badges.blade.php b/resources/views/qr-codes/badges.blade.php index b951707..bc18a42 100644 --- a/resources/views/qr-codes/badges.blade.php +++ b/resources/views/qr-codes/badges.blade.php @@ -3,7 +3,7 @@ $evColor = $c['brand_color'] ?? '#4f46e5'; $evName = $c['name'] ?? $qrCode->label; $hasLogo = !empty($c['logo_path']); - $logoUrl = $hasLogo ? route('qr.public.event.logo', $qrCode->short_code) : null; + $logoUrl = $hasLogo ? $qrCode->publicPath('event-logo') : null; $size = $c['badge_size'] ?? '4x3'; // Physical badge dimensions (inches) [$bw, $bh] = match ($size) {