diff --git a/app/Http/Controllers/MediaController.php b/app/Http/Controllers/MediaController.php index 1ecd3f0..856e64e 100644 --- a/app/Http/Controllers/MediaController.php +++ b/app/Http/Controllers/MediaController.php @@ -22,7 +22,7 @@ public function store(Request $request) 'category_name' => 'nullable|string|max:255', 'image_id' => 'nullable|exists:images,id', 'duration' => 'nullable|integer', - + 'is_premium' => 'nullable|boolean', 'file' => 'nullable|mimes:mp3,wav,mp4,mov|max:512000', 'external_url' => 'nullable|string', 'visibility' => 'nullable|in:public,private', @@ -55,6 +55,7 @@ public function store(Request $request) 'category_id' => $categoryId, 'duration' => $data['duration'] ?? null, 'visibility' => $data['visibility'] ?? 'public', + 'is_premium'=> $data['is_premium'] ?? false ]); if (!empty($data['tags'])) { $tagIds = []; @@ -115,13 +116,32 @@ public function index(Request $request) public function show($id) { - $media = Media::with(['image', 'category', 'myNote' , 'tags']) - ->where('id', $id) - ->where('visibility', 'public') - ->orWhere('user_id', auth()->id()) - ->firstOrFail(); + $media = Media::with(['image', 'category', 'myNote', 'tags']) + ->where('id', $id) + ->where(function($query) { + $query->where('visibility', 'public') + ->orWhere('user_id', auth()->id()); + }) + ->firstOrFail(); - return response()->json($media); + return response()->json([ + 'id' => $media->id, + 'title' => $media->title, + 'caption' => $media->caption, + 'type' => $media->type, + 'file_path' => $media->file_path, + 'external_url' => $media->external_url, + 'duration' => $media->duration, + 'visibility' => $media->visibility, + 'created_at' => $media->created_at, + 'updated_at' => $media->updated_at, + 'image' => $media->image, + 'category' => $media->category, + 'tags' => $media->tags, + 'myNote' => $media->myNote, + 'is_saved' => $media->is_saved, + 'is_premium' => $media->is_premium, + ]); } // UPDATE media @@ -139,7 +159,7 @@ public function update(Request $request, $id) // support both: category_id or category_name 'category_id' => 'nullable|exists:categories,id', 'category_name' => 'nullable|string|max:255', - + 'is_premium' => 'nullable|boolean', 'image_id' => 'nullable|exists:images,id', 'duration' => 'nullable|integer', 'file' => 'nullable|mimes:mp3,wav,mp4,mov|max:512000', @@ -171,6 +191,7 @@ public function update(Request $request, $id) 'caption' => $data['caption'] ?? $media->caption, 'type' => $data['type'] ?? $media->type, 'category_id' => $categoryId, + 'is_premium' => $data['is_premium'] ?? $media->is_premium, 'duration' => $data['duration'] ?? $media->duration, 'external_url' => $data['external_url'] ?? $media->external_url, 'visibility' => $data['visibility'] ?? $media->visibility, @@ -221,12 +242,20 @@ public function destroy($id) } // SAVE media - public function saveMedia($id) - { - auth()->user()->savedMedia()->syncWithoutDetaching([$id]); +public function toggleSaveMedia($id) +{ + $user = auth()->user(); + if ($user->savedMedia()->where('media_id', $id)->exists()) { + // already saved → unsave + $user->savedMedia()->detach($id); + return response()->json(['message' => 'Unsaved!']); + } else { + // not saved → save + $user->savedMedia()->attach($id); return response()->json(['message' => 'Saved!']); } +} // GET saved public function saved() @@ -234,19 +263,40 @@ public function saved() return auth()->user()->savedMedia()->with(['image','category' , 'myNote' , 'tags'])->get(); } - public function storeNote(Request $request, $mediaId) +public function storeNote(Request $request, $mediaId) { - $data = $request->validate([ - 'content' => 'required|string' - ]); - $media = Media::findOrFail($mediaId); + $userId = auth()->id(); - $note = $media->notes()->create([ - 'user_id' => auth()->id(), - 'content' => $data['content'], + $content = $request->input('content'); + + // Check if note already exists for this user + $note = $media->notes()->where('user_id', $userId)->first(); + + if (empty($content)) { + // If content is empty, delete the note if it exists + if ($note) { + $note->delete(); + return response()->json(['message' => 'Note deleted']); + } + return response()->json(['message' => 'No note to delete']); + } + + if ($note) { + // Update existing note + $note->update(['content' => $content]); + } else { + // Create new note + $note = $media->notes()->create([ + 'user_id' => $userId, + 'content' => $content, + ]); + } + + return response()->json([ + 'message' => 'Note saved successfully', + 'note' => $note ]); - - return response()->json(['message' => 'Note added', 'note' => $note]); } + } \ No newline at end of file diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 67d4de6..7eb6ce4 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -629,7 +629,7 @@ public function googleLogin(Request $request) public function leaderBoard(){ $users = User::with(['breathingSessions.template'])->where('xp', '>', 0) - ->orderBy('xp', 'desc') + ->orderBy('xp', 'desc')->limit(20) ->get(); return $users; diff --git a/app/Models/Media.php b/app/Models/Media.php index 512ceb6..3c023cd 100644 --- a/app/Models/Media.php +++ b/app/Models/Media.php @@ -17,6 +17,7 @@ class Media extends Model 'external_url', 'duration', 'visibility', + 'is_premium' ]; public function image() @@ -54,4 +55,15 @@ public function getUrlAttribute() return $this->external_url; } + + + public function getIsSavedAttribute() + { + if (!auth()->check()) return false; + + return $this->savedBy() + ->where('user_id', auth()->id()) + ->exists(); + } + } diff --git a/database/migrations/2025_11_30_103759_add_is_premium_to_media.php b/database/migrations/2025_11_30_103759_add_is_premium_to_media.php new file mode 100644 index 0000000..5f7c481 --- /dev/null +++ b/database/migrations/2025_11_30_103759_add_is_premium_to_media.php @@ -0,0 +1,28 @@ +boolean('is_premium')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('media', function (Blueprint $table) { + $table->dropColumn('is_premium'); + }); + } +}; diff --git a/routes/api.php b/routes/api.php index 4badb6f..14ebe8e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -138,10 +138,11 @@ Route::post('/media', [MediaController::class, 'store']); Route::get('/media', [MediaController::class, 'index']); Route::post('/media/{id}', [MediaController::class, 'update']); + Route::get('/media/saved', [MediaController::class, 'saved']); Route::delete('/media/{id}', [MediaController::class, 'destroy']); Route::get('/media/{id}', [MediaController::class, 'show']); - Route::post('/media/{id}/save', [MediaController::class, 'saveMedia']); - Route::get('/media/saved', [MediaController::class, 'saved']); + Route::post('/media/{id}/save', [MediaController::class, 'toggleSaveMedia']); + Route::post('/media/{id}/note', [MediaController::class, 'storeNote']); }); \ No newline at end of file