Skip to content

Commit 405e708

Browse files
Merge pull request #26 from shopperlabs/feature/sho-54-amelioration-de-la-page-detail-produit
feat:[SHO-54] add products variants in single product detail page and…
2 parents 167eadf + f0cac5c commit 405e708

28 files changed

+321
-252
lines changed

app/Livewire/Pages/Category/CategoryProducts.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@
55
namespace App\Livewire\Pages\Category;
66

77
use App\Models\Category;
8+
use App\Models\Product;
89
use Illuminate\Contracts\View\View;
10+
use Illuminate\Database\Eloquent\Builder;
911
use Livewire\Component;
1012

1113
final class CategoryProducts extends Component
1214
{
1315
public Category $category;
1416

15-
public function mount(string $slug): void
17+
public function mount(): void
1618
{
17-
$this->category = Category::with('products')->where('slug', $slug)->firstOrFail();
19+
abort_unless($this->category->is_enabled, 404);
1820
}
1921

2022
public function render(): View
2123
{
22-
return view('livewire.category.category-products', ['products' => $this->category->products]);
24+
return view('livewire.category.category-products', [
25+
'products' => Product::with('media', 'categories')
26+
->scopes('publish')
27+
->whereHas('categories', function ($query): void {
28+
$query->where('id', $this->category->id);
29+
})
30+
->get(),
31+
]);
2332
}
2433
}

app/Livewire/Pages/Collection/CollectionProducts.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@
55
namespace App\Livewire\Pages\Collection;
66

77
use App\Models\Collection;
8+
use App\Models\Product;
89
use Illuminate\Contracts\View\View;
910
use Livewire\Component;
1011

1112
class CollectionProducts extends Component
1213
{
1314
public Collection $collection;
1415

15-
public function mount(string $slug): void
16-
{
17-
$this->collection = Collection::with('products')->where('slug', $slug)->firstOrFail();
18-
}
19-
2016
public function render(): View
2117
{
22-
return view('livewire.collection.collection-products', ['products' => $this->collection->products]);
18+
return view('livewire.collection.collection-products', [
19+
'products' => Product::with('media', 'collections')
20+
->scopes('publish')
21+
->whereHas('collections', function ($query): void {
22+
$query->where('id', $this->collection->id);
23+
})
24+
->get(),
25+
]);
2326
}
2427
}

app/Livewire/Pages/SingleProduct.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,36 @@
66

77
use App\Models\Product;
88
use Illuminate\Contracts\View\View;
9+
use Livewire\Attributes\Url;
910
use Livewire\Component;
1011

1112
final class SingleProduct extends Component
1213
{
13-
public ?Product $product = null;
14+
public Product $product;
1415

15-
public function mount(string $slug): void
16+
#[Url(except: '')]
17+
public string $variant = '';
18+
19+
public function mount(Product $product): void
1620
{
17-
$this->product = Product::with(['brand', 'media', 'attributes', 'relatedProducts'])
18-
->scopes('publish')
19-
->where('slug', $slug)
20-
->firstOrFail();
21+
abort_unless($product->isPublished(), 404);
22+
23+
$this->product = $product->load([
24+
'media',
25+
'relatedProducts',
26+
'variants',
27+
'variants.media',
28+
]);
2129
}
2230

2331
public function render(): View
2432
{
25-
return view('livewire.pages.single-product')
33+
return view('livewire.pages.single-product', [
34+
'selectedVariant' => Product::with('media')
35+
->where('slug', $this->variant)
36+
->select('name', 'slug', 'sku', 'id', 'price_amount', 'old_price_amount')
37+
->first(),
38+
])
2639
->title($this->product->name);
2740
}
2841
}

app/Livewire/Pages/Store.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ class Store extends Component
1414
{
1515
use WithPagination;
1616

17-
/** @var string[] */
17+
/**
18+
* @var string[]
19+
*/
1820
public array $selectedAttributes = [];
1921

2022
public function render(): View
2123
{
22-
$query = Product::with(['media', 'attributes'])->scopes('parent');
24+
$query = Product::with(['media', 'attributes'])
25+
->scopes(['parent', 'publish'])
26+
->latest();
2327

2428
if (count($this->selectedAttributes) > 0) {
2529
$query = $query->whereHas('attributes', function ($query) {

app/Livewire/VariantsSelector.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,28 @@ final class VariantsSelector extends Component
1414
{
1515
public Product $product;
1616

17+
public ?Product $selectedVariant = null;
18+
1719
public function addToCart(): void
1820
{
19-
$this->product->loadMissing('media');
20-
2121
// @phpstan-ignore-next-line
2222
CartFacade::session(session()->getId())->add([
23-
'id' => $this->product->id,
24-
'name' => $this->product->name,
25-
'price' => $this->product->price_amount,
23+
'id' => $this->selectedVariant ? $this->selectedVariant->id : $this->product->id,
24+
'name' => $this->selectedVariant
25+
? $this->product->name . ' / ' . $this->selectedVariant->name
26+
: $this->product->name,
27+
'price' => $this->selectedVariant && $this->selectedVariant->price_amount
28+
? $this->selectedVariant->price_amount
29+
: $this->product->price_amount,
2630
'quantity' => 1,
27-
'attributes' => [],
28-
'associatedModel' => $this->product,
31+
'associatedModel' => $this->selectedVariant?->load('parent') ?? $this->product,
2932
]);
3033

3134
$this->dispatch('cartUpdated');
3235

3336
Notification::make()
3437
->title(__('Cart updated'))
35-
->body(__('Product has been added to cart'))
38+
->body(__('Product / variant has been added to your cart'))
3639
->success()
3740
->send();
3841
}

app/Models/Product.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@
55
namespace App\Models;
66

77
use Illuminate\Database\Eloquent\Builder;
8+
use Illuminate\Database\Eloquent\Casts\Attribute;
89
use Shopper\Core\Models\Product as Model;
910

1011
final class Product extends Model
1112
{
12-
/**
13-
* Scope a query to only include product parent.
14-
*/
13+
public function isPublished(): bool
14+
{
15+
return $this->is_visible && $this->published_at && $this->published_at <= now();
16+
}
17+
18+
public function discountPercentage(): Attribute
19+
{
20+
return Attribute::make(
21+
get: fn () => $this->old_price_amount > 0
22+
? round((($this->old_price_amount - $this->price_amount) / $this->old_price_amount) * 100)
23+
: 0
24+
);
25+
}
26+
1527
public function scopeParent(Builder $query): void
1628
{
1729
$query->whereNull('parent_id');

app/Providers/LivewireStarterKitProvider.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace App\Providers;
66

77
use App\View\Composers\CategoriesNavigation;
8-
use App\View\Composers\CollectionsNavigation;
98
use Illuminate\Support\Facades\View;
109
use Illuminate\Support\ServiceProvider;
1110

@@ -24,6 +23,5 @@ public function boot(): void
2423
private function loadViewsComposer(): void
2524
{
2625
View::composer('components.layouts.header', CategoriesNavigation::class);
27-
View::composer('components.layouts.header', CollectionsNavigation::class);
2826
}
2927
}

app/View/Composers/CollectionsNavigation.php

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)