diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php index 252aad59..a2af323b 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php @@ -71,19 +71,6 @@ class AjaxContingentController extends ActionController } } - /** - * @param Hotel $hotel - * @param Product $product - * @return string - * @throws \Doctrine\DBAL\DBALException - */ - public function listAction(Hotel $hotel, Product $product) - { - $enabled = $this->contingentDataService->getAvailableContingents($hotel, $product); - - return \json_encode($enabled); - } - /** * @param Hotel $hotel * @param Product $product diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php index b5738fda..96a41da8 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php @@ -31,6 +31,7 @@ use EP\EpProducts\Domain\Model\Date; use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Repository\ProductRepository; +use EP\EpProducts\Service\ContingentDataService; use EP\EpProducts\Service\DateService; use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\ResellerDataService; @@ -65,22 +66,31 @@ class AjaxTableController extends ActionController protected $resellerDataService; /** + * @var ContingentDataService + */ + protected $contingentDataService; + + /** + * @param ProductRepository $productRepository * @param DateService $dateService * @param FilterService $filterService * @param ResellerDataService $resellerDataService + * @param ContingentDataService $contingentDataService */ public function __construct ( ProductRepository $productRepository, DateService $dateService, FilterService $filterService, - ResellerDataService $resellerDataService + ResellerDataService $resellerDataService, + ContingentDataService $contingentDataService ) { parent::__construct(); $this->productRepository = $productRepository; $this->dateService = $dateService; $this->filterService = $filterService; $this->resellerDataService = $resellerDataService; + $this->contingentDataService = $contingentDataService; } public function initializeDatesAction() @@ -252,4 +262,20 @@ class AjaxTableController extends ActionController ]); } + /** + * @param Hotel $hotel + * @param Product $product + * @param string $dateFrom + * @param string $dateTo + */ + public function daytripRoomsAction(Hotel $hotel, Product $product, $dateFrom, $dateTo) + { + $template = $this->settings['bpnBookingUrlTemplateCode']; + $rooms = $this + ->contingentDataService + ->getAvailableRooms($dateFrom, $dateTo, $hotel, $product, $template); + + $this->view->assign('rooms', $rooms); + } + } diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php b/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php index 3d765613..41320e7a 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/ProductController.php @@ -31,6 +31,7 @@ use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Repository\HotelRepository; use EP\EpProducts\Domain\Repository\ProductRepository; +use EP\EpProducts\Service\ContingentDataService; use EP\EpProducts\Service\DateService; use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\HotelDataService; @@ -70,12 +71,17 @@ class ProductController extends ActionController * @var HotelDataService */ protected $hotelDataService; + /** + * @var ContingentDataService + */ + private $contingentDataService; /** * @param ProductRepository $productRepository * @param ProductDataService $productDataService * @param HotelRepository $hotelRepository * @param HotelDataService $hotelDataService + * @param ContingentDataService $contingentDataService * @param DateService $dateService * @param FilterService $filterService */ @@ -84,6 +90,7 @@ class ProductController extends ActionController ProductDataService $productDataService, HotelRepository $hotelRepository, HotelDataService $hotelDataService, + ContingentDataService $contingentDataService, DateService $dateService, FilterService $filterService ) { @@ -91,8 +98,9 @@ class ProductController extends ActionController $this->productRepository = $productRepository; $this->productDataService = $productDataService; $this->hotelRepository = $hotelRepository; - $this->dateService = $dateService; $this->hotelDataService = $hotelDataService; + $this->contingentDataService = $contingentDataService; + $this->dateService = $dateService; $this->filterService = $filterService; } @@ -146,6 +154,14 @@ class ProductController extends ActionController } } + if ($product->isDaytrip()) { + $availableContingents = $this + ->contingentDataService + ->getAvailableContingents($hotel, $product) + ; + $enabledDates = array_keys($availableContingents); + } + $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); $isProductWithExcludedConcept = ($product->getConcept() !== null) && \in_array($product->getConcept()->getUid(), $excludedConceptUids, false); @@ -157,29 +173,10 @@ class ProductController extends ActionController $backlinkUrl = GeneralUtility::_GET('ref'); $backLinkLabel = strpos($backlinkUrl, 'suche') !== -1 ? 'zurück zum Suchergebnis' : 'zurück'; - // Generate dates uri - $datesArguments = [ - 'dateFrom' => $dateFrom, - 'dateTo' => $dateTo, - 'product' => $product, - 'hotel' => $hotel - ]; - $datesUri = $this->uriBuilder - ->reset() - ->setCreateAbsoluteUri(true) - ->setTargetPageType(1702) - ->setTargetPageUid(855) - ->uriFor( - 'dates', - $datesArguments, - 'AjaxDate', - 'EpProducts', - 'ajax' - ); - $this->view->assignMultiple([ 'hotel' => $hotel, 'product' => $product, + 'enabledDates' => $enabledDates ?? [], 'isProductWithExcludedConcept' => $isProductWithExcludedConcept, 'isProductWithNoInfoConcept' => $isProductWithNoInfoConcept, 'currentPageUid' => $GLOBALS['TSFE']->id, @@ -187,7 +184,6 @@ class ProductController extends ActionController 'dateTo' => $dateTo, 'referringUrl' => $backlinkUrl, 'backlinkLabel' => $backLinkLabel, - 'datesUri' => $datesUri, ]); } diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php index c9664df4..0733894b 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php @@ -140,14 +140,14 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa } /** - * @param \DateTime $dateFrom - * @param \DateTime $dateTo + * @param string $dateFrom + * @param string $dateTo * @param Hotel $hotel * @param Product $product * @return array * @throws DBALException */ - public function getAvailableRooms(\DateTime $dateFrom, \DateTime $dateTo, Hotel $hotel, Product $product) + public function getAvailableRooms(string $dateFrom, string $dateTo, Hotel $hotel, Product $product) { $qb = $this->getDbConnection()->createQueryBuilder(); @@ -157,7 +157,7 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa 'c.additional_night_min_price as additionalNightPrice', 'c.additional_night_min_nights as additionalNightMinNights', 'd.bus_pro_id as busProId', 'd.services_included as servicesIncluded', 'd.services_general as servicesOptional', - 'd.skipass_included as skipassIncluded') + 'd.skipass_included as skipassIncluded', 'd.season as season') ->from('tx_epproducts_domain_model_contingent', 'c') ->innerJoin('c', 'tx_epproducts_domain_model_date', 'd', 'c.date = d.date_start AND c.hotel_code = d.hotel_code') ->where('c.hotel = :hotelUid') @@ -168,8 +168,8 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa ->setParameters([ 'hotelUid' => $hotel->getUid(), 'productUid' => $product->getUid(), - 'dateFrom' => $dateFrom->format('Y-m-d'), - 'dateTo' => $dateTo->format('Y-m-d'), + 'dateFrom' => $dateFrom, + 'dateTo' => $dateTo, ]) ->groupBy('c.room_code') ->orderBy('c.pax') diff --git a/public/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php b/public/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php index ecb713a0..5be066ba 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php @@ -31,6 +31,7 @@ use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Repository\ContingentRepository; use EP\EpProducts\Utility\BookingUrlUtility; +use League\Period\Period; class ContingentDataService { @@ -82,27 +83,32 @@ class ContingentDataService * @throws \Doctrine\DBAL\DBALException */ public function getAvailableRooms( - \DateTime $dateFrom, - \DateTime $dateTo, + string $dateFrom, + string $dateTo, Hotel $hotel, Product $product, $template = 'base' ) { $data = $this->contingentRepository->getAvailableRooms($dateFrom, $dateTo, $hotel, $product); + $period = new Period($dateFrom, $dateTo); + $nights = $period->getDateInterval()->format('%a'); $rooms = []; - foreach ($data as $row) - { + foreach ($data as $row) { $row['bookingUrl'] = BookingUrlUtility::generateUrl([ 'bookingId' => $row['busProId'], 'hotelId' => $row['hotelBusProId'], - 'dateEnd' => $dateTo->format('Y-m-d'), + 'dateEnd' => $dateTo, 'template' => $template, ]); - $row['servicesIncluded'] = unserialize($row['servicesIncluded']); - $row['servicesOptional'] = unserialize($row['servicesOptional']); + $row['summer'] = $row['season'] === 's'; + + $row['servicesIncluded'] = unserialize($row['servicesIncluded'], ['allowed_classes' => false]); + $row['servicesOptional'] = unserialize($row['servicesOptional'], ['allowed_classes' => false]); + + $row['priceForSelection'] = $row['price'] + ($nights - $row['minNights']) * $row['additionalNightPrice']; $rooms[] = $row; } diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index b980cb78..8bc21749 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -161,6 +161,7 @@ tx_epproducts_ajax_json { 2 = pricetable 3 = pricetableHtml 4 = eventPricetable + 5 = daytripRooms } AjaxCalendar { 1 = range diff --git a/public/typo3conf/ext/ep_products/ext_localconf.php b/public/typo3conf/ext/ep_products/ext_localconf.php index 5f21188e..00342d56 100644 --- a/public/typo3conf/ext/ep_products/ext_localconf.php +++ b/public/typo3conf/ext/ep_products/ext_localconf.php @@ -366,7 +366,7 @@ $iconRegistry->registerIcon( 'AjaxSearch' => 'searchresult', 'AjaxDate' => 'dates', 'AjaxContingent' => 'list,rooms', - 'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable', + 'AjaxTable' => 'datestable,pricetable,pricetableHtml,eventPricetable,daytripRooms', 'AjaxCalendar' => 'range,contingents,availableRooms', 'AjaxWatchlist' => 'list', 'AjaxGroupsPrice' => 'processForm', diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js index 5e668be1..f30efe33 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js @@ -10,12 +10,8 @@ smoothscroll.polyfill() // Alpine stuff import Alpine from 'alpinejs' -import daytripDateSelect from './components/daytrip-date-select' -import searchBar from './components/search-bar' import contactForm from './components/contact-form' -Alpine.data('daytripDateSelect', daytripDateSelect) -Alpine.data('searchBar', searchBar) Alpine.data('contactForm', contactForm) Alpine.start() diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/daytrip-date-select.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/daytrip-date-select.js deleted file mode 100644 index 08bc0998..00000000 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/daytrip-date-select.js +++ /dev/null @@ -1,153 +0,0 @@ -import axios from 'axios' -import flatpickr from 'flatpickr' -import { German } from 'flatpickr/dist/l10n/de' -import dayjs from 'dayjs' -import 'dayjs/locale/de' - -export default props => ({ - hotelName: props.hotelName, - hotelUid: props.hotelUid, - productUid: props.productUid, - contingentEndpointUri: props.contingentEndpointUri, - roomsEndpointUri: props.roomsEndpointUri, - loading: false, - picker: null, - displayedFrom: dayjs().startOf('month'), - displayedTo: dayjs().endOf('month'), - selectedFrom: null, - selectedTo: null, - selectedNumberOfNights: 0, - minNightsForSelectedDate: 0, - availableDates: [], - availableRooms: [], - init() { - this.picker = flatpickr(this.$refs.field, { - mode: 'range', - dateFormat: 'Y-m-d', - locale: German, - inline: true, - onChange: selectedDates => { - this.availableRooms = [] - if (selectedDates.length === 2) { - this.selectedFrom = dayjs(selectedDates[0]) - this.selectedTo = dayjs(selectedDates[1]) - this.selectedNumberOfNights = this.getSelectedNumberOfNights() - this.minNightsForSelectedDate = this.getMinNightsForSelectedDate() - if (this.selectedNumberOfNights >= this.minNightsForSelectedDate) { - this.fetchAvailableRooms() - } - } - }, - onDayCreate: (dObj, dStr, fp, dayElem) => { - const day = dayElem.dateObj.getFullYear() + '-' + ('0' + (dayElem.dateObj.getMonth()+1)).slice(-2) - + '-' + ('0' + dayElem.dateObj.getDate()).slice(-2) - if (day in this.availableDates) { - dayElem.classList.add('available') - } - } - }) - this.$nextTick(() => { - this.fetchEnabledDates() - }) - }, - headerLabel () { - let label = 'Buchungsoptionen' - if (this.hotelName) { - label += ' ' + this.hotelName - } - if (this.selectedFrom && this.selectedTo) { - label += ' ' + this.selectedFrom.format('DD.MM.YY') + ' - ' + this.selectedTo.format('DD.MM.YY') - label += ' (' + this.selectedNumberOfNights + ' Nächte)' - } - return label - }, - message() { - if (this.loading) { - return '' - } - if (this.selectedFrom === null || this.selectedTo === null) { - return 'Bitte einen Zeitraum auswählen.' - } - if (this.selectedNumberOfNights < this.minNightsForSelectedDate) { - return 'Bitte mindestens ' + this.minNightsForSelectedDate + ' Nächte auswählen.' - } - if (this.availableRooms.length === 0) { - return 'Im gewählten Zeitraum sind leider keine Zimmer verfügbar.' - } - return '' - }, - onDateSelected(date) { - this.selectedDate = dayjs(date) - }, - fetchEnabledDates() { - this.loading = true - const data = new FormData() - data.set('tx_epproducts_ajax[hotel]', this.hotelUid) - data.set('tx_epproducts_ajax[product]', this.productUid) - axios({ - url: this.contingentEndpointUri, - method: 'post', - data - }).then(response => { - const json = response.data - if (json) { - this.availableDates = json - const enabledDates = [] - for (const date in this.availableDates) { - if (this.availableDates.hasOwnProperty(date)) { - enabledDates.push(this.availableDates[date].date) - } - } - this.picker.set('enable', enabledDates) - this.picker.set('minDate', enabledDates[0]) - this.picker.set('maxDate', enabledDates[enabledDates.length - 1]) - this.picker.jumpToDate(enabledDates[0]) - } - }).finally(() => { - this.loading = false - }) - }, - fetchAvailableRooms() { - this.loading = true - const data = new FormData() - data.set('tx_epproducts_ajax[hotel]', this.hotelUid) - data.set('tx_epproducts_ajax[product]', this.productUid) - data.set('tx_epproducts_ajax[dateFrom]', this.selectedFrom.format('YYYY-MM-DD')) - data.set('tx_epproducts_ajax[dateTo]', this.selectedTo.format('YYYY-MM-DD')) - axios({ - url: this.roomsEndpointUri, - method: 'post', - data - }).then(response => { - this.availableRooms = response.data - }).finally(() => { - this.loading = false - }) - }, - calculatePrice (roomCode) { - const room = this.availableRooms.find(obj => { - return obj.code === roomCode - }); - if (room) { - const nights = this.getSelectedNumberOfNights() - return room.price + (nights - room.minNights) * room.additionalNightPrice - } - return null; - }, - getMinNightsForSelectedDate () { - if (this.selectedFrom === null) { - return 0 - } - const key = this.selectedFrom.format('YYYY-MM-DD') - if (!key in this.availableDates) { - return 0 - } - return this.availableDates[key].minNights - }, - getSelectedNumberOfNights () { - if (this.selectedFrom === null || this.selectedTo === null) { - return 0 - } - return this.selectedTo.diff(this.selectedFrom, 'days'); - } -}) diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/search-bar.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/search-bar.js deleted file mode 100644 index 3a58ccbd..00000000 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/search-bar.js +++ /dev/null @@ -1,143 +0,0 @@ -import axios from 'axios' -import flatpickr from 'flatpickr' -import { German } from 'flatpickr/dist/l10n/de' - -export default props => ({ - loading: false, - picker: null, - uri: props.uri, - sticky: props.sticky || false, - searchParams: props.initialSearchParams, - filterOptions: props.initialFilterOptions, - datePresets: props.datePresets, - show: null, - destinationName: '', - conceptSelected: false, - destinationSelected: false, - dateRangeSelected: { from: null, to: null }, - dateRangeLabel: '', - init() { - this.$watch('dateRangeSelected', () => { - if (null === this.dateRangeSelected.from && null === this.dateRangeSelected.to) { - this.searchParams.dateFrom = null - this.searchParams.dateTo = null - } else { - let dateFrom = this.dateRangeSelected.from - let dateTo = this.dateRangeSelected.to - this.searchParams.dateFrom = flatpickr.formatDate(dateFrom, 'Y-m-d') - this.searchParams.dateTo = flatpickr.formatDate(dateTo, 'Y-m-d') - } - this.updateDateRangeLabel() - this.load() - }) - }, - load() { - this.loading = true - const data = new FormData() - data.set('tx_epproducts_ajax[searchParams]', JSON.stringify(this.searchParams)) - axios.post(this.uri, data) - .then(response => { - this.applyOptions(response.data) - this.show = null - }) - .finally(() => { - this.loading = false - }) - }, - applyOptions(json) { - this.filterOptions.totalResults = json.totalResults - const filterOptions = json.filterOptions - this.filterOptions = { - ...this.filterOptions, - totalResults: json.totalResults, - priceRanges: filterOptions.priceRanges, - pax: filterOptions.pax, - destinations: filterOptions.destinations - } - if (filterOptions.dateFrom !== null) { - this.filterOptions.selectableRangeFrom = filterOptions.dateFrom - if (this.picker !== null) { - this.picker.set('minDate', new Date(filterOptions.dateFrom)) - } - } - if (filterOptions.dateTo !== null) { - this.filterOptions.selectableRangeTo = filterOptions.dateTo - if (this.picker !== null) { - this.picker.set('maxDate', new Date(filterOptions.dateTo)) - } - } - }, - updateSearchParam(param, value) { - this.searchParams = {...this.searchParams, [param]: value} - this.load() - }, - selectDateRangePreset(preset) { - let dateFrom = new Date(preset.dateFrom) - let dateTo = new Date(preset.dateTo) - this.dateRangeSelected = { from: dateFrom, to: dateTo } - this.picker.setDate([ dateFrom, dateTo ]) - }, - resetDateRange () { - this.dateRangeSelected = { from: null, to: null } - this.picker.clear() - this.picker.jumpToDate() - }, - selectDestination(uid, name, type) { - this.destinationName = name - this.destinationSelected = type !== 'concept' - this.conceptSelected = type === 'concept' - this.searchParams = {...this.searchParams, destinationUid: uid, destinationType: type} - this.load() - }, - resetDestination() { - this.destinationName = '' - this.destinationSelected = false - this.conceptSelected = false - this.searchParams = {...this.searchParams, destinationUid: null, destinationType: null} - this.load() - }, - initDatePicker() { - this.picker = flatpickr(this.$refs.picker, { - mode: 'range', - locale: German, - inline: true, - onChange: selectedDates => { - if (selectedDates.length === 2) { - this.dateRangeSelected = { from: selectedDates[0], to: selectedDates[1] } - } - } - }) - let minDate = this.filterOptions.dateFrom ? new Date(this.filterOptions.dateFrom) : new Date - this.picker.set('minDate', minDate) - if (this.filterOptions.dateTo) { - this.picker.set('maxDate', new Date(this.filterOptions.dateTo)) - } - }, - priceRangeLabel() { - if (null === this.searchParams.priceRange) { - return '' - } - let range = this.filterOptions.priceRanges[this.searchParams.priceRange] - return this.priceRangeFormatted(range) - }, - priceRangeFormatted(range) { - let min = range.min; - let max = range.max; - if (min === 1) { - return 'bis ' + max + ' €' - } - if (max === 999) { - return 'ab ' + min + ' €' - } - return min + ' - ' + max + ' €' - }, - updateDateRangeLabel() { - let dateRangeLabel = '' - if (null !== this.dateRangeSelected.from && null !== this.dateRangeSelected.to) { - let dateFrom = this.dateRangeSelected.from - let dateTo = this.dateRangeSelected.to - dateRangeLabel = `${flatpickr.formatDate(dateFrom, 'd.m.Y')} - ${flatpickr.formatDate(dateTo, 'd.m.Y')}` - } - this.dateRangeLabel = dateRangeLabel - }, -}) diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/contactform_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/contactform_controller.js new file mode 100644 index 00000000..e69de29b diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/datepicker_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/datepicker_controller.js index e4b2d207..a774c894 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/datepicker_controller.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/datepicker_controller.js @@ -15,6 +15,7 @@ export default class extends Controller { minDate: String, dateFrom: String, dateTo: String, + enabledDates: Array, } initialize() { @@ -33,6 +34,24 @@ export default class extends Controller { } } }) + if (this.hasEnabledDatesValue) { + let enabledDates = this.enabledDatesValue + let minDate = enabledDates[0] + let maxDate = enabledDates[enabledDates.length - 1] + if (this.hasMinDateValue && this.minDateValue > minDate) { + minDate = this.minDateValue + } + this.picker.set('enable', enabledDates) + this.picker.set('minDate', minDate) + this.picker.set('maxDate', maxDate) + this.picker.jumpToDate(minDate) + this.picker.set('onDayCreate', (dObj, dStr, fp, dayElem) => { + let day = flatpickr.formatDate(dayElem.dateObj, 'Y-m-d') + if (day >= minDate && -1 !== this.enabledDatesValue.indexOf(day)) { + dayElem.classList.add('available') + } + }) + } } connect() { diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/daytrip_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/daytrip_controller.js new file mode 100644 index 00000000..867ac3fe --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/daytrip_controller.js @@ -0,0 +1,58 @@ +import { Controller } from 'stimulus' +import { useDispatch } from 'stimulus-use' +import { useFetch } from '../mixins/use_fetch' + +export default class extends Controller { + + static targets = [ + 'headerLabel', + 'container', + 'loadingIndicator', + 'message', + ] + + static values = { + loading: Boolean, + contingentsUri: String, + roomsUri: String, + hotelUid: Number, + productUid: Number, + dateFrom: String, + dateTo: String, + } + + initialize() { + useDispatch(this) + useFetch(this) + } + + openModal(e) { + let eventName = `${e.currentTarget.dataset.type}-modal:open` + this.dispatch(eventName, e.currentTarget.dataset.uid) + } + + load(e) { + this.loadingValue = true + this.dateFromValue = e.detail.from + this.dateToValue = e.detail.to + let data = new FormData() + data.set('tx_epproducts_ajax[hotel]', this.hotelUidValue) + data.set('tx_epproducts_ajax[product]', this.productUidValue) + data.set('tx_epproducts_ajax[dateFrom]', this.dateFromValue) + data.set('tx_epproducts_ajax[dateTo]', this.dateToValue) + fetch(this.roomsUriValue, { method: 'POST', body: data }) + .then(this.checkStatus) + .then(this.parseHTML) + .then(html => { + this.containerTarget.innerHTML = html + this.messageTarget.classList.add('hidden') + }) + .finally(() => { + this.loadingValue = false + }) + } + + loadingValueChanged() { + this.loadingIndicatorTarget.classList.toggle('hidden', this.loadingValue === false) + } +} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/product_details_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/product_details_controller.js index a2ef6e76..089b5513 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/product_details_controller.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/product_details_controller.js @@ -18,6 +18,7 @@ export default class extends Controller { loading: Boolean, loaded: Boolean, mode: String, + daytrip: Boolean, } initialize() { @@ -26,7 +27,7 @@ export default class extends Controller { } connect() { - if ('dates' === this.modeValue) { + if (false === this.dayTripValue && 'dates' === this.modeValue) { this.loadDates() } } @@ -86,7 +87,11 @@ export default class extends Controller { } modeValueChanged() { - this.datesTableContainerTarget.classList.toggle('hidden', this.modeValue === 'prices') - this.priceTableContainerTarget.classList.toggle('hidden', this.modeValue === 'dates') + if (this.hasDatesTableContainerTarget) { + this.datesTableContainerTarget.classList.toggle('hidden', this.modeValue === 'prices') + } + if (this.hasPriceTableContainerTarget) { + this.priceTableContainerTarget.classList.toggle('hidden', this.modeValue === 'dates') + } } } diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/searchbar_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/searchbar_controller.js index 581b1341..3e8c4096 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/searchbar_controller.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/searchbar_controller.js @@ -24,7 +24,7 @@ export default class extends Controller { this.dateRangeLabelTarget.value = e.detail.label this.dateFromTarget.value = e.detail.from this.dateToTarget.value = e.detail.to - this.dispatch('input') + this.dispatch('input', this.getDetails()) } setPax(e) { @@ -32,7 +32,7 @@ export default class extends Controller { let pax = e.currentTarget.dataset.option this.paxTarget.value = pax this.paxLabelTarget.value = pax - this.dispatch('input') + this.dispatch('input', this.getDetails()) } setDestination(e) { @@ -40,7 +40,7 @@ export default class extends Controller { this.destinationUidTarget.value = e.currentTarget.dataset.optionUid this.destinationTypeTarget.value = e.currentTarget.dataset.optionType this.destinationLabelTarget.value = e.currentTarget.dataset.optionLabel - this.dispatch('input') + this.dispatch('input', this.getDetails()) } resetDestination(e) { @@ -48,13 +48,24 @@ export default class extends Controller { this.destinationUidTarget.value = '' this.destinationTypeTarget.value = '' this.destinationLabelTarget.value = '' - this.dispatch('input') + this.dispatch('input', this.getDetails()) } setPriceRange(e) { e.preventDefault() this.priceRangeTarget.value = e.currentTarget.dataset.optionValue this.priceRangeLabelTarget.value = e.currentTarget.dataset.labelValue - this.dispatch('input') + this.dispatch('input', this.getDetails()) + } + + getDetails() { + return { + dateFrom: this.dateFromTarget.value, + dateTo: this.dateToTarget.value, + pax: this.paxTarget.value, + destinationUid: this.destinationUidTarget.value, + destinationType: this.destinationTypeTarget.value, + priceRange: this.priceRangeTarget.value, + } } } diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/sticky_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/sticky_controller.js index 65cb6587..0eaaa692 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/sticky_controller.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/sticky_controller.js @@ -33,6 +33,7 @@ export default class extends Controller { } stickyValueChanged() { - this.element.classList.toggle(this.stickyClass, this.stickyValue) + let stickyClass = this.hasStickyClass ? this.stickyClass : 'sticky' + this.element.classList.toggle(stickyClass, this.stickyValue) } } diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Error.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Error.html new file mode 100644 index 00000000..0fe4b966 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Error.html @@ -0,0 +1,5 @@ + + + diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Full.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Full.html new file mode 100644 index 00000000..946680a2 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Full.html @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+ Ich habe die Datenschutzbestimmungen gelesen und akzeptiert. +
+
+ +
+
+ + diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Simple.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Simple.html new file mode 100644 index 00000000..e69de29b diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Success.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/ContactForm/Success.html new file mode 100644 index 00000000..e69de29b diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxForm/FullForm.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxForm/FullForm.html new file mode 100644 index 00000000..02202f64 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxForm/FullForm.html @@ -0,0 +1,11 @@ +
+ + + + + + + +
diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxForm/SimpleForm.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxForm/SimpleForm.html new file mode 100644 index 00000000..c86f90c7 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxForm/SimpleForm.html @@ -0,0 +1,20 @@ +
+ + + + +
+
+ +
+ +
+
+ +
diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxTable/DaytripRooms.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxTable/DaytripRooms.html new file mode 100644 index 00000000..489715b5 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/AjaxTable/DaytripRooms.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + +
ZimmerartPreisinkl.
+ {row.label} + + ab {row.priceForSelection} € + + + + + + + + + + + + Buchen + +
+ + + +
+ + diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html index cd4e62fe..fd9fdb64 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html @@ -18,7 +18,8 @@ data-product-details-datestable-uri-value="{ep:uri.ajax(action: 'datestable', controller: 'AjaxTable', arguments: '{product: product, hotel: hotel}', format: 'html', pageUid: settings.defaultAjaxUid)}" data-product-details-pricetable-uri-value="{ep:uri.ajax(action: 'pricetable', controller: 'AjaxTable', arguments: '{product: product, hotel: hotel}', format: 'html', pageUid: settings.defaultAjaxUid)}" - data-product-details-travel-alert-uri-value="{f:uri.typolink(parameter: settings.travelAlertPageUid)}"> + data-product-details-travel-alert-uri-value="{f:uri.typolink(parameter: settings.travelAlertPageUid)}" + data-product-details-daytrip-value="{product.daytrip -> f:format.json()}">
@@ -245,92 +246,40 @@ - diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Searchbar/Index.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Searchbar/Index.html index 8f2a08bb..cb1a39b3 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Searchbar/Index.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Searchbar/Index.html @@ -6,7 +6,7 @@