diff --git a/app/Http/Controllers/ExerciseController.php b/app/Http/Controllers/ExerciseController.php index dd77ff6..549ac87 100644 --- a/app/Http/Controllers/ExerciseController.php +++ b/app/Http/Controllers/ExerciseController.php @@ -6,6 +6,7 @@ use App\Models\BodyPart; use App\Models\Equipment; use App\Models\Exercise; use App\Models\Muscle; +use App\Models\WorkoutSessionItem; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -104,9 +105,23 @@ class ExerciseController extends Controller $similarExercises = $similarQuery->get(); + $personalBest = null; + if (Auth::check()) { + $personalBest = WorkoutSessionItem::query() + ->with('session') + ->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 view('exercises.show', [ 'exercise' => $exercise, 'similarExercises' => $similarExercises, + 'personalBest' => $personalBest, ]); } } diff --git a/app/Http/Controllers/WorkoutSessionController.php b/app/Http/Controllers/WorkoutSessionController.php index deb26b3..bbfef5c 100644 --- a/app/Http/Controllers/WorkoutSessionController.php +++ b/app/Http/Controllers/WorkoutSessionController.php @@ -58,6 +58,11 @@ class WorkoutSessionController extends Controller abort(404); } + $data = $request->validate([ + 'actual_weight' => ['nullable', 'numeric', 'min:0', 'max:9999.99'], + 'actual_reps' => ['nullable', 'integer', 'min:0', 'max:1000'], + ]); + $si = WorkoutSessionItem::firstOrCreate([ 'session_id' => $session->id, 'workout_exercise_id' => $item->id, @@ -66,6 +71,14 @@ class WorkoutSessionController extends Controller ]); $si->done = !$si->done; + if ($si->done) { + if (array_key_exists('actual_weight', $data) && $data['actual_weight'] !== null) { + $si->actual_weight = $data['actual_weight']; + } + if (array_key_exists('actual_reps', $data) && $data['actual_reps'] !== null) { + $si->actual_reps = $data['actual_reps']; + } + } $si->save(); return back(); diff --git a/app/Models/WorkoutSessionItem.php b/app/Models/WorkoutSessionItem.php index 4382b6a..9bf6f7d 100644 --- a/app/Models/WorkoutSessionItem.php +++ b/app/Models/WorkoutSessionItem.php @@ -16,12 +16,16 @@ class WorkoutSessionItem extends Model 'done', 'exercise_ms', 'rest_ms', + 'actual_weight', + 'actual_reps', ]; protected $casts = [ 'done' => 'boolean', 'exercise_ms' => 'integer', 'rest_ms' => 'integer', + 'actual_weight' => 'decimal:2', + 'actual_reps' => 'integer', ]; public function session(): BelongsTo diff --git a/database/factories/WorkoutSessionItemFactory.php b/database/factories/WorkoutSessionItemFactory.php new file mode 100644 index 0000000..b1e0ea7 --- /dev/null +++ b/database/factories/WorkoutSessionItemFactory.php @@ -0,0 +1,24 @@ + + */ +class WorkoutSessionItemFactory extends Factory +{ + public function definition(): array + { + return [ + 'session_id' => WorkoutSession::factory(), + 'workout_exercise_id' => WorkoutExercise::factory(), + 'done' => false, + 'actual_weight' => null, + 'actual_reps' => null, + ]; + } +} diff --git a/database/migrations/2026_08_10_091029_add_actual_performance_to_workout_session_items_table.php b/database/migrations/2026_08_10_091029_add_actual_performance_to_workout_session_items_table.php new file mode 100644 index 0000000..7da23c2 --- /dev/null +++ b/database/migrations/2026_08_10_091029_add_actual_performance_to_workout_session_items_table.php @@ -0,0 +1,29 @@ +decimal('actual_weight', 6, 2)->nullable()->after('done'); + $table->unsignedSmallInteger('actual_reps')->nullable()->after('actual_weight'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('workout_session_items', function (Blueprint $table) { + $table->dropColumn(['actual_weight', 'actual_reps']); + }); + } +}; diff --git a/lang/en/app.php b/lang/en/app.php index cfaed6f..279c431 100644 --- a/lang/en/app.php +++ b/lang/en/app.php @@ -192,6 +192,8 @@ return [ 'rename_reset' => 'Reset', 'renamed_success' => 'Your custom name has been saved.', 'rename_cleared' => 'Custom name cleared.', + 'personal_best' => 'Your Personal Best', + 'no_personal_best' => 'No completed sets logged yet. Track weight and reps when you check off a set in a session.', ], 'sessions' => [ @@ -211,7 +213,9 @@ return [ 'rest_timer' => 'Rest timer', 'start_rest' => 'Start', 'pause_rest' => 'Pause', - 'reset_rest' => 'Reset' + 'reset_rest' => 'Reset', + 'weight_lifted' => 'Weight', + 'reps_done' => 'Reps', ], 'dashboard' => [ diff --git a/lang/ro/app.php b/lang/ro/app.php index c119d78..e3a834b 100644 --- a/lang/ro/app.php +++ b/lang/ro/app.php @@ -192,6 +192,8 @@ return [ 'rename_reset' => 'Resetează', 'renamed_success' => 'Numele personalizat a fost salvat.', 'rename_cleared' => 'Numele personalizat a fost eliminat.', + 'personal_best' => 'Recordul tău personal', + 'no_personal_best' => 'Niciun set finalizat înregistrat încă. Înregistrează greutatea și repetările când bifezi un set într-o sesiune.', ], 'sessions' => [ @@ -211,7 +213,9 @@ return [ 'rest_timer' => 'Cronometru pauză', 'start_rest' => 'Start', 'pause_rest' => 'Pauză', - 'reset_rest' => 'Reset' + 'reset_rest' => 'Reset', + 'weight_lifted' => 'Greutate', + 'reps_done' => 'Repetări', ], 'dashboard' => [ diff --git a/resources/views/exercises/show.blade.php b/resources/views/exercises/show.blade.php index 41dcac3..5120815 100644 --- a/resources/views/exercises/show.blade.php +++ b/resources/views/exercises/show.blade.php @@ -79,6 +79,22 @@
+ @auth +
+

{{ __('app.exercises.personal_best') }}

+ @if($personalBest) +
+ {{ rtrim(rtrim(number_format($personalBest->actual_weight, 1), '0'), '.') }} kg + @if($personalBest->actual_reps) + × {{ $personalBest->actual_reps }} {{ __('app.sessions.reps') }} + @endif +
+

{{ optional($personalBest->session)->completed_at?->format('M j, Y') ?? $personalBest->updated_at->format('M j, Y') }}

+ @else +

{{ __('app.exercises.no_personal_best') }}

+ @endif +
+ @endauth

Exercise Info

diff --git a/resources/views/workouts/session.blade.php b/resources/views/workouts/session.blade.php index b1f3d84..8885f6d 100644 --- a/resources/views/workouts/session.blade.php +++ b/resources/views/workouts/session.blade.php @@ -29,6 +29,8 @@
@csrf @method('PATCH') + +