['image', 'detailImage', 'categories', 'subCategories', 'tags'], \App\Models\Music::class => ['image', 'playlists', 'tags'], \App\Models\MusicPlaylist::class => ['image', 'detailImage', 'categories', 'subcategories'], \App\Models\BreathingTemplate::class => ['image', 'breathingColor'], ]; } /** * Save an item (music, media, breathing template, etc.) */ public function save(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,breathing-template,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } $result = $model->addSave(); return response()->json([ 'message' => 'Item saved successfully', 'is_saved' => true, 'saved_count' => $model->saved_count ]); } /** * Unsave an item */ public function unsave(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,breathing-template,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } $result = $model->removeSave(); return response()->json([ 'message' => 'Item removed from saved', 'is_saved' => false, 'saved_count' => $model->saved_count ]); } /** * Toggle save status */ public function toggleSave(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,breathing-template,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } $result = $model->toggleSaveStatus(); return response()->json([ 'message' => $result ? 'Item saved successfully' : 'Item removed from saved', 'is_saved' => $model->is_saved, 'saved_count' => $model->saved_count ]); } /** * Get all saved items for the authenticated user */ public function mySavedItems(Request $request) { $type = $request->get('type'); // Optional filter by type $query = SavedItem::with(['saveable' => fn (MorphTo $m) => $m->morphWith(self::morphRelations())]) ->where('user_id', auth()->id()); if ($type) { $modelClass = $this->getModelClass($type); $query->where('saveable_type', $modelClass); } $savedItems = $query->latest()->paginate(20); return response()->json([ 'data' => $savedItems, 'total' => $savedItems->total(), 'types' => [ 'music' => 'App\\Models\\Music', 'media' => 'App\\Models\\Media', 'breathing-template' => 'App\\Models\\BreathingTemplate', 'playlist' => 'App\\Models\\MusicPlaylist', ] ]); } /** * Check if specific item is saved by user */ public function checkSaved(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,breathing-template,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } return response()->json([ 'is_saved' => $model->is_saved, 'saved_count' => $model->saved_count ]); } private function getModel($type, $id) { $modelClass = $this->getModelClass($type); return $modelClass::find($id); } private function getModelClass($type) { $models = [ 'music' => \App\Models\Music::class, 'media' => \App\Models\Media::class, 'breathing-template' => \App\Models\BreathingTemplate::class, 'playlist' => \App\Models\MusicPlaylist::class, ]; return $models[$type] ?? null; } } // public function mySavedItems(Request $request) // { // $type = $request->get('type'); // $query = SavedItem::with('saveable') // ->where('user_id', auth()->id()); // if ($type) { // $modelClass = $this->getModelClass($type); // $query->where('saveable_type', $modelClass); // } // $savedItems = $query->latest()->paginate(20); // // Transform the response to include formatted data // $transformedItems = $savedItems->map(function ($savedItem) { // $item = $savedItem->saveable; // if (!$item) return null; // $baseData = [ // 'saved_id' => $savedItem->id, // 'saved_at' => $savedItem->created_at, // 'type' => class_basename($savedItem->saveable_type), // ]; // // Add type-specific data // if ($item instanceof \App\Models\Music) { // return array_merge($baseData, [ // 'id' => $item->id, // 'title' => $item->title, // 'artist' => $item->artist, // 'duration' => $item->duration_formatted ?? $item->duration, // 'image_url' => $item->image_url, // 'is_saved' => true, // ]); // } elseif ($item instanceof \App\Models\Media) { // return array_merge($baseData, [ // 'id' => $item->id, // 'title' => $item->title, // 'caption' => $item->caption, // 'type' => $item->type, // 'duration' => $item->duration, // 'image_url' => $item->image->url ?? null, // 'is_saved' => true, // ]); // } elseif ($item instanceof \App\Models\BreathingTemplate) { // return array_merge($baseData, [ // 'id' => $item->id, // 'name' => $item->name, // 'description' => $item->description, // 'duration' => $item->duration, // 'inhale' => $item->inhale, // 'exhale' => $item->exhale, // 'breath_hold' => $item->breath_hold, // 'image_url' => $item->image_url, // 'is_saved' => true, // ]); // } // return $baseData; // })->filter();