diff --git a/public/typo3conf/ext/ep_events/Classes/Controller/AjaxOfferController.php b/public/typo3conf/ext/ep_events/Classes/Controller/AjaxOfferController.php new file mode 100644 index 00000000..de2e99a2 --- /dev/null +++ b/public/typo3conf/ext/ep_events/Classes/Controller/AjaxOfferController.php @@ -0,0 +1,139 @@ +offerRepository = $offerRepository; + $this->fileRepository = $fileRepository; + $this->imageService = $imageService; + } + + public function initializeListAction() + { + if (!$this->request->hasArgument('filterSettings')) { + $filterSettings = new FilterSettings(); + $this->request->setArgument('filterSettings', $filterSettings); + } else { + $propertyMappingConfiguration = $this->arguments['filterSettings']->getPropertyMappingConfiguration(); + $propertyMappingConfiguration->allowAllProperties(); + } + } + + /** + * @param \EP\EpEvents\Domain\Dto\FilterSettings $filterSettings + * @return string + */ + public function listAction(FilterSettings $filterSettings) + { + $offers = $this->offerRepository->findByFilterSettings($filterSettings); + $filterOptions = FilterOptionsCollector::process($offers); + $listData = []; + + foreach ($offers as $uid => $offer) { + /** @var Offer $offer */ + $offerDetailPageUri = $this->getDetailPageUri($offer['detailPageUid']); + + $teaserImageUri = $this->getTeaserImageUri($uid); + if (!$teaserImageMobileUri = $this->getTeaserImageUri($uid, 'image_teaser_m', 'mobile')) { + $teaserImageMobileUri = $this->getTeaserImageUri($uid, 'image_teaser', 'mobile'); + } + + $listData[] = [ + 'name' => SoftHyphenService::replace($offer['name']), + 'cssClass' => SectionCssClassService::getClass($offer['configuratorType']), + 'detailPageUri' => $offerDetailPageUri, + 'locationName' => $offer['locationName'], + 'teaserImage' => $teaserImageUri, + 'teaserImageMobile' => $teaserImageMobileUri, + ]; + } + + return json_encode([ + 'offers' => $listData, + 'filterSettings' => $filterSettings, + 'filterOptions' => $filterOptions, + ]); + } + + /** + * @param int $detailPageUid + * @return string + */ + protected function getDetailPageUri($detailPageUid) + { + return $this + ->uriBuilder + ->reset() + ->setCreateAbsoluteUri(true) + ->setTargetPageUid($detailPageUid) + ->buildFrontendUri(); + } + + /** + * @param int $offerUid + * @param string $field + * @param string $cropVariant + * @return string + */ + protected function getTeaserImageUri($offerUid, $field = 'image_teaser', $cropVariant = 'default') + { + $teaserImages = $this->fileRepository->findByRelation( + 'tx_epevents_domain_model_offer', + $field, + $offerUid + ); + + if (count($teaserImages) === 0) { + return null; + } + + $teaserImage = reset($teaserImages); + + $instructions = ['width' => '500']; + $cropVariantCollection = CropVariantCollection::create((string)$teaserImage->getProperty('crop')); + $cropArea = $cropVariantCollection->getCropArea($cropVariant); + $instructions['crop'] = $cropArea->isEmpty() ? null : $cropArea->makeAbsoluteBasedOnFile($teaserImage); + $processedTeaserImage = $this->imageService->applyProcessingInstructions($teaserImage, $instructions); + + return $this->imageService->getImageUri($processedTeaserImage, true); + } +} diff --git a/public/typo3conf/ext/ep_events/Classes/Controller/OfferController.php b/public/typo3conf/ext/ep_events/Classes/Controller/OfferController.php index 848716af..511f8109 100644 --- a/public/typo3conf/ext/ep_events/Classes/Controller/OfferController.php +++ b/public/typo3conf/ext/ep_events/Classes/Controller/OfferController.php @@ -31,6 +31,7 @@ use EP\EpEvents\Domain\Model\Offer; use EP\EpEvents\Domain\Repository\OfferRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; +use TYPO3\CMS\Extbase\Utility\LocalizationUtility; class OfferController extends ActionController { @@ -65,6 +66,22 @@ class OfferController extends ActionController $this->view->assign('content', $content); } + public function listAction() + { + $content = $this->configurationManager->getContentObject()->data; + $language = [ + 'type' => LocalizationUtility::translate('tx_epevents.label.configurator_travel_type', 'ep_events'), + 'destination' => LocalizationUtility::translate('tx_epevents.label.configurator_destination', 'ep_events'), + 'distance' => LocalizationUtility::translate('tx_epevents.label.configurator_distance', 'ep_events'), + 'hotel' => LocalizationUtility::translate('tx_epevents.label.configurator_accommodation', 'ep_events'), + 'programme' => LocalizationUtility::translate('tx_epevents.label.configurator_programme', 'ep_events'), + 'noSelection' => LocalizationUtility::translate('tx_epevents.label.configurator_please_select', 'ep_events'), + 'reset' => LocalizationUtility::translate('tx_epevents.label.reset', 'ep_events'), + ]; + $this->view->assign('content', $content); + $this->view->assign('language', json_encode($language)); + } + /** * @param Offer $offer */ diff --git a/public/typo3conf/ext/ep_events/Classes/Domain/Dto/FilterSettings.php b/public/typo3conf/ext/ep_events/Classes/Domain/Dto/FilterSettings.php new file mode 100644 index 00000000..fcc6a049 --- /dev/null +++ b/public/typo3conf/ext/ep_events/Classes/Domain/Dto/FilterSettings.php @@ -0,0 +1,110 @@ +travelType; + } + + /** + * @param int $travelType + */ + public function setTravelType($travelType) + { + $this->travelType = $travelType; + } + + /** + * @return int + */ + public function getLocationType() + { + return $this->locationType; + } + + /** + * @param int $locationType + */ + public function setLocationType($locationType) + { + $this->locationType = $locationType; + } + + /** + * @return int + */ + public function getLocationDistance() + { + return $this->locationDistance; + } + + /** + * @param int $locationDistance + */ + public function setLocationDistance($locationDistance) + { + $this->locationDistance = $locationDistance; + } + + /** + * @return int + */ + public function getHotelType() + { + return $this->hotelType; + } + + /** + * @param int $hotelType + */ + public function setHotelType($hotelType) + { + $this->hotelType = $hotelType; + } + + /** + * @return int + */ + public function getActivityType() + { + return $this->activityType; + } + + /** + * @param int $activityType + */ + public function setActivityType($activityType) + { + $this->activityType = $activityType; + } +} diff --git a/public/typo3conf/ext/ep_events/Classes/Domain/Repository/OfferRepository.php b/public/typo3conf/ext/ep_events/Classes/Domain/Repository/OfferRepository.php index ce4ff7d7..be465dfe 100644 --- a/public/typo3conf/ext/ep_events/Classes/Domain/Repository/OfferRepository.php +++ b/public/typo3conf/ext/ep_events/Classes/Domain/Repository/OfferRepository.php @@ -27,8 +27,10 @@ namespace EP\EpEvents\Domain\Repository; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use EP\EpEvents\Domain\Dto\FilterSettings; use EP\EpEvents\Domain\Model\Activity; use EP\EpEvents\Domain\Model\Offer; +use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Extbase\Persistence\QueryInterface; class OfferRepository extends AbstractRepository @@ -74,6 +76,72 @@ class OfferRepository extends AbstractRepository return $query->matching($query->logicalAnd($constraints))->execute(); } + /** + * @param FilterSettings $filterSettings + * @return array + */ + public function findByFilterSettings(FilterSettings $filterSettings) + { + /** @var ConnectionPool $connectionPool */ + $connectionPool = $this->objectManager->get(ConnectionPool::class); + $qb = $connectionPool->getQueryBuilderForTable('tx_epevents_domain_model_offer'); + + $qb->select( + 'o.uid AS uid', 'o.name AS name', 'o.configurator_type AS configuratorType', + 'o.detail_page AS detailPageUid', + 'l.name AS locationName', 'l.configurator_type AS locationType', + 'l.configurator_distance AS locationDistance', 'h.configurator_type AS hotelType', + 'a.configurator_type AS activityType' + ) + ->from('tx_epevents_domain_model_offer', 'o') + ->join('o', 'tx_epevents_domain_model_location', 'l', 'o.location = l.uid') + ->join('o', 'tx_epevents_domain_model_hotel', 'h', 'o.hotel = h.uid') + ->join('o', 'tx_epevents_offer_activity_mm', 'mm', 'mm.uid_local = o.uid') + ->join('mm', 'tx_epevents_domain_model_activity', 'a', 'mm.uid_foreign = a.uid') + ->where($qb->expr()->neq('o.type', Offer::TYPE_CLIENT)) + ->orderBy('l.name', 'ASC') + ->addOrderBy('o.name', 'ASC'); + + if ($filterSettings->getTravelType() > 0) { + $qb->andWhere($qb->expr()->eq( + 'o.configurator_type', $qb->createNamedParameter($filterSettings->getTravelType()) + )); + } + if ($filterSettings->getLocationDistance() > 0) { + $qb->andWhere($qb->expr()->eq('l.configurator_distance', $filterSettings->getLocationDistance())); + } + if ($filterSettings->getLocationType() > 0) { + $qb->andWhere($qb->expr()->eq('l.configurator_type', $filterSettings->getLocationType())); + } + if ($filterSettings->getHotelType() > 0) { + $qb->andWhere($qb->expr()->eq('h.configurator_type', $filterSettings->getHotelType())); + } + if ($filterSettings->getActivityType() > 0) { + $qb->andWhere($qb->expr()->eq('a.configurator_type', $filterSettings->getActivityType())); + } + + $result = $qb->execute()->fetchAll(); + $offers = []; + + foreach ($result as $row) { + if (!array_key_exists($row['uid'], $offers)) { + $offers[$row['uid']] = [ + 'name' => $row['name'], + 'configuratorType' => $row['configuratorType'], + 'detailPageUid' => $row['detailPageUid'], + 'locationType' => $row['locationType'], + 'locationName' => $row['locationName'], + 'locationDistance' => $row['locationDistance'], + 'hotelType' => $row['hotelType'], + 'activityTypes' => [], + ]; + } + $offers[$row['uid']]['activityTypes'][] = $row['activityType']; + } + + return $offers; + } + /** * @param Activity $activity * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface diff --git a/public/typo3conf/ext/ep_events/Classes/Service/FilterOptionsCollector.php b/public/typo3conf/ext/ep_events/Classes/Service/FilterOptionsCollector.php new file mode 100644 index 00000000..b372c933 --- /dev/null +++ b/public/typo3conf/ext/ep_events/Classes/Service/FilterOptionsCollector.php @@ -0,0 +1,67 @@ + [], + 'locationTypes' => [], + 'locationDistances' => [], + 'hotelTypes' => [], + 'activityTypes' => [], + ]; + + foreach ($offers as $offer) { + /** @var Offer $offer */ + if (!array_key_exists($offer['configuratorType'], $settings['travelTypes'])) { + $settings['travelTypes'][$offer['configuratorType']] = [ + 'type' => $offer['configuratorType'], + 'label' => LocalizationUtility::translate(sprintf('tx_epevents_domain_model_traveltype.configurator_label.%d', $offer['configuratorType']), 'ep_events'), + ]; + } + if (!array_key_exists($offer['locationType'], $settings['locationTypes'])) { + $settings['locationTypes'][$offer['locationType']] = [ + 'type' => $offer['locationType'], + 'label' => LocalizationUtility::translate(sprintf('tx_epevents_domain_model_location.configurator_label.%d', $offer['locationType']), 'ep_events'), + ]; + } + if (!array_key_exists($offer['locationDistance'], $settings['locationDistances'])) { + $settings['locationDistances'][$offer['locationDistance']] = [ + 'type' => $offer['locationDistance'], + 'label' => LocalizationUtility::translate(sprintf('tx_epevents_domain_model_distance.configurator_label.%d', $offer['locationDistance']), 'ep_events'), + ]; + } + if (!array_key_exists($offer['hotelType'], $settings['hotelTypes'])) { + $settings['hotelTypes'][$offer['hotelType']] = [ + 'type' => $offer['hotelType'], + 'label' => LocalizationUtility::translate(sprintf('tx_epevents_domain_model_hotel.configurator_label.%d', $offer['hotelType']), 'ep_events'), + ]; + } + foreach ($offer['activityTypes'] as $activityType) { + if (!array_key_exists($activityType, $settings['activityTypes'])) { + $settings['activityTypes'][$activityType] = [ + 'type' => $activityType, + 'label' => LocalizationUtility::translate(sprintf('tx_epevents_domain_model_activity.configurator_label.%d', $activityType), 'ep_events'), + ]; + } + } + } + + sort($settings['travelTypes']); + sort($settings['locationTypes']); + sort($settings['locationDistances']); + sort($settings['hotelTypes']); + sort($settings['activityTypes']); + + return $settings; + } +} diff --git a/public/typo3conf/ext/ep_events/Classes/Service/SectionCssClassService.php b/public/typo3conf/ext/ep_events/Classes/Service/SectionCssClassService.php new file mode 100644 index 00000000..77906870 --- /dev/null +++ b/public/typo3conf/ext/ep_events/Classes/Service/SectionCssClassService.php @@ -0,0 +1,28 @@ + 'incentives', + 2 => 'teambuilding', + 3 => 'meetings', + 4 => 'events', + ]; + + /** + * @param int $sectionValue + * @return string + */ + public static function getClass($sectionValue = null) + { + if (array_key_exists($sectionValue, static::$cssClasses)) { + return 'section-' . static::$cssClasses[$sectionValue]; + } + + return 'section-default'; + } +} diff --git a/public/typo3conf/ext/ep_events/Classes/Service/SoftHyphenService.php b/public/typo3conf/ext/ep_events/Classes/Service/SoftHyphenService.php new file mode 100644 index 00000000..88f0df41 --- /dev/null +++ b/public/typo3conf/ext/ep_events/Classes/Service/SoftHyphenService.php @@ -0,0 +1,14 @@ + 'incentives', - 2 => 'teambuilding', - 3 => 'meetings', - 4 => 'events', - ]; - public function initializeArguments() { parent::initializeArguments(); @@ -68,11 +59,8 @@ class SectionCssClassViewHelper extends AbstractViewHelper if ($sectionValue === null) { $sectionValue = $arguments['sectionValue']; } - if (array_key_exists($sectionValue, static::$cssClasses)) { - return 'section-' . static::$cssClasses[$sectionValue]; - } - return 'section-default'; + return SectionCssClassService::getClass($sectionValue); } } diff --git a/public/typo3conf/ext/ep_events/Classes/ViewHelpers/SoftHyphenViewHelper.php b/public/typo3conf/ext/ep_events/Classes/ViewHelpers/SoftHyphenViewHelper.php index fc361749..ef3e7b39 100644 --- a/public/typo3conf/ext/ep_events/Classes/ViewHelpers/SoftHyphenViewHelper.php +++ b/public/typo3conf/ext/ep_events/Classes/ViewHelpers/SoftHyphenViewHelper.php @@ -27,6 +27,7 @@ namespace EP\EpEvents\ViewHelpers; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use EP\EpEvents\Service\SoftHyphenService; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; @@ -64,7 +65,7 @@ class SoftHyphenViewHelper extends AbstractViewHelper $string = $arguments['string']; } - return str_replace('--', '­', $string); + return SoftHyphenService::replace($string); } } diff --git a/public/typo3conf/ext/ep_events/Configuration/TCA/Overrides/tt_content.php b/public/typo3conf/ext/ep_events/Configuration/TCA/Overrides/tt_content.php index 2b1b2c12..fb1864f5 100644 --- a/public/typo3conf/ext/ep_events/Configuration/TCA/Overrides/tt_content.php +++ b/public/typo3conf/ext/ep_events/Configuration/TCA/Overrides/tt_content.php @@ -59,6 +59,12 @@ call_user_func(function() { 'EP Events: Reisebeispiele Slider' ); + \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( + 'EP.EpEvents', + 'OfferList', + 'EP Events: Reisebeispiele Übersicht' + ); + \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpEvents', 'Testimonials', diff --git a/public/typo3conf/ext/ep_events/Configuration/TypoScript/Page/Ajax.typoscript b/public/typo3conf/ext/ep_events/Configuration/TypoScript/Page/Ajax.typoscript index 4685ac73..819b9c4d 100644 --- a/public/typo3conf/ext/ep_events/Configuration/TypoScript/Page/Ajax.typoscript +++ b/public/typo3conf/ext/ep_events/Configuration/TypoScript/Page/Ajax.typoscript @@ -24,6 +24,9 @@ ajax_page_json { 1 = processInquiryForm 2 = processConfiguratorForm } + AjaxOffer { + 1 = list + } } features.requireCHashArgumentForActionArguments = 0 settings =< plugin.tx_epevents.settings diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/app.js b/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/_app.js similarity index 97% rename from public/typo3conf/ext/ep_events/Resources/Private/Assets/js/app.js rename to public/typo3conf/ext/ep_events/Resources/Private/Assets/js/_app.js index 66c9f161..5b738280 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/app.js +++ b/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/_app.js @@ -6,6 +6,9 @@ import Vue from 'vue' import $ from 'jquery' import VueSession from 'vue-session' +import 'lazysizes'; +import 'lazysizes/plugins/attrchange/ls.attrchange'; + const slick = require('slick-carousel'); const Sticky = require('sticky-js'); const $window = $(window); @@ -15,6 +18,7 @@ Vue.use(VueSession); import InquiryForm from './components/InquiryForm.vue' import Configurator from './components/Configurator.vue' import TeaserCarousel from './components/TeaserCarousel.vue' +import OfferTeasers from './components/OfferTeasers.vue' const carouselArrowLeft = ''; const carouselArrowRight = ''; @@ -24,7 +28,8 @@ new Vue({ components: { InquiryForm, Configurator, - TeaserCarousel + TeaserCarousel, + OfferTeasers }, data () { return { diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/components/OfferTeasers.vue b/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/components/OfferTeasers.vue new file mode 100644 index 00000000..bfcef80e --- /dev/null +++ b/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/components/OfferTeasers.vue @@ -0,0 +1,131 @@ + + + diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/main.js b/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/main.js index 144555af..da0e5801 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/main.js +++ b/public/typo3conf/ext/ep_events/Resources/Private/Assets/js/main.js @@ -10,7 +10,7 @@ require('cookieconsent/build/cookieconsent.min.css'); require('flatpickr/dist/flatpickr.css'); // Require main app -require('./app'); +require('./_app'); // Require main styles require('../scss/main.scss'); diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_forms.scss b/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_forms.scss index d9bada6f..d9833cd6 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_forms.scss +++ b/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_forms.scss @@ -1,122 +1,147 @@ .form { - margin: 0; - padding: 0; - position: relative; + margin: 0; + padding: 0; + position: relative; + max-width: 100%; + + @include mq($from: desktop) { + &:not(&--horizontal) { + max-width: 75%; + } + } + + &--box { max-width: 100%; + } - @include mq($from: desktop) { - max-width: 75%; - } - - &--box { - max-width: 100%; + &--horizontal { + width: 100%; + @include mq($from: tablet) { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; } + } } .form__item { + display: block; + margin-bottom: 8px; + + &--textarea { + padding-top: 16px; + } + + &--button { + padding-top: 16px; + } + + &--radios { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + background-color: $color-brand-light; + color: white; + border-radius: 8px; + } + + &--mobile { display: block; - margin-bottom: 8px; - &--textarea { - padding-top: 16px; + @include mq($from: tablet) { + display: none; + } + } + + &--tablet { + display: none; + + @include mq($from: tablet, $until: desktop) { + display: block; + } + } + + &--desktop { + display: none; + + @include mq($from: desktop) { + display: block; + } + } + + .form--horizontal & { + width: 100%; + padding: 0 8px; + + &--no-label { + padding-top: 20px; } - &--button { - padding-top: 16px; - } - - &--radios { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - background-color: $color-brand-light; - color: white; - border-radius: 8px; - } - - &--mobile { - display: block; - - @include mq($from: tablet) { - display: none; - } - } - - &--tablet { - display: none; - - @include mq($from: tablet, $until: desktop) { - display: block; - } - } - - &--desktop { - display: none; - - @include mq($from: desktop) { - display: block; - } + @include mq($from: tablet) { + width: 33.3333%; } + } } .form__item__error { - padding: 8px; - font-size: 90%; + padding: 8px; + font-size: 90%; } .form__field { - @include nooutline; - border: none; - border-radius: 8px; - width: 100%; - padding: 8px 16px; - color: white; + @include nooutline; + border: none; + border-radius: 8px; + width: 100%; + padding: 8px 16px; + color: white; + background-color: $color-brand-light; + + .form--box & { background-color: $color-brand-light; + color: white; + } - .form--box & { - background-color: $color-brand-light; - color: white; - } + &--textarea { + resize: vertical; + } - &--textarea { - resize: vertical; + &--radio { + background-color: transparent; + display: block; + padding: 8px; + width: 100%; + @include mq($from: tablet) { + width: 50%; } + @include mq($from: desktop) { + width: 25%; + } + } - &--radio { - background-color: transparent; - display: block; - padding: 8px; - width: 100%; - @include mq($from: tablet) { - width: 50%; - } - @include mq($from: desktop) { - width: 25%; - } - } + &--configurator { + background-color: rgba(white, 0.6); + } - &--configurator { - background-color: rgba(white, 0.6); - } - - .has-errors & { - border: 1px solid $color-formerror; - } + .has-errors & { + border: 1px solid $color-formerror; + } } .form__link { - display: block; - font-size: 80%; + display: block; + font-size: 80%; - &--indent { - text-align: right; - } + &--indent { + text-align: right; + } - .configurator & { - color: white; - padding-top: 16px; - } + .configurator & { + color: white; + padding-top: 16px; + } } .form__text { @@ -128,101 +153,101 @@ } .form__button { - outline: none; - display: block; + outline: none; + display: block; + width: 100%; + color: white; + background-color: $color-brand-secondary; + border: none; + font-weight: 700; + text-decoration: none; + text-align: center; + padding: 8px 32px; + margin-bottom: 16px; + + @include mq($from: tablet) { + display: inline-block; + width: auto; + margin-bottom: 0; + } + + .form--box & { width: 100%; - color: white; - background-color: $color-brand-secondary; - border: none; - font-weight: 700; - text-decoration: none; - text-align: center; - padding: 8px 32px; - margin-bottom: 16px; - - @include mq($from: tablet) { - display: inline-block; - width: auto; - margin-bottom: 0; - } - - .form--box & { - width: 100%; - font-size: 20px; - padding: 8px 0; - } + font-size: 20px; + padding: 8px 0; + } } .form__overlay { - @include size(100%); - position: absolute; - top: 0; - left: 0; - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; - background-color: rgba($color-divider, 0.75); + @include size(100%); + position: absolute; + top: 0; + left: 0; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + background-color: rgba($color-divider, 0.75); - .form--box & { - background-color: rgba($color-brand-primary, 0.75); - } + .form--box & { + background-color: rgba($color-brand-primary, 0.75); + } } .form__overlay__text { - text-align: center; + text-align: center; } ::-webkit-input-placeholder { /* WebKit, Blink, Edge */ - color: white; - text-transform: uppercase; - font-size: 90%; + color: white; + text-transform: uppercase; + font-size: 90%; } :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ - color: white; - opacity: 1; - text-transform: uppercase; - font-size: 90%; + color: white; + opacity: 1; + text-transform: uppercase; + font-size: 90%; } ::-moz-placeholder { /* Mozilla Firefox 19+ */ - color: white; - opacity: 1; - text-transform: uppercase; - font-size: 90%; + color: white; + opacity: 1; + text-transform: uppercase; + font-size: 90%; } :-ms-input-placeholder { /* Internet Explorer 10-11 */ - color: white; - text-transform: uppercase; - font-size: 90%; + color: white; + text-transform: uppercase; + font-size: 90%; } ::-ms-input-placeholder { /* Microsoft Edge */ - color: white; - text-transform: uppercase; - font-size: 90%; + color: white; + text-transform: uppercase; + font-size: 90%; } .form--box { - ::-webkit-input-placeholder { /* WebKit, Blink, Edge */ - color: white; - } + ::-webkit-input-placeholder { /* WebKit, Blink, Edge */ + color: white; + } - :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ - color: white; - } + :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ + color: white; + } - ::-moz-placeholder { /* Mozilla Firefox 19+ */ - color: white; - } + ::-moz-placeholder { /* Mozilla Firefox 19+ */ + color: white; + } - :-ms-input-placeholder { /* Internet Explorer 10-11 */ - color: white; - } + :-ms-input-placeholder { /* Internet Explorer 10-11 */ + color: white; + } - ::-ms-input-placeholder { /* Microsoft Edge */ - color: white; - } + ::-ms-input-placeholder { /* Microsoft Edge */ + color: white; + } } diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_offerlist.scss b/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_offerlist.scss new file mode 100644 index 00000000..26e2a1a4 --- /dev/null +++ b/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/_offerlist.scss @@ -0,0 +1,35 @@ +.offerlist { + position: relative; +} + +.offerlist__overlay { + @include size(100%); + position: absolute; + top: 0; + left: 0; + z-index: 10; + background: rgba(white, 0.85) url(../images/spinner_default.gif) no-repeat 50% 5%; +} + +.offerlist__teasers { + @include mq($from: tablet) { + display: flex; + flex-wrap: wrap; + } +} + +.offerlist-item { + width: 100%; + text-decoration: none; + margin-bottom: 32px; + display: block; + @include mq($from: mobile) { + display: flex; + } + @include mq($from: tablet) { + width: 50%; + } + @include mq($from: desktop) { + width: 33.3333%; + } +} diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/main.scss b/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/main.scss index 828a5fa9..e2c3cce9 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/main.scss +++ b/public/typo3conf/ext/ep_events/Resources/Private/Assets/scss/main.scss @@ -35,6 +35,7 @@ $output-bourbon-deprecation-warnings: false; @import "team"; @import "cookieconsent"; @import "search"; +@import "offerlist"; @import "paginator"; @import "news"; @import "datepicker"; diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Language/de.locallang.xlf b/public/typo3conf/ext/ep_events/Resources/Private/Language/de.locallang.xlf index cdf11b16..e106ba82 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Language/de.locallang.xlf +++ b/public/typo3conf/ext/ep_events/Resources/Private/Language/de.locallang.xlf @@ -58,6 +58,15 @@ Spezial + + Deutschland + + + Europa + + + Welt + Outdoor & Action @@ -220,6 +229,9 @@ Suchen + + Reset + %s ergab %d Treffer:]]> diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Language/locallang.xlf b/public/typo3conf/ext/ep_events/Resources/Private/Language/locallang.xlf index 19108d7d..491b8a49 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Language/locallang.xlf +++ b/public/typo3conf/ext/ep_events/Resources/Private/Language/locallang.xlf @@ -58,6 +58,15 @@ Special + + Germany + + + Europe + + + World + Outdoor & Action @@ -220,6 +229,9 @@ Search + + Reset + %s results in %d findings:]]> diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Partials/OfferTeasers.html b/public/typo3conf/ext/ep_events/Resources/Private/Partials/OfferTeasers.html index 3393e887..bb30cbc7 100644 --- a/public/typo3conf/ext/ep_events/Resources/Private/Partials/OfferTeasers.html +++ b/public/typo3conf/ext/ep_events/Resources/Private/Partials/OfferTeasers.html @@ -19,14 +19,14 @@ + srcset="{f:uri.image(image: offer.imageTeaserMobile, width: '500')} 500w"/> - {offer.imageTeaser.alternative} + {offer.imageTeaser.alternative} diff --git a/public/typo3conf/ext/ep_events/Resources/Private/Templates/Offer/List.html b/public/typo3conf/ext/ep_events/Resources/Private/Templates/Offer/List.html new file mode 100644 index 00000000..43f0717f --- /dev/null +++ b/public/typo3conf/ext/ep_events/Resources/Private/Templates/Offer/List.html @@ -0,0 +1,10 @@ +
+ + + + + + + +
diff --git a/public/typo3conf/ext/ep_events/ext_localconf.php b/public/typo3conf/ext/ep_events/ext_localconf.php index 863651b7..cec97d1c 100644 --- a/public/typo3conf/ext/ep_events/ext_localconf.php +++ b/public/typo3conf/ext/ep_events/ext_localconf.php @@ -26,6 +26,17 @@ call_user_func(function() { ] ); + \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( + 'EP.EpEvents', + 'OfferList', + [ + 'Offer' => 'list', + ], + [ + 'Offer' => '', + ] + ); + \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( 'EP.EpEvents', 'Testimonials', @@ -130,9 +141,11 @@ call_user_func(function() { 'Ajax', [ 'AjaxForm' => 'processInquiryForm, processConfiguratorForm', + 'AjaxOffer' => 'list', ], [ 'AjaxForm' => 'processInquiryForm, processConfiguratorForm', + 'AjaxOffer' => 'list', ] ); @@ -168,4 +181,9 @@ call_user_func(function() { '# cat=plugin.tx_epevents//a; type=string; label=Configurator period options', 'plugin.tx_epevents.settings.configurator.periodOptions = ' . $extensionConfiguration['periodOptions'] ])); + + $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'gclid'; + $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'ref'; + $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epevents_configurator[travelType]'; + $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epevents_configurator[locationType]'; });