Files
WebAPP/app/Http/Controllers/Admin/InvitationController.php
Rhino 8ccadbe89f Feature-Toggles, Administration, wiederkehrende Events und Event-Serien
- Administration & Rollenmanagement: Neuer Admin-Bereich mit Feature-Toggles
  und Sichtbarkeitseinstellungen pro Rolle (11 Toggles, 24 Visibility-Settings)
- AdministrationController mit eigenem Settings-Tab, aus SettingsController extrahiert
- Feature-Toggle-Guards in Controllers (Invitation, File, ListGenerator, Comment)
  und Views (events/show, events/edit, events/create)
- Setting::isFeatureEnabled() und isFeatureVisibleFor() Hilfsmethoden
- Wiederkehrende Trainings: Täglich/Wöchentlich/2-Wöchentlich mit Ende per
  Datum oder Anzahl (max. 52), Vorschau im Formular
- Event-Serien: Verknüpfung über event_series_id (UUID), Modal-Dialog beim
  Speichern und Löschen mit Optionen "nur dieses" / "alle folgenden"
- Löschen-Button direkt in der Event-Bearbeitung mit Serien-Dialog
- DemoDataSeeder: 4 Trainings als Serie mit gemeinsamer event_series_id
- Übersetzungen in allen 6 Sprachen (de, en, pl, ru, ar, tr)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:38:45 +01:00

81 lines
2.5 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\ActivityLog;
use App\Models\Invitation;
use App\Models\Player;
use App\Models\Setting;
use App\Services\InvitationService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class InvitationController extends Controller
{
public function __construct(private InvitationService $invitationService) {}
public function index(): View
{
if (!Setting::isFeatureVisibleFor('invitations', auth()->user())) {
abort(403);
}
$invitations = Invitation::with(['creator', 'players.team'])
->latest('created_at')
->paginate(20);
return view('admin.invitations.index', compact('invitations'));
}
public function create(): View
{
if (!Setting::isFeatureVisibleFor('invitations', auth()->user())) {
abort(403);
}
$players = Player::with('team')->active()->orderBy('last_name')->get();
return view('admin.invitations.create', compact('players'));
}
public function store(Request $request): RedirectResponse
{
if (!Setting::isFeatureVisibleFor('invitations', auth()->user())) {
abort(403);
}
$validated = $request->validate([
'email' => ['nullable', 'email', 'max:255'],
'expires_in_days' => ['required', 'integer', 'min:1', 'max:90'],
'player_ids' => ['nullable', 'array'],
'player_ids.*' => ['exists:players,id'],
]);
$invitation = $this->invitationService->createInvitation($validated, $request->user());
$link = route('register', $invitation->raw_token);
ActivityLog::logWithChanges('created', __('admin.log_invitation_created', ['email' => $validated['email'] ?? '']), 'User', null, null, ['email' => $validated['email'] ?? '']);
return redirect()->route('admin.invitations.index')
->with('success', __('admin.invitation_created', ['link' => $link]));
}
public function destroy(Invitation $invitation): RedirectResponse
{
if (!Setting::isFeatureVisibleFor('invitations', auth()->user())) {
abort(403);
}
if ($invitation->isAccepted()) {
return back()->with('error', __('admin.invitation_already_used'));
}
$invitation->delete();
return back()->with('success', __('admin.invitation_deleted'));
}
}