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')); } }