diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index cb32f9d..011bf62 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -109,6 +109,9 @@ private function buildOptionPicker(int $productId): array 'id' => $variant->id, 'price' => $variant->prices->first()?->price?->decimal(), 'image' => $variant->images->first()?->getUrl(), + // Live from the DB (not the index's in_stock), with Lunar's own + // purchasability rule — drives the disabled add-to-cart button. + 'inStock' => $variant->canBeFulfilledAtQuantity(1), // handle => selected value id, for matching a combination of // selections back to this variant — see selectVariant() in // product-form-controller.js. diff --git a/resources/css/app.css b/resources/css/app.css index d76c503..29633d1 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -331,7 +331,7 @@ @layer components { transition: transform 0.35s cubic-bezier(0.2, 0.78, 0.12, 0.86); } - .btn-primary:hover::after { + .btn-primary:not(:disabled):hover::after { transform: translate(0, 0); } diff --git a/resources/js/stimulus/product-form-controller.js b/resources/js/stimulus/product-form-controller.js index ca090fd..d8e6194 100644 --- a/resources/js/stimulus/product-form-controller.js +++ b/resources/js/stimulus/product-form-controller.js @@ -2,7 +2,7 @@ import { Controller } from '@hotwired/stimulus' import { formatPrice } from '../utils/format-price' export default class extends Controller { - static targets = ['price', 'image', 'swatch', 'colorName', 'stockError'] + static targets = ['price', 'image', 'swatch', 'colorName', 'stockError', 'submit'] static values = { variants: Array, selected: Number, @@ -90,7 +90,7 @@ export default class extends Controller { // own server-side check have the final word rather than // silently blocking the shopper here. } finally { - if (submit) submit.disabled = false + if (submit) submit.disabled = !this.selectedVariant?.inStock } form.dataset.bbkStockChecked = 'true' @@ -111,6 +111,10 @@ export default class extends Controller { this.stockErrorTarget.hidden = true } + get selectedVariant() { + return this.variantsValue.find(v => v.id === this.selectedValue) + } + selectVariant(event) { const option = event.currentTarget.dataset.option const valueId = parseInt(event.currentTarget.dataset.valueId) @@ -156,6 +160,9 @@ export default class extends Controller { const purchasableInput = this.element.querySelector('[data-bbk-purchasable-input]') if (purchasableInput) purchasableInput.value = id + // Out-of-stock variant (as of page load) can't be added at all. + if (this.hasSubmitTarget) this.submitTarget.disabled = !variant.inStock + this.swatchTargets.forEach(swatch => { const isSelected = this.selections[swatch.dataset.option] === parseInt(swatch.dataset.valueId) swatch.classList.toggle('is-selected', isSelected) diff --git a/resources/views/components/newsletter-split.blade.php b/resources/views/components/newsletter-split.blade.php index 34602c7..80fadb8 100644 --- a/resources/views/components/newsletter-split.blade.php +++ b/resources/views/components/newsletter-split.blade.php @@ -3,10 +3,10 @@ ])
-
-
+
+

-

+

Γίνε μέλος της λίστας μας και κέρδισε 5% έκπτωση στην πρώτη σου παραγγελία, μαζί με αποκλειστικές προσφορές και νέα.

-
+ @csrf -
+
- Επιθυμώ διακαώς 🔥 να εγγραφώ στη λίστα αποστολής ενημερωτικού υλικού + Επιθυμώ διακαώς 🔥 να εγγραφώ στη λίστα αποστολής ενημερωτικού υλικού
diff --git a/resources/views/components/ui/button.blade.php b/resources/views/components/ui/button.blade.php index 027da68..ceded73 100644 --- a/resources/views/components/ui/button.blade.php +++ b/resources/views/components/ui/button.blade.php @@ -33,7 +33,7 @@ // "absolute" via the class prop — Tailwind's generated stylesheet always // orders the "relative" utility after "absolute", so on a class clash // "relative" silently wins and the button never actually gets positioned. - $class = trim($position.' isolate inline-flex items-center justify-center border border-black text-black cursor-pointer no-underline '.$variantClasses.' '.$sizeClasses); + $class = trim($position.' isolate inline-flex items-center justify-center border border-black text-black cursor-pointer no-underline disabled:cursor-not-allowed disabled:opacity-50 '.$variantClasses.' '.$sizeClasses); $attrs = $href ? $attributes->merge(['href' => $href, 'class' => $class]) diff --git a/resources/views/emails/partials/button.blade.php b/resources/views/emails/partials/button.blade.php index e583e8a..7193a7b 100644 --- a/resources/views/emails/partials/button.blade.php +++ b/resources/views/emails/partials/button.blade.php @@ -1,13 +1,43 @@ {{-- @include('emails.partials.button', ['url' => ..., 'label' => ...]) - Bulletproof button: the padding sits on the link (whole area clickable) - with mso-padding-alt on the cell so Outlook keeps the same size. + The site's primary button (x-ui.button, .btn-primary): neutral-200 fill, + black border, bold italic uppercase, black offset shadow. The shadow is + built from table cells, not box-shadow (Gmail and Outlook drop it): a + black column on the right starting $offset down, and a black row at the + bottom starting $offset in. The button cell spans the first two rows, so + the black column always matches its height. + + Uppercased here with the tonos removed, since emails can't run the site's + strip-accents script and CSS uppercase would keep the accents. --}} - +@php + $offset = 8; + $label = strtr(mb_strtoupper($label), [ + 'Ά' => 'Α', 'Έ' => 'Ε', 'Ή' => 'Η', 'Ί' => 'Ι', 'Ό' => 'Ο', 'Ύ' => 'Υ', 'Ώ' => 'Ω', + 'ΐ' => 'Ϊ', 'ΰ' => 'Ϋ', + ]); + $spacer = "font-size:1px;line-height:1px;mso-line-height-rule:exactly;"; +@endphp + +
- + + + + + + + +
- {{ $label }} + + {{ $label }}  
 
+ + + + +
 
+
 
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index cd5737b..26008e0 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -195,7 +195,5 @@ class="max-w-xs"

-
- -
+ @endsection diff --git a/resources/views/product/show.blade.php b/resources/views/product/show.blade.php index 92a57ca..f6d9cf9 100644 --- a/resources/views/product/show.blade.php +++ b/resources/views/product/show.blade.php @@ -196,8 +196,13 @@ class="underline-slide font-semibold whitespace-nowrap" @endif @endforeach + @php + // Same initial pick as product-form-controller.js's connect() + // (?variant= or the first), so the button doesn't flip on load. + $initialVariant = collect($variantsData)->firstWhere('id', (int) request('variant')) ?? ($variantsData[0] ?? null); + @endphp @@ -207,7 +212,7 @@ class="flex flex-col gap-6"
- {{ __('storefront.product.add_to_cart') }} + {{ __('storefront.product.add_to_cart') }}