generated from boboko/starter
temp emails, reviews theming and form, minor change in checkout module, validation translations seeder
This commit is contained in:
@@ -200,10 +200,15 @@ .bbk-cart-item-media img {
|
||||
.bbk-cart-item-detail { min-width: 0; }
|
||||
|
||||
.bbk-cart-item-title {
|
||||
display: block;
|
||||
margin: 0 0 0.25rem;
|
||||
font-weight: 600;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.bbk-cart-item-title:hover { text-decoration: underline; }
|
||||
|
||||
.bbk-cart-item-variant {
|
||||
margin: 0 0 0.25rem;
|
||||
font-size: 0.8125rem;
|
||||
|
||||
@@ -15,6 +15,7 @@ import ProductFormController from './product-form-controller'
|
||||
import ProductGalleryController from './product-gallery-controller'
|
||||
import QuantityController from './quantity-controller'
|
||||
import RangeSliderController from './range-slider-controller'
|
||||
import ReviewCountController from './review-count-controller'
|
||||
import StarRatingController from './star-rating-controller'
|
||||
import TabsController from './tabs-controller'
|
||||
|
||||
@@ -31,6 +32,7 @@ export function registerControllers(application) {
|
||||
application.register('product-gallery', ProductGalleryController)
|
||||
application.register('quantity', QuantityController)
|
||||
application.register('range-slider', RangeSliderController)
|
||||
application.register('review-count', ReviewCountController)
|
||||
application.register('star-rating', StarRatingController)
|
||||
application.register('tabs', TabsController)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Controller } from '@hotwired/stimulus'
|
||||
|
||||
// The review count sits next to the star rating, outside the tabs markup —
|
||||
// too far apart in the DOM for a plain data-action, hence the outlet.
|
||||
export default class extends Controller {
|
||||
static outlets = ['tabs']
|
||||
|
||||
activate() {
|
||||
this.tabsOutlet.activate('reviews')
|
||||
this.tabsOutlet.element.scrollIntoView({ block: 'start', behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,25 @@
|
||||
import { Controller } from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['star', 'input']
|
||||
static targets = ['star', 'input', 'error']
|
||||
static values = { rating: { type: Number, default: 0 } }
|
||||
|
||||
connect() {
|
||||
this.#fill(this.ratingValue)
|
||||
}
|
||||
|
||||
// Bound to the form's submit event (this controller sits on the <form>
|
||||
// itself, not just the star widget) — a plain `required` on the hidden
|
||||
// rating input would never surface: browsers exclude type="hidden" from
|
||||
// constraint validation entirely, so there'd be nothing to see or hear.
|
||||
validate(event) {
|
||||
if (this.ratingValue < 1) {
|
||||
event.preventDefault()
|
||||
this.errorTarget.hidden = false
|
||||
this.starTargets[0]?.focus()
|
||||
}
|
||||
}
|
||||
|
||||
hover(event) {
|
||||
this.#fill(parseInt(event.currentTarget.dataset.value))
|
||||
}
|
||||
@@ -16,6 +32,7 @@ export default class extends Controller {
|
||||
const val = parseInt(event.currentTarget.dataset.value)
|
||||
this.ratingValue = val
|
||||
this.inputTarget.value = val
|
||||
this.errorTarget.hidden = true
|
||||
|
||||
this.starTargets.forEach(star => {
|
||||
star.setAttribute('aria-pressed', String(parseInt(star.dataset.value) === val))
|
||||
|
||||
@@ -4,10 +4,10 @@ export default class extends Controller {
|
||||
static targets = ['button', 'panel']
|
||||
|
||||
show(event) {
|
||||
this.#activate(event.currentTarget.dataset.panel)
|
||||
this.activate(event.currentTarget.dataset.panel)
|
||||
}
|
||||
|
||||
#activate(panelId) {
|
||||
activate(panelId) {
|
||||
this.buttonTargets.forEach(btn => {
|
||||
const active = btn.dataset.panel === panelId
|
||||
btn.classList.toggle('is-active', active)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.bbk-* classes from its own stylesheet. No host components, no Tailwind.
|
||||
--}}
|
||||
<div class="bbk-cart" data-controller="bbk-cart" hidden>
|
||||
<div class="bbk-cart-backdrop" data-action="bbk-cart#close"></div>
|
||||
<div class="bbk-cart-backdrop" data-action="click->bbk-cart#close"></div>
|
||||
|
||||
<aside
|
||||
class="bbk-cart-panel"
|
||||
|
||||
@@ -12,17 +12,34 @@
|
||||
// the shopper picked, not just the product in general.
|
||||
$thumb = $variant?->getThumbnailImage() ?: null;
|
||||
$variantLabel = $variant?->getOption();
|
||||
// Not routed through checkout::'s own locale-explicit convention — this
|
||||
// is a storefront route, so it follows the storefront's own (implicit
|
||||
// locale) call shape, same as App\Catalog\ProductCard. Carries the
|
||||
// variant id along so the product page can restore the same option the
|
||||
// shopper actually has in their cart, not just default to the first one
|
||||
// (see product-form-controller.js reading ?variant= on connect()).
|
||||
$productUrl = $product ? route('product.show', ['id' => $product->id, 'variant' => $variant?->id]) : null;
|
||||
@endphp
|
||||
|
||||
<li class="bbk-cart-item" data-bbk-line-id="{{ $line->id }}">
|
||||
<div class="bbk-cart-item-media">
|
||||
@if ($thumb)
|
||||
<img src="{{ $thumb }}" alt="{{ $name }}" width="72" height="72" loading="lazy">
|
||||
@if ($productUrl)
|
||||
<a href="{{ $productUrl }}" aria-hidden="true" tabindex="-1">
|
||||
<img src="{{ $thumb }}" alt="{{ $name }}" width="72" height="72" loading="lazy">
|
||||
</a>
|
||||
@else
|
||||
<img src="{{ $thumb }}" alt="{{ $name }}" width="72" height="72" loading="lazy">
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="bbk-cart-item-detail">
|
||||
<p class="bbk-cart-item-title">{{ $name }}</p>
|
||||
@if ($productUrl)
|
||||
<a href="{{ $productUrl }}" class="bbk-cart-item-title">{{ $name }}</a>
|
||||
@else
|
||||
<p class="bbk-cart-item-title">{{ $name }}</p>
|
||||
@endif
|
||||
@if ($variantLabel)
|
||||
<p class="bbk-cart-item-variant">{{ $variantLabel }}</p>
|
||||
@endif
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
@props(['review'])
|
||||
|
||||
<article class="flex flex-col gap-3 py-6 border-b border-black last:border-0">
|
||||
<article class="flex flex-col gap-3 py-6">
|
||||
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<x-reviews-stars :rating="$review['rating']" :size="18" />
|
||||
<span class="font-bold">
|
||||
{{ $review['name'] ?? 'Ανώνυμος' }}
|
||||
</span>
|
||||
</div>
|
||||
<time class="text-sm text-neutral-500 shrink-0">{{ $review['date'] }}</time>
|
||||
<x-reviews-stars :rating="$review['rating']" :size="23" />
|
||||
|
||||
<div class="flex items-end gap-4">
|
||||
<span class="text-2xl font-bold leading-none">
|
||||
{{ $review['name'] ?? 'Ανώνυμος' }}
|
||||
</span>
|
||||
<time class="text-sm text-neutral-500 shrink-0 leading-none pb-0.5">{{ $review['date'] }}</time>
|
||||
</div>
|
||||
|
||||
<p class="leading-relaxed">{{ $review['text'] }}</p>
|
||||
@@ -24,4 +23,16 @@ class="w-24 h-24 object-cover border border-black"
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (!empty($review['reply']))
|
||||
<div class="mt-2 pl-4 border-l-2 border-neutral-300 flex flex-col gap-1">
|
||||
<p class="text-sm font-bold">
|
||||
{{ __('storefront.review.reply') }}
|
||||
@if (!empty($review['replyDate']))
|
||||
<span class="font-normal text-neutral-500">— {{ $review['replyDate'] }}</span>
|
||||
@endif
|
||||
</p>
|
||||
<p class="leading-relaxed">{{ $review['reply'] }}</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</article>
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
@props(['product'])
|
||||
|
||||
@php $oldRating = (int) old('rating', 0); @endphp
|
||||
|
||||
<form
|
||||
method="POST"
|
||||
action="#"
|
||||
action="{{ route('product.reviews.store', ['locale' => app()->getLocale(), 'product' => $product['id']]) }}"
|
||||
class="flex flex-col gap-8 mt-10"
|
||||
data-controller="star-rating"
|
||||
data-star-rating-rating-value="{{ $oldRating }}"
|
||||
data-action="submit->star-rating#validate"
|
||||
>
|
||||
@csrf
|
||||
|
||||
{{-- Rating --}}
|
||||
<x-ui.field :label="__('storefront.review.rating')" for="rating" :required="true">
|
||||
<x-ui.field :label="__('storefront.review.rating')" for="rating" :required="true" :error="$errors->first('rating')">
|
||||
<div
|
||||
id="rating"
|
||||
data-controller="star-rating"
|
||||
class="flex items-center gap-1.5 text-brand"
|
||||
role="radiogroup"
|
||||
aria-label="{{ __('storefront.review.rating') }}"
|
||||
aria-required="true"
|
||||
aria-describedby="rating-client-error"
|
||||
>
|
||||
<input type="hidden" name="rating" value="0" data-star-rating-target="input">
|
||||
<input type="hidden" name="rating" value="{{ $oldRating }}" data-star-rating-target="input">
|
||||
@for($i = 1; $i <= 5; $i++)
|
||||
<button
|
||||
type="button"
|
||||
@@ -25,7 +30,7 @@ class="flex items-center gap-1.5 text-brand"
|
||||
data-value="{{ $i }}"
|
||||
data-action="click->star-rating#select mouseenter->star-rating#hover mouseleave->star-rating#leave"
|
||||
aria-label="{{ trans_choice('storefront.review.stars_count', $i, ['count' => $i]) }}"
|
||||
aria-pressed="false"
|
||||
aria-pressed="{{ $i === $oldRating ? 'true' : 'false' }}"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -41,24 +46,21 @@ class="w-6 h-6"
|
||||
</button>
|
||||
@endfor
|
||||
</div>
|
||||
<p id="rating-client-error" data-star-rating-target="error" class="text-sm text-red-600" role="alert" hidden>{{ __('storefront.review.rating_required') }}</p>
|
||||
</x-ui.field>
|
||||
|
||||
<x-ui.field :label="__('storefront.review.write_label')" for="review-content" :required="true">
|
||||
<x-ui.textarea id="review-content" name="content" :required="true" />
|
||||
<x-ui.field :label="__('storefront.review.write_label')" for="review-content" :required="true" :error="$errors->first('content')">
|
||||
<x-ui.textarea id="review-content" name="content" :required="true" :rows="6">{{ old('content') }}</x-ui.textarea>
|
||||
</x-ui.field>
|
||||
|
||||
<x-ui.field :label="__('storefront.review.name')" for="review-name" :labelDescription="__('storefront.review.name_optional')">
|
||||
<x-ui.input id="review-name" name="name" autocomplete="name" />
|
||||
<x-ui.field :label="__('storefront.review.name')" for="review-name" :labelDescription="__('storefront.review.name_optional')" :error="$errors->first('name')">
|
||||
<x-ui.input id="review-name" name="name" autocomplete="name" :value="old('name')" />
|
||||
</x-ui.field>
|
||||
|
||||
<x-ui.field :label="__('storefront.review.email')" for="review-email" :required="true" :labelDescription="__('storefront.review.email_not_published')">
|
||||
<x-ui.input id="review-email" name="email" type="email" :required="true" autocomplete="email" />
|
||||
<x-ui.field :label="__('storefront.review.email')" for="review-email" :required="true" :labelDescription="__('storefront.review.email_not_published')" :error="$errors->first('email')">
|
||||
<x-ui.input id="review-email" name="email" type="email" :required="true" autocomplete="email" :value="old('email')" />
|
||||
</x-ui.field>
|
||||
|
||||
<x-ui.checkbox id="review-save-info" name="save_info" >
|
||||
<span class="text-sm">{{ __('storefront.review.save_info') }}</span>
|
||||
</x-ui.checkbox>
|
||||
|
||||
<div>
|
||||
<x-ui.button type="submit">{{ __('storefront.review.submit') }}</x-ui.button>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
'count' => 0,
|
||||
'showCount' => false,
|
||||
'size' => 24,
|
||||
'linkable' => false,
|
||||
])
|
||||
|
||||
<div class="flex items-center gap-3" {{ $attributes }}>
|
||||
@@ -28,9 +29,17 @@ class="flex items-center gap-1.5 text-brand"
|
||||
</div>
|
||||
|
||||
@if ($showCount && $count > 0)
|
||||
<span class="text-sm text-neutral-500">
|
||||
({{ trans_choice('storefront.customer_reviews', $count, ['count' => $count]) }})
|
||||
</span>
|
||||
@php $countText = '(' . trans_choice('storefront.customer_reviews', $count, ['count' => $count]) . ')'; @endphp
|
||||
@if ($linkable)
|
||||
<button
|
||||
type="button"
|
||||
data-action="click->review-count#activate"
|
||||
class="text-sm text-neutral-500 hover:underline cursor-pointer"
|
||||
aria-controls="tab-panel-reviews"
|
||||
>{{ $countText }}</button>
|
||||
@else
|
||||
<span class="text-sm text-neutral-500">{{ $countText }}</span>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
@props(['tabs' => [], 'size' => 'md'])
|
||||
@props(['tabs' => [], 'size' => 'md', 'active' => null])
|
||||
@php
|
||||
$sizeClasses = match($size) {
|
||||
'lg' => 'text-[36px] font-extrabold [--slide-h:5px]',
|
||||
default => 'text-xl font-bold [--slide-h:3px]',
|
||||
};
|
||||
$activeId = $active ?? ($tabs[0]['id'] ?? null);
|
||||
@endphp
|
||||
|
||||
{{--
|
||||
@@ -21,22 +22,22 @@
|
||||
|
||||
<div data-controller="tabs" {{ $attributes }}>
|
||||
<div class="flex gap-10 mb-8" role="tablist">
|
||||
@foreach($tabs as $i => $tab)
|
||||
@foreach($tabs as $tab)
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
data-tabs-target="button"
|
||||
data-action="click->tabs#show"
|
||||
data-panel="{{ $tab['id'] }}"
|
||||
class="underline-slide font-display pb-1 {{ $sizeClasses }} {{ $i === 0 ? 'is-active' : '' }}"
|
||||
aria-selected="{{ $i === 0 ? 'true' : 'false' }}"
|
||||
class="underline-slide font-display pb-1 {{ $sizeClasses }} {{ $tab['id'] === $activeId ? 'is-active' : '' }}"
|
||||
aria-selected="{{ $tab['id'] === $activeId ? 'true' : 'false' }}"
|
||||
aria-controls="tab-panel-{{ $tab['id'] }}"
|
||||
id="tab-btn-{{ $tab['id'] }}"
|
||||
>{{ $tab['label'] }}</button>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@foreach($tabs as $i => $tab)
|
||||
@foreach($tabs as $tab)
|
||||
@php $panelKey = $tab['id']; $panel = $$panelKey ?? null; @endphp
|
||||
<div
|
||||
role="tabpanel"
|
||||
@@ -44,7 +45,7 @@ class="underline-slide font-display pb-1 {{ $sizeClasses }} {{ $i === 0 ? 'is-ac
|
||||
id="tab-panel-{{ $tab['id'] }}"
|
||||
aria-labelledby="tab-btn-{{ $tab['id'] }}"
|
||||
tabindex="0"
|
||||
@if($i !== 0) hidden @endif
|
||||
@if($tab['id'] !== $activeId) hidden @endif
|
||||
>{{ $panel }}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta name="format-detection" content="telephone=no, date=no, address=no, email=no, url=no">
|
||||
<meta name="color-scheme" content="light">
|
||||
<meta name="supported-color-schemes" content="light">
|
||||
<title>@yield('title', '3Dealer')</title>
|
||||
<!--[if mso]>
|
||||
<noscript>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
<o:AllowPNG/>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
</noscript>
|
||||
<style>
|
||||
table { border-collapse: collapse !important; }
|
||||
.email-container { width: 600px !important; }
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if !mso]><!-->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700;800&display=swap" rel="stylesheet" type="text/css">
|
||||
<!--<![endif]-->
|
||||
<style>
|
||||
body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
|
||||
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
|
||||
img { -ms-interpolation-mode: bicubic; border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; }
|
||||
body { height: 100% !important; margin: 0 !important; padding: 0 !important; width: 100% !important; background-color: #e5e5e5; }
|
||||
a[x-apple-data-detectors] {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
#MessageViewBody, #MessageWebViewDiv { width: 100% !important; }
|
||||
u + #email-body a { color: inherit; text-decoration: none; }
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
.email-container { width: 100% !important; max-width: 100% !important; }
|
||||
.email-header { padding: 24px 20px 12px !important; }
|
||||
.email-card { padding: 28px 20px !important; }
|
||||
.email-footer { padding: 0 20px 32px !important; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body id="email-body" style="margin:0;padding:0;background-color:#e5e5e5;">
|
||||
<div style="display:none;max-height:0;overflow:hidden;mso-hide:all;font-size:1px;line-height:1px;color:#e5e5e5;">
|
||||
@yield('preheader', '')
|
||||
‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌
|
||||
</div>
|
||||
|
||||
<center role="article" aria-roledescription="email" style="width:100%;background-color:#e5e5e5;">
|
||||
<!--[if mso]>
|
||||
<table role="presentation" width="600" align="center" cellpadding="0" cellspacing="0" bgcolor="#e5e5e5"><tr><td>
|
||||
<![endif]-->
|
||||
<table role="presentation" class="email-container" width="100%" cellpadding="0" cellspacing="0" bgcolor="#e5e5e5" style="max-width:600px;margin:0 auto;">
|
||||
<tr>
|
||||
<td class="email-header" align="center" style="padding:32px 24px 16px;">
|
||||
<a href="{{ url('/') }}" target="_blank" style="text-decoration:none;">
|
||||
<img src="{{ asset('images/logo.png') }}" width="140" height="123" alt="3Dealer" style="display:inline-block;border:0;outline:none;text-decoration:none;height:auto;max-width:140px;width:100%;">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 24px;">
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" bgcolor="#ffffff" style="background-color:#ffffff;border-radius:12px;">
|
||||
<tr>
|
||||
<td class="email-card" style="padding:40px 32px;font-family:'Manrope',Arial,Helvetica,sans-serif;font-size:16px;line-height:1.5;color:#000000;text-align:left;">
|
||||
@yield('content')
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="email-footer" align="center" style="padding:24px 24px 40px;font-family:'Manrope',Arial,Helvetica,sans-serif;font-size:13px;line-height:1.6;color:#7a7a7a;">
|
||||
@yield('footer')
|
||||
<p style="margin:12px 0 0;">
|
||||
<a href="{{ url('/') }}" style="color:#7a7a7a;text-decoration:underline;">3dealer.gr</a>
|
||||
· © {{ date('Y') }} 3Dealer
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if mso]>
|
||||
</td></tr></table>
|
||||
<![endif]-->
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -149,7 +149,14 @@ class="absolute bottom-6 right-8 text-white text-sm"
|
||||
{{ $product['name'] }}
|
||||
</h1>
|
||||
|
||||
<x-reviews-stars :rating="$product['reviews']['average_rating'] ?? 0" :count="$product['reviews']['count']" :showCount="true" />
|
||||
<x-reviews-stars
|
||||
:rating="$product['reviews']['average_rating'] ?? 0"
|
||||
:count="$product['reviews']['count']"
|
||||
:showCount="true"
|
||||
:linkable="true"
|
||||
data-controller="review-count"
|
||||
data-review-count-tabs-outlet="#product-tabs"
|
||||
/>
|
||||
|
||||
@if($product['price'] !== null)
|
||||
<p class="text-2xl font-bold" data-product-form-target="price">
|
||||
@@ -196,7 +203,7 @@ class="flex items-stretch gap-10"
|
||||
|
||||
</div>
|
||||
|
||||
<x-ui.tabs class="mt-16" size="lg" :tabs="[
|
||||
<x-ui.tabs id="product-tabs" class="mt-16 scroll-mt-28" size="lg" :active="request('tab')" :tabs="[
|
||||
['id' => 'description', 'label' => __('storefront.product.description')],
|
||||
['id' => 'reviews', 'label' => __('storefront.product.reviews') . ' (' . $product['reviews']['count'] . ')'],
|
||||
]">
|
||||
@@ -211,6 +218,10 @@ class="flex items-stretch gap-10"
|
||||
</ul>
|
||||
</x-slot>
|
||||
<x-slot name="reviews">
|
||||
@if(session('reviewSubmitted'))
|
||||
<p class="mb-8 text-sm font-semibold" role="status">{{ __('storefront.review.thank_you') }}</p>
|
||||
@endif
|
||||
|
||||
@if(!empty($product['reviews']['items']))
|
||||
<div class="mb-10">
|
||||
@foreach($product['reviews']['items'] as $review)
|
||||
@@ -220,6 +231,8 @@ class="flex items-stretch gap-10"
|
||||
'date' => $review['reviewed_at'] ? \Illuminate\Support\Carbon::createFromTimestamp($review['reviewed_at'])->translatedFormat('d M Y') : '',
|
||||
'text' => $review['body'],
|
||||
'image' => $review['media'][0]['url'] ?? null,
|
||||
'reply' => $review['reply'] ?? null,
|
||||
'replyDate' => $review['replied_at'] ? \Illuminate\Support\Carbon::createFromTimestamp($review['replied_at'])->translatedFormat('d M Y') : null,
|
||||
]" />
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
@extends('emails.layout')
|
||||
|
||||
@section('title', 'Ο κωδικός σύνδεσής σου')
|
||||
|
||||
@section('preheader', "Ο κωδικός σύνδεσής σου στο 3dealer: {$code}")
|
||||
|
||||
@section('content')
|
||||
<h1 style="margin:0 0 20px;font-family:'Manrope',Arial,Helvetica,sans-serif;font-size:22px;line-height:1.3;font-weight:700;color:#000000;">
|
||||
Ο κωδικός σύνδεσής σου
|
||||
</h1>
|
||||
|
||||
<p style="margin:0 0 16px;">Γεια σου {{ $name }},</p>
|
||||
|
||||
<p style="margin:0 0 24px;">Χρησιμοποίησε τον παρακάτω κωδικό για να συνδεθείς στο διαχειριστικό του 3dealer.</p>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:0 0 24px;">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#18c28a" style="background-color:#18c28a;border-radius:8px;padding:20px;">
|
||||
<span style="font-family:'Manrope',Arial,Helvetica,sans-serif;font-size:32px;font-weight:800;letter-spacing:8px;color:#ffffff;">{{ $code }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0 0 16px;color:#5c5c5c;font-size:14px;">Ο κωδικός ισχύει για περιορισμένο χρονικό διάστημα και μπορεί να χρησιμοποιηθεί μία μόνο φορά.</p>
|
||||
|
||||
<p style="margin:0;color:#5c5c5c;font-size:14px;">Αν δεν ζήτησες εσύ αυτόν τον κωδικό, αγνόησε αυτό το email — ο λογαριασμός σου παραμένει ασφαλής.</p>
|
||||
@endsection
|
||||
|
||||
@section('footer')
|
||||
<p style="margin:0;">Αυτό το email στάλθηκε επειδή ζητήθηκε σύνδεση στο διαχειριστικό του 3dealer.</p>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user