diff --git a/app/Support/Price.php b/app/Support/Price.php new file mode 100644 index 0000000..e47b956 --- /dev/null +++ b/app/Support/Price.php @@ -0,0 +1,29 @@ + "19", 19.50 -> "19,5", 19.55 -> "19,55"). + */ + public static function format(float|int|string|null $amount, string $currency = '€'): ?string + { + if ($amount === null) { + return null; + } + + $amount = round((float) $amount, 2); + $cents = (int) round($amount * 100); + + $decimals = match (true) { + $cents % 100 === 0 => 0, + $cents % 10 === 0 => 1, + default => 2, + }; + + return $currency.number_format($amount, $decimals, ',', '.'); + } +} diff --git a/resources/js/stimulus/product-form-controller.js b/resources/js/stimulus/product-form-controller.js index 083ab55..80b0159 100644 --- a/resources/js/stimulus/product-form-controller.js +++ b/resources/js/stimulus/product-form-controller.js @@ -1,4 +1,5 @@ import { Controller } from '@hotwired/stimulus' +import { formatPrice } from '../utils/format-price' export default class extends Controller { static targets = ['price', 'image', 'swatch', 'colorName'] @@ -30,7 +31,7 @@ export default class extends Controller { if (!variant) return if (this.hasPriceTarget && variant.price !== null) { - this.priceTarget.textContent = '€' + parseFloat(variant.price).toFixed(2) + this.priceTarget.textContent = formatPrice(variant.price) } if (this.hasImageTarget && variant.image) { diff --git a/resources/js/utils/format-price.js b/resources/js/utils/format-price.js new file mode 100644 index 0000000..8501d2a --- /dev/null +++ b/resources/js/utils/format-price.js @@ -0,0 +1,19 @@ +// Mirrors App\Support\Price::format() — keep both in sync. Greek formatting: +// comma as the decimal separator, dot as the thousands separator, and no +// decimals shown unless the amount actually needs them. +// 19.00 -> "€19", 19.50 -> "€19,5", 19.55 -> "€19,55" +export function formatPrice(amount, currency = '€') { + if (amount === null || amount === undefined) return null + + const value = Math.round(parseFloat(amount) * 100) / 100 + const cents = Math.round(value * 100) + + const decimals = cents % 100 === 0 ? 0 : (cents % 10 === 0 ? 1 : 2) + + const formatted = value.toLocaleString('el-GR', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + }) + + return currency + formatted +} diff --git a/resources/views/components/ui/price.blade.php b/resources/views/components/ui/price.blade.php new file mode 100644 index 0000000..f0b8514 --- /dev/null +++ b/resources/views/components/ui/price.blade.php @@ -0,0 +1,9 @@ +@props([ + 'amount' => null, + 'currency' => '€', +]) + +{{-- No wrapper element on purpose — drop this inside whatever tag/classes + the call site already uses (span, p, etc). Formatting logic lives in + App\Support\Price so it's identical everywhere it's used. --}} +{{ \App\Support\Price::format($amount, $currency) }} diff --git a/resources/views/components/ui/product-card.blade.php b/resources/views/components/ui/product-card.blade.php index b011b74..2d6cf26 100644 --- a/resources/views/components/ui/product-card.blade.php +++ b/resources/views/components/ui/product-card.blade.php @@ -28,7 +28,7 @@ class="w-full h-auto block"
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index a103596..d3fa813 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -33,7 +33,7 @@ class="font-display font-semibold text-6xl lg:text-7xl leading-tight" aria-label="Προηγούμενο προϊόν" class="absolute left-4 lg:left-8 top-1/2 -translate-y-1/2 hover:opacity-60 transition-opacity" > -Δεν βρέθηκαν προϊόντα.
diff --git a/resources/views/product/show.blade.php b/resources/views/product/show.blade.php index 1eec3e5..7509747 100644 --- a/resources/views/product/show.blade.php +++ b/resources/views/product/show.blade.php @@ -152,7 +152,7 @@ class="absolute bottom-6 right-8 text-white text-sm" @if($product->variants->first()?->prices->isNotEmpty())
- €{{ number_format($product->variants->first()->prices->first()->price->decimal, 2) }}
+
- €{{ number_format($product->variants->first()->prices->first()->price->decimal, 2) }}
+