Added inern app integration

This commit is contained in:
2026-09-02 09:37:11 +02:00
parent 8aa6428089
commit e58a398c07
30 changed files with 1059 additions and 68 deletions
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class EmbeddedLogoutController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(Request $request): RedirectResponse
{
$joinCode = $request->string('join_code')->trim()->upper()->toString();
$playerName = $request->string('player_name')->trim()->toString();
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return to_route('embedded.room', [
'join_code' => $joinCode,
'player_name' => $playerName,
]);
}
}
@@ -0,0 +1,49 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ShowEmbeddedRoomRequest;
use App\Http\Resources\CurrentPlayerResource;
use App\Http\Resources\RoomResource;
use App\Models\Room;
use App\Models\User;
use App\Services\Rooms\RoomPageService;
use App\Services\Rooms\RoomParticipationService;
use Inertia\Inertia;
use Inertia\Response;
class EmbeddedRoomController extends Controller
{
public function __construct(
private readonly RoomParticipationService $roomParticipation,
private readonly RoomPageService $roomPage,
) {}
public function __invoke(ShowEmbeddedRoomRequest $request): Response
{
/** @var array{join_code: string, player_name: string} $validated */
$validated = $request->validated();
$user = $request->user();
abort_unless($user instanceof User, 403);
$room = Room::query()
->where('join_code', $validated['join_code'])
->firstOrFail();
$player = $this->roomParticipation->joinEmbedded(
$room,
$user,
$validated['player_name'],
);
$request->session()->put("room_players.{$room->id}", $player->id);
$request->session()->forget('embedded_login');
$pageData = $this->roomPage->prepare($room, $player, $user);
return Inertia::render('embedded/Room', [
'room' => (new RoomResource($pageData))->resolve($request),
'currentPlayer' => (new CurrentPlayerResource($pageData))->resolve($request),
]);
}
}
@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UpdateRoomSettingsRequest;
use App\Models\Room;
use App\Models\User;
use App\Services\Rooms\RoomSettingsService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class RoomSettingsController extends Controller
{
public function __construct(
private readonly RoomSettingsService $roomSettings,
) {}
public function edit(Room $room, Request $request): Response
{
abort_unless($request->user()?->id === $room->owner_id, 403);
return Inertia::render('rooms/Settings', [
'room' => [
'id' => $room->id,
'title' => $room->title,
'join_code' => $room->join_code,
'allow_participants_to_manage_rounds' => $room->allow_participants_to_manage_rounds,
'is_persistent' => $room->is_persistent,
],
]);
}
public function update(UpdateRoomSettingsRequest $request, Room $room): RedirectResponse
{
$user = $request->user();
abort_unless($user instanceof User, 403);
/** @var array{allow_participants_to_manage_rounds: bool, is_persistent: bool} $settings */
$settings = $request->validated();
$this->roomSettings->update($room, $user, $settings);
Inertia::flash('toast', [
'type' => 'success',
'message' => 'Die Raumeinstellungen wurden gespeichert.',
]);
return back();
}
}
+5 -5
View File
@@ -16,7 +16,7 @@ class RoundController extends Controller
public function reset(Request $request, Room $room): Response
{
$this->ensureModerator($request, $room);
$this->ensureCanManageRounds($request, $room);
$this->rounds->reset($room);
return response()->noContent();
@@ -24,7 +24,7 @@ class RoundController extends Controller
public function reveal(Request $request, Room $room): Response
{
$this->ensureModerator($request, $room);
$this->ensureCanManageRounds($request, $room);
$this->rounds->reveal($room);
return response()->noContent();
@@ -32,20 +32,20 @@ class RoundController extends Controller
public function nextRound(Request $request, Room $room): Response
{
$this->ensureModerator($request, $room);
$this->ensureCanManageRounds($request, $room);
$this->rounds->startNext($room);
return response()->noContent();
}
private function ensureModerator(Request $request, Room $room): void
private function ensureCanManageRounds(Request $request, Room $room): void
{
$player = $request->attributes->get('currentPlayer');
abort_unless(
$player instanceof Player
&& $player->room_id === $room->id
&& $player->is_moderator,
&& ($player->is_moderator || $room->allow_participants_to_manage_rounds),
403,
);
}
@@ -0,0 +1,110 @@
<?php
namespace App\Http\Requests;
use App\Models\Player;
use App\Models\Room;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Validation\Rule;
use Inertia\Inertia;
class ShowEmbeddedRoomRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return $this->user() !== null;
}
protected function prepareForValidation(): void
{
$this->merge([
'join_code' => $this->string('join_code')->trim()->upper()->toString(),
'player_name' => $this->string('player_name')->trim()->toString(),
]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'join_code' => [
'bail',
'required',
'string',
'size:6',
Rule::exists(Room::class, 'join_code')->whereNull('deleted_at'),
],
'player_name' => ['required', 'string', 'max:50'],
];
}
/** @return array<callable(Validator): void> */
public function after(): array
{
return [
function (Validator $validator): void {
if ($validator->errors()->has('join_code')) {
return;
}
$room = Room::query()
->where('join_code', $this->input('join_code'))
->first();
if ($room?->isClosed()) {
$validator->errors()->add('join_code', 'Dieser Raum ist geschlossen.');
return;
}
if ($room === null || $this->user() === null) {
return;
}
$nameIsTaken = Player::query()
->where('room_id', $room->id)
->where('name', $this->input('player_name'))
->where(function ($query): void {
$query->whereNull('user_id')
->orWhere('user_id', '!=', $this->user()->id);
})
->exists();
if ($nameIsTaken) {
$validator->errors()->add(
'player_name',
'Dieser Anzeigename ist in dem Raum bereits vorhanden.',
);
}
},
];
}
public function messages(): array
{
return [
'join_code.exists' => 'Dieser Raumcode existiert nicht.',
'join_code.size' => 'Der Raumcode muss aus sechs Zeichen bestehen.',
'player_name.required' => 'Bitte hinterlege in der Hub-App einen Anzeigenamen.',
];
}
protected function failedValidation(Validator $validator): never
{
throw new HttpResponseException(
Inertia::render('embedded/Error', [
'message' => $validator->errors()->first(),
])->toResponse($this)->setStatusCode(422),
);
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests;
use App\Models\Room;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRoomSettingsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
$room = $this->route('room');
return $room instanceof Room
&& $this->user()?->id === $room->owner_id;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'allow_participants_to_manage_rounds' => ['required', 'boolean'],
'is_persistent' => ['required', 'boolean'],
];
}
}
+2
View File
@@ -26,6 +26,8 @@ class RoomResource extends JsonResource
'current_round' => $room->current_round,
'revealed' => $room->revealed_at !== null,
'state_version' => $room->state_version,
'allow_participants_to_manage_rounds' => $room->allow_participants_to_manage_rounds,
'is_persistent' => $room->is_persistent,
'statistics' => $pageData->statistics,
'deck' => (new RoomDeckResource($room->deck_config))->resolve($request),
'players' => $room->players