feature/game-endpoints #62
@@ -40,6 +40,7 @@ class AuthController extends Controller
|
|||||||
'message' => 'Logged out successfully',
|
'message' => 'Logged out successfully',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function register(RegisterRequest $request)
|
public function register(RegisterRequest $request)
|
||||||
{
|
{
|
||||||
if (User::where('email', $request->email)->exists()) {
|
if (User::where('email', $request->email)->exists()) {
|
||||||
@@ -52,11 +53,11 @@ class AuthController extends Controller
|
|||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'password' => bcrypt($request->password),
|
'password' => bcrypt($request->password),
|
||||||
'photo_avatar_filename' => $request->photo,
|
'photo_avatar_filename' => $request->photo,
|
||||||
|
'type' => 'P',
|
||||||
|
'blocked' => false,
|
||||||
|
'coins_balance' => 10,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user->coins_balance = 10;
|
|
||||||
$user->save();
|
|
||||||
|
|
||||||
$token = $user->createToken('auth-token')->plainTextToken;
|
$token = $user->createToken('auth-token')->plainTextToken;
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -5,15 +5,13 @@ namespace App\Http\Controllers;
|
|||||||
use App\Models\Game;
|
use App\Models\Game;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Requests\StoreGameRequest;
|
use App\Http\Requests\StoreGameRequest;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class GameController extends Controller
|
class GameController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*/
|
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$query = Game::query()->with(['winner']);
|
$query = Game::query()->with(['winner', 'player1', 'player2']);
|
||||||
|
|
||||||
if ($request->has('type') && in_array($request->type, ['3', '9'])) {
|
if ($request->has('type') && in_array($request->type, ['3', '9'])) {
|
||||||
$query->where('type', $request->type);
|
$query->where('type', $request->type);
|
||||||
@@ -23,137 +21,114 @@ class GameController extends Controller
|
|||||||
$query->where('status', $request->status);
|
$query->where('status', $request->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sorting
|
$query->orderBy('began_at', 'desc');
|
||||||
$sortField = $request->input('sort_by', 'began_at');
|
|
||||||
$sortDirection = $request->input('sort_direction', 'desc');
|
|
||||||
|
|
||||||
$allowedSortFields = [
|
return response()->json($query->paginate(15));
|
||||||
'began_at',
|
|
||||||
'ended_at',
|
|
||||||
'total_time',
|
|
||||||
'type',
|
|
||||||
'status'
|
|
||||||
];
|
|
||||||
|
|
||||||
if (in_array($sortField, $allowedSortFields)) {
|
|
||||||
$query->orderBy($sortField, $sortDirection === 'asc' ? 'asc' : 'desc');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pagination
|
|
||||||
$perPage = $request->input('per_page', 15);
|
|
||||||
$games = $query->paginate($perPage);
|
|
||||||
|
|
||||||
return response()->json([
|
|
||||||
'data' => $games->items(),
|
|
||||||
'meta' => [
|
|
||||||
'current_page' => $games->currentPage(),
|
|
||||||
'last_page' => $games->lastPage(),
|
|
||||||
'per_page' => $games->perPage(),
|
|
||||||
'total' => $games->total()
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function store(Request $request)
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(StoreGameRequest $request)
|
|
||||||
{
|
{
|
||||||
$validated = $request->validated();
|
$validated = $request->validate([
|
||||||
$user = $request->user();
|
'type' => 'required|in:3,9',
|
||||||
|
]);
|
||||||
|
|
||||||
$type = $validated['variant'] === 'bisca-3' ? '3' : '9';
|
$user = Auth::user();
|
||||||
$initialState = $this->initializeGameState($type);
|
|
||||||
|
$activeGame = Game::where(function ($query) use ($user) {
|
||||||
|
$query->where('player1_user_id', $user->id)
|
||||||
|
->orWhere('player2_user_id', $user->id);
|
||||||
|
})
|
||||||
|
->whereIn('status', ['Pending', 'Playing'])
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($activeGame) {
|
||||||
|
return response()->json(['message' => 'You already have an active game.'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
$game = Game::create([
|
$game = Game::create([
|
||||||
'type' => $type,
|
'type' => $validated['type'],
|
||||||
'status' => 'in_progress',
|
'status' => 'Pending',
|
||||||
'player1_user_id' => $user->id,
|
'player1_user_id' => $user->id,
|
||||||
'player2_user_id' => $validated['mode'] === 'multiplayer'
|
'player2_user_id' => $user->id,
|
||||||
? $validated['opponent_id']
|
'winner_user_id' => $user->id,
|
||||||
: 1, // REPLACE 1 with your actual Bot User ID
|
'loser_user_id' => $user->id,
|
||||||
'began_at' => now(),
|
'began_at' => now(),
|
||||||
'custom' => json_encode($initialState),
|
|
||||||
'player1_points' => 0,
|
'player1_points' => 0,
|
||||||
'player2_points' => 0,
|
'player2_points' => 0,
|
||||||
|
'custom' => null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'Game created successfully',
|
'message' => 'Multiplayer game room created',
|
||||||
'game_id' => $game->id,
|
'game' => $game
|
||||||
'game_state' => $initialState,
|
|
||||||
], 201);
|
], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function initializeGameState($type)
|
public function join(Game $game)
|
||||||
{
|
{
|
||||||
$handSize = $type === 'S' ? 3 : 9;
|
$user = Auth::user();
|
||||||
|
|
||||||
$suits = ['H', 'D', 'C', 'S'];
|
if ($game->player1_user_id == $user->id) {
|
||||||
$ranks = ['2', '3', '4', '5', '6', '7', 'J', 'Q', 'K', 'A'];
|
return response()->json([
|
||||||
|
'message' => 'Waiting for opponent...',
|
||||||
$values = [
|
'game' => $game
|
||||||
'2' => 0, '3' => 0, '4' => 0, '5' => 0, '6' => 0,
|
], 200);
|
||||||
'7' => 10, 'J' => 3, 'Q' => 2, 'K' => 4, 'A' => 11
|
|
||||||
];
|
|
||||||
|
|
||||||
$deck = [];
|
|
||||||
foreach ($suits as $suit) {
|
|
||||||
foreach ($ranks as $rank) {
|
|
||||||
$deck[] = ['suit' => $suit, 'rank' => $rank, 'value' => $values[$rank]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shuffle and deal
|
if ($game->status !== 'Pending') {
|
||||||
shuffle($deck);
|
return response()->json(['message' => 'Game is full or already started'], 400);
|
||||||
$player1Hand = array_splice($deck, 0, $handSize);
|
|
||||||
$player2Hand = array_splice($deck, 0, $handSize);
|
|
||||||
|
|
||||||
// Trump is the suit of the last card in the remaining stock
|
|
||||||
$trumpCard = null;
|
|
||||||
if (count($deck) > 0) {
|
|
||||||
$trumpCard = $deck[count($deck) - 1]; // Bottom card
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
$activeGame = Game::where(function ($query) use ($user) {
|
||||||
'player1_hand' => $player1Hand,
|
$query->where('player1_user_id', $user->id)
|
||||||
'player2_hand' => $player2Hand,
|
->orWhere('player2_user_id', $user->id);
|
||||||
'stock' => $deck,
|
})
|
||||||
'trump' => $trumpCard ? $trumpCard['suit'] : null,
|
->whereIn('status', ['Pending', 'Playing'])
|
||||||
'current_trick' => [],
|
->exists();
|
||||||
'current_turn' => 'player1',
|
|
||||||
'score' => [
|
if ($activeGame) {
|
||||||
'player1' => 0,
|
return response()->json(['message' => 'You are already in another active game.'], 400);
|
||||||
'player2' => 0
|
}
|
||||||
],
|
|
||||||
'captured' => [
|
$game->update([
|
||||||
'player1' => [],
|
'status' => 'Playing',
|
||||||
'player2' => []
|
'player2_user_id' => $user->id,
|
||||||
]
|
]);
|
||||||
];
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Joined successfully! Game starts now.',
|
||||||
|
'game' => $game
|
||||||
|
], 200);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Display the specified resource.
|
|
||||||
*/
|
|
||||||
public function show(Game $game)
|
public function show(Game $game)
|
||||||
{
|
{
|
||||||
return $game;
|
$game->load(['player1', 'player2', 'winner']);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, Game $game)
|
|
||||||
{
|
|
||||||
$game->update($request->validated());
|
|
||||||
return response()->json($game);
|
return response()->json($game);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function update(Request $request, Game $game)
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(Game $game)
|
|
||||||
{
|
{
|
||||||
//
|
if ($game->status == 'Ended') {
|
||||||
|
return response()->json(['message' => 'Game already ended'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $request->validate([
|
||||||
|
'status' => 'in:Playing,Ended,Interrupted',
|
||||||
|
'winner_user_id' => 'exists:users,id',
|
||||||
|
'loser_user_id' => 'exists:users,id',
|
||||||
|
'player1_points' => 'integer',
|
||||||
|
'player2_points' => 'integer',
|
||||||
|
'is_draw' => 'boolean',
|
||||||
|
'total_time' => 'numeric'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isset($data['status']) && $data['status'] === 'Ended') {
|
||||||
|
$data['ended_at'] = now();
|
||||||
|
}
|
||||||
|
|
||||||
|
$game->update($data);
|
||||||
|
|
||||||
|
return response()->json($game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,149 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Game;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Requests\StoreGameRequest;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* GET /api/users
|
||||||
|
* Lista todos os utilizadores (Apenas para Admins)
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->user()->type !== 'A') {
|
||||||
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = User::query();
|
||||||
|
|
||||||
|
// Filtros úteis para o Backoffice
|
||||||
|
if ($request->has('type')) {
|
||||||
|
$query->where('type', $request->type);
|
||||||
|
}
|
||||||
|
if ($request->has('search')) {
|
||||||
|
$query->where('name', 'like', '%' . $request->search . '%')
|
||||||
|
->orWhere('email', 'like', '%' . $request->search . '%')
|
||||||
|
->orWhere('nickname', 'like', '%' . $request->search . '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($query->paginate(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/users/me
|
||||||
|
* Retorna o perfil do utilizador autenticado atual.
|
||||||
|
* Usado pelo VueJS para saber quem está logado.
|
||||||
|
*/
|
||||||
|
public function me(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json($request->user());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/users/{user}
|
||||||
|
* Mostra um perfil específico.
|
||||||
|
*/
|
||||||
|
public function show(User $user)
|
||||||
|
{
|
||||||
|
$currentUser = Auth::user();
|
||||||
|
if ($currentUser->id !== $user->id && $currentUser->type !== 'A') {
|
||||||
|
return response()->json([
|
||||||
|
'id' => $user->id,
|
||||||
|
'name' => $user->name,
|
||||||
|
'nickname' => $user->nickname,
|
||||||
|
'photo_avatar_filename' => $user->photo_avatar_filename,
|
||||||
|
'type' => $user->type
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT/PATCH /api/users/{user}
|
||||||
|
* Atualizar perfil (Nome, Nickname, Password, Foto)
|
||||||
|
*/
|
||||||
|
public function update(Request $request, User $user)
|
||||||
|
{
|
||||||
|
$currentUser = Auth::user();
|
||||||
|
|
||||||
|
if ($currentUser->id !== $user->id && $currentUser->type !== 'A') {
|
||||||
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$validated = $request->validate([
|
||||||
|
'name' => 'sometimes|string|max:255',
|
||||||
|
'nickname' => ['sometimes', 'string', 'max:20', Rule::unique('users')->ignore($user->id)],
|
||||||
|
'email' => ['sometimes', 'email', Rule::unique('users')->ignore($user->id)],
|
||||||
|
'password' => 'sometimes|string|min:3',
|
||||||
|
'blocked' => 'sometimes|boolean',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isset($validated['blocked']) && $currentUser->type !== 'A') {
|
||||||
|
return response()->json(['message' => 'Only admins can block users'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lógica de Upload de Foto (Exemplo Básico)
|
||||||
|
// if ($request->hasFile('photo_avatar')) {
|
||||||
|
// $path = $request->file('photo_avatar')->store('avatars', 'public');
|
||||||
|
// $validated['photo_avatar_filename'] = basename($path);
|
||||||
|
// }
|
||||||
|
|
||||||
|
$user->update($validated);
|
||||||
|
|
||||||
|
return response()->json($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE /api/users/{user}
|
||||||
|
* Apagar conta (Soft Delete)
|
||||||
|
*/
|
||||||
|
public function destroy(User $user)
|
||||||
|
{
|
||||||
|
$currentUser = Auth::user();
|
||||||
|
|
||||||
|
if ($currentUser->id !== $user->id && $currentUser->type !== 'A') {
|
||||||
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($currentUser->id === $user->id && $currentUser->type === 'A') {
|
||||||
|
if ($user->type === 'A') {
|
||||||
|
return response()->json(['message' => 'Admins cannot delete their own account'], 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->delete();
|
||||||
|
|
||||||
|
return response()->json(['message' => 'User deleted successfully']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/users/{user}/matches
|
||||||
|
* Histórico de Jogos Multiplayer do Utilizador
|
||||||
|
*/
|
||||||
|
public function getMatches(Request $request, User $user)
|
||||||
|
{
|
||||||
|
$currentUser = Auth::user();
|
||||||
|
|
||||||
|
if ($currentUser->id !== $user->id && $currentUser->type !== 'A') {
|
||||||
|
return response()->json(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$matches = Game::query()
|
||||||
|
->where(function($q) use ($user) {
|
||||||
|
$q->where('player1_user_id', $user->id)
|
||||||
|
->orWhere('player2_user_id', $user->id);
|
||||||
|
})
|
||||||
|
->with(['winner', 'player1', 'player2'])
|
||||||
|
->orderBy('began_at', 'desc')
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
|
return response()->json($matches);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Requests;
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class StoreGameRequest extends FormRequest
|
class StoreGameRequest extends FormRequest
|
||||||
{
|
{
|
||||||
@@ -11,7 +12,8 @@ class StoreGameRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
return true;
|
// Só utilizadores autenticados podem criar jogos
|
||||||
|
return Auth::check();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,11 +24,19 @@ class StoreGameRequest extends FormRequest
|
|||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'variant' => 'required|in:bisca-3,bisca-9',
|
// Agora validamos diretamente '3' ou '9' para bater certo com a BD
|
||||||
'mode' => 'required|in:single-player,multiplayer',
|
'type' => 'required|in:3,9',
|
||||||
'opponent_id' => $this->mode === 'multiplayer'
|
];
|
||||||
? 'required|exists:users,id'
|
}
|
||||||
: 'nullable',
|
|
||||||
|
/**
|
||||||
|
* Mensagens personalizadas (Opcional)
|
||||||
|
*/
|
||||||
|
public function messages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type.required' => 'You must choose a game type (Bisca de 3 or 9).',
|
||||||
|
'type.in' => 'Invalid game type. Choose 3 or 9.',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+24
-5
@@ -4,25 +4,44 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use App\Http\Requests\StoreGameRequest;
|
use App\Http\Requests\StoreGameRequest;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
|
||||||
class Game extends Model
|
class Game extends Model
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'player1_id',
|
|
||||||
'player2_id',
|
|
||||||
'winner_id',
|
|
||||||
'type',
|
'type',
|
||||||
'status',
|
'status',
|
||||||
|
'player1_user_id',
|
||||||
|
'player2_user_id',
|
||||||
|
'winner_user_id',
|
||||||
|
'loser_user_id',
|
||||||
'began_at',
|
'began_at',
|
||||||
'ended_at',
|
'ended_at',
|
||||||
'total_time',
|
'total_time',
|
||||||
'player1_moves',
|
'player1_points',
|
||||||
'player2_moves',
|
'player2_points',
|
||||||
|
'custom',
|
||||||
|
'is_draw',
|
||||||
|
'match_id'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function winner()
|
public function winner()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, "winner_user_id");
|
return $this->belongsTo(User::class, "winner_user_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function player1()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'player1_user_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function player2()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'player2_user_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Laravel\Sanctum\HasApiTokens;
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
@@ -11,7 +12,7 @@ use Laravel\Sanctum\HasApiTokens;
|
|||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||||
use HasFactory, Notifiable, HasApiTokens;
|
use HasFactory, Notifiable, HasApiTokens, SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -24,6 +25,10 @@ class User extends Authenticatable
|
|||||||
'password',
|
'password',
|
||||||
'nickname',
|
'nickname',
|
||||||
'photo_avatar_filename',
|
'photo_avatar_filename',
|
||||||
|
'type',
|
||||||
|
'blocked',
|
||||||
|
'coins_balance',
|
||||||
|
'custom',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,6 +51,7 @@ class User extends Authenticatable
|
|||||||
return [
|
return [
|
||||||
'email_verified_at' => 'datetime',
|
'email_verified_at' => 'datetime',
|
||||||
'password' => 'hashed',
|
'password' => 'hashed',
|
||||||
|
'blocked' => 'boolean',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -22,7 +22,8 @@ Route::post('/register', [AuthController::class, 'register']);
|
|||||||
# Game Routes - Protected
|
# Game Routes - Protected
|
||||||
Route::middleware('auth:sanctum')->group(function () {
|
Route::middleware('auth:sanctum')->group(function () {
|
||||||
Route::apiResource('games', GameController::class);
|
Route::apiResource('games', GameController::class);
|
||||||
|
Route::post('games', [GameController::class, 'store']);
|
||||||
Route::post('/games/{game}/resign', [GameController::class, 'resign']);
|
Route::post('/games/{game}/resign', [GameController::class, 'resign']);
|
||||||
Route::post('/games/{game}/play-card', [GameController::class, 'playCard']);
|
|
||||||
Route::get('/users/{user}/matches', [UserController::class, 'getMatches']);
|
Route::get('/users/{user}/matches', [UserController::class, 'getMatches']);
|
||||||
|
Route::post('games/{game}/join', [GameController::class, 'join']);
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user