build: initialize RetroHub with Laravel, Inertia, Vue, and Horizon

This commit is contained in:
2026-08-10 13:45:18 +02:00
commit 717db65139
218 changed files with 28356 additions and 0 deletions
@@ -0,0 +1,41 @@
<?php
namespace App\Features\Consoles\Controllers;
use App\Features\Consoles\Data\ConsoleData;
use App\Features\Consoles\Services\ConsoleService;
use App\Features\Games\Repositories\GameRepository;
use App\Http\Controllers\Controller;
use Inertia\Inertia;
use Inertia\Response;
class ConsoleController extends Controller
{
public function __construct(
private ConsoleService $consoleService,
private GameRepository $gameRepository
) {}
public function index(): Response
{
$consoles = $this->consoleService->getAll()
->map(fn ($console) => ConsoleData::fromModel($console));
return Inertia::render('Consoles/Index', [
'consoles' => $consoles,
]);
}
public function show(string $slug): Response
{
$console = $this->consoleService->getBySlug($slug);
abort_unless($console, 404);
$games = $this->gameRepository->getByConsole($console->id);
return Inertia::render('Consoles/Show', [
'selectedConsole' => ConsoleData::fromModel($console->loadCount('games')),
'games' => $games,
]);
}
}
@@ -0,0 +1,37 @@
<?php
namespace App\Features\Consoles\Data;
use App\Features\Consoles\Models\Console;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
#[MapInputName(SnakeCaseMapper::class)]
class ConsoleData extends Data
{
public function __construct(
public int $id,
public string $name,
public string $slug,
public ?string $iconPath,
public array $romExtensions,
public ?int $igdbPlatformId,
public ?int $tgdbPlatformId,
public int $gamesCount,
) {}
public static function fromModel(Console $console): self
{
return new self(
id: $console->id,
name: $console->name,
slug: $console->slug,
iconPath: $console->icon_path,
romExtensions: $console->rom_extensions,
igdbPlatformId: $console->igdb_platform_id,
tgdbPlatformId: $console->tgdb_platform_id,
gamesCount: $console->games_count ?? 0,
);
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace App\Features\Consoles\Models;
use App\Features\Games\Models\Game;
use Database\Factories\ConsoleFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Console extends Model
{
/** @use HasFactory<ConsoleFactory> */
use HasFactory;
protected static ?string $factory = ConsoleFactory::class;
protected $fillable = [
'name',
'slug',
'icon_path',
'rom_extensions',
'igdb_platform_id',
'tgdb_platform_id',
];
protected $casts = [
'rom_extensions' => 'array',
];
public function games(): HasMany
{
return $this->hasMany(Game::class);
}
public function getRouteKeyName(): string
{
return 'slug';
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Features\Consoles\Repositories;
use App\Features\Consoles\Models\Console;
use Illuminate\Database\Eloquent\Collection;
class ConsoleRepository
{
public function __construct(
private Console $model
) {}
public function getAll(): Collection
{
return $this->model->withCount('games')->orderBy('name')->get();
}
public function getBySlug(string $slug): ?Console
{
return $this->model->where('slug', $slug)->first();
}
public function getWithGamesCount(): Collection
{
return $this->model->withCount('games')->orderBy('name')->get();
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Features\Consoles\Services;
use App\Features\Consoles\Repositories\ConsoleRepository;
use Illuminate\Database\Eloquent\Collection;
class ConsoleService
{
public function __construct(
private ConsoleRepository $repository
) {}
public function getAll(): Collection
{
return $this->repository->getAll();
}
public function getBySlug(string $slug)
{
return $this->repository->getBySlug($slug);
}
}