Improve product teaser layout, add actual contents

This commit is contained in:
Björn Fromme
2021-09-01 17:58:43 +02:00
parent 3c65dfa64f
commit e65a3a45eb
4 changed files with 92 additions and 79 deletions
@@ -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'],
@@ -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">