feature: endpoint to favorite product
This commit is contained in:
parent
3db5c079b9
commit
8ef4383bd9
0
.ai/mcp/mcp.json
Normal file
0
.ai/mcp/mcp.json
Normal file
2
.gitignore
vendored
2
.gitignore
vendored
@ -38,6 +38,8 @@ yarn-error.log
|
|||||||
testem.log
|
testem.log
|
||||||
/typings
|
/typings
|
||||||
__screenshots__/
|
__screenshots__/
|
||||||
|
*.cache
|
||||||
|
.php-cs-fixer.dist.php
|
||||||
|
|
||||||
# System files
|
# System files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
35
backend/app/Http/Controllers/FavouriteProductController.php
Normal file
35
backend/app/Http/Controllers/FavouriteProductController.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Resources\FavouriteProductResource;
|
||||||
|
use App\Models\FavouriteProduct;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class FavouriteProductController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return FavouriteProductResource::collection(FavouriteProduct::all());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toggle(Request $request, Product $product)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $request->user();
|
||||||
|
|
||||||
|
$changes = $user->favoriteProducts()->toggle($product);
|
||||||
|
|
||||||
|
// If changes has any item, that means a product has been attached.
|
||||||
|
$isFavorite = count($changes['attached']) > 0;
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => $isFavorite ? 'Product added to favorites' : 'Product removed from favorites',
|
||||||
|
'isFavorite' => $isFavorite,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
backend/app/Http/Resources/FavouriteProductResource.php
Normal file
23
backend/app/Http/Resources/FavouriteProductResource.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\FavouriteProduct;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/** @mixin FavouriteProduct */
|
||||||
|
class FavouriteProductResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'created_at' => $this->created_at,
|
||||||
|
'updated_at' => $this->updated_at,
|
||||||
|
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'product_id' => $this->product_id,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,7 +11,9 @@
|
|||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||||
use HasFactory, Notifiable;
|
use HasFactory;
|
||||||
|
|
||||||
|
use Notifiable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@ -50,4 +52,14 @@ protected function casts(): array
|
|||||||
'role' => UserRoles::class,
|
'role' => UserRoles::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function favoriteProducts()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Product::class, 'favorite_products', 'user_id', 'product_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasFavorited(Product $product): bool
|
||||||
|
{
|
||||||
|
return $this->favoriteProducts()->where('product_id', $product->id)->exists();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('favorite_products', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignIdFor(User::class);
|
||||||
|
$table->foreignIdFor(Product::class);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->unique(['user_id', 'product_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('favorite_products');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\AuthenticatedUserController;
|
use App\Http\Controllers\AuthenticatedUserController;
|
||||||
|
use App\Http\Controllers\FavouriteProductController;
|
||||||
use App\Http\Controllers\ProductCategoryController;
|
use App\Http\Controllers\ProductCategoryController;
|
||||||
use App\Http\Controllers\ProductController;
|
use App\Http\Controllers\ProductController;
|
||||||
use App\Http\Controllers\ProductImagesController;
|
use App\Http\Controllers\ProductImagesController;
|
||||||
@ -15,6 +16,9 @@
|
|||||||
Route::get('/user', [AuthenticatedUserController::class, 'show']);
|
Route::get('/user', [AuthenticatedUserController::class, 'show']);
|
||||||
Route::post('/logout', [AuthenticatedUserController::class, 'destroy']);
|
Route::post('/logout', [AuthenticatedUserController::class, 'destroy']);
|
||||||
Route::post('/upload/images', action: [ProductImagesController::class, 'store']);
|
Route::post('/upload/images', action: [ProductImagesController::class, 'store']);
|
||||||
|
|
||||||
|
// Favorites
|
||||||
|
Route::post('/products/{product}/favorite', [FavouriteProductController::class, 'toggle']);
|
||||||
});
|
});
|
||||||
Route::get('/categories', [ProductCategoryController::class, 'index']);
|
Route::get('/categories', [ProductCategoryController::class, 'index']);
|
||||||
Route::apiResource('products', ProductController::class);
|
Route::apiResource('products', ProductController::class);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user