103 lines
3.2 KiB
PHP
103 lines
3.2 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace App\Http\Controllers;
|
||
|
|
|
||
|
|
use App\Models\Program;
|
||
|
|
use App\Models\WorkoutSession;
|
||
|
|
use Illuminate\Http\RedirectResponse;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Illuminate\Support\Facades\Auth;
|
||
|
|
use Illuminate\View\View;
|
||
|
|
|
||
|
|
class ProgramController extends Controller
|
||
|
|
{
|
||
|
|
public function index(): View
|
||
|
|
{
|
||
|
|
$programs = Auth::user()->programs()->withCount('workouts')->latest()->paginate(10);
|
||
|
|
|
||
|
|
return view('programs.index', compact('programs'));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function create(): View
|
||
|
|
{
|
||
|
|
return view('programs.create');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function store(Request $request): RedirectResponse
|
||
|
|
{
|
||
|
|
$data = $request->validate([
|
||
|
|
'title' => ['required', 'string', 'max:255'],
|
||
|
|
'description' => ['nullable', 'string'],
|
||
|
|
'weeks' => ['required', 'integer', 'min:1', 'max:52'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$program = Auth::user()->programs()->create($data);
|
||
|
|
|
||
|
|
return redirect()->route('programs.show', $program)->with('status', 'Program created');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function show(Program $program): View
|
||
|
|
{
|
||
|
|
$this->authorizeProgram($program);
|
||
|
|
$program->load('workouts');
|
||
|
|
|
||
|
|
$completedWorkoutIds = WorkoutSession::query()
|
||
|
|
->where('user_id', Auth::id())
|
||
|
|
->whereIn('workout_id', $program->workouts->pluck('id'))
|
||
|
|
->whereNotNull('completed_at')
|
||
|
|
->pluck('workout_id')
|
||
|
|
->unique();
|
||
|
|
|
||
|
|
$workoutsByWeek = $program->workouts->groupBy('week_number');
|
||
|
|
|
||
|
|
$totalWorkouts = $program->workouts->count();
|
||
|
|
$completedCount = $completedWorkoutIds->count();
|
||
|
|
$progressPct = $totalWorkouts > 0 ? (int) round(($completedCount / $totalWorkouts) * 100) : 0;
|
||
|
|
|
||
|
|
return view('programs.show', [
|
||
|
|
'program' => $program,
|
||
|
|
'workoutsByWeek' => $workoutsByWeek,
|
||
|
|
'completedWorkoutIds' => $completedWorkoutIds,
|
||
|
|
'progressPct' => $progressPct,
|
||
|
|
'completedCount' => $completedCount,
|
||
|
|
'totalWorkouts' => $totalWorkouts,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function destroy(Program $program): RedirectResponse
|
||
|
|
{
|
||
|
|
$this->authorizeProgram($program);
|
||
|
|
$program->delete();
|
||
|
|
|
||
|
|
return redirect()->route('programs.index')->with('status', 'Program deleted');
|
||
|
|
}
|
||
|
|
|
||
|
|
public function addWorkout(Request $request, Program $program): RedirectResponse
|
||
|
|
{
|
||
|
|
$this->authorizeProgram($program);
|
||
|
|
$data = $request->validate([
|
||
|
|
'title' => ['required', 'string', 'max:255'],
|
||
|
|
'week_number' => ['required', 'integer', 'min:1', 'max:' . $program->weeks],
|
||
|
|
'day_number' => ['required', 'integer', 'min:1', 'max:14'],
|
||
|
|
'estimated_minutes' => ['nullable', 'integer', 'min:1', 'max:600'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$program->workouts()->create([
|
||
|
|
'user_id' => Auth::id(),
|
||
|
|
'title' => $data['title'],
|
||
|
|
'estimated_minutes' => $data['estimated_minutes'] ?? null,
|
||
|
|
'week_number' => $data['week_number'],
|
||
|
|
'day_number' => $data['day_number'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
return back()->with('status', 'Workout added to program');
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function authorizeProgram(Program $program): void
|
||
|
|
{
|
||
|
|
if ($program->user_id !== Auth::id()) {
|
||
|
|
abort(403);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|