diff --git a/app/Http/Controllers/MoodController.php b/app/Http/Controllers/MoodController.php index 67ca7f7..626fe75 100644 --- a/app/Http/Controllers/MoodController.php +++ b/app/Http/Controllers/MoodController.php @@ -13,11 +13,12 @@ public function storeUserMood(Request $request) { $data = $request->validate([ 'mood_id' => 'required|exists:moods,id', + 'note' => 'nullable|string' ]); $user = auth()->user(); - $mood = UserMood::updateOrCreate( + $moodEntry = UserMood::updateOrCreate( [ 'user_id' => $user->id, 'date' => now()->toDateString(), @@ -26,28 +27,35 @@ public function storeUserMood(Request $request) 'mood_id' => $data['mood_id'], ] ); + // If a note is provided, create or update it + if (!empty($data['note'])) { + $moodEntry->notes()->updateOrCreate( + ['user_id' => $user->id], + ['content' => $data['note']] + ); + } $user->increment('xp', 10); return response()->json([ 'message' => 'Mood saved successfully', 'xp' => $user->xp, - 'mood' => $mood->load('mood') + 'mood' => $moodEntry->load(['mood', 'notes']) ]); } // Get list of all moods user has set public function getUserMoods() - { - $user = auth()->user(); + { + $user = auth()->user(); - $moods = UserMood::where('user_id', $user->id) - ->with('mood') - ->orderBy('date', 'desc') - ->get(); + $moods = UserMood::where('user_id', $user->id) + ->with(['mood', 'notes']) + ->orderBy('date', 'desc') + ->get(); - return response()->json($moods); - } + return response()->json($moods); + } public function getAllMoods() { diff --git a/app/Http/Controllers/WorryController.php b/app/Http/Controllers/WorryController.php new file mode 100644 index 0000000..8d0b3f2 --- /dev/null +++ b/app/Http/Controllers/WorryController.php @@ -0,0 +1,86 @@ +validate([ + 'title' => 'required|string|max:255', + 'note' => 'nullable|string' + ]); + + $worry = Worry::create([ + 'user_id' => auth()->id(), + 'title' => $data['title'], + ]); + + if (!empty($data['note'])) { + $worry->notes()->create([ + 'user_id' => auth()->id(), + 'content' => $data['note'] + ]); + } + + return response()->json($worry->load('notes')); + } + + public function update(Request $request, $id) + { + $data = $request->validate([ + 'title' => 'nullable|string|max:255', + 'note' => 'nullable|string' + ]); + + $worry = Worry::where('user_id', auth()->id())->findOrFail($id); + + if (!empty($data['title'])) { + $worry->update(['title' => $data['title']]); + } + + if (isset($data['note'])) { + $note = $worry->notes()->where('user_id', auth()->id())->first(); + + if ($note) { + $note->update(['content' => $data['note']]); + } else { + $worry->notes()->create([ + 'user_id' => auth()->id(), + 'content' => $data['note'] + ]); + } + } + + return response()->json($worry->load('notes')); + } + + public function index() + { + $worries = Worry::where('user_id', auth()->id()) + ->with('notes') + ->orderBy('created_at', 'desc') + ->get(); + + return response()->json($worries); + } + + public function toggleSolved($id) + { + $worry = Worry::where('user_id', auth()->id())->findOrFail($id); + $worry->update(['is_solved' => !$worry->is_solved]); + + return response()->json($worry); + } + + public function destroy($id) + { + $worry = Worry::where('user_id', auth()->id())->findOrFail($id); + $worry->delete(); + + return response()->json(['message' => 'Worry deleted successfully']); + } +} diff --git a/app/Models/Note.php b/app/Models/Note.php new file mode 100644 index 0000000..7ea6e9c --- /dev/null +++ b/app/Models/Note.php @@ -0,0 +1,20 @@ +belongsTo(User::class); + } + + public function noteable() + { + return $this->morphTo(); + } +} diff --git a/app/Models/UserMood.php b/app/Models/UserMood.php index ef2b562..1372669 100644 --- a/app/Models/UserMood.php +++ b/app/Models/UserMood.php @@ -16,4 +16,8 @@ public function mood() { return $this->belongsTo(Mood::class); } + public function notes() + { + return $this->morphMany(Note::class, 'noteable'); + } } diff --git a/app/Models/Worry.php b/app/Models/Worry.php new file mode 100644 index 0000000..4f6bf7b --- /dev/null +++ b/app/Models/Worry.php @@ -0,0 +1,20 @@ +belongsTo(User::class); + } + + public function notes() + { + return $this->morphMany(Note::class, 'noteable'); + } +} diff --git a/database/migrations/2025_08_31_083842_create_notes_table.php b/database/migrations/2025_08_31_083842_create_notes_table.php new file mode 100644 index 0000000..1821088 --- /dev/null +++ b/database/migrations/2025_08_31_083842_create_notes_table.php @@ -0,0 +1,30 @@ +id(); + $table->foreignId('user_id')->constrained()->onDelete('cascade'); + $table->text('content'); + $table->nullableMorphs('noteable'); // noteable_id & noteable_type + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('notes'); + } +}; diff --git a/database/migrations/2025_08_31_091837_create_worries_table.php b/database/migrations/2025_08_31_091837_create_worries_table.php new file mode 100644 index 0000000..cbb1fad --- /dev/null +++ b/database/migrations/2025_08_31_091837_create_worries_table.php @@ -0,0 +1,30 @@ +id(); + $table->foreignId('user_id')->constrained()->onDelete('cascade'); + $table->string('title'); + $table->boolean('is_solved')->default(false); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('worries'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 7c92eda..fe11447 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -10,7 +10,7 @@ class DatabaseSeeder extends Seeder { public function run(): void { - $this->call(MoodSeeder::class); + $this->call(BreathingTemplateSeeder::class); } /** * Seed the application's database. diff --git a/routes/api.php b/routes/api.php index 755480b..fcfe42b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -8,6 +8,7 @@ use App\Http\Controllers\ProductController; use App\Http\Controllers\BreathingTemplate; use App\Http\Controllers\MoodController; +use App\Http\Controllers\WorryController; Route::get('package-names/{name}/products', [ProductController::class, 'index']); Route::prefix('auth')->controller(UserController::class)->group(function () { @@ -35,11 +36,7 @@ Route::middleware('abilities:admin')->post('/{name}/products', [ProductController::class, 'store']); Route::middleware('abilities:admin')->patch('/{name}/products/{id}', [ProductController::class, 'update']); Route::middleware('abilities:admin')->delete('/{name}/products/{id}', [ProductController::class, 'delete']); - Route::put('/{name}/products/{id}/subscribe', [ProductController::class, 'subscribe']); - - - - + Route::put('/{name}/products/{id}/subscribe', [ProductController::class, 'subscribe']); }); // --------- user profile Route::post('/profile', [UserController::class, 'updateProfile']); @@ -66,4 +63,14 @@ Route::put('breathing-templates/{id}', [BreathingExerciseController::class, 'updateTemplate']); Route::delete('breathing-templates/{id}', [BreathingExerciseController::class, 'deleteTemplate']); Route::get('user-templates', [BreathingExerciseController::class, 'getUserTemplates']); + + /// worry box feature + Route::prefix('worries')->controller(WorryController::class)->group(function () { + Route::post('/', 'store'); // Create worry + note + Route::get('/', 'index'); // Get all worries + Route::put('/{id}', 'update'); // Edit worry & note + Route::patch('/{id}/toggle', 'toggleSolved'); // Mark solved / unsolved + Route::delete('/{id}', 'destroy'); // Delete worry + }); + }); \ No newline at end of file