2026-05-20 18:25:15 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Livewire;
|
|
|
|
|
|
|
|
|
|
use App\Models\Game;
|
|
|
|
|
use App\Models\Genre;
|
|
|
|
|
use App\Models\Platform;
|
|
|
|
|
use Illuminate\View\View;
|
|
|
|
|
use Livewire\Component;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Game Selector for existing games and new games.
|
|
|
|
|
*/
|
|
|
|
|
class GameSelector extends Component
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public const int REQUIRED_CHARS = 3;
|
|
|
|
|
|
2026-06-10 11:04:26 +02:00
|
|
|
/**
|
|
|
|
|
* Which section we can change selection mode.
|
|
|
|
|
*/
|
|
|
|
|
public const array CHANGE_SECTION_MODE = [ 'utilities', 'documents' ];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Selection mode between game|platform|none.
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
public string $selectionMode = 'game';
|
|
|
|
|
|
2026-05-20 18:25:15 +02:00
|
|
|
/**
|
|
|
|
|
* If we are in new game mode.
|
|
|
|
|
* @var bool
|
|
|
|
|
*/
|
|
|
|
|
public bool $newGame = false;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Current user game search.
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
public string $search = '';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Existing game ID selected.
|
|
|
|
|
* @var int|null
|
|
|
|
|
*/
|
|
|
|
|
public ?int $gameId = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Existing game name selected or new game name.
|
|
|
|
|
* @var string|null
|
|
|
|
|
*/
|
|
|
|
|
public ?string $gameName = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* New game platform ID.
|
|
|
|
|
* @var int|null
|
|
|
|
|
*/
|
|
|
|
|
public ?int $gamePlatformId = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* New game genre ID.
|
|
|
|
|
* @var int|null
|
|
|
|
|
*/
|
|
|
|
|
public ?int $gameGenreId = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Existing game platform name or new game platform name.
|
|
|
|
|
* @var string|null
|
|
|
|
|
*/
|
|
|
|
|
public ?string $platformName = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Existing game genre name or new game genre name.
|
|
|
|
|
* @var string|null
|
|
|
|
|
*/
|
|
|
|
|
public ?string $genreName = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If dropdown must be rendered or not.
|
|
|
|
|
* @var bool
|
|
|
|
|
*/
|
|
|
|
|
public bool $dropdown = false;
|
|
|
|
|
|
2026-06-10 11:04:26 +02:00
|
|
|
/**
|
|
|
|
|
* In platform mode.
|
|
|
|
|
* @var int|null
|
|
|
|
|
*/
|
|
|
|
|
public ?int $platformModeId = null;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* In platform mode.
|
|
|
|
|
* @var string|null
|
|
|
|
|
*/
|
|
|
|
|
public ?string $platformModeName = null;
|
|
|
|
|
|
|
|
|
|
public ?string $section = null;
|
|
|
|
|
|
|
|
|
|
public function mount( ?int $gameId = null, ?string $newGameTitle = null, ?int $newGamePlatform = null, ?int $newGameGenre = null, ?string $section, ?int $platformOnlyId ): void
|
2026-05-20 18:25:15 +02:00
|
|
|
{
|
|
|
|
|
|
2026-06-10 11:04:26 +02:00
|
|
|
$this->section = $section;
|
|
|
|
|
|
2026-05-20 18:25:15 +02:00
|
|
|
// If we selected an existent game.
|
|
|
|
|
if( $gameId ){
|
|
|
|
|
$game = Game::with(['platform','genre'])->find($gameId);
|
|
|
|
|
if( $game ){
|
|
|
|
|
$this->gameId = $game->id;
|
|
|
|
|
$this->gameName = $game->name;
|
|
|
|
|
$this->platformName = $game->platform->name;
|
|
|
|
|
$this->genreName = $game->genre->name;
|
|
|
|
|
$this->search = $game->name;
|
|
|
|
|
$this->newGame = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( $newGameTitle || $newGamePlatform || $newGameGenre ){
|
|
|
|
|
$this->newGame = true;
|
|
|
|
|
$this->gameName = $newGameTitle;
|
|
|
|
|
$this->gamePlatformId = is_numeric($newGamePlatform) ? (int) $newGamePlatform : null;
|
|
|
|
|
$this->gameGenreId = is_numeric($newGameGenre) ? (int) $newGameGenre : null;
|
|
|
|
|
}
|
2026-06-10 11:04:26 +02:00
|
|
|
|
|
|
|
|
if( in_array( $section, self::CHANGE_SECTION_MODE ) ) {
|
|
|
|
|
if ($platformOnlyId) {
|
|
|
|
|
$this->selectionMode = 'platform';
|
|
|
|
|
$this->platformModeId = $platformOnlyId;
|
|
|
|
|
$platform = Platform::find($platformOnlyId);
|
|
|
|
|
if ($platform) {
|
|
|
|
|
$this->platformModeName = $platform->name;
|
|
|
|
|
} else {
|
|
|
|
|
$this->platformModeId = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function setSelectionMode(string $mode): void
|
|
|
|
|
{
|
|
|
|
|
if( !in_array( $this->section, self::CHANGE_SECTION_MODE ) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
$this->selectionMode = $mode;
|
|
|
|
|
|
|
|
|
|
if( $mode !== 'game' ){
|
|
|
|
|
$this->clearGame();
|
|
|
|
|
$this->newGame = false;
|
|
|
|
|
}
|
|
|
|
|
if( $mode !== 'platform' ){
|
|
|
|
|
$this->platformModeId = null;
|
|
|
|
|
$this->platformModeName = null;
|
|
|
|
|
}
|
2026-05-20 18:25:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If we update search bar.
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function updatedSearch(): void
|
|
|
|
|
{
|
|
|
|
|
if( $this->gameId ){
|
|
|
|
|
$this->gameId = null;
|
|
|
|
|
$this->gameName = null;
|
|
|
|
|
$this->platformName = null;
|
|
|
|
|
$this->genreName = null;
|
|
|
|
|
}
|
|
|
|
|
$this->dropdown = strlen($this->search) >= self::REQUIRED_CHARS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Select an existent game.
|
|
|
|
|
*
|
|
|
|
|
* @param int $id
|
|
|
|
|
* @param string $name
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function selectGame( int $id, string $name ): void
|
|
|
|
|
{
|
|
|
|
|
$game = Game::with(['platform','genre'])->find($id);
|
|
|
|
|
if( $game ){
|
|
|
|
|
$this->gameId = $game->id;
|
|
|
|
|
$this->gameName = $game->name;
|
|
|
|
|
$this->platformName = $game->platform->name;
|
|
|
|
|
$this->genreName = $game->genre->name;
|
|
|
|
|
$this->search = $game->name;
|
|
|
|
|
$this->dropdown = false;
|
|
|
|
|
|
|
|
|
|
$this->dispatch( 'game-selected', id: $id ); // Send an event to the JS part.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 11:04:26 +02:00
|
|
|
public function selectPlatformOnly( int $id ): void
|
|
|
|
|
{
|
|
|
|
|
$platform = Platform::find($id);
|
|
|
|
|
if( $platform ){
|
|
|
|
|
$this->platformModeId = $platform->id;
|
|
|
|
|
$this->platformModeName = $platform->name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-20 18:25:15 +02:00
|
|
|
/**
|
|
|
|
|
* Clear existent game selection.
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function clearGame(): void
|
|
|
|
|
{
|
|
|
|
|
$this->gameId = null;
|
|
|
|
|
$this->gameName = null;
|
|
|
|
|
$this->platformName = null;
|
|
|
|
|
$this->genreName = null;
|
|
|
|
|
$this->search = '';
|
|
|
|
|
|
|
|
|
|
$this->dispatch( 'game-selected', id: null ); // Send an event to the JS part.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Switch mode.
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function switchNewGame(): void
|
|
|
|
|
{
|
|
|
|
|
$this->clearGame();
|
|
|
|
|
$this->newGame = !$this->newGame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function render(): View
|
|
|
|
|
{
|
|
|
|
|
$games = collect();
|
|
|
|
|
|
|
|
|
|
// Need to search games for dropdown.
|
|
|
|
|
if( $this->dropdown && strlen($this->search) >= self::REQUIRED_CHARS && $this->newGame === false ){
|
|
|
|
|
$games = Game::with(['platform','genre'])
|
|
|
|
|
->where('name', 'like', '%'.$this->search.'%')
|
|
|
|
|
->orderBy('name')
|
|
|
|
|
->limit(20)
|
|
|
|
|
->get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = [ 'games' => $games, 'required_chars' => self::REQUIRED_CHARS ];
|
|
|
|
|
if( $this->newGame === true ){ // If we want a new game, get platforms and genres.
|
|
|
|
|
$data['platforms'] = Platform::orderBy('name')->get();
|
|
|
|
|
$data['genres'] = Genre::orderBy('name')->get();
|
|
|
|
|
}
|
|
|
|
|
$data['hasOldNewGame'] = old('new-game-title') || old('new-game-platform') || old('new-game-genre');
|
|
|
|
|
|
2026-06-10 11:04:26 +02:00
|
|
|
$data['canChangeSelection'] = in_array( $this->section, self::CHANGE_SECTION_MODE );
|
|
|
|
|
if( in_array( $this->section, self::CHANGE_SECTION_MODE ) )
|
|
|
|
|
$data['platforms'] = Platform::orderBy('name')->get();
|
|
|
|
|
|
2026-05-20 18:25:15 +02:00
|
|
|
return view('livewire.game-selector', $data );
|
|
|
|
|
}
|
|
|
|
|
}
|