Merge branch 'feature/tailwind-3' into feature/sass-remove

This commit is contained in:
Björn Fromme
2022-08-31 16:24:07 +02:00
26 changed files with 161 additions and 106 deletions
@@ -58,7 +58,7 @@ class CityController extends ActionController
/** /**
* @param City $city * @param City $city
*/ */
public function detailAction(City $city = null) public function detailAction(City $city = null): void
{ {
if (null === $city) { if (null === $city) {
$cityUid = $this->settings['cityUid']; $cityUid = $this->settings['cityUid'];
@@ -81,11 +81,14 @@ class CityController extends ActionController
]); ]);
} }
public function teasergroupAction() public function teasergroupAction(): void
{ {
$regionUid = $this->settings['regionUid']; $regionUid = (int)$this->settings['regionUid'];
$countryUid = (int)$this->settings['countryUid'];
$season = $this->settings['season']; $season = $this->settings['season'];
$cities = $this->cityRepository->getTeasersByRegionAndSeason($regionUid, $season); $citiesPid = (int)$this->settings['citiesStoragePid'];
$cities = $this->cityRepository->getTeasersByCountryOrRegionAndSeason($regionUid, $countryUid, $season, $citiesPid);
$data = $this->configurationManager->getContentObject()->data; $data = $this->configurationManager->getContentObject()->data;
$this->view->assign('data', $data); $this->view->assign('data', $data);
$this->view->assign('teasers', $cities); $this->view->assign('teasers', $cities);
@@ -161,12 +161,13 @@ class ProductController extends ActionController
$enabledDates = array_keys($availableContingents); $enabledDates = array_keys($availableContingents);
} }
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); $concept = $product->getConcept();
$isProductWithExcludedConcept = ($product->getConcept() !== null) && \in_array($product->getConcept()->getUid(), $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
$excludedConceptUids, false); $isProductWithExcludedConcept = ($concept !== null) && \in_array($concept->getUid(), $excludedConceptUids);
$noInfoConceptUids = GeneralUtility::trimExplode(',', $this->settings['noInfoConceptUids']); $noInfoConceptUids = GeneralUtility::trimExplode(',', $this->settings['noInfoConceptUids'], true);
$isProductWithNoInfoConcept = ($product->getConcept() !== null) && \in_array($product->getConcept()->getUid(), $isProductWithNoInfoConcept = ($concept !== null) && \in_array($concept->getUid(), $noInfoConceptUids);
$noInfoConceptUids, false); $groupInquiryFormConceptUids = GeneralUtility::trimExplode(',', $this->settings['groupInquiryFormConceptUids'], true);
$isProductWithGroupInquiryForm = ($concept !== null) && \in_array($concept->getUid(), $groupInquiryFormConceptUids);
// Assemble backlink // Assemble backlink
$backlinkUrl = GeneralUtility::_GET('ref'); $backlinkUrl = GeneralUtility::_GET('ref');
@@ -178,6 +179,7 @@ class ProductController extends ActionController
'enabledDates' => $enabledDates ?? [], 'enabledDates' => $enabledDates ?? [],
'isProductWithExcludedConcept' => $isProductWithExcludedConcept, 'isProductWithExcludedConcept' => $isProductWithExcludedConcept,
'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept, 'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept,
'isProductWithGroupInquiryForm' => $isProductWithGroupInquiryForm,
'currentPageUid' => $GLOBALS['TSFE']->id, 'currentPageUid' => $GLOBALS['TSFE']->id,
'dateFrom' => $dateFrom, 'dateFrom' => $dateFrom,
'dateTo' => $dateTo, 'dateTo' => $dateTo,
@@ -83,9 +83,10 @@ class RegionController extends ActionController
public function teasergroupAction() public function teasergroupAction()
{ {
$countryUid = $this->settings['countryUid']; $countryUid = (int)$this->settings['countryUid'];
$season = $this->settings['season']; $season = $this->settings['season'];
$regions = $this->regionRepository->getTeasersByCountryAndSeason($countryUid, $season); $regionsPid = (int)$this->settings['regionsStoragePid'];
$regions = $this->regionRepository->getTeasersByCountryAndSeason($countryUid, $season, $regionsPid);
$data = $this->configurationManager->getContentObject()->data; $data = $this->configurationManager->getContentObject()->data;
$this->view->assign('data', $data); $this->view->assign('data', $data);
$this->view->assign('teasers', $regions); $this->view->assign('teasers', $regions);
@@ -93,6 +93,11 @@ class AbstractDestination extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
*/ */
protected $description = ''; protected $description = '';
/**
* @var string
*/
protected $descriptionExtended = '';
/** /**
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
*/ */
@@ -322,6 +327,22 @@ class AbstractDestination extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
$this->description = $description; $this->description = $description;
} }
/**
* @return string
*/
public function getDescriptionExtended()
{
return $this->descriptionExtended;
}
/**
* @param string $descriptionExtended
*/
public function setDescriptionExtended($descriptionExtended)
{
$this->descriptionExtended = $descriptionExtended;
}
/** /**
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $images * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $images
*/ */
@@ -31,24 +31,25 @@ use EP\EpProducts\Domain\Model\AbstractDestination;
class CityRepository extends AbstractRepository class CityRepository extends AbstractRepository
{ {
public function getTeasersByCountryOrRegionAndSeason(int $regionUid = 0, int $countryUid = 0, string $season = 'w', int $storagePid = 0)
/**
* @param int $regionUid
* @param string $season
*
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
public function getTeasersByRegionAndSeason($regionUid, $season = 'w')
{ {
if ($season === null) { if ($season === null) {
$season = AbstractDestination::SEASON_WINTER; $season = AbstractDestination::SEASON_WINTER;
} }
$query = $this->createQuery(); $query = $this->createQuery();
$constraints = [ $constraints = [
$query->equals('region', $regionUid),
$query->equals('season', $season), $query->equals('season', $season),
$query->equals('excludeFromTeasergroups', 0) $query->equals('excludeFromTeasergroups', 0)
]; ];
if (0 < $regionUid) {
$constraints[] = $query->equals('region', $regionUid);
} elseif (0 < $countryUid) {
$constraints[] = $query->equals('country', $countryUid);
}
if (0 < $storagePid) {
$constraints[] = $query->equals('pid', $storagePid);
}
return $query return $query
->matching($query->logicalAnd($constraints)) ->matching($query->logicalAnd($constraints))
->execute() ->execute()
@@ -31,13 +31,7 @@ use EP\EpProducts\Domain\Model\AbstractDestination;
class RegionRepository extends AbstractRepository class RegionRepository extends AbstractRepository
{ {
public function getTeasersByCountryAndSeason(int $countryUid, string $season = 'w', int $storagePid = 0)
/**
* @param int $countryUid
* @param string $season
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
public function getTeasersByCountryAndSeason($countryUid, $season = 'w')
{ {
if ($season === null) { if ($season === null) {
$season = AbstractDestination::SEASON_WINTER; $season = AbstractDestination::SEASON_WINTER;
@@ -48,6 +42,11 @@ class RegionRepository extends AbstractRepository
$query->equals('season', $season), $query->equals('season', $season),
$query->equals('excludeFromTeasergroups', 0) $query->equals('excludeFromTeasergroups', 0)
]; ];
if (0 < $storagePid) {
$constraints[] = $query->equals('pid', $storagePid);
}
return $query return $query
->matching($query->logicalAnd($constraints)) ->matching($query->logicalAnd($constraints))
->execute() ->execute()
@@ -23,7 +23,9 @@ return [
], ],
'types' => [ 'types' => [
'1' => [ '1' => [
'showitem' => '--palette--;;top, name_internal, --palette--;;name, --palette--;;destinations, teaser, keywords, description, party, leisure, facts, officetip, --div--;Bilder/Dateien, teaser_images, header_images, images', 'showitem' => '--palette--;;top, name_internal, --palette--;;name, --palette--;;destinations, teaser,
keywords, description, description_extended, party, leisure, facts, officetip,
--div--;Bilder/Dateien, teaser_images, header_images, images',
], ],
], ],
'palettes' => [ 'palettes' => [
@@ -209,7 +211,18 @@ return [
], ],
'description' => [ 'description' => [
'exclude' => 0, 'exclude' => 0,
'label' => 'Der Ort', 'label' => 'Der Ort (oben)',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 15,
'eval' => 'trim',
'enableRichtext' => true,
],
],
'description_extended' => [
'exclude' => 0,
'label' => 'Der Ort (unten)',
'config' => [ 'config' => [
'type' => 'text', 'type' => 'text',
'cols' => 40, 'cols' => 40,
@@ -1,48 +1,60 @@
# customsubcategory=100=Storage
# customsubcategory=110=Pages
# customsubcategory=120=Search/Filtering
# customsubcategory=130=Email
# customsubcategory=140=Misc
plugin.tx_epproducts { plugin.tx_epproducts {
settings { settings {
# cat=plugin.tx_epproducts//a; type=string; label=Products storage PID # cat=epproducts/100/100; type=string; label=Products storage PID
productsStoragePid = productsStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Hotels storage PID # cat=epproducts/100/110; type=string; label=Hotels storage PID
hotelsStoragePid = hotelsStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Concepts storage PID # cat=epproducts/100/120; type=string; label=Concepts storage PID
conceptsStoragePid = conceptsStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Facts storage PID # cat=epproducts/100/130; type=string; label=Facts storage PID
factsStoragePid = factsStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Faqs storage PID # cat=epproducts/100/140; type=string; label=Faqs storage PID
faqsStoragePid = faqsStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Destinations storage PID # cat=epproducts/100/150; type=string; label=Destinations storage PID
destinationsStoragePid = destinationsStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Teammember storage PID # cat=epproducts/100/160; type=string; label=Regions storage PID
regionsStoragePid =
# cat=epproducts/100/160; type=string; label=Cities storage PID
citiesStoragePid =
# cat=epproducts/100/170; type=string; label=Teammember storage PID
teammemberStoragePid = teammemberStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Officetip storage PID # cat=epproducts/100/180; type=string; label=Officetip storage PID
officetipStoragePid = officetipStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Snow report storage PID # cat=epproducts/100/190; type=string; label=Snow report storage PID
snowReportStoragePid = snowReportStoragePid =
# cat=plugin.tx_epproducts//a; type=string; label=Default search page UID # cat=epproducts/110/100; type=string; label=Default search page UID
defaultSearchPageUid = defaultSearchPageUid =
# cat=plugin.tx_epproducts//a; type=string; label=Default product detail page UID # cat=epproducts/110/110; type=string; label=Default product detail page UID
defaultDetailPageUid = defaultDetailPageUid =
# cat=plugin.tx_epproducts//a; type=string; label=Exclude products with concept UIDs from search result (CSV) # cat=epproducts/110/120; type=string; label=Page UID with reseller export plugin
excludedConceptUids =
# cat=plugin.tx_epproducts//a; type=string; label=Exclude regions with these UIDs from filter options (CSV)
excludedRegionUids =
# cat=plugin.tx_epproducts//a; type=string; label=Force concept UID in all search related parts (CSV)
forcedConceptUids =
# cat=plugin.tx_epproducts//a; type=string; label=Don't show availability info for products with these concept UIDs
noInfoConceptUids =
# cat=plugin.tx_epproducts//a; type=string; label=Room types for pricetables (CSV)
priceTableRoomTypes = 1,2,3,4,5,6,7,8,9,10
# cat=plugin.tx_epproducts//a; type=string; label=Ignore following IPs in searchlog
searchLogIgnoreIps =
# cat=plugin.tx_epproducts//a; type=string; label=Page UID with reseller export plugin
resellerExportPageUid = resellerExportPageUid =
# cat=plugin.tx_epproducts//a; type=string; label=Email recipient for groups price inquiries # cat=epproducts/120/100; type=string; label=Exclude products with concept UIDs from search result (CSV)
excludedConceptUids =
# cat=epproducts/120/110; type=string; label=Exclude regions with these UIDs from filter options (CSV)
excludedRegionUids =
# cat=epproducts/120/120; type=string; label=Force concept UID in all search related parts (CSV)
forcedConceptUids =
# cat=epproducts/120/130; type=string; label=Don't show availability info for products with these concept UIDs
noInfoConceptUids =
# cat=epproducts/130/110; type=string; label=Email recipient for groups price inquiries
groupsPriceToEmail = [email protected] groupsPriceToEmail = [email protected]
# cat=plugin.tx_epproducts//a; type=string; label=Email recipient for groups price inquiries # cat=epproducts/130/120; type=string; label=Email recipient for groups price inquiries
groupsPriceToName = EP Reisen groupsPriceToName = EP Reisen
# cat=epproducts/140/100; type=string; label=Room types for pricetables (CSV)
priceTableRoomTypes = 1,2,3,4,5,6,7,8,9,10
# cat=epproducts/140/110; type=string; label=Ignore following IPs in searchlog
searchLogIgnoreIps =
# cat=epproducts/140/120; type=string; label=Concept UIDs to trigger inquiry form on product detail page (CSV)
groupInquiryFormConceptUids =
} }
persistence { persistence {
# cat=plugin.tx_epproducts//a; type=string; label=Default storage PID # cat=epproducts/100/100; type=string; label=Default storage PID
storagePid = storagePid =
} }
} }
@@ -26,6 +26,8 @@ plugin.tx_epproducts {
settings { settings {
productsPid = {$plugin.tx_epproducts.settings.productsStoragePid} productsPid = {$plugin.tx_epproducts.settings.productsStoragePid}
destinationsStoragePid = {$plugin.tx_epproducts.settings.destinationsStoragePid} destinationsStoragePid = {$plugin.tx_epproducts.settings.destinationsStoragePid}
regionsStoragePid = {$plugin.tx_epproducts.settings.regionsStoragePid}
citiesStoragePid = {$plugin.tx_epproducts.settings.citiesStoragePid}
snowReportStoragePid = {$plugin.tx_epproducts.settings.snowReportStoragePid} snowReportStoragePid = {$plugin.tx_epproducts.settings.snowReportStoragePid}
defaultSearchPageUid = {$plugin.tx_epproducts.settings.defaultSearchPageUid} defaultSearchPageUid = {$plugin.tx_epproducts.settings.defaultSearchPageUid}
defaultDetailPageUid = {$plugin.tx_epproducts.settings.defaultDetailPageUid} defaultDetailPageUid = {$plugin.tx_epproducts.settings.defaultDetailPageUid}
@@ -47,6 +49,7 @@ plugin.tx_epproducts {
groupsPricePopupPageUid = {$plugin.tx_eptheme.settings.groupsPricePopupPageUid} groupsPricePopupPageUid = {$plugin.tx_eptheme.settings.groupsPricePopupPageUid}
groupsPriceToEmail = {$plugin.tx_epproducts.settings.groupsPriceToEmail} groupsPriceToEmail = {$plugin.tx_epproducts.settings.groupsPriceToEmail}
groupsPriceToName = {$plugin.tx_epproducts.settings.groupsPriceToName} groupsPriceToName = {$plugin.tx_epproducts.settings.groupsPriceToName}
groupInquiryFormConceptUids = {$plugin.tx_epproducts.settings.groupInquiryFormConceptUids}
logoImage = {$plugin.tx_eptheme.settings.logoImage} logoImage = {$plugin.tx_eptheme.settings.logoImage}
themekey = {$plugin.tx_eptheme.settings.themekey} themekey = {$plugin.tx_eptheme.settings.themekey}
datePickerPresets { datePickerPresets {
@@ -714,6 +714,7 @@ CREATE TABLE tx_epproducts_domain_model_city
header_subtitle varchar(255) DEFAULT '' NOT NULL, header_subtitle varchar(255) DEFAULT '' NOT NULL,
keywords text NOT NULL, keywords text NOT NULL,
description text NOT NULL, description text NOT NULL,
description_extended text NOT NULL,
party text NOT NULL, party text NOT NULL,
leisure text NOT NULL, leisure text NOT NULL,
teaser_images int(11) unsigned NOT NULL default '0', teaser_images int(11) unsigned NOT NULL default '0',
@@ -36,15 +36,9 @@ export default class extends Controller {
for (let item of this.markersValue) { for (let item of this.markersValue) {
const position = L.latLng(item.lat, item.lng) const position = L.latLng(item.lat, item.lng)
const marker = L.marker(position) const marker = L.marker(position)
if (item.externalLink) { const popupContent = '<div data-rte-content=""><strong>' + item.name + '</strong><br>' + item.teaser +
marker.on('click', () => { '<br><a href="' + item.uri + '">zu den Details</a></div>'
window.open(item.externalLink, '_blank') marker.bindPopup(popupContent)
})
} else {
const popupContent = '<div data-rte-content=""><strong>' + item.name + '</strong><br>' + item.teaser +
'<br><a href="' + item.uri + '">zu den Details</a></div>'
marker.bindPopup(popupContent)
}
marker.addTo(this.map) marker.addTo(this.map)
bounds.extend(position) bounds.extend(position)
} }
@@ -470,7 +470,7 @@
} }
}, },
computed: { computed: {
...mapState(['config', 'loading']), ...mapState(['config', 'loading', 'countries']),
...mapGetters(['isGroupManager']), ...mapGetters(['isGroupManager']),
availableContingents () { availableContingents () {
let filteredContingents = {}; let filteredContingents = {};
@@ -6,9 +6,7 @@
<span> <span>
Zimmer Zimmer
</span> </span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }"> <svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
<use href="#icon-chevron-down"></use>
</svg>
</button> </button>
<ul class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs divide-y" v-show="visible"> <ul class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs divide-y" v-show="visible">
<li v-for="accommodation in selectableAccommodations" :key="accommodation.id" class="py-1"> <li v-for="accommodation in selectableAccommodations" :key="accommodation.id" class="py-1">
@@ -5,9 +5,7 @@
<a role="button" href="#" class="flex items-center justify-between" <a role="button" href="#" class="flex items-center justify-between"
@click.prevent="expanded = !expanded"> @click.prevent="expanded = !expanded">
<span>{{ title }}</span> <span>{{ title }}</span>
<svg class="w-6 h-6 transform" :class="{ 'rotate-180': expanded }"> <svg class="w-6 h-6" fill="none" :class="{ 'rotate-180': expanded }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
<use href="#icon-chevron-down"></use>
</svg>
</a> </a>
</h3> </h3>
</div> </div>
@@ -6,9 +6,7 @@
<span> <span>
Telefon Telefon
</span> </span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }"> <svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
<use href="#icon-chevron-down"></use>
</svg>
</button> </button>
<div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible"> <div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible">
<input class="border-zinc-400 focus:border-zinc-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Mobil" <input class="border-zinc-400 focus:border-zinc-800 ring-0 focus:ring-0 mt-1 w-full" type="text" placeholder="Mobil"
@@ -4,9 +4,7 @@
<span> <span>
Größen Größen
</span> </span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }"> <svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
<use href="#icon-chevron-down"></use>
</svg>
</button> </button>
<div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible"> <div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible">
<input class="form-input w-full" type="text" placeholder="Körpergröße" <input class="form-input w-full" type="text" placeholder="Körpergröße"
@@ -4,9 +4,7 @@
<span> <span>
Zustieg Zustieg
</span> </span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }"> <svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
<use href="#icon-chevron-down"></use>
</svg>
</button> </button>
<div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible"> <div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible">
<div class="py-1" v-for="pickup in pickups" :key="pickup.id"> <div class="py-1" v-for="pickup in pickups" :key="pickup.id">
@@ -4,11 +4,14 @@
<span> <span>
{{ subType.label }} {{ subType.label }}
</span> </span>
<svg class="w-4 h-4 transform" :class="{ 'rotate-180': visible }"> <svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
<use href="#icon-chevron-down"></use>
</svg>
</button> </button>
<div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible"> <div class="absolute top-100 left-0 z-50 mt-1 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible">
<div class="text-right">
<button type="button" @click="visible = false">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
</button>
</div>
<div class="py-1" v-for="service in availableServices" :key="service.id"> <div class="py-1" v-for="service in availableServices" :key="service.id">
<label class="inline-flex items-center text-sm"> <label class="inline-flex items-center text-sm">
<input type="checkbox" <input type="checkbox"
@@ -8,7 +8,7 @@
<h2 class="text-base font-bold mb-1"> <h2 class="text-base font-bold mb-1">
<f:if condition="{title}"> <f:if condition="{title}">
<f:then> <f:then>
Skiurlaub {title} Facts {title}
</f:then> </f:then>
<f:else> <f:else>
Facts Facts
@@ -15,12 +15,14 @@
</f:else> </f:else>
</f:if> </f:if>
{hotel.description -> f:format.html()} {hotel.description -> f:format.html()}
<f:if condition="{hotel.groupsPriceConfigs}"> <f:if condition="{showInquiryForm}">
<f:else> <f:if condition="{hotel.groupsPriceConfigs}">
<f:link.typolink class="button bg-button" parameter="{settings.groupsContactFormPageUid}" additionalParams="&ref={currentPageUid}"> <f:else>
<f:translate key="tx_eptheme.label.to_inquiry_form" extensionName="ep_theme"/> <f:link.typolink class="button bg-button" parameter="{settings.groupsContactFormPageUid}" additionalParams="&ref={currentPageUid}">
</f:link.typolink> <f:translate key="tx_eptheme.label.to_inquiry_form" extensionName="ep_theme"/>
</f:else> </f:link.typolink>
</f:else>
</f:if>
</f:if> </f:if>
</div> </div>
<f:if condition="{teasers}"> <f:if condition="{teasers}">
@@ -37,7 +37,7 @@
{hotel.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()} {hotel.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
<f:if condition="{hotel.available} != -1"> <f:if condition="{hotel.available} != -1">
<span class="teaserbox__price"> <span class="teaserbox__price">
<strong>{f:if(condition: '{hotel.available} > 0', then: 'ab {hotel.minPrice} €', else: 'bald buchbar')}</strong> <strong>{f:if(condition: '{hotel.available} > 0', then: 'ab {hotel.minPrice} €', else: 'aktuell nicht buchbar')}</strong>
</span> </span>
</f:if> </f:if>
</div> </div>
@@ -52,6 +52,12 @@
<svg class="product-teaser__watchlist-icon" data-watchlist-toggle-target="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path></svg> <svg class="product-teaser__watchlist-icon" data-watchlist-toggle-target="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path></svg>
</button> </button>
</div> </div>
<f:if condition="{concept.code} == 'evt'">
<div class="absolute bottom-0 left-0 inset-x-0 flex justify-between text-white {f:if(condition: landscape, else: 'text-sm')} bg-concept-evt/70 px-2 py-1">
<span>{hotel.name}</span>
<span class="uppercase">{hotel.category}</span>
</div>
</f:if>
</div> </div>
</f:section> </f:section>
@@ -71,24 +77,18 @@
<ul class="product-teaser__list-included flex-1 list-none m-0 text-zinc-800 divide-y divide-zinc-400"> <ul class="product-teaser__list-included flex-1 list-none m-0 text-zinc-800 divide-y divide-zinc-400">
<li class="flex items-center space-x-1 py-1"> <li class="flex items-center space-x-1 py-1">
{ep:icon(class: 'w-6 h-6 text-ep-primary-light', icon: 'check')} {ep:icon(class: 'w-6 h-6 text-ep-primary-light', icon: 'check')}
<span class="block flex-1 leading-none"> <span class="block flex-1 leading-none">{f:if(condition: '{season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}</span>
{f:if(condition: '{season} == "s"', then: 'Bergbahnticket', else: 'Skipass')}
</span>
</li> </li>
<f:if condition="{product.feature}"> <f:if condition="{product.feature}">
<li class="flex items-center space-x-1 py-1"> <li class="flex items-center space-x-1 py-1">
{ep:icon(class: 'w-6 h-6 text-ep-primary-light', icon: 'check')} {ep:icon(class: 'w-6 h-6 text-ep-primary-light', icon: 'check')}
<span class="block flex-1 leading-tight"> <span class="block flex-1 leading-tight">{product.feature}</span>
{product.feature}
</span>
</li> </li>
</f:if> </f:if>
<f:if condition="{board}"> <f:if condition="{board}">
<li class="flex items-center space-x-1 py-1"> <li class="flex items-center space-x-1 py-1">
{ep:icon(class: 'w-6 h-6 text-ep-primary-light', icon: 'check')} {ep:icon(class: 'w-6 h-6 text-ep-primary-light', icon: 'check')}
<span class="block flex-1 leading-tight"> <span class="block flex-1 leading-tight">Verpflegung</span>
{board}
</span>
</li> </li>
</f:if> </f:if>
</ul> </ul>
@@ -75,7 +75,7 @@
</div> </div>
<f:if condition="{settings.hideMoreLink}"> <f:if condition="{settings.hideMoreLink}">
<f:else> <f:else>
<f:link.typolink class="button bg-button" <f:link.typolink class="button bg-button ml-4"
parameter="{settings.defaultSearchPageUid}" parameter="{settings.defaultSearchPageUid}"
additionalParams="f={filterSettings -> ep:filterSettingsEncoder()}" additionalParams="f={filterSettings -> ep:filterSettingsEncoder()}"
additionalAttributes="{rel: 'nofollow'}"> additionalAttributes="{rel: 'nofollow'}">
@@ -84,6 +84,11 @@
</f:else> </f:else>
</f:if> </f:if>
</f:if> </f:if>
<f:if condition="{city.descriptionExtended}">
<div class="p-4 mt-4" data-rte-content>
{city.descriptionExtended -> f:format.html()}
</div>
</f:if>
</div> </div>
<div class="col-span-3 lg:col-span-1"> <div class="col-span-3 lg:col-span-1">
<f:if condition="{teasers}"> <f:if condition="{teasers}">
@@ -170,10 +170,11 @@
</f:section> </f:section>
<f:section name="Hotel"> <f:section name="Hotel">
<div class="mb-4{f:if(condition: settings.hotelOnTop, else: ' hidden')}" <div class="mb-4{f:if(condition: settings.hotelOnTop, else: ' hidden')}"
data-tabs-target="tab" data-tabs-target="tab"
data-tab="hotel"> data-tab="hotel">
<f:render partial="Hotel/Details" arguments="{hotel: hotel, bars: 1, showNonBookableHint: 0, currentPageUid: currentPageUid}"/> <f:render partial="Hotel/Details" arguments="{hotel: hotel, bars: 1, showNonBookableHint: 0, currentPageUid: currentPageUid, showInquiryForm: isProductWithGroupInquiryForm}"/>
</div> </div>
</f:section> </f:section>
@@ -32,7 +32,7 @@
<f:if condition="{teasers}"> <f:if condition="{teasers}">
<p class="hidden lg:block"> <p class="hidden lg:block">
<button type="button" <button type="button"
class="button bg-button w-full mb-8" class="button bg-button w-full mb-8 ml-4"
data-controller="scroll-to" data-controller="scroll-to"
data-scroll-to-target-value="teasers" data-scroll-to-target-value="teasers"
data-action="scroll-to#scroll"> data-action="scroll-to#scroll">
+4
View File
@@ -101,6 +101,10 @@ module.exports = {
'primary-light': '#04A4CC', 'primary-light': '#04A4CC',
}, },
}, },
opacity: {
'55': 0.5,
'85': 0.85,
},
backgroundImage: { backgroundImage: {
'badge-gradient': 'linear-gradient(120deg, rgba(150,1,103,1) 0%, rgba(158,3,106,1) 40%, rgba(250,26,140,1) 100%)', 'badge-gradient': 'linear-gradient(120deg, rgba(150,1,103,1) 0%, rgba(158,3,106,1) 40%, rgba(250,26,140,1) 100%)',
'brand-gradient': 'linear-gradient(to top right, #009fff, #165883, #18527b)', 'brand-gradient': 'linear-gradient(to top right, #009fff, #165883, #18527b)',