Remove obsolete js

This commit is contained in:
Björn Fromme
2021-07-28 17:09:35 +02:00
parent 60e69ae8b1
commit fad342147e
34 changed files with 316 additions and 2082 deletions
@@ -56,7 +56,7 @@ class AjaxCalendarController extends ActionController
* @param string $month
* @param int $months
*/
public function rangeAction(Hotel $hotel, $year = null, $month = null, $months = 6)
public function rangeAction(Hotel $hotel, $year = null, $month = null, $months = 1)
{
[ $begin, $end ] = DateUtility::getDateRange($year, $month, $months);
@@ -29,6 +29,8 @@ import productDetail from './components/product-detail'
import daytripDateSelect from './components/daytrip-date-select'
import searchBar from './components/search-bar'
import search from './components/search'
import calendar from './components/calendar'
import contactForm from './components/contact-form'
import defaultFilterSettings from './_filtersettings'
import defaultFilterOptions from './_filteroptions'
@@ -63,6 +65,8 @@ document.addEventListener('DOMContentLoaded', () => {
Alpine.data('daytripDateSelect', daytripDateSelect)
Alpine.data('searchBar', searchBar)
Alpine.data('search', search)
Alpine.data('calendar', calendar)
Alpine.data('contactForm', contactForm)
Alpine.start()
Glightbox({
@@ -70,64 +74,3 @@ document.addEventListener('DOMContentLoaded', () => {
slideEffect: 'fade',
})
})
/// LEGACY CODE FROM HERE ///
// Import dependencies
// import Vue from 'vue'
// import $ from 'jquery'
// import dayjs from 'dayjs'
// import 'dayjs/locale/de'
// global.$ = global.jQuery = $;
// require('bootstrap-sass/assets/javascripts/bootstrap/dropdown')
// require('bootstrap-sass/assets/javascripts/bootstrap/modal')
// require('bootstrap-sass/assets/javascripts/bootstrap/transition')
// Import components
// import SearchBar from './components/SearchBar.vue'
// import SearchBox from './components/SearchBox.vue'
//import ProductDetail from './components/ProductDetail.vue'
// import Calendar from './components/Calendar.vue'
// import EventPricetable from './components/EventPriceTable.vue'
// import ContactForm from './components/ContactForm.vue'
// import Watchlist from './components/Watchlist.vue'
// import HotelList from './components/HotelList.vue'
// Define date filter for vue templates
// Vue.filter('date', (value) => {
// return dayjs(value).format('DD.MM.YY');
// });
// Store
// import store from './store';
// Initialize vue app
// new Vue({
// el: '#app',
// store,
// components: {
// SearchBar,
// //SearchBox,
// //SearchResult: () => import('./components/SearchResult.vue'),
// //ProductDetail,
// //Calendar,
// //EventPricetable,
// //ContactForm,
// //Watchlist,
// //HotelList,
// //MyEp: () => import('./myep/App.vue'),
// //GroupsPriceCalculator: () => import('./components/GroupsPriceCalculator.vue'),
// },
// data () {
// return {
// maxWindowWidth: 991,
// mobileMode: false,
// }
// },
// created () {
// this.$store.dispatch('init');
// },
// });
@@ -1,43 +0,0 @@
<template>
<div class="boardtypeselect">
<div class="checkbox" v-for="boardType of boardTypesOptions">
<label>
<input type="checkbox" v-model.number="boardTypesSelected" :value="boardType.uid" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ boardType.label }}
</label>
</div>
</div>
</template>
<script>
export default {
data () {
return {
boardTypesSelected: this.boardTypes
}
},
props: {
boardTypesOptions: {
type: Array,
required: true
},
boardTypes: {
type: Array,
default () {
return [];
}
}
},
methods: {
notifySelected () {
this.$emit('selected', this.boardTypesSelected);
}
},
watch: {
boardTypes (value) {
this.boardTypesSelected = value;
}
}
}
</script>
@@ -1,46 +0,0 @@
<template>
<div class="busselect">
<template v-if="busAvailable">
<div class="checkbox">
<label>
<input type="checkbox" v-model="busSelected" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
Busanreise
</label>
</div>
</template>
<template v-else>
nicht verfügbar
</template>
</div>
</template>
<script>
export default {
data () {
return {
busSelected: this.bus
}
},
props: {
bus: {
type: Boolean,
default: false
},
busAvailable: {
type: Boolean,
default: false
}
},
methods: {
notifySelected () {
this.$emit('selected', this.busSelected);
}
},
watch: {
bus (value) {
this.busSelected = value;
}
}
}
</script>
@@ -1,115 +0,0 @@
<template>
<div class="row calendar" :class="{ 'calendar--single': isSingleCalendar }">
<div class="col-xs-12" v-if="showHeader">
<h2>Belegungskalender {{ hotelName }}</h2>
</div>
<div class="calendar__loading" v-show="loading">
<img :src="loaderUri" alt="Loading" title="Loading">
</div>
<div class="col-xs-12">
<select class="form-control calendar__select" v-model="selectedMonth" @change="loadCalendar">
<option v-for="option in selectableMonths" :value="option" :key="option.format('YYYY')+option.format('M')">
{{ option.format('MMMM YYYY') }}
</option>
</select>
</div>
<div class="calendar__inner" v-cloak v-html="calendarHtml"></div>
</div>
</template>
<script>
import Vue from 'vue'
import axios from 'axios'
import dayjs from 'dayjs'
import 'dayjs/locale/de'
dayjs.locale('de');
export default {
props: {
uri: {
type: String,
required: true
},
loaderUri: {
type: String,
required: true
},
argumentPrefix: {
type: String,
required: true
},
hotelName: {
type: String
},
hotelUid: {
type: String,
required: true
},
months: {
type: Number,
default: 6
},
step: {
type: Number,
default: 3
},
showHeader: {
type: Boolean,
default: true
}
},
data () {
return {
startDate: dayjs().startOf('month'),
selectedMonth: dayjs().startOf('month'),
calendarHtml: '',
loading: false
}
},
computed: {
isSingleCalendar () {
return parseInt(this.months) === 1;
},
selectableMonths() {
const months = [];
let month = this.startDate.month();
let year = this.startDate.year();
for (let i = 1; i <= 20; i++) {
months.push(dayjs().set('year', year).set('month', month));
if (month < 12) {
month++;
} else {
month = 1;
year++;
}
}
return months;
}
},
methods: {
loadCalendar () {
let query = {};
query[this.argumentPrefix + '[hotel]'] = this.hotelUid;
query[this.argumentPrefix + '[month]'] = this.selectedMonth.month() + 1;
query[this.argumentPrefix + '[year]'] = this.selectedMonth.year();
query[this.argumentPrefix + '[months]'] = this.months;
this.loading = true;
axios({
url: this.uri,
responseType: 'text',
params: query
}).then((response) => {
this.calendarHtml = response.data;
}).catch(() => {
}).finally(() => {
this.loading = false;
});
}
},
mounted () {
Vue.nextTick(() => {
this.loadCalendar();
this.selectedMonth = this.selectableMonths[0];
});
}
}
</script>
@@ -1,13 +0,0 @@
<template functional>
<div v-if="Object.keys(props.concepts).length > 1" class="hidden-xs conceptbtns">
<a v-for="concept of props.concepts"
:href="'#concept-' + concept.uid"
:class="'btn btn-warning ep-sidebar concept-' + concept.code"
:title="concept.name">{{ concept.name }}</a>
</div>
</template>
<script>
export default {
props: [ 'concepts' ],
}
</script>
@@ -1,43 +0,0 @@
<template>
<div class="conceptselect">
<div class="checkbox" v-for="concept of conceptOptions">
<label>
<input type="checkbox" v-model="conceptsSelected" :value="concept.uid" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
nur {{ concept.name }}
</label>
</div>
</div>
</template>
<script>
export default {
data () {
return {
conceptsSelected: this.concepts
}
},
props: {
conceptOptions: {
type: Object,
required: true
},
concepts: {
type: Array,
default () {
return [];
}
}
},
methods: {
notifySelected () {
this.$emit('selected', this.conceptsSelected);
}
},
watch: {
concepts (value) {
this.conceptsSelected = value;
}
}
}
</script>
@@ -1,47 +0,0 @@
<script>
import $ from 'jquery'
import EventBus from '../_bus'
export default {
data () {
return {
formErrors: {},
processing: false,
success: false,
error: false
}
},
methods: {
submitForm () {
let $form = $('#contactform');
this.processing = true;
$.ajax({
url: $form.attr('action'),
type: 'POST',
data: $form.serialize(),
dataType: 'json',
success: (response) => {
this.processing = false;
if (response.status === 'validation') {
this.formErrors = response.errors;
} else {
this.success = true;
}
EventBus.$emit('scrollTo', '#contactform');
},
error: () => {
this.processing = false;
this.error = true;
}
});
},
resetForm () {
this.formErrors = {};
this.processing = false;
this.success = false;
this.error = false;
$('#contactform').trigger('reset');
}
}
}
</script>
@@ -1,149 +0,0 @@
<template>
<div>
<label v-if="showLabel">Zeitraum</label>
<ul class="nav navbar-nav">
<li class="dropdown" ref="dropdown">
<input type="text" class="form-control" placeholder="von... bis"
:value="selectedRange" @click="togglePanel"/>
<ul class="dropdown-menu daterange">
<li v-if="presets">
<div class="daterange__presets">
<template v-for="preset of presets">
<a class="daterange__preset" href="#"
@click.prevent="selectPreset(preset)">
<i class="fa fa-calendar"></i> <span>{{ preset.label }}</span>
</a>
</template>
</div>
</li>
<li>
<div class="daterange__panel">
<input ref="field" type="hidden">
</div>
</li>
<li class="daterange__buttons">
<button class="daterange__button" @click.prevent="togglePanel">
<i class="fa fa-times"></i> schließen
</button>
<button class="daterange__button" @click.prevent="reset()">
<i class="fa fa-trash-o"></i> zurücksetzen
</button>
</li>
</ul>
</li>
</ul>
</div>
</template>
<script>
import Vue from 'vue'
import $ from 'jquery'
import dayjs from 'dayjs'
import 'dayjs/locale/de'
import flatpickr from 'flatpickr'
import { German } from 'flatpickr/dist/l10n/de'
import EventBus from '../_bus'
export default {
data () {
return {
picker: null,
selectedFrom: this.from,
selectedTo: this.to
}
},
props: {
from: {
type: String,
default: null
},
to: {
type: String,
default: null
},
minDate: {
type: String,
default: null
},
maxDate: {
type: String,
default: null
},
showLabel: {
type: Boolean,
default: true
},
presets: {
type: Object,
default () {
return {};
}
}
},
watch: {
minDate (date) {
this.picker.set('minDate', new Date(date))
},
maxDate (date) {
this.picker.set('maxDate', new Date(date))
}
},
mounted () {
Vue.nextTick(() => {
this.picker = $(this.$refs.field).flatpickr({
mode: 'range',
dateFormat: 'd.m.Y',
locale: German,
inline: true,
onChange: (selectedDates) => {
if (selectedDates.length === 2) {
this.selectedFrom = selectedDates[0];
this.selectedTo = selectedDates[1];
this.togglePanel();
this.$emit('selected', { from: this.selectedFrom, to: this.selectedTo });
}
}
});
if (this.from && this.to) {
this.picker.setDate([ new Date(this.from), new Date(this.to) ]);
}
if (this.minDate && this.maxDate) {
this.picker.set('minDate', new Date(this.minDate));
this.picker.set('maxDate', new Date(this.maxDate));
}
});
EventBus.$on('filterSettingsReset', () => {
this.reset();
});
},
computed: {
selectedRange () {
if (this.selectedFrom == null && this.selectedTo == null) {
return '';
}
return dayjs(this.selectedFrom).format('DD.MM.YYYY')
+ '-' + dayjs(this.selectedTo).format('DD.MM.YYYY');
}
},
methods: {
togglePanel () {
$(this.$refs.dropdown).toggleClass('open');
},
selectPreset (preset) {
this.selectedFrom = new Date(preset.dateFrom);
this.selectedTo = new Date(preset.dateTo);
this.picker.setDate([ this.selectedFrom, this.selectedTo ]);
this.togglePanel();
this.$emit('selected', { from: this.selectedFrom, to: this.selectedTo });
},
reset () {
this.selectedFrom = null;
this.selectedTo = null;
this.picker.clear();
this.picker.jumpToDate();
this.togglePanel();
this.$emit('selected', { from: this.selectedFrom, to: this.selectedTo });
}
}
}
</script>
@@ -1,139 +0,0 @@
<template>
<div class="destinationselect" :class="{ 'loading': loading }">
<label v-if="showLabel" for="destination" class="destinationselect__label">Finde</label>
<ul class="nav navbar-nav">
<li class="dropdown" :class="{ open: opened }">
<input type="text" id="destination" class="form-control destinationselect__input"
v-model="destination"
@keyup="autocomplete"
@click="toggleOptions"
placeholder="Ort, Gebiet, Land...">
<ul ref="itemlist" class="dropdown-menu" aria-labelledby="destination" v-show="showAutocompleteOptions">
<template v-for="(section, type) of autocompleteOptions">
<template v-if="section.options.length">
<li class="dropdown-header destinationselect__group" :class="type">{{ section.label }}</li>
<li class="destinationselect__item" v-for="option of section.options">
<a href="#" @click.prevent="optionSelect(option, type)">{{ option.name }}</a>
</li>
<li role="separator" class="divider destinationselect__divider"></li>
</template>
</template>
</ul>
</li>
</ul>
</div>
</template>
<script>
import $ from 'jquery'
import axios from 'axios'
export default {
props: {
ajaxUri: {
type: String,
required: true
},
argumentPrefix: {
type: String,
required: true
},
initialFilterSettings: {
type: Object,
required: true
},
showLabel: {
type: Boolean,
default: true
}
},
data () {
return {
filterSettings: this.initialFilterSettings,
destination: '',
destinationUid: 0,
destinationType: '',
autocompleteOptions: {},
opened: false,
loading: false,
showAutocompleteOptions: false
}
},
methods: {
autocomplete () {
if (this.destination.length === 0) {
this.showAutocompleteOptions = false;
this.autocompleteOptions = {};
this.$emit('reset');
return;
}
if (this.destination.length < 3) {
return;
}
this.loading = true;
this.filterSettings.destinationName = this.destination;
let query = {};
query[this.argumentPrefix + '[filterSettings]'] = this.filterSettings;
query[this.argumentPrefix + '[search]'] = this.destination;
axios({
url: this.ajaxUri,
method: 'post',
data: $.param(query)
}).then((response) => {
this.autocompleteOptions = response.data;
this.showAutocompleteOptions = this.hasOptions();
if (this.showAutocompleteOptions) {
this.openDropdown();
}
this.loading = false;
}).catch(() => {
this.loading = false;
});
},
toggleOptions () {
if (!this.hasOptions()) {
this.showAutocompleteOptions = false;
return;
}
this.opened = !this.opened;
},
hasOptions () {
let hasOptions = false;
$.each(this.autocompleteOptions, (type, data) => {
if (data.options.length > 0) {
hasOptions = true;
return false;
}
});
return hasOptions;
},
openDropdown () {
this.opened = true;
},
closeDropdown () {
this.opened = false;
},
optionSelect (option, type) {
this.destination = option.name;
this.filterSettings.destinationName = this.destination;
this.$emit('selected', { uid: option.uid, type: type, name: option.name });
this.closeDropdown();
},
onFilterSettingsChange (filterSettings) {
this.destination = filterSettings.destinationName;
this.autocompleteOptions = {};
}
},
watch: {
'initialFilterSettings': {
deep: true,
handler: 'onFilterSettingsChange'
}
},
mounted () {
if (this.initialFilterSettings.destinationName) {
this.destination = this.initialFilterSettings.destinationName;
}
}
}
</script>
@@ -1,76 +0,0 @@
<template>
<div class="destinationselect">
<div class="destinationselect__section" v-for="(destination, uid) of selectableDestinations">
<div class="checkbox">
<label>
<input type="checkbox" v-model.number="countryUidsSelected" :value="uid" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
<strong>{{ destination.country.label }}</strong>
</label>
</div>
<div class="checkbox" v-for="region of destination.regions">
<label>
<input type="checkbox" v-model.number="regionUidsSelected" :value="region.uid" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
<span class="small">{{ region.label }}</span>
</label>
</div>
</div>
</div>
</template>
<script>
export default {
computed: {
showRegions () {
return this.selectableRegions !== null;
}
},
data () {
return {
countryUidsSelected: this.countryUids,
regionUidsSelected: this.regionUids
}
},
props: {
selectableDestinations: {
type: Object,
required: true
},
countryUids: {
type: Array,
default () {
return [];
}
},
regionUids: {
type: Array,
default () {
return [];
}
}
},
methods: {
notifySelected () {
this.$emit('selected', {
countryUids: this.countryUidsSelected,
regionUids: this.regionUidsSelected
});
}
},
watch: {
countryUids (value) {
this.countryUidsSelected = value;
},
regionUids (value) {
this.regionUidsSelected = value;
}
}
}
</script>
<style>
.destinationselect__section {
padding-bottom: 8px;
}
</style>
@@ -1,93 +0,0 @@
<template>
<div class="destinationselect">
<label v-if="showLabel" class="destinationselect__label">Reiseziel</label>
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">{{ destinationName }} <span class="glyphicon glyphicon-menu-down"></span></a>
<ul class="dropdown-menu destination-pulldown">
<li class="destination-pulldown__section"
v-if="destinationOptions && !conceptSelected"
v-for="destination of destinationOptions">
<div class="destination-pulldown__column">
<a href="#" @click.prevent="optionSelect(destination.country.uid, destination.country.label, 'country')">
<img class="destination-pulldown__flag" :src="destination.country.flag" alt="">
<strong>{{ destination.country.label }}</strong>
</a>
</div>
<div class="destination-pulldown__column">
<ul class="plain-list">
<li v-for="region of destination.regions">
<a href="#" @click.prevent="optionSelect(region.uid, region.label, 'region')">{{ region.label }}</a>
</li>
</ul>
</div>
</li>
<li class="destination-pulldown__section" v-if="conceptOptions && !destinationSelected">
<div class="destination-pulldown__column"><strong>Konzept</strong></div>
<div class="destination-pulldown__column">
<ul class="plain-list">
<li v-for="concept of conceptOptions">
<a href="#" @click.prevent="conceptSelect(concept.uid, concept.name)">{{ concept.name }}</a>
</li>
</ul>
</div>
</li>
<li class="destination-pulldown__section" v-if="destinationSelected || conceptSelected">
<button class="destination-pulldown__reset"
@click.prevent="optionReset">
<i class="fa fa-trash-o"></i>
zurücksetzen
</button>
</li>
</ul>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
showLabel: {
type: Boolean,
default: true
},
destinationOptions: {
type: Object,
required: true
},
conceptOptions: {
type: Object,
required: true
}
},
data () {
return {
destinationName: 'beliebig',
destinationSelected: false,
conceptSelected: false,
}
},
methods: {
optionReset () {
this.destinationName = 'beliebig';
this.destinationSelected = false;
this.conceptSelected = false;
this.$emit('reset');
},
optionSelect (uid, name, type) {
this.destinationName = name;
this.destinationSelected = true;
this.conceptSelected = false;
this.$emit('selected', { uid: uid, type: type, name: name });
},
conceptSelect (uid, name) {
this.destinationName = name;
this.destinationSelected = false;
this.conceptSelected = true;
this.$emit('selected', { uid: uid, type: 'concept', name: name });
}
}
}
</script>
@@ -1,94 +0,0 @@
<template>
<div class="row">
<div class="col-xs-12">
<h2>Buchungsoptionen</h2>
<div id="partnerselect" v-if="forcePartneridSelect" class="alert alert-info" :class="{ 'alert-danger': showAlert }">
<div class="row">
<div class="col-xs-12">
<p>{{ label }}</p>
<select v-model="partnerId" @change="onPartnerSelect">
<option value="">Bitte auswählen...</option>
<template v-for="partner in partnerIds">
<option :value="partner.id">{{ partner.label }}</option>
</template>
</select>
</div>
</div>
</div>
<div ref="table">
<div class="ajax-content-wrapper" x-data="ajaxContent(uri)">
<div class="ajax-content" x-ref="container"></div>
<div x-ref="trigger">
<img :src="loaderUri" alt="Loading" title="Loading">
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import $ from 'jquery'
import EventBus from '../_bus'
export default {
props: {
uri: {
type: String,
required: true
},
loaderUri: {
type: String,
required: true,
},
forcePartneridSelect: {
required: true
},
partnerIds: {
type: Array,
default: []
},
label: {
type: String,
required: true
}
},
data () {
return {
partnerId: '',
showAlert: false
}
},
methods: {
onPartnerSelect () {
if (this.partnerId) {
this.showAlert = false;
}
},
onBookingLinkClick (e) {
e.preventDefault();
if (!this.partnerId) {
this.showAlert = true;
EventBus.$emit('scrollTo', '#partnerselect');
} else {
this.showAlert = false;
let $link = $(e.target);
window.open($link.attr('href') + '&agenturcode=' + this.partnerId, '_blank');
}
},
registerClickHandler () {
const handleClickEvent = this.onBookingLinkClick;
$(this.$refs.table).on('click', '.booking-link', function (e) {
handleClickEvent(e);
});
}
},
mounted () {
if (this.forcePartneridSelect) {
Vue.nextTick(() => {
this.registerClickHandler();
});
}
}
}
</script>
@@ -114,7 +114,6 @@
</template>
<script>
import $ from 'jquery';
import dayjs from 'dayjs'
import 'dayjs/locale/de'
import 'flatpickr';
@@ -172,16 +171,16 @@
},
formatOptionPriceType (option) {
if (2 === option.type) {
return ' ('+this.formatCurrency(option.price)+' pro Person)';
return ` (${this.formatCurrency(option.price)} pro Person)`
}
if (3 === option.type) {
return ' ('+this.formatCurrency(option.price)+' pro Nacht)';
return ` (${this.formatCurrency(option.price)} pro Nacht)`
}
if (4 === option.type) {
return ' ('+this.formatCurrency(option.price)+' pro Person und Nacht)';
return ` (${this.formatCurrency(option.price)} pro Person und Nacht)`
}
return ' ('+this.formatCurrency(option.price)+')';
return ` (${this.formatCurrency(option.price)})`
},
initSelectableRanges () {
let enabledDates = [];
@@ -218,34 +217,31 @@
for (let option of this.selectedOptions) {
options.push(option.uid);
}
let formData = {
'tx_epproducts_ajax[groupsPriceInquiry][name]': this.name,
'tx_epproducts_ajax[groupsPriceInquiry][email]': this.email,
'tx_epproducts_ajax[groupsPriceInquiry][phone]': this.phone,
'tx_epproducts_ajax[groupsPriceInquiry][remarks]': this.remarks,
'tx_epproducts_ajax[groupsPriceInquiry][dateFrom]': this.selectedFrom.format('DD.MM.YYYY'),
'tx_epproducts_ajax[groupsPriceInquiry][dateTo]': this.selectedTo.format('DD.MM.YYYY'),
'tx_epproducts_ajax[groupsPriceInquiry][pax]': this.selectedPax,
'tx_epproducts_ajax[groupsPriceInquiry][board]': this.selectedBoard ? this.selectedBoard.uid : null,
'tx_epproducts_ajax[groupsPriceInquiry][options]': options,
'tx_epproducts_ajax[groupsPriceInquiry][summary]': this.priceSummary
};
let formData = new FormData()
formData.set('tx_epproducts_ajax[groupsPriceInquiry][name]', this.name)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][email]', this.email)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][phone]', this.phone)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][remarks]', this.remarks)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][dateFrom]', this.selectedFrom.format('DD.MM.YYYY'))
formData.set('tx_epproducts_ajax[groupsPriceInquiry][dateTo]', this.selectedTo.format('DD.MM.YYYY'))
formData.set('tx_epproducts_ajax[groupsPriceInquiry][pax]', this.selectedPax)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][board]', this.selectedBoard ? this.selectedBoard.uid : null)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][options]', options)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][summary]', this.priceSummary)
this.processing = true;
this.submitted = false;
axios({
url: this.endpoint,
method: 'POST',
data: $.param(formData)
}).then(response => {
if ('validation' === response.data.status) {
this.formErrors = response.data.errors;
} else {
this.submitted = true;
}
}).catch(error => {
}).finally(() => {
this.processing = false;
});
axios.post(this.endpoint, formData)
.then(response => {
if ('validation' === response.data.status) {
this.formErrors = response.data.errors;
} else {
this.submitted = true;
}
})
.catch(error => {})
.finally(() => {
this.processing = false;
});
}
},
computed: {
@@ -334,7 +330,7 @@
},
mounted () {
Vue.nextTick(() => {
this.picker = $(this.$refs.picker).flatpickr({
this.picker = flatpickr(this.$refs.picker, {
mode: 'range',
dateFormat: 'd.m.Y',
locale: German,
@@ -1,26 +0,0 @@
<script>
import defaultFilterSettings from '../_filtersettings'
export default {
props: {
referringPageUrl: {
type: String,
required: true
},
referringPage: {
type: Object,
default: null
}
},
data () {
return {
filterSettings: defaultFilterSettings
}
},
created () {
if (sessionStorage.getItem('filterSettings')) {
this.filterSettings = JSON.parse(sessionStorage.getItem('filterSettings'));
}
}
}
</script>
@@ -1,50 +0,0 @@
<template>
<div class="hoteltypeselect">
<div class="checkbox" v-for="hotelTypesOption of hotelTypesOptions">
<label>
<input type="checkbox" v-model.number="hotelTypesSelected" :value="hotelTypesOption" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ hotelTypesLabels[hotelTypesOption] }}
</label>
</div>
</div>
</template>
<script>
export default {
data () {
return {
hotelTypesLabels: {
1: 'Ferienwohnung',
2: 'Sportclub',
3: 'Appartment',
4: 'Gästehaus',
5: 'Pension'
},
hotelTypesSelected: this.hotelTypes
}
},
props: {
hotelTypesOptions: {
type: Array,
required: true
},
hotelTypes: {
type: Array,
default () {
return [];
}
}
},
methods: {
notifySelected () {
this.$emit('selected', this.hotelTypesSelected);
}
},
watch: {
hotelTypes (value) {
this.hotelTypesSelected = value;
}
}
}
</script>
@@ -1,71 +0,0 @@
<template>
<div class="form-group">
<label v-if="showLabel">Dauer</label>
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">
{{ selectedOption }} <span class="glyphicon glyphicon-menu-down"></span>
</a>
<ul class="dropdown-menu nights">
<li><a href="#" @click.prevent="optionReset">beliebig</a></li>
<li v-for="nightsOption of nightsOptions">
<a href="#" @click.prevent="optionSelect(nightsOption)">
{{ durationTypes[nightsOption] }} Übernachtungen
</a>
</li>
</ul>
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
durationTypes: {
4: '1 - 4',
5: '5 oder mehr'
},
nightsSelected: this.nights
}
},
props: {
nightsOptions: {
type: Array,
required: true
},
nights: {
default: 0
},
showLabel: {
type: Boolean,
default: true
}
},
computed: {
selectedOption () {
if (this.nightsSelected == 0) {
return 'beliebig';
}
return this.durationTypes[this.nightsSelected] + ' ÜN';
}
},
methods: {
optionReset () {
this.nightsSelected = 0;
this.$emit('selected', 0);
},
optionSelect (value) {
this.nightsSelected = value;
this.$emit('selected', value);
}
},
watch: {
nights (value) {
this.nightsSelected = value;
}
}
}
</script>
@@ -1,56 +0,0 @@
<template>
<div class="form-group">
<label v-if="showLabel">Personen</label>
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">
{{ pax }} <span class="glyphicon glyphicon-menu-down"></span>
</a>
<ul class="dropdown-menu pax">
<li v-for="paxOption of paxOptions">
<a href="#" @click.prevent="optionSelect(paxOption)">{{ paxOption }}</a>
</li>
<li v-if="groupsUri"><a :href="groupsUri">&gt; 20</a></li>
</ul>
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
paxSelected: this.pax
}
},
props: {
paxOptions: {
type: Array,
required: true
},
pax: {
default: 1
},
showLabel: {
type: Boolean,
default: true
},
groupsUri: {
type: String
}
},
methods: {
optionSelect (value) {
this.paxSelected = value;
this.$emit('selected', value);
}
},
watch: {
pax (value) {
this.paxSelected = value;
}
}
}
</script>
@@ -1,78 +0,0 @@
<template>
<div class="form-group">
<label v-if="showLabel">Preis</label>
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">
{{ rangeLabel }} <span class="glyphicon glyphicon-menu-down"></span>
</a>
<ul class="dropdown-menu price-range">
<li><a href="#" @click.prevent="optionReset()">beliebig</a></li>
<li v-for="(range, index) in rangeOptions">
<a href="#" @click.prevent="optionSelect(index)">{{ formatRange(range) }} </a>
</li>
</ul>
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
rangeSelected: this.range
}
},
props: {
rangeOptions: {
type: Object,
required: true
},
range: {
type: Number,
default: 0
},
showLabel: {
type: Boolean,
default: true
}
},
computed: {
rangeLabel () {
if (this.rangeSelected === 0 || $.isEmptyObject(this.rangeOptions)) {
return 'beliebig';
}
let range = this.rangeOptions[this.rangeSelected];
return this.formatRange(range);
}
},
methods: {
formatRange (range) {
let min = range[0];
let max = range[1];
if (min === 1) {
return 'bis ' + max;
}
if (max === 999) {
return 'ab ' + min;
}
return min + ' - ' + max;
},
optionReset () {
this.rangeSelected = 0;
this.$emit('selected', 0);
},
optionSelect (value) {
this.rangeSelected = parseInt(value);
this.$emit('selected', parseInt(value));
}
},
watch: {
range (value) {
this.rangeSelected = value;
}
}
}
</script>
@@ -1,51 +0,0 @@
<template>
<div class="roomtypeselect">
<div class="checkbox" v-for="roomTypesOption of roomTypesOptions">
<label>
<input type="checkbox" v-model.number="roomTypesSelected" :value="roomTypesOption" @change="notifySelected">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ roomTypesLabels[roomTypesOption] }}
</label>
</div>
</div>
</template>
<script>
export default {
data () {
return {
roomTypesLabels: {
1: 'EZ',
2: 'DZ / 2er',
3: '3er',
4: '4er',
5: 'ab 5 Pers.',
6: 'mit anderen'
},
roomTypesSelected: this.roomTypes
}
},
props: {
roomTypesOptions: {
type: Array,
required: true
},
roomTypes: {
type: Array,
default () {
return [];
}
}
},
methods: {
notifySelected () {
this.$emit('selected', this.roomTypesSelected);
}
},
watch: {
roomTypes (value) {
this.roomTypesSelected = value;
}
}
}
</script>
@@ -1,82 +0,0 @@
<script>
import axios from 'axios'
import DaterangeSelect from './DaterangeSelect.vue'
import DestinationSelect from './DestinationSelect.vue'
import PaxSelect from './PaxSelect.vue'
import PriceRangeSelect from './PriceRangeSelect.vue'
import dayjs from 'dayjs'
import 'dayjs/locale/de'
export default {
components: {
DaterangeSelect,
DestinationSelect,
PaxSelect,
PriceRangeSelect
},
data () {
return {
searchParams: this.initialSearchParams,
filterOptions: this.initialFilterOptions
}
},
props: [ 'initialFilterOptions', 'initialSearchParams', 'optionsUri', 'resetUri', 'argumentPrefix', 'datePresets' ],
methods: {
loadOptions () {
const query = {};
query[this.argumentPrefix + '[searchParams]'] = this.searchParams;
axios({
url: this.optionsUri,
method: 'post',
data: $.param(query)
}).then((response) => {
this.applyOptions(response.data);
});
},
applyOptions (json) {
this.filterOptions.totalResults = json.totalResults;
const filterOptions = json.filterOptions;
this.filterOptions.priceRanges = filterOptions.priceRanges;
this.filterOptions.pax = filterOptions.pax;
this.filterOptions.destinations = filterOptions.destinations;
if (filterOptions.dateFrom !== null) {
this.filterOptions.selectableRangeFrom = filterOptions.dateFrom;
}
if (filterOptions.dateTo !== null) {
this.filterOptions.selectableRangeTo = filterOptions.dateTo;
}
},
updateDateRange (range) {
this.searchParams.dateFrom = range.from ? dayjs(range.from).format('YYYY-MM-DD') : null;
this.searchParams.dateTo = range.to ? dayjs(range.to).format('YYYY-MM-DD') : null;
this.loadOptions();
},
updatePax (pax) {
this.searchParams.pax = pax;
this.loadOptions();
},
updatePriceRange (range) {
this.searchParams.priceRange = range;
this.loadOptions();
},
updateDestination (destination) {
if (destination.type === 'concept') {
this.searchParams.conceptUid = destination.uid;
} else {
this.searchParams.destinationUid = destination.uid;
this.searchParams.destinationType = destination.type;
}
this.loadOptions();
},
resetDestination () {
axios({
url: this.resetUri,
method: 'post'
}).then((response) => {
this.applyOptions(response.data);
this.searchParams = response.data.searchParams;
});
}
}
}
</script>
@@ -1,70 +0,0 @@
<script>
import $ from 'jquery'
import axios from 'axios'
import DestinationSelect from './DestinationSelect.vue'
import PriceRangeSelect from './PriceRangeSelect.vue'
export default {
components: {
DestinationSelect,
PriceRangeSelect
},
data () {
return {
searchParams: this.initialSearchParams,
filterOptions: this.initialFilterOptions
}
},
props: [ 'initialFilterOptions', 'initialSearchParams', 'optionsUri', 'resetUri', 'argumentPrefix', 'datePresets' ],
methods: {
loadOptions () {
const query = {};
query[this.argumentPrefix + '[searchParams]'] = this.searchParams;
axios({
url: this.optionsUri,
method: 'post',
data: $.param(query)
}).then((response) => {
this.applyOptions(response.data);
});
},
applyOptions (json) {
this.filterOptions.totalResults = json.totalResults;
const filterOptions = json.filterOptions;
this.filterOptions.nights = filterOptions.nights;
this.filterOptions.destinations = filterOptions.destinations;
if (filterOptions.dateFrom !== null) {
this.filterOptions.selectableRangeFrom = filterOptions.dateFrom;
}
if (filterOptions.dateTo !== null) {
this.filterOptions.selectableRangeTo = filterOptions.dateTo;
}
},
updateOptions () {
this.loadOptions();
},
updatePriceRange (range) {
this.searchParams.priceRange = range;
this.loadOptions();
},
updateDestination (destination) {
if (destination.type === 'concept') {
this.searchParams.conceptUid = destination.uid;
} else {
this.searchParams.destinationUid = destination.uid;
this.searchParams.destinationType = destination.type;
}
this.loadOptions();
},
resetDestination () {
axios({
url: this.resetUri,
method: 'post'
}).then((response) => {
this.applyOptions(response.data);
this.searchParams = response.data.searchParams;
});
}
}
};
</script>
@@ -1,214 +0,0 @@
<script>
import Vue from 'vue';
import $ from 'jquery'
import axios from 'axios'
import EventBus from '../_bus'
import DaterangeSelect from './DaterangeSelect.vue'
import DestinationCheckboxes from './DestinationCheckboxes.vue'
import DestinationAutocomplete from './DestinationAutocomplete.vue'
import ConceptSelect from './ConceptSelect.vue'
import ConceptButtons from './ConceptButtons.vue'
import PaxSelect from './PaxSelect.vue'
import PriceRangeSelect from './PriceRangeSelect.vue'
import HotelTypesSelect from './HotelTypesSelect.vue'
import BoardTypesSelect from './BoardTypesSelect.vue'
import RoomTypesSelect from './RoomTypesSelect.vue'
import BusSelect from './BusSelect.vue'
import SearchResultItem from './SearchResultItem.vue'
import dayjs from 'dayjs'
import 'dayjs/locale/de'
import defaultFilterSettings from '../_filtersettings'
import defaultFilterOptions from '../_filteroptions'
export default {
components: {
DaterangeSelect,
DestinationCheckboxes,
DestinationAutocomplete,
ConceptSelect,
ConceptButtons,
PaxSelect,
PriceRangeSelect,
HotelTypesSelect,
BoardTypesSelect,
RoomTypesSelect,
BusSelect,
SearchResultItem
},
data () {
return {
loading: false,
resultData: {},
resultMeta: null,
filterSettings: defaultFilterSettings,
referringPageUri: null,
filterOptions: defaultFilterOptions
}
},
props: {
resultsUri: {
type: String,
required: true
},
initialFilterSettings: {
type: Object,
default: null
},
argumentPrefix: {
type: String,
required: true
},
datePresets: {
type: Object,
default () {
return {};
}
}
},
computed: {
showRegions () {
return this.filterOptions.regions.length > 0;
},
resultInfo () {
let info = '';
if (this.loading) {
info = 'Suchergebnis wird geladen...';
}
if (this.resultMeta) {
info = 'Deine Suche ';
if (!this.resultMeta.organic) {
info += 'ergab leider keine genauen Treffer. Bitte benutze die Filter.';
return info;
}
if (this.resultMeta.destinationName) {
info += 'nach <b>' + this.resultMeta.destinationName + '</b> ';
}
if (this.resultMeta.dateRange) {
info += '<b>' + this.resultMeta.dateRange + '</b> ';
}
info += 'ergab ' + this.resultMeta.total + ' Treffer';
}
return info;
},
filterCount () {
let count = 0;
if (this.filterSettings.destinationUid) count++;
if (this.filterSettings.destinationName) count++;
if (this.filterSettings.countryUids.length > 0) count++;
if (this.filterSettings.regionUids.length > 0) count++;
if (this.filterSettings.cityUids.length > 0) count++;
if (this.filterSettings.conceptUids.length > 0) count++;
if (this.filterSettings.hotelTypes.length > 0) count++;
if (this.filterSettings.boardTypes.length > 0) count++;
if (this.filterSettings.roomTypes.length > 0) count++;
if (this.filterSettings.dateFrom !== null) count++;
if (this.filterSettings.dateTo !== null) count++;
if (this.filterSettings.priceRange > 0) count++;
if (this.filterSettings.bus) count++;
if (this.filterSettings.pax > 2) count++;
return count;
}
},
methods: {
loadResults () {
let query = {};
query[this.argumentPrefix + '[filterSettings]'] = this.filterSettings;
this.loading = true;
this.resultMeta = null;
axios({
url: this.resultsUri,
method: 'post',
data: $.param(query)
}).then(response => {
this.resultData = response.data.data;
this.filterOptions = response.data.filterOptions;
this.referringPageUri = response.data.referringPageUri;
this.resultMeta = response.data.meta;
this.loading = false;
EventBus.$emit('ajaxContentLoaded');
}).finally(() => {
this.loading = false;
});
},
resetFilterSettings () {
this.updateFilterSettings(defaultFilterSettings);
EventBus.$emit('filterSettingsReset');
},
updateDestination (destination) {
this.updateFilterSettings({
destinationUid: destination.uid,
destinationType: destination.type,
destinationName: destination.name
});
this.loadResults();
},
updateDestinations (destinations) {
this.updateFilterSettings({
countryUids: destinations.countryUids,
regionUids: destinations.regionUids
});
this.loadResults();
},
updateConcepts (conceptUids) {
this.updateFilterSettings({ conceptUids: conceptUids });
this.loadResults();
},
updateDateRange (range) {
const dateFrom = (range.from !== null) ? dayjs(range.from).format('YYYY-MM-DD') : null;
const dateTo = (range.to !== null) ? dayjs(range.to).format('YYYY-MM-DD') : null;
this.updateFilterSettings({ dateFrom: dateFrom, dateTo: dateTo });
this.loadResults();
},
updateDateSelectMobile () {
let dateFrom = this.filterSettings.dateFrom;
let dateTo = this.filterSettings.dateTo;
if (dateFrom === '') {
dateFrom = null;
}
if (dateTo === '') {
dateTo = null;
}
this.updateFilterSettings({ dateFrom: dateFrom, dateTo: dateTo });
this.loadResults();
},
updatePriceRange (range) {
this.updateFilterSettings({ priceRange: range });
this.loadResults();
},
updatePax (pax) {
this.updateFilterSettings({ pax: pax });
this.loadResults();
},
updateHotelTypes (hotelTypes) {
this.updateFilterSettings({ hotelTypes: hotelTypes });
this.loadResults();
},
updateBoardTypes (boardTypes) {
this.updateFilterSettings({ boardTypes: boardTypes });
this.loadResults();
},
updateRoomTypes (roomTypes) {
this.updateFilterSettings({ roomTypes: roomTypes });
this.loadResults();
},
updateBus (bus) {
this.updateFilterSettings({ bus: bus });
this.loadResults();
},
updateFilterSettings (settings) {
this.filterSettings = { ...this.filterSettings, ...settings };
}
},
created () {
if (!$.isEmptyObject(this.initialFilterSettings)) {
this.updateFilterSettings(this.initialFilterSettings)
}
},
mounted () {
Vue.nextTick(() => {
this.loadResults();
});
}
}
</script>
@@ -1,134 +0,0 @@
<template>
<div class="teaserbox teaserbox--landscape teaserbox--searchresult searchresult-item">
<div class="teaserbox__image">
<img class="teaserbox__flag" :src="item.country.flag" :alt="item.country.name"/>
<a :href="url" rel="nofollow" title="Details &amp; Buchen">
<picture class="searchresult-item__image">
<source media="(min-width: 1201px)" :data-srcset="item.hotel.images.resized.m[0].url + ' 260w'"/>
<source media="(max-width: 1200px)" :data-srcset="item.hotel.images.resized.l[0].url + ' 280w'"/>
<source media="(max-width: 768px)" :data-srcset="item.hotel.images.resized.s[0].url + ' 220w'"/>
<img class="scale lazyload" :data-src="item.hotel.images.resized.s[0].url"
:title="item.hotel.images.resized.s[0].title"
:alt="item.hotel.images.resized.s[0].alt">
</picture>
</a>
<div class="concept-badge" :id="section.concept.code"
:class=" 'concept-badge--' + section.concept.code">{{ section.concept.name }}</div>
</div>
<div class="teaserbox__main">
<div class="teaserbox__header">
<span class="searchresult-item__headline">
{{ item.region.name }}
<strong v-if="section.concept.code === 'evt'"><br>{{ item.product.name }}</strong>
</span>
<span class="searchresult-item__subline">{{ item.hotel.name }}</span>
<span class="searchresult-item__category" v-if="item.hotel.category">Kategorie {{ item.hotel.category }}</span>
</div>
<ul class="check-list searchresult-item__checklist">
<li v-if="item.hotel.fact">{{ item.hotel.fact }}</li>
<li v-if="item.product.fact">{{ item.product.fact }}</li>
<template v-if="item.region.feature">
<li>{{ item.region.feature }}</li>
</template>
<template v-else>
<li v-if="item.region.fact">{{ item.region.fact }}</li>
</template>
</ul>
<ul class="check-list check-list--inverted searchresult-item__featurelist">
<li>Skipass</li>
<li v-if="item.board">{{ item.board }}</li>
<li v-if="item.product.feature">{{ item.product.feature }}</li>
</ul>
</div>
<div class="teaserbox__aside">
<div class="teaserbox__aside__top">
<span class="searchresult-item__label">{{ item.dates.length > 1 ? 'Zeitraum' : 'Termin' }}</span>
<span class="searchresult-item__daterange">{{ dateRange }}</span>
<a :href="url" rel="nofollow" title="Details &amp; Buchen"
v-if="item.dates.length && !item.daytrip">
<span class="searchresult-item__daterange">
<i class="fa fa-arrow-circle-right"></i> {{ item.dates.length }} Termin{{ item.dates.length > 1 ? 'e' : '' }}
</span>
</a>
<hr>
<span class="searchresult-item__label">{{ item.daytrip ? 'Tageweise buchbar' : nightsOptions }}</span>
</div>
<div class="teaserbox__aside__bottom">
<span class="searchresult-item__price">ab {{ item.minPrice }} </span>
<a :href="url" class="button button--full searchresult-item__button"
rel="nofollow" title="Details">
Details<template v-if="!item.hideBookingButton"> &amp; Buchen</template>
</a>
</div>
</div>
<a href="#" x-data="watchlistToggle(item.key))" x-bind="trigger">
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
<i class="fa fa-plus-circle" x-bind:class="icon"></i>
</span>
</a>
</div>
</template>
<script>
import dayjs from 'dayjs'
import 'dayjs/locale/de'
export default {
props: {
item: {
type: Object,
required: true
},
section: {
type: Object,
required: true
},
referringPageUri: {
type: String,
default: null
}
},
computed: {
url () {
let url = this.item.detailPageUri;
if (this.referringPageUri) {
url += '?ref=' + this.referringPageUri;
}
return url;
},
nightsOptions () {
const nights = this.item.nights;
if (nights === null) {
return '';
}
nights.sort();
const optionsCount = nights.length;
const lastOption = nights.pop();
let output = '';
if (optionsCount > 2) {
output += nights.join(',') + ' oder ' + lastOption;
} else if (optionsCount === 2) {
output += nights.shift() + ' oder ' + lastOption;
} else {
output = lastOption;
}
output += lastOption > 1 ? ' Nächte' : ' Nacht';
return output;
},
dateRange () {
const dateFrom = this.item.minDateStart;
const dateTo = this.item.maxDateEnd;
if (dateFrom === null && dateTo === null) {
return '';
}
if (dateFrom !== null && dateTo === null) {
return 'ab ' + dayjs(dateFrom).format('DD.MM.YYYY');
}
if (dateFrom === null && dateTo !== null) {
return '- ' + dayjs(dateTo).format('DD.MM.YYYY');
}
return dayjs(dateFrom).format('DD.MM.YYYY') + ' - ' + dayjs(dateTo).format('DD.MM.YYYY');
}
}
}
</script>
@@ -1,102 +0,0 @@
<template>
<div class="watchlist">
<template v-for="section in teasers">
<h2 class="headline headline--secondary headline--underlined">{{ section.concept.name }}</h2>
<div class="searchresult-section" :class="'searchresult-section--' + section.concept.code">
<search-result-item
v-for="item in section.items"
:key="item.key"
:item="item"
:section="section"
:referring-page="referringPage"></search-result-item>
</div>
</template>
<div class="alert alert-info" v-if="total === 0">
Deine Merkliste ist aktuell leer...
</div>
<div v-show="loading" class="loader">
<img :src="loaderUri" alt="Loading...">
</div>
</div>
</template>
<script>
import Vue from 'vue'
import axios from 'axios'
import EventBus from '../_bus'
import SearchResultItem from './SearchResultItem.vue'
export default {
components: {
SearchResultItem
},
props: {
watchlistUri: {
type: String,
required: true
},
loaderUri: {
type: String,
required: true
},
referringPageUrl: {
type: String,
default: null
}
},
data () {
return {
teasers: {},
total: 0,
loading: false,
referringPage: {
url: this.referringPageUrl,
label: 'zurück zur Merkliste'
}
}
},
methods: {
loadList () {
if (this.watchlist.length === 0) {
this.teasers = {};
this.total = 0;
return;
}
let query = {};
query['tx_epproducts_ajax[watchlistUids]'] = this.watchlist;
this.loading = true;
axios({
url: this.watchlistUri,
headers: {
'Accept': 'application/json'
},
data: $.param(query),
method: 'post'
}).then((response) => {
this.teasers = response.data.data;
this.total = response.data.total;
this.loading = false;
EventBus.$emit('ajaxContentLoaded');
}).catch(() => {
this.loading = false;
});
}
},
computed: {
watchlist() {
const initialList = JSON.parse(sessionStorage.getItem('myep-watchlist'))
return initialList ? initialList : []
},
},
created () {
EventBus.$on('oggle', () => {
this.loadList();
});
},
mounted () {
Vue.nextTick(() => {
this.loadList();
})
}
}
</script>
@@ -7,13 +7,13 @@ export default uri => ({
loading: false,
init() {
window.addEventListener('scroll', debounce(() => {
if (true === this.loaded) {
return
}
this.load()
}, 250))
},
load() {
if (true === this.loaded) {
return
}
if (false === this.inViewport()) {
return
}
@@ -0,0 +1,42 @@
import axios from 'axios'
export default uri => ({
loading: false,
selectedIndex: null,
selectableMonths: [],
calendarWrapper: null,
init() {
this.calendarWrapper = this.$refs.calendarWrapper
let months = []
let today = new Date()
let year = today.getFullYear()
let month = today.getMonth()
for (let i = 0; i < 20; i++) {
months.push(new Date(year, month, 1))
if (month < 12) {
month++
} else {
month = 1
year++
}
}
this.selectableMonths = months
this.selectedIndex = 0
this.load()
},
load() {
this.loading = true
let selectedMonth = this.selectableMonths[this.selectedIndex]
let data = new URLSearchParams({
'tx_epproducts_ajax[month]': selectedMonth.getMonth(),
'tx_epproducts_ajax[year]': selectedMonth.getYear(),
})
axios.post(uri, data)
.then(response => (
this.calendarWrapper.innerHTML = response.data
))
.finally(() => {
this.loading = false
})
}
})
@@ -0,0 +1,35 @@
import axios from 'axios'
export default () => ({
formErrors: {},
processing: false,
success: false,
error: false,
submit() {
this.processing = true
const form = this.$refs.form
const data = new FormData(form)
axios.post(form.action, data)
.then(response => {
if (response.data.status === 'validation') {
this.formErrors = response.data.errors
} else {
this.success = true
}
})
.catch(e => {
this.error = true
})
.finally(() => {
this.processing = false
this.$el.scrollIntoView({behavior: 'smooth'})
})
},
reset() {
this.formErrors = {}
this.processing = false
this.success = false
this.error = false
this.$refs.form.reset()
}
})
@@ -1,20 +1,29 @@
<html data-namespace-typo3-fluid="true" lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
<f:layout name="Default"/>
<f:section name="Main">
<div class="container">
<calendar
uri="{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: data.tx_eptheme_context_hotel}', format: 'html')}"
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
hotel-uid="{hotel.0.data.uid}"
hotel-name="{hotel.0.data.name}"
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax', extensionName: 'epproducts')}"
></calendar>
<div class="row calendar calandar--single"
x-data='calendar("<f:format.raw>{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: data.tx_eptheme_context_hotel}', format: 'html')}</f:format.raw>")'>
<div class="col-xs-12">
<h2>Belegungskalender {hotel.0.data.name}</h2>
</div>
<div class="col-xs-12">
<select class="form-control calendar__select" x-model="selectedIndex" x-on:change="load">
<template x-for="(month, index) in selectableMonths">
<option x-bind:value="index" x-text="month.toLocaleDateString('de-DE', {year: 'numeric', month: 'long'})"></option>
</template>
</select>
</div>
<div class="calendar__inner" x-cloak x-ref="calendarWrapper"></div>
<div class="absolute top-0 left-0 inset-0 w-full h-full bg-overlay-white" x-show="loading">
<f:image class="absolute top-1/2 left-1/2 -translate-xy-1/2" src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
</div>
</div>
</div>
</f:section>
@@ -5,104 +5,102 @@
<f:layout name="Form/Default"/>
<f:section name="Main">
<contact-form inline-template>
<div class="relative">
<f:form id="contactform" object="{contactForm}" name="contactForm"
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
pageUid="{settings.defaultAjaxUid}"
additionalAttributes="{'v-show': '!success', '@submit.prevent': 'submitForm()'}">
<f:form.hidden property="pageUrl"/>
<label class="block mb-4 hidden">
<span class="text-gray-700">Betreff*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.name }">
<span :class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
<div class="text-red-500 mt-2" v-show="formErrors.name" v-html="formErrors.name"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.firstName }">
<span :class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
<div class="text-red-500 mt-2" v-show="formErrors.firstName" v-html="formErrors.firstName"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.gender }">
<span :class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
<div class="text-red-500 mt-2" v-show="formErrors.gender" v-html="formErrors.gender"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.company }">
<span :class="formErrors.company ? 'text-red-500' : 'text-gray-700'">Firma/Verein*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="company"/>
<div class="text-red-500 mt-2" v-show="formErrors.company" v-html="formErrors.company"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.email }">
<span :class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
<div class="text-red-500 mt-2" v-show="formErrors.email" v-html="formErrors.email"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.phone }">
<span :class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
<div class="text-red-500 mt-2" v-show="formErrors.phone" v-html="formErrors.phone"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.period }">
<span :class="formErrors.period ? 'text-red-500' : 'text-gray-700'">Zeitraum</span>
<f:form.textfield class="form-input mt-1 block w-full" property="period" placeholder="tt.mm.jjjj - tt.mm.jjjj"/>
<div class="text-red-500 mt-2" v-show="formErrors.period" v-html="formErrors.period"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.duration }">
<span :class="formErrors.duration ? 'text-red-500' : 'text-gray-700'">Aufenthaltsdauer</span>
<f:form.textfield class="form-input mt-1 block w-full" property="duration" placeholder="Tage inkl. An- & Abreisetag"/>
<div class="text-red-500 mt-2" v-show="formErrors.duration" v-html="formErrors.duration"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.pax }">
<span :class="formErrors.pax ? 'text-red-500' : 'text-gray-700'">Anzahl der Personen</span>
<f:form.textfield class="form-input mt-1 block w-full" property="pax" placeholder="ab 25 Personen"/>
<div class="text-red-500 mt-2" v-show="formErrors.pax" v-html="formErrors.pax"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.age }">
<span :class="formErrors.age ? 'text-red-500' : 'text-gray-700'">Durchschnittsalter</span>
<f:form.textfield class="form-input mt-1 block w-full" property="age"/>
<div class="text-red-500 mt-2" v-show="formErrors.age" v-html="formErrors.age"></div>
</label>
<div class="mb-4">
<label class="inline-flex items-center">
<f:form.checkbox class="form-checkbox" property="children" value="Ja"/>
<span class="ml-2">Kinder (ja/nein)</span>
</label>
</div>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.inquiry }">
<span :class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
<f:form.textarea class="form-textarea mt-1 block w-full"
property="inquiry"
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
cols="30" rows="5"/>
<div class="text-red-500 mt-2" v-show="formErrors.inquiry" v-html="formErrors.inquiry"></div>
</label>
<div class="mb-4">
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
title="Datenschutzerklärung"
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
</div>
<div class="mb-4">
<button type="submit" class="button button-warning">Jetzt anfragen</button>
</div>
</f:form>
<div class="form__overlay" v-show="processing">
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
</div>
<div class="form__success" v-show="success">
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
setzen.</p>
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
</div>
<div class="form__overlay" v-show="error">
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
</div>
<div class="relative" x-data="contactForm">
<f:form id="contactform" object="{contactForm}" name="contactForm"
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
pageUid="{settings.defaultAjaxUid}"
additionalAttributes="{'x-ref': 'form', 'x-show': '!success', 'x-on:submit.prevent': 'submit'}">
<f:form.hidden property="pageUrl"/>
<label class="block mb-4 hidden">
<span class="text-gray-700">Betreff*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.name">
<span x-bind:class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
<div class="text-red-500 mt-2" x-show="formErrors.name" x-html="formErrors.name"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.firstName">
<span x-bind:class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
<div class="text-red-500 mt-2" x-show="formErrors.firstName" x-html="formErrors.firstName"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.gender">
<span x-bind:class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
<div class="text-red-500 mt-2" x-show="formErrors.gender" x-html="formErrors.gender"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.company">
<span x-bind:class="formErrors.company ? 'text-red-500' : 'text-gray-700'">Firma/Verein*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="company"/>
<div class="text-red-500 mt-2" x-show="formErrors.company" x-html="formErrors.company"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.email">
<span x-bind:class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
<div class="text-red-500 mt-2" x-show="formErrors.email" x-html="formErrors.email"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.phone">
<span x-bind:class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
<div class="text-red-500 mt-2" x-show="formErrors.phone" x-html="formErrors.phone"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.period">
<span x-bind:class="formErrors.period ? 'text-red-500' : 'text-gray-700'">Zeitraum</span>
<f:form.textfield class="form-input mt-1 block w-full" property="period" placeholder="tt.mm.jjjj - tt.mm.jjjj"/>
<div class="text-red-500 mt-2" x-show="formErrors.period" x-html="formErrors.period"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.duration">
<span x-bind:class="formErrors.duration ? 'text-red-500' : 'text-gray-700'">Aufenthaltsdauer</span>
<f:form.textfield class="form-input mt-1 block w-full" property="duration" placeholder="Tage inkl. An- & Abreisetag"/>
<div class="text-red-500 mt-2" x-show="formErrors.duration" x-html="formErrors.duration"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.pax">
<span x-bind:class="formErrors.pax ? 'text-red-500' : 'text-gray-700'">Anzahl der Personen</span>
<f:form.textfield class="form-input mt-1 block w-full" property="pax" placeholder="ab 25 Personen"/>
<div class="text-red-500 mt-2" x-show="formErrors.pax" x-html="formErrors.pax"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.age">
<span x-bind:class="formErrors.age ? 'text-red-500' : 'text-gray-700'">Durchschnittsalter</span>
<f:form.textfield class="form-input mt-1 block w-full" property="age"/>
<div class="text-red-500 mt-2" x-show="formErrors.age" x-html="formErrors.age"></div>
</label>
<div class="mb-4">
<label class="inline-flex items-center">
<f:form.checkbox class="form-checkbox" property="children" value="Ja"/>
<span class="ml-2">Kinder (ja/nein)</span>
</label>
</div>
</contact-form>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.inquiry">
<span x-bind:class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
<f:form.textarea class="form-textarea mt-1 block w-full"
property="inquiry"
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
cols="30" rows="5"/>
<div class="text-red-500 mt-2" x-show="formErrors.inquiry" x-html="formErrors.inquiry"></div>
</label>
<div class="mb-4">
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
title="Datenschutzerklärung"
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
</div>
<div class="mb-4">
<button type="submit" class="button button-warning">Jetzt anfragen</button>
</div>
</f:form>
<div class="form__overlay" x-show="processing">
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
</div>
<div class="form__success" x-show="success">
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
setzen.</p>
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
</div>
<div class="form__overlay" x-show="error">
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
</div>
</div>
</f:section>
</div>
@@ -5,73 +5,71 @@
<f:layout name="Form/Default"/>
<f:section name="Main">
<contact-form inline-template>
<div class="form form--border">
<f:form id="contactform" object="{contactForm}" name="contactForm"
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
pageUid="{settings.defaultAjaxUid}"
additionalAttributes="{'v-show': '!success', '@submit.prevent': 'submitForm()'}">
<f:form.hidden property="pageUrl"/>
<label class="block mb-4 hidden">
<span class="text-gray-700">Betreff*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.gender }">
<span :class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
<div class="text-red-500" v-show="formErrors.gender" v-html="formErrors.gender"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.name }">
<span :class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
<div class="text-red-500" v-show="formErrors.name" v-html="formErrors.name"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.firstName }">
<span :class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
<div class="text-red-500" v-show="formErrors.firstName" v-html="formErrors.firstName"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.email }">
<span :class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
<div class="text-red-500" v-show="formErrors.email" v-html="formErrors.email"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.phone }">
<span :class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
<div class="text-red-500" v-show="formErrors.phone" v-html="formErrors.phone"></div>
</label>
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.inquiry }">
<span :class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
<f:form.textarea class="form-textarea mt-1 block w-full"
property="inquiry"
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
cols="30" rows="5"/>
<div class="text-red-500" v-show="formErrors.inquiry" v-html="formErrors.inquiry"></div>
</label>
<div class="mb-4">
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
title="Datenschutzerklärung"
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
</div>
<div class="mb-4">
<button type="submit" class="button button-warning">Jetzt anfragen</button>
</div>
</f:form>
<div class="form__overlay" v-show="processing">
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
</div>
<div class="form__success" v-show="success">
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
setzen.</p>
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
</div>
<div class="form__success" v-show="error">
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
</div>
<div class="form form--border" x-data="contactForm">
<f:form id="contactform" object="{contactForm}" name="contactForm"
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
pageUid="{settings.defaultAjaxUid}"
additionalAttributes="{'x-ref': 'form', 'x-show': '!success', 'x-on:submit.prevent': 'submit'}">
<f:form.hidden property="pageUrl"/>
<label class="block mb-4 hidden">
<span class="text-gray-700">Betreff*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.gender">
<span x-bind:class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
<div class="text-red-500" x-show="formErrors.gender" x-html="formErrors.gender"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.name">
<span x-bind:class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
<div class="text-red-500" x-show="formErrors.name" x-html="formErrors.name"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.firstName">
<span x-bind:class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
<div class="text-red-500" x-show="formErrors.firstName" x-html="formErrors.firstName"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.email">
<span x-bind:class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
<div class="text-red-500" x-show="formErrors.email" x-html="formErrors.email"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.phone">
<span x-bind:class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
<div class="text-red-500" x-show="formErrors.phone" x-html="formErrors.phone"></div>
</label>
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.inquiry">
<span x-bind:class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
<f:form.textarea class="form-textarea mt-1 block w-full"
property="inquiry"
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
cols="30" rows="5"/>
<div class="text-red-500" x-show="formErrors.inquiry" x-html="formErrors.inquiry"></div>
</label>
<div class="mb-4">
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
title="Datenschutzerklärung"
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
</div>
</contact-form>
<div class="mb-4">
<button type="submit" class="button button-warning">Jetzt anfragen</button>
</div>
</f:form>
<div class="form__overlay" x-show="processing">
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
</div>
<div class="form__success" x-show="success">
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
setzen.</p>
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
</div>
<div class="form__success" x-show="error">
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
</div>
</div>
</f:section>
</div>
@@ -7,13 +7,13 @@
<f:layout name="Default"/>
<f:section name="Main">
<event-pricetable
uri="{ep:uri.ajax(extensionName: 'epproducts', action: 'eventPricetable', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: productUid}', format: 'html')}"
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
:force-partnerid-select="{settings.forcePartnerIdSelect}"
:partner-ids='{settings.partnerIds -> v:format.json.encode()}'
label="{settings.partnerIdSelectLabel}"
></event-pricetable>
<div class="ajax-content-wrapper"
x-data="ajaxContent('{ep:uri.ajax(extensionName: 'epproducts', action: 'eventPricetable', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: productUid}', format: 'html')}')">
<div class="ajax-content" x-ref="container"></div>
<div x-ref="trigger">
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
</div>
</div>
</f:section>
</html>
@@ -581,24 +581,27 @@
<f:if condition="{hotel.groupsPriceConfigs}">
<a class="button button--full"
data-glightbox
data-gallery="groups-calculator"
href="{f:uri.action(action: 'index', controller: 'GroupsPrice', arguments: '{hotel: hotel}', pageUid: settings.groupsPricePopupPageUid)}">
Preisberechnung
</a>
</f:if>
<div class="ep-sidebar ep-facts">
<div class="ep-sidebar ep-facts relative">
<p><strong>Belegungskalender</strong></p>
<f:comment><!--
<calendar
uri="{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: product.calendarHotel}', format: 'html')}"
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
hotel-uid="{product.calendarHotel.uid}"
hotel-name="{product.calendarHotel.name}"
:months="1"
:show-header="false"
:step="1"
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax', extensionName: 'epproducts')}"
></calendar>
--></f:comment>
<div class="row calendar calandar--single"
x-data='calendar("<f:format.raw>{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: hotel}', format: 'html')}</f:format.raw>")'>
<div class="col-xs-12">
<select class="form-control calendar__select" x-model="selectedIndex" x-on:change="load">
<template x-for="(month, index) in selectableMonths">
<option x-bind:value="index" x-text="month.toLocaleDateString('de-DE', {year: 'numeric', month: 'long'})"></option>
</template>
</select>
</div>
<div class="calendar__inner" x-cloak x-ref="calendarWrapper"></div>
<div class="absolute top-0 left-0 inset-0 w-full h-full bg-overlay-white" x-show="loading">
<f:image class="absolute top-1/2 left-1/2 -translate-xy-1/2" src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
</div>
</div>
</div>
<f:if condition="{hotel.groupsPriceConfigs}">
<f:else>
+3 -1
View File
@@ -9,11 +9,13 @@ Encore
.addEntry('snowzone', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/snowzone.js')
.addEntry('unichamp', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/unichamp.js')
.addStyleEntry('rte', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/rte.scss')
.addExternals({
jquery: 'jQuery',
})
.splitEntryChunks()
.enableSingleRuntimeChunk()
.enableSassLoader()
.enableVueLoader()
.autoProvidejQuery()
.enableVersioning()
.enableSourceMaps(!Encore.isProduction())
.cleanupOutputBeforeBuild()