diff --git a/package-lock.json b/package-lock.json index 089cbb46..57c86511 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1547,6 +1547,19 @@ } } }, + "@vue/reactivity": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.2.tgz", + "integrity": "sha512-glJzJoN2xE7I2lRvwKM5u1BHRPTd1yc8iaf//Lai/78/uYAvE5DXp5HzWRFOwMlbRvMGJHIQjOqoxj87cDAaag==", + "requires": { + "@vue/shared": "3.1.2" + } + }, + "@vue/shared": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.2.tgz", + "integrity": "sha512-EmH/poaDWBPJaPILXNI/1fvUbArJQmmTyVCwvvyDYDFnkPoTclAbHRAtyIvqfez7jybTDn077HTNILpxlsoWhg==" + }, "@webassemblyjs/ast": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", @@ -1806,6 +1819,14 @@ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, + "alpinejs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.1.1.tgz", + "integrity": "sha512-svEX82laPua+oqbYlUgX1H7Q+R0GD0V7fOnjZocPBqABmpQGkofPtPV9dGFkgZy7G6q60KFSzkiSwKMw33EFYw==", + "requires": { + "@vue/reactivity": "^3.0.2" + } + }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", diff --git a/package.json b/package.json index c55f57b7..6c046539 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@fancyapps/fancybox": "^3.5.7", "@splidejs/splide": "^2.4.21", "@tailwindcss/custom-forms": "^0.2.1", + "alpinejs": "^3.1.1", "axios": "^0.21.1", "axios-auth-refresh": "^1.0.7", "bootstrap-sass": "^3.4.1", 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 ae78f64b..1d3a26e5 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 @@ -5,62 +5,37 @@ require('lazysizes/plugins/unveilhooks/ls.unveilhooks') require('picturefill') require('leaflet') -// Enable resolution of stimulus controllers -import { Application } from 'stimulus' -import { definitionsFromContext } from 'stimulus/webpack-helpers' - -const application = Application.start() -const context = require.context('./controllers', true, /\.js$/) -application.load(definitionsFromContext(context)) - // Polyfills import smoothscroll from 'smoothscroll-polyfill' smoothscroll.polyfill() -// Function to parse config values from JSON data in HTML source -const parseAppConfig = () => { - const configElement = document.getElementById('appconfig'); - if (null === configElement) { - return {} - } - return JSON.parse(configElement.innerHTML); -} - -// Function to append pacode parameter to urls specified in config by domain -const appendPaCode = appConfig => { - const paCode = appConfig.paCode - const externalDomains = appConfig.externalDomains - if (!paCode) { - return - } - document.querySelectorAll('a').forEach(element => { - if (element.hostname === location.hostname) { - return - } - if (externalDomains.indexOf(element.hostname) === -1) { - return - } - let url = element.href - if (!url) { - return - } - if (url.indexOf('agenturcode=') !== -1) { - return - } - const separator = url.indexOf('?') === -1 ? '?' : '&' - url += separator + 'agenturcode=' + paCode - element.href = url - }) -} +import Alpine from 'alpinejs' +import parseAppConfig from './components/appconfig' +import initSliders from './components/sliders' +import appendPaCode from './components/pacode' +import scrollTop from './components/scoll-top' +import sticky from './components/sticky' +import watchlistToggle from './components/watchlist-toggle' // Executed on document ready document.addEventListener('DOMContentLoaded', () => { const appConfig = parseAppConfig() + const storedWatchlist = JSON.parse(sessionStorage.getItem('myep-watchlist')) appendPaCode(appConfig) + initSliders() + Alpine.store('appconfig', appConfig) + Alpine.store('show', { + searchBox: false, + mobileNav: false, + }) + Alpine.store('watchlist', storedWatchlist ? storedWatchlist : []) + Alpine.data('scrollTop', scrollTop) + Alpine.data('sticky', sticky) + Alpine.data('watchlistToggle', watchlistToggle) + Alpine.start() }) - /// LEGACY CODE FROM HERE /// // Import dependencies diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/SearchResultItem.vue b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/SearchResultItem.vue index 0766cf30..e8d08865 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/SearchResultItem.vue +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/SearchResultItem.vue @@ -61,12 +61,9 @@ - - - + + + diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/appconfig.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/appconfig.js new file mode 100644 index 00000000..0069f458 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/appconfig.js @@ -0,0 +1,9 @@ +const parseAppConfig = () => { + const configElement = document.getElementById('appconfig'); + if (null === configElement) { + return {} + } + return JSON.parse(configElement.innerHTML); +} + +export default parseAppConfig diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/debounce.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/debounce.js new file mode 100644 index 00000000..641ef282 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/debounce.js @@ -0,0 +1,7 @@ +export default (callback, interval) => { + let debounceId + return (...args) => { + clearTimeout(debounceId) + debounceId = setTimeout(() => callback.apply(this, args), interval) + } +} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/pacode.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/pacode.js new file mode 100644 index 00000000..4fa8c4d6 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/pacode.js @@ -0,0 +1,27 @@ +const appendPaCode = appConfig => { + const paCode = appConfig.paCode + const externalDomains = appConfig.externalDomains + if (!paCode) { + return + } + document.querySelectorAll('a').forEach(element => { + if (element.hostname === location.hostname) { + return + } + if (externalDomains.indexOf(element.hostname) === -1) { + return + } + let url = element.href + if (!url) { + return + } + if (url.indexOf('agenturcode=') !== -1) { + return + } + const separator = url.indexOf('?') === -1 ? '?' : '&' + url += separator + 'agenturcode=' + paCode + element.href = url + }) +} + +export default appendPaCode diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/scoll-top.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/scoll-top.js new file mode 100644 index 00000000..7783c186 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/scoll-top.js @@ -0,0 +1,15 @@ +import debounce from './debounce' + +export default function () { + return { + show: false, + init() { + window.addEventListener('scroll', debounce(() => { + this.show = window.scrollY > window.innerHeight/3 + }, 250)) + }, + scroll() { + window.scroll({ top: 0, left: 0, behavior: 'smooth' }) + } + } +} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/sliders.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/sliders.js new file mode 100644 index 00000000..24ff9007 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/sliders.js @@ -0,0 +1,110 @@ +import Splide from '@splidejs/splide' + +const defaultOptions = { + arrows: false, + pagination: false, + perMove: 1, + gap: '1rem', + pauseOnHover: false, + pauseOnFocus: false, +} + +const presets = { + header: { + ...defaultOptions, + autoplay: true, + type: 'fade', + perPage: 1, + gap: 0, + rewind: true, + }, + content: { + ...defaultOptions, + rewind: true, + pagination: true, + gap: 0, + classes: { + pagination: 'slider-pagination', + page: 'slider-pagination__dot', + }, + }, + teasers: { + ...defaultOptions, + perPage: 4, + padding: { + right: '2rem', + }, + breakpoints: { + 1200: { + perPage: 4, + padding: { + right: '2rem', + }, + }, + 1024: { + perPage: 3, + padding: { + right: '2rem', + }, + }, + 960: { + perPage: 2, + padding: { + right: '2rem', + }, + }, + 640: { + perPage: 1, + padding: { + right: '2rem', + }, + }, + }, + }, + teasersEmbedded: { + ...defaultOptions, + perPage: 2, + padding: { + right: '25%', + }, + breakpoints: { + 960: { + perPage: 3, + padding: { + right: '10%', + }, + }, + 768: { + perPage: 2, + padding: { + right: '25%', + }, + }, + 640: { + perPage: 2, + padding: { + right: '10%', + }, + }, + 512: { + perPage: 1, + padding: { + right: '10%', + }, + }, + }, + }, +} + +const initSliders = () => { + document.querySelectorAll( '[data-slider]').forEach(element => { + let options = {} + const preset = element.dataset.slider + if (preset in presets) { + options = presets[preset] + } + new Splide(element, options).mount() + }) +} + +export default initSliders diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/sticky.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/sticky.js new file mode 100644 index 00000000..26632b41 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/sticky.js @@ -0,0 +1,16 @@ +import debounce from './debounce' + +export default function () { + return { + sticky: false, + offset: 0, + init() { + if (this.$el.dataset.offset) { + this.offset = this.$el.dataset.offset + } + window.addEventListener('scroll', debounce(() => { + this.sticky = window.scrollY > this.offset + }, 250)) + } + } +} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/watchlist-toggle.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/watchlist-toggle.js new file mode 100644 index 00000000..b24a5e00 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/watchlist-toggle.js @@ -0,0 +1,26 @@ +export default function () { + return { + uid: null, + init() { + this.uid = this.$el.dataset.uid + }, + onList() { + return -1 !== this.$store.watchlist.indexOf(this.uid) + }, + label() { + return this.onList() ? 'von der Merkliste entfernen' : 'auf die Merkliste setzen' + }, + icon() { + return this.onList() ? 'fa-minus-circle' : 'fa-plus-circle' + }, + toggle() { + const watchlistIndex = this.$store.watchlist.indexOf(this.uid) + if (-1 !== watchlistIndex) { + this.$store.watchlist.splice(watchlistIndex, 1) + } else { + this.$store.watchlist.push(this.uid) + } + sessionStorage.setItem('myep-watchlist', JSON.stringify(this.$store.watchlist)) + } + } +} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/scroll_top_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/scroll_top_controller.js deleted file mode 100644 index d72da559..00000000 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/scroll_top_controller.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Controller } from 'stimulus' -import {useDebounce} from '../mixins/useDebounce' - -export default class extends Controller { - - static values = { show: Boolean } - - connect() { - useDebounce(this) - window.addEventListener('scroll', this.debounce(() => { - this.showValue = window.scrollY > window.innerHeight/3 - }, 250)) - } - - scroll(e) { - e.preventDefault() - window.scroll({ top: 0, left: 0, behavior: 'smooth' }) - } - - showValueChanged() { - this.element.classList.toggle('hidden', false === this.showValue) - } -} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/slider_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/slider_controller.js deleted file mode 100644 index 029fef79..00000000 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/slider_controller.js +++ /dev/null @@ -1,110 +0,0 @@ -import { Controller } from 'stimulus' -import Splide from '@splidejs/splide' - -export default class extends Controller { - - static classes = [ 'pagination' ] - static values = { preset: String, arrows: Boolean, dots: Boolean } - - connect() { - const classes = { - page: 'slider-pagination__dot', - } - - if (this.hasPaginationClass) { - classes.pagination = this.paginationClass - } - - let options = { - perMove: 1, - gap: '1rem', - pauseOnHover: false, - pauseOnFocus: false, - pagination: this.dotsValue, - arrows: this.arrowsValue, - classes - } - - switch (this.presetValue) { - case 'header-detail': - options = { - ...options, - rewind: true, - } - break; - case 'teasers': - options = { - ...options, - perPage: 4, - padding: { - right: '2rem', - }, - breakpoints: { - 1200: { - perPage: 4, - padding: { - right: '2rem', - }, - }, - 1024: { - perPage: 3, - padding: { - right: '2rem', - }, - }, - 960: { - perPage: 2, - padding: { - right: '2rem', - }, - }, - 640: { - perPage: 1, - padding: { - right: '2rem', - }, - } - } - } - break; - case 'teasers_embedded': - options = { - ...options, - perPage: 2, - padding: { - right: '25%', - }, - breakpoints: { - 960: { - perPage: 3, - padding: { - right: '10%', - }, - }, - 768: { - perPage: 2, - padding: { - right: '25%', - }, - }, - 640: { - perPage: 2, - padding: { - right: '10%', - }, - }, - 512: { - perPage: 1, - padding: { - right: '10%', - }, - }, - } - } - break; - default: - } - - new Splide(this.element, options).mount() - } -} 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 deleted file mode 100644 index 13e4ae99..00000000 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/sticky_controller.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Controller } from 'stimulus' -import {useDebounce} from '../mixins/useDebounce' - -export default class extends Controller { - - static classes = [ 'sticky' ] - static values = { offset: Number } - - connect() { - useDebounce(this) - window.addEventListener('scroll', this.debounce(() => { - this.element.classList.toggle(this.stickyClass, window.scrollY > this.offsetValue) - }, 250)) - } -} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/watchlist_toggle_controller.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/watchlist_toggle_controller.js deleted file mode 100644 index 30a91758..00000000 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/controllers/watchlist_toggle_controller.js +++ /dev/null @@ -1,39 +0,0 @@ -import { Controller } from 'stimulus' - -export default class extends Controller { - - static targets = [ 'tooltip', 'label', 'icon' ] - static values = { uid: String, onList: Boolean } - - connect() { - const list = this.getCurrentList() - this.onListValue = -1 !== list.indexOf(this.uidValue) - } - - toggle(e) { - e.preventDefault() - this.onListValue = !this.onListValue - window.dispatchEvent(new CustomEvent('watchlist-toggle', { - detail: this.uidValue - })) - } - - onListValueChanged() { - const label = this.onListValue ? 'von der Merkliste entfernen' : 'auf die Merkliste setzen' - if (this.hasTooltipTarget) { - this.tooltipTarget.setAttribute('aria-label', label) - } - if (this.hasLabelTarget) { - this.labelTarget.textContent = label - } - if (this.hasIconTarget) { - this.iconTarget.classList.toggle('fa-minus-circle', this.onListValue) - this.iconTarget.classList.toggle('fa-plus-circle', !this.onListValue) - } - } - - getCurrentList() { - const initialList = JSON.parse(sessionStorage.getItem('myep-watchlist')) - return initialList ? initialList : [] - } -} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/main.scss b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/main.scss index 09c1ab1e..331b3e33 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/main.scss +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/main.scss @@ -3,6 +3,10 @@ @tailwind utilities; @layer base { + [x-cloak] { + @apply hidden; + } + @import "variables"; @import "color"; diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Footer.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Footer.html index d6e67957..b76232ea 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Footer.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Footer.html @@ -90,6 +90,6 @@ - diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/HeaderSlider.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/HeaderSlider.html index 4261fc03..71497e9f 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/HeaderSlider.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/HeaderSlider.html @@ -3,10 +3,7 @@ xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
-
+
    diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/Details.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/Details.html index 57360e8c..ab091876 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/Details.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/Details.html @@ -10,7 +10,7 @@ -
    +
      diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/TeaserWide.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/TeaserWide.html index cc2b4bb7..c7f290e1 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/TeaserWide.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Hotel/TeaserWide.html @@ -117,11 +117,10 @@
    - + + + +
    diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Mainnav.html b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Mainnav.html index e0344091..d2e0ad94 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Mainnav.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Partials/Mainnav.html @@ -5,7 +5,7 @@ xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers" > -