Fix payment QR preview rendering using inline data URIs.
Deploy Ladill Mini / deploy (push) Successful in 44s

Match Events/QR Plus pattern so QR images render without a separate authenticated preview URL, and add a styled preview card on the show page.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-06-07 19:57:55 +00:00
co-authored by Cursor
parent 47b6772295
commit 7eaa0ab23a
5 changed files with 90 additions and 20 deletions
@@ -32,7 +32,14 @@ class PaymentQrController extends Controller
->latest()
->get();
return view('mini.payment-qrs.index', ['qrCodes' => $qrCodes]);
$previewDataUris = $qrCodes->mapWithKeys(function (QrCode $qr) {
return [$qr->id => $this->imageGenerator->previewDataUri($qr)];
});
return view('mini.payment-qrs.index', [
'qrCodes' => $qrCodes,
'previewDataUris' => $previewDataUris,
]);
}
public function create(): View
@@ -67,7 +74,12 @@ class PaymentQrController extends Controller
{
$this->authorizePaymentQr($paymentQr);
return view('mini.payment-qrs.show', ['qrCode' => $paymentQr]);
$previewDataUri = $this->imageGenerator->previewDataUri($paymentQr);
return view('mini.payment-qrs.show', [
'qrCode' => $paymentQr->fresh(),
'previewDataUri' => $previewDataUri,
]);
}
public function update(Request $request, QrCode $paymentQr): RedirectResponse
@@ -1,7 +1,18 @@
<x-user-layout>
<x-slot name="title">Create Payment QR</x-slot>
<div class="mx-auto max-w-2xl space-y-6">
<div>
<div class="flex items-center gap-3 py-1 lg:hidden">
<a href="{{ route('mini.payment-qrs.index') }}"
class="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl border border-slate-200 bg-white text-slate-500 shadow-sm transition hover:text-slate-900">
<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>
</a>
<img src="{{ asset('images/logo/ladillmini-logo.svg') }}?v={{ @filemtime(public_path('images/logo/ladillmini-logo.svg')) ?: '1' }}"
alt="Ladill Mini" class="h-5 w-auto shrink-0">
<span class="min-w-0 flex-1 truncate text-sm font-semibold text-slate-900">Create payment QR</span>
</div>
<div class="hidden lg:block">
<a href="{{ route('mini.payment-qrs.index') }}" class="text-sm text-slate-500 hover:text-slate-700"> Back to payment QRs</a>
<h1 class="mt-2 text-xl font-semibold text-slate-900">Create payment QR</h1>
<p class="mt-1 text-sm text-slate-500">Customers scan, enter an amount, and pay. Your QR is generated automatically no styling needed.</p>
@@ -26,7 +26,7 @@
<p class="mt-1 text-xs text-slate-400">{{ $c['branch_label'] }}</p>
@endif
</div>
<img src="{{ route('mini.payment-qrs.preview', $qr) }}" alt="" class="h-16 w-16 rounded-lg border border-slate-100 bg-white object-contain">
<img src="{{ $previewDataUris[$qr->id] ?? '' }}" alt="" class="h-16 w-16 rounded-lg border border-slate-100 bg-white object-contain p-1">
</div>
<p class="mt-4 truncate text-xs text-indigo-600">{{ $qr->publicUrl() }}</p>
</a>
@@ -0,0 +1,35 @@
@php
$showDownloads = $showDownloads ?? true;
@endphp
<div class="overflow-hidden rounded-2xl border border-slate-200/80 bg-white shadow-sm">
<div class="relative flex items-center justify-center bg-gradient-to-br from-indigo-50/60 via-white to-violet-50/40 px-8 py-10">
<div class="w-full max-w-xs">
<div class="overflow-hidden rounded-2xl bg-white p-4 shadow-2xl ring-1 ring-black/5">
<img src="{{ $previewDataUri }}"
alt="Payment QR code for {{ $qrCode->label }}"
class="aspect-square w-full object-contain">
</div>
</div>
</div>
@if ($showDownloads)
<div class="border-t border-slate-100 bg-slate-50/50 px-6 py-5">
<p class="mb-3 text-[10px] font-semibold uppercase tracking-[0.1em] text-slate-400">Download</p>
<div class="grid grid-cols-3 gap-2">
<a href="{{ route('mini.payment-qrs.download', [$qrCode, 'png']) }}"
class="group flex flex-col items-center gap-1.5 rounded-xl border border-slate-200 bg-white py-3.5 text-center transition hover:border-indigo-300 hover:bg-indigo-50">
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-indigo-700">PNG</span>
</a>
<a href="{{ route('mini.payment-qrs.download', [$qrCode, 'svg']) }}"
class="group flex flex-col items-center gap-1.5 rounded-xl border border-slate-200 bg-white py-3.5 text-center transition hover:border-violet-300 hover:bg-violet-50">
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-violet-700">SVG</span>
</a>
<a href="{{ route('mini.payment-qrs.download', [$qrCode, 'pdf']) }}"
class="group flex flex-col items-center gap-1.5 rounded-xl border border-slate-200 bg-white py-3.5 text-center transition hover:border-rose-300 hover:bg-rose-50">
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-rose-700">PDF</span>
</a>
</div>
</div>
@endif
</div>
+28 -16
View File
@@ -1,28 +1,40 @@
<x-user-layout>
<x-slot name="title">{{ $qrCode->label }}</x-slot>
@php $c = $qrCode->content(); @endphp
<div class="space-y-6">
<div class="flex flex-wrap items-start justify-between gap-4">
<div>
<a href="{{ route('mini.payment-qrs.index') }}" class="text-sm text-slate-500 hover:text-slate-700"> All payment QRs</a>
<h1 class="mt-2 text-xl font-semibold text-slate-900">{{ $qrCode->label }}</h1>
<p class="mt-1 text-sm text-slate-500">{{ $c['business_name'] ?? '' }}@if(!empty($c['branch_label'])) · {{ $c['branch_label'] }}@endif</p>
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ route('mini.payment-qrs.download', [$qrCode, 'png']) }}" class="rounded-lg border border-slate-200 px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50">PNG</a>
<a href="{{ route('mini.payment-qrs.download', [$qrCode, 'svg']) }}" class="rounded-lg border border-slate-200 px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50">SVG</a>
<a href="{{ route('mini.payment-qrs.download', [$qrCode, 'pdf']) }}" class="rounded-lg border border-slate-200 px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-50">PDF</a>
</div>
<div class="mx-auto max-w-6xl space-y-6">
<div class="flex items-center gap-3 py-1 lg:hidden">
<a href="{{ route('mini.payment-qrs.index') }}"
class="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl border border-slate-200 bg-white text-slate-500 shadow-sm transition hover:text-slate-900">
<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>
<img src="{{ asset('images/logo/ladillmini-logo.svg') }}?v={{ @filemtime(public_path('images/logo/ladillmini-logo.svg')) ?: '1' }}"
alt="Ladill Mini" class="h-5 w-auto shrink-0">
<span class="min-w-0 flex-1 truncate text-sm font-semibold text-slate-900">{{ $qrCode->label }}</span>
</div>
<div class="hidden lg:block">
<a href="{{ route('mini.payment-qrs.index') }}" class="text-sm text-slate-500 hover:text-slate-700"> All payment QRs</a>
<h1 class="mt-2 text-xl font-semibold text-slate-900">{{ $qrCode->label }}</h1>
<p class="mt-1 text-sm text-slate-500">{{ $c['business_name'] ?? '' }}@if(!empty($c['branch_label'])) · {{ $c['branch_label'] }}@endif</p>
</div>
@if(session('success'))
<div class="rounded-xl border border-emerald-100 bg-emerald-50 px-4 py-3 text-sm text-emerald-800">{{ session('success') }}</div>
@endif
<div class="grid gap-6 lg:grid-cols-2">
<div class="flex flex-col items-center rounded-2xl border border-slate-200 bg-white p-8">
<img src="{{ route('mini.payment-qrs.preview', $qrCode) }}" alt="QR code" class="max-h-64 w-auto">
<div class="grid gap-6 lg:grid-cols-[380px_1fr]">
<div class="lg:sticky lg:top-6 lg:self-start">
@include('mini.payment-qrs.partials.preview-card', [
'qrCode' => $qrCode,
'previewDataUri' => $previewDataUri,
'showDownloads' => true,
])
<p class="mt-4 break-all text-center text-sm text-indigo-600">{{ $qrCode->publicUrl() }}</p>
<p class="mt-2 text-xs text-slate-500">Standard black-and-white QR ready to print at your till or counter.</p>
<p class="mt-2 text-center text-xs text-slate-500">Standard black-and-white QR ready to print at your till or counter.</p>
</div>
<form method="post" action="{{ route('mini.payment-qrs.update', $qrCode) }}" enctype="multipart/form-data" class="space-y-4 rounded-2xl border border-slate-200 bg-white p-6">
@csrf
@method('PATCH')