diff --git a/app/Http/Controllers/BreathingExerciseController.php b/app/Http/Controllers/BreathingExerciseController.php new file mode 100644 index 0000000..337231a --- /dev/null +++ b/app/Http/Controllers/BreathingExerciseController.php @@ -0,0 +1,50 @@ +validate([ + 'subject' => 'required|string', + 'duration' => 'required|integer', + 'created_at' => 'nullable|date', + ]); + + $user = auth()->user(); + + $exercise = BreathingExercise::create([ + 'user_id' => $user->id, + 'subject' => $data['subject'], + 'duration' => $data['duration'], + 'created_at' => $data['created_at'] ?? now(), + ]); + + // Give XP (e.g., +10 per session) + $user->increment('xp', 10); + + return response()->json([ + 'message' => 'Exercise saved', + 'exercise' => $exercise, + 'xp' => $user->xp + ]); + } + + public function profile() + { + $user = auth()->user(); + $user->load('breathingExercises'); + + return response()->json([ + 'email' => $user->email, + 'name' => $user->first_name . ' ' . $user->last_name, + 'xp' => $user->xp, + 'breathing_exercises' => $user->breathingExercises + ]); + } +} diff --git a/app/Models/BreathingExercise.php b/app/Models/BreathingExercise.php new file mode 100644 index 0000000..46e1e0d --- /dev/null +++ b/app/Models/BreathingExercise.php @@ -0,0 +1,16 @@ +belongsTo(User::class); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index cbb8897..7d4fe43 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -97,5 +97,10 @@ public function response() { return $this->hasOne(UserResponse::class); } + + public function breathingExercises() +{ + return $this->hasMany(BreathingExercise::class); +} } \ No newline at end of file diff --git a/database/migrations/2025_08_24_154921_create_breathing_exercises_table.php b/database/migrations/2025_08_24_154921_create_breathing_exercises_table.php new file mode 100644 index 0000000..0f81a2e --- /dev/null +++ b/database/migrations/2025_08_24_154921_create_breathing_exercises_table.php @@ -0,0 +1,30 @@ +id(); + $table->foreignId('user_id')->constrained()->onDelete('cascade'); + $table->string('subject'); + $table->integer('duration'); // duration in seconds or minutes + $table->timestamp('created_at')->nullable(); // if null = now + }); +} + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('breathing_exercises'); + } +}; diff --git a/database/migrations/2025_08_24_154949_add_xp_to_users_table.php b/database/migrations/2025_08_24_154949_add_xp_to_users_table.php new file mode 100644 index 0000000..5edfdaa --- /dev/null +++ b/database/migrations/2025_08_24_154949_add_xp_to_users_table.php @@ -0,0 +1,29 @@ +integer('xp')->default(0); + }); +} + + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + // + }); + } +}; diff --git a/routes/api.php b/routes/api.php index 5652f33..2b2402c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -3,7 +3,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use Laravel\Socialite\Facades\Socialite; - +use App\Http\Controllers\BreathingExerciseController; use App\Http\Controllers\PackageNameController; use App\Http\Controllers\ProductController; @@ -37,5 +37,7 @@ Route::put('/{name}/products/{id}/subscribe', [ProductController::class, 'subscribe']); }); + Route::post('breathing-exercises', [BreathingExerciseController::class, 'store']); + Route::get('profile', [BreathingExerciseController::class, 'profile']); }); \ No newline at end of file