Files
fotospiel-app/resources/views/filament/tenant/pages/invite-studio.blade.php
Codex Agent 1a4bdb1fe1 tenant admin startseite schicker gestaltet und super-admin und tenant admin (filament) aufgesplittet.
Es gibt nun task collections und vordefinierte tasks für alle. Onboarding verfeinert und webseite-carousel gefixt (logging später entfernen!)
2025-10-14 15:17:52 +02:00

123 lines
7.9 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-filament-panels::page>
<div class="mx-auto w-full max-w-4xl space-y-10">
<section class="rounded-3xl border border-white/70 bg-white/85 p-8 shadow-xl shadow-sky-100/50">
<header class="space-y-3">
<h1 class="text-3xl font-semibold text-slate-900">Einladungen & QR-Codes</h1>
<p class="text-sm text-slate-600">
Erstellt und verwaltet eure QR-Einladungen. Jeder Link enthält druckfertige Layouts als PDF &amp; SVG.
</p>
</header>
<div class="mt-6 grid gap-6 md:grid-cols-[2fr,1fr]">
<div>
<label class="block text-sm font-semibold text-slate-700">
Event auswählen
<select
wire:model="selectedEventId"
class="mt-2 w-full rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 shadow-sm focus:border-rose-400 focus:ring-rose-400">
<option value="">Bitte wählt ein Event</option>
@foreach ($this->events as $event)
<option value="{{ $event->id }}">{{ data_get($event->name, app()->getLocale()) ?? data_get($event->name, 'de') ?? 'Event #' . $event->id }}</option>
@endforeach
</select>
</label>
</div>
<div class="rounded-2xl border border-rose-100 bg-rose-50/70 p-4 text-sm text-rose-700 shadow-inner">
<p class="font-semibold">Tipp</p>
<p class="mt-2">Druckt mehrere Layouts aus und verteilt sie am Eingang, am Gästebuch und beim DJ-Pult.</p>
</div>
</div>
</section>
<section class="rounded-3xl border border-white/70 bg-white/85 p-8 shadow-xl shadow-rose-100/50">
<form wire:submit.prevent="createInvite" class="grid gap-4 md:grid-cols-[2fr,1fr] md:items-end">
<label class="block text-sm font-semibold text-slate-700">
Bezeichnung des Links (optional)
<input
type="text"
wire:model.defer="tokenLabel"
class="mt-2 w-full rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 shadow-sm focus:border-rose-400 focus:ring-rose-400"
placeholder="z.B. Empfang, Fotobox, Tanzfläche" />
</label>
<div class="flex justify-end">
<button
type="submit"
class="inline-flex items-center justify-center gap-2 rounded-full bg-rose-500 px-6 py-3 text-sm font-semibold text-white shadow-lg shadow-rose-300/60 transition hover:bg-rose-600 disabled:cursor-not-allowed disabled:opacity-70"
@disabled($this->events->isEmpty())
wire:loading.attr="disabled"
wire:target="createInvite">
<span wire:loading.remove wire:target="createInvite">Neuen Einladungslink erzeugen</span>
<span wire:loading wire:target="createInvite" class="flex items-center gap-2">
<x-filament::loading-indicator class="h-4 w-4" />
Wird erstellt
</span>
</button>
</div>
</form>
@if ($this->events->isEmpty())
<p class="mt-4 text-sm text-slate-600">Legt zunächst ein Event an, um Einladungslinks zu erstellen.</p>
@endif
</section>
<section class="rounded-3xl border border-white/70 bg-white/90 p-8 shadow-xl shadow-slate-100/60">
<h2 class="text-2xl font-semibold text-slate-900">Aktive Einladungslinks</h2>
@if (empty($tokens))
<p class="mt-4 text-sm text-slate-600">
Noch keine Einladungen erstellt. Generiert euren ersten Link, um die QR-Codes als PDF oder SVG herunterzuladen.
</p>
@else
<div class="mt-6 space-y-4">
@foreach ($tokens as $token)
<article class="rounded-2xl border border-slate-200 bg-white/80 p-5 shadow-sm">
<div class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
<div>
<h3 class="text-lg font-semibold text-slate-900">{{ $token['label'] }}</h3>
<p class="text-sm text-slate-500">
{{ $token['url'] }} · erstellt am {{ $token['created_at'] }} · Aufrufe: {{ $token['usage_count'] }}{{ $token['usage_limit'] ? ' / ' . $token['usage_limit'] : '' }}
</p>
</div>
<div class="flex flex-wrap items-center gap-2">
<a
href="{{ $token['url'] }}"
target="_blank"
class="inline-flex items-center gap-2 rounded-full border border-slate-200 px-4 py-2 text-sm font-semibold text-slate-600 transition hover:border-rose-300 hover:text-rose-600">
Link öffnen
</a>
<button
type="button"
x-data="{ copied: false }"
x-on:click="navigator.clipboard.writeText('{{ $token['url'] }}').then(() => { copied = true; setTimeout(() => copied = false, 1500); })"
class="inline-flex items-center gap-2 rounded-full border border-slate-200 px-4 py-2 text-sm font-semibold text-slate-600 transition hover:border-rose-300 hover:text-rose-600">
<span x-show="!copied">Link kopieren</span>
<span x-cloak x-show="copied" class="text-rose-500">Kopiert!</span>
</button>
</div>
</div>
<div class="mt-4 grid gap-3 md:grid-cols-2 lg:grid-cols-3">
@foreach ($token['downloads'] as $layout)
<div class="rounded-xl border border-slate-200 bg-white/70 p-4 text-sm text-slate-600">
<p class="font-semibold text-slate-900">{{ $layout['name'] }}</p>
<p class="text-xs text-slate-500">{{ $layout['subtitle'] }}</p>
<div class="mt-3 flex flex-wrap gap-2">
@foreach ($layout['download_urls'] as $format => $url)
<a
href="{{ $url }}"
class="inline-flex items-center gap-2 rounded-full border border-slate-200 px-3 py-1 text-xs font-semibold text-slate-600 transition hover:border-rose-300 hover:text-rose-600"
target="_blank">
{{ strtoupper($format) }} herunterladen
</a>
@endforeach
</div>
</div>
@endforeach
</div>
</article>
@endforeach
</div>
@endif
</section>
</div>
</x-filament-panels::page>