stock check, variants in cart, variant buttons in product page

This commit is contained in:
elvira
2026-09-17 21:52:39 +03:00
parent fe55cb5f33
commit afa1993c53
27 changed files with 564 additions and 155 deletions
+7 -1
View File
@@ -19,7 +19,7 @@ final class ProductCard
{
/**
* @param array<string, mixed> $product one item from ProductService's localized array shape
* @return array{name: ?string, price: ?string, image: ?string, href: string}
* @return array{name: ?string, price: ?string, image: ?string, href: string, variantId: ?int}
*/
public static function fromIndexed(array $product): array
{
@@ -28,6 +28,12 @@ public static function fromIndexed(array $product): array
'price' => $product['price'],
'image' => $product['media'][0]['url'] ?? null,
'href' => route('product.show', ['id' => $product['id']]),
// The card's quick "Add to cart" always adds this variant, same
// default Modules\Core\Catalog\Services\ProductService::
// variantSummaries() and product/show.blade.php both use — no
// picker at listing-grid scope, unlike the product page's own
// color swatches.
'variantId' => $product['variants'][0]['id'] ?? null,
];
}
}
+11 -3
View File
@@ -17,7 +17,14 @@
*/
final class ProductListingPage
{
private const PER_PAGE = 12;
private const PER_PAGE = 40;
/** Category pages rarely have enough products to fill a page, so this
* ceiling is high enough to act as "no pagination" in practice — the
* pagination component self-hides via hasPages() when everything fits.
* If a category ever exceeds it, pagination reappears as a safety net
* rather than silently truncating results. */
private const CATEGORY_PER_PAGE = 200;
public function __construct(
private readonly ProductService $products,
@@ -33,6 +40,7 @@ public function __construct(
public function build(ProductListing $listing, Closure $url, ?int $collectionId = null, ?string $query = null): array
{
$filters = $listing->filters($collectionId);
$perPage = $collectionId !== null ? self::CATEGORY_PER_PAGE : self::PER_PAGE;
// Listing reads from the Meilisearch index via ProductService/
// ProductSearchService, not Eloquent. Both return a
@@ -45,12 +53,12 @@ public function build(ProductListing $listing, Closure $url, ?int $collectionId
query: $query,
filters: $filters,
sort: $listing->sort,
perPage: self::PER_PAGE,
perPage: $perPage,
page: $listing->page,
)
: $this->products->list(
filters: $filters,
perPage: self::PER_PAGE,
perPage: $perPage,
page: $listing->page,
sort: $listing->sort,
);