Spielerpositionen, Statistiken, Fahrgemeinschaften, Spielfeld-Visualisierung

- PlayerPosition Enum (7 Handball-Positionen) mit Label/ShortLabel
- Spielerstatistik pro Spiel (Tore, Würfe, TW-Paraden, Bemerkung)
- Position-Dropdown in Spieler-Editor und Event-Stats-Formular
- Statistik-Seite: TW zuerst, Trennlinie, Feldspieler, Position-Badges
- Spielfeld-SVG mit Ampel-Performance (grün/gelb/rot)
- Anklickbare Spieler im Spielfeld öffnen Detail-Modal
- Fahrgemeinschaften (Anbieten, Zuordnen, Zurückziehen)
- Übersetzungen in allen 6 Sprachen (de, en, pl, ru, ar, tr)
- .gitignore für Laravel hinzugefügt
- Demo-Daten mit Positionen und Statistiken

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Rhino
2026-03-02 11:47:34 +01:00
parent 2e24a40d68
commit ad60e7a9f9
46 changed files with 2041 additions and 86 deletions

View File

@@ -91,28 +91,35 @@ class SettingsController extends Controller
abort(403, 'Nur Admins koennen Einstellungen aendern.');
}
// Favicon-Upload verarbeiten (vor der normalen Settings-Schleife)
if ($request->hasFile('favicon')) {
$request->validate([
'favicon' => 'file|mimes:ico,png,svg,jpg,jpeg,gif,webp|max:512',
]);
// Bild-Uploads verarbeiten (vor der normalen Settings-Schleife)
$imageUploads = [
'favicon' => ['setting' => 'app_favicon', 'dir' => 'favicon', 'max' => 512],
'logo_login' => ['setting' => 'app_logo_login', 'dir' => 'logos', 'max' => 1024],
'logo_app' => ['setting' => 'app_logo_app', 'dir' => 'logos', 'max' => 1024],
];
// Altes Favicon löschen
$oldFavicon = Setting::get('app_favicon');
if ($oldFavicon) {
Storage::disk('public')->delete($oldFavicon);
}
foreach ($imageUploads as $field => $config) {
if ($request->hasFile($field)) {
$request->validate([
$field => 'file|mimes:ico,png,svg,jpg,jpeg,gif,webp|max:' . $config['max'],
]);
$file = $request->file('favicon');
$filename = Str::uuid() . '.' . $file->guessExtension();
$path = $file->storeAs('favicon', $filename, 'public');
Setting::set('app_favicon', $path);
} elseif ($request->has('remove_favicon')) {
$oldFavicon = Setting::get('app_favicon');
if ($oldFavicon) {
Storage::disk('public')->delete($oldFavicon);
$oldFile = Setting::get($config['setting']);
if ($oldFile) {
Storage::disk('public')->delete($oldFile);
}
$file = $request->file($field);
$filename = Str::uuid() . '.' . $file->guessExtension();
$path = $file->storeAs($config['dir'], $filename, 'public');
Setting::set($config['setting'], $path);
} elseif ($request->has("remove_{$field}")) {
$oldFile = Setting::get($config['setting']);
if ($oldFile) {
Storage::disk('public')->delete($oldFile);
}
Setting::set($config['setting'], null);
}
Setting::set('app_favicon', null);
}
$inputSettings = $request->input('settings', []);
@@ -310,6 +317,9 @@ class SettingsController extends Controller
// Löschreihenfolge beachtet FK-Constraints
DB::table('activity_logs')->delete();
DB::table('comments')->delete();
DB::table('event_player_stats')->delete();
DB::table('event_carpool_passengers')->delete();
DB::table('event_carpools')->delete();
DB::table('event_participants')->delete();
DB::table('event_catering')->delete();
DB::table('event_timekeepers')->delete();
@@ -364,6 +374,7 @@ class SettingsController extends Controller
Storage::disk('private')->deleteDirectory('files');
Storage::disk('public')->deleteDirectory('avatars');
Storage::disk('public')->deleteDirectory('favicon');
Storage::disk('public')->deleteDirectory('logos');
Storage::disk('public')->deleteDirectory('dsgvo');
// 2. FK-Constraints deaktivieren (DB-agnostisch)
@@ -376,7 +387,8 @@ class SettingsController extends Controller
// 3. Alle Tabellen leeren
$tables = [
'activity_logs', 'comments', 'event_participants',
'activity_logs', 'comments', 'event_player_stats',
'event_carpool_passengers', 'event_carpools', 'event_participants',
'event_catering', 'event_timekeepers', 'event_faq',
'event_file', 'events', 'parent_player', 'players',
'team_user', 'team_file', 'teams',