feat: join hunt
This commit is contained in:
parent
a323489a6f
commit
66cf5e1de8
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum ParticipateStatus: string
|
||||
{
|
||||
case Started = 'started';
|
||||
case Completed = 'completed';
|
||||
}
|
||||
|
|
@ -57,17 +57,72 @@ class HuntsController extends Controller
|
|||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show($id)
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Request $request, $id)
|
||||
{
|
||||
$hunt = Hunts::find($id);
|
||||
$hunt = Hunts::with('steps')->find($id);
|
||||
|
||||
if (!$hunt) {
|
||||
return response()->json(['message' => 'Hunt not found'], 404);
|
||||
}
|
||||
|
||||
$user = $request->user('sanctum');
|
||||
|
||||
if ($user) {
|
||||
$participation = $user->participations()->where('hunt_id', $hunt->id)->first();
|
||||
|
||||
if ($participation) {
|
||||
// User is a participant
|
||||
$currentStepNumber = $participation->pivot->current_step_number;
|
||||
|
||||
// Filter steps
|
||||
$hunt->setRelation('steps', $hunt->steps->filter(function ($step) use ($currentStepNumber) {
|
||||
if ($step->step_number < $currentStepNumber) {
|
||||
return true; // Show past steps fully
|
||||
}
|
||||
if ($step->step_number == $currentStepNumber) {
|
||||
// Hide hints for current step
|
||||
$step->makeHidden(['hint_text', 'hint_media_url']);
|
||||
return true;
|
||||
}
|
||||
return false; // Hide future steps
|
||||
})->values());
|
||||
|
||||
$hunt->participation_status = $participation->pivot;
|
||||
} elseif ($hunt->creator_id !== $user->id) {
|
||||
// User is logged in but not participant and not creator
|
||||
// Show only first step or nothing specific (keep as is for now, maybe hide all steps or just show basic info)
|
||||
// For now, let's just hide hints of all steps if not participating?
|
||||
// Or maybe just show nothing of steps if not participating?
|
||||
// Requirement: "fetch the hunt in question it retrieves me the hunt steps already passed and the next one" implying context of participation.
|
||||
// If not participating, maybe just return basic hunt info without steps?
|
||||
$hunt->unsetRelation('steps');
|
||||
}
|
||||
// If creator, show everything (default)
|
||||
} else {
|
||||
// Guest
|
||||
$hunt->unsetRelation('steps');
|
||||
}
|
||||
|
||||
return response()->json($hunt);
|
||||
}
|
||||
|
||||
public function participate(Request $request, $id)
|
||||
{
|
||||
$hunt = Hunts::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if ($user->participations()->where('hunt_id', $hunt->id)->exists()) {
|
||||
return response()->json(['message' => 'Already participating'], 409);
|
||||
}
|
||||
|
||||
$hunt->participants()->attach($user->id, ['current_step_number' => 1, 'status' => 'started']);
|
||||
|
||||
return response()->json(['message' => 'Participation started'], 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -43,4 +43,11 @@ class Hunts extends Model
|
|||
{
|
||||
return $this->hasMany(HuntSteps::class, 'hunt_id');
|
||||
}
|
||||
|
||||
public function participants()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'hunt_participants', 'hunt_id', 'user_id')
|
||||
->withPivot(['current_step_number', 'status'])
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,4 +54,11 @@ class User extends Authenticatable
|
|||
'role'=> UserRole::class
|
||||
];
|
||||
}
|
||||
|
||||
public function participations()
|
||||
{
|
||||
return $this->belongsToMany(Hunts::class, 'hunt_participants', 'user_id', 'hunt_id')
|
||||
->withPivot(['current_step_number', 'status'])
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use App\Enums\ParticipateStatus;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('hunt_participants', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('hunt_id')->constrained('hunts')->cascadeOnDelete();
|
||||
$table->unsignedSmallInteger('current_step_number')->default(1);
|
||||
$table->string('status')->default(ParticipateStatus::Started->value);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('hunt_participants');
|
||||
}
|
||||
};
|
||||
|
|
@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Route;
|
|||
|
||||
|
||||
use App\Http\Controllers\HuntsController;
|
||||
use App\Http\Controllers\HuntStepsController;
|
||||
use App\Http\Middleware\EnsureUserIsOrga;
|
||||
|
||||
Route::prefix('auth')->group(function (): void {
|
||||
|
|
@ -17,36 +18,22 @@ Route::prefix('auth')->group(function (): void {
|
|||
// Route::get('{provider}/callback', [ProviderCallbackController::class, 'callback']);
|
||||
});
|
||||
|
||||
|
||||
// List hunts
|
||||
Route::get('hunts', [HuntsController::class, 'index']);
|
||||
Route::get('hunts/{hunt}', [HuntsController::class, 'show']);
|
||||
|
||||
// Ensure is Orga
|
||||
Route::middleware(['auth:sanctum', EnsureUserIsOrga::class])->group(function () {
|
||||
Route::post('hunts', [HuntsController::class, 'store']);
|
||||
Route::post('hunts/{hunt}/steps', [\App\Http\Controllers\HuntStepsController::class, 'store']);
|
||||
Route::post('hunts/{hunt}/steps', [HuntStepsController::class, 'store']);
|
||||
Route::match(['put', 'patch'], 'hunts/{hunt}', [HuntsController::class, 'update']);
|
||||
Route::delete('hunts/{hunt}', [HuntsController::class, 'destroy']);
|
||||
});
|
||||
|
||||
// Auth middleware
|
||||
Route::middleware('auth:sanctum')->group(function (): void {
|
||||
// Route::get('/user', function (Request $request) {
|
||||
// return $request->user();
|
||||
// });
|
||||
|
||||
// User
|
||||
Route::post('hunts/{hunt}/participate', [HuntsController::class, 'participate']);
|
||||
Route::get('auth/me', [AuthController::class, 'me']);
|
||||
Route::post('auth/logout', [AuthController::class, 'logout']);
|
||||
|
||||
|
||||
|
||||
// Route::middleware([EnsureAdmin::class])->group(function (): void {
|
||||
// Route::apiResource('users', UserController::class);
|
||||
// Route::apiResource('main-categories', MainCategoryController::class)->except(['index', 'show']);
|
||||
// Route::apiResource('categories', CategoryController::class)->except(['index', 'show']);
|
||||
// Route::apiResource('products', ProductsController::class)->except(['index', 'show']);
|
||||
// Route::apiResource('product-variants', ProductVariantController::class);
|
||||
// Route::apiResource('product-variant-images', ProductVariantImagesController::class);
|
||||
// Route::apiResource('pickup-points', PickupPointsController::class)->only(['destroy']);
|
||||
// Route::apiResource('pickup-point-schedules', PickupPointsSchedulesController::class)->except(['index', 'show']);
|
||||
// });
|
||||
});
|
||||
Loading…
Reference in New Issue