WIP Migrate search result
This commit is contained in:
@@ -149,24 +149,6 @@ routeEnhancers:
|
|||||||
type: PersistedAliasMapper
|
type: PersistedAliasMapper
|
||||||
tableName: tx_epproducts_domain_model_product
|
tableName: tx_epproducts_domain_model_product
|
||||||
routeFieldName: path_segment
|
routeFieldName: path_segment
|
||||||
SearchResultPlugin:
|
|
||||||
type: Extbase
|
|
||||||
extension: EpProducts
|
|
||||||
plugin: searchresult
|
|
||||||
limitToPages:
|
|
||||||
- 41
|
|
||||||
routes:
|
|
||||||
-
|
|
||||||
routePath: '/ergebnis/{filter_settings}'
|
|
||||||
_controller: 'Search::searchresult'
|
|
||||||
_arguments:
|
|
||||||
filter_settings: filterSettings
|
|
||||||
defaultController: 'Search::searchresult'
|
|
||||||
requirements:
|
|
||||||
filter_settings: '[A-Z\d%\-\|;]+'
|
|
||||||
aspects:
|
|
||||||
filter_settings:
|
|
||||||
type: PassthroughMapper
|
|
||||||
StaticResultsPlugin:
|
StaticResultsPlugin:
|
||||||
type: Extbase
|
type: Extbase
|
||||||
extension: EpProducts
|
extension: EpProducts
|
||||||
|
|||||||
Generated
+79
-36
@@ -4,6 +4,11 @@
|
|||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@alpinejs/persist": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@alpinejs/persist/-/persist-3.2.2.tgz",
|
||||||
|
"integrity": "sha512-OY5QDmr46qvmHygzDjjABfGhWcigI2WVOhu1h4ONP5/TstexviRpyzVygkjmLHEVBiE5zdTU6rFsSEQx+7Karg=="
|
||||||
|
},
|
||||||
"@babel/code-frame": {
|
"@babel/code-frame": {
|
||||||
"version": "7.14.5",
|
"version": "7.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
|
||||||
@@ -116,17 +121,28 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-create-class-features-plugin": {
|
"@babel/helper-create-class-features-plugin": {
|
||||||
"version": "7.14.6",
|
"version": "7.14.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.8.tgz",
|
||||||
"integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==",
|
"integrity": "sha512-bpYvH8zJBWzeqi1o+co8qOrw+EXzQ/0c74gVmY205AWXy9nifHrOg77y+1zwxX5lXE7Icq4sPlSQ4O2kWBrteQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/helper-annotate-as-pure": "^7.14.5",
|
"@babel/helper-annotate-as-pure": "^7.14.5",
|
||||||
"@babel/helper-function-name": "^7.14.5",
|
"@babel/helper-function-name": "^7.14.5",
|
||||||
"@babel/helper-member-expression-to-functions": "^7.14.5",
|
"@babel/helper-member-expression-to-functions": "^7.14.7",
|
||||||
"@babel/helper-optimise-call-expression": "^7.14.5",
|
"@babel/helper-optimise-call-expression": "^7.14.5",
|
||||||
"@babel/helper-replace-supers": "^7.14.5",
|
"@babel/helper-replace-supers": "^7.14.5",
|
||||||
"@babel/helper-split-export-declaration": "^7.14.5"
|
"@babel/helper-split-export-declaration": "^7.14.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-member-expression-to-functions": {
|
||||||
|
"version": "7.14.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz",
|
||||||
|
"integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/types": "^7.14.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-create-regexp-features-plugin": {
|
"@babel/helper-create-regexp-features-plugin": {
|
||||||
@@ -156,9 +172,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
@@ -999,9 +1015,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/preset-env": {
|
"@babel/preset-env": {
|
||||||
"version": "7.14.7",
|
"version": "7.14.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.8.tgz",
|
||||||
"integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==",
|
"integrity": "sha512-a9aOppDU93oArQ51H+B8M1vH+tayZbuBqzjOhntGetZVa+4tTu5jp+XTwqHGG2lxslqomPYVSjIxQkFwXzgnxg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/compat-data": "^7.14.7",
|
"@babel/compat-data": "^7.14.7",
|
||||||
@@ -1071,7 +1087,7 @@
|
|||||||
"@babel/plugin-transform-unicode-escapes": "^7.14.5",
|
"@babel/plugin-transform-unicode-escapes": "^7.14.5",
|
||||||
"@babel/plugin-transform-unicode-regex": "^7.14.5",
|
"@babel/plugin-transform-unicode-regex": "^7.14.5",
|
||||||
"@babel/preset-modules": "^0.1.4",
|
"@babel/preset-modules": "^0.1.4",
|
||||||
"@babel/types": "^7.14.5",
|
"@babel/types": "^7.14.8",
|
||||||
"babel-plugin-polyfill-corejs2": "^0.2.2",
|
"babel-plugin-polyfill-corejs2": "^0.2.2",
|
||||||
"babel-plugin-polyfill-corejs3": "^0.2.2",
|
"babel-plugin-polyfill-corejs3": "^0.2.2",
|
||||||
"babel-plugin-polyfill-regenerator": "^0.2.2",
|
"babel-plugin-polyfill-regenerator": "^0.2.2",
|
||||||
@@ -1084,6 +1100,22 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz",
|
||||||
"integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==",
|
"integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"@babel/helper-validator-identifier": {
|
||||||
|
"version": "7.14.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz",
|
||||||
|
"integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@babel/types": {
|
||||||
|
"version": "7.14.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz",
|
||||||
|
"integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/helper-validator-identifier": "^7.14.8",
|
||||||
|
"to-fast-properties": "^2.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1101,9 +1133,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.14.6",
|
"version": "7.14.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
|
||||||
"integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
|
"integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
@@ -1538,17 +1570,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/reactivity": {
|
"@vue/reactivity": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
|
||||||
"integrity": "sha512-glJzJoN2xE7I2lRvwKM5u1BHRPTd1yc8iaf//Lai/78/uYAvE5DXp5HzWRFOwMlbRvMGJHIQjOqoxj87cDAaag==",
|
"integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/shared": "3.1.2"
|
"@vue/shared": "3.1.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/shared": {
|
"@vue/shared": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
|
||||||
"integrity": "sha512-EmH/poaDWBPJaPILXNI/1fvUbArJQmmTyVCwvvyDYDFnkPoTclAbHRAtyIvqfez7jybTDn077HTNILpxlsoWhg=="
|
"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA=="
|
||||||
},
|
},
|
||||||
"@webassemblyjs/ast": {
|
"@webassemblyjs/ast": {
|
||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
@@ -1813,9 +1845,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"alpinejs": {
|
"alpinejs": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.2.2.tgz",
|
||||||
"integrity": "sha512-MYYGUmVHNWN27TvgAtUCYXZlfsXoVCrLQT3a0Ak6CQKqf1TCHfQKxmhzJWscW5kPcLlOK2aYmWbV2H+XyfN2FQ==",
|
"integrity": "sha512-XkQKikB4tJTLIQuRUeF86CZnvmAKhjGzw5lmMri+7MTQzz77DTetuOqldBWjEgdJ/DOExXuiM57rQwWfBPdMPA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@vue/reactivity": "^3.0.2"
|
"@vue/reactivity": "^3.0.2"
|
||||||
}
|
}
|
||||||
@@ -2232,6 +2264,12 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2729,9 +2767,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"core-js-compat": {
|
"core-js-compat": {
|
||||||
"version": "3.15.1",
|
"version": "3.15.2",
|
||||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz",
|
||||||
"integrity": "sha512-xGhzYMX6y7oEGQGAJmP2TmtBLvR4nZmRGEcFa3ubHOq5YEp51gGN9AovVa0AoujGZIq+Wm6dISiYyGNfdflYww==",
|
"integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"browserslist": "^4.16.6",
|
"browserslist": "^4.16.6",
|
||||||
@@ -3487,6 +3525,12 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||||
|
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5658,9 +5702,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"version": "8.3.5",
|
"version": "8.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz",
|
||||||
"integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
|
"integrity": "sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"colorette": "^1.2.2",
|
"colorette": "^1.2.2",
|
||||||
@@ -6251,18 +6295,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"qs": {
|
|
||||||
"version": "6.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
|
||||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"querystring": {
|
"querystring": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
||||||
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
|
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"querystringify": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||||
|
},
|
||||||
"queue-microtask": {
|
"queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
|
|||||||
+5
-3
@@ -9,8 +9,9 @@
|
|||||||
"build": "NODE_ENV=production ./node_modules/.bin/encore production"
|
"build": "NODE_ENV=production ./node_modules/.bin/encore production"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@alpinejs/persist": "^3.2.2",
|
||||||
"@splidejs/splide": "^2.4.21",
|
"@splidejs/splide": "^2.4.21",
|
||||||
"alpinejs": "^3.2.1",
|
"alpinejs": "^3.2.2",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"axios-auth-refresh": "^1.0.7",
|
"axios-auth-refresh": "^1.0.7",
|
||||||
"bootstrap-sass": "^3.4.1",
|
"bootstrap-sass": "^3.4.1",
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
"microtip": "^0.2.2",
|
"microtip": "^0.2.2",
|
||||||
"normalize.css": "^7.0.0",
|
"normalize.css": "^7.0.0",
|
||||||
"picturefill": "^3.0.3",
|
"picturefill": "^3.0.3",
|
||||||
|
"querystringify": "^2.2.0",
|
||||||
"slick-carousel": "^1.8.1",
|
"slick-carousel": "^1.8.1",
|
||||||
"sticky-js": "^1.3.0",
|
"sticky-js": "^1.3.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
@@ -37,14 +39,14 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
|
"@babel/plugin-proposal-object-rest-spread": "^7.14.7",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||||
"@babel/preset-env": "^7.14.7",
|
"@babel/preset-env": "^7.14.8",
|
||||||
"@symfony/webpack-encore": "^1.5.0",
|
"@symfony/webpack-encore": "^1.5.0",
|
||||||
"@tailwindcss/custom-forms": "^0.2.1",
|
"@tailwindcss/custom-forms": "^0.2.1",
|
||||||
"autoprefixer": "^9.4.6",
|
"autoprefixer": "^9.4.6",
|
||||||
"core-js": "^3.15.2",
|
"core-js": "^3.15.2",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"postcss": "^8.3.5",
|
"postcss": "^8.3.6",
|
||||||
"postcss-loader": "^5.3.0",
|
"postcss-loader": "^5.3.0",
|
||||||
"sass-loader": "^9.0.3",
|
"sass-loader": "^9.0.3",
|
||||||
"sass-mq": "^3.3.2",
|
"sass-mq": "^3.3.2",
|
||||||
|
|||||||
@@ -65,6 +65,26 @@ class AjaxFilterpanelController extends ActionController
|
|||||||
$this->processFilterSettingsArgument($forcedConceptUids);
|
$this->processFilterSettingsArgument($forcedConceptUids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FilterSettings $filterSettings
|
||||||
|
*/
|
||||||
|
public function panelAction(FilterSettings $filterSettings)
|
||||||
|
{
|
||||||
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
|
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
||||||
|
|
||||||
|
$filterOptions = $this->filterService->getFilterOptions(
|
||||||
|
$filterSettings,
|
||||||
|
$excludedConceptUids,
|
||||||
|
$excludedRegionUids
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->view->assignMultiple([
|
||||||
|
'filterOptions' => $filterOptions,
|
||||||
|
'filterSettings' => $filterSettings,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FilterSettings $filterSettings
|
* @param FilterSettings $filterSettings
|
||||||
* @param string $search
|
* @param string $search
|
||||||
@@ -82,7 +102,7 @@ class AjaxFilterpanelController extends ActionController
|
|||||||
$excludedConceptUids,
|
$excludedConceptUids,
|
||||||
$excludedRegionUids
|
$excludedRegionUids
|
||||||
);
|
);
|
||||||
return json_encode($destinations);
|
return json_encode($destinations, JSON_THROW_ON_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
use EP\EpProducts\Domain\Model\FilterSettings;
|
||||||
use EP\EpProducts\Service\FilterService;
|
use EP\EpProducts\Service\FilterService;
|
||||||
use EP\EpProducts\Service\FilterSettingsEncoder;
|
|
||||||
use EP\EpProducts\Service\SearchResultUrlService;
|
use EP\EpProducts\Service\SearchResultUrlService;
|
||||||
use EP\EpProducts\Service\SearchResultService;
|
use EP\EpProducts\Service\SearchResultService;
|
||||||
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
||||||
@@ -93,7 +92,6 @@ class AjaxSearchController extends ActionController
|
|||||||
$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']);
|
|
||||||
|
|
||||||
if ($filterSettings === null) {
|
if ($filterSettings === null) {
|
||||||
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
$filterSettings = $this->filterService->getDefaultFilterSettings($forcedConceptUids);
|
||||||
@@ -111,35 +109,27 @@ class AjaxSearchController extends ActionController
|
|||||||
$organic = false;
|
$organic = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filterOptions = $this->filterService->getFilterOptions(
|
|
||||||
$filterSettings,
|
|
||||||
$excludedConceptUids,
|
|
||||||
$excludedRegionUids
|
|
||||||
);
|
|
||||||
|
|
||||||
$options = [
|
$options = [
|
||||||
'defaultDetailPageUid' => $this->settings['defaultDetailPageUid'],
|
'defaultDetailPageUid' => $this->settings['defaultDetailPageUid'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->searchResultUrlService->process($searchResult, $options);
|
$this->searchResultUrlService->process($searchResult, $options);
|
||||||
|
|
||||||
$encodedFilterSettings = FilterSettingsEncoder::encode($filterSettings);
|
|
||||||
$referringPageUri = $this
|
$referringPageUri = $this
|
||||||
->uriBuilder
|
->uriBuilder
|
||||||
->reset()
|
->reset()
|
||||||
->setTargetPageUid($this->settings['defaultSearchPageUid'])
|
->setTargetPageUid($this->settings['defaultSearchPageUid'])
|
||||||
->uriFor(
|
->uriFor(
|
||||||
'searchresult',
|
'searchresult',
|
||||||
['filterSettings' => $encodedFilterSettings],
|
['filterSettings' => $filterSettings->toArray()],
|
||||||
'Search',
|
'Search',
|
||||||
null,
|
null,
|
||||||
'searchresult'
|
'searchresult'
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
return json_encode([
|
$this->view->assignMultiple([
|
||||||
'data' => $searchResult->getData(),
|
'searchResult' => $searchResult->getData(),
|
||||||
'filterOptions' => $filterOptions,
|
|
||||||
'referringPageUri' => $referringPageUri,
|
'referringPageUri' => $referringPageUri,
|
||||||
'meta' => [
|
'meta' => [
|
||||||
'organic' => $organic,
|
'organic' => $organic,
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ namespace EP\EpProducts\Controller;
|
|||||||
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
use EP\EpProducts\Domain\Model\FilterSettings;
|
||||||
use EP\EpProducts\Domain\Model\SearchParams;
|
use EP\EpProducts\Domain\Model\SearchParams;
|
||||||
use EP\EpProducts\Service\DateService;
|
|
||||||
use EP\EpProducts\Service\FilterService;
|
use EP\EpProducts\Service\FilterService;
|
||||||
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
@@ -64,7 +63,7 @@ class AjaxSearchbarController extends ActionController
|
|||||||
* @param SearchParams $searchParams
|
* @param SearchParams $searchParams
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function optionsAction(SearchParams $searchParams = null)
|
public function updateAction(SearchParams $searchParams = null)
|
||||||
{
|
{
|
||||||
if ($searchParams === null) {
|
if ($searchParams === null) {
|
||||||
$searchParams = new SearchParams();
|
$searchParams = new SearchParams();
|
||||||
@@ -79,16 +78,6 @@ class AjaxSearchbarController extends ActionController
|
|||||||
return json_encode([
|
return json_encode([
|
||||||
'filterOptions' => $filterOptions,
|
'filterOptions' => $filterOptions,
|
||||||
'searchParams' => $searchParams,
|
'searchParams' => $searchParams,
|
||||||
]);
|
], JSON_THROW_ON_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function resetAction()
|
|
||||||
{
|
|
||||||
// To reset we simply forward to options action with empty search params
|
|
||||||
$this->forward('options');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,14 @@ class AjaxWatchlistController extends ActionController
|
|||||||
$this->filterService = $filterService;
|
$this->filterService = $filterService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function initializeAction()
|
||||||
|
{
|
||||||
|
if ($this->request->hasArgument('watchlistUids')) {
|
||||||
|
$watchlistUids = json_decode($this->request->getArgument('watchlistUids'), true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
$this->request->setArgument('watchlistUids', $watchlistUids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $watchlistUids
|
* @param array $watchlistUids
|
||||||
* @return string
|
* @return string
|
||||||
@@ -104,8 +112,8 @@ class AjaxWatchlistController extends ActionController
|
|||||||
];
|
];
|
||||||
$this->searchResultUrlService->process($watchlist, $options);
|
$this->searchResultUrlService->process($watchlist, $options);
|
||||||
|
|
||||||
return json_encode([
|
$this->view->assignMultiple([
|
||||||
'data' => $watchlist->getData(),
|
'watchlist' => $watchlist->getData(),
|
||||||
'total' => $watchlist->getTotal()
|
'total' => $watchlist->getTotal()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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\EpEvents\Domain\Model\Search;
|
|
||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
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;
|
||||||
@@ -122,7 +121,7 @@ class SearchController extends ActionController
|
|||||||
->setCreateAbsoluteUri(true)
|
->setCreateAbsoluteUri(true)
|
||||||
->uriFor(
|
->uriFor(
|
||||||
'searchresult',
|
'searchresult',
|
||||||
['filterSettings' => FilterSettingsEncoder::encode($filterSettings)],
|
['filterSettings' => $filterSettings->toArray()],
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
'searchresult'
|
'searchresult'
|
||||||
@@ -142,9 +141,18 @@ class SearchController extends ActionController
|
|||||||
*/
|
*/
|
||||||
public function searchresultAction(FilterSettings $filterSettings)
|
public function searchresultAction(FilterSettings $filterSettings)
|
||||||
{
|
{
|
||||||
|
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']);
|
||||||
|
$excludedRegionUids = GeneralUtility::trimExplode(',', $this->settings['excludedRegionUids']);
|
||||||
|
|
||||||
|
$filterOptions = $this->filterService->getFilterOptions(
|
||||||
|
$filterSettings,
|
||||||
|
$excludedConceptUids,
|
||||||
|
$excludedRegionUids
|
||||||
|
);
|
||||||
|
|
||||||
$this->view->assignMultiple([
|
$this->view->assignMultiple([
|
||||||
'detailPageUid' => $this->settings['detailPageUid'],
|
|
||||||
'referringPageUid' => $this->settings['defaultSearchPageUid'],
|
'referringPageUid' => $this->settings['defaultSearchPageUid'],
|
||||||
|
'filterOptions' => $filterOptions,
|
||||||
'filterSettings' => $filterSettings,
|
'filterSettings' => $filterSettings,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -155,11 +163,13 @@ class SearchController extends ActionController
|
|||||||
*/
|
*/
|
||||||
public function staticresultAction($encodedFilterSettings)
|
public function staticresultAction($encodedFilterSettings)
|
||||||
{
|
{
|
||||||
|
$filterSettings = FilterSettingsEncoder::decode($encodedFilterSettings);
|
||||||
|
|
||||||
$this->forward(
|
$this->forward(
|
||||||
'searchresult',
|
'searchresult',
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
['filterSettings' => $encodedFilterSettings]
|
['filterSettings' => $filterSettings]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace EP\EpProducts\Domain\Model;
|
namespace EP\EpProducts\Domain\Model;
|
||||||
|
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
*
|
*
|
||||||
* Copyright notice
|
* Copyright notice
|
||||||
@@ -29,6 +27,10 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|||||||
* 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\Utility\TypeConversionUtility;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Request;
|
||||||
|
|
||||||
class FilterSettings implements \JsonSerializable
|
class FilterSettings implements \JsonSerializable
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -143,10 +145,6 @@ class FilterSettings implements \JsonSerializable
|
|||||||
*/
|
*/
|
||||||
protected $bus;
|
protected $bus;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \DateTime $dateFrom
|
|
||||||
* @param \DateTime $dateTo
|
|
||||||
*/
|
|
||||||
public function __construct(\DateTime $dateFrom = null, \DateTime $dateTo = null)
|
public function __construct(\DateTime $dateFrom = null, \DateTime $dateTo = null)
|
||||||
{
|
{
|
||||||
if ($dateFrom !== null) {
|
if ($dateFrom !== null) {
|
||||||
@@ -158,15 +156,13 @@ class FilterSettings implements \JsonSerializable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function fromSearchParams(SearchParams $searchParams): self
|
||||||
* @param SearchParams $searchParams
|
|
||||||
* @return FilterSettings
|
|
||||||
*/
|
|
||||||
public static function fromSearchParams(SearchParams $searchParams)
|
|
||||||
{
|
{
|
||||||
$filterSettings = new self;
|
$filterSettings = new self;
|
||||||
$filterSettings->setDateFrom($searchParams->getDateFrom());
|
$filterSettings->setDateFrom($searchParams->getDateFrom());
|
||||||
$filterSettings->setDateTo($searchParams->getDateTo());
|
$filterSettings->setDateTo($searchParams->getDateTo());
|
||||||
|
$filterSettings->setDestinationUid($searchParams->getDestinationUid());
|
||||||
|
$filterSettings->setDestinationType($searchParams->getDestinationType());
|
||||||
if ($searchParams->getDestinationType() && $searchParams->getDestinationUid()) {
|
if ($searchParams->getDestinationType() && $searchParams->getDestinationUid()) {
|
||||||
switch ($searchParams->getDestinationType()) {
|
switch ($searchParams->getDestinationType()) {
|
||||||
case self::DESTINATION_TYPE_COUNTRY:
|
case self::DESTINATION_TYPE_COUNTRY:
|
||||||
@@ -186,11 +182,7 @@ class FilterSettings implements \JsonSerializable
|
|||||||
return $filterSettings;
|
return $filterSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function fromStaticSearchParams(array $searchParams): self
|
||||||
* @param array $searchParams
|
|
||||||
* @return FilterSettings
|
|
||||||
*/
|
|
||||||
public static function fromStaticSearchParams(array $searchParams)
|
|
||||||
{
|
{
|
||||||
$filterSettings = new self;
|
$filterSettings = new self;
|
||||||
if (!empty($searchParams['country'])) {
|
if (!empty($searchParams['country'])) {
|
||||||
@@ -230,6 +222,39 @@ class FilterSettings implements \JsonSerializable
|
|||||||
return $filterSettings;
|
return $filterSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function fromRequest(Request $request): self
|
||||||
|
{
|
||||||
|
$requestArgument = $request->getArgument('filterSettings');
|
||||||
|
|
||||||
|
$filterSettings = is_array($requestArgument) ?
|
||||||
|
$requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
|
||||||
|
if ($requestArgument instanceof FilterSettings) {
|
||||||
|
$filterSettingsObject = $requestArgument;
|
||||||
|
} else {
|
||||||
|
$filterSettings['dateFrom'] = !empty($filterSettings['dateFrom']) ? new \DateTime($filterSettings['dateFrom']) : null;
|
||||||
|
$filterSettings['dateTo'] = !empty($filterSettings['dateTo']) ? new \DateTime($filterSettings['dateTo']) : null;
|
||||||
|
|
||||||
|
if (!empty($filterSettings['bus'])) {
|
||||||
|
$filterSettings['bus'] = \in_array($filterSettings['bus'], [ true, 'true', '1' ], true);
|
||||||
|
} else {
|
||||||
|
$filterSettings['bus'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filterSettingsObject = new FilterSettings();
|
||||||
|
|
||||||
|
foreach ($filterSettings as $key => $value) {
|
||||||
|
$setter = 'set' . ucfirst($key);
|
||||||
|
$value = TypeConversionUtility::convertType($value);
|
||||||
|
if (method_exists($filterSettingsObject, $setter)) {
|
||||||
|
$filterSettingsObject->{$setter}($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filterSettingsObject;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@@ -525,10 +550,8 @@ class FilterSettings implements \JsonSerializable
|
|||||||
return $this->destinationType !== '';
|
return $this->destinationType !== '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
public function toArray(): array
|
||||||
*/
|
|
||||||
public function jsonSerialize()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'priceRange' => $this->getPriceRange(),
|
'priceRange' => $this->getPriceRange(),
|
||||||
@@ -552,4 +575,9 @@ class FilterSettings implements \JsonSerializable
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return $this->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ namespace EP\EpProducts\Domain\Model;
|
|||||||
* 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\Utility\TypeConversionUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Request;
|
||||||
|
|
||||||
class SearchParams implements \JsonSerializable
|
class SearchParams implements \JsonSerializable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -77,11 +80,33 @@ class SearchParams implements \JsonSerializable
|
|||||||
/**
|
/**
|
||||||
* @param int $pageUid
|
* @param int $pageUid
|
||||||
*/
|
*/
|
||||||
public function __construct($pageUid = 0)
|
public function __construct(int $pageUid = 0)
|
||||||
{
|
{
|
||||||
$this->setPageUid($pageUid);
|
$this->setPageUid($pageUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function fromRequest(Request $request): self
|
||||||
|
{
|
||||||
|
$requestArgument = $request->getArgument('searchParams');
|
||||||
|
$searchParams = is_array($requestArgument) ?
|
||||||
|
$requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
|
||||||
|
$searchParams['dateFrom'] = !empty($searchParams['dateFrom']) ? new \DateTime($searchParams['dateFrom']) : null;
|
||||||
|
$searchParams['dateTo'] = !empty($searchParams['dateTo']) ? new \DateTime($searchParams['dateTo']) : null;
|
||||||
|
|
||||||
|
$searchParamsObject = new self;
|
||||||
|
|
||||||
|
foreach ($searchParams as $key => $value) {
|
||||||
|
$setter = 'set' . ucfirst($key);
|
||||||
|
$value = TypeConversionUtility::convertType($value);
|
||||||
|
if (method_exists($searchParamsObject, $setter)) {
|
||||||
|
$searchParamsObject->{$setter}($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $searchParamsObject;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@@ -226,10 +251,7 @@ class SearchParams implements \JsonSerializable
|
|||||||
$this->pageUid = $pageUid;
|
$this->pageUid = $pageUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function toArray(): array
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function jsonSerialize()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'priceRange' => $this->getPriceRange(),
|
'priceRange' => $this->getPriceRange(),
|
||||||
@@ -244,4 +266,9 @@ class SearchParams implements \JsonSerializable
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return $this->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class DateRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dates = $query->execute()->fetch();
|
$dates = $query->execute()->fetchAssociative();
|
||||||
|
|
||||||
if ($dates['dateRangeFrom'] !== null && $dates['dateRangeTo'] !== null) {
|
if ($dates['dateRangeFrom'] !== null && $dates['dateRangeTo'] !== null) {
|
||||||
$dateRangeFrom = \DateTime::createFromFormat('Y-m-d', $dates['dateRangeFrom']);
|
$dateRangeFrom = \DateTime::createFromFormat('Y-m-d', $dates['dateRangeFrom']);
|
||||||
@@ -122,7 +122,7 @@ class DateRepository extends AbstractRepository
|
|||||||
|
|
||||||
$this->addFiltersettingsConditions($query, $filterSettings);
|
$this->addFiltersettingsConditions($query, $filterSettings);
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,7 +157,7 @@ class DateRepository extends AbstractRepository
|
|||||||
$this->addPaxFilterConditions($query, $filterSettings);
|
$this->addPaxFilterConditions($query, $filterSettings);
|
||||||
$this->addConceptFilterConditions($query, $filterSettings);
|
$this->addConceptFilterConditions($query, $filterSettings);
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,7 +205,7 @@ class DateRepository extends AbstractRepository
|
|||||||
$this->addPaxFilterConditions($query, $filterSettings);
|
$this->addPaxFilterConditions($query, $filterSettings);
|
||||||
$this->addConceptFilterConditions($query, $filterSettings);
|
$this->addConceptFilterConditions($query, $filterSettings);
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,7 +249,7 @@ class DateRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class FaqRepository extends AbstractRepository
|
|||||||
->add('orderBy', 'FIELD(uid, ' . $uids . ')')
|
->add('orderBy', 'FIELD(uid, ' . $uids . ')')
|
||||||
->setParameter('uids', GeneralUtility::trimExplode(',', $uids), Connection::PARAM_INT_ARRAY)
|
->setParameter('uids', GeneralUtility::trimExplode(',', $uids), Connection::PARAM_INT_ARRAY)
|
||||||
->execute()
|
->execute()
|
||||||
->fetchAll()
|
->fetchAllAssociative()
|
||||||
;
|
;
|
||||||
|
|
||||||
return $dataMapper->map(Faq::class, $rows);
|
return $dataMapper->map(Faq::class, $rows);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class HotelRepository extends AbstractRepository
|
|||||||
->setMaxResults(1)
|
->setMaxResults(1)
|
||||||
;
|
;
|
||||||
|
|
||||||
return $qb->execute()->fetch();
|
return $qb->execute()->fetchAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +76,7 @@ class HotelRepository extends AbstractRepository
|
|||||||
->setParameter('hotelUid', $hotelUid)
|
->setParameter('hotelUid', $hotelUid)
|
||||||
;
|
;
|
||||||
|
|
||||||
return $qb->execute()->fetch();
|
return $qb->execute()->fetchAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,7 +92,7 @@ class HotelRepository extends AbstractRepository
|
|||||||
->setParameter('productUid', $productUid)
|
->setParameter('productUid', $productUid)
|
||||||
;
|
;
|
||||||
|
|
||||||
return $qb->execute()->fetchAll();
|
return $qb->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +144,7 @@ class HotelRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $qb->execute()->fetchAll();
|
return $qb->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,7 +214,7 @@ class HotelRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $qb->execute()->fetchAll();
|
return $qb->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
->setParameter('hotelUids', $hotelUids, Connection::PARAM_INT_ARRAY)
|
->setParameter('hotelUids', $hotelUids, Connection::PARAM_INT_ARRAY)
|
||||||
;
|
;
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +127,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
|
|
||||||
$this->addFiltersettingsConditions($query, $filterSettings);
|
$this->addFiltersettingsConditions($query, $filterSettings);
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,7 +195,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->execute()->fetchAll(\PDO::FETCH_ASSOC);
|
return $query->execute()->fetchAllAssociative(\PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -242,7 +242,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
|
|
||||||
$this->addFiltersettingsConditions($query, $filterSettings);
|
$this->addFiltersettingsConditions($query, $filterSettings);
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -282,7 +282,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
|
|
||||||
$this->addFiltersettingsConditions($query, $filterSettings, true);
|
$this->addFiltersettingsConditions($query, $filterSettings, true);
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -341,7 +341,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
])
|
])
|
||||||
;
|
;
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -369,7 +369,7 @@ class ProductRepository extends AbstractRepository
|
|||||||
->setParameter('productUid', $product->getUid())
|
->setParameter('productUid', $product->getUid())
|
||||||
;
|
;
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class SnowreportRepository extends AbstractRepository
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->execute()->fetchAll();
|
return $query->execute()->fetchAllAssociative();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class DateService implements SingletonInterface
|
|||||||
* @return array
|
* @return array
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
* @throws \Doctrine\DBAL\DBALException
|
||||||
*/
|
*/
|
||||||
public function getPriceTable(array $options)
|
public function getPriceTable(array $options): array
|
||||||
{
|
{
|
||||||
$resolver = new OptionsResolver();
|
$resolver = new OptionsResolver();
|
||||||
$this->configurePriceTableOptions($resolver);
|
$this->configurePriceTableOptions($resolver);
|
||||||
@@ -128,9 +128,6 @@ class DateService implements SingletonInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param OptionsResolver $resolver
|
|
||||||
*/
|
|
||||||
protected function configurePriceTableOptions(OptionsResolver $resolver)
|
protected function configurePriceTableOptions(OptionsResolver $resolver)
|
||||||
{
|
{
|
||||||
$resolver->setRequired(['product', 'hotel']);
|
$resolver->setRequired(['product', 'hotel']);
|
||||||
@@ -141,11 +138,7 @@ class DateService implements SingletonInterface
|
|||||||
$resolver->setAllowedTypes('date', Date::class);
|
$resolver->setAllowedTypes('date', Date::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getDatesTable(array $options): array
|
||||||
* @param array $options
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getDatesTable(array $options)
|
|
||||||
{
|
{
|
||||||
$resolver = new OptionsResolver();
|
$resolver = new OptionsResolver();
|
||||||
$this->configureDatesTableOptions($resolver);
|
$this->configureDatesTableOptions($resolver);
|
||||||
@@ -192,16 +185,10 @@ class DateService implements SingletonInterface
|
|||||||
$resolver->setAllowedTypes('hotel', Hotel::class);
|
$resolver->setAllowedTypes('hotel', Hotel::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getEventPriceTable(Product $product, int $maxPax = 99, string $template = 'base'): array
|
||||||
* @param Product $product
|
|
||||||
* @param int $maxPax
|
|
||||||
* @param string $template
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getEventPriceTable(Product $product, $maxPax = 99, $template = 'base')
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$priceTableData = $this->productRepository->getEventPriceTable($product);
|
$priceTableData = $this->productRepository->getEventPriceTable($product);
|
||||||
|
|
||||||
return $this->preprocessEventPriceTable([
|
return $this->preprocessEventPriceTable([
|
||||||
'priceTableData' => $priceTableData,
|
'priceTableData' => $priceTableData,
|
||||||
'maxPax' => $maxPax,
|
'maxPax' => $maxPax,
|
||||||
@@ -209,20 +196,12 @@ class DateService implements SingletonInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
* @param string $search
|
|
||||||
* @param array $excludedConceptUids
|
|
||||||
* @param array $excludedRegionUids
|
|
||||||
* @return array
|
|
||||||
* @throws \Doctrine\DBAL\DBALException
|
|
||||||
*/
|
|
||||||
public function getAutocompleteOptions
|
public function getAutocompleteOptions
|
||||||
(
|
(
|
||||||
FilterSettings $filterSettings,
|
FilterSettings $filterSettings,
|
||||||
$search,
|
string $search,
|
||||||
$excludedConceptUids = [],
|
array $excludedConceptUids = [],
|
||||||
$excludedRegionUids = []
|
array $excludedRegionUids = []
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$destinations = [
|
$destinations = [
|
||||||
@@ -250,10 +229,8 @@ class DateService implements SingletonInterface
|
|||||||
|
|
||||||
$search = mb_strtolower(trim($search));
|
$search = mb_strtolower(trim($search));
|
||||||
|
|
||||||
foreach ($destinations as $type => $dummy)
|
foreach ($destinations as $type => $dummy) {
|
||||||
{
|
switch ($type) {
|
||||||
switch ($type)
|
|
||||||
{
|
|
||||||
case 'hotel':
|
case 'hotel':
|
||||||
$result = $this->dateRepository->searchHotels($search, $filterSettings);
|
$result = $this->dateRepository->searchHotels($search, $filterSettings);
|
||||||
break;
|
break;
|
||||||
@@ -269,8 +246,7 @@ class DateService implements SingletonInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($result as $row)
|
foreach ($result as $row) {
|
||||||
{
|
|
||||||
$destinations[$type]['options'][] = [
|
$destinations[$type]['options'][] = [
|
||||||
'uid' => $row['uid'],
|
'uid' => $row['uid'],
|
||||||
'name' => $row['name'],
|
'name' => $row['name'],
|
||||||
@@ -281,11 +257,7 @@ class DateService implements SingletonInterface
|
|||||||
return $destinations;
|
return $destinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function preprocessPriceTable(array $options): array
|
||||||
* @param array $options
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function preprocessPriceTable(array $options)
|
|
||||||
{
|
{
|
||||||
$resolver = new OptionsResolver();
|
$resolver = new OptionsResolver();
|
||||||
$resolver->setDefined(['paCode', 'isDayTrip', 'isHideBookingButton', 'nonBookableDateUids']);
|
$resolver->setDefined(['paCode', 'isDayTrip', 'isHideBookingButton', 'nonBookableDateUids']);
|
||||||
@@ -301,8 +273,7 @@ class DateService implements SingletonInterface
|
|||||||
$isDayTrip = $resolvedOptions['isDayTrip'];
|
$isDayTrip = $resolvedOptions['isDayTrip'];
|
||||||
$nonBookableDateUids = $resolvedOptions['nonBookableDateUids'];
|
$nonBookableDateUids = $resolvedOptions['nonBookableDateUids'];
|
||||||
|
|
||||||
foreach ($priceTableData as $row)
|
foreach ($priceTableData as $row) {
|
||||||
{
|
|
||||||
$isHideBookingButton = $resolvedOptions['isHideBookingButton'] || in_array($row['dateBusProId'], $nonBookableDateUids, false);
|
$isHideBookingButton = $resolvedOptions['isHideBookingButton'] || in_array($row['dateBusProId'], $nonBookableDateUids, false);
|
||||||
|
|
||||||
$dateStart = new \DateTime($row['dateStart']);
|
$dateStart = new \DateTime($row['dateStart']);
|
||||||
@@ -315,7 +286,7 @@ class DateService implements SingletonInterface
|
|||||||
'paCode' => $paCode,
|
'paCode' => $paCode,
|
||||||
'isDayTrip' => $isDayTrip,
|
'isDayTrip' => $isDayTrip,
|
||||||
]);
|
]);
|
||||||
$optionalServices = $this->preprocessOptionalServices(unserialize($row['roomOptionalServices']));
|
$optionalServices = $this->preprocessOptionalServices(unserialize($row['roomOptionalServices'], ['allowed_classes' => false]));
|
||||||
$priceTable[] = [
|
$priceTable[] = [
|
||||||
'dateStart' => $dateStart->format('d.m.Y'),
|
'dateStart' => $dateStart->format('d.m.Y'),
|
||||||
'dateEnd' => $dateEnd->format('d.m.Y'),
|
'dateEnd' => $dateEnd->format('d.m.Y'),
|
||||||
@@ -360,11 +331,7 @@ class DateService implements SingletonInterface
|
|||||||
return $processed;
|
return $processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function preprocessDatesTable(array $options): array
|
||||||
* @param array $options
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function preprocessDatesTable(array $options)
|
|
||||||
{
|
{
|
||||||
$resolver = new OptionsResolver();
|
$resolver = new OptionsResolver();
|
||||||
$resolver->setDefined(['paCode', 'isDayTrip', 'isHideBookingButton', 'nonBookableDateUids']);
|
$resolver->setDefined(['paCode', 'isDayTrip', 'isHideBookingButton', 'nonBookableDateUids']);
|
||||||
@@ -382,8 +349,7 @@ class DateService implements SingletonInterface
|
|||||||
$isDayTrip = $resolvedOptions['isDayTrip'];
|
$isDayTrip = $resolvedOptions['isDayTrip'];
|
||||||
$nonBookableDateUids = $resolvedOptions['nonBookableDateUids'];
|
$nonBookableDateUids = $resolvedOptions['nonBookableDateUids'];
|
||||||
|
|
||||||
foreach ($dateTableData as $row)
|
foreach ($dateTableData as $row) {
|
||||||
{
|
|
||||||
$isHideBookingButton = $resolvedOptions['isHideBookingButton'] || in_array($row['dateBusProId'], $nonBookableDateUids, false);
|
$isHideBookingButton = $resolvedOptions['isHideBookingButton'] || in_array($row['dateBusProId'], $nonBookableDateUids, false);
|
||||||
|
|
||||||
$dateStart = new \DateTime($row['dateStart']);
|
$dateStart = new \DateTime($row['dateStart']);
|
||||||
@@ -421,11 +387,7 @@ class DateService implements SingletonInterface
|
|||||||
return $dateTable;
|
return $dateTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function preprocessEventPriceTable(array $options): array
|
||||||
* @param array $options
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function preprocessEventPriceTable(array $options)
|
|
||||||
{
|
{
|
||||||
$resolver = new OptionsResolver();
|
$resolver = new OptionsResolver();
|
||||||
$resolver->setDefined('paCode');
|
$resolver->setDefined('paCode');
|
||||||
@@ -520,7 +482,7 @@ class DateService implements SingletonInterface
|
|||||||
return $priceTable;
|
return $priceTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkSurcharcheOrDiscount(array $datesTableData)
|
public function checkSurcharcheOrDiscount(array $datesTableData): array
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'surcharge' => false,
|
'surcharge' => false,
|
||||||
|
|||||||
@@ -198,9 +198,14 @@ class FilterService implements SingletonInterface
|
|||||||
if (array_key_exists($index, $priceRanges)) {
|
if (array_key_exists($index, $priceRanges)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
list($min, $max) = $priceRange;
|
[$min, $max] = $priceRange;
|
||||||
if ($row['minPrice'] >= $min && $row['minPrice'] < $max) {
|
if ($row['minPrice'] >= $min && $row['minPrice'] < $max) {
|
||||||
$priceRanges[$index] = FilterSettings::$priceRanges[$index];
|
$range = FilterSettings::$priceRanges[$index];
|
||||||
|
$priceRanges[$index] = [
|
||||||
|
'uid' => $index,
|
||||||
|
'min' => $range[0],
|
||||||
|
'max' => $range[1],
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,17 +58,12 @@ class FilterSettingsEncoder
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function encode(FilterSettings $filterSettings): string
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function encode(FilterSettings $filterSettings)
|
|
||||||
{
|
{
|
||||||
$encoded = [];
|
$encoded = [];
|
||||||
foreach (static::getMapping() as $property)
|
foreach (static::getMapping() as $property)
|
||||||
{
|
{
|
||||||
list($name, $type) = $property;
|
[$name, $type] = $property;
|
||||||
$method = 'get' . ucfirst($name);
|
$method = 'get' . ucfirst($name);
|
||||||
$value = $filterSettings->{$method}();
|
$value = $filterSettings->{$method}();
|
||||||
if ($type === 'array') {
|
if ($type === 'array') {
|
||||||
@@ -76,19 +71,14 @@ class FilterSettingsEncoder
|
|||||||
} elseif ($type === 'date') {
|
} elseif ($type === 'date') {
|
||||||
$encoded[] = ($value !== null) ? $value->format('Y-m-d') : '';
|
$encoded[] = ($value !== null) ? $value->format('Y-m-d') : '';
|
||||||
} else {
|
} else {
|
||||||
$encoded[] = preg_replace('/\r|\n/', '', $value);
|
$encoded[] = preg_replace('/[\r\n]/', '', $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode('|', $encoded);
|
return implode('|', $encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function decode(string $data): array
|
||||||
* @param string $data
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function decode($data)
|
|
||||||
{
|
{
|
||||||
$decoded = [];
|
$decoded = [];
|
||||||
$values = explode('|', $data);
|
$values = explode('|', $data);
|
||||||
|
|||||||
@@ -66,30 +66,19 @@ class SearchResultService implements SingletonInterface
|
|||||||
$this->flagIconService = $flagIconService;
|
$this->flagIconService = $flagIconService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getResult(FilterSettings $filterSettings, array $excludedConceptUids = []): SearchResult
|
||||||
* @param FilterSettings $filterSettings
|
|
||||||
* @param array $excludedConceptUids
|
|
||||||
*
|
|
||||||
* @return SearchResult
|
|
||||||
*/
|
|
||||||
public function getResult(FilterSettings $filterSettings, $excludedConceptUids = [])
|
|
||||||
{
|
{
|
||||||
$searchResultData = $this->productRepository->getSearchResult($filterSettings, $excludedConceptUids);
|
$searchResultData = $this->productRepository->getSearchResult($filterSettings, $excludedConceptUids);
|
||||||
|
|
||||||
return $this->preprocess($searchResultData);
|
return $this->preprocess($searchResultData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function preprocess(array $searchResultData): SearchResult
|
||||||
* @param array $searchResultData
|
|
||||||
*
|
|
||||||
* @return SearchResult
|
|
||||||
*/
|
|
||||||
public function preprocess(array $searchResultData)
|
|
||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
foreach ($searchResultData as $row)
|
foreach ($searchResultData as $row) {
|
||||||
{
|
|
||||||
// Concepts
|
// Concepts
|
||||||
if (!array_key_exists($row['conceptUid'], $data)) {
|
if (!array_key_exists($row['conceptUid'], $data)) {
|
||||||
$data[$row['conceptUid']] = [
|
$data[$row['conceptUid']] = [
|
||||||
@@ -120,7 +109,7 @@ class SearchResultService implements SingletonInterface
|
|||||||
'daytrip' => $row['daytrip'],
|
'daytrip' => $row['daytrip'],
|
||||||
'hideBookingButton' => $row['hideBookingButton'],
|
'hideBookingButton' => $row['hideBookingButton'],
|
||||||
'lowContingent' => $row['lowContingent'],
|
'lowContingent' => $row['lowContingent'],
|
||||||
'servicesIncluded' => unserialize($row['servicesIncluded']),
|
'servicesIncluded' => unserialize($row['servicesIncluded'], ['allowed_classes' => false]),
|
||||||
'hotel' => [
|
'hotel' => [
|
||||||
'uid' => $row['hotelUid'],
|
'uid' => $row['hotelUid'],
|
||||||
'name' => $row['hotelName'],
|
'name' => $row['hotelName'],
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class SearchResultUrlService implements SingletonInterface
|
|||||||
* @param SearchResult $searchResult
|
* @param SearchResult $searchResult
|
||||||
* @param array $options
|
* @param array $options
|
||||||
*/
|
*/
|
||||||
public function process(SearchResult $searchResult, array $options)
|
public function process(SearchResult $searchResult, array $options): void
|
||||||
{
|
{
|
||||||
$optionsResolver = new OptionsResolver();
|
$optionsResolver = new OptionsResolver();
|
||||||
$optionsResolver->setRequired([ 'defaultDetailPageUid' ]);
|
$optionsResolver->setRequired([ 'defaultDetailPageUid' ]);
|
||||||
@@ -60,10 +60,8 @@ class SearchResultUrlService implements SingletonInterface
|
|||||||
|
|
||||||
$data = $searchResult->getData();
|
$data = $searchResult->getData();
|
||||||
|
|
||||||
foreach ($data as $conceptUid => $conceptData)
|
foreach ($data as $conceptUid => $conceptData) {
|
||||||
{
|
foreach ($conceptData['items'] as $key => $item) {
|
||||||
foreach ($conceptData['items'] as $key => $item)
|
|
||||||
{
|
|
||||||
$detailPageUid = $this->getProductPageUid($item['product']['detailPage'], $defaultDetailPageUid);
|
$detailPageUid = $this->getProductPageUid($item['product']['detailPage'], $defaultDetailPageUid);
|
||||||
$arguments = [
|
$arguments = [
|
||||||
'product' => $item['product']['uid'],
|
'product' => $item['product']['uid'],
|
||||||
@@ -88,15 +86,15 @@ class SearchResultUrlService implements SingletonInterface
|
|||||||
* @param int $defaultUid
|
* @param int $defaultUid
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected function getProductPageUid($uid, $defaultUid)
|
protected function getProductPageUid($uid, int $defaultUid): int
|
||||||
{
|
{
|
||||||
if (is_numeric($uid)) {
|
if (is_numeric($uid)) {
|
||||||
return $uid;
|
return (int) $uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strpos($uid, 't3://') !== false) {
|
if (strpos($uid, 't3://') !== false) {
|
||||||
parse_str(parse_url($uid, PHP_URL_QUERY), $arguments);
|
parse_str(parse_url($uid, PHP_URL_QUERY), $arguments);
|
||||||
return $arguments['uid'];
|
return (int) $arguments['uid'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $defaultUid;
|
return $defaultUid;
|
||||||
|
|||||||
+2
-70
@@ -30,7 +30,6 @@ namespace EP\EpProducts\Traits;
|
|||||||
use EP\EpProducts\Domain\Model\FilterSettings;
|
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 TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||||
|
|
||||||
@@ -44,21 +43,7 @@ trait RequestArgumentTypeConversionTrait
|
|||||||
public function processSearchParamsArgument(array $forcedConceptUids = [])
|
public function processSearchParamsArgument(array $forcedConceptUids = [])
|
||||||
{
|
{
|
||||||
if ($this->request->hasArgument('searchParams')) {
|
if ($this->request->hasArgument('searchParams')) {
|
||||||
|
$searchParamsObject = SearchParams::fromRequest($this->request);
|
||||||
$searchParams = (array) $this->request->getArgument('searchParams');
|
|
||||||
|
|
||||||
$searchParams['dateFrom'] = !empty($searchParams['dateFrom']) ? new \DateTime($searchParams['dateFrom']) : null;
|
|
||||||
$searchParams['dateTo'] = !empty($searchParams['dateTo']) ? new \DateTime($searchParams['dateTo']) : null;
|
|
||||||
|
|
||||||
$searchParamsObject = new SearchParams();
|
|
||||||
|
|
||||||
foreach ($searchParams as $key => $value) {
|
|
||||||
$setter = 'set' . ucfirst($key);
|
|
||||||
$value = static::convertType($value);
|
|
||||||
if (method_exists($searchParamsObject, $setter)) {
|
|
||||||
$searchParamsObject->{$setter}($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($forcedConceptUids) {
|
if ($forcedConceptUids) {
|
||||||
$searchParamsObject->setConceptUids($forcedConceptUids);
|
$searchParamsObject->setConceptUids($forcedConceptUids);
|
||||||
@@ -83,37 +68,7 @@ trait RequestArgumentTypeConversionTrait
|
|||||||
if (!$this->request->hasArgument('filterSettings')) {
|
if (!$this->request->hasArgument('filterSettings')) {
|
||||||
$filterSettingsObject = $filterService->getDefaultFilterSettings($forcedConceptUids);
|
$filterSettingsObject = $filterService->getDefaultFilterSettings($forcedConceptUids);
|
||||||
} else {
|
} else {
|
||||||
$filterSettingsRaw = $this->request->getArgument('filterSettings');
|
$filterSettingsObject = FilterSettings::fromRequest($this->request);
|
||||||
|
|
||||||
if (is_array($filterSettingsRaw)) {
|
|
||||||
$filterSettings = $filterSettingsRaw;
|
|
||||||
} elseif (is_string($filterSettingsRaw)) {
|
|
||||||
$filterSettingsString = urldecode($filterSettingsRaw);
|
|
||||||
$filterSettings = FilterSettingsEncoder::decode($filterSettingsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($filterSettingsRaw instanceof FilterSettings) {
|
|
||||||
$filterSettingsObject = $filterSettingsRaw;
|
|
||||||
} else {
|
|
||||||
$filterSettings['dateFrom'] = !empty($filterSettings['dateFrom']) ? new \DateTime($filterSettings['dateFrom']) : null;
|
|
||||||
$filterSettings['dateTo'] = !empty($filterSettings['dateTo']) ? new \DateTime($filterSettings['dateTo']) : null;
|
|
||||||
|
|
||||||
if (!empty($filterSettings['bus'])) {
|
|
||||||
$filterSettings['bus'] = \in_array($filterSettings['bus'], [ 'true', '1' ], true);
|
|
||||||
} else {
|
|
||||||
$filterSettings['bus'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$filterSettingsObject = new FilterSettings();
|
|
||||||
|
|
||||||
foreach ($filterSettings as $key => $value) {
|
|
||||||
$setter = 'set' . ucfirst($key);
|
|
||||||
$value = static::convertType($value);
|
|
||||||
if (method_exists($filterSettingsObject, $setter)) {
|
|
||||||
$filterSettingsObject->{$setter}($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($forcedConceptUids) {
|
if ($forcedConceptUids) {
|
||||||
$conceptUids = $filterSettingsObject->getConceptUids();
|
$conceptUids = $filterSettingsObject->getConceptUids();
|
||||||
@@ -127,27 +82,4 @@ trait RequestArgumentTypeConversionTrait
|
|||||||
$this->request->setArgument('filterSettings', $filterSettingsObject);
|
$this->request->setArgument('filterSettings', $filterSettingsObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts numeric scalars and numeric elements of arrays
|
|
||||||
* to integers and string scalars to booleans if applicable
|
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
protected static function convertType($value)
|
|
||||||
{
|
|
||||||
if (\is_string($value) && (strtolower($value) === 'true' || strtolower($value) === 'false')) {
|
|
||||||
return strtolower($value) === 'true';
|
|
||||||
}
|
|
||||||
if (\is_numeric($value)) {
|
|
||||||
return (int) $value;
|
|
||||||
}
|
|
||||||
if (\is_array($value)) {
|
|
||||||
return array_map(function($item) {
|
|
||||||
return static::convertType($item);
|
|
||||||
}, $value);
|
|
||||||
}
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,20 +30,17 @@ namespace EP\EpProducts\Utility;
|
|||||||
class DateUtility
|
class DateUtility
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
public static function formatDateRange
|
||||||
* @param \DateTime $dateFrom
|
(
|
||||||
* @param \DateTime $dateTo
|
\DateTime $dateFrom = null,
|
||||||
* @param bool $includeLabel*
|
\DateTime $dateTo = null,
|
||||||
* @param string $format
|
bool $includeLabel = true,
|
||||||
*
|
string $format = 'd.m.Y'
|
||||||
* @return string
|
): string {
|
||||||
*/
|
|
||||||
public static function formatDateRange(\DateTime $dateFrom = null, \DateTime $dateTo = null, $includeLabel = true, $format = 'd.m.Y')
|
|
||||||
{
|
|
||||||
if ($dateFrom === null && $dateTo === null) {
|
if ($dateFrom === null && $dateTo === null) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
$label = (bool) $includeLabel ? 'im Zeitraum ' : '';
|
$label = $includeLabel ? 'im Zeitraum ' : '';
|
||||||
if ($dateFrom !== null && $dateTo === null) {
|
if ($dateFrom !== null && $dateTo === null) {
|
||||||
return $label . 'ab ' . $dateFrom->format($format);
|
return $label . 'ab ' . $dateFrom->format($format);
|
||||||
}
|
}
|
||||||
@@ -53,14 +50,7 @@ class DateUtility
|
|||||||
return $label . $dateFrom->format($format) . '-' . $dateTo->format($format);
|
return $label . $dateFrom->format($format) . '-' . $dateTo->format($format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function getDateRange($fromYear = null, $fromMonth = null, int $months = 6): array
|
||||||
* @param string|int $fromYear
|
|
||||||
* @param string|int $fromMonth
|
|
||||||
* @param int $months
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getDateRange($fromYear = null, $fromMonth = null, $months = 6)
|
|
||||||
{
|
{
|
||||||
$now = new \DateTime('now');
|
$now = new \DateTime('now');
|
||||||
$currentMonth = (int) $now->format('m');
|
$currentMonth = (int) $now->format('m');
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpProducts\Utility;
|
||||||
|
|
||||||
|
class TypeConversionUtility
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Converts numeric scalars and numeric elements of arrays
|
||||||
|
* to integers and string scalars to booleans if applicable
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function convertType($value)
|
||||||
|
{
|
||||||
|
if (\is_string($value) && (strtolower($value) === 'true' || strtolower($value) === 'false')) {
|
||||||
|
return strtolower($value) === 'true';
|
||||||
|
}
|
||||||
|
if (\is_numeric($value)) {
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
if (\is_array($value)) {
|
||||||
|
return array_map(function($item) {
|
||||||
|
return static::convertType($item);
|
||||||
|
}, $value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -149,18 +149,18 @@ tx_epproducts_ajax_json {
|
|||||||
action = searchresult
|
action = searchresult
|
||||||
switchableControllerActions {
|
switchableControllerActions {
|
||||||
AjaxSearch {
|
AjaxSearch {
|
||||||
|
1 = pricetable
|
||||||
2 = searchresult
|
2 = searchresult
|
||||||
4 = pricetable
|
|
||||||
}
|
}
|
||||||
AjaxDate {
|
AjaxDate {
|
||||||
1 = dates
|
1 = dates
|
||||||
}
|
}
|
||||||
AjaxSearchbar {
|
AjaxSearchbar {
|
||||||
1 = options
|
1 = update
|
||||||
2 = reset
|
|
||||||
}
|
}
|
||||||
AjaxFilterpanel {
|
AjaxFilterpanel {
|
||||||
1 = autocomplete
|
1 = panel
|
||||||
|
2 = autocomplete
|
||||||
}
|
}
|
||||||
AjaxTable {
|
AjaxTable {
|
||||||
1 = pricetable
|
1 = pricetable
|
||||||
|
|||||||
@@ -371,8 +371,8 @@ $iconRegistry->registerIcon(
|
|||||||
[
|
[
|
||||||
'AjaxSearch' => 'searchresult',
|
'AjaxSearch' => 'searchresult',
|
||||||
'AjaxDate' => 'dates',
|
'AjaxDate' => 'dates',
|
||||||
'AjaxFilterpanel' => 'autocomplete',
|
'AjaxFilterpanel' => 'panel,autocomplete',
|
||||||
'AjaxSearchbar' => 'options,reset',
|
'AjaxSearchbar' => 'update',
|
||||||
'AjaxContingent' => 'list,rooms',
|
'AjaxContingent' => 'list,rooms',
|
||||||
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
||||||
'AjaxCalendar' => 'range,contingents,availableRooms',
|
'AjaxCalendar' => 'range,contingents,availableRooms',
|
||||||
@@ -382,8 +382,8 @@ $iconRegistry->registerIcon(
|
|||||||
[
|
[
|
||||||
'AjaxSearch' => 'searchresult',
|
'AjaxSearch' => 'searchresult',
|
||||||
'AjaxDate' => 'dates',
|
'AjaxDate' => 'dates',
|
||||||
'AjaxFilterpanel' => 'autocomplete',
|
'AjaxFilterpanel' => 'panel,autocomplete',
|
||||||
'AjaxSearchbar' => 'options,reset',
|
'AjaxSearchbar' => 'update',
|
||||||
'AjaxContingent' => 'list,rooms',
|
'AjaxContingent' => 'list,rooms',
|
||||||
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
||||||
'AjaxCalendar' => 'range,contingents,availableRooms',
|
'AjaxCalendar' => 'range,contingents,availableRooms',
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ class DateRangeViewHelper extends AbstractViewHelper
|
|||||||
{
|
{
|
||||||
parent::initializeArguments();
|
parent::initializeArguments();
|
||||||
|
|
||||||
$this->registerArgument('dateFrom', \DateTime::class, 'Date range start');
|
$this->registerArgument('dateFrom', 'mixed', 'Date range start');
|
||||||
$this->registerArgument('dateTo', \DateTime::class, 'Date range end');
|
$this->registerArgument('dateTo', 'mixed', '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');
|
||||||
}
|
}
|
||||||
@@ -58,11 +58,25 @@ class DateRangeViewHelper extends AbstractViewHelper
|
|||||||
RenderingContextInterface $renderingContext
|
RenderingContextInterface $renderingContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
$dateFrom = static::ensureDateObject($arguments['dateFrom']);
|
||||||
|
$dateTo = static::ensureDateObject($arguments['dateTo']);
|
||||||
|
|
||||||
return DateUtility::formatDateRange(
|
return DateUtility::formatDateRange(
|
||||||
$arguments['dateFrom'],
|
$dateFrom,
|
||||||
$arguments['dateTo'],
|
$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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpTheme\ViewHelpers;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2021 Björn Fromme <[email protected]>, dreipunktnull
|
||||||
|
*
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||||
|
* free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The GNU General Public License can be found at
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
*
|
||||||
|
* This script is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||||
|
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||||
|
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||||
|
|
||||||
|
class PriceRangeViewHelper extends AbstractViewHelper
|
||||||
|
{
|
||||||
|
use CompileWithRenderStatic;
|
||||||
|
|
||||||
|
public function initializeArguments()
|
||||||
|
{
|
||||||
|
parent::initializeArguments();
|
||||||
|
|
||||||
|
$this->registerArgument('min', 'mixed', 'Price range start');
|
||||||
|
$this->registerArgument('max', 'mixed', 'Price range end');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $arguments
|
||||||
|
* @param \Closure $renderChildrenClosure
|
||||||
|
* @param RenderingContextInterface $renderingContext
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public static function renderStatic(
|
||||||
|
array $arguments,
|
||||||
|
\Closure $renderChildrenClosure,
|
||||||
|
RenderingContextInterface $renderingContext
|
||||||
|
) {
|
||||||
|
if (1 === (int) $arguments['min']) {
|
||||||
|
return sprintf('bis %d €', $arguments['max']);
|
||||||
|
}
|
||||||
|
if (999 === (int) $arguments['max']) {
|
||||||
|
return sprintf('ab %d €', $arguments['min']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('%d bis %d €', $arguments['min'], $arguments['max']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,9 +15,11 @@ 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 scrollTop from './components/scoll-top'
|
||||||
|
import scrollTo from './components/scroll-to'
|
||||||
import sticky from './components/sticky'
|
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 collapse from './components/collapse'
|
import collapse from './components/collapse'
|
||||||
import fbpixel from './components/fbpixel'
|
import fbpixel from './components/fbpixel'
|
||||||
import ajaxContent from './components/ajax-content'
|
import ajaxContent from './components/ajax-content'
|
||||||
@@ -26,6 +28,11 @@ 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 searchResult from './components/search-result'
|
||||||
|
import filterPanel from './components/filter-panel'
|
||||||
|
|
||||||
|
import defaultFilterSettings from './_filtersettings'
|
||||||
|
import defaultFilterOptions from './_filteroptions'
|
||||||
|
|
||||||
// Executed on document ready
|
// Executed on document ready
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
@@ -40,10 +47,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
modal: null,
|
modal: null,
|
||||||
})
|
})
|
||||||
Alpine.store('watchlist', storedWatchlist)
|
Alpine.store('watchlist', storedWatchlist)
|
||||||
|
Alpine.store('filterSettings', defaultFilterSettings)
|
||||||
|
Alpine.store('filterOptions', defaultFilterOptions)
|
||||||
Alpine.data('scrollTop', scrollTop)
|
Alpine.data('scrollTop', scrollTop)
|
||||||
|
Alpine.data('scrollTo', scrollTo)
|
||||||
Alpine.data('sticky', sticky)
|
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('collapse', collapse)
|
Alpine.data('collapse', collapse)
|
||||||
Alpine.data('fbpixel', fbpixel)
|
Alpine.data('fbpixel', fbpixel)
|
||||||
Alpine.data('ajaxContent', ajaxContent)
|
Alpine.data('ajaxContent', ajaxContent)
|
||||||
@@ -52,6 +63,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
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('searchResult', searchResult)
|
||||||
|
Alpine.data('filterPanel', filterPanel)
|
||||||
Alpine.start()
|
Alpine.start()
|
||||||
|
|
||||||
Glightbox({
|
Glightbox({
|
||||||
@@ -64,31 +77,31 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
/// LEGACY CODE FROM HERE ///
|
/// LEGACY CODE FROM HERE ///
|
||||||
|
|
||||||
// Import dependencies
|
// Import dependencies
|
||||||
import Vue from 'vue'
|
// import Vue from 'vue'
|
||||||
import $ from 'jquery'
|
// import $ from 'jquery'
|
||||||
import dayjs from 'dayjs'
|
// import dayjs from 'dayjs'
|
||||||
import 'dayjs/locale/de'
|
// import 'dayjs/locale/de'
|
||||||
|
|
||||||
global.$ = global.jQuery = $;
|
// global.$ = global.jQuery = $;
|
||||||
|
|
||||||
require('bootstrap-sass/assets/javascripts/bootstrap/dropdown')
|
// require('bootstrap-sass/assets/javascripts/bootstrap/dropdown')
|
||||||
require('bootstrap-sass/assets/javascripts/bootstrap/modal')
|
// require('bootstrap-sass/assets/javascripts/bootstrap/modal')
|
||||||
require('bootstrap-sass/assets/javascripts/bootstrap/transition')
|
// require('bootstrap-sass/assets/javascripts/bootstrap/transition')
|
||||||
|
|
||||||
// Import components
|
// Import components
|
||||||
import SearchBar from './components/SearchBar.vue'
|
// import SearchBar from './components/SearchBar.vue'
|
||||||
import SearchBox from './components/SearchBox.vue'
|
// import SearchBox from './components/SearchBox.vue'
|
||||||
//import ProductDetail from './components/ProductDetail.vue'
|
//import ProductDetail from './components/ProductDetail.vue'
|
||||||
import Calendar from './components/Calendar.vue'
|
// import Calendar from './components/Calendar.vue'
|
||||||
import EventPricetable from './components/EventPriceTable.vue'
|
// import EventPricetable from './components/EventPriceTable.vue'
|
||||||
import ContactForm from './components/ContactForm.vue'
|
// import ContactForm from './components/ContactForm.vue'
|
||||||
import Watchlist from './components/Watchlist.vue'
|
// import Watchlist from './components/Watchlist.vue'
|
||||||
import HotelList from './components/HotelList.vue'
|
// import HotelList from './components/HotelList.vue'
|
||||||
|
|
||||||
// Define date filter for vue templates
|
// Define date filter for vue templates
|
||||||
Vue.filter('date', (value) => {
|
// Vue.filter('date', (value) => {
|
||||||
return dayjs(value).format('DD.MM.YY');
|
// return dayjs(value).format('DD.MM.YY');
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
// import store from './store';
|
// import store from './store';
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ export default () => {
|
|||||||
if (null === configElement) {
|
if (null === configElement) {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
return JSON.parse(configElement.innerHTML);
|
return JSON.parse(configElement.innerHTML)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default (isCollapsed = true, until = null, from = null) => ({
|
|||||||
trigger: {
|
trigger: {
|
||||||
['@click.prevent']() {
|
['@click.prevent']() {
|
||||||
this.collapsed = !this.collapsed
|
this.collapsed = !this.collapsed
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
['x-show']() {
|
['x-show']() {
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
import flatpickr from 'flatpickr';
|
||||||
|
import { German } from 'flatpickr/dist/l10n/de';
|
||||||
|
import defaultFilterSettings from '../_filtersettings'
|
||||||
|
|
||||||
|
export default props => ({
|
||||||
|
loading: false,
|
||||||
|
show: null,
|
||||||
|
picker: null,
|
||||||
|
uri: props.uri,
|
||||||
|
datePresets: props.datePresets,
|
||||||
|
filterSettings: props.initialFilterSettings,
|
||||||
|
defaultFilterSettings,
|
||||||
|
filterCount: 0,
|
||||||
|
dateRangeSelected: { from: null, to: null },
|
||||||
|
dateRangeLabel: null,
|
||||||
|
init() {
|
||||||
|
this.updateFilterCount()
|
||||||
|
this.load()
|
||||||
|
this.$watch('filterSettings', () => {
|
||||||
|
this.$dispatch('filter-settings-updated', this.filterSettings)
|
||||||
|
this.updateFilterCount()
|
||||||
|
this.updateDateRangeLabel()
|
||||||
|
this.load()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
load() {
|
||||||
|
this.loading = true
|
||||||
|
let data = new URLSearchParams({
|
||||||
|
'tx_epproducts_ajax[filterSettings]': JSON.stringify(this.filterSettings)
|
||||||
|
})
|
||||||
|
axios.post(this.uri, data)
|
||||||
|
.then(response => {
|
||||||
|
this.$refs.panel.innerHTML = response.data
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
if (null !== this.filterSettings.dateFrom && null !== this.filterSettings.dateTo) {
|
||||||
|
this.picker.setDate([ this.filterSettings.dateFrom, this.filterSettings.dateTo ])
|
||||||
|
this.dateRangeSelected = { from: new Date(this.filterSettings.dateFrom), to: new Date(this.filterSettings.dateTo) }
|
||||||
|
this.updateDateRangeLabel()
|
||||||
|
}
|
||||||
|
this.$el.scrollIntoView({behavior: 'smooth'})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
this.filterSettings = {...this.defaultFilterSettings}
|
||||||
|
this.dateRangeLabel = null
|
||||||
|
},
|
||||||
|
initDatePicker(minDate, maxDate) {
|
||||||
|
this.picker = flatpickr(this.$refs.picker, {
|
||||||
|
mode: 'range',
|
||||||
|
locale: German,
|
||||||
|
inline: true,
|
||||||
|
minDate: minDate,
|
||||||
|
maxDate: maxDate,
|
||||||
|
onChange: selectedDates => {
|
||||||
|
if (selectedDates.length === 2) {
|
||||||
|
this.dateRangeSelected = { from: selectedDates[0], to: selectedDates[1] }
|
||||||
|
this.updateFilterSettings({
|
||||||
|
dateFrom: flatpickr.formatDate(selectedDates[0], 'Y-m-d'),
|
||||||
|
dateTo: flatpickr.formatDate(selectedDates[1], 'Y-m-d'),
|
||||||
|
})
|
||||||
|
this.updateDateRangeLabel()
|
||||||
|
this.show = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateFilterSettings(values) {
|
||||||
|
let filterSettings = {...this.filterSettings}
|
||||||
|
this.filterSettings = {...filterSettings, ...values}
|
||||||
|
},
|
||||||
|
selectDateRangePreset(preset) {
|
||||||
|
let dateFrom = new Date(preset.dateFrom)
|
||||||
|
let dateTo = new Date(preset.dateTo)
|
||||||
|
this.dateRangeSelected = { from: dateFrom, to: dateTo }
|
||||||
|
this.updateFilterSettings({
|
||||||
|
dateFrom: flatpickr.formatDate(dateFrom, 'Y-m-d'),
|
||||||
|
dateTo: flatpickr.formatDate(dateTo, 'Y-m-d'),
|
||||||
|
})
|
||||||
|
this.updateDateRangeLabel()
|
||||||
|
this.picker.setDate([ dateFrom, dateTo ])
|
||||||
|
this.show = null
|
||||||
|
},
|
||||||
|
resetDateRange() {
|
||||||
|
this.dateRangeSelected = { from: null, to: null }
|
||||||
|
this.updateFilterSettings({
|
||||||
|
dateFrom: null,
|
||||||
|
dateTo: null,
|
||||||
|
})
|
||||||
|
this.updateDateRangeLabel()
|
||||||
|
this.show = null
|
||||||
|
},
|
||||||
|
toggleFilterValue(name, value, multiple = false) {
|
||||||
|
let updates = {}
|
||||||
|
let newValue = this.filterSettings[name]
|
||||||
|
if (!multiple) {
|
||||||
|
newValue = newValue === value ? null : value
|
||||||
|
} else {
|
||||||
|
let index = newValue.indexOf(value)
|
||||||
|
if (index !== -1) {
|
||||||
|
newValue.splice(index, 1)
|
||||||
|
} else {
|
||||||
|
newValue.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updates[name] = newValue
|
||||||
|
this.updateFilterSettings(updates)
|
||||||
|
},
|
||||||
|
toggleDestinationOrConcept(uid, name, type) {
|
||||||
|
let values = { destinationUid: null, destinationName: null, destinationType: null }
|
||||||
|
if ('concept' === type) {
|
||||||
|
values = {...values, conceptUids: []}
|
||||||
|
}
|
||||||
|
let currentUid = this.filterSettings.destinationUid
|
||||||
|
let currentType = this.filterSettings.destinationType
|
||||||
|
if (currentUid !== uid || currentType !== type) {
|
||||||
|
values = { destinationUid: uid, destinationName: name, destinationType: type }
|
||||||
|
if ('concept' === type) {
|
||||||
|
values = {...values, conceptUids: [uid]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateFilterSettings(values)
|
||||||
|
},
|
||||||
|
updateDateRangeLabel() {
|
||||||
|
let dateRangeLabel = ''
|
||||||
|
if (null !== this.dateRangeSelected.from && null !== this.dateRangeSelected.to) {
|
||||||
|
let dateFrom = this.dateRangeSelected.from
|
||||||
|
let dateTo = this.dateRangeSelected.to
|
||||||
|
dateRangeLabel = `${flatpickr.formatDate(dateFrom, 'd.m.Y')} - ${flatpickr.formatDate(dateTo, 'd.m.Y')}`
|
||||||
|
}
|
||||||
|
this.dateRangeLabel = dateRangeLabel
|
||||||
|
},
|
||||||
|
updateFilterCount() {
|
||||||
|
let count = 0
|
||||||
|
if (this.filterSettings.destinationUid) count++
|
||||||
|
if (this.filterSettings.destinationName) count++
|
||||||
|
if (this.filterSettings.countryUids.length > 0) count++
|
||||||
|
if (this.filterSettings.regionUids.length > 0) count++
|
||||||
|
if (this.filterSettings.cityUids.length > 0) count++
|
||||||
|
if (this.filterSettings.conceptUids.length > 0) count++
|
||||||
|
if (this.filterSettings.hotelTypes.length > 0) count++
|
||||||
|
if (this.filterSettings.boardTypes.length > 0) count++
|
||||||
|
if (this.filterSettings.roomTypes.length > 0) count++
|
||||||
|
if (this.filterSettings.dateFrom !== null) count++
|
||||||
|
if (this.filterSettings.dateTo !== null) count++
|
||||||
|
if (this.filterSettings.priceRange > 0) count++
|
||||||
|
if (this.filterSettings.bus) count++
|
||||||
|
if (this.filterSettings.pax > 2) count++
|
||||||
|
this.filterCount = count
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export default targetId => ({
|
||||||
|
targetId,
|
||||||
|
init() {
|
||||||
|
this.$el.addEventListener('click', e => {
|
||||||
|
e.preventDefault()
|
||||||
|
document.getElementById(this.targetId).scrollIntoView({behavior: 'smooth'})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
+47
-64
@@ -3,9 +3,9 @@ import flatpickr from 'flatpickr'
|
|||||||
import { German } from 'flatpickr/dist/l10n/de'
|
import { German } from 'flatpickr/dist/l10n/de'
|
||||||
|
|
||||||
export default props => ({
|
export default props => ({
|
||||||
|
loading: false,
|
||||||
picker: null,
|
picker: null,
|
||||||
optionsUri: props.optionsUri,
|
uri: props.uri,
|
||||||
resetUri: props.resetUri,
|
|
||||||
searchParams: props.initialSearchParams,
|
searchParams: props.initialSearchParams,
|
||||||
filterOptions: props.initialFilterOptions,
|
filterOptions: props.initialFilterOptions,
|
||||||
datePresets: props.datePresets,
|
datePresets: props.datePresets,
|
||||||
@@ -22,26 +22,28 @@ export default props => ({
|
|||||||
this.searchParams.dateFrom = null
|
this.searchParams.dateFrom = null
|
||||||
this.searchParams.dateTo = null
|
this.searchParams.dateTo = null
|
||||||
} else {
|
} else {
|
||||||
let dateFrom = flatpickr.formatDate(this.dateRangeSelected.from, 'd.m.Y')
|
let dateFrom = this.dateRangeSelected.from
|
||||||
let dateTo = flatpickr.formatDate(this.dateRangeSelected.to, 'd.m.Y')
|
let dateTo = this.dateRangeSelected.to
|
||||||
dateRangeLabel = `${dateFrom} - ${dateTo}`
|
dateRangeLabel = `${flatpickr.formatDate(dateFrom, 'd.m.Y')} - ${flatpickr.formatDate(dateTo, 'd.m.Y')}`
|
||||||
this.searchParams.dateFrom = dateFrom
|
this.searchParams.dateFrom = flatpickr.formatDate(dateFrom, 'Y-m-d')
|
||||||
this.searchParams.dateTo = dateTo
|
this.searchParams.dateTo = flatpickr.formatDate(dateTo, 'Y-m-d')
|
||||||
}
|
}
|
||||||
this.dateRangeLabel = dateRangeLabel
|
this.dateRangeLabel = dateRangeLabel
|
||||||
this.loadOptions()
|
this.load()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
loadOptions() {
|
load() {
|
||||||
const data = { 'tx_epproducts_ajax[searchParams]': this.searchParams }
|
this.loading = true
|
||||||
axios({
|
const data = new FormData()
|
||||||
url: this.optionsUri,
|
data.set('tx_epproducts_ajax[searchParams]', JSON.stringify(this.searchParams))
|
||||||
method: 'post',
|
axios.post(this.uri, data)
|
||||||
data
|
.then(response => {
|
||||||
}).then(response => {
|
|
||||||
this.applyOptions(response.data)
|
this.applyOptions(response.data)
|
||||||
this.show = null
|
this.show = null
|
||||||
})
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
applyOptions(json) {
|
applyOptions(json) {
|
||||||
this.filterOptions.totalResults = json.totalResults
|
this.filterOptions.totalResults = json.totalResults
|
||||||
@@ -58,26 +60,7 @@ export default props => ({
|
|||||||
},
|
},
|
||||||
updateSearchParam(param, value) {
|
updateSearchParam(param, value) {
|
||||||
this.searchParams[param] = value
|
this.searchParams[param] = value
|
||||||
this.loadOptions()
|
this.load()
|
||||||
},
|
|
||||||
updateDestination(destination) {
|
|
||||||
if (destination.type === 'concept') {
|
|
||||||
this.searchParams.conceptUid = destination.uid
|
|
||||||
} else {
|
|
||||||
this.searchParams.destinationUid = destination.uid
|
|
||||||
this.searchParams.destinationType = destination.type
|
|
||||||
}
|
|
||||||
this.loadOptions()
|
|
||||||
},
|
|
||||||
resetDestination() {
|
|
||||||
axios({
|
|
||||||
url: this.resetUri,
|
|
||||||
method: 'post'
|
|
||||||
}).then(response => {
|
|
||||||
this.applyOptions(response.data)
|
|
||||||
this.searchParams = response.data.searchParams
|
|
||||||
this.show = null
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
selectDateRangePreset(preset) {
|
selectDateRangePreset(preset) {
|
||||||
let dateFrom = new Date(preset.dateFrom)
|
let dateFrom = new Date(preset.dateFrom)
|
||||||
@@ -90,10 +73,31 @@ export default props => ({
|
|||||||
this.picker.clear()
|
this.picker.clear()
|
||||||
this.picker.jumpToDate()
|
this.picker.jumpToDate()
|
||||||
},
|
},
|
||||||
|
selectDestination(uid, name, type) {
|
||||||
|
this.destinationName = name
|
||||||
|
this.destinationSelected = true
|
||||||
|
this.conceptSelected = false
|
||||||
|
this.searchParams.destinationUid = uid
|
||||||
|
this.searchParams.destinationType = type
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
selectConcept(uid, name) {
|
||||||
|
this.destinationName = name
|
||||||
|
this.destinationSelected = false
|
||||||
|
this.conceptSelected = true
|
||||||
|
this.searchParams.destinationUid = uid
|
||||||
|
this.searchParams.destinationType = 'concept'
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
resetDestination() {
|
||||||
|
this.destinationName = 'beliebig'
|
||||||
|
this.destinationSelected = false
|
||||||
|
this.conceptSelected = false
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
initDatePicker() {
|
initDatePicker() {
|
||||||
this.picker = flatpickr(this.$refs.picker, {
|
this.picker = flatpickr(this.$refs.picker, {
|
||||||
mode: 'range',
|
mode: 'range',
|
||||||
dateFormat: 'd.m.Y',
|
|
||||||
locale: German,
|
locale: German,
|
||||||
inline: true,
|
inline: true,
|
||||||
onChange: selectedDates => {
|
onChange: selectedDates => {
|
||||||
@@ -102,8 +106,9 @@ export default props => ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (this.filterOptions.minDate && this.filterOptions.maxDate) {
|
let minDate = this.filterOptions.minDate ? new Date(this.filterOptions.minDate) : new Date
|
||||||
this.picker.set('minDate', new Date(this.filterOptions.minDate))
|
this.picker.set('minDate', minDate)
|
||||||
|
if (this.filterOptions.maxDate) {
|
||||||
this.picker.set('maxDate', new Date(this.filterOptions.maxDate))
|
this.picker.set('maxDate', new Date(this.filterOptions.maxDate))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -112,11 +117,11 @@ export default props => ({
|
|||||||
return 'beliebig'
|
return 'beliebig'
|
||||||
}
|
}
|
||||||
let range = this.filterOptions.priceRanges[this.searchParams.priceRange]
|
let range = this.filterOptions.priceRanges[this.searchParams.priceRange]
|
||||||
return this.formatPriceRange(range)
|
return this.priceRangeFormatted(range)
|
||||||
},
|
},
|
||||||
formatPriceRange(range) {
|
priceRangeFormatted(range) {
|
||||||
let min = range[0];
|
let min = range.min;
|
||||||
let max = range[1];
|
let max = range.max;
|
||||||
if (min === 1) {
|
if (min === 1) {
|
||||||
return 'bis ' + max + ' €'
|
return 'bis ' + max + ' €'
|
||||||
}
|
}
|
||||||
@@ -125,26 +130,4 @@ export default props => ({
|
|||||||
}
|
}
|
||||||
return min + ' - ' + max + ' €'
|
return min + ' - ' + max + ' €'
|
||||||
},
|
},
|
||||||
selectDestination(uid, name, type) {
|
|
||||||
this.destinationName = name
|
|
||||||
this.destinationSelected = true
|
|
||||||
this.conceptSelected = false
|
|
||||||
this.searchParams.destinationUid = uid
|
|
||||||
this.searchParams.destinationType = type
|
|
||||||
this.loadOptions()
|
|
||||||
},
|
|
||||||
selectConcept(uid, name) {
|
|
||||||
this.destinationName = name
|
|
||||||
this.destinationSelected = false
|
|
||||||
this.conceptSelected = true
|
|
||||||
this.searchParams.destinationUid = uid
|
|
||||||
this.searchParams.destinationType = 'concept'
|
|
||||||
this.loadOptions()
|
|
||||||
},
|
|
||||||
resetDestinationSelect() {
|
|
||||||
this.destinationName = 'beliebig'
|
|
||||||
this.destinationSelected = false
|
|
||||||
this.conceptSelected = false
|
|
||||||
this.resetDestination()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default props => ({
|
||||||
|
loading: false,
|
||||||
|
uri: props.uri,
|
||||||
|
filterSettings: props.initialFilterSettings,
|
||||||
|
init() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
onFilterSettingsUpdated(e) {
|
||||||
|
this.filterSettings = e.detail
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
load() {
|
||||||
|
this.loading = true
|
||||||
|
let data = new URLSearchParams({
|
||||||
|
'tx_epproducts_ajax[filterSettings]': JSON.stringify(this.filterSettings)
|
||||||
|
})
|
||||||
|
axios.post(this.uri, data)
|
||||||
|
.then(response => {
|
||||||
|
this.$refs.results.innerHTML = response.data
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default uri => ({
|
||||||
|
loading: false,
|
||||||
|
uri,
|
||||||
|
init() {
|
||||||
|
this.load()
|
||||||
|
},
|
||||||
|
load() {
|
||||||
|
this.loading = true
|
||||||
|
let data = new URLSearchParams({
|
||||||
|
'tx_epproducts_ajax[watchlistUids]': JSON.stringify(this.$store.watchlist),
|
||||||
|
})
|
||||||
|
axios.post(this.uri, data)
|
||||||
|
.then(response => {
|
||||||
|
this.$refs.watchlist.innerHTML = response.data
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
||||||
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
|
||||||
|
|
||||||
|
<form class="border rounded p-4">
|
||||||
|
<div x-data="collapse" x-init='initDatePicker(
|
||||||
|
"<f:format.raw>{filterOptions.dateFrom -> f:format.date(format: 'Y-m-d')}</f:format.raw>",
|
||||||
|
"<f:format.raw>{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="form-control cursor-pointer"
|
||||||
|
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 x-data="collapse">
|
||||||
|
<label x-bind="trigger" class="cursor-pointer">
|
||||||
|
Reiseziel
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.destinations}" as="destination">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleDestinationOrConcept(<f:format.raw>{destination.country.uid}, '{destination.country.label}', 'country'</f:format.raw>)"
|
||||||
|
class="{f:if(condition: '{filterSettings.destinationType} == "country" && {filterSettings.destinationUid} == {destination.country.uid}', then: 'underline')}">
|
||||||
|
{destination.country.label}
|
||||||
|
</a>
|
||||||
|
<f:if condition="{destination.regions -> f:count()}">
|
||||||
|
<ul>
|
||||||
|
<f:for each="{destination.regions}" as="region">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleDestinationOrConcept(<f:format.raw>{region.uid}, '{region.label}', 'region'</f:format.raw>)"
|
||||||
|
class="{f:if(condition: '{filterSettings.destinationType} == "region" && {filterSettings.destinationUid} == {region.uid}', then: 'underline')}">
|
||||||
|
{region.label}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</f:if>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Reisekonzepte
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.concepts}" as="concept">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleDestinationOrConcept(<f:format.raw>{concept.uid}, '{concept.name}', 'concept'</f:format.raw>)"
|
||||||
|
class="{f:if(condition: '{filterSettings.destinationType} == "concept" && {filterSettings.destinationUid} == {concept.uid}', then: 'underline')}">
|
||||||
|
{concept.name}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Preis
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.priceRanges}" as="range">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleFilterValue('priceRange', <f:format.raw>{range.uid}</f:format.raw>)"
|
||||||
|
class="{f:if(condition: '{filterSettings.priceRange} == {range.uid}', then: 'underline')}">
|
||||||
|
{ep:priceRange(min: range.min, max: range.max)}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Personen
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="h-48 overflow-y-scroll border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.pax}" as="option">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleFilterValue('pax', <f:format.raw>{option}</f:format.raw>)">
|
||||||
|
{option}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
<li><a href="{f:uri.typolink(parameter: settings.groupsPageUid)}">> 20</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<f:variable name="hotelTypes" value="{
|
||||||
|
1: 'Ferienwohnung',
|
||||||
|
2: 'Sportclub',
|
||||||
|
3: 'Appartment',
|
||||||
|
4: 'Gästehaus',
|
||||||
|
5: 'Pension'
|
||||||
|
}"/>
|
||||||
|
<div x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Unterkunft
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.hotelTypes}" as="type">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleFilterValue('hotelTypes', <f:format.raw>{type}</f:format.raw>, true)">
|
||||||
|
{hotelTypes.{type}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Verpflegung
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.boardTypes}" as="type">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleFilterValue('boardTypes', <f:format.raw>{type.uid}</f:format.raw>, true)">
|
||||||
|
{type.label}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</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 x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Zimmerarten/Apart.
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<f:for each="{filterOptions.roomTypes}" as="type">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleFilterValue('roomTypes', <f:format.raw>{type}</f:format.raw>, true)">
|
||||||
|
{roomTypes.{type}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<f:if condition="{filterOptions.busAvailable}">
|
||||||
|
<div x-data="collapse">
|
||||||
|
<label x-bind="trigger">
|
||||||
|
Anreise
|
||||||
|
</label>
|
||||||
|
<div x-bind="container" x-transition>
|
||||||
|
<ul class="border rounded shadow-md mb-0">
|
||||||
|
<li>
|
||||||
|
<a href="#"
|
||||||
|
x-on:click.prevent="toggleFilterValue('bus', true)"
|
||||||
|
class="{f:if(condition: filterSettings.bus, then: 'underline')}">
|
||||||
|
Busanreise
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</html>
|
||||||
+142
@@ -0,0 +1,142 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
||||||
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<a href="#" class="teaserbox-watchlist" x-data="watchlistToggle('{item.key}')" x-bind="trigger">
|
||||||
|
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
|
||||||
|
<i class="fa fa-plus-circle" x-bind:class="icon"></i>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
||||||
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
|
||||||
|
|
||||||
|
<f:if condition="{watchlist -> f:count()} == 0">
|
||||||
|
<f:then>
|
||||||
|
<div class="alert alert-info">
|
||||||
|
Deine Merkliste ist aktuell leer...
|
||||||
|
</div>
|
||||||
|
</f:then>
|
||||||
|
<f:else>
|
||||||
|
<f:for each="{watchlist}" 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>
|
||||||
|
<a href="#" class="teaserbox-watchlist" x-data="watchlistToggle('{item.key}')" x-bind="trigger">
|
||||||
|
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
|
||||||
|
<i class="fa fa-plus-circle" x-bind:class="icon"></i>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
</f:if>
|
</f:if>
|
||||||
<f:if condition="{product.faqs}">
|
<f:if condition="{product.faqs}">
|
||||||
<button class="button button--light button--sidebar"
|
<button class="button button--light button--sidebar"
|
||||||
x-on:click.prevent="scrollTo('#faq')">FAQ</button>
|
x-data="scrollTo('faq')">FAQ</button>
|
||||||
</f:if>
|
</f:if>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
|||||||
@@ -1,305 +0,0 @@
|
|||||||
<html data-namespace-typo3-fluid="true" lang="en"
|
|
||||||
xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
|
||||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
|
||||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
|
|
||||||
|
|
||||||
<f:layout name="Default"/>
|
|
||||||
|
|
||||||
<f:section name="Main">
|
|
||||||
<product-detail
|
|
||||||
:uris='{
|
|
||||||
dates: "<f:format.raw>{ep:uri.ajax(action: 'dates', controller: 'AjaxDate', arguments: '{product: product, hotel: hotel}', format: 'json', pageUid: settings.defaultAjaxUid)}</f:format.raw>",
|
|
||||||
contingents: "<f:format.raw>{ep:uri.ajax(action: 'list', controller: 'AjaxContingent', format: 'json', pageUid: settings.defaultAjaxUid)}</f:format.raw>",
|
|
||||||
rooms: "<f:format.raw>{ep:uri.ajax(action: 'rooms', controller: 'AjaxContingent', format: 'json', pageUid: settings.defaultAjaxUid)}</f:format.raw>",
|
|
||||||
pricetable: "<f:format.raw>{ep:uri.ajax(action: 'pricetable', controller: 'AjaxTable', arguments: '{product: product, hotel: hotel}', format: 'json', pageUid: settings.defaultAjaxUid)}</f:format.raw>"
|
|
||||||
}'
|
|
||||||
argument-prefix='<ep:argumentPrefix pluginName="Ajax" />'
|
|
||||||
:hotel-first="{f:if(condition: settings.hotelOnTop, then: 'true', else: 'false')}"
|
|
||||||
:bus-pro-id="{product.busProId -> f:format.raw()}"
|
|
||||||
name-internal="{product.nameInternal -> f:format.raw()}"
|
|
||||||
:daytrip="{product.daytrip -> v:variable.convert(type: 'int')}"
|
|
||||||
date-from="{dateFrom}"
|
|
||||||
date-to="{dateTo}"
|
|
||||||
inline-template>
|
|
||||||
<article>
|
|
||||||
<f:render partial="Product/HeaderDetail" arguments="{_all}"/>
|
|
||||||
<div class="container" id="detail">
|
|
||||||
<div class="product-detail-wrapper">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<f:render partial="Header/Header" arguments="{layout: 8, subheader: '{product.region.name} / {product.name}', header: product.headline}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4 col-md-push-8">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<f:if condition="{settings.hotelOnTop}">
|
|
||||||
<f:then>
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'hotel'}"
|
|
||||||
@click.prevent="showHtml('hotel')">Unterkunft</button>
|
|
||||||
</f:then>
|
|
||||||
<f:else>
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'dates'}"
|
|
||||||
@click.prevent="loadDatesView()">Termine/Preise</button>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-6 col-md-12">
|
|
||||||
<f:if condition="{settings.hotelOnTop}">
|
|
||||||
<f:then>
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'dates'}"
|
|
||||||
@click.prevent="loadDatesView()">Termine/Preise</button>
|
|
||||||
</f:then>
|
|
||||||
<f:else>
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'hotel'}"
|
|
||||||
@click.prevent="showHtml('hotel')">Unterkunft</button>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'region'}"
|
|
||||||
@click.prevent="showHtml('region')">Gebiet</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-6 col-md-12">
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'city'}"
|
|
||||||
@click.prevent="showHtml('city')">Ort</button>
|
|
||||||
<f:if condition="{product.journey}">
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
:class="{ 'button--active': activeSection === 'journey'}"
|
|
||||||
@click.prevent="showHtml('journey')">Anreise</button>
|
|
||||||
</f:if>
|
|
||||||
<f:if condition="{product.faqs}">
|
|
||||||
<button class="button button--light button--sidebar"
|
|
||||||
@click.prevent="scrollTo('#faq')">FAQ</button>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<p>
|
|
||||||
<a href="#" x-data="watchlistToggle" x-bind="trigger" data-uid="{hotel.uid}:{product.uid}">
|
|
||||||
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
|
|
||||||
<i class="fa" x-bind:class="icon"></i>
|
|
||||||
</span>
|
|
||||||
<span x-text="label"></span>
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="{f:uri.typolink(parameter: settings.coronaUpdatesPageUid)}"
|
|
||||||
class="block w-full py-2 border-2 border-red-500 rounded text-red-500 text-center uppercase hover:bg-red-500 hover:text-white transition-colors duration-200 ease-in-out"
|
|
||||||
title="Corona Updates">
|
|
||||||
Corona Updates
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="hidden-xs">
|
|
||||||
<f:render section="Calendar" arguments="{_all}"/>
|
|
||||||
<f:render partial="Facts" arguments="{facts: product.facts}"/>
|
|
||||||
<f:if condition="{product.video}">
|
|
||||||
<div class="video">
|
|
||||||
<iframe class="video__frame" width="560" height="315" frameborder="0" allowfullscreen
|
|
||||||
src="{ep:uri.video(value: product.video)}"></iframe>
|
|
||||||
</div>
|
|
||||||
</f:if>
|
|
||||||
<div class="ep-sidebar ep-snow">
|
|
||||||
<p><strong>Lage</strong></p>
|
|
||||||
<div>
|
|
||||||
<div class="osm-map"
|
|
||||||
x-data="osmMap"
|
|
||||||
data-lat="{hotel.latitude}"
|
|
||||||
data-lng="{hotel.longitude}"
|
|
||||||
data-link="{f:uri.typolink(parameter: hotel.externalLink)}"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<f:render partial="Region/Webcam" arguments="{region: product.region}"/>
|
|
||||||
<f:render partial="RegionMaps" arguments="{region: product.region}"/>
|
|
||||||
<f:render partial="RegionAward" arguments="{region: product.region}"/>
|
|
||||||
<f:if condition="{product.banner}">
|
|
||||||
<div class="ep-sidebar ep-snow">
|
|
||||||
<f:link.typolink parameter="{product.banner.originalResource.link}"
|
|
||||||
title="{product.banner.title}">
|
|
||||||
<f:image src="{product.banner.uid}" treatIdAsReference="1"
|
|
||||||
class="scale" alt="{product.banner.alternative}"/>
|
|
||||||
</f:link.typolink>
|
|
||||||
</div>
|
|
||||||
</f:if>
|
|
||||||
<f:render partial="Rating" arguments="{product: product, targetPageUid: settings.ratingPageUid, label: settings.ratingWidgetLabel}"/>
|
|
||||||
<f:render partial="Snowreport" arguments="{snowreport: product.region.snowreport}"/>
|
|
||||||
<f:render partial="Officetip" arguments="{officetip: product.officetip}"/>
|
|
||||||
<f:if condition="{settings.hideTeamer}">
|
|
||||||
<f:else>
|
|
||||||
<f:render partial="Teamer" arguments="{teamer: hotel.teamer}"/>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="main" class="col-md-8 col-md-pull-4">
|
|
||||||
<!-- Dates -->
|
|
||||||
<div v-cloak v-show="!loading && datesShow">
|
|
||||||
<f:if condition="{isProductWithExcludedConcept}">
|
|
||||||
<f:if condition="{product.region.season} == 'w'">
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<p><strong>Gruppenrabatt bis zu 100€ möglich</strong></p>
|
|
||||||
<p>Für Gruppen bis 15 Personen könnt ihr <f:link.typolink parameter="31">hier direkt buchen</f:link.typolink>.
|
|
||||||
Für Gruppen ab 16 Personen erstellen wir euch ein konkretes Angebot zu günstigen
|
|
||||||
Gruppenkonditionen zu dieser Reise. Anfrage via Tel. 0221 - 272 276 18 oder mit einer
|
|
||||||
<f:link.typolink parameter="{settings.defaultContactFormPageUid}">Kurzanfrage</f:link.typolink>!</p>
|
|
||||||
</div>
|
|
||||||
</f:if>
|
|
||||||
</f:if>
|
|
||||||
<f:if condition="{product.daytrip}">
|
|
||||||
<f:then>
|
|
||||||
<date-select
|
|
||||||
hotel-name="{hotel.name}"
|
|
||||||
:hotel-uid="{hotel.uid}"
|
|
||||||
:product-uid="{product.uid}"
|
|
||||||
:contingent-endpoint-uri="uris.contingents"
|
|
||||||
:rooms-endpoint-uri="uris.rooms"
|
|
||||||
:argument-prefix="argumentPrefix"
|
|
||||||
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
|
||||||
></date-select>
|
|
||||||
</f:then>
|
|
||||||
<f:else>
|
|
||||||
<template v-if="available">
|
|
||||||
<dates-table :dates-rows="datesRows"
|
|
||||||
:alt-product-link="altProductLink"
|
|
||||||
:alt-label="altLabel"
|
|
||||||
hotel-name="{hotel.name}"
|
|
||||||
:bookable="bookable"
|
|
||||||
travel-alert-url="{f:uri.typolink(parameter: settings.travelAlertPageUid)}"
|
|
||||||
></dates-table>
|
|
||||||
</template>
|
|
||||||
<f:if condition="{isProductWithNoInfoConcept}">
|
|
||||||
<f:else>
|
|
||||||
<template v-else>
|
|
||||||
<f:render partial="NotBookable" arguments="{_all}"/>
|
|
||||||
</template>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
<f:render partial="Product/Details" arguments="{_all}"/>
|
|
||||||
</div>
|
|
||||||
<!-- /Dates -->
|
|
||||||
<!-- Prices -->
|
|
||||||
<div v-cloak v-show="!loading && priceTableShow">
|
|
||||||
<price-table :price-table-rows="priceTableRows"
|
|
||||||
:services-included="servicesIncluded"
|
|
||||||
:date-label="dateLabel"
|
|
||||||
:single-date="singleDate"
|
|
||||||
travel-alert-url="{f:uri.typolink(parameter: settings.travelAlertPageUid)}"
|
|
||||||
></price-table>
|
|
||||||
<f:alias map="{currentPageUid: 1}">
|
|
||||||
<f:render partial="Product/Details" arguments="{_all}"/>
|
|
||||||
</f:alias>
|
|
||||||
</div>
|
|
||||||
<!-- /Prices -->
|
|
||||||
<!-- Hotel -->
|
|
||||||
<div v-show="detailShow && activeSection === 'hotel'">
|
|
||||||
<f:render partial="Hotel/Details" arguments="{hotel: hotel, bars: 1, showNonBookableHint: 0}"/>
|
|
||||||
</div>
|
|
||||||
<!-- /Hotel -->
|
|
||||||
<!-- City -->
|
|
||||||
<div v-show="detailShow && activeSection === 'city'">
|
|
||||||
<f:render partial="City/Details" arguments="{city: product.city, bars: 1}"/>
|
|
||||||
</div>
|
|
||||||
<!-- /City -->
|
|
||||||
<!-- Region -->
|
|
||||||
<div v-show="detailShow && activeSection === 'region'">
|
|
||||||
<f:render partial="Region/Details" arguments="{region: product.region, bars: 1}"/>
|
|
||||||
</div>
|
|
||||||
<!-- /Region -->
|
|
||||||
<!-- Journey -->
|
|
||||||
<div v-show="detailShow && activeSection === 'journey'">
|
|
||||||
<f:render partial="Journey/Details" arguments="{journey: product.journey, bars: 1}"/>
|
|
||||||
</div>
|
|
||||||
<!-- /Journey -->
|
|
||||||
<!-- Loader -->
|
|
||||||
<div v-show="loading" class="loader"><p>Loading... <f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/></p></div>
|
|
||||||
<!-- /Loader -->
|
|
||||||
<div class="hidden-md hidden-lg">
|
|
||||||
<f:render section="Calendar" arguments="{_all}"/>
|
|
||||||
<f:render partial="Facts" arguments="{facts: product.facts}"/>
|
|
||||||
<f:if condition="{product.video}">
|
|
||||||
<div class="video">
|
|
||||||
<iframe class="video__frame" width="560" height="315" frameborder="0" allowfullscreen
|
|
||||||
src="{ep:uri.video(value: product.video)}"></iframe>
|
|
||||||
</div>
|
|
||||||
</f:if>
|
|
||||||
<div class="ep-sidebar ep-snow">
|
|
||||||
<p><strong>Lage</strong></p>
|
|
||||||
<div>
|
|
||||||
<div class="osm-map"
|
|
||||||
x-data="osmMap"
|
|
||||||
data-lat="{hotel.latitude}"
|
|
||||||
data-lng="{hotel.longitude}"
|
|
||||||
data-link="{f:uri.typolink(parameter: hotel.externalLink)}"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<f:render partial="Region/Webcam" arguments="{region: product.region}"/>
|
|
||||||
<f:render partial="RegionMaps" arguments="{region: product.region}"/>
|
|
||||||
<f:render partial="RegionAward" arguments="{region: product.region}"/>
|
|
||||||
<f:if condition="{product.banner}">
|
|
||||||
<div class="ep-sidebar ep-snow">
|
|
||||||
<f:link.typolink parameter="{product.banner.originalResource.link}"
|
|
||||||
title="{product.banner.title}">
|
|
||||||
<f:image src="{product.banner.uid}" treatIdAsReference="1"
|
|
||||||
class="scale" alt="{product.banner.alternative}"/>
|
|
||||||
</f:link.typolink>
|
|
||||||
</div>
|
|
||||||
</f:if>
|
|
||||||
<f:render partial="Rating" arguments="{product: product, targetPageUid: settings.ratingPageUid, label: settings.ratingWidgetLabel}"/>
|
|
||||||
<f:render partial="Snowreport" arguments="{snowreport: product.region.snowreport}"/>
|
|
||||||
<f:render partial="Officetip" arguments="{officetip: product.officetip}"/>
|
|
||||||
<f:render partial="Teamer" arguments="{teamer: hotel.teamer}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</product-detail>
|
|
||||||
<div x-data="fbpixel('{ "content_ids": [ {product.busProId -> f:format.raw()} ], "content_name": "{product.nameInternal -> f:format.raw()}", "content_type": "product" }')"></div>
|
|
||||||
<f:render partial="Faq" arguments="{faqs: product.faqs, settings: settings}"/>
|
|
||||||
</f:section>
|
|
||||||
|
|
||||||
<f:section name="Calendar">
|
|
||||||
<f:if condition="{product.calendarHotel}">
|
|
||||||
<f:if condition="{hotel.groupsPriceConfigs}">
|
|
||||||
<a class="button button--full"
|
|
||||||
data-glightbox
|
|
||||||
href="{f:uri.action(action: 'index', controller: 'GroupsPrice', arguments: '{hotel: hotel}', pageUid: settings.groupsPricePopupPageUid)}">
|
|
||||||
Preisberechnung
|
|
||||||
</a>
|
|
||||||
</f:if>
|
|
||||||
<div class="ep-sidebar ep-facts">
|
|
||||||
<p><strong>Belegungskalender</strong></p>
|
|
||||||
<calendar
|
|
||||||
uri="{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: product.calendarHotel}', format: 'html')}"
|
|
||||||
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
|
||||||
hotel-uid="{product.calendarHotel.uid}"
|
|
||||||
hotel-name="{product.calendarHotel.name}"
|
|
||||||
:months="1"
|
|
||||||
:show-header="false"
|
|
||||||
:step="1"
|
|
||||||
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax', extensionName: 'epproducts')}"
|
|
||||||
></calendar>
|
|
||||||
</div>
|
|
||||||
<f:if condition="{hotel.groupsPriceConfigs}">
|
|
||||||
<f:else>
|
|
||||||
<f:link.typolink class="button button--full" parameter="{settings.groupsContactFormPageUid}" additionalParams="&ref={currentPageUid}">
|
|
||||||
Direkt zum Anfrageformular
|
|
||||||
</f:link.typolink>
|
|
||||||
</f:else>
|
|
||||||
</f:if>
|
|
||||||
</f:if>
|
|
||||||
</f:section>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -5,9 +5,6 @@
|
|||||||
<f:layout name="Default"/>
|
<f:layout name="Default"/>
|
||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<hotel-list
|
|
||||||
referring-page-url="{f:uri.typolink(parameter: currentPageUid)}"
|
|
||||||
inline-template>
|
|
||||||
<article>
|
<article>
|
||||||
<f:render partial="Product/HeaderDetail" arguments="{_all}"/>
|
<f:render partial="Product/HeaderDetail" arguments="{_all}"/>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -52,7 +49,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</hotel-list>
|
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -6,13 +6,12 @@
|
|||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<div id="searchbar" x-data='searchBar({
|
<div id="searchbar" x-data='searchBar({
|
||||||
optionsUri: "<ep:uri.ajax controller="AjaxSearchbar" action="options" pageUid="{settings.defaultAjaxUid}" />",
|
uri: "<ep:uri.ajax controller="AjaxSearchbar" action="update" pageUid="{settings.defaultAjaxUid}" />",
|
||||||
resetUri: "<ep:uri.ajax controller="AjaxSearchbar" action="reset" pageUid="{settings.defaultAjaxUid}" />",
|
|
||||||
initialSearchParams: {searchParams -> f:format.json() -> f:format.raw()},
|
initialSearchParams: {searchParams -> f:format.json() -> f:format.raw()},
|
||||||
initialFilterOptions: {filterOptions -> f:format.json() -> f:format.raw()},
|
initialFilterOptions: {filterOptions -> f:format.json() -> f:format.raw()},
|
||||||
datePresets: {settings.datePickerPresets -> f:format.json() -> f:format.raw()}
|
datePresets: {settings.datePickerPresets -> f:format.json() -> f:format.raw()}
|
||||||
})'>
|
})'>
|
||||||
<div class="container searchbar{f:if(condition: fixed, then: ' affix')}"{f:if(condition: fixed, else: ' x-data="sticky(650)" x-bind:class="sticky ? \'affix\': \'\'"')}>
|
<div class="container searchbar{f:if(condition: fixed, then: ' affix')}"{f:if(condition: fixed, else: ' x-data="sticky(650)" x-bind:class="sticky && \'affix\'"')}">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<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"
|
||||||
@@ -36,6 +35,7 @@
|
|||||||
<input type="text"
|
<input type="text"
|
||||||
class="form-control cursor-pointer"
|
class="form-control cursor-pointer"
|
||||||
placeholder="von... bis"
|
placeholder="von... bis"
|
||||||
|
x-bind:class="loading && 'cursor-not-allowed'"
|
||||||
x-bind:value="dateRangeLabel"
|
x-bind:value="dateRangeLabel"
|
||||||
x-on:click.prevent="show = show === 'dateRange' ? null : 'dateRange'"/>
|
x-on:click.prevent="show = show === 'dateRange' ? null : 'dateRange'"/>
|
||||||
<div class="absolute top-100 left-0 bg-white p-4 shadow-md" x-show="show === 'dateRange'" x-transition x-cloak>
|
<div class="absolute top-100 left-0 bg-white p-4 shadow-md" x-show="show === 'dateRange'" x-transition x-cloak>
|
||||||
@@ -70,6 +70,7 @@
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text"
|
<input type="text"
|
||||||
class="form-control cursor-pointer"
|
class="form-control cursor-pointer"
|
||||||
|
x-bind:class="loading && 'cursor-not-allowed'"
|
||||||
x-bind:value="searchParams.pax"
|
x-bind:value="searchParams.pax"
|
||||||
x-on:click.prevent="show = show === 'pax' ? null : 'pax'"/>
|
x-on:click.prevent="show = show === 'pax' ? null : 'pax'"/>
|
||||||
<div class="absolute top-100 left-0 bg-white p-4 shadow-md w-full h-48 overflow-y-scroll" x-show="show === 'pax'" x-transition x-cloak>
|
<div class="absolute top-100 left-0 bg-white p-4 shadow-md w-full h-48 overflow-y-scroll" x-show="show === 'pax'" x-transition x-cloak>
|
||||||
@@ -93,6 +94,7 @@
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text"
|
<input type="text"
|
||||||
class="form-control cursor-pointer"
|
class="form-control cursor-pointer"
|
||||||
|
x-bind:class="loading && 'cursor-not-allowed'"
|
||||||
x-bind:value="destinationName"
|
x-bind:value="destinationName"
|
||||||
x-on:click.prevent="show = show === 'destination' ? null : 'destination'"/>
|
x-on:click.prevent="show = show === 'destination' ? null : 'destination'"/>
|
||||||
<div class="absolute top-100 left-0 bg-white p-4 shadow-md min-w-full h-48 overflow-y-scroll" x-show="show === 'destination'" x-transition x-cloak>
|
<div class="absolute top-100 left-0 bg-white p-4 shadow-md min-w-full h-48 overflow-y-scroll" x-show="show === 'destination'" x-transition x-cloak>
|
||||||
@@ -134,7 +136,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template x-if="destinationSelected || conceptSelected">
|
<template x-if="destinationSelected || conceptSelected">
|
||||||
<button x-on:click.prevent="resetDestinationSelect()">
|
<button x-on:click.prevent="resetDestination()">
|
||||||
<i class="fa fa-trash-o"></i>
|
<i class="fa fa-trash-o"></i>
|
||||||
zurücksetzen
|
zurücksetzen
|
||||||
</button>
|
</button>
|
||||||
@@ -151,18 +153,19 @@
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<input type="text"
|
<input type="text"
|
||||||
class="form-control cursor-pointer"
|
class="form-control cursor-pointer"
|
||||||
|
x-bind:class="loading && 'cursor-not-allowed'"
|
||||||
x-bind:value="priceRangeLabel()"
|
x-bind:value="priceRangeLabel()"
|
||||||
x-on:click.prevent="show = show === 'priceRange' ? null : 'priceRange'"/>
|
x-on:click.prevent="show = show === 'priceRange' ? null : 'priceRange'"/>
|
||||||
<div class="absolute top-100 left-0 bg-white p-4 shadow-md w-full h-48 overflow-y-scroll" x-show="show === 'priceRange'" x-transition x-cloak>
|
<div class="absolute top-100 left-0 bg-white p-4 shadow-md w-full h-48 overflow-y-scroll" x-show="show === 'priceRange'" x-transition x-cloak>
|
||||||
<ul class="m-0 p-0">
|
<ul class="m-0 p-0">
|
||||||
<li>
|
<li>
|
||||||
<a href="#" x-on:click.prevent="resetPriceRange()">beliebig</a>
|
<a href="#" x-on:click.prevent="updateSearchParam('priceRange', null)">beliebig</a>
|
||||||
</li>
|
</li>
|
||||||
<template x-for="(range, index) in filterOptions.priceRanges">
|
<template x-for="(range, index) in filterOptions.priceRanges">
|
||||||
<li>
|
<li>
|
||||||
<a href="#"
|
<a href="#"
|
||||||
x-on:click.prevent="updateSearchParam('priceRange', index)"
|
x-on:click.prevent="updateSearchParam('priceRange', index)"
|
||||||
x-text="formatPriceRange(range)"></a>
|
x-text="priceRangeFormatted(range)"></a>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -173,8 +176,12 @@
|
|||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label> </label>
|
<label> </label>
|
||||||
<button type="submit" class="btn btn-warning">Suchen <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span></button>
|
<button type="submit" class="btn btn-warning" x-bind:disabled="loading">
|
||||||
<button type="submit" class="searchbar__link">Detailsuche</button>
|
Suchen <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="searchbar__link" x-bind:disabled="loading">
|
||||||
|
Detailsuche
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,39 +5,33 @@
|
|||||||
<f:layout name="Default"/>
|
<f:layout name="Default"/>
|
||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
</f:section>
|
<div id="searchbox" class="searchbox hidden-lg" x-show="$store.show.searchBox" x-transition x-cloak x-data='searchBar({
|
||||||
<f:section name="Main__">
|
uri: "<ep:uri.ajax controller="AjaxSearchbar" action="update" pageUid="{settings.defaultAjaxUid}" />",
|
||||||
<div id="searchbox" class="searchbox hidden-lg" x-data x-show="$store.show.searchBox" x-transition x-cloak>
|
initialSearchParams: {searchParams -> f:format.json() -> f:format.raw()},
|
||||||
<search-box
|
initialFilterOptions: {filterOptions -> f:format.json() -> f:format.raw()},
|
||||||
options-uri='<ep:uri.ajax controller="AjaxSearchbar" action="options" pageUid="{settings.defaultAjaxUid}" />'
|
datePresets: {settings.datePickerPresets -> f:format.json() -> f:format.raw()}
|
||||||
reset-uri='<ep:uri.ajax controller="AjaxSearchbar" action="reset" pageUid="{settings.defaultAjaxUid}" />'
|
})'>
|
||||||
argument-prefix='<ep:argumentPrefix pluginName="ajax" />'
|
|
||||||
:initial-search-params='{searchParams -> f:format.json() -> f:format.raw()}'
|
|
||||||
:initial-filter-options='{filterOptions -> f:format.json() -> f:format.raw()}'
|
|
||||||
:date-presets='{settings.datePickerPresets -> f:format.json() -> f:format.raw()}'
|
|
||||||
inline-template>
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<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}" class="form-horizontal">
|
pageUid="{settings.defaultSearchPageUid}" class="form-horizontal">
|
||||||
<f:form.hidden property="destinationUid" additionalAttributes="{v-model: 'searchParams.destinationUid', number: 'number'}"/>
|
<f:form.hidden property="destinationUid" additionalAttributes="{x-model: 'searchParams.destinationUid'}"/>
|
||||||
<f:form.hidden property="destinationType" additionalAttributes="{v-model: 'searchParams.destinationType'}"/>
|
<f:form.hidden property="destinationType" additionalAttributes="{x-model: 'searchParams.destinationType'}"/>
|
||||||
<f:form.hidden property="dateFrom" value="" additionalAttributes="{v-model: 'searchParams.dateFrom'}"/>
|
<f:form.hidden property="dateFrom" value="" additionalAttributes="{x-model: 'searchParams.dateFrom'}"/>
|
||||||
<f:form.hidden property="dateTo" value="" additionalAttributes="{v-model: 'searchParams.dateTo'}"/>
|
<f:form.hidden property="dateTo" value="" additionalAttributes="{x-model: 'searchParams.dateTo'}"/>
|
||||||
<f:form.hidden property="nights" additionalAttributes="{v-model: 'searchParams.nights', number: 'number'}"/>
|
<f:form.hidden property="nights" additionalAttributes="{x-model: 'searchParams.nights'}"/>
|
||||||
<f:form.hidden property="pax" additionalAttributes="{v-model: 'searchParams.pax', number: 'number'}"/>
|
<f:form.hidden property="pax" additionalAttributes="{x-model: 'searchParams.pax'}"/>
|
||||||
<f:form.hidden property="conceptUid" additionalAttributes="{v-model: 'searchParams.conceptUid', number: 'number'}"/>
|
<f:form.hidden property="conceptUid" additionalAttributes="{x-model: 'searchParams.conceptUid'}"/>
|
||||||
<f:form.hidden property="pageUid" additionalAttributes="{v-model: 'searchParams.pageUid', number: 'number'}"/>
|
<f:form.hidden property="pageUid" additionalAttributes="{x-model: 'searchParams.pageUid'}"/>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Früheste Anreise</label>
|
<label>Früheste Anreise</label>
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
@change="updateOptions"
|
x-model="searchParams.dateFrom"
|
||||||
v-model="searchParams.dateFrom"
|
x-bind:min="filterOptions.dateFrom"
|
||||||
:min="filterOptions.dateFrom"
|
x-bind:max="filterOptions.dateTo"
|
||||||
:max="filterOptions.dateTo"
|
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,10 +39,9 @@
|
|||||||
<label>Späteste Abreise</label>
|
<label>Späteste Abreise</label>
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
@change="updateOptions"
|
x-model="searchParams.dateTo"
|
||||||
v-model="searchParams.dateTo"
|
x-bind:min="filterOptions.dateFrom"
|
||||||
:min="filterOptions.dateFrom"
|
x-bind:max="filterOptions.dateTo"
|
||||||
:max="filterOptions.dateTo"
|
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,10 +53,9 @@
|
|||||||
<label>Personen</label>
|
<label>Personen</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
@change="updateOptions"
|
|
||||||
min="1"
|
min="1"
|
||||||
max="20"
|
max="20"
|
||||||
v-model="searchParams.pax"
|
x-model="searchParams.pax"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,23 +63,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<destination-select
|
|
||||||
class="form-group"
|
|
||||||
@selected="updateDestination"
|
|
||||||
@reset="resetDestination"
|
|
||||||
:destination-options="filterOptions.destinations"
|
|
||||||
:concept-options="filterOptions.concepts"
|
|
||||||
></destination-select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<price-range-select
|
|
||||||
class="form-group"
|
|
||||||
@selected="updatePriceRange"
|
|
||||||
:range-options="filterOptions.priceRanges"
|
|
||||||
:range="searchParams.priceRange"
|
|
||||||
></price-range-select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -100,7 +79,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</f:form>
|
</f:form>
|
||||||
</div>
|
</div>
|
||||||
</search-box>
|
|
||||||
</div>
|
</div>
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
|
|||||||
+38
-289
@@ -7,13 +7,6 @@
|
|||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<div id="search">
|
<div id="search">
|
||||||
<search-result
|
|
||||||
results-uri="{ep:uri.ajax(action: 'searchresult', controller: 'AjaxSearch', pageUid: settings.defaultAjaxUid, format: 'json')}"
|
|
||||||
:initial-filter-settings='<v:format.json.encode>{filterSettings}</v:format.json.encode>'
|
|
||||||
referring-page-url="{f:uri.typolink(parameter: referringPageUid)}"
|
|
||||||
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax')}"
|
|
||||||
:date-presets='{settings.datePickerPresets -> v:format.json.encode()}'
|
|
||||||
inline-template>
|
|
||||||
<div class="searchresult-wrapper">
|
<div class="searchresult-wrapper">
|
||||||
<div class="pagehead pagehead--searchresult">
|
<div class="pagehead pagehead--searchresult">
|
||||||
<div class="pagehead__image"
|
<div class="pagehead__image"
|
||||||
@@ -21,301 +14,57 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3" x-data="collapse(false, 991)">
|
<div class="col-md-3 relative" x-data="collapse(false, 991)">
|
||||||
<p class="lg:hidden">
|
<p class="lg:hidden">
|
||||||
<button class="button button--full button--small" role="button" x-bind="trigger">
|
<button class="button button--full button--small" role="button" x-bind="trigger">
|
||||||
<i class="fa fa-toggle-on"></i> Filter ein-/ausblenden
|
<i class="fa fa-toggle-on"></i> Filter ein-/ausblenden
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
<div id="filterpanel" class="lg:block" v-cloak x-bind="container" x-transition x-cloak>
|
<f:spaceless>
|
||||||
<concept-buttons :concepts="filterOptions.concepts"></concept-buttons>
|
<div class="lg:block"
|
||||||
|
x-bind="container"
|
||||||
|
x-transition
|
||||||
|
x-cloak
|
||||||
|
x-data='filterPanel({
|
||||||
|
<f:format.raw>
|
||||||
|
uri: "{ep:uri.ajax(controller: 'AjaxFilterpanel', action: 'panel', pageUid: settings.defaultAjaxUid, format: 'html')}",
|
||||||
|
initialFilterSettings: {filterSettings -> f:format.json()},
|
||||||
|
datePresets: {settings.datePickerPresets -> f:format.json()}
|
||||||
|
</f:format.raw>
|
||||||
|
})'>
|
||||||
<h3>Filter</h3>
|
<h3>Filter</h3>
|
||||||
<a v-if="filterCount > 0"
|
<button class="button button--sidebar button--small"
|
||||||
class="button button--sidebar button--small"
|
x-show="filterCount > 0"
|
||||||
href="#"
|
x-cloak
|
||||||
@click.prevent="resetFilterSettings">Filter zurücksetzen</a>
|
x-on:click.prevent="reset">
|
||||||
<form class="border">
|
Filter zurücksetzen
|
||||||
<div class="panel-group" id="filteroptions" role="tablist" aria-multiselectable="true">
|
</button>
|
||||||
<div class="panel panel-default">
|
<div x-ref="panel"></div>
|
||||||
<div class="panel-heading" role="tab" id="headingPeriod">
|
<div x-show="loading" class="absolute z-20 inset-0 w-full h-fill bg-overlay-white">
|
||||||
<h4 class="panel-title">
|
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading" class="absolute top-1/2 left-1/2 -translate-xy-1/2"/>
|
||||||
<a role="button" data-toggle="collapse" href="#collapsePeriod"
|
|
||||||
aria-expanded="true" aria-controls="collapsePeriod"
|
|
||||||
:class="{ collapsed: !filterSettings.dateFrom && !filterSettings.dateTo }">
|
|
||||||
Reisezeitraum
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="collapsePeriod" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.dateFrom || filterSettings.dateTo }"
|
|
||||||
aria-labelledby="headingPeriod">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group hidden-xs hidden-sm">
|
|
||||||
<daterange-select
|
|
||||||
class="form-control"
|
|
||||||
:presets="datePresets"
|
|
||||||
:from="filterSettings.dateFrom"
|
|
||||||
:to="filterSettings.dateTo"
|
|
||||||
:min-date="filterOptions.dateFrom"
|
|
||||||
:max-date="filterOptions.dateTo"
|
|
||||||
:show-label="false"
|
|
||||||
@selected="updateDateRange"
|
|
||||||
></daterange-select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group hidden-md hidden-lg">
|
</f:spaceless>
|
||||||
<label>Früheste Anreise</label>
|
</div>
|
||||||
<input
|
<f:spaceless>
|
||||||
type="date"
|
<div class="col-md-9 relative"
|
||||||
@change="updateDateSelectMobile"
|
x-data='searchResult({
|
||||||
v-model="filterSettings.dateFrom"
|
<f:format.raw>
|
||||||
class="form-control"
|
uri: "{ep:uri.ajax(controller: 'AjaxSearch', action: 'searchresult', pageUid: settings.defaultAjaxUid, format: 'html')}",
|
||||||
|
initialFilterSettings: {filterSettings -> f:format.json()}
|
||||||
|
</f:format.raw>
|
||||||
|
})'
|
||||||
|
x-on:filter-settings-updated.window="onFilterSettingsUpdated($event)"
|
||||||
>
|
>
|
||||||
|
<div x-ref="results"></div>
|
||||||
|
<div x-show="loading" class="absolute z-20 inset-0 w-full h-fill bg-overlay-white">
|
||||||
|
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading" class="absolute top-1/2 left-1/2 -translate-xy-1/2"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group hidden-md hidden-lg">
|
</div>
|
||||||
<label>Späteste Abreise</label>
|
</f:spaceless>
|
||||||
<input
|
|
||||||
type="date"
|
|
||||||
@change="updateDateSelectMobile"
|
|
||||||
v-model="filterSettings.dateTo"
|
|
||||||
class="form-control"
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-heading" role="tab" id="headingSearch">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseSearch"
|
|
||||||
aria-expanded="true" aria-controls="collapseSearch" class="collapsed">
|
|
||||||
Suchen
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseSearch" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
aria-labelledby="headingSearch">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<destination-autocomplete
|
|
||||||
class="form-group form-control"
|
|
||||||
@selected="updateDestination"
|
|
||||||
:show-label="false"
|
|
||||||
:initial-filter-settings="filterSettings"
|
|
||||||
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax', extensionName: 'epproducts')}"
|
|
||||||
ajax-uri="{ep:uri.ajax(controller: 'AjaxFilterpanel', action: 'autocomplete', pageUid: settings.defaultAjaxUid, extensionName: 'epproducts')}"
|
|
||||||
></destination-autocomplete>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingDestination">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseDestination"
|
|
||||||
aria-expanded="true" aria-controls="collapseDestination">
|
|
||||||
Reiseziele
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseDestination" class="panel-collapse collapse in" role="tabpanel"
|
|
||||||
aria-labelledby="headingDestination">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<destination-checkboxes
|
|
||||||
:selectable-destinations="filterOptions.destinations"
|
|
||||||
:country-uids="filterSettings.countryUids"
|
|
||||||
:region-uids="filterSettings.regionUids"
|
|
||||||
:show-label="false"
|
|
||||||
@selected="updateDestinations"
|
|
||||||
></destination-checkboxes>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingConcept">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseConcept"
|
|
||||||
aria-expanded="true" aria-controls="collapseConcept">
|
|
||||||
Reisekonzepte
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseConcept" class="panel-collapse collapse in" role="tabpanel"
|
|
||||||
aria-labelledby="headingConcept">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<concept-select
|
|
||||||
:concept-options="filterOptions.concepts"
|
|
||||||
:concepts="filterSettings.conceptUids"
|
|
||||||
@selected="updateConcepts"
|
|
||||||
></concept-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingDuration">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseDuration"
|
|
||||||
aria-expanded="true" aria-controls="collapseDuration"
|
|
||||||
:class="{ collapsed: filterSettings.priceRange === 0 }">
|
|
||||||
Preis
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseDuration" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.priceRange > 0 }"
|
|
||||||
aria-labelledby="headingDuration">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<price-range-select
|
|
||||||
class="form-control"
|
|
||||||
:range-options="filterOptions.priceRanges"
|
|
||||||
:range="filterSettings.priceRange"
|
|
||||||
:show-label="false"
|
|
||||||
@selected="updatePriceRange"
|
|
||||||
></price-range-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingPax">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapsePax"
|
|
||||||
aria-expanded="true" aria-controls="collapsePax"
|
|
||||||
:class="{ collapsed: filterSettings.pax === 1 }">
|
|
||||||
Personen
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapsePax" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.pax > 1 }"
|
|
||||||
aria-labelledby="headingPax">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<pax-select
|
|
||||||
class="form-control"
|
|
||||||
:pax-options="filterOptions.pax"
|
|
||||||
:pax="filterSettings.pax"
|
|
||||||
:show-label="false"
|
|
||||||
@selected="updatePax"
|
|
||||||
></pax-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingHotel">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseHotel"
|
|
||||||
aria-expanded="true" aria-controls="collapseHotel"
|
|
||||||
:class="{ collapsed: !filterSettings.hotelTypes.length }">
|
|
||||||
Unterkunft
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseHotel" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.hotelTypes.length }"
|
|
||||||
aria-labelledby="headingHotel">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<hotel-types-select
|
|
||||||
:hotel-types-options="filterOptions.hotelTypes"
|
|
||||||
:hotel-types="filterSettings.hotelTypes"
|
|
||||||
@selected="updateHotelTypes"
|
|
||||||
></hotel-types-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingBoard">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseBoard"
|
|
||||||
aria-expanded="true" aria-controls="collapseBoard"
|
|
||||||
:class="{ collapsed: !filterSettings.boardTypes.length }">
|
|
||||||
Verpflegung
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseBoard" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.boardTypes.length }"
|
|
||||||
aria-labelledby="headingBoard">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<board-types-select
|
|
||||||
:board-types-options="filterOptions.boardTypes"
|
|
||||||
:board-types="filterSettings.boardTypes"
|
|
||||||
@selected="updateBoardTypes"
|
|
||||||
></board-types-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingRoomtype">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseRoomtype"
|
|
||||||
aria-expanded="true" aria-controls="collapseRoomtype"
|
|
||||||
:class="{ collapsed: !filterSettings.roomTypes.length }">
|
|
||||||
Zimmerarten / Apart.
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseRoomtype" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.roomTypes.length }"
|
|
||||||
aria-labelledby="headingRoomtype">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<room-types-select
|
|
||||||
:room-types-options="filterOptions.roomTypes"
|
|
||||||
:room-types="filterSettings.roomTypes"
|
|
||||||
@selected="updateRoomTypes"
|
|
||||||
></room-types-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-heading" role="tab" id="headingBus">
|
|
||||||
<h4 class="panel-title">
|
|
||||||
<a role="button" data-toggle="collapse" href="#collapseBus"
|
|
||||||
aria-expanded="true" aria-controls="collapseBus"
|
|
||||||
:class="{ collapsed: !filterSettings.bus }">
|
|
||||||
Anreise
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div id="collapseBus" class="panel-collapse collapse" role="tabpanel"
|
|
||||||
:class="{ in: filterSettings.bus }"
|
|
||||||
aria-labelledby="headingBus">
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<bus-select
|
|
||||||
:bus-available="filterOptions.busAvailable"
|
|
||||||
:bus="filterSettings.bus"
|
|
||||||
@selected="updateBus"
|
|
||||||
></bus-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div v-show="loading" class="loader">
|
|
||||||
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-9 ajaxtarget searchresult" v-cloak>
|
|
||||||
<div class="searchresult__info alert alert-info" v-html="resultInfo"></div>
|
|
||||||
<div class="searchresult__content">
|
|
||||||
<template v-for="section in resultData">
|
|
||||||
<a :id="'concept-' + section.concept.uid" class="anchor"></a>
|
|
||||||
<h2 class="headline headline--secondary headline--underlined">{{ section.concept.name }}</h2>
|
|
||||||
<div class="searchresult-section" :class="'searchresult-section--' + section.concept.code">
|
|
||||||
<search-result-item
|
|
||||||
v-for="item in section.items"
|
|
||||||
:key="item.key"
|
|
||||||
:item="item"
|
|
||||||
:section="section"
|
|
||||||
:referring-page-uri="referringPageUri"
|
|
||||||
></search-result-item>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div v-show="loading" class="loader">
|
|
||||||
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</search-result>
|
|
||||||
</div>
|
</div>
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,12 @@
|
|||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<ep:container data="{data}">
|
<ep:container data="{data}">
|
||||||
<watchlist loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
<div class="watchlist" x-data='watchlist("<ep:uri.ajax action="list" controller="AjaxWatchlist" pageUid="{settings.defaultAjaxUid}"/>")'>
|
||||||
referring-page-url="{f:uri.typolink(parameter: referringPageUid)}"
|
<div x-ref="watchlist"></div>
|
||||||
watchlist-uri="{ep:uri.ajax(action: 'list', controller: 'AjaxWatchlist', pageUid: settings.defaultAjaxUid)}"></watchlist>
|
<div x-show="loading" class="loader">
|
||||||
|
<f:image src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</ep:container>
|
</ep:container>
|
||||||
</f:section>
|
</f:section>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user