Files
WebAPP/app/Http/Controllers/EventController.php
Rhino ad60e7a9f9 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>
2026-03-02 11:47:34 +01:00

138 lines
4.9 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers;
use App\Enums\EventStatus;
use App\Enums\EventType;
use App\Models\ActivityLog;
use App\Models\Event;
use App\Models\Setting;
use App\Models\Team;
use Illuminate\Http\Request;
use Illuminate\View\View;
class EventController extends Controller
{
public function index(Request $request): View
{
$user = auth()->user();
$query = Event::with(['team', 'participants'])
->withCount([
'caterings as caterings_yes_count' => fn ($q) => $q->where('status', 'yes'),
'timekeepers as timekeepers_yes_count' => fn ($q) => $q->where('status', 'yes'),
]);
// Admins sehen auch Entwürfe, Eltern nur published
if ($user->canAccessAdminPanel()) {
$teams = Team::where('is_active', true)->orderBy('name')->get();
} else {
$teamIds = $user->accessibleTeamIds();
$query->published()->whereIn('team_id', $teamIds);
$teams = Team::whereIn('id', $teamIds)->orderBy('name')->get();
}
// Filter: Team (nur Integer-IDs akzeptieren)
if ($request->filled('team_id')) {
$query->where('team_id', (int) $request->team_id);
}
// Filter: Typ (nur gueltige EventType-Werte)
if ($request->filled('type')) {
$validTypes = array_column(EventType::cases(), 'value');
if (in_array($request->type, $validTypes)) {
$query->where('type', $request->type);
}
}
// Filter: Zeitraum
if ($request->input('period') === 'past') {
$query->where('start_at', '<', now())->orderByDesc('start_at');
} else {
$query->where('start_at', '>=', now())->orderBy('start_at');
}
$events = $query->paginate(15)->withQueryString();
return view('events.index', compact('events', 'teams'));
}
public function show(Event $event): View
{
$user = auth()->user();
// Entwürfe nur für Admins
if ($event->status === EventStatus::Draft && !$user->canAccessAdminPanel()) {
abort(403);
}
// Kinder einmal laden, für Zugriffsprüfung + Teilnahme-Buttons
$userChildren = $user->children()->select('players.id', 'players.team_id', 'players.first_name', 'players.last_name')->get();
// Zugriffsbeschraenkung: User muss Zugang zum Team haben (ueber accessibleTeamIds)
if (!$user->canAccessAdminPanel()) {
$accessibleTeamIds = $user->accessibleTeamIds();
if (!$accessibleTeamIds->contains($event->team_id)) {
abort(403);
}
}
$event->syncParticipants($user->id);
$isMeeting = $event->type === EventType::Meeting;
$relations = ['team', 'comments.user', 'files.category'];
$relations[] = $isMeeting ? 'participants.user' : 'participants.player';
$relations[] = 'participants.setByUser';
if ($event->type->hasCatering()) {
$relations[] = 'caterings.user';
}
if ($event->type->hasTimekeepers()) {
$relations[] = 'timekeepers.user';
}
if ($event->type->hasCarpool()) {
$relations[] = 'carpools.driver';
$relations[] = 'carpools.passengers.player';
}
$event->load($relations);
$userChildIds = $userChildren->pluck('id');
// Eigener Catering-Status
$myCatering = $event->type->hasCatering()
? $event->caterings->where('user_id', $user->id)->first()
: null;
// Eigener Zeitnehmer-Status
$myTimekeeper = $event->type->hasTimekeepers()
? $event->timekeepers->where('user_id', $user->id)->first()
: null;
// Eigene Fahrgemeinschaft
$myCarpool = $event->type->hasCarpool()
? $event->carpools->where('user_id', $user->id)->first()
: null;
// Catering/Zeitnehmer-Verlauf für Staff (chronologische Statusänderungen)
$cateringHistory = collect();
$timekeeperHistory = collect();
if ($user->canAccessAdminPanel() && Setting::isFeatureVisibleFor('catering_history', $user)) {
$statusLogs = ActivityLog::where('model_type', 'Event')
->where('model_id', $event->id)
->where('action', 'status_changed')
->orderBy('created_at')
->get();
$cateringHistory = $statusLogs->filter(
fn ($log) => ($log->properties['new']['source'] ?? null) === 'catering'
);
$timekeeperHistory = $statusLogs->filter(
fn ($log) => ($log->properties['new']['source'] ?? null) === 'timekeeper'
);
}
return view('events.show', compact('event', 'userChildIds', 'userChildren', 'myCatering', 'myTimekeeper', 'myCarpool', 'cateringHistory', 'timekeeperHistory'));
}
}