mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-app.git
synced 2025-12-15 12:16:47 +00:00
✨ Implement SeoTrait across components for improved SEO integration.
This commit is contained in:
@@ -4,10 +4,13 @@ use App\Models\City;
|
||||
use App\Models\Course;
|
||||
use App\Models\CourseEvent;
|
||||
use App\Models\Venue;
|
||||
use App\Traits\SeoTrait;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Volt\Component;
|
||||
|
||||
new class extends Component {
|
||||
use SeoTrait;
|
||||
|
||||
public Course $course;
|
||||
public ?CourseEvent $event = null;
|
||||
|
||||
@@ -63,7 +66,8 @@ new class extends Component {
|
||||
session()->flash('status', __('Event erfolgreich erstellt!'));
|
||||
}
|
||||
|
||||
$this->redirect(route('courses.landingpage', ['course' => $this->course, 'country' => $this->country]), navigate: true);
|
||||
$this->redirect(route('courses.landingpage', ['course' => $this->course, 'country' => $this->country]),
|
||||
navigate: true);
|
||||
}
|
||||
|
||||
public function delete(): void
|
||||
@@ -71,7 +75,8 @@ new class extends Component {
|
||||
if ($this->event) {
|
||||
$this->event->delete();
|
||||
session()->flash('status', __('Event erfolgreich gelöscht!'));
|
||||
$this->redirect(route('courses.landingpage', ['course' => $this->course, 'country' => $this->country]), navigate: true);
|
||||
$this->redirect(route('courses.landingpage', ['course' => $this->course, 'country' => $this->country]),
|
||||
navigate: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,12 +176,14 @@ new class extends Component {
|
||||
<!-- Form Actions -->
|
||||
<div class="flex items-center justify-between pt-8 border-t border-gray-200 dark:border-gray-700">
|
||||
<div class="flex items-center gap-4">
|
||||
<flux:button class="cursor-pointer" variant="ghost" type="button" :href="route('courses.landingpage', ['course' => $course, 'country' => $country])">
|
||||
<flux:button class="cursor-pointer" variant="ghost" type="button"
|
||||
:href="route('courses.landingpage', ['course' => $course, 'country' => $country])">
|
||||
{{ __('Abbrechen') }}
|
||||
</flux:button>
|
||||
|
||||
@if($event)
|
||||
<flux:button class="cursor-pointer" variant="danger" type="button" wire:click="delete" wire:confirm="{{ __('Bist du sicher, dass du dieses Event löschen möchtest?') }}">
|
||||
<flux:button class="cursor-pointer" variant="danger" type="button" wire:click="delete"
|
||||
wire:confirm="{{ __('Bist du sicher, dass du dieses Event löschen möchtest?') }}">
|
||||
{{ __('Event löschen') }}
|
||||
</flux:button>
|
||||
@endif
|
||||
@@ -235,10 +242,12 @@ new class extends Component {
|
||||
<flux:spacer/>
|
||||
|
||||
<flux:modal.close>
|
||||
<flux:button class="cursor-pointer" type="button" variant="ghost">{{ __('Abbrechen') }}</flux:button>
|
||||
<flux:button class="cursor-pointer" type="button"
|
||||
variant="ghost">{{ __('Abbrechen') }}</flux:button>
|
||||
</flux:modal.close>
|
||||
|
||||
<flux:button class="cursor-pointer" type="submit" variant="primary">{{ __('Ort erstellen') }}</flux:button>
|
||||
<flux:button class="cursor-pointer" type="submit"
|
||||
variant="primary">{{ __('Ort erstellen') }}</flux:button>
|
||||
</div>
|
||||
</form>
|
||||
</flux:modal>
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
use App\Models\Course;
|
||||
use App\Models\Lecturer;
|
||||
use App\Traits\SeoTrait;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Volt\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
|
||||
new class extends Component {
|
||||
use WithFileUploads;
|
||||
use SeoTrait;
|
||||
|
||||
#[Validate('image|max:10240')] // 10MB Max
|
||||
public $logo;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use App\Models\Course;
|
||||
use App\Models\Lecturer;
|
||||
use App\Traits\SeoTrait;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Volt\Component;
|
||||
@@ -9,6 +10,7 @@ use Livewire\WithFileUploads;
|
||||
|
||||
new class extends Component {
|
||||
use WithFileUploads;
|
||||
use SeoTrait;
|
||||
|
||||
#[Validate('image|max:10240')] // 10MB Max
|
||||
public $logo;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Course;
|
||||
use App\Traits\SeoTrait;
|
||||
use Livewire\Volt\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
new class extends Component {
|
||||
use WithPagination;
|
||||
use SeoTrait;
|
||||
|
||||
public $country = 'de';
|
||||
public $search = '';
|
||||
@@ -67,8 +69,9 @@ new class extends Component {
|
||||
<flux:table.cell variant="strong">
|
||||
<flux:tooltip content="{{ $course->name }}">
|
||||
<div class="flex items-center gap-3">
|
||||
<flux:avatar :href="route('courses.landingpage', ['course' => $course, 'country' => $country])"
|
||||
src="{{ $course->getFirstMedia('logo') ? $course->getFirstMediaUrl('logo', 'thumb') : asset('android-chrome-512x512.png') }}"/>
|
||||
<flux:avatar
|
||||
:href="route('courses.landingpage', ['course' => $course, 'country' => $country])"
|
||||
src="{{ $course->getFirstMedia('logo') ? $course->getFirstMediaUrl('logo', 'thumb') : asset('android-chrome-512x512.png') }}"/>
|
||||
<div>
|
||||
<a href="{{ route('courses.landingpage', ['course' => $course, 'country' => $country]) }}">
|
||||
<span>{{ Str::limit($course->name, 30) }}</span>
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
use App\Models\Course;
|
||||
use App\Models\CourseEvent;
|
||||
use App\Traits\SeoTrait;
|
||||
use Livewire\Volt\Component;
|
||||
|
||||
new class extends Component {
|
||||
use SeoTrait;
|
||||
|
||||
public Course $course;
|
||||
|
||||
public $country = 'de';
|
||||
@@ -39,7 +42,8 @@ new class extends Component {
|
||||
<flux:heading size="xl" class="mb-4">{{ $course->name }}</flux:heading>
|
||||
@if($course->lecturer)
|
||||
<flux:subheading class="text-gray-600 dark:text-gray-400 flex items-center gap-2">
|
||||
<flux:avatar size="xs" src="{{ $course->lecturer->getFirstMedia('avatar') ? $course->lecturer->getFirstMediaUrl('avatar', 'thumb') : asset('img/einundzwanzig.png') }}"/>
|
||||
<flux:avatar size="xs"
|
||||
src="{{ $course->lecturer->getFirstMedia('avatar') ? $course->lecturer->getFirstMediaUrl('avatar', 'thumb') : asset('img/einundzwanzig.png') }}"/>
|
||||
{{ $course->lecturer->name }}
|
||||
</flux:subheading>
|
||||
@endif
|
||||
@@ -58,36 +62,43 @@ new class extends Component {
|
||||
<flux:heading size="lg">{{ __('Über den Dozenten') }}</flux:heading>
|
||||
|
||||
<div class="flex items-start gap-4 p-4 bg-zinc-50 dark:bg-zinc-900 rounded-lg">
|
||||
<flux:avatar size="lg" src="{{ $course->lecturer->getFirstMedia('avatar') ? $course->lecturer->getFirstMediaUrl('avatar', 'preview') : asset('img/einundzwanzig.png') }}"/>
|
||||
<flux:avatar size="lg"
|
||||
src="{{ $course->lecturer->getFirstMedia('avatar') ? $course->lecturer->getFirstMediaUrl('avatar', 'preview') : asset('img/einundzwanzig.png') }}"/>
|
||||
<div class="flex-1">
|
||||
<flux:heading size="md" class="mb-1">{{ $course->lecturer->name }}</flux:heading>
|
||||
@if($course->lecturer->subtitle)
|
||||
<flux:text class="text-sm text-zinc-600 dark:text-zinc-400 mb-2">{{ $course->lecturer->subtitle }}</flux:text>
|
||||
<flux:text
|
||||
class="text-sm text-zinc-600 dark:text-zinc-400 mb-2">{{ $course->lecturer->subtitle }}</flux:text>
|
||||
@endif
|
||||
@if($course->lecturer->intro)
|
||||
<x-markdown class="prose prose-sm whitespace-pre-wrap">{!! $course->lecturer->intro !!}</x-markdown>
|
||||
<x-markdown
|
||||
class="prose prose-sm whitespace-pre-wrap">{!! $course->lecturer->intro !!}</x-markdown>
|
||||
@endif
|
||||
|
||||
<!-- Lecturer Social Links -->
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
@if($course->lecturer->website)
|
||||
<flux:button href="{{ $course->lecturer->website }}" target="_blank" variant="ghost" size="xs">
|
||||
<flux:button href="{{ $course->lecturer->website }}" target="_blank" variant="ghost"
|
||||
size="xs">
|
||||
<flux:icon.globe-alt class="w-4 h-4 mr-1"/>
|
||||
Website
|
||||
</flux:button>
|
||||
@endif
|
||||
|
||||
@if($course->lecturer->twitter_username)
|
||||
<flux:button href="https://twitter.com/{{ $course->lecturer->twitter_username }}" target="_blank" variant="ghost" size="xs">
|
||||
<flux:button href="https://twitter.com/{{ $course->lecturer->twitter_username }}"
|
||||
target="_blank" variant="ghost" size="xs">
|
||||
<svg class="w-4 h-4 mr-1" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
|
||||
<path
|
||||
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
|
||||
</svg>
|
||||
Twitter
|
||||
</flux:button>
|
||||
@endif
|
||||
|
||||
@if($course->lecturer->nostr)
|
||||
<flux:button href="https://njump.me/{{ $course->lecturer->nostr }}" target="_blank" variant="ghost" size="xs">
|
||||
<flux:button href="https://njump.me/{{ $course->lecturer->nostr }}" target="_blank"
|
||||
variant="ghost" size="xs">
|
||||
<flux:icon.bolt class="w-4 h-4 mr-1"/>
|
||||
Nostr
|
||||
</flux:button>
|
||||
|
||||
Reference in New Issue
Block a user