Files
WebAPP/app/Http/Controllers/CarpoolController.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

177 lines
5.5 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Enums\EventStatus;
use App\Models\ActivityLog;
use App\Models\Event;
use App\Models\EventCarpool;
use App\Models\EventCarpoolPassenger;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class CarpoolController extends Controller
{
public function offer(Request $request, Event $event): RedirectResponse
{
$this->authorizeCarpool($event);
$request->validate([
'seats' => 'required|integer|min:1|max:9',
'note' => 'nullable|string|max:255',
]);
$carpool = EventCarpool::where('event_id', $event->id)
->where('user_id', auth()->id())
->first();
$isNew = !$carpool;
if (!$carpool) {
$carpool = new EventCarpool(['event_id' => $event->id, 'seats' => $request->seats, 'note' => $request->note]);
$carpool->user_id = auth()->id();
} else {
$carpool->seats = $request->seats;
$carpool->note = $request->note;
}
// Sitzplaetze duerfen nicht unter aktuelle Passagieranzahl fallen
if (!$isNew && $carpool->passengers()->count() > $request->seats) {
return redirect(route('events.show', $event) . '#carpool')
->withErrors(['seats' => __('events.carpool_seats_too_few')]);
}
$carpool->save();
ActivityLog::log(
$isNew ? 'created' : 'updated',
__('admin.log_carpool_offer', ['event' => $event->title, 'seats' => $request->seats]),
'Event',
$event->id
);
return redirect(route('events.show', $event) . '#carpool');
}
public function withdraw(Request $request, Event $event): RedirectResponse
{
$this->authorizeCarpool($event);
$carpool = EventCarpool::where('event_id', $event->id)
->where('user_id', auth()->id())
->firstOrFail();
$passengerCount = $carpool->passengers()->count();
$carpool->delete();
ActivityLog::log(
'deleted',
__('admin.log_carpool_withdrawn', ['event' => $event->title, 'passengers' => $passengerCount]),
'Event',
$event->id
);
return redirect(route('events.show', $event) . '#carpool');
}
public function join(Request $request, Event $event): RedirectResponse
{
$this->authorizeCarpool($event);
$request->validate([
'carpool_id' => 'required|integer',
'player_id' => 'required|integer',
]);
$carpool = EventCarpool::where('id', $request->carpool_id)
->where('event_id', $event->id)
->firstOrFail();
$user = auth()->user();
$player = $user->children()->where('players.id', $request->player_id)->first();
if (!$player && !$user->isAdmin()) {
abort(403);
}
// Pruefen ob noch Plaetze frei
if ($carpool->passengers()->count() >= $carpool->seats) {
return redirect(route('events.show', $event) . '#carpool')
->withErrors(['carpool' => __('events.carpool_full')]);
}
// Pruefen ob Spieler nicht bereits in dieser Fahrt
if (EventCarpoolPassenger::where('carpool_id', $carpool->id)->where('player_id', $request->player_id)->exists()) {
return redirect(route('events.show', $event) . '#carpool');
}
$passenger = new EventCarpoolPassenger(['carpool_id' => $carpool->id, 'player_id' => $request->player_id]);
$passenger->added_by = auth()->id();
$passenger->save();
$playerName = $player ? $player->full_name : "Spieler #{$request->player_id}";
ActivityLog::log(
'created',
__('admin.log_carpool_joined', ['player' => $playerName, 'driver' => $carpool->driver->name, 'event' => $event->title]),
'Event',
$event->id
);
return redirect(route('events.show', $event) . '#carpool');
}
public function leave(Request $request, Event $event): RedirectResponse
{
$this->authorizeCarpool($event);
$request->validate([
'carpool_id' => 'required|integer',
'player_id' => 'required|integer',
]);
$passenger = EventCarpoolPassenger::where('carpool_id', $request->carpool_id)
->where('player_id', $request->player_id)
->firstOrFail();
$user = auth()->user();
if ($passenger->added_by !== $user->id && !$user->isAdmin()) {
abort(403);
}
$carpool = $passenger->carpool;
$playerName = $passenger->player->full_name ?? "Spieler #{$request->player_id}";
$passenger->delete();
ActivityLog::log(
'deleted',
__('admin.log_carpool_left', ['player' => $playerName, 'driver' => $carpool->driver->name, 'event' => $event->title]),
'Event',
$event->id
);
return redirect(route('events.show', $event) . '#carpool');
}
private function authorizeCarpool(Event $event): void
{
$user = auth()->user();
if ($event->status === EventStatus::Cancelled) {
abort(403);
}
if (!$event->type->hasCarpool()) {
abort(403);
}
if (!$user->canAccessAdminPanel()) {
if ($event->status === EventStatus::Draft) {
abort(403);
}
if (!$user->accessibleTeamIds()->contains($event->team_id)) {
abort(403);
}
}
}
}