Improve product teaser layout, add actual contents
This commit is contained in:
@@ -194,7 +194,7 @@ class ProductDataService implements SingletonInterface
|
||||
'daytrip' => $teaserData['daytrip'],
|
||||
'hideBookingButton' => $teaserData['hideBookingButton'],
|
||||
'lowContingent' => $teaserData['lowContingent'],
|
||||
'servicesIncluded' => unserialize($teaserData['servicesIncluded']),
|
||||
'servicesIncluded' => unserialize($teaserData['servicesIncluded'], ['allowed_classes' => false]),
|
||||
'season' => $teaserData['season'],
|
||||
'product' => [
|
||||
'uid' => $teaserData['productUid'],
|
||||
|
||||
+16
-7
@@ -5,24 +5,33 @@ export default class extends Controller {
|
||||
static classes = [ 'grid' ]
|
||||
|
||||
static targets = [
|
||||
'icon',
|
||||
'button',
|
||||
'container',
|
||||
]
|
||||
|
||||
static values = { disabled: Boolean }
|
||||
|
||||
toggle(e) {
|
||||
grid(e) {
|
||||
e.preventDefault()
|
||||
this.disabledValue = !this.disabledValue
|
||||
this.disabledValue = false
|
||||
this.toggleButtonClass(e)
|
||||
}
|
||||
|
||||
block(e) {
|
||||
e.preventDefault()
|
||||
this.disabledValue = true
|
||||
this.toggleButtonClass(e)
|
||||
}
|
||||
|
||||
toggleButtonClass(e) {
|
||||
this.buttonTargets.forEach(element => {
|
||||
element.classList.toggle('opacity-50', element === e.currentTarget)
|
||||
})
|
||||
}
|
||||
|
||||
disabledValueChanged() {
|
||||
if (this.hasContainerTarget) {
|
||||
this.containerTarget.classList.toggle(this.gridClass, this.disabledValue === false)
|
||||
}
|
||||
if (this.hasIconTarget) {
|
||||
let icon = this.disabledValue ? '#icon-grid' : '#icon-block'
|
||||
this.iconTarget.setAttribute('href', icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:section name="Teaser">
|
||||
<div class="product-teaser">
|
||||
<div class="relative">
|
||||
<div class="absolute top-0 left-0 z-10 inset-x-0 flex justify-between items-center bg-ep-primary-80">
|
||||
<div class="w-2/3 flex items-center">
|
||||
<div class="bg-ep-primary p-2 mr-4 text-white">
|
||||
@@ -13,7 +13,7 @@
|
||||
</svg>
|
||||
</f:alias>
|
||||
</div>
|
||||
<span class="product-teaser__concept text-white uppercase font-semibold">
|
||||
<span class="text-sm md:text-base text-white uppercase font-semibold">
|
||||
{teaser.concept.name}
|
||||
</span>
|
||||
</div>
|
||||
@@ -31,77 +31,72 @@
|
||||
</div>
|
||||
<a href="{ep:uri.product(forceHotelUid: teaser.forceHotelUid, product: teaser.product, hotel: teaser.hotel, dateFrom: dateFrom, dateTo: dateTo, slug: slug)}"
|
||||
title="{teaser.region.name} {teaser.product.name} Details und Buchen"
|
||||
class="block sm:flex sm:flex-wrap bg-white">
|
||||
<div class="relative w-full">
|
||||
<img class="block w-full h-auto lazyload"
|
||||
src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/lazy.png')}"
|
||||
data-src="{f:uri.image(image: teaser.product.images.original.0, width: '640', height: '480c')}"
|
||||
width="640" height="480" />
|
||||
</div>
|
||||
class="flex flex-col h-full bg-white">
|
||||
<f:render section="TeaserImage" arguments="{_all}"/>
|
||||
<f:render section="TeaserContent" arguments="{_all}"/>
|
||||
</a>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
<f:section name="TeaserImage">
|
||||
<img class="block w-full h-auto lazyload"
|
||||
src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/lazy.png')}"
|
||||
data-src="{f:uri.image(image: teaser.product.images.original.0, width: '640', height: '480c')}"
|
||||
alt="{teaser.product.name}"
|
||||
width="640" height="480" />
|
||||
</f:section>
|
||||
|
||||
<f:section name="TeaserContent">
|
||||
<div class="product-teaser__content w-full">
|
||||
<div class="product-teaser__product text-gray-800 leading-none pb-1">
|
||||
<div class="flex-1 flex flex-col space-y-1 px-2 py-4 md:p-4">
|
||||
<div class="text-gray-800 leading-none pl-8 md:pl-10">
|
||||
{teaser.product.name}
|
||||
</div>
|
||||
<div class="flex items-baseline">
|
||||
<div class="w-8 md:w-10 pr-2">
|
||||
<svg class="w-6 h-4 md:w-8 md:h-6">
|
||||
<use href="#icon-flag-{teaser.country.code -> f:format.case(mode: 'lower')}"/>
|
||||
<div class="relative h-16 md:h-24 text-gray-800 text-lg md:text-3xl leading-none font-bold pl-8 md:pl-10">
|
||||
{teaser.region.name}
|
||||
<svg class="w-6 h-4 md:w-8 md:h-6 absolute top-0 left-0 md:mt-1">
|
||||
<use href="#icon-flag-{teaser.country.code -> f:format.case(mode: 'lower')}"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="pb-2 text-gray-800 text-lg md:text-xl font-bold leading-none pl-8 md:pl-10">
|
||||
{ep:nightsOptions(options: teaser.nights, daytrip: teaser.daytrip)} inkl.
|
||||
</div>
|
||||
<ul class="flex-1 list-none m-0 text-gray-800 divide-y divide-gray-400 pl-8 md:pl-10">
|
||||
<li class="flex items-center space-x-1 py-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="h-16 md:h-24 text-gray-800 text-lg md:text-3xl leading-none font-bold">
|
||||
{teaser.region.name}
|
||||
<span class="block flex-1 leading-none">
|
||||
{f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</span>
|
||||
</li>
|
||||
<f:if condition="{teaser.product.feature}">
|
||||
<li class="flex items-center space-x-1 py-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
<span class="block flex-1 leading-none">
|
||||
{teaser.product.feature}
|
||||
</span>
|
||||
</li>
|
||||
</f:if>
|
||||
<f:if condition="{teaser.board}">
|
||||
<li class="flex items-center space-x-1 py-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
<span class="block flex-1 leading-none">
|
||||
{teaser.board}
|
||||
</span>
|
||||
</li>
|
||||
</f:if>
|
||||
</ul>
|
||||
<div class="pt-8 pl-8 md:pl-10">
|
||||
<div class="bg-ep-primary text-white font-bold px-4 py-1">
|
||||
<div class="lg:inline-block">
|
||||
ab <span class="text-xl md:text-3xl mx-1">{teaser.minPrice} €</span>
|
||||
</div>
|
||||
<div class="pb-2 text-gray-800 text-lg md:text-xl font-bold">
|
||||
{ep:nightsOptions(options: teaser.nights, daytrip: teaser.daytrip)}
|
||||
</div>
|
||||
<ul class="list-none p-0 m-0 text-gray-800 divide-y divide-gray-400">
|
||||
<li class="flex items-center space-x-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
<span>
|
||||
{f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</span>
|
||||
</li>
|
||||
<li class="flex items-center space-x-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
<span>
|
||||
{f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</span>
|
||||
</li>
|
||||
<li class="flex items-center space-x-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
<span>
|
||||
{f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</span>
|
||||
</li>
|
||||
<li class="flex items-center space-x-1">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-check"></use>
|
||||
</svg>
|
||||
<span>
|
||||
{f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="bg-ep-primary text-white font-bold px-4 py-1 mt-8">
|
||||
<div class="lg:inline-block">
|
||||
ab <span class="text-xl md:text-3xl mx-1">{teaser.minPrice} €</span>
|
||||
</div>
|
||||
<div class="text-sm md:text-base lg:inline-block">
|
||||
p. P. / inkl. {f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</div>
|
||||
<div class="text-sm md:text-base lg:inline-block">
|
||||
p. P. / inkl. {f:if(condition: '{teaser.season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,15 +13,24 @@
|
||||
</f:if>
|
||||
<div class="container"
|
||||
data-controller="teasergrid"
|
||||
data-teasergrid-grid-class="grid-cols-2">
|
||||
data-teasergrid-grid-class="grid-cols-2"
|
||||
data-teasergrid-disabled-value="false">
|
||||
<f:if condition="{teasers}">
|
||||
<button class="inline-block sm:hidden mb-2"
|
||||
data-action="teasergrid#toggle">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-block"
|
||||
data-teasergrid-target="icon"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="flex items-center space-x-1 mb-2 sm:hidden">
|
||||
<button class="opacity-50"
|
||||
data-action="teasergrid#grid"
|
||||
data-teasergrid-target="button">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-grid"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<button data-action="teasergrid#block"
|
||||
data-teasergrid-target="button">
|
||||
<svg class="w-6 h-6 text-ep-primary">
|
||||
<use href="#icon-block"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 lg:grid-cols-3 gap-4 md:gap-8"
|
||||
data-teasergrid-target="container">
|
||||
<f:for each="{teasers}" as="teaser">
|
||||
|
||||
Reference in New Issue
Block a user