WIP Migrate to stimulus.js
This commit is contained in:
Generated
+124
-1
@@ -17,6 +17,7 @@
|
|||||||
"bourbon": "^4.3.2",
|
"bourbon": "^4.3.2",
|
||||||
"cookieconsent": "^3.1.0",
|
"cookieconsent": "^3.1.0",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.10.6",
|
||||||
|
"es6-slide-up-down": "^1.0.0",
|
||||||
"flatpickr": "^4.6.9",
|
"flatpickr": "^4.6.9",
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"glightbox": "^3.0.9",
|
"glightbox": "^3.0.9",
|
||||||
@@ -28,11 +29,14 @@
|
|||||||
"picturefill": "^3.0.3",
|
"picturefill": "^3.0.3",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
"sticky-js": "^1.3.0",
|
"sticky-js": "^1.3.0",
|
||||||
|
"stimulus": "^2.0.0",
|
||||||
|
"stimulus-use": "^0.25.4",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-router": "^3.5.2",
|
"vue-router": "^3.5.2",
|
||||||
"vue-scrollto": "^2.20.0",
|
"vue-scrollto": "^2.20.0",
|
||||||
"vue-session": "^1.0.0",
|
"vue-session": "^1.0.0",
|
||||||
"vuex": "^3.6.2"
|
"vuex": "^3.6.2",
|
||||||
|
"whatwg-fetch": "^3.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
|
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
|
||||||
@@ -1650,6 +1654,32 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-2.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-2.4.21.tgz",
|
||||||
"integrity": "sha512-LdIwSnmNsGybCCnA3QG2dOeRv/rQl46jf7FflXxMGX0ADYWyL6UJHWJbMZvHBi5I67uRJY1ga/W+CvJ39nH26A=="
|
"integrity": "sha512-LdIwSnmNsGybCCnA3QG2dOeRv/rQl46jf7FflXxMGX0ADYWyL6UJHWJbMZvHBi5I67uRJY1ga/W+CvJ39nH26A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@stimulus/core": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/core/-/core-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-ff70GafKtzc8zQ1/cG+UvL06GcifPWovf2wBEdjLMh9xO2GOYURO3y2RYgzIGYUIBefQwyfX2CLfJdZFJrEPTw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@stimulus/mutation-observers": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@stimulus/multimap": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/multimap/-/multimap-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-pMBCewkZCFVB3e5mEMoyO9+9aKzHDITmf3OnPun51YWxlcPdHcwbjqm1ylK63fsoduIE+RowBpFwFqd3poEz4w=="
|
||||||
|
},
|
||||||
|
"node_modules/@stimulus/mutation-observers": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/mutation-observers/-/mutation-observers-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kx4VAJdPhIGBQKGIoUDC2tupEKorG3A+ckc2b1UiwInKTMAC1axOHU8ebcwhaJIxRqIrs8//4SJo9YAAOx6FEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@stimulus/multimap": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@stimulus/webpack-helpers": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-D6tJWsAC024MwGEIKlUVYU8Ln87mlrmiwHvYAjipg+s8H4eLxUMQ3PZkWyPevfipH+oR3leuHsjYsK1gN5ViQA=="
|
||||||
|
},
|
||||||
"node_modules/@symfony/webpack-encore": {
|
"node_modules/@symfony/webpack-encore": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-1.5.0.tgz",
|
||||||
@@ -4305,6 +4335,11 @@
|
|||||||
"es6-symbol": "^3.1.1"
|
"es6-symbol": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/es6-slide-up-down": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es6-slide-up-down/-/es6-slide-up-down-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-RTBJFkFvRliBBk6Q7t8SHTZmT14="
|
||||||
|
},
|
||||||
"node_modules/es6-symbol": {
|
"node_modules/es6-symbol": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
||||||
@@ -5242,6 +5277,11 @@
|
|||||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/hotkeys-js": {
|
||||||
|
"version": "3.8.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz",
|
||||||
|
"integrity": "sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg=="
|
||||||
|
},
|
||||||
"node_modules/hpack.js": {
|
"node_modules/hpack.js": {
|
||||||
"version": "2.1.6",
|
"version": "2.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
|
||||||
@@ -9394,6 +9434,26 @@
|
|||||||
"resolved": "https://registry.npmjs.org/sticky-js/-/sticky-js-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/sticky-js/-/sticky-js-1.3.0.tgz",
|
||||||
"integrity": "sha512-X5zWjFrw7c2xE4tUtSeK7I+1o252JOyZOlzxsu1Q9qZ6hlk2NCd9Sr/AFxf8hfGkLnE1Pak+iLaDyd883LFRgw=="
|
"integrity": "sha512-X5zWjFrw7c2xE4tUtSeK7I+1o252JOyZOlzxsu1Q9qZ6hlk2NCd9Sr/AFxf8hfGkLnE1Pak+iLaDyd883LFRgw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/stimulus": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/stimulus/-/stimulus-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-xipy7BS5TVpg4fX6S8LhrYZp7cmHGjmk09WSAiVx1gF5S5g43IWsuetfUhIk8HfHUG+4MQ9nY0FQz4dRFLs/8w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@stimulus/core": "^2.0.0",
|
||||||
|
"@stimulus/webpack-helpers": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/stimulus-use": {
|
||||||
|
"version": "0.25.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/stimulus-use/-/stimulus-use-0.25.4.tgz",
|
||||||
|
"integrity": "sha512-Rr4m4PpcOni7y4KiwUMdCuUJ5IPE2LEELwoz8e+VB3jbfPb9DNjrurCTKCWT5BiPBrn9OEfhnWJIRPcbxUpQvQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"hotkeys-js": ">=3"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"stimulus": ">=1.1.1 <3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string_decoder": {
|
"node_modules/string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
@@ -10835,6 +10895,11 @@
|
|||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/whatwg-fetch": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||||
@@ -12236,6 +12301,32 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-2.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/@splidejs/splide/-/splide-2.4.21.tgz",
|
||||||
"integrity": "sha512-LdIwSnmNsGybCCnA3QG2dOeRv/rQl46jf7FflXxMGX0ADYWyL6UJHWJbMZvHBi5I67uRJY1ga/W+CvJ39nH26A=="
|
"integrity": "sha512-LdIwSnmNsGybCCnA3QG2dOeRv/rQl46jf7FflXxMGX0ADYWyL6UJHWJbMZvHBi5I67uRJY1ga/W+CvJ39nH26A=="
|
||||||
},
|
},
|
||||||
|
"@stimulus/core": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/core/-/core-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-ff70GafKtzc8zQ1/cG+UvL06GcifPWovf2wBEdjLMh9xO2GOYURO3y2RYgzIGYUIBefQwyfX2CLfJdZFJrEPTw==",
|
||||||
|
"requires": {
|
||||||
|
"@stimulus/mutation-observers": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@stimulus/multimap": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/multimap/-/multimap-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-pMBCewkZCFVB3e5mEMoyO9+9aKzHDITmf3OnPun51YWxlcPdHcwbjqm1ylK63fsoduIE+RowBpFwFqd3poEz4w=="
|
||||||
|
},
|
||||||
|
"@stimulus/mutation-observers": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/mutation-observers/-/mutation-observers-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kx4VAJdPhIGBQKGIoUDC2tupEKorG3A+ckc2b1UiwInKTMAC1axOHU8ebcwhaJIxRqIrs8//4SJo9YAAOx6FEg==",
|
||||||
|
"requires": {
|
||||||
|
"@stimulus/multimap": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@stimulus/webpack-helpers": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-D6tJWsAC024MwGEIKlUVYU8Ln87mlrmiwHvYAjipg+s8H4eLxUMQ3PZkWyPevfipH+oR3leuHsjYsK1gN5ViQA=="
|
||||||
|
},
|
||||||
"@symfony/webpack-encore": {
|
"@symfony/webpack-encore": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-1.5.0.tgz",
|
||||||
@@ -14384,6 +14475,11 @@
|
|||||||
"es6-symbol": "^3.1.1"
|
"es6-symbol": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"es6-slide-up-down": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es6-slide-up-down/-/es6-slide-up-down-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-RTBJFkFvRliBBk6Q7t8SHTZmT14="
|
||||||
|
},
|
||||||
"es6-symbol": {
|
"es6-symbol": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
||||||
@@ -15116,6 +15212,11 @@
|
|||||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"hotkeys-js": {
|
||||||
|
"version": "3.8.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz",
|
||||||
|
"integrity": "sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg=="
|
||||||
|
},
|
||||||
"hpack.js": {
|
"hpack.js": {
|
||||||
"version": "2.1.6",
|
"version": "2.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
|
||||||
@@ -18251,6 +18352,23 @@
|
|||||||
"resolved": "https://registry.npmjs.org/sticky-js/-/sticky-js-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/sticky-js/-/sticky-js-1.3.0.tgz",
|
||||||
"integrity": "sha512-X5zWjFrw7c2xE4tUtSeK7I+1o252JOyZOlzxsu1Q9qZ6hlk2NCd9Sr/AFxf8hfGkLnE1Pak+iLaDyd883LFRgw=="
|
"integrity": "sha512-X5zWjFrw7c2xE4tUtSeK7I+1o252JOyZOlzxsu1Q9qZ6hlk2NCd9Sr/AFxf8hfGkLnE1Pak+iLaDyd883LFRgw=="
|
||||||
},
|
},
|
||||||
|
"stimulus": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/stimulus/-/stimulus-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-xipy7BS5TVpg4fX6S8LhrYZp7cmHGjmk09WSAiVx1gF5S5g43IWsuetfUhIk8HfHUG+4MQ9nY0FQz4dRFLs/8w==",
|
||||||
|
"requires": {
|
||||||
|
"@stimulus/core": "^2.0.0",
|
||||||
|
"@stimulus/webpack-helpers": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stimulus-use": {
|
||||||
|
"version": "0.25.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/stimulus-use/-/stimulus-use-0.25.4.tgz",
|
||||||
|
"integrity": "sha512-Rr4m4PpcOni7y4KiwUMdCuUJ5IPE2LEELwoz8e+VB3jbfPb9DNjrurCTKCWT5BiPBrn9OEfhnWJIRPcbxUpQvQ==",
|
||||||
|
"requires": {
|
||||||
|
"hotkeys-js": ">=3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
@@ -19317,6 +19435,11 @@
|
|||||||
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
|
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"whatwg-fetch": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
|
||||||
|
},
|
||||||
"which": {
|
"which": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||||
|
|||||||
+6
-2
@@ -17,6 +17,7 @@
|
|||||||
"bourbon": "^4.3.2",
|
"bourbon": "^4.3.2",
|
||||||
"cookieconsent": "^3.1.0",
|
"cookieconsent": "^3.1.0",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.10.6",
|
||||||
|
"es6-slide-up-down": "^1.0.0",
|
||||||
"flatpickr": "^4.6.9",
|
"flatpickr": "^4.6.9",
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"glightbox": "^3.0.9",
|
"glightbox": "^3.0.9",
|
||||||
@@ -28,11 +29,14 @@
|
|||||||
"picturefill": "^3.0.3",
|
"picturefill": "^3.0.3",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
"sticky-js": "^1.3.0",
|
"sticky-js": "^1.3.0",
|
||||||
|
"stimulus": "^2.0.0",
|
||||||
|
"stimulus-use": "^0.25.4",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-router": "^3.5.2",
|
"vue-router": "^3.5.2",
|
||||||
"vue-scrollto": "^2.20.0",
|
"vue-scrollto": "^2.20.0",
|
||||||
"vue-session": "^1.0.0",
|
"vue-session": "^1.0.0",
|
||||||
"vuex": "^3.6.2"
|
"vuex": "^3.6.2",
|
||||||
|
"whatwg-fetch": "^3.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
|
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
|
||||||
@@ -54,8 +58,8 @@
|
|||||||
"tailwindcss": "^2.2.7",
|
"tailwindcss": "^2.2.7",
|
||||||
"tailwindcss-alt": "^3.0.0",
|
"tailwindcss-alt": "^3.0.0",
|
||||||
"tinycolor2": "^1.4.1",
|
"tinycolor2": "^1.4.1",
|
||||||
"vue-loader": "^15.9.7",
|
|
||||||
"vue-custom-element": "^3.3.0",
|
"vue-custom-element": "^3.3.0",
|
||||||
|
"vue-loader": "^15.9.7",
|
||||||
"vue-template-compiler": "^2.6.14"
|
"vue-template-compiler": "^2.6.14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\Hotel;
|
use EP\EpProducts\Domain\Model\Hotel;
|
||||||
use EP\EpProducts\Domain\Model\Product;
|
use EP\EpProducts\Domain\Model\Product;
|
||||||
use EP\EpProducts\Domain\Repository\ProductRepository;
|
use EP\EpProducts\Domain\Repository\ProductRepository;
|
||||||
@@ -85,12 +84,6 @@ class AjaxDateController extends ActionController
|
|||||||
$this->productRepository = $productRepository;
|
$this->productRepository = $productRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initializeAction()
|
|
||||||
{
|
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
|
||||||
$this->processFilterSettingsArgument($forcedConceptUids);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initializeDatesAction()
|
public function initializeDatesAction()
|
||||||
{
|
{
|
||||||
if ($this->request->hasArgument('dateFrom')) {
|
if ($this->request->hasArgument('dateFrom')) {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Service\FilterService;
|
use EP\EpProducts\Service\FilterService;
|
||||||
use EP\EpProducts\Service\SearchResultUrlService;
|
use EP\EpProducts\Service\SearchResultUrlService;
|
||||||
use EP\EpProducts\Service\SearchResultService;
|
use EP\EpProducts\Service\SearchResultService;
|
||||||
@@ -66,8 +65,7 @@ class AjaxSearchController extends ActionController
|
|||||||
FilterService $filterService,
|
FilterService $filterService,
|
||||||
SearchResultService $searchResultService,
|
SearchResultService $searchResultService,
|
||||||
SearchResultUrlService $searchResultUrlService
|
SearchResultUrlService $searchResultUrlService
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->filterService = $filterService;
|
$this->filterService = $filterService;
|
||||||
@@ -75,34 +73,26 @@ class AjaxSearchController extends ActionController
|
|||||||
$this->searchResultUrlService = $searchResultUrlService;
|
$this->searchResultUrlService = $searchResultUrlService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initializeAction()
|
/**
|
||||||
|
* @param array $filterSettings
|
||||||
|
*/
|
||||||
|
public function searchresultAction(array $filterSettings = [])
|
||||||
{
|
{
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$this->processFilterSettingsArgument($forcedConceptUids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
* @return string
|
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
|
||||||
*/
|
|
||||||
public function searchresultAction(FilterSettings $filterSettings = null)
|
|
||||||
{
|
|
||||||
$dateSelected = false;
|
$dateSelected = false;
|
||||||
$organic = true;
|
$organic = true;
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
||||||
|
|
||||||
if ($filterSettings === null) {
|
if (isset($filterSettings['dateFrom']) || isset($filterSettings['dateTo'])) {
|
||||||
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($filterSettings->getDateFrom() !== null || $filterSettings->getDateTo() !== null) {
|
|
||||||
$dateSelected = true;
|
$dateSelected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids);
|
$searchResult = $this
|
||||||
|
->searchResultService
|
||||||
|
->getResult($filterSettings, $excludedConceptUids);
|
||||||
|
|
||||||
if ($searchResult->getTotal() === 0) {
|
if ($searchResult->getTotal() === 0) {
|
||||||
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
||||||
@@ -110,11 +100,7 @@ class AjaxSearchController extends ActionController
|
|||||||
$organic = false;
|
$organic = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = [
|
$this->searchResultUrlService->process($searchResult, $this->settings['defaultDetailPageUid']);
|
||||||
'defaultDetailPageUid' => $this->settings['defaultDetailPageUid'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->searchResultUrlService->process($searchResult, $options);
|
|
||||||
|
|
||||||
$filterOptions = $this->filterService->getFilterOptions(
|
$filterOptions = $this->filterService->getFilterOptions(
|
||||||
$filterSettings,
|
$filterSettings,
|
||||||
@@ -129,7 +115,7 @@ class AjaxSearchController extends ActionController
|
|||||||
->setTargetPageUid($this->settings['defaultSearchPageUid'])
|
->setTargetPageUid($this->settings['defaultSearchPageUid'])
|
||||||
->uriFor(
|
->uriFor(
|
||||||
'searchresult',
|
'searchresult',
|
||||||
['filterSettings' => $filterSettings->toArray()],
|
['filterSettings' => $filterSettings],
|
||||||
'Search',
|
'Search',
|
||||||
null,
|
null,
|
||||||
'searchresult'
|
'searchresult'
|
||||||
@@ -144,7 +130,7 @@ class AjaxSearchController extends ActionController
|
|||||||
'meta' => [
|
'meta' => [
|
||||||
'organic' => $organic,
|
'organic' => $organic,
|
||||||
'total' => $searchResult->getTotal(),
|
'total' => $searchResult->getTotal(),
|
||||||
'dateRange' => DateUtility::formatDateRange($filterSettings->getDateFrom(), $filterSettings->getDateTo()),
|
'dateRange' => DateUtility::formatDateRange($filterSettings['dateFrom'], $filterSettings['dateTo']),
|
||||||
'dateSelected' => $dateSelected,
|
'dateSelected' => $dateSelected,
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\SearchParams;
|
use EP\EpProducts\Domain\Model\SearchParams;
|
||||||
use EP\EpProducts\Service\FilterService;
|
use EP\EpProducts\Service\FilterService;
|
||||||
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
||||||
@@ -70,7 +69,7 @@ class AjaxSearchbarController extends ActionController
|
|||||||
$searchParams = new SearchParams();
|
$searchParams = new SearchParams();
|
||||||
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
||||||
} else {
|
} else {
|
||||||
$filterSettings = FilterSettings::fromSearchParams($searchParams);
|
$filterSettings = $searchParams->toFilterSettings();
|
||||||
}
|
}
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\Concept;
|
use EP\EpProducts\Domain\Model\Concept;
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Repository\ConceptRepository;
|
use EP\EpProducts\Domain\Repository\ConceptRepository;
|
||||||
use EP\EpProducts\Service\ProductDataService;
|
use EP\EpProducts\Service\ProductDataService;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
@@ -69,11 +68,13 @@ class ConceptController extends ActionController
|
|||||||
}
|
}
|
||||||
$teaserConceptUids = GeneralUtility::trimExplode(',', $this->settings['additionalConceptUids']);
|
$teaserConceptUids = GeneralUtility::trimExplode(',', $this->settings['additionalConceptUids']);
|
||||||
array_unshift($teaserConceptUids, $concept->getUid());
|
array_unshift($teaserConceptUids, $concept->getUid());
|
||||||
$filterSettings = new FilterSettings();
|
$filterSettings = [
|
||||||
$filterSettings->setConceptUids($teaserConceptUids);
|
'conceptUids' => $teaserConceptUids,
|
||||||
|
];
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
||||||
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
||||||
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
||||||
|
|
||||||
$this->view->assignMultiple([
|
$this->view->assignMultiple([
|
||||||
'teasers' => $teasers,
|
'teasers' => $teasers,
|
||||||
'concept' => $concept,
|
'concept' => $concept,
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\Country;
|
use EP\EpProducts\Domain\Model\Country;
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Repository\CountryRepository;
|
use EP\EpProducts\Domain\Repository\CountryRepository;
|
||||||
use EP\EpProducts\Service\ProductDataService;
|
use EP\EpProducts\Service\ProductDataService;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
@@ -67,8 +66,9 @@ class CountryController extends ActionController
|
|||||||
$countryUid = $this->settings['countryUid'];
|
$countryUid = $this->settings['countryUid'];
|
||||||
$country = $this->countryRepository->findByIdentifier($countryUid);
|
$country = $this->countryRepository->findByIdentifier($countryUid);
|
||||||
}
|
}
|
||||||
$filterSettings = new FilterSettings();
|
$filterSettings = [
|
||||||
$filterSettings->setCountryUids([$countryUid]);
|
'countryUids' => [ $countryUid ],
|
||||||
|
];
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
||||||
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
||||||
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\Hotel;
|
use EP\EpProducts\Domain\Model\Hotel;
|
||||||
use EP\EpProducts\Domain\Repository\HotelRepository;
|
use EP\EpProducts\Domain\Repository\HotelRepository;
|
||||||
use EP\EpProducts\Domain\Repository\ProductRepository;
|
use EP\EpProducts\Domain\Repository\ProductRepository;
|
||||||
@@ -92,8 +91,9 @@ class HotelController extends ActionController
|
|||||||
/** @var Hotel $hotel */
|
/** @var Hotel $hotel */
|
||||||
$hotel = $this->hotelRepository->findByIdentifier($hotelUid);
|
$hotel = $this->hotelRepository->findByIdentifier($hotelUid);
|
||||||
}
|
}
|
||||||
$filterSettings = new FilterSettings();
|
$filterSettings = [
|
||||||
$filterSettings->setHotelUid($hotelUid);
|
'hotelUid' => $hotelUid,
|
||||||
|
];
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
||||||
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
||||||
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class ProductController extends ActionController
|
|||||||
'searchresult',
|
'searchresult',
|
||||||
'Search',
|
'Search',
|
||||||
null,
|
null,
|
||||||
['filterSettings' => $filterSettings->toArray()],
|
['filterSettings' => $filterSettings],
|
||||||
$this->settings['defaultSearchPageUid']
|
$this->settings['defaultSearchPageUid']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\Region;
|
use EP\EpProducts\Domain\Model\Region;
|
||||||
use EP\EpProducts\Domain\Repository\RegionRepository;
|
use EP\EpProducts\Domain\Repository\RegionRepository;
|
||||||
use EP\EpProducts\Service\ProductDataService;
|
use EP\EpProducts\Service\ProductDataService;
|
||||||
@@ -72,8 +71,9 @@ class RegionController extends ActionController
|
|||||||
return (int)$uid;
|
return (int)$uid;
|
||||||
}, $additionalRegionUids);
|
}, $additionalRegionUids);
|
||||||
$teaserRegionUids = array_merge([$region->getUid()], $additionalRegionUids);
|
$teaserRegionUids = array_merge([$region->getUid()], $additionalRegionUids);
|
||||||
$filterSettings = new FilterSettings();
|
$filterSettings = [
|
||||||
$filterSettings->setRegionUids($teaserRegionUids);
|
'regionUids' => $teaserRegionUids,
|
||||||
|
];
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
||||||
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
$limit = $this->settings['showMoreLink'] ? 4 : 0;
|
||||||
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\SearchParams;
|
use EP\EpProducts\Domain\Model\SearchParams;
|
||||||
use EP\EpProducts\Service\FilterService;
|
use EP\EpProducts\Service\FilterService;
|
||||||
use EP\EpProducts\Service\FilterSettingsEncoder;
|
use EP\EpProducts\Service\FilterSettingsEncoder;
|
||||||
|
use EP\EpProducts\Service\SearchResultService;
|
||||||
|
use EP\EpProducts\Service\SearchResultUrlService;
|
||||||
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
||||||
|
use EP\EpProducts\Utility\DateUtility;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||||
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
|
||||||
@@ -47,7 +49,17 @@ class SearchController extends ActionController
|
|||||||
protected $filterService;
|
protected $filterService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \EP\EpProducts\Domain\Model\FilterSettings
|
* @var SearchResultService
|
||||||
|
*/
|
||||||
|
private $searchResultService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SearchResultUrlService
|
||||||
|
*/
|
||||||
|
private $searchResultUrlService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $defaultFilterSettings;
|
protected $defaultFilterSettings;
|
||||||
|
|
||||||
@@ -59,10 +71,16 @@ class SearchController extends ActionController
|
|||||||
/**
|
/**
|
||||||
* @param FilterService $filterService
|
* @param FilterService $filterService
|
||||||
*/
|
*/
|
||||||
public function __construct(FilterService $filterService)
|
public function __construct
|
||||||
{
|
(
|
||||||
|
FilterService $filterService,
|
||||||
|
SearchResultService $searchResultService,
|
||||||
|
SearchResultUrlService $searchResultUrlService
|
||||||
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->filterService = $filterService;
|
$this->filterService = $filterService;
|
||||||
|
$this->searchResultService = $searchResultService;
|
||||||
|
$this->searchResultUrlService = $searchResultUrlService;
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
|
||||||
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids'], true);
|
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids'], true);
|
||||||
@@ -104,19 +122,17 @@ class SearchController extends ActionController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param SearchParams $searchParams
|
* @param SearchParams $searchParams
|
||||||
* @throws StopActionException
|
|
||||||
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
|
|
||||||
*/
|
*/
|
||||||
public function processSearchAction(SearchParams $searchParams)
|
public function processSearchAction(SearchParams $searchParams)
|
||||||
{
|
{
|
||||||
$filterSettings = FilterSettings::fromSearchParams($searchParams);
|
$filterSettings = $searchParams->toFilterSettings();
|
||||||
|
|
||||||
$redirectUri = $this->uriBuilder
|
$redirectUri = $this->uriBuilder
|
||||||
->reset()
|
->reset()
|
||||||
->setCreateAbsoluteUri(true)
|
->setCreateAbsoluteUri(true)
|
||||||
->uriFor(
|
->uriFor(
|
||||||
'searchresult',
|
'searchresult',
|
||||||
['filterSettings' => $filterSettings->toArray()],
|
['filterSettings' => $filterSettings],
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
'searchresult'
|
'searchresult'
|
||||||
@@ -128,17 +144,33 @@ class SearchController extends ActionController
|
|||||||
public function initializeSearchresultAction()
|
public function initializeSearchresultAction()
|
||||||
{
|
{
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$this->processFilterSettingsArgument($forcedConceptUids);
|
//$this->processFilterSettingsArgument($forcedConceptUids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \EP\EpProducts\Domain\Model\FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
*/
|
*/
|
||||||
public function searchresultAction(FilterSettings $filterSettings)
|
public function searchresultAction(array $filterSettings = [])
|
||||||
{
|
{
|
||||||
|
$dateSelected = false;
|
||||||
|
$organic = true;
|
||||||
|
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
||||||
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
||||||
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true);
|
|
||||||
|
if (!empty($filterSettings['dateFrom']) || !empty($filterSettings['dateTo'])) {
|
||||||
|
$dateSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids);
|
||||||
|
|
||||||
|
if ($searchResult->getTotal() === 0) {
|
||||||
|
$filterSettings = $this->defaultFilterSettings;
|
||||||
|
$searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids);
|
||||||
|
$organic = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->searchResultUrlService->process($searchResult, $this->settings['defaultDetailPageUid']);
|
||||||
|
|
||||||
$filterOptions = $this->filterService->getFilterOptions(
|
$filterOptions = $this->filterService->getFilterOptions(
|
||||||
$filterSettings,
|
$filterSettings,
|
||||||
@@ -147,10 +179,30 @@ class SearchController extends ActionController
|
|||||||
$forcedConceptUids
|
$forcedConceptUids
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$referringPageUri = $this
|
||||||
|
->uriBuilder
|
||||||
|
->reset()
|
||||||
|
->setTargetPageUid($this->settings['defaultSearchPageUid'])
|
||||||
|
->uriFor(
|
||||||
|
'searchresult',
|
||||||
|
['filterSettings' => $filterSettings],
|
||||||
|
'Search',
|
||||||
|
null,
|
||||||
|
'searchresult'
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
$this->view->assignMultiple([
|
$this->view->assignMultiple([
|
||||||
'referringPageUid' => $this->settings['defaultSearchPageUid'],
|
|
||||||
'filterOptions' => $filterOptions,
|
|
||||||
'filterSettings' => $filterSettings,
|
'filterSettings' => $filterSettings,
|
||||||
|
'filterOptions' => $filterOptions,
|
||||||
|
'searchResult' => $searchResult->getData(),
|
||||||
|
'referringPageUri' => $referringPageUri,
|
||||||
|
'meta' => [
|
||||||
|
'organic' => $organic,
|
||||||
|
'total' => $searchResult->getTotal(),
|
||||||
|
'dateRange' => DateUtility::formatDateRange($filterSettings['dateFrom'], $filterSettings['dateTo']),
|
||||||
|
'dateSelected' => $dateSelected,
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $countryUids
|
* @param array $countryUids
|
||||||
*/
|
*/
|
||||||
public function setCountryUids(array $countryUids)
|
public function setCountryUids(?array $countryUids)
|
||||||
{
|
{
|
||||||
$this->countryUids = $countryUids;
|
$this->countryUids = $countryUids;
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $regionUids
|
* @param array $regionUids
|
||||||
*/
|
*/
|
||||||
public function setRegionUids(array $regionUids)
|
public function setRegionUids(?array $regionUids)
|
||||||
{
|
{
|
||||||
$this->regionUids = $regionUids;
|
$this->regionUids = $regionUids;
|
||||||
}
|
}
|
||||||
@@ -294,7 +294,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $cityUids
|
* @param array $cityUids
|
||||||
*/
|
*/
|
||||||
public function setCityUids($cityUids)
|
public function setCityUids(?array $cityUids)
|
||||||
{
|
{
|
||||||
$this->cityUids = $cityUids;
|
$this->cityUids = $cityUids;
|
||||||
}
|
}
|
||||||
@@ -310,7 +310,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $conceptUids
|
* @param array $conceptUids
|
||||||
*/
|
*/
|
||||||
public function setConceptUids($conceptUids)
|
public function setConceptUids(?array $conceptUids)
|
||||||
{
|
{
|
||||||
$this->conceptUids = $conceptUids;
|
$this->conceptUids = $conceptUids;
|
||||||
}
|
}
|
||||||
@@ -421,7 +421,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $boardTypes
|
* @param array $boardTypes
|
||||||
*/
|
*/
|
||||||
public function setBoardTypes($boardTypes)
|
public function setBoardTypes(?array $boardTypes)
|
||||||
{
|
{
|
||||||
$this->boardTypes = $boardTypes;
|
$this->boardTypes = $boardTypes;
|
||||||
}
|
}
|
||||||
@@ -437,7 +437,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $hotelTypes
|
* @param array $hotelTypes
|
||||||
*/
|
*/
|
||||||
public function setHotelTypes($hotelTypes)
|
public function setHotelTypes(?array $hotelTypes)
|
||||||
{
|
{
|
||||||
$this->hotelTypes = $hotelTypes;
|
$this->hotelTypes = $hotelTypes;
|
||||||
}
|
}
|
||||||
@@ -453,7 +453,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param array $roomTypes
|
* @param array $roomTypes
|
||||||
*/
|
*/
|
||||||
public function setRoomTypes($roomTypes)
|
public function setRoomTypes(?array $roomTypes)
|
||||||
{
|
{
|
||||||
$this->roomTypes = $roomTypes;
|
$this->roomTypes = $roomTypes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,6 +235,46 @@ class SearchParams implements \JsonSerializable
|
|||||||
$this->pageUid = $pageUid;
|
$this->pageUid = $pageUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function toFilterSettings(): array
|
||||||
|
{
|
||||||
|
$filterSettings = [];
|
||||||
|
|
||||||
|
if ($this->getDestinationType() && $this->getDestinationUid()) {
|
||||||
|
$destinationUid = $this->getDestinationUid();
|
||||||
|
switch ($this->getDestinationType()) {
|
||||||
|
case SearchParams::DESTINATION_TYPE_COUNTRY:
|
||||||
|
$filterSettings['countryUids'] = [ $destinationUid ];
|
||||||
|
break;
|
||||||
|
case SearchParams::DESTINATION_TYPE_REGION:
|
||||||
|
$filterSettings['regionUids'] = [ $destinationUid ];
|
||||||
|
break;
|
||||||
|
case SearchParams::DESTINATION_TYPE_CITY:
|
||||||
|
$filterSettings['cityUids'] = [ $destinationUid ];
|
||||||
|
break;
|
||||||
|
case SearchParams::DESTINATION_TYPE_CONCEPT:
|
||||||
|
$filterSettings['conceptUids'] = [ $destinationUid ];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null !== $this->getDateFrom()) {
|
||||||
|
$filterSettings['dateFrom'] = $this->getDateFrom()->format('Y-m-d');
|
||||||
|
}
|
||||||
|
if (null !== $this->getDateTo()) {
|
||||||
|
$filterSettings['dateTo'] = $this->getDateTo()->format('Y-m-d');
|
||||||
|
}
|
||||||
|
if (null !== $this->getPriceRange()) {
|
||||||
|
$filterSettings['priceRanges'] = [ $this->getPriceRange() ];
|
||||||
|
}
|
||||||
|
if (null !== $this->getPax()) {
|
||||||
|
$filterSettings['pax'] = $this->getPax();
|
||||||
|
}
|
||||||
|
if (null !== $this->getNights()) {
|
||||||
|
$filterSettings['nights'] = $this->getNights();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filterSettings;
|
||||||
|
}
|
||||||
|
|
||||||
public function toArray(): array
|
public function toArray(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -40,21 +40,14 @@ class SearchResult
|
|||||||
*/
|
*/
|
||||||
protected $data = [];
|
protected $data = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* @var FilterSettings
|
|
||||||
*/
|
|
||||||
protected $filterSettings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param int $total
|
* @param int $total
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
*/
|
||||||
public function __construct(array $data = [], $total = 0, FilterSettings $filterSettings = null)
|
public function __construct(array $data = [], $total = 0)
|
||||||
{
|
{
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
$this->total = $total;
|
$this->total = $total;
|
||||||
$this->filterSettings = $filterSettings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,20 +82,4 @@ class SearchResult
|
|||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return FilterSettings
|
|
||||||
*/
|
|
||||||
public function getFilterSettings()
|
|
||||||
{
|
|
||||||
return $this->filterSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
public function setFilterSettings($filterSettings)
|
|
||||||
{
|
|
||||||
$this->filterSettings = $filterSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-113
@@ -42,7 +42,7 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit
|
|||||||
{
|
{
|
||||||
/** @var $querySettings \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings */
|
/** @var $querySettings \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings */
|
||||||
$querySettings = $this->objectManager->get(Typo3QuerySettings::class);
|
$querySettings = $this->objectManager->get(Typo3QuerySettings::class);
|
||||||
$querySettings->setRespectStoragePage(FALSE);
|
$querySettings->setRespectStoragePage(false);
|
||||||
$this->setDefaultQuerySettings($querySettings);
|
$this->setDefaultQuerySettings($querySettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,114 +60,90 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit
|
|||||||
return $query->execute();
|
return $query->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addDateFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addDateFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Date Start
|
// Date Start
|
||||||
if ($filterSettings->getDateFrom() !== null) {
|
if (!empty($filterSettings['dateFrom'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.date_start >= :dateStart')
|
->andWhere('date.date_start >= :dateStart')
|
||||||
->setParameter('dateStart', $filterSettings->getDateFrom()->format('Y-m-d'))
|
->setParameter('dateStart', $filterSettings['dateFrom'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Date End
|
// Date End
|
||||||
if ($filterSettings->getDateTo() !== null) {
|
if (!empty($filterSettings['dateTo'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.date_end <= :dateEnd')
|
->andWhere('date.date_end <= :dateEnd')
|
||||||
->setParameter('dateEnd', $filterSettings->getDateTo()->format('Y-m-d'))
|
->setParameter('dateEnd', $filterSettings['dateTo'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addHotelFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addHotelFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Hotel
|
// Hotel
|
||||||
if ((int) $filterSettings->getHotelUid() > 0) {
|
if (!empty($filterSettings['hotelUid'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.hotel = :hotelUid')
|
->andWhere('date.hotel = :hotelUid')
|
||||||
->setParameter('hotelUid', $filterSettings->getHotelUid())
|
->setParameter('hotelUid', (int)$filterSettings['hotelUid'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
// Hotel types
|
// Hotel types
|
||||||
if (count($filterSettings->getHotelTypes()) > 0) {
|
if (!empty($filterSettings['hotelTypes'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.hotel_type IN (:hotelTypes)')
|
->andWhere('date.hotel_type IN (:hotelTypes)')
|
||||||
->setParameter('hotelTypes', $filterSettings->getHotelTypes(), Connection::PARAM_INT_ARRAY)
|
->setParameter('hotelTypes', (array)$filterSettings['hotelTypes'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addCountryRegionAndCityFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addCountryRegionAndCityFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
if (count($filterSettings->getCityUids()) > 0) {
|
if (!empty($filterSettings['cityUids'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.city IN (:cityUids)')
|
->andWhere('date.city IN (:cityUids)')
|
||||||
->setParameter('cityUids', $filterSettings->getCityUids(), Connection::PARAM_INT_ARRAY)
|
->setParameter('cityUids', (array)$filterSettings['cityUids'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
} elseif (count($filterSettings->getRegionUids()) > 0) {
|
} elseif (!empty($filterSettings['regionUids'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.region IN (:regionUids)')
|
->andWhere('date.region IN (:regionUids)')
|
||||||
->setParameter('regionUids', $filterSettings->getRegionUids(), Connection::PARAM_INT_ARRAY)
|
->setParameter('regionUids', (array)$filterSettings['regionUids'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
} elseif (count($filterSettings->getCountryUids()) > 0) {
|
} elseif (!empty($filterSettings['countryUids'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.country IN (:countryUids)')
|
->andWhere('date.country IN (:countryUids)')
|
||||||
->setParameter('countryUids', $filterSettings->getCountryUids(), Connection::PARAM_INT_ARRAY)
|
->setParameter('countryUids', (array)$filterSettings['countryUids'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addConceptFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addConceptFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
if (count($filterSettings->getConceptUids()) > 0) {
|
if (!empty($filterSettings['conceptUids'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.concept IN (:conceptUids)')
|
->andWhere('date.concept IN (:conceptUids)')
|
||||||
->setParameter('conceptUids', $filterSettings->getConceptUids(), Connection::PARAM_INT_ARRAY)
|
->setParameter('conceptUids', (array)$filterSettings['conceptUids'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addPaxFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addPaxFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Pax
|
// Pax
|
||||||
if ((int) $filterSettings->getPax() > 0) {
|
if (!empty($filterSettings['pax'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.available >= :pax')
|
->andWhere('date.available >= :pax')
|
||||||
->setParameter('pax', $filterSettings->getPax())
|
->setParameter('pax', (int)$filterSettings['pax'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addPriceRangeFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addPriceRangeFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Price ranges
|
// Price ranges
|
||||||
if (count($filterSettings->getPriceRanges()) > 0) {
|
if (!empty($filterSettings['priceRanges'])) {
|
||||||
$orX = $query->expr()->orX();
|
$orX = $query->expr()->orX();
|
||||||
foreach ($filterSettings->getPriceRanges() as $priceRange) {
|
foreach ((array)$filterSettings['priceRanges'] as $priceRange) {
|
||||||
[ $priceMin, $priceMax ] = FilterOptions::$priceRangeOptions[$priceRange];
|
[ $priceMin, $priceMax ] = FilterOptions::$priceRangeOptions[$priceRange];
|
||||||
$orX->add($query->expr()->andX(
|
$orX->add($query->expr()->andX(
|
||||||
$query->expr()->gte('date.min_price', ':priceMin'),
|
$query->expr()->gte('date.min_price', ':priceMin'),
|
||||||
@@ -182,79 +158,63 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addDurationFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addDurationFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Duration
|
// Duration
|
||||||
if ((int) $filterSettings->getNights() === FilterSettings::DURATION_SHORT) {
|
if (empty($filterSettings['nights'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$nights = (int)$filterSettings['nights'];
|
||||||
|
if ($nights === FilterSettings::DURATION_SHORT) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.nights <= :nights')
|
->andWhere('date.nights <= :nights')
|
||||||
->setParameter('nights', $filterSettings->getNights())
|
->setParameter('nights', $nights)
|
||||||
;
|
;
|
||||||
} elseif ((int) $filterSettings->getNights() === FilterSettings::DURATION_LONG) {
|
} elseif ($nights === FilterSettings::DURATION_LONG) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.nights >= :nights')
|
->andWhere('date.nights >= :nights')
|
||||||
->setParameter('nights', $filterSettings->getNights())
|
->setParameter('nights', $nights)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addHotelTypesFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addHotelTypesFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Hotel types
|
// Hotel types
|
||||||
if (count($filterSettings->getHotelTypes()) > 0) {
|
if (!empty($filterSettings['hotelTypes'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.hotel_type IN (:hotelTypes)')
|
->andWhere('date.hotel_type IN (:hotelTypes)')
|
||||||
->setParameter('hotelTypes', $filterSettings->getHotelTypes(), Connection::PARAM_INT_ARRAY)
|
->setParameter('hotelTypes', (array)$filterSettings['hotelTypes'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addBoardTypesFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addBoardTypesFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Board types
|
// Board types
|
||||||
if (count($filterSettings->getBoardTypes()) > 0) {
|
if (!empty($filterSettings['boardTypes'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.board_bus_pro_id IN (:boardTypes)')
|
->andWhere('date.board_bus_pro_id IN (:boardTypes)')
|
||||||
->setParameter('boardTypes', $filterSettings->getBoardTypes(), Connection::PARAM_STR_ARRAY)
|
->setParameter('boardTypes', (array)$filterSettings['boardTypes'], Connection::PARAM_STR_ARRAY)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addRoomTypesFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addRoomTypesFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Room types
|
// Room types
|
||||||
if (count($filterSettings->getRoomTypes()) > 0) {
|
if (!empty($filterSettings['roomTypes'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('room.type IN (:roomTypes)')
|
->andWhere('room.type IN (:roomTypes)')
|
||||||
->setParameter('roomTypes', $filterSettings->getRoomTypes(), Connection::PARAM_INT_ARRAY)
|
->setParameter('roomTypes', (array)$filterSettings['roomTypes'], Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function addTransportationFilterConditions(QueryBuilder $query, array $filterSettings): void
|
||||||
* @param QueryBuilder $query
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*/
|
|
||||||
protected function addTransportationFilterConditions(QueryBuilder $query, FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
// Transportation
|
// Transportation
|
||||||
if ($filterSettings->getBus() === true) {
|
if (!empty($filterSettings['bus'])) {
|
||||||
$query->andWhere('date.bus_available = 1');
|
$query->andWhere('date.bus_available = 1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,10 +223,10 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit
|
|||||||
* Adds general conditions for provided filtersettings
|
* Adds general conditions for provided filtersettings
|
||||||
*
|
*
|
||||||
* @param QueryBuilder $query
|
* @param QueryBuilder $query
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param bool $constraintDates
|
* @param bool $constraintDates
|
||||||
*/
|
*/
|
||||||
protected function addFiltersettingsConditions(QueryBuilder $query, FilterSettings $filterSettings, $constraintDates = true)
|
protected function addFiltersettingsConditions(QueryBuilder $query, array $filterSettings, $constraintDates = true)
|
||||||
{
|
{
|
||||||
if ($constraintDates) {
|
if ($constraintDates) {
|
||||||
$this->addDateFilterConditions($query, $filterSettings);
|
$this->addDateFilterConditions($query, $filterSettings);
|
||||||
@@ -281,41 +241,21 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit
|
|||||||
$this->addRoomTypesFilterConditions($query, $filterSettings);
|
$this->addRoomTypesFilterConditions($query, $filterSettings);
|
||||||
$this->addTransportationFilterConditions($query, $filterSettings);
|
$this->addTransportationFilterConditions($query, $filterSettings);
|
||||||
|
|
||||||
// Default fulltext search in case autocompletion has not been used
|
|
||||||
// if ((int) $filterSettings->getDestinationUid() === 0 && !empty($filterSettings->getDestinationName())) {
|
|
||||||
// $query
|
|
||||||
// ->andWhere($query->expr()->orX(
|
|
||||||
// $query->expr()->like('LOWER(date.country_name) COLLATE utf8_bin',':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.country_keywords) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.region_name) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.region_keywords) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.city_name) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.city_keywords) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.hotel_name) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.hotel_keywords) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.product_name) COLLATE utf8_bin', ':destination'),
|
|
||||||
// $query->expr()->like('LOWER(date.product_keywords) COLLATE utf8_bin', ':destination')
|
|
||||||
// ))
|
|
||||||
// ->setParameter('destination', '%' . mb_strtolower($filterSettings->getDestinationName()) . '%')
|
|
||||||
// ;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Product
|
// Product
|
||||||
if ((int) $filterSettings->getProductUid() > 0) {
|
if (!empty($filterSettings['productUid'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.product = :productUid')
|
->andWhere('date.product = :productUid')
|
||||||
->setParameter('productUid', $filterSettings->getProductUid())
|
->setParameter('productUid', (int)$filterSettings['productUid'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hotel
|
// Hotel
|
||||||
if ((int) $filterSettings->getHotelUid() > 0) {
|
if (!empty($filterSettings['hotelUid'])) {
|
||||||
$query
|
$query
|
||||||
->andWhere('date.hotel = :hotel')
|
->andWhere('date.hotel = :hotel')
|
||||||
->setParameter(':hotel', $filterSettings->getHotelUid())
|
->setParameter(':hotel', (int)$filterSettings['hotelUid'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Domain\Repository;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\Product;
|
use EP\EpProducts\Domain\Model\Product;
|
||||||
use TYPO3\CMS\Core\Database\Connection;
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
|
|
||||||
@@ -73,7 +72,7 @@ class DateRepository extends AbstractRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getFilterOptions(
|
public function getFilterOptions(
|
||||||
FilterSettings $filterSettings,
|
array $filterSettings,
|
||||||
array $excludedConceptUids = [],
|
array $excludedConceptUids = [],
|
||||||
array $excludedRegionUids = [],
|
array $excludedRegionUids = [],
|
||||||
array $forcedConceptUids = []
|
array $forcedConceptUids = []
|
||||||
@@ -131,11 +130,11 @@ class DateRepository extends AbstractRepository
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $search
|
* @param string $search
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function searchHotels($search, FilterSettings $filterSettings)
|
public function searchHotels($search, array $filterSettings)
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
@@ -166,12 +165,12 @@ class DateRepository extends AbstractRepository
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $search
|
* @param string $search
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param array $excludedConceptUids
|
* @param array $excludedConceptUids
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function searchProducts($search, FilterSettings $filterSettings, $excludedConceptUids = [])
|
public function searchProducts($search, array $filterSettings, $excludedConceptUids = [])
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
@@ -215,12 +214,12 @@ class DateRepository extends AbstractRepository
|
|||||||
/**
|
/**
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string $search
|
* @param string $search
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param array $excludedRegionUids
|
* @param array $excludedRegionUids
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function searchDestinations($type, $search, FilterSettings $filterSettings, $excludedRegionUids = [])
|
public function searchDestinations($type, $search, array $filterSettings, $excludedRegionUids = [])
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace EP\EpProducts\Domain\Repository;
|
|||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\Date;
|
use EP\EpProducts\Domain\Model\Date;
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use EP\EpProducts\Domain\Model\Hotel;
|
use EP\EpProducts\Domain\Model\Hotel;
|
||||||
use EP\EpProducts\Domain\Model\Product;
|
use EP\EpProducts\Domain\Model\Product;
|
||||||
use TYPO3\CMS\Core\Database\Connection;
|
use TYPO3\CMS\Core\Database\Connection;
|
||||||
@@ -78,12 +77,12 @@ class ProductRepository extends AbstractRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param array $excludedConceptUids
|
* @param array $excludedConceptUids
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function getSearchResult(FilterSettings $filterSettings, $excludedConceptUids = [])
|
public function getSearchResult(array $filterSettings, $excludedConceptUids = [])
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
@@ -131,13 +130,13 @@ class ProductRepository extends AbstractRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param array $excludedConceptUids
|
* @param array $excludedConceptUids
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function getTeasers(FilterSettings $filterSettings, $excludedConceptUids = [], $limit = 0)
|
public function getTeasers(array $filterSettings, $excludedConceptUids = [], $limit = 0)
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
@@ -173,12 +172,12 @@ class ProductRepository extends AbstractRepository
|
|||||||
$query->setMaxResults($limit);
|
$query->setMaxResults($limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$filterSettings->getProductUid()) {
|
if (empty($filterSettings['productUid'])) {
|
||||||
$query->andWhere('product_searchable = 1');
|
$query->andWhere('product_searchable = 1');
|
||||||
} else {
|
} else {
|
||||||
$query
|
$query
|
||||||
->andWhere('product = :productUid')
|
->andWhere('product = :productUid')
|
||||||
->setParameter('productUid', $filterSettings->getProductUid())
|
->setParameter('productUid', (int)$filterSettings['productUid'])
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,18 +194,18 @@ class ProductRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->execute()->fetchAllAssociative(\PDO::FETCH_ASSOC);
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Product $product
|
* @param Product $product
|
||||||
* @param Hotel $hotel
|
* @param Hotel $hotel
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param Date $date
|
* @param Date $date
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function getPricetable(Product $product, Hotel $hotel, FilterSettings $filterSettings, Date $date = null)
|
public function getPricetable(Product $product, Hotel $hotel, array $filterSettings, Date $date = null)
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
@@ -248,11 +247,11 @@ class ProductRepository extends AbstractRepository
|
|||||||
/**
|
/**
|
||||||
* @param Product $product
|
* @param Product $product
|
||||||
* @param Hotel $hotel
|
* @param Hotel $hotel
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function getAvailableDates(Product $product, Hotel $hotel, FilterSettings $filterSettings)
|
public function getAvailableDates(Product $product, Hotel $hotel, array $filterSettings)
|
||||||
{
|
{
|
||||||
$qb = $this->getDbConnection()->createQueryBuilder();
|
$qb = $this->getDbConnection()->createQueryBuilder();
|
||||||
|
|
||||||
|
|||||||
@@ -61,22 +61,23 @@ class FilterService implements SingletonInterface
|
|||||||
bool $respectBookableDaterange = true,
|
bool $respectBookableDaterange = true,
|
||||||
string $dateFromYmd = null,
|
string $dateFromYmd = null,
|
||||||
string $dateToYmd = null
|
string $dateToYmd = null
|
||||||
): FilterSettings {
|
): array {
|
||||||
|
$filterSettings = [];
|
||||||
|
|
||||||
[ $dateFrom, $dateTo ] = $this->constrainDateRange($this->dateRepository->getDateRange());
|
[ $dateFrom, $dateTo ] = $this->constrainDateRange($this->dateRepository->getDateRange());
|
||||||
|
|
||||||
if (null !== $dateFromYmd) {
|
if (null !== $dateFromYmd) {
|
||||||
$dateFrom = new \DateTime($dateFromYmd);
|
$filterSettings['dateFrom'] = $dateFromYmd;
|
||||||
} elseif (!$respectBookableDaterange) {
|
} elseif (!$respectBookableDaterange) {
|
||||||
$dateFrom = new \DateTime('now');
|
$dateFrom = (new \DateTime('now'))->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $dateToYmd) {
|
if (null !== $dateToYmd) {
|
||||||
$dateTo = new \DateTime($dateToYmd);
|
$filterSettings['dateTo'] = $dateToYmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filterSettings = new FilterSettings($dateFrom, $dateTo);
|
|
||||||
if ($forcedConceptUids) {
|
if ($forcedConceptUids) {
|
||||||
$filterSettings->setConceptUids($forcedConceptUids);
|
$filterSettings['conceptUids'] = $forcedConceptUids;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $filterSettings;
|
return $filterSettings;
|
||||||
@@ -84,7 +85,7 @@ class FilterService implements SingletonInterface
|
|||||||
|
|
||||||
public function getFilterOptions
|
public function getFilterOptions
|
||||||
(
|
(
|
||||||
FilterSettings $filterSettings,
|
array $filterSettings,
|
||||||
array $excludedConceptUids = [],
|
array $excludedConceptUids = [],
|
||||||
array $excludedRegionUids = [],
|
array $excludedRegionUids = [],
|
||||||
array $forcedConceptUids = []
|
array $forcedConceptUids = []
|
||||||
@@ -250,36 +251,36 @@ class FilterService implements SingletonInterface
|
|||||||
return [$dateFrom, $dateTo];
|
return [$dateFrom, $dateTo];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFiltersettingsFromSettings(array $settings): FilterSettings
|
public function getFiltersettingsFromSettings(array $settings): array
|
||||||
{
|
{
|
||||||
$filterSettings = new FilterSettings();
|
$filterSettings = [];
|
||||||
if (isset($settings['regionUid']) && (int) $settings['regionUid'] > 0) {
|
if (isset($settings['regionUid']) && (int) $settings['regionUid'] > 0) {
|
||||||
$filterSettings->setRegionUids([$settings['regionUid']]);
|
$filterSettings['regionUids'] = [ $settings['regionUid'] ];
|
||||||
} elseif (isset($settings['countryUid']) && (int) $settings['countryUid'] > 0) {
|
} elseif (isset($settings['countryUid']) && (int) $settings['countryUid'] > 0) {
|
||||||
$filterSettings->setCountryUids([$settings['countryUid']]);
|
$filterSettings['countryUids'] = [ $settings['countryUid'] ];
|
||||||
} elseif (isset($settings['hotelUid']) && (int) $settings['hotelUid'] > 0) {
|
} elseif (isset($settings['hotelUid']) && (int) $settings['hotelUid'] > 0) {
|
||||||
$filterSettings->setHotelUid($settings['hotelUid']);
|
$filterSettings['hotelUid'] = $settings['hotelUid'];
|
||||||
}
|
}
|
||||||
$conceptUids = GeneralUtility::trimExplode(',', $settings['conceptUid'], true);
|
$conceptUids = GeneralUtility::trimExplode(',', $settings['conceptUid'], true);
|
||||||
if ($conceptUids) {
|
if ($conceptUids) {
|
||||||
$filterSettings->setConceptUids($conceptUids);
|
$filterSettings['conceptUids'] = $conceptUids;
|
||||||
}
|
}
|
||||||
if (isset($settings['dateFrom']) && (int) $settings['dateFrom'] > 0) {
|
if (isset($settings['dateFrom']) && (int) $settings['dateFrom'] > 0) {
|
||||||
$dateFrom = new \DateTime();
|
$dateFrom = new \DateTime();
|
||||||
$dateFrom->setTimestamp($settings['dateFrom']);
|
$dateFrom->setTimestamp($settings['dateFrom']);
|
||||||
$filterSettings->setDateFrom($dateFrom);
|
$filterSettings['dateFrom'] = $dateFrom->format('Y-m-d');
|
||||||
}
|
}
|
||||||
if (isset($settings['dateTo']) && (int) $settings['dateTo'] > 0) {
|
if (isset($settings['dateTo']) && (int) $settings['dateTo'] > 0) {
|
||||||
$dateTo = new \DateTime();
|
$dateTo = new \DateTime();
|
||||||
$dateTo->setTimestamp($settings['dateTo']);
|
$dateTo->setTimestamp($settings['dateTo']);
|
||||||
$filterSettings->setDateTo($dateTo);
|
$filterSettings['dateTo'] = $dateTo->format('Y-m-d');
|
||||||
}
|
}
|
||||||
if (isset($settings['busAvailable']) && (bool) $settings['busAvailable'] === true) {
|
if (isset($settings['busAvailable']) && (bool) $settings['busAvailable'] === true) {
|
||||||
$filterSettings->setBus(true);
|
$filterSettings['bus'] = true;
|
||||||
}
|
}
|
||||||
if (array_key_exists('hotelTypes', $settings)) {
|
if (array_key_exists('hotelTypes', $settings)) {
|
||||||
$hotelTypes = GeneralUtility::trimExplode(',', $settings['hotelTypes'], true);
|
$hotelTypes = GeneralUtility::trimExplode(',', $settings['hotelTypes'], true);
|
||||||
$filterSettings->setHotelTypes($hotelTypes);
|
$filterSettings['hotelTypes'] = $hotelTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $filterSettings;
|
return $filterSettings;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace EP\EpProducts\Service;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
class FilterSettingsEncoder
|
class FilterSettingsEncoder
|
||||||
@@ -55,18 +54,20 @@ class FilterSettingsEncoder
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function encode(FilterSettings $filterSettings): string
|
public static function encode(array $filterSettings): string
|
||||||
{
|
{
|
||||||
$encoded = [];
|
$encoded = [];
|
||||||
foreach (static::getMapping() as $property)
|
foreach (static::getMapping() as $property) {
|
||||||
{
|
|
||||||
[$name, $type] = $property;
|
[$name, $type] = $property;
|
||||||
$method = 'get' . ucfirst($name);
|
if (!isset($filterSettings[$name])) {
|
||||||
$value = $filterSettings->{$method}();
|
$encoded[] = '';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$value = $filterSettings[$name];
|
||||||
if ($type === 'array') {
|
if ($type === 'array') {
|
||||||
$encoded[] = implode(';', $value);
|
$encoded[] = implode(';', $value);
|
||||||
} elseif ($type === 'date') {
|
} elseif ($type === 'date') {
|
||||||
$encoded[] = ($value !== null) ? $value->format('Y-m-d') : '';
|
$encoded[] = $value ?? '';
|
||||||
} else {
|
} else {
|
||||||
$encoded[] = preg_replace('/[\r\n]/', '', $value);
|
$encoded[] = preg_replace('/[\r\n]/', '', $value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ class ProductDataService implements SingletonInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FilterSettings $filterSettings
|
* @param array $filterSettings
|
||||||
* @param array $excludedConceptUids
|
* @param array $excludedConceptUids
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getTeasergroup(FilterSettings $filterSettings, $excludedConceptUids = [], $limit = 0)
|
public function getTeasergroup(array $filterSettings, $excludedConceptUids = [], $limit = 0)
|
||||||
{
|
{
|
||||||
$teaserData = $this->productRepository->getTeasers($filterSettings, $excludedConceptUids);
|
$teaserData = $this->productRepository->getTeasers($filterSettings, $excludedConceptUids);
|
||||||
return $this->preprocessTeasergroup($teaserData, $limit);
|
return $this->preprocessTeasergroup($teaserData, $limit);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class SearchResultService implements SingletonInterface
|
|||||||
$this->flagIconService = $flagIconService;
|
$this->flagIconService = $flagIconService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getResult(FilterSettings $filterSettings, array $excludedConceptUids = []): SearchResult
|
public function getResult(array $filterSettings, array $excludedConceptUids = []): SearchResult
|
||||||
{
|
{
|
||||||
$searchResultData = $this->productRepository->getSearchResult($filterSettings, $excludedConceptUids);
|
$searchResultData = $this->productRepository->getSearchResult($filterSettings, $excludedConceptUids);
|
||||||
|
|
||||||
|
|||||||
@@ -48,16 +48,10 @@ class SearchResultUrlService implements SingletonInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param SearchResult $searchResult
|
* @param SearchResult $searchResult
|
||||||
* @param array $options
|
* @param int $defaultDetailPageUid
|
||||||
*/
|
*/
|
||||||
public function process(SearchResult $searchResult, array $options): void
|
public function process(SearchResult $searchResult, $defaultDetailPageUid): void
|
||||||
{
|
{
|
||||||
$optionsResolver = new OptionsResolver();
|
|
||||||
$optionsResolver->setRequired([ 'defaultDetailPageUid' ]);
|
|
||||||
$resolvedOptions = $optionsResolver->resolve($options);
|
|
||||||
|
|
||||||
$defaultDetailPageUid = $resolvedOptions['defaultDetailPageUid'];
|
|
||||||
|
|
||||||
$data = $searchResult->getData();
|
$data = $searchResult->getData();
|
||||||
|
|
||||||
foreach ($data as $conceptUid => $conceptData) {
|
foreach ($data as $conceptUid => $conceptData) {
|
||||||
|
|||||||
@@ -32,19 +32,21 @@ class DateUtility
|
|||||||
|
|
||||||
public static function formatDateRange
|
public static function formatDateRange
|
||||||
(
|
(
|
||||||
\DateTime $dateFrom = null,
|
?string $dateFromString = '',
|
||||||
\DateTime $dateTo = null,
|
?string $dateToString = '',
|
||||||
bool $includeLabel = true,
|
bool $includeLabel = true,
|
||||||
string $format = 'd.m.Y'
|
string $format = 'd.m.Y'
|
||||||
): string {
|
): string {
|
||||||
if ($dateFrom === null && $dateTo === null) {
|
if (empty($dateFromString) && empty($dateToString)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
$dateFrom = new \DateTime($dateFromString);
|
||||||
|
$dateTo = new \DateTime($dateToString);
|
||||||
$label = $includeLabel ? 'im Zeitraum ' : '';
|
$label = $includeLabel ? 'im Zeitraum ' : '';
|
||||||
if ($dateFrom !== null && $dateTo === null) {
|
if ($dateFromString !== '' && $dateToString === '') {
|
||||||
return $label . 'ab ' . $dateFrom->format($format);
|
return $label . 'ab ' . $dateFrom->format($format);
|
||||||
}
|
}
|
||||||
if ($dateFrom === null && $dateTo !== null) {
|
if ($dateFromString === '' && $dateToString !== '') {
|
||||||
return $label . '-' . $dateTo->format($format);
|
return $label . '-' . $dateTo->format($format);
|
||||||
}
|
}
|
||||||
return $label . $dateFrom->format($format) . '-' . $dateTo->format($format);
|
return $label . $dateFrom->format($format) . '-' . $dateTo->format($format);
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ class DateRangeViewHelper extends AbstractViewHelper
|
|||||||
{
|
{
|
||||||
parent::initializeArguments();
|
parent::initializeArguments();
|
||||||
|
|
||||||
$this->registerArgument('dateFrom', 'mixed', 'Date range start');
|
$this->registerArgument('dateFrom', 'string', 'Date range start');
|
||||||
$this->registerArgument('dateTo', 'mixed', 'Date range end');
|
$this->registerArgument('dateTo', 'string', 'Date range end');
|
||||||
$this->registerArgument('includeLabel', 'Bool', 'Whether to include a label', false, true);
|
$this->registerArgument('includeLabel', 'Bool', 'Whether to include a label', false, true);
|
||||||
$this->registerArgument('format', 'String', 'The date format', false, 'd.m.Y');
|
$this->registerArgument('format', 'String', 'The date format', false, 'd.m.Y');
|
||||||
}
|
}
|
||||||
@@ -56,27 +56,12 @@ class DateRangeViewHelper extends AbstractViewHelper
|
|||||||
array $arguments,
|
array $arguments,
|
||||||
\Closure $renderChildrenClosure,
|
\Closure $renderChildrenClosure,
|
||||||
RenderingContextInterface $renderingContext
|
RenderingContextInterface $renderingContext
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
$dateFrom = static::ensureDateObject($arguments['dateFrom']);
|
|
||||||
$dateTo = static::ensureDateObject($arguments['dateTo']);
|
|
||||||
|
|
||||||
return DateUtility::formatDateRange(
|
return DateUtility::formatDateRange(
|
||||||
$dateFrom,
|
$arguments['dateFrom'],
|
||||||
$dateTo,
|
$arguments['dateTo'],
|
||||||
$arguments['includeLabel'],
|
$arguments['includeLabel'],
|
||||||
$arguments['format']
|
$arguments['format']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function ensureDateObject($argument): \DateTime
|
|
||||||
{
|
|
||||||
if ($argument instanceof \DateTime) {
|
|
||||||
$dateTime = $argument;
|
|
||||||
} else {
|
|
||||||
$dateTime = new \DateTime($argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $dateTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,21 +14,12 @@ import Alpine from 'alpinejs'
|
|||||||
import parseAppConfig from './components/appconfig'
|
import parseAppConfig from './components/appconfig'
|
||||||
import initSliders from './components/sliders'
|
import initSliders from './components/sliders'
|
||||||
import appendPaCode from './components/pacode'
|
import appendPaCode from './components/pacode'
|
||||||
import scrollTop from './components/scoll-top'
|
|
||||||
import scrollTo from './components/scroll-to'
|
|
||||||
import sticky from './components/sticky'
|
|
||||||
import watchlistToggle from './components/watchlist-toggle'
|
import watchlistToggle from './components/watchlist-toggle'
|
||||||
import watchlistButton from './components/watchlist-button'
|
import watchlistButton from './components/watchlist-button'
|
||||||
import watchlist from './components/watchlist'
|
import watchlist from './components/watchlist'
|
||||||
import collapse from './components/collapse'
|
|
||||||
import fbpixel from './components/fbpixel'
|
|
||||||
import ajaxContent from './components/ajax-content'
|
|
||||||
import faq from './components/faq'
|
|
||||||
import osmMap from './components/osm-map'
|
|
||||||
import productDetail from './components/product-detail'
|
import productDetail from './components/product-detail'
|
||||||
import daytripDateSelect from './components/daytrip-date-select'
|
import daytripDateSelect from './components/daytrip-date-select'
|
||||||
import searchBar from './components/search-bar'
|
import searchBar from './components/search-bar'
|
||||||
import search from './components/search'
|
|
||||||
import calendar from './components/calendar'
|
import calendar from './components/calendar'
|
||||||
import contactForm from './components/contact-form'
|
import contactForm from './components/contact-form'
|
||||||
|
|
||||||
@@ -54,21 +45,12 @@ Alpine.store('show', {
|
|||||||
Alpine.store('watchlist', storedWatchlist)
|
Alpine.store('watchlist', storedWatchlist)
|
||||||
Alpine.store('filterSettings', defaultFilterSettings)
|
Alpine.store('filterSettings', defaultFilterSettings)
|
||||||
Alpine.store('filterOptions', defaultFilterOptions)
|
Alpine.store('filterOptions', defaultFilterOptions)
|
||||||
Alpine.data('scrollTop', scrollTop)
|
|
||||||
Alpine.data('scrollTo', scrollTo)
|
|
||||||
Alpine.data('sticky', sticky)
|
|
||||||
Alpine.data('watchlistToggle', watchlistToggle)
|
Alpine.data('watchlistToggle', watchlistToggle)
|
||||||
Alpine.data('watchlistButton', watchlistButton)
|
Alpine.data('watchlistButton', watchlistButton)
|
||||||
Alpine.data('watchlist', watchlist)
|
Alpine.data('watchlist', watchlist)
|
||||||
Alpine.data('collapse', collapse)
|
|
||||||
Alpine.data('fbpixel', fbpixel)
|
|
||||||
Alpine.data('ajaxContent', ajaxContent)
|
|
||||||
Alpine.data('faq', faq)
|
|
||||||
Alpine.data('osmMap', osmMap)
|
|
||||||
Alpine.data('productDetail', productDetail)
|
Alpine.data('productDetail', productDetail)
|
||||||
Alpine.data('daytripDateSelect', daytripDateSelect)
|
Alpine.data('daytripDateSelect', daytripDateSelect)
|
||||||
Alpine.data('searchBar', searchBar)
|
Alpine.data('searchBar', searchBar)
|
||||||
Alpine.data('search', search)
|
|
||||||
Alpine.data('calendar', calendar)
|
Alpine.data('calendar', calendar)
|
||||||
Alpine.data('contactForm', contactForm)
|
Alpine.data('contactForm', contactForm)
|
||||||
Alpine.start()
|
Alpine.start()
|
||||||
@@ -77,3 +59,10 @@ Glightbox({
|
|||||||
selector: 'data-glightbox',
|
selector: 'data-glightbox',
|
||||||
slideEffect: 'fade',
|
slideEffect: 'fade',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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))
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import axios from 'axios'
|
|
||||||
import { debounce } from './throttle-debounce'
|
|
||||||
|
|
||||||
export default uri => ({
|
|
||||||
uri,
|
|
||||||
loaded: false,
|
|
||||||
loading: false,
|
|
||||||
init() {
|
|
||||||
window.addEventListener('scroll', debounce(() => {
|
|
||||||
if (true === this.loaded) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.load()
|
|
||||||
}, 250))
|
|
||||||
},
|
|
||||||
load() {
|
|
||||||
if (false === this.inViewport()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.loading = true
|
|
||||||
axios({
|
|
||||||
url: this.uri,
|
|
||||||
responseType: 'text'
|
|
||||||
}).then((response) => {
|
|
||||||
this.loaded = true
|
|
||||||
this.$refs.container.innerHTML = response.data
|
|
||||||
this.$refs.trigger.remove()
|
|
||||||
}).catch(() => {
|
|
||||||
this.loaded = false
|
|
||||||
}).finally(() => {
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
inViewport () {
|
|
||||||
const rect = this.$refs.trigger.getBoundingClientRect()
|
|
||||||
|
|
||||||
return (
|
|
||||||
rect.top >= 0 &&
|
|
||||||
rect.left >= 0 &&
|
|
||||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
||||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { debounce } from './throttle-debounce'
|
|
||||||
|
|
||||||
export default (isCollapsed = true, until = null, from = null) => ({
|
|
||||||
collapsed: isCollapsed,
|
|
||||||
collapsedUntil: until,
|
|
||||||
collapsedFrom: from,
|
|
||||||
init() {
|
|
||||||
this.checkBreakpoints()
|
|
||||||
window.addEventListener('resize', debounce(() => {
|
|
||||||
this.checkBreakpoints()
|
|
||||||
}, 250))
|
|
||||||
},
|
|
||||||
checkBreakpoints() {
|
|
||||||
if (null !== this.collapsedUntil) {
|
|
||||||
this.collapsed = window.innerWidth < parseInt(this.collapsedUntil)
|
|
||||||
}
|
|
||||||
if (null !== this.collapsedFrom) {
|
|
||||||
this.collapsed = window.innerWidth > parseInt(this.collapsedFrom)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trigger: {
|
|
||||||
['@click.prevent']() {
|
|
||||||
this.collapsed = !this.collapsed
|
|
||||||
},
|
|
||||||
},
|
|
||||||
container: {
|
|
||||||
['x-show']() {
|
|
||||||
return this.collapsed === false
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { debounce } from './throttle-debounce'
|
|
||||||
|
|
||||||
export default () => ({
|
|
||||||
query: '',
|
|
||||||
init() {
|
|
||||||
this.entries = this.$el.querySelectorAll('[x-data^="collapse"]')
|
|
||||||
this.$watch('query', debounce(value => {
|
|
||||||
if (value.length < 3) {
|
|
||||||
this.entries.forEach(entry => {
|
|
||||||
entry.classList.remove('hidden')
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const pattern = new RegExp(value, 'i')
|
|
||||||
this.entries.forEach(entry => {
|
|
||||||
const question = entry.childNodes[0].textContent
|
|
||||||
const answer = entry.childNodes[1].textContent
|
|
||||||
if (!question.match(pattern) && !answer.match(pattern)) {
|
|
||||||
entry.classList.add('hidden')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, 200))
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
export default props => ({
|
|
||||||
init() {
|
|
||||||
fbq('track', 'ViewContent', props)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
import L from 'leaflet';
|
|
||||||
|
|
||||||
export default () => ({
|
|
||||||
init() {
|
|
||||||
this.lat = this.$el.dataset.lat
|
|
||||||
this.lng = this.$el.dataset.lng
|
|
||||||
this.zoom = this.$el.dataset.zoom || 12
|
|
||||||
this.externalLink = this.$el.dataset.link
|
|
||||||
this.markers = this.$el.dataset.markers ? JSON.parse(this.$el.dataset.markers) : []
|
|
||||||
this.map = L.map(this.$el, {
|
|
||||||
scrollWheelZoom: false
|
|
||||||
});
|
|
||||||
this.map.setZoom(this.zoom);
|
|
||||||
if (this.lat && this.lng) {
|
|
||||||
const position = L.latLng(this.lat, this.lng);
|
|
||||||
const marker = L.marker(position);
|
|
||||||
if (this.externalLink) {
|
|
||||||
marker.on('click', () => {
|
|
||||||
window.open(this.externalLink, '_blank')
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
marker.on('click', () => {
|
|
||||||
window.open('https://www.google.com/maps/search/?api=1&zoom=15&query=' + this.lat + ',' + this.lng, '_blank')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
marker.addTo(this.map);
|
|
||||||
this.map.setView(position);
|
|
||||||
} else if (this.markers.length) {
|
|
||||||
const bounds = L.latLngBounds();
|
|
||||||
for (let item of this.markers) {
|
|
||||||
const position = L.latLng(item.lat, item.lng);
|
|
||||||
const marker = L.marker(position);
|
|
||||||
if (item.externalLink) {
|
|
||||||
marker.on('click', () => {
|
|
||||||
window.open(item.externalLink, '_blank');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const popupContent = '<div><strong>' + item.name + '</strong><br>' + item.teaser +
|
|
||||||
'<br><a href="' + item.uri + '">zu den Details</a></div>';
|
|
||||||
marker.bindPopup(popupContent);
|
|
||||||
}
|
|
||||||
marker.addTo(this.map);
|
|
||||||
bounds.extend(position);
|
|
||||||
}
|
|
||||||
this.map.fitBounds(bounds);
|
|
||||||
}
|
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
|
|
||||||
maxZoom: 19,
|
|
||||||
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
||||||
}).addTo(this.map);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { debounce } from './throttle-debounce'
|
|
||||||
|
|
||||||
export default () => ({
|
|
||||||
show: false,
|
|
||||||
trigger: {
|
|
||||||
['@click.prevent']() {
|
|
||||||
window.scroll({top: 0, left: 0, behavior: 'smooth'})
|
|
||||||
},
|
|
||||||
['x-show']() {
|
|
||||||
return this.show
|
|
||||||
}
|
|
||||||
},
|
|
||||||
init() {
|
|
||||||
window.addEventListener('scroll', debounce(() => {
|
|
||||||
this.show = window.scrollY > window.innerHeight / 3
|
|
||||||
}, 250))
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
export default targetId => ({
|
|
||||||
targetId,
|
|
||||||
init() {
|
|
||||||
this.$el.addEventListener('click', e => {
|
|
||||||
e.preventDefault()
|
|
||||||
document.getElementById(this.targetId).scrollIntoView({behavior: 'smooth'})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { debounce } from './throttle-debounce'
|
|
||||||
|
|
||||||
export default offset => ({
|
|
||||||
offset,
|
|
||||||
sticky: false,
|
|
||||||
init() {
|
|
||||||
window.addEventListener('scroll', debounce(() => {
|
|
||||||
this.sticky = window.scrollY > this.offset
|
|
||||||
}, 250))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useDebounce } from 'stimulus-use'
|
||||||
|
import { useFetch} from '../mixins/use_fetch'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static debounces = [ 'load' ]
|
||||||
|
|
||||||
|
static values = {
|
||||||
|
uri: String,
|
||||||
|
loading: Boolean,
|
||||||
|
loaded: Boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
static targets = [ 'container', 'trigger' ]
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useDebounce(this)
|
||||||
|
useFetch(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
this.load()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
window.removeEventListener('scroll', () => {
|
||||||
|
this.load()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
load() {
|
||||||
|
if (true === this.loadedValue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (false === this.inViewport()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loadHtml()
|
||||||
|
}
|
||||||
|
|
||||||
|
loadHtml() {
|
||||||
|
this.loadingValue = true
|
||||||
|
fetch(this.uriValue)
|
||||||
|
.then(this.checkStatus)
|
||||||
|
.then(this.parseHTML)
|
||||||
|
.then(html => {
|
||||||
|
this.loadedValue = true
|
||||||
|
this.containerTarget.innerHTML = html
|
||||||
|
this.triggerTarget.remove()
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loadedValue = false
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loadingValue = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
inViewport() {
|
||||||
|
const rect = this.triggerTarget.getBoundingClientRect()
|
||||||
|
return (
|
||||||
|
rect.top >= 0 &&
|
||||||
|
rect.left >= 0 &&
|
||||||
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||||
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useWindowResize, useDebounce } from 'stimulus-use'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static debounces = [ 'checkBreakpoints' ]
|
||||||
|
|
||||||
|
static values = {
|
||||||
|
collapsed: Boolean,
|
||||||
|
from: Number,
|
||||||
|
until: Number,
|
||||||
|
}
|
||||||
|
|
||||||
|
static targets = [ 'container', 'icon' ]
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useWindowResize(this)
|
||||||
|
useDebounce(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.toggleByWindowWidth(window.innerWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
windowResize({ width, height, event }) {
|
||||||
|
this.toggleByWindowWidth(width)
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
this.collapsedValue = !this.collapsedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleByWindowWidth(width) {
|
||||||
|
if (0 !== this.untilValue) {
|
||||||
|
this.collapsedValue = width < this.untilValue
|
||||||
|
}
|
||||||
|
if (0 !== this.fromValue) {
|
||||||
|
this.collapsedValue = width > this.fromValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collapsedValueChanged() {
|
||||||
|
this.containerTarget.classList.toggle('hidden', this.collapsedValue === true)
|
||||||
|
if (this.hasIconTarget) {
|
||||||
|
this.iconTarget.classList.toggle('rotate-180', this.collapsedValue === false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useDispatch } from 'stimulus-use'
|
||||||
|
import flatpickr from 'flatpickr'
|
||||||
|
import { German } from 'flatpickr/dist/l10n/de'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static targets = [ 'field' ]
|
||||||
|
|
||||||
|
static values = {
|
||||||
|
minDate: String,
|
||||||
|
dateFrom: String,
|
||||||
|
dateTo: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useDispatch(this)
|
||||||
|
|
||||||
|
this.picker = flatpickr(this.fieldTarget, {
|
||||||
|
mode: 'range',
|
||||||
|
locale: German,
|
||||||
|
inline: true,
|
||||||
|
minDate: this.minDateValue,
|
||||||
|
onChange: selectedDates => {
|
||||||
|
if (selectedDates.length === 2) {
|
||||||
|
this.dispatch('range-select', {
|
||||||
|
from: flatpickr.formatDate(selectedDates[0], 'Y-m-d'),
|
||||||
|
to: flatpickr.formatDate(selectedDates[1], 'Y-m-d'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
if ('' !== this.dateFromValue && '' !== this.dateToValue) {
|
||||||
|
let dateFrom = new Date(this.dateFromValue)
|
||||||
|
let dateTo = new Date(this.dateToValue)
|
||||||
|
this.picker.setDate([ dateFrom, dateTo ])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectPreset(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
const preset = JSON.parse(e.currentTarget.dataset.preset)
|
||||||
|
this.picker.setDate([ new Date(preset.dateFrom), new Date(preset.dateTo) ])
|
||||||
|
this.dispatch('range-select', { from: preset.dateFrom, to: preset.dateTo })
|
||||||
|
}
|
||||||
|
|
||||||
|
reset(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.picker.clear()
|
||||||
|
this.picker.jumpToDate()
|
||||||
|
this.dispatch('range-select', { from: null, to: null })
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useDebounce } from 'stimulus-use'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static debounces = [ 'filter' ]
|
||||||
|
|
||||||
|
static targets = [ 'entry' ]
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useDebounce(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
filter(e) {
|
||||||
|
let value = e.target.value
|
||||||
|
if (value.length < 3) {
|
||||||
|
this.entryTargets.forEach(entry => {
|
||||||
|
entry.classList.remove('hidden')
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const pattern = new RegExp(value, 'i')
|
||||||
|
this.entryTargets.forEach(entry => {
|
||||||
|
const question = entry.childNodes[0].textContent
|
||||||
|
const answer = entry.childNodes[1].textContent
|
||||||
|
if (!question.match(pattern) && !answer.match(pattern)) {
|
||||||
|
entry.classList.add('hidden')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static values = { props: Object }
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
fbq('track', 'ViewContent', this.propsValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import L from 'leaflet'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static values = {
|
||||||
|
lat: Number,
|
||||||
|
lng: Number,
|
||||||
|
zoom: Number,
|
||||||
|
externalLink: String,
|
||||||
|
markers: Array,
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.map = L.map(this.element, {
|
||||||
|
scrollWheelZoom: false
|
||||||
|
})
|
||||||
|
const zoom = this.hasZoomValue ? this.zoomValue : 12
|
||||||
|
this.map.setZoom(zoom)
|
||||||
|
if (this.hasLatValue && this.hasLngValue) {
|
||||||
|
const position = L.latLng(this.latValue, this.lngValue)
|
||||||
|
const marker = L.marker(position)
|
||||||
|
if (this.hasExternalLinkValue) {
|
||||||
|
marker.on('click', () => {
|
||||||
|
window.open(this.externalLinkValue, '_blank')
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
marker.on('click', () => {
|
||||||
|
window.open('https://www.google.com/maps/search/?api=1&zoom=15&query=' + this.latValue + ',' + this.lngValue, '_blank')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
marker.addTo(this.map)
|
||||||
|
this.map.setView(position)
|
||||||
|
} else if (this.hasMarkersValue && this.markersValue.length) {
|
||||||
|
const bounds = L.latLngBounds()
|
||||||
|
for (let item of this.markers) {
|
||||||
|
const position = L.latLng(item.lat, item.lng)
|
||||||
|
const marker = L.marker(position)
|
||||||
|
if (item.externalLink) {
|
||||||
|
marker.on('click', () => {
|
||||||
|
window.open(item.externalLink, '_blank')
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const popupContent = '<div><strong>' + item.name + '</strong><br>' + item.teaser +
|
||||||
|
'<br><a href="' + item.uri + '">zu den Details</a></div>'
|
||||||
|
marker.bindPopup(popupContent)
|
||||||
|
}
|
||||||
|
marker.addTo(this.map)
|
||||||
|
bounds.extend(position)
|
||||||
|
}
|
||||||
|
this.map.fitBounds(bounds)
|
||||||
|
}
|
||||||
|
L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
|
||||||
|
maxZoom: 19,
|
||||||
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||||
|
}).addTo(this.map)
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static values = { target: String }
|
||||||
|
|
||||||
|
scroll() {
|
||||||
|
document.getElementById(this.targetValue).scrollIntoView({ behavior: 'smooth' })
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useDebounce} from 'stimulus-use'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static debounces = [ 'toggle' ]
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useDebounce(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
this.toggle()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
this.element.classList.toggle('hidden', window.scrollY < window.innerHeight / 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll() {
|
||||||
|
window.scroll({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useDispatch } from 'stimulus-use'
|
||||||
|
import { useFetch } from '../mixins/use_fetch'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static values = {
|
||||||
|
loading: Boolean,
|
||||||
|
uri: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
static targets = [
|
||||||
|
'form',
|
||||||
|
'resultsContainer',
|
||||||
|
'loadingIndicator',
|
||||||
|
'dateFrom',
|
||||||
|
'dateTo',
|
||||||
|
]
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useFetch(this)
|
||||||
|
useDispatch(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
filter() {
|
||||||
|
this.loadingValue = true
|
||||||
|
let data = new FormData(this.formTarget)
|
||||||
|
fetch(this.uriValue, { method: 'POST', body: data })
|
||||||
|
.then(this.checkStatus)
|
||||||
|
.then(this.parseHTML)
|
||||||
|
.then(html => {
|
||||||
|
this.resultsContainerTarget.innerHTML = html
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loadingValue = false
|
||||||
|
this.element.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.filter()
|
||||||
|
}
|
||||||
|
|
||||||
|
selectDateRange(e) {
|
||||||
|
this.dateFromTarget.value = e.detail.from
|
||||||
|
this.dateToTarget.value = e.detail.to
|
||||||
|
this.filter()
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingValueChanged() {
|
||||||
|
this.loadingIndicatorTarget.classList.toggle('hidden', this.loadingValue === false)
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import { Controller } from 'stimulus'
|
||||||
|
import { useDebounce } from 'stimulus-use'
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static debounces = [ 'toggle' ]
|
||||||
|
|
||||||
|
static classes = [ 'sticky' ]
|
||||||
|
|
||||||
|
static values = {
|
||||||
|
sticky: Boolean,
|
||||||
|
offset: Number,
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
useDebounce(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
this.toggle()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
window.removeEventListener('scroll', () => {
|
||||||
|
this.toggle()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
this.stickyValue = window.scrollY > this.offsetValue
|
||||||
|
}
|
||||||
|
|
||||||
|
stickyValueChanged() {
|
||||||
|
this.element.classList.toggle(this.stickyClass, this.stickyValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export const useConfig = controller => {
|
||||||
|
Object.assign(controller, {
|
||||||
|
getConfig() {
|
||||||
|
const configElement = document.getElementById('appconfig')
|
||||||
|
if (null === configElement) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
return JSON.parse(configElement.innerHTML)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export const useDebounce = controller => {
|
||||||
|
Object.assign(controller, {
|
||||||
|
debounce(callback, interval) {
|
||||||
|
let debounceId
|
||||||
|
return (...args) => {
|
||||||
|
clearTimeout(debounceId)
|
||||||
|
debounceId = setTimeout(() => callback.apply(this, args), interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import 'whatwg-fetch'
|
||||||
|
|
||||||
|
export const useFetch = controller => {
|
||||||
|
Object.assign(controller, {
|
||||||
|
checkStatus(response) {
|
||||||
|
if (response.status >= 200 && response.status < 300) {
|
||||||
|
return response
|
||||||
|
} else {
|
||||||
|
const error = new Error(response.statusText)
|
||||||
|
error.response = response
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseJSON(response) {
|
||||||
|
return response.json()
|
||||||
|
},
|
||||||
|
parseHTML(response) {
|
||||||
|
return response.text()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
+2
-18
@@ -1,27 +1,11 @@
|
|||||||
.bg-winter {
|
.bg-winter {
|
||||||
@apply relative bg-cover bg-no-repeat bg-center;
|
@apply bg-cover bg-no-repeat bg-center;
|
||||||
background-image: url(../../images/background/winter.jpg);
|
background-image: url(../../images/background/winter.jpg);
|
||||||
z-index: -5;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
@apply block absolute top-0 left-0 inset-0 opacity-80;
|
|
||||||
@apply bg-ep-primary sbw:bg-sbw-primary uch:bg-uch-primary;
|
|
||||||
z-index: -10;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-pattern {
|
.bg-pattern {
|
||||||
@apply relative bg-cover bg-no-repeat bg-center;
|
@apply bg-cover bg-no-repeat bg-center;
|
||||||
background-image: url(../../images/background/pattern.jpg);
|
background-image: url(../../images/background/pattern.jpg);
|
||||||
z-index: -5;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
@apply block absolute top-0 left-0 inset-0 opacity-80;
|
|
||||||
@apply bg-ep-primary sbw:bg-sbw-primary uch:bg-uch-primary;
|
|
||||||
z-index: -10;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-header-season-w {
|
.bg-header-season-w {
|
||||||
|
|||||||
@@ -4,64 +4,66 @@
|
|||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
<div class="bg-winter my-2">
|
<div class="bg-winter my-2">
|
||||||
<f:if condition="{settings.themeKey} == 'ep'">
|
<div class="bg-ep-primary-80">
|
||||||
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
<f:if condition="{settings.themeKey} == 'ep'">
|
||||||
</f:if>
|
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
||||||
<div class="relative container grid grid-cols-2 gap-8" data-rte-content>
|
</f:if>
|
||||||
<div class="col-span-2 md:col-span-1">
|
<div class="relative container grid grid-cols-2 gap-8" data-rte-content>
|
||||||
<div class="relative max-w-md mx-auto mb-8">
|
<div class="col-span-2 md:col-span-1">
|
||||||
<f:if condition="{image}">
|
<div class="relative max-w-md mx-auto mb-8">
|
||||||
<f:then>
|
<f:if condition="{image}">
|
||||||
<img class="block rounded-full w-full h-auto lazyload"
|
<f:then>
|
||||||
data-src="{f:uri.image(image: image, width: '400', height: '400c')}"
|
<img class="block rounded-full w-full h-auto lazyload"
|
||||||
alt="{image.alternative}" title="{image.title}">
|
data-src="{f:uri.image(image: image, width: '400', height: '400c')}"
|
||||||
</f:then>
|
alt="{image.alternative}" title="{image.title}">
|
||||||
<f:else>
|
</f:then>
|
||||||
<img src="https://placehold.it/800x600" alt="">
|
<f:else>
|
||||||
</f:else>
|
<img src="https://placehold.it/800x600" alt="">
|
||||||
</f:if>
|
</f:else>
|
||||||
<a href="tel:{settings.phoneNumber -> v:format.pregReplace(pattern: '/[\-\s]/', replacement: '')}"
|
</f:if>
|
||||||
rel="nofollow"
|
<a href="tel:{settings.phoneNumber -> v:format.pregReplace(pattern: '/[\-\s]/', replacement: '')}"
|
||||||
class="absolute bottom-0 left-1/2 transform -translate-x-1/2 -mb-8 rounded-full py-4 px-6 bg-ep-secondary sbw:bg-sbw-secondary uch:bg-uch-secondary flex items-center space-x-2">
|
rel="nofollow"
|
||||||
<svg class="w-10 h-10 text-white">
|
class="absolute bottom-0 left-1/2 transform -translate-x-1/2 -mb-8 rounded-full py-4 px-6 bg-ep-secondary sbw:bg-sbw-secondary uch:bg-uch-secondary flex items-center space-x-2">
|
||||||
<use href="#icon-phone"></use>
|
<svg class="w-10 h-10 text-white">
|
||||||
</svg>
|
<use href="#icon-phone"></use>
|
||||||
<div class="text-center text-white">
|
</svg>
|
||||||
|
<div class="text-center text-white">
|
||||||
<span class="block whitespace-nowrap">
|
<span class="block whitespace-nowrap">
|
||||||
Ihr habt Fragen?
|
Ihr habt Fragen?
|
||||||
</span>
|
</span>
|
||||||
<span class="block whitespace-nowrap">
|
<span class="block whitespace-nowrap">
|
||||||
Wir helfen euch gerne!
|
Wir helfen euch gerne!
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-span-2 md:col-span-1">
|
||||||
<div class="col-span-2 md:col-span-1">
|
|
||||||
<span class="headline--secondary font-light text-white">
|
<span class="headline--secondary font-light text-white">
|
||||||
{data.subheadline}
|
{data.subheadline}
|
||||||
</span>
|
</span>
|
||||||
<span class="headline--secondary uppercase font-light text-white mb-4">
|
<span class="headline--secondary uppercase font-light text-white mb-4">
|
||||||
{data.headline}
|
{data.headline}
|
||||||
</span>
|
</span>
|
||||||
<div class="text-white" data-rte-content>
|
<div class="text-white" data-rte-content>
|
||||||
{data.bodytext -> f:format.html()}
|
{data.bodytext -> f:format.html()}
|
||||||
</div>
|
|
||||||
<f:if condition="{data.flexForm.buttons}">
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-8">
|
|
||||||
<f:for each="{data.flexForm.buttons}" as="button">
|
|
||||||
<f:link.typolink parameter="{button.container.link}"
|
|
||||||
class="button shadow-lg">
|
|
||||||
{button.container.label}
|
|
||||||
</f:link.typolink>
|
|
||||||
</f:for>
|
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
<f:if condition="{data.flexForm.buttons}">
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-8">
|
||||||
|
<f:for each="{data.flexForm.buttons}" as="button">
|
||||||
|
<f:link.typolink parameter="{button.container.link}"
|
||||||
|
class="button shadow-lg">
|
||||||
|
{button.container.label}
|
||||||
|
</f:link.typolink>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<f:if condition="{settings.themeKey} == 'ep'">
|
||||||
|
<f:render partial="Disrupter/Outlines" section="Bottom1" arguments="{classes: 'hidden md:block transform translate-y-2 text-white'}"/>
|
||||||
|
</f:if>
|
||||||
</div>
|
</div>
|
||||||
<f:if condition="{settings.themeKey} == 'ep'">
|
|
||||||
<f:render partial="Disrupter/Outlines" section="Bottom1" arguments="{classes: 'hidden md:block transform translate-y-2 text-white'}"/>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3,39 +3,41 @@
|
|||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
<div class="bg-winter my-2">
|
<div class="bg-winter my-2">
|
||||||
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
<div class="bg-ep-primary-80 sbw:bg-sbw-primary-80 uch:bg-uch-primary-80">
|
||||||
<div class="max-w-screen-lg mx-auto" data-rte-content>
|
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
||||||
<div class="md:flex md:items-start py-4">
|
<div class="max-w-screen-lg mx-auto" data-rte-content>
|
||||||
<div class="px-16 pb-4 md:px-4 md:pb-0 md:w-1/6">
|
<div class="md:flex md:items-start py-4">
|
||||||
<f:if condition="{image}">
|
<div class="px-16 pb-4 md:px-4 md:pb-0 md:w-1/6">
|
||||||
<f:then>
|
<f:if condition="{image}">
|
||||||
<img class="block w-full h-auto rounded-full lazyload"
|
<f:then>
|
||||||
data-src="{f:uri.image(image: image, width: '400', height: '400c')}"
|
<img class="block w-full h-auto rounded-full lazyload"
|
||||||
alt="{image.alternative}" title="{image.title}">
|
data-src="{f:uri.image(image: image, width: '400', height: '400c')}"
|
||||||
</f:then>
|
alt="{image.alternative}" title="{image.title}">
|
||||||
<f:else>
|
</f:then>
|
||||||
<img class="block w-full h-auto rounded-full" src="https://placehold.it/800x600" alt="">
|
<f:else>
|
||||||
</f:else>
|
<img class="block w-full h-auto rounded-full" src="https://placehold.it/800x600" alt="">
|
||||||
</f:if>
|
</f:else>
|
||||||
</div>
|
</f:if>
|
||||||
<div class="px-16 md:px-4 md:w-5/6 md:pl-8 text-center text-white md:text-left" data-rte-content>
|
</div>
|
||||||
|
<div class="px-16 md:px-4 md:w-5/6 md:pl-8 text-center text-white md:text-left" data-rte-content>
|
||||||
<span class="headline--3 text-white uppercase">
|
<span class="headline--3 text-white uppercase">
|
||||||
{data.headline}
|
{data.headline}
|
||||||
</span>
|
</span>
|
||||||
{data.text -> f:format.html()}
|
{data.text -> f:format.html()}
|
||||||
<div class="flex flex-col space-y-4 md:flex-row md:items-center md:space-y-0 md:space-x-4">
|
<div class="flex flex-col space-y-4 md:flex-row md:items-center md:space-y-0 md:space-x-4">
|
||||||
<f:for each="{data.flexForm.buttons}" as="button" iteration="iteration">
|
<f:for each="{data.flexForm.buttons}" as="button" iteration="iteration">
|
||||||
<f:if condition="{iteration.cycle} <= 3">
|
<f:if condition="{iteration.cycle} <= 3">
|
||||||
<f:link.typolink parameter="{button.container.link}" class="button shadow-lg">
|
<f:link.typolink parameter="{button.container.link}" class="button shadow-lg">
|
||||||
{button.container.label}
|
{button.container.label}
|
||||||
</f:link.typolink>
|
</f:link.typolink>
|
||||||
</f:if>
|
</f:if>
|
||||||
</f:for>
|
</f:for>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<f:render partial="Disrupter/Outlines" section="Bottom1" arguments="{classes: 'hidden md:block transform translate-y-2 text-white'}"/>
|
||||||
</div>
|
</div>
|
||||||
<f:render partial="Disrupter/Outlines" section="Bottom1" arguments="{classes: 'hidden md:block transform translate-y-2 text-white'}"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -5,65 +5,66 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="bg-winter my-2">
|
<div class="bg-winter my-2">
|
||||||
<f:if condition="{settings.themeKey} == 'ep'">
|
<div class="bg-ep-primary-80">
|
||||||
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
<f:if condition="{settings.themeKey} == 'ep'">
|
||||||
</f:if>
|
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
||||||
<div class="relative container grid grid-cols-2 gap-8 py-8" data-rte-content>
|
</f:if>
|
||||||
<div class="col-span-2 md:col-span-1">
|
<div class="relative container grid grid-cols-2 gap-8 py-8" data-rte-content>
|
||||||
<div class="relative max-w-md mx-auto mb-8">
|
<div class="col-span-2 md:col-span-1">
|
||||||
<f:if condition="{teaserImage}">
|
<div class="relative max-w-md mx-auto mb-8">
|
||||||
<f:then>
|
<f:if condition="{teaserImage}">
|
||||||
<img class="block rounded-full w-full h-auto lazyload"
|
<f:then>
|
||||||
data-src="{f:uri.image(image: teaserImage, width: '400', height: '400c')}"
|
<img class="block rounded-full w-full h-auto lazyload"
|
||||||
alt="{teaserImage.alternative}" title="{teaserImage.title}">
|
data-src="{f:uri.image(image: teaserImage, width: '400', height: '400c')}"
|
||||||
</f:then>
|
alt="{teaserImage.alternative}" title="{teaserImage.title}">
|
||||||
<f:else>
|
</f:then>
|
||||||
<img src="https://placehold.it/800x600" alt="">
|
<f:else>
|
||||||
</f:else>
|
<img src="https://placehold.it/800x600" alt="">
|
||||||
</f:if>
|
</f:else>
|
||||||
<a href="tel:{settings.phoneNumber -> v:format.pregReplace(pattern: '/[\-\s]/', replacement: '')}"
|
</f:if>
|
||||||
rel="nofollow"
|
<a href="tel:{settings.phoneNumber -> v:format.pregReplace(pattern: '/[\-\s]/', replacement: '')}"
|
||||||
class="absolute bottom-0 left-1/2 transform -translate-x-1/2 -mb-8 rounded-full py-4 px-6 bg-ep-secondary sbw:bg-sbw-secondary uch:bg-uch-secondary flex items-center space-x-2">
|
rel="nofollow"
|
||||||
<svg class="w-10 h-10 text-white">
|
class="absolute bottom-0 left-1/2 transform -translate-x-1/2 -mb-8 rounded-full py-4 px-6 bg-ep-secondary sbw:bg-sbw-secondary uch:bg-uch-secondary flex items-center space-x-2">
|
||||||
<use href="#icon-phone"></use>
|
<svg class="w-10 h-10 text-white">
|
||||||
</svg>
|
<use href="#icon-phone"></use>
|
||||||
<div class="text-center text-white">
|
</svg>
|
||||||
|
<div class="text-center text-white">
|
||||||
<span class="block whitespace-nowrap">
|
<span class="block whitespace-nowrap">
|
||||||
Ihr habt Fragen?
|
Ihr habt Fragen?
|
||||||
</span>
|
</span>
|
||||||
<span class="block whitespace-nowrap">
|
<span class="block whitespace-nowrap">
|
||||||
Wir helfen euch gerne!
|
Wir helfen euch gerne!
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-span-2 md:col-span-1">
|
||||||
<div class="col-span-2 md:col-span-1">
|
|
||||||
<span class="headline--secondary font-light text-white">
|
<span class="headline--secondary font-light text-white">
|
||||||
{data.subheader}
|
{data.subheader}
|
||||||
</span>
|
</span>
|
||||||
<span class="headline--secondary uppercase font-light text-white mb-4">
|
<span class="headline--secondary uppercase font-light text-white mb-4">
|
||||||
{data.header}
|
{data.header}
|
||||||
</span>
|
</span>
|
||||||
<div class="text-white" data-rte-content>
|
<div class="text-white" data-rte-content>
|
||||||
{data.bodytext -> f:format.html()}
|
{data.bodytext -> f:format.html()}
|
||||||
</div>
|
|
||||||
<f:if condition="{data.flexForm.buttons}">
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-8">
|
|
||||||
<f:for each="{data.flexForm.buttons}" as="button">
|
|
||||||
<f:link.typolink parameter="{button.container.link}"
|
|
||||||
class="button shadow-lg">
|
|
||||||
{button.container.label}
|
|
||||||
</f:link.typolink>
|
|
||||||
</f:for>
|
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
<f:if condition="{data.flexForm.buttons}">
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-8">
|
||||||
|
<f:for each="{data.flexForm.buttons}" as="button">
|
||||||
|
<f:link.typolink parameter="{button.container.link}"
|
||||||
|
class="button shadow-lg">
|
||||||
|
{button.container.label}
|
||||||
|
</f:link.typolink>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<f:if condition="{settings.themeKey} == 'ep'">
|
||||||
|
<f:render partial="Disrupter/Outlines" section="Bottom1" arguments="{classes: 'hidden md:block sbw:md:hidden transform translate-y-2 text-white'}"/>
|
||||||
|
</f:if>
|
||||||
</div>
|
</div>
|
||||||
<f:if condition="{settings.themeKey} == 'ep'">
|
|
||||||
<f:render partial="Disrupter/Outlines" section="Bottom1" arguments="{classes: 'hidden md:block sbw:md:hidden transform translate-y-2 text-white'}"/>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,58 +1,57 @@
|
|||||||
<f:if condition="{faqs}">
|
<f:if condition="{faqs}">
|
||||||
<div class="bg-winter my-2">
|
<div class="bg-winter my-2">
|
||||||
<f:render partial="Disrupter/Outlines" section="Top2" arguments="{classes: 'hidden md:block transform -translate-y-2 text-white'}"/>
|
<div class="bg-ep-primary-80 sbw:bg-sbw-primary-80 uch:bg-uch-primary-80">
|
||||||
<div class="container" x-data="faq">
|
<f:render partial="Disrupter/Outlines" section="Top2" arguments="{classes: 'hidden md:block text-white'}"/>
|
||||||
<span class="headline--3 text-white uppercase mb-4">
|
<div class="container"
|
||||||
Häufig gestellte Fragen
|
data-controller="faq">
|
||||||
</span>
|
<span class="headline--3 text-white uppercase mb-4">
|
||||||
<f:if condition="{filter}">
|
Häufig gestellte Fragen
|
||||||
<div class="mb-4 pr-2 w-80 border-b border-r border-white flex items-center justify-between">
|
</span>
|
||||||
<input type="text"
|
<f:if condition="{filter}">
|
||||||
x-model="query"
|
<div class="mb-4 pr-2 w-80 border-b border-r border-white flex items-center justify-between">
|
||||||
class="bg-transparent border-0 uppercase ring-0 focus:ring-0 placeholder-white text-white"
|
<input type="text"
|
||||||
placeholder="Suchbegriff">
|
data-action="faq#filter"
|
||||||
<svg class="w-6 h-6 text-white">
|
class="bg-transparent border-0 uppercase ring-0 focus:ring-0 placeholder-white text-white"
|
||||||
<use href="#icon-search"></use>
|
placeholder="Suchbegriff">
|
||||||
</svg>
|
<svg class="w-6 h-6 text-white">
|
||||||
</div>
|
<use href="#icon-search"></use>
|
||||||
</f:if>
|
|
||||||
<f:for each="{faqs}" as="faq" iteration="iteration">
|
|
||||||
<div class="p-4 rounded mb-2"
|
|
||||||
x-data="collapse(<f:format.raw>{f:if(condition: iteration.isFirst, then: 'false', else: 'true')}</f:format.raw>)"
|
|
||||||
x-bind:class="collapsed || 'bg-ep-primary-80'">
|
|
||||||
<button class="uppercase text-lg text-white flex items-center space-x-4" x-bind="trigger">
|
|
||||||
<svg class="w-4 h-4 text-white transform transition duration-200 ease-in-out" x-bind:class="collapsed || 'rotate-180'">
|
|
||||||
<use href="#icon-chevron-down"></use>
|
|
||||||
</svg>
|
</svg>
|
||||||
<span>
|
</div>
|
||||||
|
</f:if>
|
||||||
|
<f:for each="{faqs}" as="faq" iteration="iteration">
|
||||||
|
<div class="p-4 rounded mb-2"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: iteration.isFirst, then: 'false', else: 'true')}"
|
||||||
|
data-faq-target="entry">
|
||||||
|
<button class="uppercase text-lg text-white flex items-center space-x-4"
|
||||||
|
data-action="collapse#toggle">
|
||||||
|
<svg class="w-4 h-4 text-white transform transition duration-200 ease-in-out"
|
||||||
|
data-collapse-target="icon">
|
||||||
|
<use href="#icon-chevron-down"></use>
|
||||||
|
</svg>
|
||||||
|
<span>
|
||||||
{faq.question}
|
{faq.question}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="text-white pt-2"
|
<div class="text-white pt-2 transition-transform ease-out overflow-hidden origin-top transform hidden"
|
||||||
x-bind="container"
|
data-collapse-target="container"
|
||||||
x-transition:enter="transition ease-out duration-300"
|
data-rte-content>
|
||||||
x-transition:enter-start="opacity-0"
|
{faq.answer -> f:format.html()}
|
||||||
x-transition:enter-end="opacity-100"
|
</div>
|
||||||
x-transition:leave="transition ease-in duration-300"
|
|
||||||
x-transition:leave-start="opacity-100"
|
|
||||||
x-transition:leave-end="opacity-0"
|
|
||||||
x-cloak
|
|
||||||
data-rte-content>
|
|
||||||
{faq.answer -> f:format.html()}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</f:for>
|
||||||
</f:for>
|
<f:if condition="{settings.infoPageUid}">
|
||||||
<f:if condition="{settings.infoPageUid}">
|
<div class="flex items-center justify-end space-x-2 text-sm text-white">
|
||||||
<div class="flex items-center justify-end space-x-2 text-sm text-white">
|
<svg class="w-4 h-4">
|
||||||
<svg class="w-4 h-4">
|
<use href="#icon-info-circle"></use>
|
||||||
<use href="#icon-info-circle"></use>
|
</svg>
|
||||||
</svg>
|
<a href="{f:uri.typolink(parameter: settings.infoPageUid)}">
|
||||||
<a href="{f:uri.typolink(parameter: settings.infoPageUid)}">
|
Weitere Reiseinfos findet ihr <span class="underline">hier</span>
|
||||||
Weitere Reiseinfos findet ihr <span class="underline">hier</span>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</f:if>
|
||||||
</f:if>
|
</div>
|
||||||
|
<f:render partial="Disrupter/Outlines" section="Bottom2" arguments="{classes: 'hidden md:block transform translate-y-2 text-white'}"/>
|
||||||
</div>
|
</div>
|
||||||
<f:render partial="Disrupter/Outlines" section="Bottom2" arguments="{classes: 'hidden md:block transform translate-y-2 text-white'}"/>
|
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
|
|||||||
@@ -4,93 +4,95 @@
|
|||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
<div class="bg-winter mt-8">
|
<div class="bg-winter mt-8">
|
||||||
<f:if condition="{settings.themeKey} == 'ep'">
|
<div class="bg-ep-primary-80 sbw:bg-sbw-primary-80 uch:bg-uch-primary-80">
|
||||||
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'transform -translate-y-2 text-white'}"/>
|
<f:if condition="{settings.themekey} == 'ep'">
|
||||||
</f:if>
|
<f:render partial="Disrupter/Outlines" section="Top1" arguments="{classes: 'transform -translate-y-2 text-white'}"/>
|
||||||
<div class="py-4 relative">
|
</f:if>
|
||||||
<div class="container grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 pb-4">
|
<div class="py-4 relative">
|
||||||
<v:menu pageUid="{settings.footerNavPid}" levels="2" expandAll="true">
|
<div class="container grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 pb-4">
|
||||||
<f:for each="{menu}" as="menuheader" iteration="iteration">
|
<v:menu pageUid="{settings.footerNavPid}" levels="2" expandAll="true">
|
||||||
<div x-data="collapse(true, 991)">
|
<f:for each="{menu}" as="menuheader" iteration="iteration">
|
||||||
<span class="headline--4 text-white hidden md:block">
|
<div data-controller="collapse"
|
||||||
{menuheader.title}
|
data-collapse-until-value="991">
|
||||||
</span>
|
<span class="headline--4 text-white hidden md:block">
|
||||||
<button class="headline--4 text-white md:hidden"
|
{menuheader.title}
|
||||||
x-bind="trigger">
|
</span>
|
||||||
{menuheader.title}
|
<button class="headline--4 text-white md:hidden"
|
||||||
</button>
|
data-action="collapse#toggle">
|
||||||
<v:menu pageUid="{menuheader.uid}" useShortcutUid="true" as="submenu">
|
{menuheader.title}
|
||||||
<ul class="list-disc text-white mb-0 pl-4"
|
</button>
|
||||||
x-bind="container"
|
<v:menu pageUid="{menuheader.uid}" useShortcutUid="true" as="submenu">
|
||||||
x-transition>
|
<ul class="list-disc text-white mb-0 pl-4"
|
||||||
<f:for each="{submenu}" as="submenuitem">
|
data-collapse-target="container">
|
||||||
<f:if condition="{submenuitem.doktype} == 3">
|
<f:for each="{submenu}" as="submenuitem">
|
||||||
<f:then>
|
<f:if condition="{submenuitem.doktype} == 3">
|
||||||
<li>
|
<f:then>
|
||||||
<a class="text-white" href="{submenuitem.url}" target="_blank" title="{submenuitem.linktext}">{submenuitem.title}</a>
|
<li>
|
||||||
</li>
|
<a class="text-white" href="{submenuitem.url}" target="_blank" title="{submenuitem.linktext}">{submenuitem.title}</a>
|
||||||
</f:then>
|
</li>
|
||||||
<f:else>
|
</f:then>
|
||||||
<li>
|
<f:else>
|
||||||
<a class="text-white" href="{f:uri.typolink(parameter: submenuitem.uid)}" title="{submenuitem.linktext}">{submenuitem.title}</a>
|
<li>
|
||||||
</li>
|
<a class="text-white" href="{f:uri.typolink(parameter: submenuitem.uid)}" title="{submenuitem.linktext}">{submenuitem.title}</a>
|
||||||
</f:else>
|
</li>
|
||||||
</f:if>
|
</f:else>
|
||||||
</f:for>
|
</f:if>
|
||||||
</ul>
|
</f:for>
|
||||||
</v:menu>
|
</ul>
|
||||||
</div>
|
</v:menu>
|
||||||
</f:for>
|
</div>
|
||||||
</v:menu>
|
</f:for>
|
||||||
</div>
|
</v:menu>
|
||||||
<div class="hidden md:block container border-t border-white pt-4">
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-16">
|
<div class="hidden md:block container border-t border-white pt-4">
|
||||||
<div class="flex">
|
<div class="grid grid-cols-2 gap-16">
|
||||||
<div class="flex items-start space-x-2 pr-4">
|
<div class="flex">
|
||||||
<svg class="w-12 h-12 text-white">
|
<div class="flex items-start space-x-2 pr-4">
|
||||||
<use href="#icon-phone"></use>
|
<svg class="w-12 h-12 text-white">
|
||||||
</svg>
|
<use href="#icon-phone"></use>
|
||||||
<div class="text-white">
|
</svg>
|
||||||
<span class="block uppercase text-xl">
|
<div class="text-white">
|
||||||
Service-Telefon
|
<span class="block uppercase text-xl">
|
||||||
|
Service-Telefon
|
||||||
|
</span>
|
||||||
|
<a class="text-white whitespace-nowrap"
|
||||||
|
href="tel:{settings.phoneNumberLink}"
|
||||||
|
title="Service Telefon anrufen"
|
||||||
|
rel="nofollow">
|
||||||
|
{settings.phoneNumber}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-white flex-1">
|
||||||
|
<span class="block">
|
||||||
|
{settings.businessHoursDays}
|
||||||
|
</span>
|
||||||
|
<span class="block">
|
||||||
|
{settings.businessHoursTime}
|
||||||
</span>
|
</span>
|
||||||
<a class="text-white whitespace-nowrap"
|
|
||||||
href="tel:{settings.phoneNumberLink}"
|
|
||||||
title="Service Telefon anrufen"
|
|
||||||
rel="nofollow">
|
|
||||||
{settings.phoneNumber}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-white flex-1">
|
<div class="flex">
|
||||||
<span class="block">
|
<div class="flex items-start space-x-2 pr-4">
|
||||||
{settings.businessHoursDays}
|
<svg class="w-12 h-12 text-white">
|
||||||
</span>
|
<use href="#icon-whatsapp"></use>
|
||||||
<span class="block">
|
</svg>
|
||||||
{settings.businessHoursTime}
|
<div class="text-white">
|
||||||
</span>
|
<span class="block uppercase text-xl">
|
||||||
</div>
|
WhatsApp
|
||||||
</div>
|
</span>
|
||||||
<div class="flex">
|
<a class="text-white whitespace-nowrap"
|
||||||
<div class="flex items-start space-x-2 pr-4">
|
href="https://api.whatsapp.com/send?phone={settings.whatsAppNumberLink}"
|
||||||
<svg class="w-12 h-12 text-white">
|
title="WhatsApp"
|
||||||
<use href="#icon-whatsapp"></use>
|
target="_blank"
|
||||||
</svg>
|
rel="nofollow">
|
||||||
<div class="text-white">
|
{settings.whatsApp}
|
||||||
<span class="block uppercase text-xl">
|
</a>
|
||||||
WhatsApp
|
</div>
|
||||||
</span>
|
</div>
|
||||||
<a class="text-white whitespace-nowrap"
|
<div class="text-white flex-1">
|
||||||
href="https://api.whatsapp.com/send?phone={settings.whatsAppNumberLink}"
|
{f:translate(key: 'label.whatsapp_instructions', extensionName: 'ep_theme')}
|
||||||
title="WhatsApp"
|
|
||||||
target="_blank"
|
|
||||||
rel="nofollow">
|
|
||||||
{settings.whatsApp}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="text-white flex-1">
|
|
||||||
{f:translate(key: 'label.whatsapp_instructions', extensionName: 'ep_theme')}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -176,10 +178,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button x-data="scrollTop"
|
<button data-controller="scroll-top"
|
||||||
x-bind="trigger"
|
data-action="scroll-top#scroll"
|
||||||
x-cloak
|
class="hidden fixed bottom-0 right-0 mb-16 md:mb-8 mr-4 md:mr-8 z-10 h-10 w-10 flex items-center justify-center rounded bg-ep-secondary-80">
|
||||||
class="fixed bottom-0 right-0 mb-16 md:mb-8 mr-4 md:mr-8 z-10 h-10 w-10 flex items-center justify-center rounded bg-ep-secondary-80">
|
|
||||||
<svg class="w-8 h-8 text-white">
|
<svg class="w-8 h-8 text-white">
|
||||||
<use href="#icon-chevron-up"></use>
|
<use href="#icon-chevron-up"></use>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<html data-namespace-typo3-fluid="true" lang="en"
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
xmlns="http://www.w3.org/1999/xhtml"
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
|
|
||||||
xmlns:ce="http://typo3.org/ns/TYPO3/CMS/FluidStyledContent/ViewHelpers"
|
xmlns:ce="http://typo3.org/ns/TYPO3/CMS/FluidStyledContent/ViewHelpers"
|
||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
@@ -9,9 +8,12 @@
|
|||||||
<f:if condition="{contentElements}">
|
<f:if condition="{contentElements}">
|
||||||
<f:for each="{contentElements}" as="contentElement">
|
<f:for each="{contentElements}" as="contentElement">
|
||||||
<li>
|
<li>
|
||||||
<a href="{f:uri.typolink(parameter: data.pid, section: 'c{contentElement.uid}')}"
|
<button class="button w-full"
|
||||||
class="btn btn-warning ep-sidebar"
|
data-controller="scroll-to"
|
||||||
@click.prevent="scrollTo('#c{contentElement.uid}')">{contentElement.header}</a>
|
data-scroll-to-target-value="c{contentElement.uid}"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
|
{contentElement.header}
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</f:for>
|
</f:for>
|
||||||
</f:if>
|
</f:if>
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<f:form object="{filterSettings}"
|
||||||
|
name="filterSettings"
|
||||||
|
pluginName="Ajax"
|
||||||
|
data="{'search-target': 'form'}">
|
||||||
|
<div class="border rounded p-4">
|
||||||
|
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.dateFrom} || {filterSettings.dateTo}', then: 'false', else: 'true')}">
|
||||||
|
<label class="cursor-pointer"
|
||||||
|
data-action="click->collapse#toggle">
|
||||||
|
Zeitraum
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<input type="text"
|
||||||
|
data-search-target="dateRangeLabel"
|
||||||
|
class="cursor-pointer focus:outline-none"
|
||||||
|
value="{ep:dateRange(dateFrom: filterSettings.dateFrom, dateTo: filterSettings.dateTo, includeLabel: 0)}"
|
||||||
|
placeholder="von... bis">
|
||||||
|
<f:form.hidden property="dateFrom"
|
||||||
|
data="{'search-target': 'dateFrom'}"/>
|
||||||
|
<f:form.hidden property="dateTo"
|
||||||
|
data="{'search-target': 'dateTo'}"/>
|
||||||
|
<div data-controller="datepicker"
|
||||||
|
<f:if condition="{filterSettings.dateFrom} && {filterSettings.dateTo}">
|
||||||
|
data-datepicker-date-from-value="{filterSettings.dateFrom -> f:format.date(format: 'Y-m-d')}"
|
||||||
|
data-datepicker-date-to-value="{filterSettings.dateTo -> f:format.date(format: 'Y-m-d')}"
|
||||||
|
</f:if>
|
||||||
|
data-datepicker-min-date-value="{f:format.date(date: 'now', format: 'Y-m-d')}">
|
||||||
|
<f:if condition="{settings.datePickerPresets}">
|
||||||
|
<div class="flex items-center justify-between pb-2">
|
||||||
|
<f:for each="{settings.datePickerPresets}" as="preset">
|
||||||
|
<button class="daterange__preset"
|
||||||
|
data-preset='{preset -> f:format.json()}'
|
||||||
|
data-action="datepicker#selectPreset">
|
||||||
|
<span>
|
||||||
|
{preset.label}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
<input type="hidden"
|
||||||
|
data-datepicker-target="field">
|
||||||
|
<div class="flex items-center justify-between pt-2">
|
||||||
|
<button class="daterange__button focus:outline-none">
|
||||||
|
schließen
|
||||||
|
</button>
|
||||||
|
<button class="daterange__button focus:outline-none"
|
||||||
|
data-action="datepicker#reset">
|
||||||
|
zurücksetzen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.countryUids} || {filterSettings.regionUids}', then: 'false', else: 'true')}">
|
||||||
|
<label class="cursor-pointer"
|
||||||
|
data-action="click->collapse#toggle">
|
||||||
|
Reiseziel
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0">
|
||||||
|
<f:for each="{filterOptions.destinations}" as="destination">
|
||||||
|
<li>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="countryUids"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{destination.country.uid}"/>
|
||||||
|
{destination.country.label}
|
||||||
|
<f:if condition="{destination.regions}">
|
||||||
|
<ul class="pl-4 pt-1">
|
||||||
|
<f:for each="{destination.regions}" as="region">
|
||||||
|
<li>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="regionUids"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{region.uid}"/>
|
||||||
|
{region.label}
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</f:if>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.conceptUids}', then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Reisekonzepte
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0">
|
||||||
|
<f:for each="{filterOptions.concepts}" as="concept">
|
||||||
|
<li>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="conceptUids"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{concept.uid}"/>
|
||||||
|
{concept.name}
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.priceRanges}', then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Preis
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0">
|
||||||
|
<f:for each="{filterOptions.priceRanges}" as="range">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="priceRanges"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{range.uid}"/>
|
||||||
|
{ep:priceRange(min: range.min, max: range.max)}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.pax} > 1', then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Personen
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<div class="border rounded">
|
||||||
|
<select name="pax"
|
||||||
|
data-action="search#filter">
|
||||||
|
<f:for each="{filterOptions.pax}" as="option">
|
||||||
|
<option value="<f:format.raw>{option}</f:format.raw>">
|
||||||
|
<f:format.raw>{option}</f:format.raw>
|
||||||
|
</option>
|
||||||
|
</f:for>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<f:variable name="hotelTypes" value="{
|
||||||
|
1: 'Ferienwohnung',
|
||||||
|
2: 'Sportclub',
|
||||||
|
3: 'Appartment',
|
||||||
|
4: 'Gästehaus',
|
||||||
|
5: 'Pension'
|
||||||
|
}"/>
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.hotelTypes}', then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Unterkunft
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0">
|
||||||
|
<f:for each="{filterOptions.hotelTypes}" as="type">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="hotelTypes"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{type}"/>
|
||||||
|
{hotelTypes.{type}}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.boardTypes}', then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Verpflegung
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0">
|
||||||
|
<f:for each="{filterOptions.boardTypes}" as="type">
|
||||||
|
<f:if condition="{type.label}">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="boardTypes"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{type.uid}"/>
|
||||||
|
{type.label}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</f:if>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<f:variable name="roomTypes" value="{
|
||||||
|
1: 'EZ',
|
||||||
|
2: 'DZ / 2er',
|
||||||
|
3: '3er',
|
||||||
|
4: '4er',
|
||||||
|
5: 'ab 5 Pers.',
|
||||||
|
6: 'mit anderen'
|
||||||
|
}"/>
|
||||||
|
<div class="mb-2 pb-2 border-b"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: '{filterSettings.roomTypes}', then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Zimmerarten/Apart.
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0 p-0">
|
||||||
|
<f:for each="{filterOptions.roomTypes}" as="type">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="roomTypes"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="{type}"/>
|
||||||
|
{roomTypes.{type}}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<f:if condition="{filterOptions.busAvailable}">
|
||||||
|
<div data-controller="collapse"
|
||||||
|
data-collapse-collapsed-value="{f:if(condition: filterSettings.bus, then: 'false', else: 'true')}">
|
||||||
|
<label data-action="click->collapse#toggle">
|
||||||
|
Anreise
|
||||||
|
</label>
|
||||||
|
<div data-collapse-target="container">
|
||||||
|
<ul class="mb-0 p-0">
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<f:form.checkbox class="mr-2"
|
||||||
|
property="bus"
|
||||||
|
data="{action: 'search#filter'}"
|
||||||
|
value="1"/>
|
||||||
|
Busanreise
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</f:form>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<div class="grid grid-cols-3 gap-8">
|
||||||
|
<div class="col-span-3 lg:col-span-1 relative"
|
||||||
|
data-controller="collapse"
|
||||||
|
data-collapse-until-value="991">
|
||||||
|
<p class="lg:hidden">
|
||||||
|
<button class="button button--small w-full"
|
||||||
|
data-action="collapse#toggle">
|
||||||
|
<span>Filter ein-/ausblenden</span>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
<div class="lg:block"
|
||||||
|
data-collapse-target="container">
|
||||||
|
<h3>Filter</h3>
|
||||||
|
<button class="button button--small w-full"
|
||||||
|
data-action="search#reset">
|
||||||
|
Filter zurücksetzen
|
||||||
|
</button>
|
||||||
|
<f:render partial="Search/FilterPanel" arguments="{_all}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-3 lg:col-span-2 relative">
|
||||||
|
<f:render partial="Search/Result" arguments="{_all}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<div class="searchresult__info alert alert-info">
|
||||||
|
Deine Suche
|
||||||
|
<f:if condition="{meta.organic}">
|
||||||
|
<f:then>
|
||||||
|
<f:if condition="{meta.destinationName}">
|
||||||
|
nach <strong>{meta.destinationName}</strong>
|
||||||
|
</f:if>
|
||||||
|
<f:if condition="{meta.dateRange}">
|
||||||
|
<strong>{meta.dateRange}</strong>
|
||||||
|
</f:if>
|
||||||
|
ergab {meta.total} Treffer
|
||||||
|
</f:then>
|
||||||
|
<f:else>
|
||||||
|
ergab leider keine genauen Treffer. Bitte benutze die Filter.
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
</div>
|
||||||
|
<div class="searchresult__content">
|
||||||
|
<f:for each="{searchResult}" as="section">
|
||||||
|
<div id="concept-{section.concept.uid}">
|
||||||
|
<h2 class="headline headline--secondary headline--underlined">
|
||||||
|
{section.concept.name}
|
||||||
|
</h2>
|
||||||
|
<div class="searchresult-section searchresult-section--{section.concept.code}">
|
||||||
|
<f:for each="{section.items}" as="item">
|
||||||
|
<div class="teaserbox teaserbox--landscape teaserbox--searchresult searchresult-item">
|
||||||
|
<div class="teaserbox__image">
|
||||||
|
<img src="{item.country.flag}" class="teaserbox__flag" alt="{item.country.name}"/>
|
||||||
|
<a href="{item.detailPageUri}" rel="nofollow" title="Details & 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 concept-badge--{section.concept.code}"
|
||||||
|
id="{section.concept.code}">
|
||||||
|
{section.concept.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="teaserbox__main">
|
||||||
|
<div class="teaserbox__header">
|
||||||
|
<span class="searchresult-item__headline">
|
||||||
|
{item.region.name}
|
||||||
|
<f:if condition="{section.concept.code} == 'evt'">
|
||||||
|
<strong>
|
||||||
|
<span class="block">
|
||||||
|
{item.product.name}
|
||||||
|
</span>
|
||||||
|
</strong>
|
||||||
|
</f:if>
|
||||||
|
</span>
|
||||||
|
<span class="searchresult-item__subline">
|
||||||
|
{item.hotel.name}
|
||||||
|
</span>
|
||||||
|
<f:if condition="{item.hotel.category}">
|
||||||
|
<span class="searchresult-item__category">
|
||||||
|
Kategorie {item.hotel.category}
|
||||||
|
</span>
|
||||||
|
</f:if>
|
||||||
|
</div>
|
||||||
|
<ul class="check-list searchresult-item__checklist">
|
||||||
|
<f:if condition="{item.hotel.fact}">
|
||||||
|
<li>{item.hotel.fact}</li>
|
||||||
|
</f:if>
|
||||||
|
<f:if condition="{item.product.fact}">
|
||||||
|
<li>{item.product.fact}</li>
|
||||||
|
</f:if>
|
||||||
|
<f:if condition="{item.region.feature}">
|
||||||
|
<f:then>
|
||||||
|
<li>{item.region.feature}</li>
|
||||||
|
</f:then>
|
||||||
|
<f:else>
|
||||||
|
<f:if condition="{item.region.fact}">
|
||||||
|
<li>{item.region.fact}</li>
|
||||||
|
</f:if>
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
</ul>
|
||||||
|
<ul class="check-list check-list--inverted searchresult-item__featurelist">
|
||||||
|
<li>Skipass</li>
|
||||||
|
<f:if condition="{item.board}">
|
||||||
|
<li>{item.board}</li>
|
||||||
|
</f:if>
|
||||||
|
<f:if condition="{item.product.feature}">
|
||||||
|
<li>{item.product.feature}</li>
|
||||||
|
</f:if>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="teaserbox__aside">
|
||||||
|
<div class="teaserbox__aside__top">
|
||||||
|
<span class="searchresult-item__label">
|
||||||
|
{f:if(condition: '{item.dates -> f:count()} > 1', then: 'Zeitraum', else: 'Termin')}
|
||||||
|
</span>
|
||||||
|
<span class="searchresult-item__daterange">
|
||||||
|
{ep:dateRange(dateFrom: item.minDateStart, dateTo: item.maxDateEnd, includeLabel: 0)}
|
||||||
|
</span>
|
||||||
|
<f:if condition="{item.dates -> f:count()} > 0">
|
||||||
|
<f:if condition="{item.daytrip}">
|
||||||
|
<f:else>
|
||||||
|
<a href="{item.detailPageUri}{f:if(condition: referringPageUri, then: '?ref={referringPageUri -> f:format.urlencode()}')}" rel="nofollow" title="Details & Buchen">
|
||||||
|
<span class="searchresult-item__daterange">
|
||||||
|
<i class="fa fa-arrow-circle-right"></i> {item.dates -> f:count()} {f:if(condition: '{item.dates -> f:count()} > 1', then: 'Termine', else: 'Termin')}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
</f:if>
|
||||||
|
<hr>
|
||||||
|
<span class="searchresult-item__label">
|
||||||
|
{f:if(condition: item.daytrip, then: 'Tageweise buchbar', else: '{ep:nightsOptions(options: item.nights, daytrip: item.daytrip)}')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="teaserbox__aside__bottom">
|
||||||
|
<span class="searchresult-item__price">ab {item.minPrice} €</span>
|
||||||
|
<a href="{item.detailPageUri}{f:if(condition: referringPageUri, then: '?ref={referringPageUri -> f:format.urlencode()}')}" class="button button--full searchresult-item__button"
|
||||||
|
rel="nofollow" title="Details">
|
||||||
|
Details{f:if(condition: item.hideBookingButton, else: ' & Buchen')}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="teaserbox-watchlist" x-data="watchlistToggle('{item.key}')" x-bind="trigger">
|
||||||
|
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
|
||||||
|
<svg class="w-5 h-5">
|
||||||
|
<use x-bind:href="onList() ? '#icon-minus-circle' : '#icon-plus-circle'"></use>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</html>
|
||||||
+4
-404
@@ -1,419 +1,19 @@
|
|||||||
<html data-namespace-typo3-fluid="true" lang="en"
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
xmlns="http://www.w3.org/1999/xhtml"
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
|
|
||||||
|
|
||||||
<f:layout name="Default"/>
|
<f:layout name="Default"/>
|
||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<div class="grid grid-cols-3 gap-8" x-ref="container">
|
<f:render partial="Search/Main" arguments="{_all}"/>
|
||||||
<div class="col-span-3 lg:col-span-1 relative" x-data="collapse(false, 991)">
|
|
||||||
<p class="lg:hidden">
|
|
||||||
<button class="button button--full button--small" role="button" x-bind="trigger">
|
|
||||||
<i class="fa fa-toggle-on"></i> Filter ein-/ausblenden
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
<div class="lg:block"
|
|
||||||
x-bind="container"
|
|
||||||
x-transition
|
|
||||||
x-cloak
|
|
||||||
>
|
|
||||||
<h3>Filter</h3>
|
|
||||||
<button class="button button--sidebar button--small"
|
|
||||||
x-show="filterCount > 0"
|
|
||||||
x-cloak
|
|
||||||
x-on:click.prevent="reset">
|
|
||||||
Filter zurücksetzen
|
|
||||||
</button>
|
|
||||||
<f:render section="FilterPanel" arguments="{_all}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-span-3 lg:col-span-2 relative">
|
|
||||||
<f:render section="SearchResult" arguments="{_all}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="SearchResult">
|
<f:section name="SearchResult">
|
||||||
<div class="searchresult__info alert alert-info">
|
<f:render partial="Search/Result" arguments="{_all}"/>
|
||||||
Deine Suche
|
|
||||||
<f:if condition="{meta.organic}">
|
|
||||||
<f:then>
|
|
||||||
<f:if condition="{meta.destinationName}">
|
|
||||||
nach <strong>{meta.destinationName}</strong>
|
|
||||||
</f:if>
|
|
||||||
<f:if condition="{meta.dateRange}">
|
|
||||||
<strong>{meta.dateRange}</strong>
|
|
||||||
</f:if>
|
|
||||||
ergab {meta.total} Treffer
|
|
||||||
</f:then>
|
|
||||||
<f:else>
|
|
||||||
ergab leider keine genauen Treffer. Bitte benutze die Filter.
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
|
||||||
<div class="searchresult__content">
|
|
||||||
<f:for each="{searchResult}" as="section">
|
|
||||||
<div id="concept-{section.concept.uid}">
|
|
||||||
<h2 class="headline headline--secondary headline--underlined">
|
|
||||||
{section.concept.name}
|
|
||||||
</h2>
|
|
||||||
<div class="searchresult-section searchresult-section--{section.concept.code}">
|
|
||||||
<f:for each="{section.items}" as="item">
|
|
||||||
<div class="teaserbox teaserbox--landscape teaserbox--searchresult searchresult-item">
|
|
||||||
<div class="teaserbox__image">
|
|
||||||
<img src="{item.country.flag}" class="teaserbox__flag" alt="{item.country.name}"/>
|
|
||||||
<a href="{item.detailPageUri}" rel="nofollow" title="Details & 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 concept-badge--{section.concept.code}"
|
|
||||||
id="{section.concept.code}">
|
|
||||||
{section.concept.name}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="teaserbox__main">
|
|
||||||
<div class="teaserbox__header">
|
|
||||||
<span class="searchresult-item__headline">
|
|
||||||
{item.region.name}
|
|
||||||
<f:if condition="{section.concept.code} == 'evt'">
|
|
||||||
<strong>
|
|
||||||
<span class="block">
|
|
||||||
{item.product.name}
|
|
||||||
</span>
|
|
||||||
</strong>
|
|
||||||
</f:if>
|
|
||||||
</span>
|
|
||||||
<span class="searchresult-item__subline">
|
|
||||||
{item.hotel.name}
|
|
||||||
</span>
|
|
||||||
<f:if condition="{item.hotel.category}">
|
|
||||||
<span class="searchresult-item__category">
|
|
||||||
Kategorie {item.hotel.category}
|
|
||||||
</span>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
|
||||||
<ul class="check-list searchresult-item__checklist">
|
|
||||||
<f:if condition="{item.hotel.fact}">
|
|
||||||
<li>{item.hotel.fact}</li>
|
|
||||||
</f:if>
|
|
||||||
<f:if condition="{item.product.fact}">
|
|
||||||
<li>{item.product.fact}</li>
|
|
||||||
</f:if>
|
|
||||||
<f:if condition="{item.region.feature}">
|
|
||||||
<f:then>
|
|
||||||
<li>{item.region.feature}</li>
|
|
||||||
</f:then>
|
|
||||||
<f:else>
|
|
||||||
<f:if condition="{item.region.fact}">
|
|
||||||
<li>{item.region.fact}</li>
|
|
||||||
</f:if>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</ul>
|
|
||||||
<ul class="check-list check-list--inverted searchresult-item__featurelist">
|
|
||||||
<li>Skipass</li>
|
|
||||||
<f:if condition="{item.board}">
|
|
||||||
<li>{item.board}</li>
|
|
||||||
</f:if>
|
|
||||||
<f:if condition="{item.product.feature}">
|
|
||||||
<li>{item.product.feature}</li>
|
|
||||||
</f:if>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="teaserbox__aside">
|
|
||||||
<div class="teaserbox__aside__top">
|
|
||||||
<span class="searchresult-item__label">
|
|
||||||
{f:if(condition: '{item.dates -> f:count()} > 1', then: 'Zeitraum', else: 'Termin')}
|
|
||||||
</span>
|
|
||||||
<span class="searchresult-item__daterange">
|
|
||||||
{ep:dateRange(dateFrom: item.minDateStart, dateTo: item.maxDateEnd, includeLabel: 0)}
|
|
||||||
</span>
|
|
||||||
<f:if condition="{item.dates -> f:count()} > 0">
|
|
||||||
<f:if condition="{item.daytrip}">
|
|
||||||
<f:else>
|
|
||||||
<a href="{item.detailPageUri}{f:if(condition: referringPageUri, then: '?ref={referringPageUri -> f:format.urlencode()}')}" rel="nofollow" title="Details & Buchen">
|
|
||||||
<span class="searchresult-item__daterange">
|
|
||||||
<i class="fa fa-arrow-circle-right"></i> {item.dates -> f:count()} {f:if(condition: '{item.dates -> f:count()} > 1', then: 'Termine', else: 'Termin')}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</f:if>
|
|
||||||
<hr>
|
|
||||||
<span class="searchresult-item__label">
|
|
||||||
{f:if(condition: item.daytrip, then: 'Tageweise buchbar', else: '{ep:nightsOptions(options: item.nights, daytrip: item.daytrip)}')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="teaserbox__aside__bottom">
|
|
||||||
<span class="searchresult-item__price">ab {item.minPrice} €</span>
|
|
||||||
<a href="{item.detailPageUri}{f:if(condition: referringPageUri, then: '?ref={referringPageUri -> f:format.urlencode()}')}" class="button button--full searchresult-item__button"
|
|
||||||
rel="nofollow" title="Details">
|
|
||||||
Details{f:if(condition: item.hideBookingButton, else: ' & Buchen')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button class="teaserbox-watchlist" x-data="watchlistToggle('{item.key}')" x-bind="trigger">
|
|
||||||
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
|
|
||||||
<svg class="w-5 h-5">
|
|
||||||
<use x-bind:href="onList() ? '#icon-minus-circle' : '#icon-plus-circle'"></use>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</f:for>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</f:for>
|
|
||||||
</div>
|
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="FilterPanel">
|
<f:section name="FilterPanel">
|
||||||
<div class="border rounded p-4">
|
<f:render partial="Search/FilterPanel" arguments="{_all}"/>
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.dateFrom} || {filterSettings.dateTo}">false</f:if>)"
|
|
||||||
x-init='initDatePicker(
|
|
||||||
<f:format.raw>
|
|
||||||
"{filterOptions.dateFrom -> f:format.date(format: 'Y-m-d')}",
|
|
||||||
"{filterOptions.dateTo -> f:format.date(format: 'Y-m-d')}"
|
|
||||||
</f:format.raw>
|
|
||||||
)'>
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Zeitraum
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" class="relative">
|
|
||||||
<input type="text"
|
|
||||||
class="cursor-pointer focus:outline-none"
|
|
||||||
placeholder="von... bis"
|
|
||||||
x-bind:value="dateRangeLabel"
|
|
||||||
x-bind:class="loading && 'cursor-not-allowed'"
|
|
||||||
x-on:click.prevent="show = show === 'dateRange' ? null : 'dateRange'"/>
|
|
||||||
<div class="absolute top-100 left-0 z-20 bg-white p-4 shadow-md" x-show="show === 'dateRange'" x-transition x-cloak>
|
|
||||||
<template x-if="datePresets">
|
|
||||||
<div class="flex items-center justify-between pb-2">
|
|
||||||
<template x-for="preset in datePresets">
|
|
||||||
<a class="daterange__preset" href="#"
|
|
||||||
x-on:click.prevent="selectDateRangePreset(preset)">
|
|
||||||
<i class="fa fa-calendar"></i> <span x-text="preset.label"></span>
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<input x-ref="picker" type="hidden">
|
|
||||||
<div class="flex items-center justify-between pt-2">
|
|
||||||
<button class="daterange__button focus:outline-none" x-on:click.prevent="show = null">
|
|
||||||
<i class="fa fa-times"></i> schließen
|
|
||||||
</button>
|
|
||||||
<button class="daterange__button focus:outline-none" x-on:click.prevent="resetDateRange()">
|
|
||||||
<i class="fa fa-trash-o"></i> zurücksetzen
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.countryUids -> f:count()} || {filterSettings.regionUids -> f:count()}">false</f:if>)">
|
|
||||||
<label x-bind="trigger" class="cursor-pointer">
|
|
||||||
Reiseziel
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0">
|
|
||||||
<f:for each="{filterOptions.destinations}" as="destination">
|
|
||||||
<li>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.countryUids"
|
|
||||||
value="{destination.country.uid}">
|
|
||||||
{destination.country.label}
|
|
||||||
<f:if condition="{destination.regions -> f:count()}">
|
|
||||||
<ul>
|
|
||||||
<f:for each="{destination.regions}" as="region">
|
|
||||||
<li>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.regionUids"
|
|
||||||
value="{region.uid}">
|
|
||||||
{region.label}
|
|
||||||
</li>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</f:if>
|
|
||||||
</li>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.conceptUids -> f:count()}">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Reisekonzepte
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0">
|
|
||||||
<f:for each="{filterOptions.concepts}" as="concept">
|
|
||||||
<li>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.conceptUids"
|
|
||||||
value="{concept.uid}">
|
|
||||||
{concept.name}
|
|
||||||
</li>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.priceRanges -> f:count()}">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Preis
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0">
|
|
||||||
<f:for each="{filterOptions.priceRanges}" as="range">
|
|
||||||
<li>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.priceRanges"
|
|
||||||
value="<f:format.raw>{range.uid}</f:format.raw>">
|
|
||||||
{ep:priceRange(min: range.min, max: range.max)}
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.pax} > 1">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Personen
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<div class="border rounded">
|
|
||||||
<select x-model="filterSettings.pax" x-on:change="refresh">
|
|
||||||
<f:for each="{filterOptions.pax}" as="option">
|
|
||||||
<option value="<f:format.raw>{option}</f:format.raw>">
|
|
||||||
<f:format.raw>{option}</f:format.raw>
|
|
||||||
</option>
|
|
||||||
</f:for>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<f:variable name="hotelTypes" value="{
|
|
||||||
1: 'Ferienwohnung',
|
|
||||||
2: 'Sportclub',
|
|
||||||
3: 'Appartment',
|
|
||||||
4: 'Gästehaus',
|
|
||||||
5: 'Pension'
|
|
||||||
}"/>
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.hotelTypes -> f:count()}">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Unterkunft
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0">
|
|
||||||
<f:for each="{filterOptions.hotelTypes}" as="type">
|
|
||||||
<li>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.hotelTypes"
|
|
||||||
value="<f:format.raw>{type}</f:format.raw>">
|
|
||||||
{hotelTypes.{type}}
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.boardTypes -> f:count()}">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Verpflegung
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0">
|
|
||||||
<f:for each="{filterOptions.boardTypes}" as="type">
|
|
||||||
<f:if condition="{type.label}">
|
|
||||||
<li>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.boardTypes"
|
|
||||||
value="<f:format.raw>{type.uid}</f:format.raw>">
|
|
||||||
{type.label}
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</f:if>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<f:variable name="roomTypes" value="{
|
|
||||||
1: 'EZ',
|
|
||||||
2: 'DZ / 2er',
|
|
||||||
3: '3er',
|
|
||||||
4: '4er',
|
|
||||||
5: 'ab 5 Pers.',
|
|
||||||
6: 'mit anderen'
|
|
||||||
}"/>
|
|
||||||
<div class="mb-2 pb-2 border-b" x-data="collapse(<f:if condition="{filterSettings.roomTypes -> f:count()}">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Zimmerarten/Apart.
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0 p-0">
|
|
||||||
<f:for each="{filterOptions.roomTypes}" as="type">
|
|
||||||
<li>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model.number="filterSettings.roomTypes"
|
|
||||||
value="<f:format.raw>{type}</f:format.raw>">
|
|
||||||
{roomTypes.{type}}
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</f:for>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<f:if condition="{filterOptions.busAvailable}">
|
|
||||||
<div x-data="collapse(<f:if condition="{filterSettings.bus}">false</f:if>)">
|
|
||||||
<label x-bind="trigger">
|
|
||||||
Anreise
|
|
||||||
</label>
|
|
||||||
<div x-bind="container" x-transition>
|
|
||||||
<ul class="mb-0 p-0">
|
|
||||||
<li>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox"
|
|
||||||
class="mr-2"
|
|
||||||
x-on:change="refresh"
|
|
||||||
x-model="filterSettings.bus">
|
|
||||||
Busanreise
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
||||||
<div class="mb-8 lg:hidden">
|
<div class="mb-8 lg:hidden">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Header/Header" arguments="{layout: 8, subheader: city.name, header: city.headline}"/>
|
<f:render partial="Header/Header" arguments="{layout: 8, subheader: city.name, header: city.headline}"/>
|
||||||
@@ -26,11 +27,12 @@
|
|||||||
<div class="col-span-3 lg:col-span-1">
|
<div class="col-span-3 lg:col-span-1">
|
||||||
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
||||||
<p class="hidden lg:block">
|
<p class="hidden lg:block">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Facts" arguments="{facts: city.facts}"/>
|
<f:render partial="Facts" arguments="{facts: city.facts}"/>
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<f:if condition="{teasers}">
|
<f:if condition="{teasers}">
|
||||||
<div class="mb-8 lg:hidden">
|
<div class="mb-8 lg:hidden">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Header/Header" arguments="{layout: 8, subheader: concept.name, header: concept.headline}"/>
|
<f:render partial="Header/Header" arguments="{layout: 8, subheader: concept.name, header: concept.headline}"/>
|
||||||
@@ -50,11 +51,12 @@
|
|||||||
<div class="col-span-3 lg:col-span-1">
|
<div class="col-span-3 lg:col-span-1">
|
||||||
<f:if condition="{teasers}">
|
<f:if condition="{teasers}">
|
||||||
<p class="hidden lg:block">
|
<p class="hidden lg:block">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</f:if>
|
</f:if>
|
||||||
<v:menu pageUid="{settings.conceptsPageUid}" levels="1">
|
<v:menu pageUid="{settings.conceptsPageUid}" levels="1">
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
||||||
<div class="mb-8 lg:hidden">
|
<div class="mb-8 lg:hidden">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Header/Header" arguments="{layout: 8, subheader: country.name, header: country.headline}"/>
|
<f:render partial="Header/Header" arguments="{layout: 8, subheader: country.name, header: country.headline}"/>
|
||||||
@@ -53,11 +54,12 @@
|
|||||||
<div class="col-span-3 lg:col-span-1">
|
<div class="col-span-3 lg:col-span-1">
|
||||||
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
||||||
<p class="hidden lg:block">
|
<p class="hidden lg:block">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Facts" arguments="{facts: country.facts}"/>
|
<f:render partial="Facts" arguments="{facts: country.facts}"/>
|
||||||
|
|||||||
+5
-5
@@ -13,11 +13,11 @@
|
|||||||
<f:variable name="latitude" value="{region.0.data.latitude}"/>
|
<f:variable name="latitude" value="{region.0.data.latitude}"/>
|
||||||
<f:variable name="longitude" value="{region.0.data.longitude}"/>
|
<f:variable name="longitude" value="{region.0.data.longitude}"/>
|
||||||
</f:if>
|
</f:if>
|
||||||
<div class="osm-map"
|
<div class="w-full aspect-w-16 aspect-h-9 mb-8"
|
||||||
x-data="osmMap"
|
data-controller="osm"
|
||||||
data-lat="{latitude}"
|
data-osm-lat-value="{latitude}"
|
||||||
data-lng="{longitude}"
|
data-osm-lng-value="{longitude}"
|
||||||
data-zoom="17"></div>
|
data-osm-zoom-value="17"></div>
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+5
-4
@@ -10,11 +10,12 @@
|
|||||||
<f:if condition="{page.content}">
|
<f:if condition="{page.content}">
|
||||||
<f:for each="{page.content}" as="element">
|
<f:for each="{page.content}" as="element">
|
||||||
<f:if condition="{element.data.header}">
|
<f:if condition="{element.data.header}">
|
||||||
<a href="{page.link}#c{element.data.uid}"
|
<button class="button w-full"
|
||||||
class="button w-full"
|
data-controller="scroll-to"
|
||||||
x-data="scrollTo('c{element.data.uid}')">
|
data-scroll-to-target-value="c{element.data.uid}"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
{element.data.header}
|
{element.data.header}
|
||||||
</a>
|
</button>
|
||||||
</f:if>
|
</f:if>
|
||||||
</f:for>
|
</f:for>
|
||||||
</f:if>
|
</f:if>
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
||||||
<div class="mb-8 lg:hidden">
|
<div class="mb-8 lg:hidden">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Header/Header" arguments="{layout: 8, subheader: hotel.name, header: hotel.headline}"/>
|
<f:render partial="Header/Header" arguments="{layout: 8, subheader: hotel.name, header: hotel.headline}"/>
|
||||||
@@ -25,11 +26,12 @@
|
|||||||
<div class="col-span-3 md:col-span-1">
|
<div class="col-span-3 md:col-span-1">
|
||||||
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
<f:if condition="{v:content.get(column: 1) -> f:count()} > 0">
|
||||||
<p class="hidden lg:block">
|
<p class="hidden lg:block">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Facts" arguments="{facts: hotel.facts}"/>
|
<f:render partial="Facts" arguments="{facts: hotel.facts}"/>
|
||||||
@@ -40,14 +42,11 @@
|
|||||||
<div class="bg-gray-200 p-4">
|
<div class="bg-gray-200 p-4">
|
||||||
<p><strong>Lage</strong></p>
|
<p><strong>Lage</strong></p>
|
||||||
<div>
|
<div>
|
||||||
<f:format.raw>
|
<div class="w-full aspect-w-16 aspect-h-9"
|
||||||
<div class="osm-map"
|
data-controller="osm"
|
||||||
x-data="osmMap"
|
data-osm-lat-value="{hotel.latitude}"
|
||||||
data-lat="{hotel.latitude}"
|
data-osm-lng-value="{hotel.longitude}"
|
||||||
data-lng="{hotel.longitude}"
|
data-osm-external-link-value="{f:uri.typolink(parameter: hotel.externalLink)}"></div>
|
||||||
data-zoom="12"
|
|
||||||
data-link="{f:uri.typolink(parameter: hotel.externalLink)}"></div>
|
|
||||||
</f:format.raw>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,9 +17,10 @@
|
|||||||
<f:if condition="{product.bookable}">
|
<f:if condition="{product.bookable}">
|
||||||
<h2>Buchungsoptionen</h2>
|
<h2>Buchungsoptionen</h2>
|
||||||
<div class="ajax-content-wrapper"
|
<div class="ajax-content-wrapper"
|
||||||
x-data="ajaxContent('{ep:uri.ajax(action: 'pricetableHtml', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: product, hotel: hotel}', format: 'html')}')">
|
data-controller="ajax-content"
|
||||||
<div class="ajax-content" x-ref="container"></div>
|
data-ajax-content-uri-value="{ep:uri.ajax(action: 'pricetableHtml', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: product, hotel: hotel}', format: 'html')}">
|
||||||
<div x-ref="trigger">
|
<div class="ajax-content" data-ajax-content-target="container"></div>
|
||||||
|
<div data-ajax-content-target="trigger">
|
||||||
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
|
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<ep:container data="{data}">
|
<ep:container data="{data}">
|
||||||
<div class="w-full aspect-w-16 aspect-h-9 mb-8"
|
<div class="w-full aspect-w-16 aspect-h-9 mb-8"
|
||||||
x-data="osmMap"
|
data-controller="osm"
|
||||||
data-markers='{markerData -> f:format.raw()}'></div>
|
data-osm-markers-value='{markerData -> f:format.raw()}'></div>
|
||||||
</ep:container>
|
</ep:container>
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<div class="ajax-content-wrapper"
|
<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')}')">
|
data-controller="ajax-content"
|
||||||
<div class="ajax-content" x-ref="container"></div>
|
data-ajax-content-uri-value="{ep:uri.ajax(extensionName: 'epproducts', action: 'eventPricetable', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: productUid}', format: 'html')}">
|
||||||
<div x-ref="trigger">
|
<div class="ajax-content" data-ajax-content-target="container"></div>
|
||||||
|
<div data-ajax-content-target="trigger">
|
||||||
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
|
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -60,7 +60,11 @@
|
|||||||
</f:if>
|
</f:if>
|
||||||
<f:if condition="{product.faqs}">
|
<f:if condition="{product.faqs}">
|
||||||
<button class="button button--light col-span-1 md:col-span-2"
|
<button class="button button--light col-span-1 md:col-span-2"
|
||||||
x-data="scrollTo('faq')">FAQ</button>
|
data-controller="scroll-to"
|
||||||
|
data-scroll-to-target-value="faq"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
|
FAQ
|
||||||
|
</button>
|
||||||
</f:if>
|
</f:if>
|
||||||
<div class="col-span-2">
|
<div class="col-span-2">
|
||||||
<p class="mb-4">
|
<p class="mb-4">
|
||||||
@@ -184,13 +188,12 @@
|
|||||||
<p class="font-bold">
|
<p class="font-bold">
|
||||||
Lage
|
Lage
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div class="w-full aspect-w-16 aspect-h-9"
|
||||||
<div class="osm-map"
|
data-controller="osm"
|
||||||
x-data="osmMap"
|
data-osm-zoom-value="15"
|
||||||
data-lat="{hotel.latitude}"
|
data-osm-lat-value="{hotel.latitude}"
|
||||||
data-lng="{hotel.longitude}"
|
data-osm-lng-value="{hotel.longitude}"
|
||||||
data-link="{f:uri.typolink(parameter: hotel.externalLink)}"></div>
|
data-osm-external-link-value="{f:uri.typolink(parameter: hotel.externalLink)}"></div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<f:render partial="Region/Webcam" arguments="{region: product.region}"/>
|
<f:render partial="Region/Webcam" arguments="{region: product.region}"/>
|
||||||
<f:render partial="RegionMaps" arguments="{region: product.region}"/>
|
<f:render partial="RegionMaps" arguments="{region: product.region}"/>
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<f:if condition="{teasers}">
|
<f:if condition="{teasers}">
|
||||||
<div class="mb-8 lg:hidden">
|
<div class="mb-8 lg:hidden">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:render partial="Header/Header" arguments="{layout: 8, subheader: region.name, header: region.headline}"/>
|
<f:render partial="Header/Header" arguments="{layout: 8, subheader: region.name, header: region.headline}"/>
|
||||||
@@ -26,11 +27,12 @@
|
|||||||
<div class="col-span-3 lg:col-span-1">
|
<div class="col-span-3 lg:col-span-1">
|
||||||
<f:if condition="{teasers}">
|
<f:if condition="{teasers}">
|
||||||
<p class="hidden lg:block">
|
<p class="hidden lg:block">
|
||||||
<a href="#teasers"
|
<button class="button w-full mb-8"
|
||||||
x-data="scrollTo('teasers')"
|
data-controller="scroll-to"
|
||||||
class="button w-full mb-8">
|
data-scroll-to-target-value="teasers"
|
||||||
|
data-action="scroll-to#scroll">
|
||||||
Direkt zu den Angeboten
|
Direkt zu den Angeboten
|
||||||
</a>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</f:if>
|
</f:if>
|
||||||
<f:if condition="{region.winter}">
|
<f:if condition="{region.winter}">
|
||||||
@@ -44,7 +46,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div x-data='fbpixel({ "content_ids": [ {region.uid -> f:format.raw()} ], "content_name": "{region.nameInternal -> f:format.raw()}", "content_type": "product" })'></div>
|
<div data-controller="fbpixel"
|
||||||
|
data-fbpixel-props-value='{ "content_ids": [ {region.uid -> f:format.raw()} ], "content_name": "{region.nameInternal -> f:format.raw()}", "content_type": "product" }'></div>
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -35,15 +35,16 @@
|
|||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="CollapsibleSimple">
|
<f:section name="CollapsibleSimple">
|
||||||
<div class="panel panel-default" x-data="collapse">
|
<div class="panel panel-default"
|
||||||
|
data-controller="collapse">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<a role="button" href="#" x-bind="trigger">
|
<button data-action="collapse#toggle">
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</button>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" x-bind="container">
|
<div class="hidden" data-collapse-target="container">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<f:if condition="{name}">
|
<f:if condition="{name}">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -69,15 +70,17 @@
|
|||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="CollapsibleHotel">
|
<f:section name="CollapsibleHotel">
|
||||||
<div class="panel panel-default" x-data="collapse">
|
<div class="panel panel-default"
|
||||||
|
data-controller="collapse">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<a role="button" href="#" data-bind="trigger">
|
<button data-action="collapse#toggle">
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</button>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" data-bind="container">
|
<div class="hidden"
|
||||||
|
data-collapse-target="container">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Name</label>
|
<label class="control-label">Name</label>
|
||||||
@@ -229,15 +232,17 @@
|
|||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="CollapsibleCity">
|
<f:section name="CollapsibleCity">
|
||||||
<div class="panel panel-default" x-data="collapse">
|
<div class="panel panel-default"
|
||||||
|
data-controller="collapse">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<a role="button" href="#" x-bind="trigger">
|
<button data-action="collapse#toggle">
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</button>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" x-bind="container">
|
<div class="hidden"
|
||||||
|
data-collapse-target="container">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Name</label>
|
<label class="control-label">Name</label>
|
||||||
@@ -257,15 +262,17 @@
|
|||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="CollapsibleRegion">
|
<f:section name="CollapsibleRegion">
|
||||||
<div class="panel panel-default" x-data="collapse">
|
<div class="panel panel-default"
|
||||||
|
data-controller="collapse">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<a role="button" href="#" x-bind="trigger">
|
<button data-action="collapse#toggle">
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</button>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" x-bind="container">
|
<div class="hidden"
|
||||||
|
data-collapse-target="container">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Name</label>
|
<label class="control-label">Name</label>
|
||||||
@@ -309,15 +316,17 @@
|
|||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
<f:section name="CollapsibleImages">
|
<f:section name="CollapsibleImages">
|
||||||
<div class="panel panel-default" x-data="collapse">
|
<div class="panel panel-default"
|
||||||
|
data-controller="collapse">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
<a role="button" href="#" x-bind="trigger">
|
<button data-action="collapse#toggle">
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</button>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" x-bind="container">
|
<div class="hidden"
|
||||||
|
data-collapse-target="container">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<f:for each="{images}" as="image">
|
<f:for each="{images}" as="image">
|
||||||
<a href="{image}" target="_blank">{image}</a><br>
|
<a href="{image}" target="_blank">{image}</a><br>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
sticky: <f:if condition="{fixed}"><f:then>true</f:then><f:else>false</f:else></f:if>
|
sticky: <f:if condition="{fixed}"><f:then>true</f:then><f:else>false</f:else></f:if>
|
||||||
</f:format.raw>
|
</f:format.raw>
|
||||||
})'>
|
})'>
|
||||||
<div class="searchbar {f:if(condition: fixed, then: ' searchbar--sticky')}"{f:if(condition: fixed, else: ' x-data="sticky(650)" x-bind:class="sticky && \'searchbar--sticky\'"')}>
|
<div class="searchbar {f:if(condition: fixed, then: ' searchbar--sticky')}"{f:if(condition: fixed, else: ' data-controller="sticky" data-sticky-offset-value="650" data-sticky-sticky-class="searchbar--sticky"')}>
|
||||||
<f:form action="processSearch" controller="Search" method="post" name="searchParams"
|
<f:form action="processSearch" controller="Search" method="post" name="searchParams"
|
||||||
object="{searchParams}" pluginName="searchresult" extensionName="epproducts"
|
object="{searchParams}" pluginName="searchresult" extensionName="epproducts"
|
||||||
pageUid="{settings.defaultSearchPageUid}" additionalAttributes="{ref: 'form'}">
|
pageUid="{settings.defaultSearchPageUid}" additionalAttributes="{ref: 'form'}">
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
|
||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
||||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
|
||||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
|
|
||||||
|
|
||||||
<f:layout name="Default"/>
|
<f:layout name="Default"/>
|
||||||
|
|
||||||
@@ -13,15 +12,14 @@
|
|||||||
style="background-image: url({f:uri.image(src: settings.searchPageHeaderImage, width: '1366', height: '160c+100')})"></div>
|
style="background-image: url({f:uri.image(src: settings.searchPageHeaderImage, width: '1366', height: '160c+100')})"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container relative"
|
<div class="container relative"
|
||||||
x-data='search({
|
data-controller="search"
|
||||||
<f:format.raw>
|
data-search-uri-value="{ep:uri.ajax(controller: 'AjaxSearch', action: 'searchresult', pageUid: settings.defaultAjaxUid, format: 'html')}"
|
||||||
uri: "{ep:uri.ajax(controller: 'AjaxSearch', action: 'searchresult', pageUid: settings.defaultAjaxUid, format: 'html')}",
|
data-action="datepicker:range-select->search#selectDateRange">
|
||||||
initialFilterSettings: {filterSettings -> f:format.json()},
|
<div data-search-target="resultsContainer">
|
||||||
datePresets: {settings.datePickerPresets -> f:format.json()}
|
<f:render partial="Search/Main" arguments="{_all}"/>
|
||||||
</f:format.raw>
|
</div>
|
||||||
})'>
|
<div class="absolute z-20 inset-0 w-full h-fill bg-overlay-white hidden"
|
||||||
<div x-ref="container"></div>
|
data-search-target="loadingIndicator">
|
||||||
<div x-show="loading" class="absolute z-20 inset-0 w-full h-fill bg-overlay-white">
|
|
||||||
<div class="absolute mt-16 top-0 left-1/2 transform -translate-x-1/2 flex items-center space-x-4 alert alert-info">
|
<div class="absolute mt-16 top-0 left-1/2 transform -translate-x-1/2 flex items-center space-x-4 alert alert-info">
|
||||||
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading" />
|
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading" />
|
||||||
<span>Suchergebnis wird geladen...</span>
|
<span>Suchergebnis wird geladen...</span>
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ module.exports = {
|
|||||||
'primary': '#82C3C6',
|
'primary': '#82C3C6',
|
||||||
'secondary': '#f9c33d',
|
'secondary': '#f9c33d',
|
||||||
'primary-10': tinycolor('#82C3C6').setAlpha(0.1).toRgbString(),
|
'primary-10': tinycolor('#82C3C6').setAlpha(0.1).toRgbString(),
|
||||||
|
'primary-50': tinycolor('#82C3C6').setAlpha(0.5).toRgbString(),
|
||||||
'primary-80': tinycolor('#82C3C6').setAlpha(0.8).toRgbString(),
|
'primary-80': tinycolor('#82C3C6').setAlpha(0.8).toRgbString(),
|
||||||
},
|
},
|
||||||
'uch': {
|
'uch': {
|
||||||
|
|||||||
Reference in New Issue
Block a user