progress
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Resources\ExerciseResource;
|
||||
use App\Models\BodyPart;
|
||||
use App\Models\Equipment;
|
||||
use App\Models\Exercise;
|
||||
use App\Models\Muscle;
|
||||
use App\Models\WorkoutSessionItem;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ExerciseController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$q = trim((string) $request->query('q', ''));
|
||||
$bodypart = (string) $request->query('bodypart', '');
|
||||
$muscle = (string) $request->query('muscle', '');
|
||||
$equipment = (string) $request->query('equipment', '');
|
||||
$perPage = (int) ($request->query('per_page', 12));
|
||||
if ($perPage < 6 || $perPage > 60) { $perPage = 12; }
|
||||
|
||||
$query = Exercise::query()
|
||||
->with(['bodyParts:id,name,slug', 'targetMuscles:id,name,slug', 'secondaryMuscles:id,name,slug', 'equipments:id,name,slug']
|
||||
+ (Auth::check() ? ['aliases' => function ($rel) { $rel->where('user_id', Auth::id()); }] : []))
|
||||
->when($q !== '', function ($qBuilder) use ($q) {
|
||||
$qBuilder->where(function ($sub) use ($q) {
|
||||
$sub->where('name', 'like', "%{$q}%")
|
||||
->orWhere('instructions', 'like', "%{$q}%");
|
||||
});
|
||||
})
|
||||
->when($bodypart !== '', function ($qBuilder) use ($bodypart) {
|
||||
$qBuilder->whereHas('bodyParts', function ($rel) use ($bodypart) {
|
||||
$rel->where('slug', $bodypart);
|
||||
});
|
||||
})
|
||||
->when($muscle !== '', function ($qBuilder) use ($muscle) {
|
||||
$qBuilder->where(function ($sub) use ($muscle) {
|
||||
$sub->whereHas('targetMuscles', function ($rel) use ($muscle) { $rel->where('slug', $muscle); })
|
||||
->orWhereHas('secondaryMuscles', function ($rel) use ($muscle) { $rel->where('slug', $muscle); });
|
||||
});
|
||||
})
|
||||
->when($equipment !== '', function ($qBuilder) use ($equipment) {
|
||||
$qBuilder->whereHas('equipments', function ($rel) use ($equipment) {
|
||||
$rel->where('slug', $equipment);
|
||||
});
|
||||
})
|
||||
->orderBy('name');
|
||||
|
||||
$exercises = $query->paginate($perPage)->withQueryString();
|
||||
|
||||
return response()->json([
|
||||
'data' => ExerciseResource::collection($exercises->items()),
|
||||
'meta' => [
|
||||
'current_page' => $exercises->currentPage(),
|
||||
'last_page' => $exercises->lastPage(),
|
||||
'per_page' => $exercises->perPage(),
|
||||
'total' => $exercises->total(),
|
||||
],
|
||||
'filters' => [
|
||||
'body_parts' => BodyPart::orderBy('name')->get(['id', 'name', 'slug']),
|
||||
'muscles' => Muscle::orderBy('name')->get(['id', 'name', 'slug']),
|
||||
'equipments' => Equipment::orderBy('name')->get(['id', 'name', 'slug']),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Exercise $exercise): JsonResponse
|
||||
{
|
||||
$exercise->load(['bodyParts:id,name,slug', 'targetMuscles:id,name,slug', 'secondaryMuscles:id,name,slug', 'equipments:id,name,slug']
|
||||
+ (Auth::check() ? ['aliases' => function ($rel) { $rel->where('user_id', Auth::id()); }] : []));
|
||||
|
||||
$targetIds = $exercise->targetMuscles->pluck('id')->all();
|
||||
$bodyPartIds = $exercise->bodyParts->pluck('id')->all();
|
||||
$equipmentIds = $exercise->equipments->pluck('id')->all();
|
||||
|
||||
$similarExercises = Exercise::query()
|
||||
->with(['bodyParts:id,name,slug', 'targetMuscles:id,name,slug', 'equipments:id,name,slug']
|
||||
+ (Auth::check() ? ['aliases' => function ($rel) { $rel->where('user_id', Auth::id()); }] : []))
|
||||
->where('id', '!=', $exercise->id)
|
||||
->where(function ($q) use ($targetIds, $bodyPartIds, $equipmentIds) {
|
||||
if (!empty($targetIds)) {
|
||||
$q->orWhereHas('targetMuscles', fn ($rel) => $rel->whereIn('id', $targetIds));
|
||||
}
|
||||
if (!empty($bodyPartIds)) {
|
||||
$q->orWhereHas('bodyParts', fn ($rel) => $rel->whereIn('id', $bodyPartIds));
|
||||
}
|
||||
if (!empty($equipmentIds)) {
|
||||
$q->orWhereHas('equipments', fn ($rel) => $rel->whereIn('id', $equipmentIds));
|
||||
}
|
||||
})
|
||||
->orderBy('name')
|
||||
->limit(9)
|
||||
->get();
|
||||
|
||||
$personalBest = null;
|
||||
if (Auth::check()) {
|
||||
$personalBest = WorkoutSessionItem::query()
|
||||
->whereHas('workoutExercise', fn ($q) => $q->where('exercise_id', $exercise->id))
|
||||
->whereHas('session', fn ($q) => $q->where('user_id', Auth::id()))
|
||||
->where('done', true)
|
||||
->whereNotNull('actual_weight')
|
||||
->orderByDesc('actual_weight')
|
||||
->orderByDesc('actual_reps')
|
||||
->first();
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'exercise' => new ExerciseResource($exercise),
|
||||
'similar_exercises' => ExerciseResource::collection($similarExercises),
|
||||
'personal_best' => $personalBest ? [
|
||||
'actual_weight' => $personalBest->actual_weight !== null ? (float) $personalBest->actual_weight : null,
|
||||
'actual_reps' => $personalBest->actual_reps,
|
||||
] : null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user