diff --git a/app/Http/Controllers/Admin/EventController.php b/app/Http/Controllers/Admin/EventController.php index 0d38d77..328e376 100755 --- a/app/Http/Controllers/Admin/EventController.php +++ b/app/Http/Controllers/Admin/EventController.php @@ -99,6 +99,7 @@ class EventController extends Controller $event->updated_by = $request->user()->id; $event->save(); + $this->handleThumbnail($request, $event); $this->createParticipantsForTeam($event); $this->syncAssignments($event, $request); $this->saveKnownLocation($validated, $request->input('location_name')); @@ -172,6 +173,7 @@ class EventController extends Controller $event->syncParticipants($request->user()->id); } + $this->handleThumbnail($request, $event); $this->syncAssignments($event, $request); $this->saveKnownLocation($validated, $request->input('location_name')); $this->syncEventFiles($event, $request); @@ -349,6 +351,7 @@ class EventController extends Controller 'new_files.*' => ['file', 'max:10240', 'mimes:pdf,docx,xlsx,jpg,jpeg,png,gif,webp'], 'new_file_categories' => ['nullable', 'array'], 'new_file_categories.*' => ['integer', 'exists:file_categories,id'], + 'thumbnail' => ['nullable', 'image', 'max:10240', 'mimes:jpg,jpeg,png,gif,webp'], ]); $validated = $request->validate([ @@ -666,4 +669,68 @@ class EventController extends Controller return count($dates); } + + /** + * Thumbnail hochladen, auf max. 1920x1080 skalieren und als JPEG speichern. + */ + private function handleThumbnail(Request $request, Event $event): void + { + // Thumbnail entfernen + if ($request->boolean('remove_thumbnail') && $event->thumbnail) { + Storage::disk('public')->delete('thumbnails/' . $event->thumbnail); + $event->thumbnail = null; + $event->save(); + return; + } + + if (!$request->hasFile('thumbnail')) { + return; + } + + // Altes Thumbnail löschen + if ($event->thumbnail) { + Storage::disk('public')->delete('thumbnails/' . $event->thumbnail); + } + + $uploadedFile = $request->file('thumbnail'); + $storedName = Str::uuid() . '.jpg'; + + // Bild laden und auf max. FullHD skalieren + $imageData = file_get_contents($uploadedFile->getRealPath()); + $source = @imagecreatefromstring($imageData); + + if (!$source) { + return; + } + + $origWidth = imagesx($source); + $origHeight = imagesy($source); + $maxWidth = 1920; + $maxHeight = 1080; + + // Nur verkleinern, nicht vergrößern + if ($origWidth > $maxWidth || $origHeight > $maxHeight) { + $ratio = min($maxWidth / $origWidth, $maxHeight / $origHeight); + $newWidth = (int) round($origWidth * $ratio); + $newHeight = (int) round($origHeight * $ratio); + + $resized = imagecreatetruecolor($newWidth, $newHeight); + imagecopyresampled($resized, $source, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight); + imagedestroy($source); + $source = $resized; + } + + // Verzeichnis sicherstellen + $dir = storage_path('app/public/thumbnails'); + if (!is_dir($dir)) { + mkdir($dir, 0755, true); + } + + // Als JPEG speichern (Qualität 85) + imagejpeg($source, $dir . '/' . $storedName, 85); + imagedestroy($source); + + $event->thumbnail = $storedName; + $event->save(); + } } diff --git a/app/Models/Event.php b/app/Models/Event.php index 548c775..ac9ef9a 100755 --- a/app/Models/Event.php +++ b/app/Models/Event.php @@ -36,6 +36,7 @@ class Event extends Model 'opponent', 'score_home', 'score_away', + 'thumbnail', ]; protected function casts(): array @@ -300,6 +301,27 @@ class Event extends Model return $query->where('team_id', $teamId); } + /** + * URL zum Event-Bild: Custom-Thumbnail oder Standard-Logo nach Event-Typ. + */ + public function imageUrl(): string + { + if ($this->thumbnail) { + return asset('storage/thumbnails/' . $this->thumbnail); + } + + $map = [ + 'home_game' => 'Logo_Heimspiel.png', + 'away_game' => 'Logo_Auswärtsspiel.png', + 'training' => 'Logo_Training.png', + 'tournament' => 'Logo_Turnier.png', + 'meeting' => 'Logo_Besprechung.png', + 'other' => 'Logo_Sonstiges.png', + ]; + + return asset('images/' . ($map[$this->type->value] ?? 'Logo_Sonstiges.png')); + } + public function isPartOfSeries(): bool { return $this->event_series_id !== null; diff --git a/database/migrations/0043_01_01_000000_add_thumbnail_to_events.php b/database/migrations/0043_01_01_000000_add_thumbnail_to_events.php new file mode 100644 index 0000000..16b9db4 --- /dev/null +++ b/database/migrations/0043_01_01_000000_add_thumbnail_to_events.php @@ -0,0 +1,22 @@ +string('thumbnail', 255)->nullable()->after('event_series_id'); + }); + } + + public function down(): void + { + Schema::table('events', function (Blueprint $table) { + $table->dropColumn('thumbnail'); + }); + } +}; diff --git a/lang/ar/admin.php b/lang/ar/admin.php index b5953b7..4dad4c6 100755 --- a/lang/ar/admin.php +++ b/lang/ar/admin.php @@ -221,6 +221,8 @@ return [ 'category_not_empty' => 'لا يمكن حذف الفئة لأنها تحتوي على ملفات.', 'confirm_delete_category' => 'هل تريد حذف هذه الفئة حقاً؟', 'event_files' => 'الملفات', + 'event_thumbnail' => 'صورة مصغرة', + 'upload_thumbnail' => 'اختر صورة', 'attach_from_library' => 'إرفاق من المكتبة', 'upload_new_file' => 'رفع ملف جديد', 'attached_files' => 'الملفات المرفقة', diff --git a/lang/de/admin.php b/lang/de/admin.php index 01f4d0f..613cf3a 100755 --- a/lang/de/admin.php +++ b/lang/de/admin.php @@ -252,6 +252,8 @@ return [ 'category_not_empty' => 'Kategorie kann nicht gelöscht werden, da sie noch Dateien enthält.', 'confirm_delete_category' => 'Kategorie wirklich löschen?', 'event_files' => 'Dateien', + 'event_thumbnail' => 'Vorschaubild', + 'upload_thumbnail' => 'Bild wählen', 'attach_from_library' => 'Aus Bibliothek anhängen', 'upload_new_file' => 'Neue Datei hochladen', 'attached_files' => 'Angehängte Dateien', diff --git a/lang/en/admin.php b/lang/en/admin.php index 131b215..cc2388f 100755 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -220,6 +220,8 @@ return [ 'category_not_empty' => 'Category cannot be deleted because it still contains files.', 'confirm_delete_category' => 'Really delete this category?', 'event_files' => 'Files', + 'event_thumbnail' => 'Thumbnail', + 'upload_thumbnail' => 'Choose image', 'attach_from_library' => 'Attach from library', 'upload_new_file' => 'Upload new file', 'attached_files' => 'Attached Files', diff --git a/lang/pl/admin.php b/lang/pl/admin.php index 6b20062..0012f8f 100755 --- a/lang/pl/admin.php +++ b/lang/pl/admin.php @@ -221,6 +221,8 @@ return [ 'category_not_empty' => 'Nie można usunąć kategorii, ponieważ zawiera pliki.', 'confirm_delete_category' => 'Naprawdę usunąć tę kategorię?', 'event_files' => 'Pliki', + 'event_thumbnail' => 'Miniatura', + 'upload_thumbnail' => 'Wybierz obraz', 'attach_from_library' => 'Dołącz z biblioteki', 'upload_new_file' => 'Prześlij nowy plik', 'attached_files' => 'Dołączone pliki', diff --git a/lang/ru/admin.php b/lang/ru/admin.php index dd4bcd4..87ae392 100755 --- a/lang/ru/admin.php +++ b/lang/ru/admin.php @@ -239,6 +239,8 @@ return [ 'category_not_empty' => 'Категория не может быть удалена, так как содержит файлы.', 'confirm_delete_category' => 'Действительно удалить эту категорию?', 'event_files' => 'Файлы', + 'event_thumbnail' => 'Миниатюра', + 'upload_thumbnail' => 'Выбрать фото', 'attach_from_library' => 'Прикрепить из библиотеки', 'upload_new_file' => 'Загрузить новый файл', 'attached_files' => 'Прикреплённые файлы', diff --git a/lang/tr/admin.php b/lang/tr/admin.php index 54d8055..2649ff9 100755 --- a/lang/tr/admin.php +++ b/lang/tr/admin.php @@ -239,6 +239,8 @@ return [ 'category_not_empty' => 'Kategori dosya içerdiği için silinemez.', 'confirm_delete_category' => 'Bu kategoriyi gerçekten silmek istiyor musunuz?', 'event_files' => 'Dosyalar', + 'event_thumbnail' => 'Önizleme resmi', + 'upload_thumbnail' => 'Resim seç', 'attach_from_library' => 'Kütüphaneden ekle', 'upload_new_file' => 'Yeni dosya yükle', 'attached_files' => 'Ekli Dosyalar', diff --git a/resources/views/admin/events/create.blade.php b/resources/views/admin/events/create.blade.php index e4000fb..a4d1121 100755 --- a/resources/views/admin/events/create.blade.php +++ b/resources/views/admin/events/create.blade.php @@ -12,28 +12,53 @@