Skip to content

Commit f0cac5c

Browse files
committed
feat: [SHO-54] update variants selector and fix failing test
1 parent ce1eef7 commit f0cac5c

27 files changed

+243
-279
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: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,36 @@
66

77
use App\Models\Product;
88
use Illuminate\Contracts\View\View;
9-
use Illuminate\Http\Request;
9+
use Livewire\Attributes\Url;
1010
use Livewire\Component;
1111

1212
final class SingleProduct extends Component
1313
{
14-
public ?Product $product = null;
14+
public Product $product;
1515

16-
public ?Product $currentVariant = null;
16+
#[Url(except: '')]
17+
public string $variant = '';
1718

18-
public function mount(string $slug, Request $request): void
19+
public function mount(Product $product): void
1920
{
20-
$search = $request->query('variant');
21-
if ($search) {
22-
$this->currentVariant = Product::with('media')
23-
->where('slug', $search)
24-
->firstOrFail();
25-
}
26-
27-
$this->product = Product::with(['brand', 'media', 'attributes', 'relatedProducts', 'variants.media'])
28-
->scopes('publish')
29-
->where('slug', $slug)
30-
->firstOrFail();
21+
abort_unless($product->isPublished(), 404);
22+
23+
$this->product = $product->load([
24+
'media',
25+
'relatedProducts',
26+
'variants',
27+
'variants.media',
28+
]);
3129
}
3230

3331
public function render(): View
3432
{
35-
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+
])
3639
->title($this->product->name);
3740
}
3841
}

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: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,34 @@
88
use Darryldecode\Cart\Facades\CartFacade;
99
use Filament\Notifications\Notification;
1010
use Illuminate\Contracts\View\View;
11-
use Illuminate\Http\Request;
1211
use Livewire\Component;
1312

1413
final class VariantsSelector extends Component
1514
{
1615
public Product $product;
1716

18-
public ?string $search = null;
19-
20-
public ?Product $currentVariant = null;
21-
22-
public function mount(Request $request): void
23-
{
24-
$this->search = $request->query('variant');
25-
}
17+
public ?Product $selectedVariant = null;
2618

2719
public function addToCart(): void
2820
{
29-
$this->product->loadMissing('media');
3021
// @phpstan-ignore-next-line
3122
CartFacade::session(session()->getId())->add([
32-
'id' => (! $this->currentVariant) ? $this->product->id : $this->currentVariant->id,
33-
'name' => (! $this->currentVariant) ? $this->product->name : $this->product->name . ' / ' . $this->currentVariant->name,
34-
'price' => (! $this->currentVariant) ? $this->product->price_amount : $this->currentVariant->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,
3530
'quantity' => 1,
36-
'attributes' => (! $this->currentVariant) ? $this->product->attributes : [],
37-
'associatedModel' => (! $this->currentVariant) ? $this->product : $this->currentVariant,
31+
'associatedModel' => $this->selectedVariant?->load('parent') ?? $this->product,
3832
]);
3933

4034
$this->dispatch('cartUpdated');
4135

4236
Notification::make()
4337
->title(__('Cart updated'))
44-
->body(__('Product has been added to cart'))
38+
->body(__('Product / variant has been added to your cart'))
4539
->success()
4640
->send();
4741
}

app/Models/Product.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@
1010

1111
final class Product extends Model
1212
{
13-
/**
14-
* Scope a query to only include product parent.
15-
*/
16-
public function scopeParent(Builder $query): void
13+
public function isPublished(): bool
1714
{
18-
$query->whereNull('parent_id');
15+
return $this->is_visible && $this->published_at && $this->published_at <= now();
1916
}
2017

2118
public function discountPercentage(): Attribute
@@ -26,4 +23,9 @@ public function discountPercentage(): Attribute
2623
: 0
2724
);
2825
}
26+
27+
public function scopeParent(Builder $query): void
28+
{
29+
$query->whereNull('parent_id');
30+
}
2931
}

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.

resources/views/components/cart/item.blade.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
@props(['item'])
1+
@props([
2+
'item',
3+
])
24

35
@php
46
$price = shopper_money_format(
@@ -8,28 +10,30 @@
810
@endphp
911

1012
<li class="flex py-6">
11-
<x-products.thumbnail :product="$item->associatedModel" class="size-32 border border-gray-200 aspect-none" />
13+
<x-products.thumbnail :product="$item->associatedModel" class="size-32 border border-gray-200 rounded-lg aspect-none" />
1214
<div class="flex flex-col flex-1 ml-4">
13-
<div>
14-
<div class="flex justify-between text-base">
15-
<h3 class="font-medium font-heading text-primary-900">
16-
<x-link :href="route('single-product', ['slug' => $item->associatedModel->slug])">
17-
{{ $item->name }}
18-
</x-link>
19-
</h3>
20-
<p class="ml-4 text-gray-700">
21-
{{ $price }}
22-
</p>
23-
</div>
15+
<div class="flex justify-between text-base">
16+
<h3 class="font-medium font-heading text-primary-900">
17+
<x-link :href="route('single-product', $item->associatedModel)">
18+
{{ $item->name }}
19+
</x-link>
20+
</h3>
21+
<p class="ml-4 text-gray-700">
22+
{{ $price }}
23+
</p>
2424
</div>
2525
<div class="flex items-end justify-between flex-1 text-sm">
2626
<p class="text-gray-500">
2727
{{ __('Quantity: :qty', ['qty' => $item->quantity]) }}
2828
</p>
2929

3030
<div class="flex">
31-
<button type="button" wire:click="removeToCart('{{ $item->id }}')" class="relative inline-flex items-center gap-2 font-medium text-gray-600 group hover:text-gray-900">
32-
<x-untitledui-trash-03 class="w-4 h-4 text-gray-400 group-hover:text-gray-500" />
31+
<button
32+
type="button"
33+
wire:click="removeToCart('{{ $item->id }}')"
34+
class="inline-flex items-center px-2 py-1.5 bg-red-50 rounded-md text-xs gap-2 font-medium text-red-700 hover:bg-red-100"
35+
>
36+
<x-untitledui-trash-03 class="size-4" aria-hidden="true" />
3337
{{ __('Remove') }}
3438
</button>
3539
</div>

resources/views/components/layouts/header.blade.php

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,10 @@
77
</x-link>
88
<div class="items-center lg:gap-x-4 ml-10 gap-x-6 hidden md:flex">
99
@foreach ($categories as $category)
10-
<x-nav.item link="{{ route('category.products', $category->slug) }}">{{ $category->name }}</x-nav.item>
10+
<x-nav.item :href="route('category.products', $category->slug)">
11+
{{ $category->name }}
12+
</x-nav.item>
1113
@endforeach
12-
13-
<div class="relative group">
14-
<x-link class="flex items-center text-sm font-medium text-gray-700 hover:text-gray-800">
15-
{{ __('Collections') }}
16-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 inline-block ml-1" viewBox="0 0 20 20" fill="currentColor">
17-
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 011.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
18-
</svg>
19-
</x-link>
20-
21-
<div class="absolute left-0 w-48 bg-white border rounded shadow-lg hidden group-hover:block z-50">
22-
@foreach ($collections as $collection)
23-
<x-link :href="route('collection.products', $collection->slug)" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900">
24-
{{ $collection->name }}
25-
</x-link>
26-
@endforeach
27-
</div>
28-
</div>
2914
</div>
3015
</nav>
3116
<div class="flex items-center ml-auto gap-x-6">

0 commit comments

Comments
 (0)