Fix QR codes views to use user.qr-codes route names.
Deploy Ladill QR Plus / deploy (push) Successful in 56s
Deploy Ladill QR Plus / deploy (push) Successful in 56s
Removes missing topup route/modal and sends low-balance users to the platform wallet. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -20,8 +20,10 @@ use Illuminate\Http\RedirectResponse;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
use Throwable;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
|
||||||
@@ -45,12 +47,22 @@ class QrCodeController extends Controller
|
|||||||
->latest()
|
->latest()
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
$ladillWalletBalance = 0.0;
|
||||||
|
try {
|
||||||
|
$ladillWalletBalance = $this->platformBilling->balanceMinor($user->public_id) / 100;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
Log::warning('QR Plus index could not load Ladill wallet balance', [
|
||||||
|
'user' => $user->public_id,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return view('qr-codes.index', [
|
return view('qr-codes.index', [
|
||||||
'wallet' => $wallet,
|
'wallet' => $wallet,
|
||||||
'qrCodes' => $qrCodes,
|
'qrCodes' => $qrCodes,
|
||||||
'pricePerQr' => QrWallet::pricePerQr(),
|
'pricePerQr' => QrWallet::pricePerQr(),
|
||||||
'minTopup' => QrWallet::minTopupGhs(),
|
'minTopup' => QrWallet::minTopupGhs(),
|
||||||
'ladillWalletBalance' => $this->platformBilling->balanceMinor($user->public_id) / 100,
|
'ladillWalletBalance' => $ladillWalletBalance,
|
||||||
'topupUrl' => 'https://'.config('app.account_domain').'/wallet',
|
'topupUrl' => 'https://'.config('app.account_domain').'/wallet',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
balance: Number(config.balance ?? 0),
|
balance: Number(config.balance ?? 0),
|
||||||
price: Number(config.price ?? 0),
|
price: Number(config.price ?? 0),
|
||||||
modalId: config.modalId ?? null,
|
modalId: config.modalId ?? null,
|
||||||
|
topupUrl: config.topupUrl ?? null,
|
||||||
href: config.href ?? null,
|
href: config.href ?? null,
|
||||||
requiresPayment: Object.prototype.hasOwnProperty.call(config, 'requiresPayment')
|
requiresPayment: Object.prototype.hasOwnProperty.call(config, 'requiresPayment')
|
||||||
? config.requiresPayment !== false
|
? config.requiresPayment !== false
|
||||||
@@ -367,6 +368,11 @@ document.addEventListener('alpine:init', () => {
|
|||||||
return this.needsTopupFor(this.requiresPayment);
|
return this.needsTopupFor(this.requiresPayment);
|
||||||
},
|
},
|
||||||
openTopup() {
|
openTopup() {
|
||||||
|
if (this.topupUrl) {
|
||||||
|
window.location.href = this.topupUrl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (! this.modalId) {
|
if (! this.modalId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
selected: [],
|
selected: [],
|
||||||
toggle(id) { const i = this.selected.indexOf(id); i === -1 ? this.selected.push(id) : this.selected.splice(i, 1); },
|
toggle(id) { const i = this.selected.indexOf(id); i === -1 ? this.selected.push(id) : this.selected.splice(i, 1); },
|
||||||
get qs() { return this.selected.map(id => 'ids[]=' + id).join('&'); },
|
get qs() { return this.selected.map(id => 'ids[]=' + id).join('&'); },
|
||||||
printSelected() { window.open(@js(route('qr-codes.badges', $qrCode)) + '?auto=1&' + this.qs, '_blank'); },
|
printSelected() { window.open(@js(route('user.qr-codes.badges', $qrCode)) + '?auto=1&' + this.qs, '_blank'); },
|
||||||
zplSelected() { window.location = @js(route('qr-codes.badges.zpl', $qrCode)) + '?' + this.qs; }
|
zplSelected() { window.location = @js(route('user.qr-codes.badges.zpl', $qrCode)) + '?' + this.qs; }
|
||||||
}">
|
}">
|
||||||
|
|
||||||
{{-- Flash --}}
|
{{-- Flash --}}
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
{{-- Header --}}
|
{{-- Header --}}
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ route('qr-codes.show', $qrCode) }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
<a href="{{ route('user.qr-codes.show', $qrCode) }}" 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>
|
<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>
|
||||||
{{ $qrCode->label }}
|
{{ $qrCode->label }}
|
||||||
</a>
|
</a>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<p class="text-xs text-slate-500">Email & text the <span class="font-medium text-slate-600">{{ $programme->label }}</span> programme link to all confirmed attendees.</p>
|
<p class="text-xs text-slate-500">Email & text the <span class="font-medium text-slate-600">{{ $programme->label }}</span> programme link to all confirmed attendees.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form method="POST" action="{{ route('qr-codes.attendees.share-programme', $qrCode) }}"
|
<form method="POST" action="{{ route('user.qr-codes.attendees.share-programme', $qrCode) }}"
|
||||||
x-data="{ busy: false }"
|
x-data="{ busy: false }"
|
||||||
@submit="if (!confirm('Send the programme outline to all confirmed attendees by email and SMS?')) { $event.preventDefault(); return; } busy = true;"
|
@submit="if (!confirm('Send the programme outline to all confirmed attendees by email and SMS?')) { $event.preventDefault(); return; } busy = true;"
|
||||||
class="shrink-0">
|
class="shrink-0">
|
||||||
@@ -90,9 +90,9 @@
|
|||||||
class="rounded-xl bg-indigo-600 px-3.5 py-2 text-xs font-semibold text-white hover:bg-indigo-700 transition">Print selected</button>
|
class="rounded-xl bg-indigo-600 px-3.5 py-2 text-xs font-semibold text-white hover:bg-indigo-700 transition">Print selected</button>
|
||||||
<button type="button" x-show="selected.length" x-cloak @click="zplSelected()"
|
<button type="button" x-show="selected.length" x-cloak @click="zplSelected()"
|
||||||
class="rounded-xl border border-slate-200 px-3.5 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-50 transition">ZPL selected</button>
|
class="rounded-xl border border-slate-200 px-3.5 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-50 transition">ZPL selected</button>
|
||||||
<a href="{{ route('qr-codes.badges', $qrCode) }}?auto=1" target="_blank"
|
<a href="{{ route('user.qr-codes.badges', $qrCode) }}?auto=1" target="_blank"
|
||||||
class="rounded-xl bg-slate-900 px-3.5 py-2 text-xs font-semibold text-white hover:bg-slate-800 transition">Print all badges</a>
|
class="rounded-xl bg-slate-900 px-3.5 py-2 text-xs font-semibold text-white hover:bg-slate-800 transition">Print all badges</a>
|
||||||
<a href="{{ route('qr-codes.badges.zpl', $qrCode) }}"
|
<a href="{{ route('user.qr-codes.badges.zpl', $qrCode) }}"
|
||||||
class="rounded-xl border border-slate-200 px-3.5 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-50 transition">Download ZPL</a>
|
class="rounded-xl border border-slate-200 px-3.5 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-50 transition">Download ZPL</a>
|
||||||
</div>
|
</div>
|
||||||
@endunless
|
@endunless
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
</td>
|
</td>
|
||||||
@unless($isContribution)
|
@unless($isContribution)
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
<form method="POST" action="{{ route('qr-codes.attendees.check-in', [$qrCode, $reg]) }}">
|
<form method="POST" action="{{ route('user.qr-codes.attendees.check-in', [$qrCode, $reg]) }}">
|
||||||
@csrf @method('PATCH')
|
@csrf @method('PATCH')
|
||||||
<button type="submit" class="rounded-lg border px-2.5 py-1 text-xs font-semibold transition {{ $reg->checked_in_at ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-slate-200 text-slate-500 hover:bg-slate-50' }}">
|
<button type="submit" class="rounded-lg border px-2.5 py-1 text-xs font-semibold transition {{ $reg->checked_in_at ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-slate-200 text-slate-500 hover:bg-slate-50' }}">
|
||||||
{{ $reg->checked_in_at ? '✓ In' : 'Check in' }}
|
{{ $reg->checked_in_at ? '✓ In' : 'Check in' }}
|
||||||
|
|||||||
@@ -2,20 +2,18 @@
|
|||||||
<x-slot name="title">Create QR Code</x-slot>
|
<x-slot name="title">Create QR Code</x-slot>
|
||||||
|
|
||||||
@php
|
@php
|
||||||
$modalId = 'service-topup-qr';
|
|
||||||
$openTopup = session('open_topup_modal') === 'qr';
|
|
||||||
$defaultStyle = \App\Support\Qr\QrStyleDefaults::merge(old('style'));
|
$defaultStyle = \App\Support\Qr\QrStyleDefaults::merge(old('style'));
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<div class="mx-auto max-w-6xl space-y-6"
|
<div class="mx-auto max-w-6xl space-y-6"
|
||||||
x-data="qrCustomizer({
|
x-data="qrCustomizer({
|
||||||
previewUrl: @js(route('qr-codes.style-preview')),
|
previewUrl: @js(route('user.qr-codes.style-preview')),
|
||||||
csrf: @js(csrf_token()),
|
csrf: @js(csrf_token()),
|
||||||
shortCode: 'preview',
|
shortCode: 'preview',
|
||||||
style: @js($defaultStyle),
|
style: @js($defaultStyle),
|
||||||
balance: @js((float) $wallet->spendableBalance()),
|
balance: @js((float) $wallet->spendableBalance()),
|
||||||
price: @js((float) $pricePerQr),
|
price: @js((float) $pricePerQr),
|
||||||
topupModalId: @js($modalId),
|
topupUrl: @js($topupUrl),
|
||||||
type: @js(old('type', 'url')),
|
type: @js(old('type', 'url')),
|
||||||
})">
|
})">
|
||||||
|
|
||||||
@@ -25,7 +23,7 @@
|
|||||||
|
|
||||||
{{-- Mobile page header --}}
|
{{-- Mobile page header --}}
|
||||||
<div class="flex items-center gap-3 py-1 lg:hidden">
|
<div class="flex items-center gap-3 py-1 lg:hidden">
|
||||||
<a href="{{ route('qr-codes.index') }}"
|
<a href="{{ route('user.qr-codes.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">
|
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">
|
<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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
|
||||||
@@ -36,7 +34,7 @@
|
|||||||
|
|
||||||
{{-- Desktop page header --}}
|
{{-- Desktop page header --}}
|
||||||
<div class="hidden lg:block">
|
<div class="hidden lg:block">
|
||||||
<a href="{{ route('qr-codes.index') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
<a href="{{ route('user.qr-codes.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>
|
<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
|
QR Codes
|
||||||
</a>
|
</a>
|
||||||
@@ -44,7 +42,7 @@
|
|||||||
<p class="mt-1 text-sm text-slate-500">Customize your code, then create.</p>
|
<p class="mt-1 text-sm text-slate-500">Customize your code, then create.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form x-ref="createForm" action="{{ route('qr-codes.store') }}" method="POST" enctype="multipart/form-data"
|
<form x-ref="createForm" action="{{ route('user.qr-codes.store') }}" method="POST" enctype="multipart/form-data"
|
||||||
class="grid grid-cols-1 gap-8 lg:grid-cols-[380px_1fr]"
|
class="grid grid-cols-1 gap-8 lg:grid-cols-[380px_1fr]"
|
||||||
@submit="submitOrTopup($event)">
|
@submit="submitOrTopup($event)">
|
||||||
@csrf
|
@csrf
|
||||||
@@ -77,7 +75,7 @@
|
|||||||
slug: @js(old('custom_short_code', '')),
|
slug: @js(old('custom_short_code', '')),
|
||||||
status: '',
|
status: '',
|
||||||
timer: null,
|
timer: null,
|
||||||
checkUrl: @js(route('qr-codes.check-slug')),
|
checkUrl: @js(route('user.qr-codes.check-slug')),
|
||||||
baseUrl: @js(\App\Models\QrCode::publicBaseUrl() . '/q'),
|
baseUrl: @js(\App\Models\QrCode::publicBaseUrl() . '/q'),
|
||||||
check() {
|
check() {
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
@@ -250,18 +248,4 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<x-user.service-topup-modal
|
|
||||||
:id="$modalId"
|
|
||||||
title="Add QR credits"
|
|
||||||
description="Top up your QR balance to create codes."
|
|
||||||
:topup-action="route('qr-codes.topup')"
|
|
||||||
:min-topup="$minTopup"
|
|
||||||
:suggested-amount="max($minTopup, $pricePerQr)"
|
|
||||||
:ladill-wallet-balance="$ladillWalletBalance"
|
|
||||||
:service-balance="$wallet->spendableBalance()"
|
|
||||||
service-balance-label="QR balance"
|
|
||||||
:return-url="url()->current()"
|
|
||||||
:open-on-load="$openTopup"
|
|
||||||
/>
|
|
||||||
</x-user-layout>
|
</x-user-layout>
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
<x-user-layout>
|
<x-user-layout>
|
||||||
<x-slot name="title">QR Codes</x-slot>
|
<x-slot name="title">QR Codes</x-slot>
|
||||||
|
|
||||||
@php
|
|
||||||
$modalId = 'service-topup-qr';
|
|
||||||
$openTopup = session('open_topup_modal') === 'qr';
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="space-y-6"
|
<div class="space-y-6"
|
||||||
x-data="balanceGate({
|
x-data="balanceGate({
|
||||||
balance: @js((float) $wallet->spendableBalance()),
|
balance: @js((float) $wallet->spendableBalance()),
|
||||||
price: @js((float) $pricePerQr),
|
price: @js((float) $pricePerQr),
|
||||||
modalId: @js($modalId),
|
topupUrl: @js($topupUrl),
|
||||||
href: @js(route('qr-codes.create')),
|
href: @js(route('user.qr-codes.create')),
|
||||||
})">
|
})">
|
||||||
@foreach(['success', 'error'] as $flash)
|
@foreach(['success', 'error'] as $flash)
|
||||||
@if(session($flash))
|
@if(session($flash))
|
||||||
@@ -70,7 +65,7 @@
|
|||||||
@else
|
@else
|
||||||
<div class="divide-y divide-slate-100">
|
<div class="divide-y divide-slate-100">
|
||||||
@foreach($qrCodes as $code)
|
@foreach($qrCodes as $code)
|
||||||
<a href="{{ route('qr-codes.show', $code) }}" class="flex items-center gap-4 px-6 py-4 transition hover:bg-slate-50">
|
<a href="{{ route('user.qr-codes.show', $code) }}" 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-lg {{ $code->is_active ? 'bg-violet-100 text-violet-600' : 'bg-slate-100 text-slate-400' }}">
|
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg {{ $code->is_active ? 'bg-violet-100 text-violet-600' : 'bg-slate-100 text-slate-400' }}">
|
||||||
<x-icons.qr-code class="h-5 w-5" />
|
<x-icons.qr-code class="h-5 w-5" />
|
||||||
</div>
|
</div>
|
||||||
@@ -88,18 +83,4 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<x-user.service-topup-modal
|
|
||||||
:id="$modalId"
|
|
||||||
title="Add QR credits"
|
|
||||||
description="Top up your QR balance to create codes."
|
|
||||||
:topup-action="route('qr-codes.topup')"
|
|
||||||
:min-topup="$minTopup"
|
|
||||||
:suggested-amount="max($minTopup, $pricePerQr)"
|
|
||||||
:ladill-wallet-balance="$ladillWalletBalance"
|
|
||||||
:service-balance="$wallet->spendableBalance()"
|
|
||||||
service-balance-label="QR balance"
|
|
||||||
:return-url="route('qr-codes.index')"
|
|
||||||
:open-on-load="$openTopup"
|
|
||||||
/>
|
|
||||||
</x-user-layout>
|
</x-user-layout>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
balance: config.balance ?? null,
|
balance: config.balance ?? null,
|
||||||
price: config.price ?? null,
|
price: config.price ?? null,
|
||||||
topupModalId: config.topupModalId ?? null,
|
topupModalId: config.topupModalId ?? null,
|
||||||
|
topupUrl: config.topupUrl ?? null,
|
||||||
canonicalSyncUrl: config.canonicalSyncUrl ?? null,
|
canonicalSyncUrl: config.canonicalSyncUrl ?? null,
|
||||||
csrf: config.csrf ?? null,
|
csrf: config.csrf ?? null,
|
||||||
_canonicalSynced: false,
|
_canonicalSynced: false,
|
||||||
@@ -225,28 +226,36 @@
|
|||||||
Object.assign(this, presets[preset] || presets.square);
|
Object.assign(this, presets[preset] || presets.square);
|
||||||
this.schedulePreview();
|
this.schedulePreview();
|
||||||
},
|
},
|
||||||
checkBalance(event) {
|
redirectTopup() {
|
||||||
if (this.balance === null || this.price === null || !this.topupModalId) {
|
if (this.topupUrl) {
|
||||||
return;
|
window.location.href = this.topupUrl;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.balance <= 0 || this.balance < this.price) {
|
|
||||||
event?.preventDefault();
|
|
||||||
window.dispatchEvent(new CustomEvent('open-modal', {
|
|
||||||
detail: this.topupModalId,
|
|
||||||
bubbles: true,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
submitOrTopup(event) {
|
|
||||||
if (this.balance <= 0 || this.balance < this.price) {
|
|
||||||
event?.preventDefault();
|
|
||||||
if (this.topupModalId) {
|
if (this.topupModalId) {
|
||||||
window.dispatchEvent(new CustomEvent('open-modal', {
|
window.dispatchEvent(new CustomEvent('open-modal', {
|
||||||
detail: this.topupModalId,
|
detail: this.topupModalId,
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
}));
|
}));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
checkBalance(event) {
|
||||||
|
if (this.balance === null || this.price === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.balance <= 0 || this.balance < this.price) {
|
||||||
|
event?.preventDefault();
|
||||||
|
this.redirectTopup();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submitOrTopup(event) {
|
||||||
|
if (this.balance <= 0 || this.balance < this.price) {
|
||||||
|
event?.preventDefault();
|
||||||
|
this.redirectTopup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
<p class="mb-3 text-[10px] font-semibold uppercase tracking-[0.1em] text-slate-400">Download & Share</p>
|
<p class="mb-3 text-[10px] font-semibold uppercase tracking-[0.1em] text-slate-400">Download & Share</p>
|
||||||
<div class="grid grid-cols-4 gap-2">
|
<div class="grid grid-cols-4 gap-2">
|
||||||
|
|
||||||
<a href="{{ route('qr-codes.download', [$qrCode, 'png']) }}"
|
<a href="{{ route('user.qr-codes.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">
|
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">
|
||||||
<svg class="h-4 w-4 text-slate-400 transition group-hover:text-indigo-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
<svg class="h-4 w-4 text-slate-400 transition group-hover:text-indigo-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12M12 16.5V3"/>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12M12 16.5V3"/>
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-indigo-700">PNG</span>
|
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-indigo-700">PNG</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ route('qr-codes.download', [$qrCode, 'svg']) }}"
|
<a href="{{ route('user.qr-codes.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">
|
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">
|
||||||
<svg class="h-4 w-4 text-slate-400 transition group-hover:text-violet-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
<svg class="h-4 w-4 text-slate-400 transition group-hover:text-violet-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21 3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5"/>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21 3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5"/>
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-violet-700">SVG</span>
|
<span class="text-xs font-semibold text-slate-600 transition group-hover:text-violet-700">SVG</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ route('qr-codes.download', [$qrCode, 'pdf']) }}"
|
<a href="{{ route('user.qr-codes.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">
|
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">
|
||||||
<svg class="h-4 w-4 text-slate-400 transition group-hover:text-rose-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
<svg class="h-4 w-4 text-slate-400 transition group-hover:text-rose-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/>
|
||||||
|
|||||||
@@ -596,11 +596,13 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="{{ route('qr-codes.attendees', $qrCode) }}"
|
@if (Route::has('user.qr-codes.attendees'))
|
||||||
|
<a href="{{ route('user.qr-codes.attendees', $qrCode) }}"
|
||||||
class="flex items-center justify-center gap-2 rounded-xl border border-indigo-200 bg-indigo-50 px-4 py-3 text-sm font-semibold text-indigo-700 hover:bg-indigo-100 transition">
|
class="flex items-center justify-center gap-2 rounded-xl border border-indigo-200 bg-indigo-50 px-4 py-3 text-sm font-semibold text-indigo-700 hover:bg-indigo-100 transition">
|
||||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/></svg>
|
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/></svg>
|
||||||
Manage attendees & print badges
|
Manage attendees & print badges
|
||||||
</a>
|
</a>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@elseif($qrCode->type === \App\Models\QrCode::TYPE_ITINERARY)
|
@elseif($qrCode->type === \App\Models\QrCode::TYPE_ITINERARY)
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
<div class="mx-auto max-w-6xl space-y-6"
|
<div class="mx-auto max-w-6xl space-y-6"
|
||||||
x-data="qrCustomizer({
|
x-data="qrCustomizer({
|
||||||
previewUrl: @js(route('qr-codes.style-preview')),
|
previewUrl: @js(route('user.qr-codes.style-preview')),
|
||||||
csrf: @js(csrf_token()),
|
csrf: @js(csrf_token()),
|
||||||
canonicalSyncUrl: @js(route('qr-codes.canonical-image', $qrCode)),
|
canonicalSyncUrl: @js(route('user.qr-codes.canonical-image', $qrCode)),
|
||||||
shortCode: @js($qrCode->short_code),
|
shortCode: @js($qrCode->short_code),
|
||||||
qrData: @js($qrCode->encodedPayload()),
|
qrData: @js($qrCode->encodedPayload()),
|
||||||
initialPreview: @js($previewDataUri),
|
initialPreview: @js($previewDataUri),
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
{{-- Mobile page header --}}
|
{{-- Mobile page header --}}
|
||||||
<div class="flex items-center gap-3 py-1 lg:hidden">
|
<div class="flex items-center gap-3 py-1 lg:hidden">
|
||||||
<a href="{{ route('qr-codes.index') }}"
|
<a href="{{ route('user.qr-codes.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">
|
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">
|
<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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
{{-- Desktop page header --}}
|
{{-- Desktop page header --}}
|
||||||
<div class="hidden lg:block">
|
<div class="hidden lg:block">
|
||||||
<a href="{{ route('qr-codes.index') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700">
|
<a href="{{ route('user.qr-codes.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>
|
<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
|
QR Codes
|
||||||
</a>
|
</a>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Main 2-column layout --}}
|
{{-- Main 2-column layout --}}
|
||||||
<form x-ref="updateForm" action="{{ route('qr-codes.update', $qrCode) }}" method="POST" enctype="multipart/form-data"
|
<form x-ref="updateForm" action="{{ route('user.qr-codes.update', $qrCode) }}" method="POST" enctype="multipart/form-data"
|
||||||
class="grid grid-cols-1 gap-8 lg:grid-cols-[380px_1fr]">
|
class="grid grid-cols-1 gap-8 lg:grid-cols-[380px_1fr]">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PATCH')
|
@method('PATCH')
|
||||||
@@ -193,15 +193,15 @@
|
|||||||
$mobileShareEnc = urlencode($mobileShareUrl);
|
$mobileShareEnc = urlencode($mobileShareUrl);
|
||||||
@endphp
|
@endphp
|
||||||
<div class="grid grid-cols-4 gap-2 px-6 pb-6">
|
<div class="grid grid-cols-4 gap-2 px-6 pb-6">
|
||||||
<a href="{{ route('qr-codes.download', [$qrCode, 'png']) }}"
|
<a href="{{ route('user.qr-codes.download', [$qrCode, 'png']) }}"
|
||||||
class="flex flex-col items-center gap-1 rounded-xl border border-white/20 bg-white/10 py-3 text-center text-white transition hover:bg-white/20">
|
class="flex flex-col items-center gap-1 rounded-xl border border-white/20 bg-white/10 py-3 text-center text-white transition hover:bg-white/20">
|
||||||
<span class="text-xs font-semibold">PNG</span>
|
<span class="text-xs font-semibold">PNG</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ route('qr-codes.download', [$qrCode, 'svg']) }}"
|
<a href="{{ route('user.qr-codes.download', [$qrCode, 'svg']) }}"
|
||||||
class="flex flex-col items-center gap-1 rounded-xl border border-white/20 bg-white/10 py-3 text-center text-white transition hover:bg-white/20">
|
class="flex flex-col items-center gap-1 rounded-xl border border-white/20 bg-white/10 py-3 text-center text-white transition hover:bg-white/20">
|
||||||
<span class="text-xs font-semibold">SVG</span>
|
<span class="text-xs font-semibold">SVG</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ route('qr-codes.download', [$qrCode, 'pdf']) }}"
|
<a href="{{ route('user.qr-codes.download', [$qrCode, 'pdf']) }}"
|
||||||
class="flex flex-col items-center gap-1 rounded-xl border border-white/20 bg-white/10 py-3 text-center text-white transition hover:bg-white/20">
|
class="flex flex-col items-center gap-1 rounded-xl border border-white/20 bg-white/10 py-3 text-center text-white transition hover:bg-white/20">
|
||||||
<span class="text-xs font-semibold">PDF</span>
|
<span class="text-xs font-semibold">PDF</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user