diff --git a/app/Http/Controllers/EventController.php b/app/Http/Controllers/EventController.php index 1136c5a..1b594c8 100755 --- a/app/Http/Controllers/EventController.php +++ b/app/Http/Controllers/EventController.php @@ -134,4 +134,20 @@ class EventController extends Controller return view('events.show', compact('event', 'userChildIds', 'userChildren', 'myCatering', 'myTimekeeper', 'myCarpool', 'cateringHistory', 'timekeeperHistory')); } + + /** + * Öffentliche Share-Seite mit OG-Meta-Tags für Social-Media-Vorschau. + */ + public function share(Event $event): View + { + // Nur veröffentlichte/abgesagte Events (keine Entwürfe) + if ($event->status === EventStatus::Draft) { + abort(404); + } + + $event->load('team'); + $appName = Setting::get('app_name', config('app.name')); + + return view('events.share', compact('event', 'appName')); + } } diff --git a/public/images/Logo_Auswärtsspiel.png b/public/images/Logo_Auswärtsspiel.png new file mode 100644 index 0000000..848eaf4 Binary files /dev/null and b/public/images/Logo_Auswärtsspiel.png differ diff --git a/public/images/Logo_Besprechung.png b/public/images/Logo_Besprechung.png new file mode 100644 index 0000000..2c708f3 Binary files /dev/null and b/public/images/Logo_Besprechung.png differ diff --git a/public/images/Logo_Heimspiel.png b/public/images/Logo_Heimspiel.png new file mode 100644 index 0000000..71c8391 Binary files /dev/null and b/public/images/Logo_Heimspiel.png differ diff --git a/public/images/Logo_Sonstiges.png b/public/images/Logo_Sonstiges.png new file mode 100644 index 0000000..b6c0de6 Binary files /dev/null and b/public/images/Logo_Sonstiges.png differ diff --git a/public/images/Logo_Training.png b/public/images/Logo_Training.png new file mode 100644 index 0000000..72997f1 Binary files /dev/null and b/public/images/Logo_Training.png differ diff --git a/public/images/Logo_Turnier.png b/public/images/Logo_Turnier.png new file mode 100644 index 0000000..1f75818 Binary files /dev/null and b/public/images/Logo_Turnier.png differ diff --git a/resources/views/events/share.blade.php b/resources/views/events/share.blade.php new file mode 100644 index 0000000..87a64c6 --- /dev/null +++ b/resources/views/events/share.blade.php @@ -0,0 +1,138 @@ + + + + + + {{ $event->title }} - {{ $appName }} + + {{-- OG Meta Tags für Social-Media-Vorschau --}} + @php + $ogDescription = $event->start_at->translatedFormat(__('ui.date_format_long')) . ' ' . __('ui.clock'); + if ($event->location_name) { + $ogDescription .= ' · ' . $event->location_name; + } + @endphp + + + + + + + + {{-- Twitter Card --}} + + + + + + + @include('components.tailwind-config') + @php $favicon = \App\Models\Setting::get('app_favicon'); @endphp + @if ($favicon) + + @else + + @endif + + +
+
+ {{-- App-Logo --}} +
+ @php $logoLogin = \App\Models\Setting::get('app_logo_login'); @endphp + {{ $appName }} +

{{ $appName }}

+
+ +
+ {{-- Event-Bild --}} +
+ {{ $event->type->label() }} +
+ +
+ {{-- Abgesagt-Banner --}} + @if ($event->status === \App\Enums\EventStatus::Cancelled) +
+ {{ __('events.share_cancelled_notice') }} +
+ @endif + + {{-- Event-Typ Badge + Team --}} +
+ + {{ $event->team->name }} +
+ + {{-- Titel --}} +

+ {{ $event->title }} +

+ + {{-- Gegner und Ergebnis (bei Spielen) --}} + @if ($event->type->isGameType() && $event->opponent) +

+ {{ __('events.vs') }} {{ $event->opponent }} + @if ($event->hasScore()) + {{ $event->scoreDisplay() }} + @endif +

+ @endif + + {{-- Datum und Uhrzeit --}} +
+
+ + + + + {{ $event->start_at->translatedFormat(__('ui.date_format_long')) }} {{ __('ui.clock') }} + @if ($event->end_at) + – {{ $event->end_at->format('H:i') }} {{ __('ui.clock') }} + @endif + +
+ + @if ($event->location_name || $event->address_text) +
+ + + + +
+ @if ($event->location_name) + {{ $event->location_name }} + @endif + @if ($event->location_name && $event->address_text) +
+ @endif + @if ($event->address_text) + {{ $event->address_text }} + @endif +
+
+ @endif +
+ + {{-- CTA-Button --}} + +
+
+ + {{-- Footer --}} + +
+
+ + diff --git a/resources/views/events/show.blade.php b/resources/views/events/show.blade.php index d9e26d2..24a7520 100755 --- a/resources/views/events/show.blade.php +++ b/resources/views/events/show.blade.php @@ -32,9 +32,25 @@

@endif - @if (auth()->user()->canAccessAdminPanel()) - {{ __('ui.edit') }} - @endif +
+ {{-- Teilen-Button --}} +
+ +
+ {{ __('events.share_link_copied') }} +
+
+ @if (auth()->user()->canAccessAdminPanel()) + {{ __('ui.edit') }} + @endif +
@@ -595,6 +611,44 @@ ← {{ __('events.back_to_list') }}
+ {{-- Share-Button Script --}} + @push('scripts') + + @endpush + {{-- Leaflet.js Karte --}} @if ($event->hasCoordinates()) @push('styles') diff --git a/routes/web.php b/routes/web.php index 625d069..94d58a3 100755 --- a/routes/web.php +++ b/routes/web.php @@ -64,6 +64,9 @@ Route::get('/impressum', fn () => view('legal.impressum'))->name('impressum'); Route::get('/datenschutz', fn () => view('legal.datenschutz'))->name('datenschutz'); Route::get('/offline', fn () => view('offline'))->name('offline'); +// Event-Share (öffentlich für Social-Media-Crawler) +Route::get('/e/{event}', [\App\Http\Controllers\EventController::class, 'share'])->name('events.share')->middleware('throttle:60,1'); + // Club-Logo — öffentlich erreichbar für externe Dienste (z.B. Support-Backend) Route::get('/club-logo', function () { // 1. Dynamisches Favicon aus Settings