Merge branch 'develop' into feature/jnou/fix-iss-regression
This commit is contained in:
commit
b827ec8f45
102 changed files with 3840 additions and 1668 deletions
326
package-lock.json
generated
326
package-lock.json
generated
|
|
@ -8,6 +8,7 @@
|
|||
"name": "digitalconsumer.iss",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@adyen/adyen-web": "^6.31.1",
|
||||
"axios": "^1.13.5",
|
||||
"axios-retry": "^3.5.0",
|
||||
"bootstrap": "^5.3",
|
||||
|
|
@ -93,6 +94,18 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@adyen/adyen-web": {
|
||||
"version": "6.31.1",
|
||||
"resolved": "https://registry.npmjs.org/@adyen/adyen-web/-/adyen-web-6.31.1.tgz",
|
||||
"integrity": "sha512-vxeJW1bTvjXxYf6CkPQV8gbYIhm/hupcjjeoKkkBdxk7geW3qy18Jlco4/MuSeb88ctTRM3gebwFXpqF2NjBLQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/applepayjs": "14.0.9",
|
||||
"@types/googlepay": "0.7.10",
|
||||
"classnames": "2.5.1",
|
||||
"preact": "10.28.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
"version": "2.3.0",
|
||||
"dev": true,
|
||||
|
|
@ -3298,9 +3311,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz",
|
||||
"integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
|
||||
"integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -3312,9 +3325,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3326,9 +3339,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3340,9 +3353,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz",
|
||||
"integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -3354,9 +3367,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3368,9 +3381,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz",
|
||||
"integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -3382,9 +3395,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz",
|
||||
"integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
|
||||
"integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -3396,9 +3409,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz",
|
||||
"integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
|
||||
"integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -3410,9 +3423,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3424,9 +3437,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz",
|
||||
"integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3438,9 +3451,23 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-musl": {
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
|
|
@ -3452,9 +3479,23 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-musl": {
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
|
|
@ -3466,9 +3507,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -3480,9 +3521,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz",
|
||||
"integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -3494,9 +3535,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
|
|
@ -3508,9 +3549,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -3522,9 +3563,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz",
|
||||
"integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
|
||||
"integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -3535,10 +3576,24 @@
|
|||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openbsd-x64": {
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
|
||||
"integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
|
||||
"integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3550,9 +3605,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz",
|
||||
"integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -3564,9 +3619,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz",
|
||||
"integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -3578,7 +3633,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.52.3",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
|
||||
"integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -3590,7 +3647,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.52.3",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
|
||||
"integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -4079,13 +4138,11 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
"node_modules/@types/applepayjs": {
|
||||
"version": "14.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/applepayjs/-/applepayjs-14.0.9.tgz",
|
||||
"integrity": "sha512-xEprYbb0TEP/XIiDPbVnTYpDai8fTFpsQfVSfTd81Is2GOMUy7ie019eyX6Mz2ECxfjoUVKaiGSL577roIeHCg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/aria-query": {
|
||||
"version": "5.0.1",
|
||||
|
|
@ -4245,6 +4302,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/googlepay": {
|
||||
"version": "0.7.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/googlepay/-/googlepay-0.7.10.tgz",
|
||||
"integrity": "sha512-ByXjDfxEp87zsjw5cVsNKEeA+AIJYcWwJvRqPu85jO0Lp/FeG67csnf4mqbPaIxmdI6+Khp3v5I0yyjq9MrGhw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/graceful-fs": {
|
||||
"version": "4.1.5",
|
||||
"dev": true,
|
||||
|
|
@ -4643,13 +4706,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
|
@ -4819,11 +4882,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
|
@ -7331,6 +7396,12 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.1",
|
||||
"dev": true,
|
||||
|
|
@ -8872,13 +8943,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/editorconfig": {
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.7.tgz",
|
||||
"integrity": "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@one-ini/wasm": "0.1.1",
|
||||
"commander": "^10.0.0",
|
||||
"minimatch": "9.0.1",
|
||||
"minimatch": "^9.0.1",
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -8905,11 +8978,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/editorconfig/node_modules/minimatch": {
|
||||
"version": "9.0.1",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
|
@ -11320,7 +11395,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "4.1.0",
|
||||
"version": "4.3.8",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz",
|
||||
"integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
@ -14615,7 +14692,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/js-beautify/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -15627,7 +15706,9 @@
|
|||
"license": "ISC"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -17357,6 +17438,16 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.28.2",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz",
|
||||
"integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.3",
|
||||
"dev": true,
|
||||
|
|
@ -18027,7 +18118,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.52.3",
|
||||
"version": "4.59.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
|
||||
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -18041,28 +18134,31 @@
|
|||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.52.3",
|
||||
"@rollup/rollup-android-arm64": "4.52.3",
|
||||
"@rollup/rollup-darwin-arm64": "4.52.3",
|
||||
"@rollup/rollup-darwin-x64": "4.52.3",
|
||||
"@rollup/rollup-freebsd-arm64": "4.52.3",
|
||||
"@rollup/rollup-freebsd-x64": "4.52.3",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.52.3",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.52.3",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.52.3",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.52.3",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-x64-musl": "4.52.3",
|
||||
"@rollup/rollup-openharmony-arm64": "4.52.3",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.52.3",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.52.3",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.52.3",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.52.3",
|
||||
"@rollup/rollup-android-arm-eabi": "4.59.0",
|
||||
"@rollup/rollup-android-arm64": "4.59.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.59.0",
|
||||
"@rollup/rollup-darwin-x64": "4.59.0",
|
||||
"@rollup/rollup-freebsd-arm64": "4.59.0",
|
||||
"@rollup/rollup-freebsd-x64": "4.59.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.59.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-loong64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-ppc64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.59.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.59.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.59.0",
|
||||
"@rollup/rollup-openbsd-x64": "4.59.0",
|
||||
"@rollup/rollup-openharmony-arm64": "4.59.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.59.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.59.0",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.59.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.59.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
|
|
@ -18248,6 +18344,16 @@
|
|||
"node": ">=16.13.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
|
||||
"integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"engines": {
|
||||
"node": ">=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/saxes": {
|
||||
"version": "6.0.0",
|
||||
"dev": true,
|
||||
|
|
@ -19234,16 +19340,18 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/svgo": {
|
||||
"version": "2.8.0",
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.2.tgz",
|
||||
"integrity": "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@trysound/sax": "0.2.0",
|
||||
"commander": "^7.2.0",
|
||||
"css-select": "^4.1.3",
|
||||
"css-tree": "^1.1.3",
|
||||
"csso": "^4.2.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"sax": "^1.5.0",
|
||||
"stable": "^0.1.8"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -20056,7 +20164,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/underscore": {
|
||||
"version": "1.13.6",
|
||||
"version": "1.13.8",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz",
|
||||
"integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"lint:inspect": "eslint --inspect-config"
|
||||
},
|
||||
"dependencies": {
|
||||
"@adyen/adyen-web": "^6.31.1",
|
||||
"axios": "^1.13.5",
|
||||
"axios-retry": "^3.5.0",
|
||||
"bootstrap": "^5.3",
|
||||
|
|
|
|||
|
|
@ -3,21 +3,28 @@
|
|||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
@import url("https://fonts.googleapis.com/css2?family=Urbanist:ital,wght@0,100..900;1,100..900&display=swap");
|
||||
@font-face {
|
||||
font-family: "Glyphicons Halflings";
|
||||
src: url(/fonts/glyphicons-halflings-regular.eot);
|
||||
src: url(/fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"), url(/fonts/glyphicons-halflings-regular.woff2) format("woff2"), url(/fonts/glyphicons-halflings-regular.woff) format("woff"), url(/fonts/glyphicons-halflings-regular.ttf) format("truetype"), url(/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg");
|
||||
}
|
||||
body {
|
||||
font-family: Urbanist, Roboto, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.03em;
|
||||
color: #000;
|
||||
color: #4d4e53;
|
||||
margin: 0;
|
||||
background-color: white;
|
||||
padding: 8px;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
body .validation-info {
|
||||
display: none;
|
||||
color: #db0020;
|
||||
}
|
||||
body .italicSmall {
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
body span {
|
||||
line-height: 24px;
|
||||
|
|
@ -25,75 +32,69 @@ body span {
|
|||
body a {
|
||||
color: #0070D1;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
body a:hover {
|
||||
text-decoration: underline;
|
||||
color: #167cac;
|
||||
}
|
||||
body .form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
body .headerlinecontainer {
|
||||
color: #000;
|
||||
}
|
||||
body .headerlinecontainer .headerline1 {
|
||||
font-size: 20px;
|
||||
line-height: 32px;
|
||||
font-weight: 400;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
body input,
|
||||
body select {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 0.75rem;
|
||||
margin-top: 0rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.375rem;
|
||||
}
|
||||
body .headerlinecontainer .headerline5v2 {
|
||||
display: block;
|
||||
padding: 0.75rem 0;
|
||||
color: #db0020;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
body input,
|
||||
body select {
|
||||
height: 2.8125rem;
|
||||
border: solid 1px #b3b4b5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #8E9292;
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||
color: #525656;
|
||||
font-family: inherit;
|
||||
letter-spacing: inherit;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
font-size: 16px;
|
||||
line-height: 1.56;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
body input:focus, body input:focus-visible,
|
||||
body select:focus,
|
||||
body select:focus-visible {
|
||||
box-shadow: 0 0 0 2.5px #1574a1;
|
||||
border: 1px solid transparent;
|
||||
border: solid 2.5px #0070d1;
|
||||
outline: none;
|
||||
}
|
||||
body input:disabled, body input.disabled,
|
||||
body select:disabled,
|
||||
body select.disabled {
|
||||
background-color: #f5f5f5;
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
body input:disabled:hover, body input.disabled:hover,
|
||||
body select:disabled:hover,
|
||||
body select.disabled:hover {
|
||||
box-shadow: 0 0 0 4px transparent;
|
||||
border: 1px solid #8e9292;
|
||||
}
|
||||
body input:hover,
|
||||
body select:hover {
|
||||
border: 1px solid #8e9292;
|
||||
box-shadow: 0 0 0 4px #9fcee6;
|
||||
}
|
||||
body select {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #8E9292;
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%231474a2'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 95% 50%;
|
||||
background-size: 15px 9px;
|
||||
background: url(/icons/select.png) no-repeat 98% #ffffff;
|
||||
background-size: 10px 17px;
|
||||
appearance: none;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
}
|
||||
body .creditCardSpecific div {
|
||||
padding: 8px 0;
|
||||
}
|
||||
body .creditCardSpecific div .headerlinecontainer {
|
||||
display: none;
|
||||
body h3 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-top: 1.375rem;
|
||||
margin-bottom: 0.6875rem;
|
||||
color: #000;
|
||||
}
|
||||
body .creditCardSpecific div label {
|
||||
font-weight: 500;
|
||||
|
|
@ -124,87 +125,84 @@ body #cardExpirationContainer {
|
|||
body .optional-label span {
|
||||
display: none;
|
||||
}
|
||||
body .optional-label:after {
|
||||
content: " (optional)";
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 15px;
|
||||
body .buttonContainer #sghopcancelbutton {
|
||||
float: left;
|
||||
}
|
||||
body .buttonContainer {
|
||||
height: 48px;
|
||||
body .buttonContainer #sghopsubmitbutton {
|
||||
float: right;
|
||||
}
|
||||
body .buttonContainer button {
|
||||
position: relative;
|
||||
background: linear-gradient(270deg, #1574a1 0%, #003d58 100%);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
justify-content: center;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-family: inherit;
|
||||
letter-spacing: inherit;
|
||||
height: 48px;
|
||||
body .buttonContainer #sghopsubmitbutton.creditCardSpecific {
|
||||
float: right;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
body .buttonContainer button {
|
||||
background: linear-gradient(270deg, #1574a1 0%, #003d58 100%);
|
||||
cursor: pointer;
|
||||
@media (max-width: 500px) {
|
||||
body .buttonContainer #sghopsubmitbutton.creditCardSpecific {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
body .buttonContainer button:focus {
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
|
||||
body .buttonContainer #selectPaymentTypeButton {
|
||||
float: right;
|
||||
}
|
||||
body .buttonContainer button:focus, body .buttonContainer button:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
|
||||
color: #fff;
|
||||
background: linear-gradient(270deg, rgb(6, 87, 124) 0%, rgb(6, 87, 124) 100%);
|
||||
@media (max-width: 500px) {
|
||||
body .buttonContainer #selectPaymentTypeButton {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
body .buttonContainer button:disabled {
|
||||
background: #e3e4e4 !important;
|
||||
background: linear-gradient(270deg, #e3e4e4 0%, #e3e4e4 100%) !important;
|
||||
color: #4d5151 !important;
|
||||
font-weight: 400;
|
||||
height: 48px;
|
||||
body .buttonContainer .btn-success {
|
||||
width: 99%;
|
||||
height: 45px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
border-radius: 22.5px;
|
||||
font-size: 16px;
|
||||
line-height: 0.94;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
background-color: #0c7e47;
|
||||
border-color: #0a673a;
|
||||
font-family: Urbanist;
|
||||
cursor: pointer;
|
||||
pointer-events: all;
|
||||
}
|
||||
body .buttonContainer button.has-loader {
|
||||
color: #fff;
|
||||
background: #06577c;
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
|
||||
pointer-events: auto;
|
||||
body .buttonContainer .btn-success:hover {
|
||||
background-color: #084f2d;
|
||||
}
|
||||
body .buttonContainer button.delay {
|
||||
transition: background 0s 0s ease-in-out;
|
||||
body .buttonContainer .btn-success:focus, body .buttonContainer .btn-success:active {
|
||||
outline: none;
|
||||
background-color: #0c7e47;
|
||||
box-shadow: 0 0 0 3px #ffffff, 0 0 0 5.5px #0c7e47;
|
||||
}
|
||||
body .has-error input,
|
||||
body .has-error select {
|
||||
border: 1px solid #d4281c;
|
||||
body .has-error input.form-control,
|
||||
body .has-error select.form-control {
|
||||
border-color: #db0020;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
body .has-error input:focus,
|
||||
body .has-error select:focus {
|
||||
box-shadow: 0 0 0 2.5px #fcbfbb;
|
||||
}
|
||||
body .has-error input:hover,
|
||||
body .has-error select:hover {
|
||||
border: 1px solid #d4281c;
|
||||
box-shadow: 0 0 0 4px #fcbfbb;
|
||||
body .has-error input.form-control:focus,
|
||||
body .has-error select.form-control:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
body .has-error select {
|
||||
border: 1px solid #d4281c;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%23d4281c'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 95% 50%;
|
||||
background-size: 15px 9px;
|
||||
appearance: none;
|
||||
background-image: url(/icons/select-error.png);
|
||||
}
|
||||
body .has-error small {
|
||||
margin-top: 4px;
|
||||
color: #d4281c;
|
||||
font-size: 1rem;
|
||||
line-height: 1.56;
|
||||
margin-bottom: 0.3125rem;
|
||||
color: #db0020;
|
||||
}
|
||||
body .has-success .control-label {
|
||||
color: #4d4e53;
|
||||
}
|
||||
body .has-success input.form-control,
|
||||
body .has-success select.form-control {
|
||||
border-color: #0c7e47;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
body .has-success input.form-control:focus,
|
||||
body .has-success select.form-control:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
body .has-success select {
|
||||
background-image: url(/icons/select-success.png);
|
||||
}
|
||||
body .cc-error-container #alert-message {
|
||||
background-color: #fcbfbb;
|
||||
|
|
@ -212,14 +210,17 @@ body .cc-error-container #alert-message {
|
|||
}
|
||||
|
||||
#fmg-checkout-shared .form-group .list-group.radio .list-group-item {
|
||||
border-radius: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#fmg-checkout-shared .form-group .list-group.radio .list-group-item.active {
|
||||
box-shadow: 0 0 0 5px #b9d7e6;
|
||||
}
|
||||
#fmg-checkout-shared .form-group .list-group.radio .list-group-item label {
|
||||
padding: 12px 20px;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container #paypalParentDiv {
|
||||
|
|
@ -227,38 +228,31 @@ body .cc-error-container #alert-message {
|
|||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
width: 48%;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection #applepayParentLink {
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection .list-group-item {
|
||||
border-radius: 35px;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection .list-group-item#applepayParentLink {
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
background-color: #000000;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection #applepayParentLink label {
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection .list-group-item#applepayParentLink label {
|
||||
padding: 0;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection #applepayParentLink label apple-pay-button {
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection .list-group-item#applepayParentLink label apple-pay-button {
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection #applepayParentLink.list-group-item {
|
||||
box-shadow: none;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #8E9292;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group.paymentSelection #applepayParentLink:host {
|
||||
--apple-pay-button-width: auto;
|
||||
--apple-pay-button-height: 47px;
|
||||
--apple-pay-button-border-radius: 35px;
|
||||
--apple-pay-button-padding: 2px 0;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group #paypalParentLink {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group #paypalParentLink #paypalImage {
|
||||
max-width: 50%;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container .form-group .list-group #paypalParentLink.list-group-item {
|
||||
box-shadow: none;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #8E9292;
|
||||
max-width: 90px;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container.no-applepay .form-group {
|
||||
width: 100%;
|
||||
|
|
@ -273,15 +267,19 @@ body .cc-error-container #alert-message {
|
|||
width: 100%;
|
||||
}
|
||||
#fmg-checkout-shared #applepay-and-paypal-container.no-applepay .form-group .list-group #paypalParentLink #paypalImage {
|
||||
max-width: 25%;
|
||||
max-width: 5.3125rem;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container label {
|
||||
display: inline-flex;
|
||||
display: block;
|
||||
text-align: left;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
line-height: 1.56;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container label.control-label {
|
||||
justify-content: start;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container label span.paymentOptionText {
|
||||
margin: auto 0;
|
||||
|
|
@ -294,35 +292,56 @@ body .cc-error-container #alert-message {
|
|||
#fmg-checkout-shared #other-payments-container #afterpayParentLink label > span:last-of-type {
|
||||
width: 0;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv #creditCardParentLink {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@media (max-width: 33.9em) {
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv #creditCardParentLink {
|
||||
min-height: 3.5rem;
|
||||
}
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv #creditCardParentLink label {
|
||||
display: flex;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv #creditCardParentLink label .paymentOptionText {
|
||||
text-align: left;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv.active {
|
||||
margin-bottom: 32px;
|
||||
padding-bottom: 10px;
|
||||
border: 1px solid #0070D1;
|
||||
border-radius: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv.active > .paymentSelection #creditCardParentLink {
|
||||
border-width: 0 0 2px 0;
|
||||
min-height: unset;
|
||||
border-bottom-color: #0070D1;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv .paymentSelection #creditCardImages {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv .paymentSelection #creditCardImages > img {
|
||||
width: 20%;
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv .paymentSelection #creditCardImages img {
|
||||
max-width: fit-content;
|
||||
width: 25%;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv .paymentSelection #creditCardImages img:not(:last-of-type) {
|
||||
margin-right: 1%;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv .creditCardSpecific {
|
||||
padding: 0 16px;
|
||||
padding: 0 2%;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container #creditCardParentDiv .creditCardSpecific > .form-group {
|
||||
width: 100%;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container .italicSmall {
|
||||
margin-top: 10px;
|
||||
}
|
||||
#fmg-checkout-shared #other-payments-container .disclaimerContainerv2 {
|
||||
margin-bottom: 32px;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
@media only screen and (max-device-width: 767px) {
|
||||
#fmg-checkout-shared #applepay-and-paypal-container {
|
||||
|
|
@ -332,3 +351,26 @@ body .cc-error-container #alert-message {
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.form-control-feedback {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
display: block;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
top: 27px;
|
||||
}
|
||||
.form-control-feedback.glyphicon {
|
||||
display: none;
|
||||
}
|
||||
.form-control-feedback.glyphicon-remove:before {
|
||||
content: "\e014";
|
||||
}
|
||||
.form-control-feedback.glyphicon-ok:before {
|
||||
content: "\e013";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,103 +4,16 @@
|
|||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* Style the modal when PayPal button is selected */
|
||||
#pageLoadingModal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
display: flex;
|
||||
}
|
||||
#pageLoadingModal .modal-content {
|
||||
margin: auto auto;
|
||||
}
|
||||
#pageLoadingModal p {
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
}
|
||||
#pageLoadingModal .modal {
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
outline: 0;
|
||||
}
|
||||
#pageLoadingModal .modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
background-clip: padding-box;
|
||||
outline: 0;
|
||||
width: 176px;
|
||||
height: 136px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg fill='none' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 32'%3e%3cpath d='M22.39 27.313a3.53 3.53 0 0 0 7.058 0' fill='%23fff'/%3e%3cpath d='M22.39 27.313a3.53 3.53 0 0 0 7.058 0' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M54.459 27.313a3.527 3.527 0 0 0 7.054 0' fill='%23fff'/%3e%3cpath d='M54.459 27.313a3.527 3.527 0 0 0 7.054 0' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M42.06.8c8.08 0 11.89.935 11.89.935 3.58.576 5.696 7.207 5.696 7.207h.727c0-2.427 1.302-2.397 2.341-2 .723.292 1.363.76 1.86 1.361 1.319 1.547.465 1.674.465 1.674h-5.067l3.846 3.01v12.016c0 2.41-2.029 2.31-2.029 2.31H22.338s-2.029.1-2.029-2.31V12.996l3.84-3.009H19.07s-.853-.127.466-1.674a4.693 4.693 0 0 1 1.86-1.361c1.032-.397 2.341-.427 2.341 2h.736s2.117-6.64 5.696-7.21c0 0 3.81-.942 11.89-.942Z' fill='%23fff' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M42.06 8.847c7.924 0 14.685.511 14.685.511 0-2.585-2.38-6.011-2.38-6.011S50.4 2.519 42.06 2.519s-12.303.828-12.303.828-2.38 3.426-2.38 6.011c0 0 6.76-.51 14.683-.51Z' fill='%23DA291C' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M35.277 16.523a62.558 62.558 0 0 1 13.277 0m3.276-.439s2.384-2.257 8.608-2.257c0 0 1.179 2.657-2.54 3.37m-25.894-1.113s-2.387-2.257-8.611-2.257c0 0-1.16 2.579 2.543 3.37m-3.546 5.856s21.52 3.647 39.123 0' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 96px;
|
||||
}
|
||||
#pageLoadingModal .modal-content:after {
|
||||
content: "";
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
width: 5.5rem;
|
||||
height: 5.5rem;
|
||||
border: 0.45em solid #d4281c;
|
||||
border-right-color: transparent;
|
||||
animation: spinnerrotate 0.75s linear infinite;
|
||||
}
|
||||
@keyframes spinnerrotate {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
#pageLoadingModal .modal-content p {
|
||||
display: none;
|
||||
}
|
||||
#pageLoadingModal .modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background-color: #000000;
|
||||
}
|
||||
#pageLoadingModal .modal-backdrop.fade {
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
#pageLoadingModal.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.buy-backdrop {
|
||||
background-color: rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
.buy-backdrop #afterpay__iframe-checkout-container {
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.8) !important;
|
||||
}
|
||||
.buy-backdrop #afterpay__iframe-checkout-container .style_closeWrapper__lIHJe {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.buy-container-closer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
|
|
|
|||
BIN
public/fonts/glyphicons-halflings-regular.eot
Normal file
BIN
public/fonts/glyphicons-halflings-regular.eot
Normal file
Binary file not shown.
229
public/fonts/glyphicons-halflings-regular.svg
Normal file
229
public/fonts/glyphicons-halflings-regular.svg
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata></metadata>
|
||||
<defs>
|
||||
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
|
||||
<font-face units-per-em="1200" ascent="960" descent="-240" />
|
||||
<missing-glyph horiz-adv-x="500" />
|
||||
<glyph />
|
||||
<glyph />
|
||||
<glyph unicode="
" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
|
||||
<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode=" " horiz-adv-x="652" />
|
||||
<glyph unicode=" " horiz-adv-x="1304" />
|
||||
<glyph unicode=" " horiz-adv-x="652" />
|
||||
<glyph unicode=" " horiz-adv-x="1304" />
|
||||
<glyph unicode=" " horiz-adv-x="434" />
|
||||
<glyph unicode=" " horiz-adv-x="326" />
|
||||
<glyph unicode=" " horiz-adv-x="217" />
|
||||
<glyph unicode=" " horiz-adv-x="217" />
|
||||
<glyph unicode=" " horiz-adv-x="163" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="72" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="326" />
|
||||
<glyph unicode="€" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
|
||||
<glyph unicode="−" d="M200 400h900v300h-900v-300z" />
|
||||
<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
|
||||
<glyph unicode="☁" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
|
||||
<glyph unicode="✉" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
|
||||
<glyph unicode="✏" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
|
||||
<glyph unicode="" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
|
||||
<glyph unicode="" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
|
||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
|
||||
<glyph unicode="" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
|
||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
|
||||
<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
|
||||
<glyph unicode="" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
|
||||
<glyph unicode="" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
|
||||
<glyph unicode="" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
|
||||
<glyph unicode="" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
|
||||
<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
|
||||
<glyph unicode="" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
|
||||
<glyph unicode="" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
|
||||
<glyph unicode="" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
|
||||
<glyph unicode="" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
|
||||
<glyph unicode="" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
|
||||
<glyph unicode="" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
|
||||
<glyph unicode="" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
|
||||
<glyph unicode="" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
|
||||
<glyph unicode="" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
|
||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
|
||||
<glyph unicode="" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
|
||||
<glyph unicode="" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
|
||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
|
||||
<glyph unicode="" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
|
||||
<glyph unicode="" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
|
||||
<glyph unicode="" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
|
||||
<glyph unicode="" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
|
||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
|
||||
<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
|
||||
<glyph unicode="" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
|
||||
<glyph unicode="" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
|
||||
<glyph unicode="" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
|
||||
<glyph unicode="" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
|
||||
<glyph unicode="" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
|
||||
<glyph unicode="" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
|
||||
<glyph unicode="" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
|
||||
<glyph unicode="" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
|
||||
<glyph unicode="" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
|
||||
<glyph unicode="" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
|
||||
<glyph unicode="" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
|
||||
<glyph unicode="" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
|
||||
<glyph unicode="" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
|
||||
<glyph unicode="" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
|
||||
<glyph unicode="" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
|
||||
<glyph unicode="" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
|
||||
<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
|
||||
<glyph unicode="" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" />
|
||||
<glyph unicode="" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
|
||||
<glyph unicode="" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
|
||||
<glyph unicode="" d="M200 0l900 550l-900 550v-1100z" />
|
||||
<glyph unicode="" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
||||
<glyph unicode="" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
|
||||
<glyph unicode="" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
|
||||
<glyph unicode="" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
|
||||
<glyph unicode="" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
|
||||
<glyph unicode="" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
|
||||
<glyph unicode="" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
|
||||
<glyph unicode="" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" />
|
||||
<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
|
||||
<glyph unicode="" d="M0 547l600 453v-300h600v-300h-600v-301z" />
|
||||
<glyph unicode="" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
|
||||
<glyph unicode="" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
|
||||
<glyph unicode="" d="M104 600h296v600h300v-600h298l-449 -600z" />
|
||||
<glyph unicode="" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
|
||||
<glyph unicode="" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
|
||||
<glyph unicode="" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
|
||||
<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
|
||||
<glyph unicode="" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
|
||||
<glyph unicode="" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
|
||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
|
||||
<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
|
||||
<glyph unicode="" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
|
||||
<glyph unicode="" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
|
||||
<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
|
||||
<glyph unicode="" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
|
||||
<glyph unicode="" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
|
||||
<glyph unicode="" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
|
||||
<glyph unicode="" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
|
||||
<glyph unicode="" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
|
||||
<glyph unicode="" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
|
||||
<glyph unicode="" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
|
||||
<glyph unicode="" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
|
||||
<glyph unicode="" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
|
||||
<glyph unicode="" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
|
||||
<glyph unicode="" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
|
||||
<glyph unicode="" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
|
||||
<glyph unicode="" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
|
||||
<glyph unicode="" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
|
||||
<glyph unicode="" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
|
||||
<glyph unicode="" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
|
||||
<glyph unicode="" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
|
||||
<glyph unicode="" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" />
|
||||
<glyph unicode="" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
|
||||
<glyph unicode="" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" />
|
||||
<glyph unicode="" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
|
||||
<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" />
|
||||
<glyph unicode="" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
|
||||
<glyph unicode="" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
|
||||
<glyph unicode="" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
|
||||
<glyph unicode="" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
|
||||
<glyph unicode="" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
|
||||
<glyph unicode="" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" />
|
||||
<glyph unicode="" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
|
||||
<glyph unicode="" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
|
||||
<glyph unicode="" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
|
||||
<glyph unicode="" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
|
||||
<glyph unicode="" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
|
||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
|
||||
<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
|
||||
<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
|
||||
<glyph unicode="" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
|
||||
<glyph unicode="" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" />
|
||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
|
||||
<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" />
|
||||
<glyph unicode="" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
|
||||
<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
|
||||
<glyph unicode="" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
|
||||
<glyph unicode="" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
|
||||
<glyph unicode="" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" />
|
||||
<glyph unicode="" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
|
||||
<glyph unicode="" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
|
||||
<glyph unicode="" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
|
||||
<glyph unicode="" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
|
||||
<glyph unicode="" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
|
||||
<glyph unicode="" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
|
||||
<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
|
||||
<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
|
||||
<glyph unicode="" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" />
|
||||
<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
|
||||
<glyph unicode="" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
|
||||
<glyph unicode="" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 62 KiB |
BIN
public/fonts/glyphicons-halflings-regular.ttf
Normal file
BIN
public/fonts/glyphicons-halflings-regular.ttf
Normal file
Binary file not shown.
BIN
public/fonts/glyphicons-halflings-regular.woff
Normal file
BIN
public/fonts/glyphicons-halflings-regular.woff
Normal file
Binary file not shown.
BIN
public/fonts/glyphicons-halflings-regular.woff2
Normal file
BIN
public/fonts/glyphicons-halflings-regular.woff2
Normal file
Binary file not shown.
BIN
public/icons/select-disabled.png
Normal file
BIN
public/icons/select-disabled.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/icons/select-error.png
Normal file
BIN
public/icons/select-error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/icons/select-success.png
Normal file
BIN
public/icons/select-success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/icons/select.png
Normal file
BIN
public/icons/select.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -3,22 +3,30 @@
|
|||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
/* IMPORTANT: READ README.md in this folder! Do not edit .css file directly! */
|
||||
@import url("https://fonts.googleapis.com/css2?family=Urbanist:ital,wght@0,100..900;1,100..900&display=swap");
|
||||
|
||||
@font-face {
|
||||
font-family: 'Glyphicons Halflings';
|
||||
src: url(/fonts/glyphicons-halflings-regular.eot);
|
||||
src: url(/fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'), url(/fonts/glyphicons-halflings-regular.woff2) format('woff2'), url(/fonts/glyphicons-halflings-regular.woff) format('woff'), url(/fonts/glyphicons-halflings-regular.ttf) format('truetype'), url(/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg');
|
||||
}
|
||||
body {
|
||||
font-family: Urbanist, Roboto, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
letter-spacing: .03em;
|
||||
color: #000;
|
||||
color: #4d4e53;
|
||||
margin: 0;
|
||||
background-color: white;
|
||||
padding: 8px;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1rem;
|
||||
|
||||
.validation-info {
|
||||
display: none;
|
||||
color: #db0020
|
||||
}
|
||||
|
||||
.italicSmall {
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span {
|
||||
|
|
@ -28,79 +36,77 @@ body {
|
|||
a {
|
||||
color: #0070D1;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
color: #167cac;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.headerlinecontainer {
|
||||
color: #000;
|
||||
.headerline1 {
|
||||
font-size: 20px;
|
||||
line-height: 32px;
|
||||
font-weight: 400;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
margin-bottom: .75rem;
|
||||
margin-top: 0rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.375rem;
|
||||
}
|
||||
.headerline5v2 {
|
||||
display: block;
|
||||
padding: .75rem 0;
|
||||
color: #db0020;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
input,
|
||||
select {
|
||||
height: 2.8125rem;
|
||||
border: solid 1px #b3b4b5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #8E9292;
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||
color: #525656;
|
||||
font-family: inherit;
|
||||
letter-spacing: inherit;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
font-size: 16px;
|
||||
line-height: 1.56;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
box-shadow: 0 0 0 2.5px #1574a1;
|
||||
border: 1px solid transparent;
|
||||
border: solid 2.5px #0070d1;
|
||||
outline: none;
|
||||
}
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
background-color: #f5f5f5;
|
||||
filter: grayscale(100%);
|
||||
&:hover {
|
||||
box-shadow: 0 0 0 4px transparent;
|
||||
border: 1px solid #8e9292;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
border: 1px solid #8e9292;
|
||||
box-shadow: 0 0 0 4px #9fcee6;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
border-radius: 4px;
|
||||
border: 1px solid #8E9292;
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%231474a2'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 95% 50%;
|
||||
background-size: 15px 9px;
|
||||
background: url(/icons/select.png) no-repeat 98% #ffffff;;
|
||||
background-size: 10px 17px;
|
||||
appearance: none;
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-top: 1.375rem;
|
||||
margin-bottom: .6875rem;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.creditCardSpecific {
|
||||
div {
|
||||
padding: 8px 0;
|
||||
.headerlinecontainer {
|
||||
display: none;
|
||||
}
|
||||
label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
|
@ -133,63 +139,57 @@ body {
|
|||
span {
|
||||
display: none;
|
||||
}
|
||||
&:after {
|
||||
content: " (optional)";
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
height: 48px;
|
||||
button {
|
||||
position: relative;
|
||||
background: linear-gradient(270deg, #1574a1 0%, #003d58 100%);
|
||||
|
||||
#sghopcancelbutton {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#sghopsubmitbutton {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#sghopsubmitbutton.creditCardSpecific {
|
||||
float: right;
|
||||
|
||||
@media(max-width: 500px) {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#selectPaymentTypeButton {
|
||||
float: right;
|
||||
|
||||
@media(max-width: 500px) {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.btn-success {
|
||||
width: 99%;
|
||||
height: 45px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
justify-content: center;
|
||||
font-weight: 500;
|
||||
border-radius: 22.5px;
|
||||
font-size: 16px;
|
||||
font-family: inherit;
|
||||
letter-spacing: inherit;
|
||||
height: 48px;
|
||||
@media (hover: hover) {
|
||||
background: linear-gradient(270deg, #1574a1 0%, #003d58 100%);
|
||||
cursor: pointer;
|
||||
line-height: 0.94;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
background-color: #0c7e47;
|
||||
border-color: #0a673a;
|
||||
font-family: Urbanist;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #084f2d;
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
|
||||
}
|
||||
&:focus, // Mouse, touch, stylus focus
|
||||
&:focus-visible {
|
||||
// Keyboard focus for accessibility
|
||||
&:focus,
|
||||
&:active {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
|
||||
color: #fff;
|
||||
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
|
||||
}
|
||||
&:disabled {
|
||||
background: #e3e4e4 !important;
|
||||
background: linear-gradient(270deg, #e3e4e4 0%, #e3e4e4 100%) !important;
|
||||
color: #4d5151 !important;
|
||||
font-weight: 400;
|
||||
height: 48px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
pointer-events: all;
|
||||
}
|
||||
&.has-loader {
|
||||
color: #fff;
|
||||
background: #06577c;
|
||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
|
||||
pointer-events: auto;
|
||||
}
|
||||
&.delay {
|
||||
// fixes flicker while transitioning between states
|
||||
transition: background 0s 0s ease-in-out;
|
||||
background-color: #0c7e47;
|
||||
box-shadow: 0 0 0 3px #ffffff, 0 0 0 5.5px #0c7e47;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,26 +198,42 @@ body {
|
|||
.has-error {
|
||||
input,
|
||||
select {
|
||||
border: 1px solid #d4281c;
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 2.5px #fcbfbb;
|
||||
}
|
||||
&:hover {
|
||||
border: 1px solid #d4281c;
|
||||
box-shadow: 0 0 0 4px #fcbfbb;
|
||||
&.form-control {
|
||||
border-color: #db0020;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
select {
|
||||
border: 1px solid #d4281c;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%23d4281c'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 95% 50%;
|
||||
background-size: 15px 9px;
|
||||
appearance: none;
|
||||
background-image: url(/icons/select-error.png);
|
||||
}
|
||||
small {
|
||||
margin-top: 4px;
|
||||
color: #d4281c;
|
||||
font-size: 1rem;
|
||||
line-height: 1.56;
|
||||
margin-bottom: .3125rem;
|
||||
color: #db0020;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.has-success {
|
||||
.control-label {
|
||||
color: #4d4e53
|
||||
}
|
||||
input,
|
||||
select {
|
||||
&.form-control {
|
||||
border-color: #0c7e47;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
select {
|
||||
background-image: url(/icons/select-success.png);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +250,11 @@ body {
|
|||
.list-group {
|
||||
&.radio {
|
||||
.list-group-item {
|
||||
border-radius: 10px;
|
||||
border-radius: 5px;
|
||||
|
||||
&.active {
|
||||
box-shadow: 0 0 0 5px #b9d7e6;
|
||||
}
|
||||
|
||||
label {
|
||||
padding: 12px 20px;
|
||||
|
|
@ -246,8 +266,7 @@ body {
|
|||
|
||||
#applepay-and-paypal-container {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
|
||||
#paypalParentDiv {
|
||||
|
|
@ -256,49 +275,38 @@ body {
|
|||
|
||||
.form-group {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
width: 48%;
|
||||
|
||||
.list-group {
|
||||
&.paymentSelection {
|
||||
.list-group-item {
|
||||
border-radius: 35px;
|
||||
|
||||
#applepayParentLink {
|
||||
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
background-color: #000000;
|
||||
|
||||
label {
|
||||
padding: 0;
|
||||
|
||||
apple-pay-button {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-group-item {
|
||||
&#applepayParentLink {
|
||||
margin: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #8E9292;
|
||||
}
|
||||
|
||||
&:host {
|
||||
--apple-pay-button-width: auto;
|
||||
label {
|
||||
padding: 0;
|
||||
|
||||
apple-pay-button {
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
--apple-pay-button-height: 47px;
|
||||
--apple-pay-button-border-radius: 35px;
|
||||
--apple-pay-button-padding: 2px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#paypalParentLink {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
|
||||
#paypalImage {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
&.list-group-item {
|
||||
box-shadow: none;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #8E9292;
|
||||
max-width: 90px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,7 +332,7 @@ body {
|
|||
#paypalParentLink {
|
||||
|
||||
#paypalImage {
|
||||
max-width: 25%;
|
||||
max-width: 5.3125rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -334,14 +342,19 @@ body {
|
|||
|
||||
#other-payments-container {
|
||||
label {
|
||||
display: inline-flex;
|
||||
display: block;
|
||||
text-align: left;
|
||||
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
line-height: 1.56;
|
||||
|
||||
&.control-label {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
span {
|
||||
&.paymentOptionText {
|
||||
|
|
@ -367,14 +380,28 @@ body {
|
|||
}
|
||||
|
||||
#creditCardParentDiv {
|
||||
#creditCardParentLink {
|
||||
margin-bottom: 0;
|
||||
|
||||
@media (max-width: 33.9em) {
|
||||
min-height: 3.5rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
.paymentOptionText {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
margin-bottom: 32px;
|
||||
padding-bottom: 10px;
|
||||
border: 1px solid #0070D1;
|
||||
border-radius: 10px;
|
||||
border-radius: 5px;
|
||||
|
||||
> .paymentSelection {
|
||||
#creditCardParentLink {
|
||||
border-width: 0 0 2px 0;
|
||||
min-height: unset;
|
||||
border-bottom-color: #0070D1;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
|
|
@ -384,20 +411,28 @@ body {
|
|||
|
||||
.paymentSelection {
|
||||
#creditCardImages {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
justify-content: flex-end;
|
||||
|
||||
> img {
|
||||
width: 20%;
|
||||
img {
|
||||
max-width: fit-content;
|
||||
width: 25%;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
margin-right: 1%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.creditCardSpecific {
|
||||
padding: 0 16px;
|
||||
padding: 0 2%;
|
||||
|
||||
> .form-group {
|
||||
width: 100%;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +442,7 @@ body {
|
|||
}
|
||||
|
||||
.disclaimerContainerv2 {
|
||||
margin-bottom: 32px;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -422,4 +457,27 @@ body {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-control-feedback {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
display: block;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
top: 27px;
|
||||
&.glyphicon {
|
||||
display: none;
|
||||
}
|
||||
&.glyphicon-remove:before {
|
||||
content: "\e014";
|
||||
}
|
||||
&.glyphicon-ok:before {
|
||||
content: "\e013";
|
||||
}
|
||||
}
|
||||
|
|
@ -5,107 +5,20 @@
|
|||
|
||||
/* Style the modal when PayPal button is selected */
|
||||
#pageLoadingModal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.40);
|
||||
display: flex;
|
||||
|
||||
.modal-content {
|
||||
margin: auto auto;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
background-clip: padding-box;
|
||||
outline: 0;
|
||||
width: 176px;
|
||||
height: 136px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg fill='none' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 32'%3e%3cpath d='M22.39 27.313a3.53 3.53 0 0 0 7.058 0' fill='%23fff'/%3e%3cpath d='M22.39 27.313a3.53 3.53 0 0 0 7.058 0' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M54.459 27.313a3.527 3.527 0 0 0 7.054 0' fill='%23fff'/%3e%3cpath d='M54.459 27.313a3.527 3.527 0 0 0 7.054 0' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M42.06.8c8.08 0 11.89.935 11.89.935 3.58.576 5.696 7.207 5.696 7.207h.727c0-2.427 1.302-2.397 2.341-2 .723.292 1.363.76 1.86 1.361 1.319 1.547.465 1.674.465 1.674h-5.067l3.846 3.01v12.016c0 2.41-2.029 2.31-2.029 2.31H22.338s-2.029.1-2.029-2.31V12.996l3.84-3.009H19.07s-.853-.127.466-1.674a4.693 4.693 0 0 1 1.86-1.361c1.032-.397 2.341-.427 2.341 2h.736s2.117-6.64 5.696-7.21c0 0 3.81-.942 11.89-.942Z' fill='%23fff' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M42.06 8.847c7.924 0 14.685.511 14.685.511 0-2.585-2.38-6.011-2.38-6.011S50.4 2.519 42.06 2.519s-12.303.828-12.303.828-2.38 3.426-2.38 6.011c0 0 6.76-.51 14.683-.51Z' fill='%23DA291C' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3cpath d='M35.277 16.523a62.558 62.558 0 0 1 13.277 0m3.276-.439s2.384-2.257 8.608-2.257c0 0 1.179 2.657-2.54 3.37m-25.894-1.113s-2.387-2.257-8.611-2.257c0 0-1.16 2.579 2.543 3.37m-3.546 5.856s21.52 3.647 39.123 0' stroke='%23000' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 96px;
|
||||
&:after {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
width: 5.5rem;
|
||||
height: 5.5rem;
|
||||
border: 0.45em solid #d4281c;
|
||||
border-right-color: transparent;
|
||||
animation: spinnerrotate 0.75s linear infinite;
|
||||
}
|
||||
@keyframes spinnerrotate {
|
||||
0% { transform: rotate(0)}
|
||||
100% { transform: rotate(360deg)}
|
||||
}
|
||||
p {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background-color: #000000;
|
||||
&.fade {
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
}
|
||||
}
|
||||
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
display: none;
|
||||
}
|
||||
|
||||
// AfterPay Styles
|
||||
|
||||
.buy-backdrop {
|
||||
background-color: rgba(0,0,0,.3)!important;
|
||||
background-color: rgba(0,0,0,.8)!important;
|
||||
#afterpay__iframe-checkout-container {
|
||||
width: 100%;
|
||||
.style_closeWrapper__lIHJe {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.buy-container-closer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Modal Spinner
|
||||
|
||||
@keyframes rotate {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ const applicationConfig = Object.freeze({
|
|||
FRONTEND_LOGGER_PATH: "/analytics/api/v1/logging",
|
||||
BAILOUT_ON_APPLICATION_ERROR: true,
|
||||
BAILOUT_ON_API_ERROR: true,
|
||||
BAILOUT_ON_ROUTER_ERROR: true
|
||||
BAILOUT_ON_ROUTER_ERROR: true,
|
||||
ADYEN_CLIENT_KEY: process.env.VUE_APP_ADYEN_CLIENT_KEY,
|
||||
ADYEN_ENVIRONMENT: process.env.VUE_APP_ADYEN_ENVIRONMENT
|
||||
});
|
||||
|
||||
export default applicationConfig;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// When adding a new bailout, the Digital Consumer Order Service must also be updated to map the new bailout code to the SV2BailoutCode
|
||||
const bailoutCode = Object.freeze({
|
||||
Unknown: 0,
|
||||
SaveSessionError: 1,
|
||||
|
|
@ -15,7 +16,8 @@ const bailoutCode = Object.freeze({
|
|||
VehicleYMMSLookupError: 13,
|
||||
ApplicationError: 14,
|
||||
ApiError: 15,
|
||||
RouterError: 16
|
||||
RouterError: 16,
|
||||
CoverageCancelledByUser: 17
|
||||
});
|
||||
|
||||
export default bailoutCode;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ const bailoutMessage = Object.freeze({
|
|||
}),
|
||||
HeavyTruckVehicle: (carId) => ({
|
||||
code: bailoutCode.HeavyTruckVehicle,
|
||||
message: `User selected a heavy truck vehicle. Car ID: ${carId}`
|
||||
message: `User selected a big truck that Safelite cannot service. Car ID: ${carId}`
|
||||
}),
|
||||
NoPartsAvailable: () => ({
|
||||
code: bailoutCode.NoPartsAvailable,
|
||||
|
|
@ -93,7 +93,11 @@ const bailoutMessage = Object.freeze({
|
|||
code: bailoutCode.VehicleYMMSLookupError,
|
||||
message: getMessage(year, make, model, style)
|
||||
};
|
||||
}
|
||||
},
|
||||
CoverageCancelledByUser: () => ({
|
||||
code: bailoutCode.CoverageCancelledByUser,
|
||||
message: 'User canceled claim on ITAC/No Comp coverage statement.'
|
||||
})
|
||||
});
|
||||
|
||||
export default bailoutMessage;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,3 @@ export const dropdownVariants = Object.freeze({
|
|||
primary: 'primary',
|
||||
compact: 'compact'
|
||||
});
|
||||
export const modalPositions = Object.freeze({
|
||||
center: 'center',
|
||||
edge: 'edge'
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ const cookieNames = Object.freeze({
|
|||
|
||||
// Existing Safelite.com cookies
|
||||
DXDEV: 'dxdev',
|
||||
SESSION_ID: 'sid',
|
||||
SESSION_KEY: 'skey'
|
||||
SESSION_ID: 'sid'
|
||||
});
|
||||
|
||||
const cookieExpirations = Object.freeze({
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const PARTS_BASE_URL = '/parts/api/v1/parts';
|
|||
const PRICE_BASE_URL = '/price/api/v1/price';
|
||||
const SCHEDULE_BASE_URL = '/schedule/api/v1/schedule';
|
||||
const VEHICLE_BASE_URL = '/vehicle/api/v1/vehicle';
|
||||
const PAYMENT_BASE_URL = '/payment/api/v1/payment';
|
||||
|
||||
const endpoints = Object.freeze({
|
||||
GetRouteInfo: {
|
||||
|
|
@ -239,6 +240,14 @@ const endpoints = Object.freeze({
|
|||
GetPaymentSignature: {
|
||||
url: `${ORDER_BASE_URL}/sign`,
|
||||
method: 'POST'
|
||||
},
|
||||
InitializeAdyenPayment: {
|
||||
url: `${PAYMENT_BASE_URL}/payment/session/initialize-session`,
|
||||
method: "POST",
|
||||
},
|
||||
GetAdyenSessionResult: {
|
||||
url: `${PAYMENT_BASE_URL}/payment/session/session-result`,
|
||||
method: "POST",
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const errorMessages = Object.freeze({
|
|||
PASSENGER_SIDE_OPTIONS_REQUIRED: 'Please select window',
|
||||
WINDSHIELD_DAMAGE_TYPE_REQUIRED: 'Please select windshield damage',
|
||||
WINDSHIELD_CHIP_COUNT_REQUIRED: 'Please select chip(s)',
|
||||
WINDSHIELD_REPLACE_OPTIONS_REQUIRED: 'Please select windshield part',
|
||||
WINDSHIELD_REPLACE_OPTIONS_REQUIRED: 'Select all windshield parts that need to be replaced',
|
||||
REPLACE_OPTIONS_REQUIRED: 'Please select rear window type',
|
||||
STREET_ADDRESS_REQUIRED: 'Street Address is required.',
|
||||
CITY_REQUIRED: 'City is required.',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
const experimentUniverses = Object.freeze({
|
||||
ISS_FUNNEL: 'ISSFunnel',
|
||||
ISS_FEATURETOGGLE_AREFEES_HIDDEN: 'NextGenISS_FeatureToggle_AreFeesHidden',
|
||||
ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN: 'NextGenISS_FeatureToggle_AreFeesOverridden'
|
||||
ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN: 'NextGenISS_FeatureToggle_AreFeesOverridden',
|
||||
ADYEN_PAYMENT_TEST: 'NextGenAdyenPaymentTest'
|
||||
});
|
||||
|
||||
const experimentSettings = Object.freeze({
|
||||
|
|
@ -10,7 +11,8 @@ const experimentSettings = Object.freeze({
|
|||
ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN: 'HideMobileFee',
|
||||
ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'OverrideMobileFee',
|
||||
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN: 'HideRecycleFee',
|
||||
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'OverrideRecycleFee'
|
||||
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'OverrideRecycleFee',
|
||||
ISS_ENABLE_ADYEN_V1: 'ISS_Enable_Adyen_V1'
|
||||
});
|
||||
|
||||
const experimentTriggers = Object.freeze({
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const partNumberStrings = Object.freeze({
|
||||
RECYCLE_FEE: 'RECYCLE FEE'
|
||||
RECYCLE_FEE: 'RECYCLE FEE',
|
||||
LABOR2: 'LABOR2',
|
||||
});
|
||||
|
||||
export default partNumberStrings;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,14 @@ export const pageProgressMapper = {
|
|||
// No progress bar on this page
|
||||
percent: 0
|
||||
},
|
||||
'payment-page-adyen': {
|
||||
// No progress bar on this page
|
||||
percent: 0
|
||||
},
|
||||
'payment-return-adyen': {
|
||||
// No progress bar on this page
|
||||
percent: 0
|
||||
},
|
||||
'tpa-search': {
|
||||
percent: 80
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
const vehicleLookupAlertTypes = Object.freeze({
|
||||
NOT_FOUND: 'notFound',
|
||||
NOT_MATCHED: 'notMatched',
|
||||
NO_SERVICE: 'noService',
|
||||
TWO_IDENTICAL_YMM_MATCHED: 'twoIdenticalYMMMatched',
|
||||
PERFECT_MATCH: 'perfectMatch',
|
||||
NO_SERVICE: 'noService'
|
||||
PERFECT_MATCH: 'perfectMatch'
|
||||
});
|
||||
|
||||
export default vehicleLookupAlertTypes;
|
||||
|
|
|
|||
|
|
@ -11,22 +11,19 @@
|
|||
'hidden.bs.modal': onModalClosed,
|
||||
'shown.bs.modal': onModalOpened
|
||||
}">
|
||||
<div class="modal-dialog"
|
||||
:class="{
|
||||
'modal-dialog-edge': modalPosition === modalPositions.edge,
|
||||
'modal-dialog-centered': modalPosition === modalPositions.center
|
||||
}">
|
||||
<div class="modal-dialog">
|
||||
<div
|
||||
class="modal-content"
|
||||
role="dialog"
|
||||
aria-modal="true">
|
||||
<div class="modal-header mb-2 mt-2">
|
||||
<div class="modal-header">
|
||||
<span
|
||||
v-if="headerText"
|
||||
class="modal-title d-flex justify-content-center pb-0 w-100"
|
||||
class="modal-title d-flex pb-0 w-100"
|
||||
:innerHTML="headerText">
|
||||
</span>
|
||||
<button
|
||||
v-if="displayCloseButton"
|
||||
ref="closeButton"
|
||||
type="button"
|
||||
class="btn-close"
|
||||
|
|
@ -34,22 +31,30 @@
|
|||
@mousedown="closeModal"
|
||||
@keypress.space="closeModal"></button>
|
||||
</div>
|
||||
<div class="modal-body ps-5 pe-5 pb-5 pt-1">
|
||||
<div class="modal-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="modal-footer px-5 py-4">
|
||||
<div class="modal-footer">
|
||||
<buttonMain
|
||||
v-if="displayFooterButton"
|
||||
id="modalbtn"
|
||||
ref="modalButtonMain"
|
||||
:variant="buttonVariant"
|
||||
class="w-100"
|
||||
:buttonText="footerButtonText"
|
||||
pushToGA
|
||||
:variant="buttonVariant"
|
||||
:class="[
|
||||
(isButtonDisabled || isFooterButtonDisabled) &&
|
||||
'form-test-invalid'
|
||||
]"
|
||||
@clickEvent="validateAndEmit" />
|
||||
<textLink
|
||||
v-if="displayCloseLink"
|
||||
class="mt-4 mb-0"
|
||||
linkType="text"
|
||||
:text="closeLinkText"
|
||||
href="#!"
|
||||
@click="closeModal" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -60,12 +65,13 @@
|
|||
import ButtonMain from '@/ux-components/button-main/button-main.vue';
|
||||
import { Modal } from 'bootstrap';
|
||||
import { useForm } from 'vee-validate';
|
||||
import { modalPositions } from '@/constants/component-variants';
|
||||
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||
|
||||
export default {
|
||||
name: 'modal',
|
||||
components: {
|
||||
ButtonMain
|
||||
ButtonMain,
|
||||
textLink
|
||||
},
|
||||
props: {
|
||||
modalId: String,
|
||||
|
|
@ -82,13 +88,25 @@ export default {
|
|||
type: String,
|
||||
default: 'success'
|
||||
},
|
||||
modalPosition: {
|
||||
type: String,
|
||||
default: modalPositions.edge
|
||||
},
|
||||
allowInvalidSubmit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
displayFooterButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
displayCloseButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
displayCloseLink: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
closeLinkText: {
|
||||
type: String,
|
||||
default: 'Close window'
|
||||
}
|
||||
},
|
||||
emits: ['footer-button-event', 'isModalOpened'],
|
||||
|
|
@ -105,8 +123,7 @@ export default {
|
|||
modalId,
|
||||
meta,
|
||||
validate,
|
||||
resetForm,
|
||||
modalPositions
|
||||
resetForm
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -159,8 +176,12 @@ export default {
|
|||
@import "@/styles/ux-variables-svg-strings.scss";
|
||||
|
||||
.modal {
|
||||
top: auto;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding-right: 1rem;
|
||||
h5,
|
||||
strong,
|
||||
.subheader-text {
|
||||
|
|
@ -178,10 +199,11 @@ export default {
|
|||
}
|
||||
|
||||
.modal-title {
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
font-size: 1.25rem;
|
||||
line-height: 2rem;
|
||||
color: $black;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
|
|
@ -190,7 +212,7 @@ export default {
|
|||
bottom: 0;
|
||||
z-index: 5;
|
||||
border-radius: 0;
|
||||
background-color: $gray-100;
|
||||
justify-content: center;
|
||||
|
||||
> .navigation-link {
|
||||
color: $black;
|
||||
|
|
@ -205,10 +227,19 @@ export default {
|
|||
&.modal-component {
|
||||
.modal-dialog {
|
||||
display: flex;
|
||||
max-width: 47.9375rem;
|
||||
width: 37.5rem;
|
||||
max-width: unset;
|
||||
min-height: auto;
|
||||
.modal-content {
|
||||
box-shadow: 0px 1rem 3rem -1rem rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid;
|
||||
border-radius: 5px;
|
||||
overflow: auto;
|
||||
}
|
||||
.modal-content {
|
||||
margin: 1.5rem auto 0 auto;
|
||||
margin: 0 auto;
|
||||
.modal-body {
|
||||
padding: 0 1.5rem 0 1.5rem;
|
||||
.col {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
|
@ -217,6 +248,11 @@ export default {
|
|||
}
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 22px;
|
||||
}
|
||||
p {
|
||||
&:last-child {
|
||||
|
|
@ -233,51 +269,26 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
&.modal-dialog-edge {
|
||||
min-height: 100%;
|
||||
margin: 0 auto;
|
||||
align-items: flex-end;
|
||||
@include media-breakpoint-up(md) {
|
||||
align-items: inherit;
|
||||
width: 23.5rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform: translate(100%);
|
||||
}
|
||||
.modal-content {
|
||||
box-shadow: 0px 1rem 3rem -1rem rgba(0, 0, 0, 0.25);
|
||||
border-radius: 1.5rem 1.5rem 0 0;
|
||||
@include media-breakpoint-up(md) {
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.modal-dialog-centered {
|
||||
.modal-content {
|
||||
box-shadow: 0px 1rem 3rem -1rem rgba(0, 0, 0, 0.25);
|
||||
border-radius: 1.5rem;
|
||||
overflow: auto;
|
||||
}
|
||||
.modal-header {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.show .modal-dialog {
|
||||
&.modal-dialog-edge {
|
||||
@include media-breakpoint-up(md) {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
border-top: none;
|
||||
padding: .625rem 1.5rem 1.5rem 1.5rem;
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
background-color: $white;
|
||||
color: $blue;
|
||||
border-color: $blue;
|
||||
font-weight: 400;
|
||||
&:hover {
|
||||
background-color: $heritage-blue-secondary;
|
||||
color: $white;
|
||||
border-color: $heritage-blue-secondary;
|
||||
}
|
||||
&:active,
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $heritage-blue-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -286,6 +297,15 @@ export default {
|
|||
transition: opacity 0.25s linear;
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-down(md) {
|
||||
&.modal-component {
|
||||
.modal-dialog {
|
||||
width: auto;
|
||||
max-width: unset;
|
||||
margin: .625rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
body {
|
||||
.modal-backdrop {
|
||||
|
|
|
|||
164
src/helpers/adyen-helper.js
Normal file
164
src/helpers/adyen-helper.js
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
import { AdyenCheckout } from "@adyen/adyen-web/auto";
|
||||
import { useMainStore } from "@/store";
|
||||
import globalMethods from "@/global-methods";
|
||||
import endpoints from "@/constants/endpoints";
|
||||
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||
import { paymentMethods } from "@/constants/payment-method-constants";
|
||||
import applicationConfig from "@/constants/application-config";
|
||||
|
||||
export async function getSessionInfo(sessionId, encryptedSessionResult) {
|
||||
const order = useMainStore().order;
|
||||
const location = getLocationInfo(order);
|
||||
const workOrder = getWorkOrderLastSixDigits(order);
|
||||
const system = getSourceSystem();
|
||||
|
||||
const request = {
|
||||
sessionId: sessionId,
|
||||
sessionResult: encryptedSessionResult,
|
||||
zipCodeCtu: location.zipCodeCtu,
|
||||
workOrderNumber: workOrder,
|
||||
sourceSystem: system,
|
||||
};
|
||||
|
||||
const response = await globalMethods.callHttpClient({
|
||||
method: endpoints.GetAdyenSessionResult.method,
|
||||
endpoint: endpoints.GetAdyenSessionResult.url,
|
||||
payload: request,
|
||||
logApiCall: true
|
||||
});
|
||||
|
||||
return response?.data;
|
||||
}
|
||||
|
||||
export async function createAdyenCheckout({
|
||||
session: { id, sessionData },
|
||||
handlers: { onPaymentCompleted, onPaymentFailed, onError },
|
||||
options: { showPayButton = true, amount },
|
||||
}) {
|
||||
const config = {
|
||||
session: {
|
||||
id: id,
|
||||
sessionData: sessionData,
|
||||
},
|
||||
clientKey: applicationConfig.ADYEN_CLIENT_KEY,
|
||||
environment: applicationConfig.ADYEN_ENVIRONMENT,
|
||||
locale: "en_US",
|
||||
countryCode: "US",
|
||||
showPayButton: showPayButton,
|
||||
translations: {
|
||||
en_US: {
|
||||
"creditCard.securityCode.label": "CVV/CVC",
|
||||
},
|
||||
},
|
||||
onPaymentCompleted: onPaymentCompleted,
|
||||
onPaymentFailed: onPaymentFailed,
|
||||
onError: onError,
|
||||
};
|
||||
|
||||
if (amount !== undefined && amount !== null) {
|
||||
config.amount = {
|
||||
value: amount,
|
||||
currency: "USD",
|
||||
};
|
||||
}
|
||||
|
||||
return await AdyenCheckout(config);
|
||||
}
|
||||
|
||||
export function mapAdyenToIssPaymentMethod(adyenMethod) {
|
||||
const paymentMethodMap = {
|
||||
["scheme"]: paymentMethods.CREDIT_CARD,
|
||||
["afterpaytouch_US"]: paymentMethods.AFTERPAY,
|
||||
["paypal"]: paymentMethods.PAYPAL,
|
||||
["applepay"]: paymentMethods.APPLEPAY,
|
||||
};
|
||||
|
||||
const match = paymentMethodMap[adyenMethod];
|
||||
|
||||
return match ?? paymentMethods.CREDIT_CARD;
|
||||
}
|
||||
|
||||
export function mapIssToAdyenPaymentMethod(issMethod) {
|
||||
const paymentMethodMap = {
|
||||
[paymentMethods.CREDIT_CARD]: "scheme",
|
||||
[paymentMethods.AFTERPAY]: "afterpaytouch_US",
|
||||
[paymentMethods.PAYPAL]: "paypal",
|
||||
[paymentMethods.APPLEPAY]: "applepay",
|
||||
[paymentMethods.PayNow]: null,
|
||||
[paymentMethods.PAY_AT_TIME_OF_SERVICE]: null,
|
||||
};
|
||||
|
||||
const match = paymentMethodMap[issMethod];
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
export function generateCcToken(adyenSessionInfo) {
|
||||
const zipCode = useMainStore().order.customer.address.zipCode
|
||||
?? useMainStore().order.serviceLocation.zipCode
|
||||
?? useMainStore().order.serviceLocation.provider.address.zipCode
|
||||
|
||||
const ccToken = {
|
||||
subscriptionId: adyenSessionInfo?.storedToken,
|
||||
expMonth: adyenSessionInfo?.cardExpiryMonth,
|
||||
expYear: adyenSessionInfo?.cardExpiryYear,
|
||||
cardType: adyenSessionInfo?.cardType,
|
||||
billToPostalCode: zipCode,
|
||||
billToFirstName: useMainStore().contactInfo.firstName,
|
||||
billToLastName: useMainStore().contactInfo.lastName,
|
||||
referenceNumber: adyenSessionInfo?.workOrderNumber,
|
||||
authCode: adyenSessionInfo?.authCode,
|
||||
transactionId: adyenSessionInfo?.transactionReference,
|
||||
transReferenceNumber: adyenSessionInfo?.transactionReference,
|
||||
lastFour: adyenSessionInfo?.last4DigitsOfCard,
|
||||
};
|
||||
|
||||
return ccToken;
|
||||
}
|
||||
|
||||
function getLocationInfo(order) {
|
||||
const serviceLocation = order.serviceLocation;
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE ||
|
||||
serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
if (isMobile) {
|
||||
return {
|
||||
address: serviceLocation.address,
|
||||
address2: serviceLocation.address2,
|
||||
city: serviceLocation.city,
|
||||
state: serviceLocation.state,
|
||||
zipCode: serviceLocation.zipCode,
|
||||
zipCodeCtu: serviceLocation.zipCodeCtu,
|
||||
};
|
||||
} else {
|
||||
const providerInfo = serviceLocation.provider.address;
|
||||
return {
|
||||
address: providerInfo.streetAddress,
|
||||
address2: "",
|
||||
city: providerInfo.city,
|
||||
state: providerInfo.state,
|
||||
zipCode: providerInfo.zipCode,
|
||||
zipCodeCtu: providerInfo.zipCodeCtu,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getWorkOrderLastSixDigits(order) {
|
||||
const workOrderNumber = order.workOrderNumber ?? "";
|
||||
const tokens = workOrderNumber.split("-");
|
||||
const lastSegment = tokens[tokens.length - 1] ?? "";
|
||||
const numDigits = lastSegment.length;
|
||||
const numZeroes = 6 - numDigits;
|
||||
|
||||
let result = "";
|
||||
for (let i = 0; i < numZeroes; i++) {
|
||||
result += "0";
|
||||
}
|
||||
|
||||
result += lastSegment;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSourceSystem() {
|
||||
return "ISS-NextGen";
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ function canBailoutNavigateBack() {
|
|||
case BailoutCode.VehicleNotFound:
|
||||
case BailoutCode.RequestCallback:
|
||||
case BailoutCode.TPANotEnabled:
|
||||
case BailoutCode.CoverageCancelledByUser:
|
||||
case BailoutCode.HeavyTruckVehicle:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,21 @@
|
|||
export function supportsApplePay() {
|
||||
return !!(window.ApplePaySession && window.ApplePaySession.canMakePayments());
|
||||
var iOSversion = getiOSversion();
|
||||
var isMacOS = navigator.platform.indexOf("Mac") !== -1;
|
||||
if (isMacOS || (iOSversion && iOSversion[0] >= 17)) {
|
||||
if (window.ApplePaySession && window.ApplePaySession.canMakePayments()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function getiOSversion() {
|
||||
if (/iP(hone|od|ad)/.test(navigator.platform)) {
|
||||
// supports iOS 2.0 and later:
|
||||
var v = navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/);
|
||||
if (!v) {
|
||||
return null;
|
||||
}
|
||||
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ export function getDeviceIdValue() {
|
|||
Gets value of skey cookie, returns 0 if not found.
|
||||
*/
|
||||
export function getSessionKeyValue() {
|
||||
const cookieValue = getCookieValueByName(cookieNames.SESSION_KEY);
|
||||
const cookieValue = getCookieValueByName(cookieNames.ISS_SESSION_KEY);
|
||||
|
||||
if (cookieValue) {
|
||||
return cookieValue;
|
||||
|
|
@ -281,7 +281,7 @@ export function setSessionIdIfUnset(value) {
|
|||
}
|
||||
|
||||
export function setSessionKeyIfUnset(value) {
|
||||
if (!isCookieSet(cookieNames.ISS_SESSION_KEY)) {
|
||||
if (getSessionKeyValue() === 0) {
|
||||
setCookieProperties(
|
||||
{
|
||||
[cookieNames.ISS_SESSION_KEY]: value
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ Object {
|
|||
"salesTax": "SalesTaxWidget",
|
||||
"servicePackage": "ServicePackageTitle",
|
||||
"subtotal": "SubtotalWidget",
|
||||
"total": "TotalWidget",
|
||||
"vapsItemDescriptions": "VapsItemDescriptions",
|
||||
"warrantyText": "WarrantyCartItemTextWidget",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/serv
|
|||
import { getPriceOfLineItems } from '@/helpers/price-calculator.js';
|
||||
import coverageStatuses from '@/constants/coverage-statuses';
|
||||
import coverageType from '@/constants/coverage-type';
|
||||
import * as cartHelper from '@/helpers/cart-helper';
|
||||
|
||||
const VERIFYING_COVERAGE = 'Verifying coverage';
|
||||
|
||||
|
|
@ -341,21 +342,76 @@ describe('cart-dropdown component', () => {
|
|||
});
|
||||
describe('computed', () => {
|
||||
describe('amountDue', () => {
|
||||
test('returns 0 when showAsPaid is true', () => {
|
||||
test('returns total when showAsPaid is false', () => {
|
||||
// Arrange
|
||||
const expectedAmount = 123.45;
|
||||
const propsData = {
|
||||
showAsPaid: true
|
||||
showAsPaid: false
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, propsData);
|
||||
const totalSpy = jest.spyOn(cartHelper, 'getCartTotal').mockReturnValue(expectedAmount);
|
||||
|
||||
// Act
|
||||
const result = wrapper.vm.amountDue;
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(expectedAmount);
|
||||
});
|
||||
test('returns total minus amount paid when showAsPaid is true', () => {
|
||||
// Arrange
|
||||
const total = 123.45;
|
||||
const amountPaid = 23.45;
|
||||
const expectedAmount = total - amountPaid;
|
||||
const propsData = {
|
||||
showAsPaid: true
|
||||
};
|
||||
const storeData = {
|
||||
order: {
|
||||
settledTenderAmount: amountPaid
|
||||
}
|
||||
};
|
||||
const { wrapper } = getMountedComponent(storeData, {}, propsData);
|
||||
const totalSpy = jest.spyOn(cartHelper, 'getCartTotal').mockReturnValue(total);
|
||||
|
||||
// Act
|
||||
const result = wrapper.vm.amountDue;
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(expectedAmount);
|
||||
});
|
||||
});
|
||||
describe('amountPaid', () => {
|
||||
test('returns 0 when showAsPaid is false', () => {
|
||||
// Arrange
|
||||
const propsData = {
|
||||
showAsPaid: false
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, propsData);
|
||||
|
||||
// Act
|
||||
const result = wrapper.vm.amountPaid;
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
test('returns sum of subTotal and salesTax when showAsPaid is false', () => {
|
||||
// TODO when subTotal and salesTax are finished
|
||||
test('returns settled tender amount when showAsPaid is true', () => {
|
||||
// Arrange
|
||||
const expectedAmount = 123.45;
|
||||
const propsData = {
|
||||
showAsPaid: true
|
||||
};
|
||||
const storeData = {
|
||||
order: {
|
||||
settledTenderAmount: expectedAmount
|
||||
}
|
||||
};
|
||||
const { wrapper } = getMountedComponent(storeData, {}, propsData);
|
||||
|
||||
// Act
|
||||
const result = wrapper.vm.amountPaid;
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(expectedAmount);
|
||||
});
|
||||
});
|
||||
describe('availableLineItems', () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="!isDeductibleOnly"
|
||||
v-if="!isDeductibleOnly || showAsPaid"
|
||||
class="cart-table">
|
||||
<div class="cart-item-list">
|
||||
<div
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
id="cart-footer"
|
||||
class="cart-footer">
|
||||
<div
|
||||
v-if="!isUnverified"
|
||||
v-if="!isUnverified && !isDeductibleOnly"
|
||||
id="cart-subtotal-and-tax"
|
||||
class="subtotal-and-tax">
|
||||
<div
|
||||
|
|
@ -68,12 +68,23 @@
|
|||
<span id="sales-tax-label">{{ salesTaxLabel }}</span>
|
||||
<span id="sales-tax-value">{{ formatAmountInDollars(salesTax) }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="showAsPaid"
|
||||
id="cart-amount-paid"
|
||||
class="py-2 col d-flex justify-content-between">
|
||||
</div>
|
||||
<div
|
||||
v-if="showAsPaid"
|
||||
id="cart-total"
|
||||
class="cart-item">
|
||||
<div class="price-row">
|
||||
<span id="total-label">{{ totalLabel }}</span>
|
||||
<span id="total-value">{{ getDisplayed(total) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="showAsPaid"
|
||||
id="cart-amount-paid"
|
||||
class="cart-item">
|
||||
<div class="price-row">
|
||||
<span id="amount-paid-label">{{ amountPaidLabel }}</span>
|
||||
<span if="amount-paid-value">{{ getDisplayed(amountPaid) }}</span>
|
||||
<span id="amount-paid-value">{{ getDisplayed(amountPaid) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -111,7 +122,7 @@ import {
|
|||
getServiceLineItems, getSubtotal, isOrderITAC, isOrderNoComp,
|
||||
isOrderUnverified
|
||||
} from '@/helpers/cart-helper';
|
||||
import { getPriceOfLineItems, getTaxOfLineItems } from '@/helpers/price-calculator';
|
||||
import { getPriceOfLineItem, getPriceOfLineItems, getTaxOfLineItems } from '@/helpers/price-calculator';
|
||||
import { processIfStatements } from '@/helpers/cms-content-helper';
|
||||
|
||||
const VERIFYING_COVERAGE = 'Verifying coverage';
|
||||
|
|
@ -141,7 +152,8 @@ export default {
|
|||
servicePackage: 'ServicePackageTitle',
|
||||
vapsItemDescriptions: 'VapsItemDescriptions',
|
||||
warrantyText: 'WarrantyCartItemTextWidget',
|
||||
guaranteeText: 'GuaranteeCartItemTextWidget'
|
||||
guaranteeText: 'GuaranteeCartItemTextWidget',
|
||||
total: 'TotalWidget'
|
||||
},
|
||||
cartItemType
|
||||
};
|
||||
|
|
@ -176,7 +188,8 @@ export default {
|
|||
},
|
||||
servicePrice() {
|
||||
const price = getPriceOfLineItems(getServiceLineItems(this.cartOrder)) ?? 0;
|
||||
return price - this.recalibrationPrice;
|
||||
const recycleFee = this.recycleFeeLineItem ? getPriceOfLineItem(this.recycleFeeLineItem) : 0;
|
||||
return price - this.recalibrationPrice - recycleFee;
|
||||
},
|
||||
isUnverified() {
|
||||
return isOrderUnverified(this.cartOrder);
|
||||
|
|
@ -198,10 +211,10 @@ export default {
|
|||
return getCartTotal(this.cartOrder);
|
||||
},
|
||||
amountDue() {
|
||||
return this.showAsPaid ? 0 : this.total;
|
||||
return this.total - this.amountPaid;
|
||||
},
|
||||
amountPaid() {
|
||||
return !this.showAsPaid ? 0 : this.total;
|
||||
return !this.showAsPaid ? 0 : this.cartOrder.settledTenderAmount;
|
||||
},
|
||||
availableLineItems() {
|
||||
const { supportingItems, glassParts, otherParts, feeItems } = this.lineItems;
|
||||
|
|
@ -278,6 +291,9 @@ export default {
|
|||
salesTaxLabel() {
|
||||
return this.getCmsContent(this.widget.salesTax, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
totalLabel() {
|
||||
return this.getCmsContent(this.widget.total, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
recycleFeeCartItem() {
|
||||
return this.recycleFeeLineItem
|
||||
? this.getCartItem(
|
||||
|
|
@ -350,6 +366,7 @@ export default {
|
|||
removeVap(partType) {
|
||||
const newVaps = useMainStore().lineItems.vaps?.filter((vap) => vap?.partType !== partType) ?? [];
|
||||
useMainStore().updateVaps(newVaps);
|
||||
useMainStore().updateServicePackage(null);
|
||||
},
|
||||
getCmsContentForVapsType(vapsPartType) {
|
||||
const vapsItemDescriptions = this.getCmsContent(
|
||||
|
|
@ -414,6 +431,10 @@ export default {
|
|||
a:hover {
|
||||
color: $heritage-blue-secondary;
|
||||
}
|
||||
|
||||
#amount-paid-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-footer {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,6 @@ Object {
|
|||
"firstName": "Frederick",
|
||||
"isModalOpened": false,
|
||||
"lastName": "Taylor",
|
||||
"modalPositions": Object {
|
||||
"center": "center",
|
||||
"edge": "edge",
|
||||
},
|
||||
"phoneNumber": "606-009-2943",
|
||||
"rules": Object {
|
||||
"emailAddress": "email-required|email-address-format",
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
<template>
|
||||
<modal
|
||||
:ref="modalName"
|
||||
:modalPosition="modalPositions.center"
|
||||
:headerText="headerText"
|
||||
:footerButtonText="footerButtonText"
|
||||
:onModalClosedCallback="resetFormValues"
|
||||
:displayCloseLink="true"
|
||||
:closeLinkText="closeLinkText"
|
||||
class="contact-details-drawer"
|
||||
@isModalOpened="setModalStatus"
|
||||
@footerButtonEvent="clickFooterButtonEvent">
|
||||
<template v-if="isModalOpened">
|
||||
<span class="name-section-label">{{ nameSectionLabel }}</span>
|
||||
<div class="name-section-label">{{ nameSectionLabel }}</div>
|
||||
<div class="row form-group">
|
||||
<textboxQuestion
|
||||
class="col-lg-6"
|
||||
|
|
@ -71,7 +72,6 @@ import { useMainStore } from '@/store';
|
|||
import globalRules from '@/constants/global-rules.js';
|
||||
import MaskaFormattedMasks from '@/constants/maska-masks';
|
||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||
import { modalPositions } from '@/constants/component-variants';
|
||||
|
||||
export default {
|
||||
name: 'contact-details-drawer',
|
||||
|
|
@ -109,7 +109,6 @@ export default {
|
|||
phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`,
|
||||
extension: `${globalRules.EXTENSION_FORMAT}`
|
||||
},
|
||||
modalPositions,
|
||||
detailsSaved: false
|
||||
};
|
||||
},
|
||||
|
|
@ -132,6 +131,9 @@ export default {
|
|||
nameSectionLabel() {
|
||||
return this.getCmsContent(this.widget.firstNameQuestion, widgetFields.INPUT_QUESTION_WIDGET.QUESTION_TEXT);
|
||||
},
|
||||
closeLinkText() {
|
||||
return this.getCmsContent(this.widget.drawerFooter, widgetFields.FOOTER_WIDGET.BACK_BUTTON_TEXT);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setModalStatus(isOpened) {
|
||||
|
|
@ -203,5 +205,58 @@ export default {
|
|||
margin-top: .625rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.modal-dialog) {
|
||||
.modal-content {
|
||||
padding: 1.25rem 1.25rem 0;
|
||||
.modal-header {
|
||||
padding: 0;
|
||||
|
||||
.modal-title {
|
||||
padding: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding: 0rem;
|
||||
|
||||
button {
|
||||
background-color: $heritage-blue-primary;
|
||||
color: $white;
|
||||
font-weight: 600;
|
||||
width: 10.75rem;
|
||||
margin-bottom: 1.25rem;
|
||||
|
||||
&:hover {
|
||||
background-color: #00559e;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
margin: .5rem 0 0;
|
||||
font-weight: $font-weight-normal;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(lg) {
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@
|
|||
@footerButtonEvent="footerButtonClick">
|
||||
<img
|
||||
:src="ModalImage"
|
||||
class="mw-100 d-flex mx-auto mb-4"
|
||||
class="mw-100 d-flex"
|
||||
:class="imgClass"
|
||||
alt="" />
|
||||
<h5
|
||||
class="mb-4"
|
||||
class="header-text"
|
||||
:class="cssModalHeadlineClass"
|
||||
v-html="ModalHeadline"></h5>
|
||||
<p
|
||||
class="fw-bold mb-2 subheader-text"
|
||||
class="fw-bold subheader-text"
|
||||
v-html="ModalSubheadertext"></p>
|
||||
<p
|
||||
class="mb-0"
|
||||
|
|
@ -59,7 +60,13 @@ export default {
|
|||
},
|
||||
ModalCloseButtonText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||
}
|
||||
},
|
||||
imgClass() {
|
||||
if (this.cmsWidgetName === 'RainDefenseModal') {
|
||||
return 'rain-repel';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
|
|
@ -79,6 +86,10 @@ export default {
|
|||
.modal-dialog {
|
||||
.modal-content {
|
||||
.modal-body {
|
||||
.header-text {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.modal-sub-body {
|
||||
color: $gray-600;
|
||||
}
|
||||
|
|
@ -100,4 +111,7 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
.rain-repel {
|
||||
height: 3.5rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -8,18 +8,23 @@
|
|||
:headerText="modalHeaderText"
|
||||
:footerButtonText="modalFooterText"
|
||||
buttonVariant="primary"
|
||||
:displayCloseButton="false"
|
||||
@isModalOpened="setModalStatus"
|
||||
@footerButtonEvent="startNewReferral">
|
||||
<p class="mb-2 subheader-text text-center">
|
||||
<p class="continue-subheader">
|
||||
{{ modalSubHeaderText }}
|
||||
</p>
|
||||
<buttonMain
|
||||
id="btnContinueReferral"
|
||||
variant="success"
|
||||
class="mt-2 w-100"
|
||||
class="continue-btn w-100"
|
||||
:buttonText="modalBodyText"
|
||||
@click-event="continueReferral">
|
||||
</buttonMain>
|
||||
<div class="or-container">
|
||||
<hr/>
|
||||
<span>or</span>
|
||||
</div>
|
||||
</modal>
|
||||
</div>
|
||||
</transition>
|
||||
|
|
@ -58,7 +63,7 @@ export default {
|
|||
},
|
||||
modalSubHeaderText() {
|
||||
return this.getCmsContent('ContinueReferralModalWidget', 'SubheaderText')
|
||||
.replaceAll('{custom:mmFound}', this.getMakeModelString);
|
||||
.replaceAll('{custom:mmFound}', this.getMakeModelString.toUpperCase());
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -82,5 +87,64 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.continue-modal-container {
|
||||
.continue-subheader {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.continue-btn {
|
||||
background-color: #098649;
|
||||
}
|
||||
|
||||
.or-container {
|
||||
position: relative;
|
||||
hr {
|
||||
margin: 1.875rem 0 1.25rem;
|
||||
}
|
||||
span {
|
||||
position: absolute;
|
||||
top: -0.75rem;
|
||||
left: 50%;
|
||||
margin-left: -1.625rem;
|
||||
padding: 0 1.125rem;
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.modal) {
|
||||
.modal-dialog {
|
||||
.modal-content {
|
||||
.modal-header {
|
||||
padding: 1.25rem 1rem .625rem;
|
||||
|
||||
.modal-title {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 0rem 1rem;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 0rem 1rem 1rem;
|
||||
|
||||
button {
|
||||
background-color: $heritage-blue-primary;
|
||||
color: $white;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1.25rem;
|
||||
|
||||
&:hover {
|
||||
background-color: #00559e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-down(md) {
|
||||
margin: 1.625rem 1rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ export default {
|
|||
}
|
||||
},
|
||||
async beforeMount() {
|
||||
await this.createMapWithMarkersForAddresses(this.markers);
|
||||
await this.createMapWithMarkersForAddresses(this.markers)
|
||||
.catch(() => {
|
||||
console.error('Error creating map with markers: if handled jest fails to run tests');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async getMap(center) {
|
||||
|
|
|
|||
|
|
@ -124,13 +124,7 @@ export default {
|
|||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
@include media-breakpoint-up(xs) {
|
||||
padding-top: 5rem;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
padding-top: 7rem;
|
||||
}
|
||||
padding: 2rem;
|
||||
|
||||
.modal-loader-content-container {
|
||||
min-width: 15rem; // 240px
|
||||
|
|
|
|||
101
src/iss-components/recal-modal/recal-modal.vue
Normal file
101
src/iss-components/recal-modal/recal-modal.vue
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<div class="recal-modal-container">
|
||||
<modal
|
||||
ref="recalModal"
|
||||
:footerButtonText="modalCloseButtonText"
|
||||
@footerButtonEvent="footerButtonClick">
|
||||
<h5
|
||||
class="header-text"
|
||||
v-html="modalHeaderText"></h5>
|
||||
<img
|
||||
:src="modalImage"
|
||||
class="mw-100 d-flex"
|
||||
alt="" />
|
||||
<div v-html="modalBodyText" class="recal-modal-body"></div>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from '@/digital-components/modal/modal.vue';
|
||||
|
||||
export default {
|
||||
name: 'recal-modal',
|
||||
components: {
|
||||
modal
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: {
|
||||
type: String,
|
||||
default: 'RecalModal'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
modalBodyText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'BodyText').replaceAll('{custom:vehicleMake}', this.vehicleMake);
|
||||
},
|
||||
modalHeaderText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||
},
|
||||
modalImage() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'Image');
|
||||
},
|
||||
modalCloseButtonText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||
},
|
||||
vehicleMake() {
|
||||
return this.mainStore.order.vehicle.make.toUpperCase();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
this.$refs.recalModal.openModal();
|
||||
},
|
||||
footerButtonClick() {
|
||||
this.$refs.recalModal.closeModal();
|
||||
},
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.modal) {
|
||||
&.modal-component {
|
||||
.modal-dialog {
|
||||
.modal-content {
|
||||
.modal-body {
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
button {
|
||||
&:hover {
|
||||
background-color: $white;
|
||||
color: $heritage-blue-secondary;
|
||||
}
|
||||
&:focus, &:active {
|
||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $heritage-blue-secondary;
|
||||
}
|
||||
font-weight: 600;
|
||||
color: $heritage-blue-secondary;
|
||||
border-color: $heritage-blue-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
.recal-modal-body {
|
||||
padding: 10px 0 10px 0;
|
||||
p:first-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
p {
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
'form-test-invalid': (disableForwardAction || isForwardActionDisabled),
|
||||
'hide-button': isForwardButtonHidden
|
||||
}"
|
||||
:aria-disabled="disableForwardAction || isForwardActionDisabled"
|
||||
:isDisabled="disableForwardAction || isForwardActionDisabled"
|
||||
:isDisabled="disableForwardAction || isForwardActionDisabled || isForwardButtonHidden"
|
||||
data-test-id="site-footer-main-button"
|
||||
buttonType="submit"
|
||||
@clickEvent="buttonClick" />
|
||||
</div>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -466,76 +466,5 @@ describe('address-lookup.vue', () => {
|
|||
// Assert
|
||||
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('selected vehicle is a non-serviceable big truck, display no service alert', async () => {
|
||||
// Arrange
|
||||
const mockRegistrationAddress = {
|
||||
streetAddress: '1234 Main St',
|
||||
city: 'Columbus',
|
||||
state: 'OH',
|
||||
zipCode: '43215'
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({
|
||||
vinVehicles: [
|
||||
{
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKCARID',
|
||||
isBigTruck: true,
|
||||
canSafeliteService: false
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
useMainStore().order.vehicle.carId = 'BIGTRUCKCARID';
|
||||
|
||||
await wrapper.setData({
|
||||
customerQuestions: {
|
||||
addressQuestions: mockRegistrationAddress
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'alertNoService' }).isVisible()).toBe(true);
|
||||
});
|
||||
test('selected vehicle is a serviceable big truck, do not display no service alert', async () => {
|
||||
// Arrange
|
||||
const mockRegistrationAddress = {
|
||||
streetAddress: '1234 Main St',
|
||||
city: 'Columbus',
|
||||
state: 'OH',
|
||||
zipCode: '43215'
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({
|
||||
vinVehicles: [
|
||||
{
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKCARID2',
|
||||
isBigTruck: true,
|
||||
canSafeliteService: true
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
useMainStore().order.vehicle.carId = 'BIGTRUCKCARID2';
|
||||
|
||||
await wrapper.setData({
|
||||
customerQuestions: {
|
||||
addressQuestions: mockRegistrationAddress
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'alertNoService' }).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -55,14 +55,6 @@
|
|||
alertClass="alert-danger"
|
||||
:isCollapsible="true"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayNoServiceAlert"
|
||||
ref="alertNoService"
|
||||
class="mt-5"
|
||||
cmsWidgetName="AlertNoServiceWidget"
|
||||
alertClass="alert-danger"
|
||||
:isCollapsible="true"
|
||||
:isDismissable="false" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
|
|
@ -142,8 +134,7 @@ export default {
|
|||
isCarIdDifferent: false,
|
||||
isSelectedGlassAvailableForVehicle: true,
|
||||
customAlertData: {},
|
||||
forwardButtonCarStyle: '',
|
||||
displayNoServiceAlert: false
|
||||
forwardButtonCarStyle: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -224,6 +215,7 @@ export default {
|
|||
|
||||
async forwardButtonAction() {
|
||||
this.resetWarningsAndErrors();
|
||||
useMainStore().resetBailout();
|
||||
|
||||
// Vehicle info change in the flow, use a variable to keep track and commit to state at the end.
|
||||
let vehicleInfoToCommit = {};
|
||||
|
|
@ -261,9 +253,8 @@ export default {
|
|||
const carFound = carsFound[0].vehicle;
|
||||
|
||||
if (!carFound.canSafeliteService) {
|
||||
this.displayNoServiceAlert = true;
|
||||
showIssLoadingModal(false);
|
||||
return this.$refs.siteFooter.disableForwardButton();
|
||||
this.mainStore.setBailout(bailoutMessage.HeavyTruckVehicle(carFound.carId));
|
||||
return this.$router.push({ name: 'bailout' });
|
||||
}
|
||||
|
||||
this.isCarIdDifferent = carFound.carId !== useMainStore().order.vehicle.carId;
|
||||
|
|
@ -371,7 +362,6 @@ export default {
|
|||
this.displayVinNotFoundAlert = false;
|
||||
this.displayMatchedDifferentVehicleAlert = false;
|
||||
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
||||
this.displayNoServiceAlert = false;
|
||||
this.$refs.siteFooter.enableForwardAction();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ describe('address-vehicles.vue', () => {
|
|||
const { wrapper } = setupMocks({});
|
||||
const lookupVinResponse = {
|
||||
data: {
|
||||
carId: '456'
|
||||
carId: '456',
|
||||
canSafeliteService: true
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -247,94 +248,4 @@ describe('address-vehicles.vue', () => {
|
|||
// Assert
|
||||
expect(arePagePrerequisitesValid).toBe(true);
|
||||
});
|
||||
|
||||
test('selected vehicle is a non-serviceable big truck, display no service alert', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
useMainStore().order.vehicle.carId = 'BIGTRUCKCARID';
|
||||
useMainStore().applicationUser = {
|
||||
pageData: {
|
||||
'address-vehicles':
|
||||
[
|
||||
{
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKCARID',
|
||||
make: 'Isuzu',
|
||||
model: 'Reach',
|
||||
style: 'Step Van',
|
||||
year: 2016,
|
||||
isBigTruck: true,
|
||||
canSafeliteService: false
|
||||
},
|
||||
vin: 'BIGTRUCKVIN'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: 'BIGTRUCKVIN',
|
||||
previouslyEnteredCarId: 'BIGTRUCKCARID'
|
||||
});
|
||||
|
||||
wrapper.vm.selectedVehicle = {
|
||||
vin: 'BIGTRUCKVIN',
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKCARID',
|
||||
isBigTruck: true,
|
||||
canSafeliteService: false
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'AlertNoService' }).isVisible()).toBe(true);
|
||||
});
|
||||
|
||||
test('selected vehicle is a serviceable big truck, do not display no service alert', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
useMainStore().order.vehicle.carId = 'BIGTRUCKCARID2';
|
||||
useMainStore().applicationUser = {
|
||||
pageData: {
|
||||
'address-vehicles':
|
||||
[
|
||||
{
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKCARID2',
|
||||
make: 'Mack',
|
||||
model: 'Terrapro',
|
||||
style: 'Cabover',
|
||||
year: 2024,
|
||||
isBigTruck: true,
|
||||
canSafeliteService: true
|
||||
},
|
||||
vin: 'BIGTRUCKVIN2'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: 'BIGTRUCKVIN2',
|
||||
previouslyEnteredCarId: 'BIGTRUCKCARID2'
|
||||
});
|
||||
|
||||
wrapper.vm.selectedVehicle = {
|
||||
vin: 'BIGTRUCKVIN2',
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKCARID2',
|
||||
isBigTruck: true,
|
||||
canSafeliteService: true
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'AlertNoService' }).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,13 +13,6 @@
|
|||
<siteSubHeader
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
class="mt-4" />
|
||||
<alert
|
||||
v-if="displayNoServiceAlert"
|
||||
ref="AlertNoService"
|
||||
class="mt-5"
|
||||
cmsWidgetName="AlertVehicleSelection"
|
||||
alertClass="alert-danger"
|
||||
:isDismissable="false" />
|
||||
<addressVehiclesQuestion
|
||||
ref="addressVehiclesQuestion"
|
||||
v-model="selectedVehicleVin"
|
||||
|
|
@ -91,6 +84,7 @@ import {
|
|||
} from '@/helpers/cms-content-helper.js';
|
||||
import routerParams from '@/router/router-constants/router-params';
|
||||
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
|
||||
// Import Component
|
||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||
|
|
@ -147,8 +141,7 @@ export default {
|
|||
displayMatchedDifferentVehicleAlert: false,
|
||||
displayMatchedTwoIdenticalYMMVehicleAlert: false,
|
||||
previouslyEnteredCarId: '',
|
||||
forwardButtonCarStyle: '',
|
||||
displayNoServiceAlert: false
|
||||
forwardButtonCarStyle: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -203,10 +196,6 @@ export default {
|
|||
selectedVehicleVin: {
|
||||
handler() {
|
||||
this.resetWarningsAndErrors();
|
||||
if (!this.selectedVehicle?.vehicle.canSafeliteService) {
|
||||
this.displayNoServiceAlert = true;
|
||||
return this.$refs.siteFooter.disableForwardButton();
|
||||
}
|
||||
// does this vehicle match the previously selected carId?
|
||||
this.isCarIdDifferent =
|
||||
this.selectedVehicle?.vehicle.carId
|
||||
|
|
@ -242,10 +231,19 @@ export default {
|
|||
return false;
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
this.mainStore.resetBailout();
|
||||
const vinLookup = await useMainStore().lookupVehicleByVin(this.selectedVehicle.vin);
|
||||
if (!vinLookup) {
|
||||
return;
|
||||
}
|
||||
if (vinLookup.data?.canSafeliteService === false) {
|
||||
this.mainStore.setBailout(bailoutMessage.HeavyTruckVehicle(vinLookup.data.carId));
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.BAILOUT,
|
||||
this.$route
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
|
||||
await useMainStore().saveVin(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -204,7 +204,9 @@ export default {
|
|||
methods: {
|
||||
backButtonAction() {
|
||||
// route to move backwards
|
||||
this.mainStore.resetBailout();
|
||||
if (this.bailout.bailoutCode !== BailoutCode.HeavyTruckVehicle) {
|
||||
this.mainStore.resetBailout();
|
||||
}
|
||||
this.$router.navigateWithSpinner(
|
||||
this.navigationScenarios.CLICKED_BACK_PREVIOUS,
|
||||
this.$route
|
||||
|
|
|
|||
|
|
@ -10,11 +10,69 @@ import { getRandomString, getRandomInt, getRandomBoolean } from '@/helpers/data-
|
|||
import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
|
||||
import { useMainStore } from '@/store/index.js';
|
||||
|
||||
/** @ignore */
|
||||
function setupMocks({
|
||||
storeData,
|
||||
props
|
||||
}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn(),
|
||||
navigateWithSpinner: jest.fn()
|
||||
},
|
||||
loadScript: jest.fn().mockResolvedValue()
|
||||
});
|
||||
|
||||
if (storeData) mountOptions.global.plugins = [createTestingPinia({
|
||||
initialState: {
|
||||
main: storeData
|
||||
}
|
||||
})];
|
||||
|
||||
window.google = {
|
||||
maps: {
|
||||
event: {
|
||||
addListener: jest
|
||||
.fn()
|
||||
.mockImplementation((element, eventName, callbackFunction) => {
|
||||
/** @ignore */
|
||||
function interceptedCallbackFunction(e) {
|
||||
callbackFunction(e.detail);
|
||||
}
|
||||
// selectedPlace = "Woogly";
|
||||
element.addEventListener(eventName, interceptedCallbackFunction);
|
||||
}),
|
||||
removeListener: jest.fn(),
|
||||
clearInstanceListeners: jest.fn()
|
||||
},
|
||||
places: {
|
||||
Autocomplete: jest.fn().mockImplementation((el) => el),
|
||||
AutocompleteService: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
getPlacePredictions: (request, callback) => {
|
||||
// Throwing an error here guarantees that the function that calls it finishes
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
}),
|
||||
PlacesService: jest.fn().mockImplementation(() => {}),
|
||||
AutocompleteSessionToken: jest.fn().mockImplementation(() => {})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (props) mountOptions.propsData = props;
|
||||
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('contactDetails.vue', () => {
|
||||
describe('Rendering', () => {
|
||||
test('Should render site header', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const siteHeader = wrapper.findComponent({ ref: 'siteHeader' });
|
||||
|
|
@ -24,7 +82,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render sub title', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const siteSubHeader = wrapper.findComponent({ ref: 'siteSubHeader' });
|
||||
|
|
@ -34,7 +92,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render appointment information alert', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const appointmentInformationAlert = wrapper.findComponent({ ref: 'appointmentInformationAlert' });
|
||||
|
|
@ -44,8 +102,6 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render same as policy address question subcomponent if service zip is same as customer zip', async () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions();
|
||||
|
||||
const customerStreetAddress = getRandomString(10, 50);
|
||||
const customerStreetAddress2 = getRandomString(0, 50);
|
||||
const customerCity = getRandomString(4, 20);
|
||||
|
|
@ -55,7 +111,7 @@ describe('contactDetails.vue', () => {
|
|||
const serviceCity = getRandomString(4, 20);
|
||||
const serviceState = getRandomString(2, 2);
|
||||
const zipCode = getRandomInt(10000, 99999).toString();
|
||||
const mainInitialState = {
|
||||
const storeData = {
|
||||
order: {
|
||||
customer: {
|
||||
address: {
|
||||
|
|
@ -75,12 +131,7 @@ describe('contactDetails.vue', () => {
|
|||
}
|
||||
}
|
||||
};
|
||||
mountOptions.global.plugins = [createTestingPinia({
|
||||
initialState: {
|
||||
main: mainInitialState
|
||||
}
|
||||
})];
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
const { wrapper } = setupMocks({ storeData });
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
|
|
@ -92,8 +143,6 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should not render same as policy address question subcomponent if service zip is different from customer zip', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions();
|
||||
|
||||
const firstName = getRandomString(4, 15);
|
||||
const lastName = getRandomString(4, 15);
|
||||
const emailAddress = getRandomString(10, 20);
|
||||
|
|
@ -101,7 +150,7 @@ describe('contactDetails.vue', () => {
|
|||
const testZipCode = getRandomInt(10000, 99999);
|
||||
const customerZipCode = testZipCode.toString();
|
||||
const serviceZipCode = (testZipCode + 1).toString();
|
||||
const mainInitialState = {
|
||||
const storeData = {
|
||||
order: {
|
||||
customer: {
|
||||
firstName,
|
||||
|
|
@ -119,12 +168,7 @@ describe('contactDetails.vue', () => {
|
|||
}
|
||||
}
|
||||
};
|
||||
mountOptions.global.plugins = [createTestingPinia({
|
||||
initialState: {
|
||||
main: mainInitialState
|
||||
}
|
||||
})];
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
const { wrapper } = setupMocks({ storeData });
|
||||
|
||||
// Act
|
||||
const sameAsPolicyAddressQuestion = wrapper.findComponent({ ref: 'sameAsPolicyAddressQuestion' });
|
||||
|
|
@ -134,7 +178,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render address question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const addressQuestion = wrapper.findComponent({ ref: 'addressQuestion' });
|
||||
|
|
@ -144,7 +188,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render apartment question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const address2Question = wrapper.findComponent({ ref: 'address2Question' });
|
||||
|
|
@ -154,7 +198,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render city question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const cityQuestion = wrapper.findComponent({ ref: 'cityQuestion' });
|
||||
|
|
@ -164,7 +208,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render state question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const stateQuestion = wrapper.findComponent({ ref: 'stateQuestion' });
|
||||
|
|
@ -174,7 +218,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render zip code question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const zipCodeQuestion = wrapper.findComponent({ ref: 'zipCodeQuestion' });
|
||||
|
|
@ -184,7 +228,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render change zip code alert', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const changeZipCodeAlert = wrapper.findComponent({ ref: 'changeZipCodeAlert' });
|
||||
|
|
@ -194,7 +238,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render vehicle protected question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const vehicleProtectedQuestion = wrapper.findComponent({ ref: 'vehicleProtectedQuestion' });
|
||||
|
|
@ -204,7 +248,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render technician notes textarea question subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const notesQuestion = wrapper.findComponent({ ref: 'notesQuestion' });
|
||||
|
|
@ -214,7 +258,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render clearance text subcomponent', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const clearanceText = wrapper.findComponent({ ref: 'clearanceText' });
|
||||
|
|
@ -224,7 +268,7 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Should render site footer', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions());
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
const footer = wrapper.findComponent({ ref: 'siteFooter' });
|
||||
|
|
@ -234,8 +278,6 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
test('Mocked store yields expected data', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions();
|
||||
|
||||
const address = getRandomString(10, 50);
|
||||
const address2 = getRandomString(0, 50);
|
||||
const city = getRandomString(4, 20);
|
||||
|
|
@ -243,7 +285,7 @@ describe('contactDetails.vue', () => {
|
|||
const zipCode = getRandomInt(10000, 99999).toString();
|
||||
const notesForTechnician = getRandomString(1, 100);
|
||||
const isVehicleProtected = getRandomBoolean();
|
||||
const mainInitialState = {
|
||||
const storeData = {
|
||||
order: {
|
||||
serviceLocation: {
|
||||
address,
|
||||
|
|
@ -258,13 +300,8 @@ describe('contactDetails.vue', () => {
|
|||
}
|
||||
}
|
||||
};
|
||||
mountOptions.global.plugins = [createTestingPinia({
|
||||
initialState: {
|
||||
main: mainInitialState
|
||||
}
|
||||
})];
|
||||
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
const { wrapper } = setupMocks({ storeData });
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.address).toBe(address);
|
||||
|
|
@ -280,11 +317,7 @@ describe('contactDetails.vue', () => {
|
|||
describe('Navigation', () => {
|
||||
test('Back button clicked triggers navigation', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(contactDetails, getMountOptions({
|
||||
router: {
|
||||
navigateWithSpinner: jest.fn()
|
||||
}
|
||||
}));
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
|
||||
|
||||
// Act
|
||||
|
|
@ -295,42 +328,45 @@ describe('contactDetails.vue', () => {
|
|||
expect(wrapper.vm.$router.navigateWithSpinner)
|
||||
.toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, undefined);
|
||||
});
|
||||
test('Forward button clicked triggers appropriate navigation', () => {
|
||||
test('Forward button clicked triggers appropriate navigation', async () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
},
|
||||
navigationScenarios
|
||||
});
|
||||
const mainInitialState = {
|
||||
const storeData = {
|
||||
order: {
|
||||
serviceLocation: { IsSafeliteProvider: true }
|
||||
}
|
||||
};
|
||||
mountOptions.global.plugins = [createTestingPinia({
|
||||
initialState: {
|
||||
main: mainInitialState
|
||||
}
|
||||
})];
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
const { wrapper } = setupMocks({ storeData });
|
||||
|
||||
// Act
|
||||
wrapper.vm.forwardButtonAction();
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||
expect(wrapper.vm.$router.navigate)
|
||||
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined);
|
||||
});
|
||||
test('Forward button click updates service location info', () => {
|
||||
test('Forward button click updates service location info', async () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
const provider = {
|
||||
address: {
|
||||
city: getRandomString(4, 20),
|
||||
state: getRandomString(2, 2),
|
||||
streetAddress: getRandomString(10, 50),
|
||||
zipCode: getRandomInt(10000, 99999).toString(),
|
||||
zipCodeCtu: getRandomInt(10000, 99999).toString()
|
||||
},
|
||||
companyName: getRandomString(5, 15),
|
||||
phoneNumber: getRandomInt(1000000000, 9999999999).toString(),
|
||||
providerNumber: getRandomInt(100000, 999999).toString()
|
||||
}
|
||||
const storeData = {
|
||||
order: {
|
||||
serviceLocation: {
|
||||
provider
|
||||
}
|
||||
}
|
||||
});
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
};
|
||||
const { wrapper } = setupMocks({ storeData });
|
||||
const address = getRandomString(10, 50);
|
||||
const address2 = getRandomString(0, 50);
|
||||
const city = getRandomString(4, 20);
|
||||
|
|
@ -347,32 +383,28 @@ describe('contactDetails.vue', () => {
|
|||
});
|
||||
|
||||
// Act
|
||||
wrapper.vm.forwardButtonAction();
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(useMainStore().updateServiceLocation).toHaveBeenCalledWith({
|
||||
address,
|
||||
address2,
|
||||
city,
|
||||
isVehicleProtected
|
||||
isVehicleProtected,
|
||||
provider
|
||||
});
|
||||
});
|
||||
|
||||
test('Forward button click updates notes for technician', () => {
|
||||
test('Forward button click updates notes for technician', async () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
const wrapper = shallowMount(contactDetails, mountOptions);
|
||||
const { wrapper } = setupMocks({});
|
||||
const notesForTechnician = getRandomString(1, 100);
|
||||
wrapper.setData({
|
||||
notesForTechnician
|
||||
});
|
||||
|
||||
// Act
|
||||
wrapper.vm.forwardButtonAction();
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(useMainStore().updateContactInfo).toHaveBeenCalledWith({
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ import errorMessages from '@/constants/error-messages';
|
|||
import { required } from '@/helpers/validation-rules';
|
||||
import widgetFields from '@/constants/cms-widget-fields';
|
||||
import states from '@/constants/states';
|
||||
import applicationConfig from '@/constants/application-config';
|
||||
|
||||
// DEFINE VALIDATION RULES
|
||||
defineRule('street-address-required', required(errorMessages.SERVICE_ADDRESS_REQUIRED));
|
||||
|
|
@ -157,8 +158,9 @@ export default {
|
|||
async beforeRouteEnter(to, from, next) {
|
||||
const cmsContent = await fetchCmsContentForPage(to.query.issPage);
|
||||
|
||||
next((vm) => {
|
||||
next(async (vm) => {
|
||||
vm.setCmsContent(cmsContent);
|
||||
await vm.setupAddressLookup();
|
||||
});
|
||||
},
|
||||
data() {
|
||||
|
|
@ -239,17 +241,22 @@ export default {
|
|||
/**
|
||||
* @summary Steps to perform when forward button clicked.
|
||||
*/
|
||||
forwardButtonAction() {
|
||||
async forwardButtonAction() {
|
||||
const contactInfo = {
|
||||
notesForTechnician: this.notesForTechnician
|
||||
};
|
||||
useMainStore().updateContactInfo(contactInfo);
|
||||
|
||||
const provider = useMainStore().serviceLocation.provider;
|
||||
|
||||
await this.geocodeAddress();
|
||||
|
||||
useMainStore().updateServiceLocation({
|
||||
address: this.address,
|
||||
address2: this.address2,
|
||||
city: this.city,
|
||||
isVehicleProtected: this.isVehicleProtected || 'false'
|
||||
isVehicleProtected: this.isVehicleProtected || 'false',
|
||||
provider
|
||||
});
|
||||
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||
|
|
@ -264,7 +271,100 @@ export default {
|
|||
this.address = '';
|
||||
this.address2 = '';
|
||||
this.city = '';
|
||||
}
|
||||
},
|
||||
async setupAddressLookup() {
|
||||
const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
|
||||
|
||||
await this.$loadScript(`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=Function.prototype`)
|
||||
.catch(() => {
|
||||
// Failed to fetch script
|
||||
window.console.warn('Unable to load Google Places API script');
|
||||
});
|
||||
},
|
||||
geocodeAddress() {
|
||||
const autoCompletePromise = new Promise((resolve, reject) => {
|
||||
try {
|
||||
// Get Autocomplete Service
|
||||
const acService = new window.google.maps.places.AutocompleteService();
|
||||
// Get Places Service, needs pseudo element (or a map)
|
||||
const placeService = new window.google.maps.places.PlacesService(document.createElement('div'));
|
||||
// Create Autocomplete Session token, multiple requests one pricing hit
|
||||
const acSessionToken = new window.google.maps.places.AutocompleteSessionToken();
|
||||
|
||||
const addressValue = `${this.address}, ${this.city}, ${this.state} ${this.zipCode}`;
|
||||
acService.getPlacePredictions(
|
||||
{
|
||||
input: addressValue,
|
||||
type: ['geocode'],
|
||||
componentRestrictions: { country: ['us'] },
|
||||
sessionToken: acSessionToken
|
||||
},
|
||||
(predictions) => {
|
||||
if (predictions && predictions.length > 0) {
|
||||
const firstPrediction = predictions[0];
|
||||
if (firstPrediction.place_id) {
|
||||
placeService.getDetails(
|
||||
{
|
||||
placeId: firstPrediction.place_id,
|
||||
fields: ['address_components'],
|
||||
sessionToken: acSessionToken
|
||||
},
|
||||
(details) => {
|
||||
this.fillInAddress(details);
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
window.console.warn('Error initializing Google Places API services', error);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
return autoCompletePromise;
|
||||
},
|
||||
async fillInAddress(googlePlace) {
|
||||
let processedStreetAddress = false;
|
||||
let processedRoute = false;
|
||||
for (const component of googlePlace.address_components) {
|
||||
const componentType = component.types[0];
|
||||
|
||||
switch (componentType) {
|
||||
case 'street_number': {
|
||||
if (processedRoute) {
|
||||
this.address = `${component.long_name} ${this.address}`;
|
||||
} else {
|
||||
this.address = component.long_name;
|
||||
}
|
||||
|
||||
processedStreetAddress = true;
|
||||
break;
|
||||
}
|
||||
case 'route': {
|
||||
if (processedStreetAddress) {
|
||||
this.address += ` ${component.short_name}`;
|
||||
} else {
|
||||
this.address = component.short_name;
|
||||
}
|
||||
|
||||
processedRoute = true;
|
||||
break;
|
||||
}
|
||||
case 'locality': {
|
||||
this.city = component.long_name;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
exports[`coverageStatement.vue returns the initial data 1`] = `
|
||||
Object {
|
||||
"CANCEL_CLAIM_REF_NAME": "CancelClaimModal",
|
||||
"OEM_ENDORSEMENT_REF_NAME": "OEMModal",
|
||||
"RECAL_MODAL_REF_NAME": "RecalModal",
|
||||
"baseServiceLineItems": Array [],
|
||||
"isPageLoading": true,
|
||||
|
|
|
|||
|
|
@ -6,18 +6,25 @@
|
|||
<modal
|
||||
ref="cancelClaimModal"
|
||||
:headerText="modalHeaderText"
|
||||
:footerButtonText="modalFooterText"
|
||||
buttonVariant="link"
|
||||
@isModalOpened="setModalStatus"
|
||||
@footerButtonEvent="cancelClaimConfirmation">
|
||||
:displayFooterButton="false">
|
||||
<div v-html="modalBodyText"></div>
|
||||
<buttonMain
|
||||
id="btnContinueReferral"
|
||||
variant="success"
|
||||
:buttonText="modalBodyText2"
|
||||
class="mt-4 w-100"
|
||||
class="mt-5 w-100"
|
||||
@clickEvent="returnToClaim">
|
||||
</buttonMain>
|
||||
<div class="text-center mt-5">
|
||||
<textLink
|
||||
class="cancel-link"
|
||||
linkType="text"
|
||||
text="No, I want to cancel"
|
||||
href="#!"
|
||||
@clickEvent="cancelClaimConfirmation">
|
||||
</textLink>
|
||||
</div>
|
||||
</modal>
|
||||
</div>
|
||||
</transition>
|
||||
|
|
@ -26,12 +33,14 @@
|
|||
<script>
|
||||
import modal from '@/digital-components/modal/modal.vue';
|
||||
import ButtonMain from '@/ux-components/button-main/button-main.vue';
|
||||
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||
|
||||
export default {
|
||||
name: 'cancel-claim-modal',
|
||||
components: {
|
||||
ButtonMain,
|
||||
modal
|
||||
modal,
|
||||
textLink
|
||||
},
|
||||
emits: ['cancel-claim-confirmation', 'return-to-claim'],
|
||||
data() {
|
||||
|
|
@ -74,5 +83,18 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
:deep(.modal) {
|
||||
.modal-title {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.cancel-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.modal-footer {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.modal-body {
|
||||
color: #4d4e53;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
cmsWidgetName="SiteHeaderWidget" />
|
||||
</div>
|
||||
<div class="iss-heritage-container-width">
|
||||
<div v-if="!isPageLoading"
|
||||
<div v-show="!isPageLoading"
|
||||
class="coverage-statement-container iss-heritage-content-container-width">
|
||||
<h5
|
||||
ref="siteSubHeader"
|
||||
|
|
@ -101,14 +101,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<contentGroupModal
|
||||
<recalModal
|
||||
:ref="RECAL_MODAL_REF_NAME"
|
||||
cssModalHeadlineClass="text-center"
|
||||
cmsWidgetName="RecalModal" />
|
||||
<cancelClaimModal
|
||||
:ref="CANCEL_CLAIM_REF_NAME"
|
||||
@cancelClaimConfirmation="cancelClaim"
|
||||
@returnToClaim="navigateForward" />
|
||||
<oemEndorsementModal
|
||||
:ref="OEM_ENDORSEMENT_REF_NAME"
|
||||
cmsWidgetName="OEMEndorsementModal" />
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
|
|
@ -116,13 +118,14 @@
|
|||
// Import Component
|
||||
import { Form } from 'vee-validate';
|
||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
||||
import cancelClaimModal from '@/layouts/coverage-statement/cancel-claim-modal/cancel-claim-modal.vue';
|
||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
import afterpayModalBanner from '@/layouts/coverage-statement/afterpay-modal-banner/afterpay-modal-banner.vue';
|
||||
import recalModal from '@/iss-components/recal-modal/recal-modal.vue';
|
||||
|
||||
// Import Supporting Files
|
||||
import {
|
||||
fetchCmsContentForPage,
|
||||
|
|
@ -143,22 +146,25 @@ import showIssLoadingModal from '@/helpers/loading-modal-helper';
|
|||
import { getPriceOfLineItems } from '@/helpers/price-calculator';
|
||||
import coverageStatuses from '@/constants/coverage-statuses';
|
||||
import coverageType from '@/constants/coverage-type';
|
||||
import oemEndorsementModal from '@/layouts/coverage-statement/oem-endorsement-modal/oem-endorsement-modal.vue';
|
||||
|
||||
const RECAL_MODAL_REF_NAME = 'RecalModal';
|
||||
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
|
||||
const OEM_ENDORSEMENT_REF_NAME = 'OEMModal';
|
||||
|
||||
export default {
|
||||
name: 'coverage-statement',
|
||||
components: {
|
||||
siteHeader,
|
||||
Form,
|
||||
contentGroupModal,
|
||||
buttonMain,
|
||||
textBlock,
|
||||
textLink,
|
||||
siteFooter,
|
||||
cancelClaimModal,
|
||||
afterpayModalBanner
|
||||
afterpayModalBanner,
|
||||
recalModal,
|
||||
oemEndorsementModal
|
||||
},
|
||||
mixins: [baseFormMixin, vehicleQuestionsMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -221,7 +227,8 @@ export default {
|
|||
nextStep: 'NextStepsWidget'
|
||||
},
|
||||
RECAL_MODAL_REF_NAME,
|
||||
CANCEL_CLAIM_REF_NAME
|
||||
CANCEL_CLAIM_REF_NAME,
|
||||
OEM_ENDORSEMENT_REF_NAME
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -356,6 +363,7 @@ export default {
|
|||
nextStepsBody(newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
setupModalLink(this, RECAL_MODAL_REF_NAME);
|
||||
setupModalLink(this, OEM_ENDORSEMENT_REF_NAME);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -424,6 +432,7 @@ export default {
|
|||
},
|
||||
getCustomValueFromString(str) {
|
||||
const { isRepair } = useMainStore().damage;
|
||||
|
||||
switch (str) {
|
||||
case 'coverageUnverified':
|
||||
return this.isUnverifiedVisible;
|
||||
|
|
@ -449,6 +458,8 @@ export default {
|
|||
return !isRepair && this.isDeductibleVisible && this.deductibleValue <= 0;
|
||||
case 'verifiedReplaceDeductibleOverZero':
|
||||
return !isRepair && this.isDeductibleVisible && this.deductibleValue > 0;
|
||||
case 'hasOEMEndorsement':
|
||||
return this.mainStore.hasOemEndorsement;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
@ -462,7 +473,7 @@ export default {
|
|||
},
|
||||
cancelClaim() {
|
||||
this.mainStore.updateIsSafeliteProvider(false);
|
||||
this.$router.navigateBailout(bailoutMessage.RequestCallback());
|
||||
this.$router.navigateBailout(bailoutMessage.CoverageCancelledByUser());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -622,8 +633,4 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`returns the initial data 1`] = `Object {}`;
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import oemEndorsementModal from '@/layouts/coverage-statement/oem-endorsement-modal/oem-endorsement-modal.vue';
|
||||
|
||||
|
||||
const mockDataStrings = {
|
||||
cmsBodyText: `Some Body Text from CMS`,
|
||||
cmsHeaderText: 'Some Header Text from CMS',
|
||||
cmsFooterText: 'Some Footer Text from CMS'
|
||||
};
|
||||
|
||||
const mockCmsContent = {
|
||||
BodyText: mockDataStrings.cmsBodyText,
|
||||
HeaderText: mockDataStrings.cmsHeaderText,
|
||||
FooterText: mockDataStrings.cmsFooterText
|
||||
};
|
||||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((_, cmsFieldName) => mockCmsContent[cmsFieldName])
|
||||
},
|
||||
};
|
||||
|
||||
function setupMocks() {
|
||||
const wrapper = shallowMount(oemEndorsementModal, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
cmsWidgetName: 'OEMEndorsementModal'
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
test('returns the initial data', () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.$data).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('Computed', () => {
|
||||
test('Should get modal header text from Widget CMS', () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
|
||||
// Act
|
||||
const result = wrapper.vm.modalHeaderText;
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(mockDataStrings.cmsHeaderText);
|
||||
});
|
||||
|
||||
test('Should get modal close button text from Widget CMS', () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
|
||||
// Act
|
||||
const result = wrapper.vm.modalCloseButtonText;
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(mockDataStrings.cmsFooterText);
|
||||
});
|
||||
|
||||
test('Should call getCmsContent with the correct widget name and field name for body text', () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
|
||||
// Act
|
||||
wrapper.vm.modalBodyText;
|
||||
|
||||
// Assert
|
||||
expect(mockMixin.methods.getCmsContent).toHaveBeenCalledWith('OEMEndorsementModal', 'BodyText');
|
||||
});
|
||||
|
||||
test('Should call getCmsContent with the correct widget name and field name for header text', () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
|
||||
// Act
|
||||
wrapper.vm.modalHeaderText;
|
||||
|
||||
// Assert
|
||||
expect(mockMixin.methods.getCmsContent).toHaveBeenCalledWith('OEMEndorsementModal', 'HeaderText');
|
||||
});
|
||||
|
||||
test('Should call getCmsContent with the correct widget name and field name for footer text', () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks();
|
||||
|
||||
// Act
|
||||
wrapper.vm.modalCloseButtonText;
|
||||
|
||||
// Assert
|
||||
expect(mockMixin.methods.getCmsContent).toHaveBeenCalledWith('OEMEndorsementModal', 'FooterText');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Props', () => {
|
||||
test('Should use the default cmsWidgetName prop value of OEMEndorsementModal', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(oemEndorsementModal, {
|
||||
mixins: [mockMixin],
|
||||
attachTo: document.body
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.cmsWidgetName).toBe('OEMEndorsementModal');
|
||||
});
|
||||
|
||||
test('Should accept a custom cmsWidgetName prop', () => {
|
||||
// Arrange
|
||||
const customWidgetName = 'CustomOEMModal';
|
||||
const wrapper = shallowMount(oemEndorsementModal, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
cmsWidgetName: customWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.cmsWidgetName).toBe(customWidgetName);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<template>
|
||||
<div class="recal-modal-container">
|
||||
<modal
|
||||
ref="oemEndorsementModal"
|
||||
:footerButtonText="modalCloseButtonText"
|
||||
@footerButtonEvent="footerButtonClick">
|
||||
<h5
|
||||
class="header-text"
|
||||
v-html="modalHeaderText"></h5>
|
||||
<div v-html="modalBodyText" class="oem-endorsement-modal-body"></div>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from '@/digital-components/modal/modal.vue';
|
||||
|
||||
export default {
|
||||
name: 'oem-endorsement-modal',
|
||||
components: {
|
||||
modal
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: {
|
||||
type: String,
|
||||
default: 'OEMEndorsementModal'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
modalBodyText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'BodyText');
|
||||
},
|
||||
modalHeaderText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||
},
|
||||
modalCloseButtonText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
this.$refs.oemEndorsementModal.openModal();
|
||||
},
|
||||
footerButtonClick() {
|
||||
this.$refs.oemEndorsementModal.closeModal();
|
||||
},
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.modal) {
|
||||
&.modal-component {
|
||||
.modal-dialog {
|
||||
.modal-content {
|
||||
.modal-body {
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
button {
|
||||
&:hover {
|
||||
background-color: $heritage-blue-primary;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.oem-endorsement-modal-body {
|
||||
padding: 10px 0 10px 0;
|
||||
p:first-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -151,68 +151,6 @@ describe('license-plate-lookup.vue', () => {
|
|||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'alertVinNotFound' }).isVisible()).toBe(true);
|
||||
});
|
||||
test('non-serviceable big truck found, display NoServiceAlert', async () => {
|
||||
// Arrange
|
||||
const mockRegistrationLicensePlate = {
|
||||
licensePlate: 'BIGTRUCKTEST'
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({
|
||||
lookupVinByPlateResponse: {
|
||||
vin: 'BIGTRUCKVIN',
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKTESTCARID',
|
||||
isBigTruck: true,
|
||||
canSafeliteService: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
useMainStore().order.vehicle.carId = 'BIGTRUCKTESTCARID';
|
||||
|
||||
await wrapper.setData({
|
||||
licensePlate: mockRegistrationLicensePlate
|
||||
});
|
||||
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'alertNoService' }).isVisible()).toBe(true);
|
||||
});
|
||||
test('serviceable big truck found, do not display NoServiceAlert', async () => {
|
||||
// Arrange
|
||||
const mockRegistrationLicensePlate = {
|
||||
licensePlate: 'BIGTRUCKTEST2'
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({
|
||||
lookupVinByPlateResponse: {
|
||||
vin: 'BIGTRUCKVIN2',
|
||||
vehicle: {
|
||||
carId: 'BIGTRUCKTESTCARID2',
|
||||
isBigTruck: true,
|
||||
canSafeliteService: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
useMainStore().order.vehicle.carId = 'BIGTRUCKTESTCARID2';
|
||||
|
||||
await wrapper.setData({
|
||||
licensePlate: mockRegistrationLicensePlate
|
||||
});
|
||||
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'alertNoService' }).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('navigation', () => {
|
||||
|
|
|
|||
|
|
@ -59,13 +59,6 @@
|
|||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||
alertClass="alert-warning"
|
||||
:isDismissible="false" />
|
||||
<alert
|
||||
v-if="displayNoServiceAlert"
|
||||
ref="alertNoService"
|
||||
class="mt-5"
|
||||
cmsWidgetName="AlertNoServiceWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissable="false" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
|
|
@ -156,8 +149,7 @@ export default {
|
|||
isCarIdDifferent: false,
|
||||
customAlertData: {},
|
||||
isSelectedGlassAvailableForVehicle: true,
|
||||
forwardButtonCarStyle: '',
|
||||
displayNoServiceAlert: false
|
||||
forwardButtonCarStyle: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -247,6 +239,7 @@ export default {
|
|||
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
||||
async forwardButtonAction() {
|
||||
this.resetWarningsAndErrors();
|
||||
this.mainStore.resetBailout();
|
||||
|
||||
// Lookup VIN
|
||||
const vinLookupResponse = await useMainStore().lookupVinByPlate(
|
||||
|
|
@ -265,9 +258,11 @@ export default {
|
|||
// Vehicle found from VIN lookup
|
||||
const vehicleFromLookup = vinLookupResponse.data.vehicle;
|
||||
if (!vehicleFromLookup.canSafeliteService) {
|
||||
this.displayNoServiceAlert = true;
|
||||
showIssLoadingModal(false);
|
||||
return this.$refs.siteFooter.disableForwardButton();
|
||||
this.mainStore.setBailout({
|
||||
type: 'HeavyTruckVehicle',
|
||||
carId: vehicleFromLookup.carId
|
||||
});
|
||||
return this.navigateForward();
|
||||
}
|
||||
|
||||
// Check if the CarId has changed
|
||||
|
|
@ -326,7 +321,6 @@ export default {
|
|||
resetWarningsAndErrors() {
|
||||
this.displayVinNotFoundAlert = false;
|
||||
this.displayMatchedDifferentVehicleAlert = false;
|
||||
this.displayNoServiceAlert = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -281,11 +281,13 @@ export default {
|
|||
},
|
||||
serviceTypeText() {
|
||||
const glassPieces = this.submittedOrder.lineItems.glassParts?.map((part) => part.partType.toLowerCase()) ?? [];
|
||||
let glassList = getGlassList(glassPieces);
|
||||
let glassList = '';
|
||||
let workType = '';
|
||||
if (this.isRepair) {
|
||||
glassList = 'windshield';
|
||||
workType = 'repair';
|
||||
} else {
|
||||
glassList = getGlassList(glassPieces);
|
||||
workType = 'replacement';
|
||||
if (this.hasRecalibrationPart) {
|
||||
if (glassList === 'windshield') {
|
||||
|
|
@ -622,7 +624,7 @@ export default {
|
|||
}
|
||||
|
||||
.cart-container {
|
||||
padding: 0 .9375rem;
|
||||
padding: 0 .9375rem 2.1875rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ function setupMocks({ customMountOptions = {}, queryString }, mainInitialState =
|
|||
}
|
||||
|
||||
return 'false';
|
||||
})
|
||||
}),
|
||||
savePageDataToStore: jest.fn()
|
||||
}
|
||||
};
|
||||
const cmsMixin = {
|
||||
|
|
@ -84,33 +85,10 @@ describe('payment-method.vue', () => {
|
|||
const wrapper = setupMocks({}, store);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
wrapper.vm.initializeComponent();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).toBe(payLaterMethod);
|
||||
});
|
||||
test('getting payment method when method is pay in advance', async () => {
|
||||
// Arrange
|
||||
const payInAdvanceMethod = paymentMethods.CREDIT_CARD;
|
||||
const store = {
|
||||
order: {
|
||||
payment: {
|
||||
paymentMethod: payInAdvanceMethod
|
||||
},
|
||||
insuranceCoverage: {
|
||||
coverageStatus: coverageStatuses.VERIFIED,
|
||||
coverageType: coverageType.Deductible
|
||||
},
|
||||
currentDeductible: 1000
|
||||
}
|
||||
};
|
||||
const wrapper = setupMocks({}, store);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).toBe(payInAdvanceMethod);
|
||||
expect(wrapper.vm.paymentMethod).toBe(payLaterMethod);
|
||||
});
|
||||
test('getting PAY_AT_TIME_OF_SERVICE when deductible is 0', async () => {
|
||||
// Arrange
|
||||
|
|
@ -124,16 +102,18 @@ describe('payment-method.vue', () => {
|
|||
coverageStatus: coverageStatuses.VERIFIED,
|
||||
coverageType: coverageType.Deductible
|
||||
},
|
||||
currentDeductible: 0
|
||||
currentDeductible: {
|
||||
replace: 0
|
||||
}
|
||||
}
|
||||
};
|
||||
const wrapper = setupMocks({}, store);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
wrapper.vm.initializeComponent();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).toBe(payInAdvanceMethod);
|
||||
expect(wrapper.vm.paymentMethod).toBe(payInAdvanceMethod);
|
||||
});
|
||||
test('getting PAY_AT_TIME_OF_SERVICE when Unverified', async () => {
|
||||
// Arrange
|
||||
|
|
@ -147,16 +127,18 @@ describe('payment-method.vue', () => {
|
|||
coverageStatus: coverageStatuses.PENDING,
|
||||
coverageType: coverageType.Deductible
|
||||
},
|
||||
currentDeductible: 1000
|
||||
currentDeductible: {
|
||||
replace: 1000
|
||||
}
|
||||
}
|
||||
};
|
||||
const wrapper = setupMocks({}, store);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
wrapper.vm.initializeComponent();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).toBe(payInAdvanceMethod);
|
||||
expect(wrapper.vm.paymentMethod).toBe(payInAdvanceMethod);
|
||||
});
|
||||
test('getting PAY_AT_TIME_OF_SERVICE when PIA Experiment disabled', async () => {
|
||||
// Arrange
|
||||
|
|
@ -180,16 +162,18 @@ describe('payment-method.vue', () => {
|
|||
coverageStatus: coverageStatuses.VERIFIED,
|
||||
coverageType: coverageType.Deductible
|
||||
},
|
||||
currentDeductible: 1000
|
||||
currentDeductible: {
|
||||
replace: 1000
|
||||
}
|
||||
}
|
||||
};
|
||||
const wrapper = setupMocks({}, store, mixin);
|
||||
|
||||
// Act
|
||||
const paymethod = wrapper.vm.getPaymentMethodFromStore();
|
||||
wrapper.vm.initializeComponent();
|
||||
|
||||
// Assert
|
||||
expect(paymethod).toBe(payInAdvanceMethod);
|
||||
expect(wrapper.vm.paymentMethod).toBe(payInAdvanceMethod);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ export default {
|
|||
async beforeRouteEnter(to, from, next) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
const pageData = useMainStore().pageData(to.query.issPage);
|
||||
|
||||
const promiseResultMap = [
|
||||
{
|
||||
|
|
@ -192,7 +193,7 @@ export default {
|
|||
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.initializeComponent();
|
||||
vm.initializeComponent(pageData);
|
||||
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
||||
});
|
||||
},
|
||||
|
|
@ -238,8 +239,23 @@ export default {
|
|||
|
||||
return !isEnabled || useMainStore().isUnverified || (useMainStore().isDeductible && isDeductibleTotalEqualToZero);
|
||||
},
|
||||
isAdyenEnabled() {
|
||||
const adyenEnabled = this.getSettingValue(experimentSettings.ISS_ENABLE_ADYEN_V1);
|
||||
return adyenEnabled === 'true';
|
||||
},
|
||||
paymentMethodWidgetName() {
|
||||
return supportsApplePay() ? this.widget.paymentMethodApplePay : this.widget.paymentMethod;
|
||||
let showApplePay = false;
|
||||
if (this.isAdyenEnabled) {
|
||||
// Apple Pay is Available in Adyen if the protocol is HTTPS
|
||||
if (window.location.protocol === 'https:') {
|
||||
showApplePay = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
showApplePay = supportsApplePay();
|
||||
}
|
||||
|
||||
return showApplePay ? this.widget.paymentMethodApplePay : this.widget.paymentMethod;
|
||||
},
|
||||
showCartTotal() {
|
||||
return this.mainStore.isVerified && (this.mainStore.isITAC || this.mainStore.isNoComp
|
||||
|
|
@ -382,26 +398,21 @@ export default {
|
|||
&& customerReqs
|
||||
&& contactInfoReqs);
|
||||
},
|
||||
initializeComponent() {
|
||||
const paymentMethodFromStore = this.getPaymentMethodFromStore();
|
||||
// SMS Opt In defaults to 'no', but we don't actually want to use it if the user hasn't saved data form this page yet
|
||||
if (paymentMethodFromStore) {
|
||||
this.smsOptIn = this.getSMSOptInFromStore();
|
||||
initializeComponent(pageData) {
|
||||
if (pageData) {
|
||||
this.smsOptIn = pageData.smsOptIn;
|
||||
}
|
||||
this.smsPhoneNumber = this.getSMSPhoneFromStore();
|
||||
},
|
||||
getPaymentMethodFromStore() {
|
||||
if (this.isPayInAdvanceDisabled) {
|
||||
return paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
this.paymentMethod = paymentMethods.PAY_AT_TIME_OF_SERVICE;
|
||||
}
|
||||
|
||||
return useMainStore().order.payment.paymentMethod;
|
||||
},
|
||||
updateFooterButtonText(newValue) {
|
||||
this.$refs.siteFooter.updateButtonText(newValue);
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
this.mainStore.savePaymentMethodChoice(this.paymentMethod);
|
||||
this.savePageDataToStore(issPageValues.PAYMENT_METHOD, { smsOptIn: this.smsOptIn });
|
||||
if (!this.hideSMSOptIn) {
|
||||
const requestTextUpdates = this.smsOptIn === 'Yes';
|
||||
this.mainStore.updateContactInfo({ requestTextUpdates });
|
||||
|
|
@ -422,8 +433,12 @@ export default {
|
|||
bailoutOnError: true
|
||||
});
|
||||
|
||||
const scenario = this.isAdyenEnabled
|
||||
? this.navigationScenarios.CLICKED_PAY_NOW_ADYEN
|
||||
: this.navigationScenarios.CLICKED_PAY_NOW;
|
||||
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_PAY_NOW,
|
||||
scenario,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.SKIP_SAVE_SESSION]: true }
|
||||
|
|
@ -439,17 +454,17 @@ export default {
|
|||
this.$route
|
||||
);
|
||||
},
|
||||
getSMSOptInFromStore() {
|
||||
return this.mainStore.contactInfo.requestTextUpdates ? 'Yes' : 'No';
|
||||
},
|
||||
getSMSPhoneFromStore() {
|
||||
return this.mainStore.contactInfo.alternativePhone ?? this.mainStore.contactInfo.servicePhone;
|
||||
},
|
||||
handleEditClicked(section) {
|
||||
switch (section) {
|
||||
case 'location':
|
||||
const scenario = this.mainStore.isMobileAppointment
|
||||
? this.navigationScenarios.EDIT_SERVICE_LOCATION_MOBILE
|
||||
: this.navigationScenarios.EDIT_SERVICE_LOCATION_INSHOP;
|
||||
this.$router.navigateWithSpinner(
|
||||
this.navigationScenarios.EDIT_SERVICE_LOCATION,
|
||||
scenario,
|
||||
this.$route
|
||||
);
|
||||
break;
|
||||
|
|
|
|||
623
src/layouts/payment-page-adyen/payment-page-adyen.vue
Normal file
623
src/layouts/payment-page-adyen/payment-page-adyen.vue
Normal file
|
|
@ -0,0 +1,623 @@
|
|||
<template>
|
||||
<Form>
|
||||
<div class="fade-on-route-transition">
|
||||
<div class="justify-content-center">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
</div>
|
||||
<div class="iss-heritage-container-width payment-page-container">
|
||||
<div id="card-container" class="row">
|
||||
<div class="col-lg-8">
|
||||
<alert
|
||||
v-if="hasPaymentFailureError"
|
||||
name="payInAdvanceErrorAlert"
|
||||
class="pay-in-advance-alert"
|
||||
cmsWidgetName="PayInAdvanceErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
:isCollapsible="true"
|
||||
:preventDefaultOnClick="true"
|
||||
@textLinkClicked="paymentFailedPayLater" />
|
||||
<div id="adyen-container"></div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-10 col-xs-12">
|
||||
<div class="order-summary-panel">
|
||||
<div class="cart-title">{{ cartTitle }}</div>
|
||||
<cartDropdown
|
||||
ref="cart"
|
||||
class="cart-dropdown-component"
|
||||
:readOnly="true"
|
||||
:showAsPaid="false"
|
||||
recyclingModalCmsWidgetName="RecycleModal"
|
||||
servicePackageTitleWidgetName="ServicePackageTitle" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<siteFooter
|
||||
class="footer-component"
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="true"
|
||||
:isForwardButtonHidden="true"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="backButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
<script>
|
||||
// Components
|
||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
import alert from '@/ux-components/alert/alert.vue';
|
||||
import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue';
|
||||
|
||||
// Supporting files
|
||||
import issPageValues from '@/router/router-constants/issPage-values.js';
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { getCartTotal } from '@/helpers/cart-helper';
|
||||
import { useMainStore } from '@/store';
|
||||
import widgetFields from '@/constants/cms-widget-fields.js';
|
||||
import { paymentMethods } from '@/constants/payment-method-constants.js';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants.js';
|
||||
import queryStrings from '@/constants/query-strings';
|
||||
import { formatAmountInDollars } from '@/helpers/text-helper';
|
||||
import showIssLoadingModal from '@/helpers/loading-modal-helper';
|
||||
import { submitWorkOrder } from '@/helpers/order-helper';
|
||||
import submitType from '@/constants/submit-type';
|
||||
|
||||
import "@adyen/adyen-web/styles/adyen.css";
|
||||
import { mapAdyenToIssPaymentMethod, mapIssToAdyenPaymentMethod } from '@/helpers/adyen-helper';
|
||||
import { createAdyenCheckout } from "@/helpers/adyen-helper";
|
||||
import { Dropin } from "@adyen/adyen-web/auto";
|
||||
import applicationConfig from '@/constants/application-config';
|
||||
|
||||
export default {
|
||||
name: 'payment-page-adyen',
|
||||
components: {
|
||||
cartDropdown,
|
||||
siteHeader,
|
||||
siteFooter,
|
||||
Form,
|
||||
alert
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
const alertToDisplay = to.query[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT];
|
||||
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}
|
||||
];
|
||||
|
||||
// use resultMap to populate layout content.
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.$nextTick(() => {
|
||||
if (vm.$refs.cart) {
|
||||
const cartItems = vm.$refs.cart.cartItems;
|
||||
vm.getPayInAdvanceLineItems(cartItems);
|
||||
}
|
||||
if (alertToDisplay) {
|
||||
vm.hasPaymentFailureError = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
showIssLoadingModal(true);
|
||||
this.initializeAdyen().finally(() => {
|
||||
showIssLoadingModal(false);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
referralSequenceNumber: useMainStore().order.referralSequenceNumber,
|
||||
emailAddress: useMainStore().contactInfo.emailAddress,
|
||||
address1: this.getAddress1(),
|
||||
address2: this.getAddress2(),
|
||||
city: this.getCity(),
|
||||
state: this.getState(),
|
||||
zipCode: this.getZipCode(),
|
||||
firstName: useMainStore().contactInfo.firstName,
|
||||
lastName: useMainStore().contactInfo.lastName,
|
||||
phoneNumber: useMainStore().contactInfo.servicePhone,
|
||||
ctu: useMainStore().order.serviceLocation.provider?.address?.zipCodeCtu ?? useMainStore().order.serviceLocation.zipCodeCtu,
|
||||
referralCorrelationId: useMainStore().order.referralCorrelationId,
|
||||
workOrderNumber: this.getWorkOrderNumber(),
|
||||
invoiceNumber: this.getInvoiceNumber(),
|
||||
totalAmount: this.getAmountDue(),
|
||||
displayAmount: this.getDisplayAmountDue(),
|
||||
payInAdvanceLineItems: '',
|
||||
sessionId: '',
|
||||
dropinComponent: null,
|
||||
sourceSystem: 'ISS-NextGen',
|
||||
hasPaymentFailureError: false,
|
||||
adyenTimeout: null
|
||||
};
|
||||
},
|
||||
unmounted() {
|
||||
if (this.adyenTimeout) {
|
||||
clearTimeout(this.adyenTimeout);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
piaType() {
|
||||
return this.mainStore.payment.paymentMethod;
|
||||
},
|
||||
parentDomainName() {
|
||||
return window.location.hostname;
|
||||
},
|
||||
payInAdvanceResponseUrl() {
|
||||
const { protocol, host } = window.location;
|
||||
return `${protocol}//${host}/?issPage=${issPageValues.PAYMENT_RETURN_ADYEN}&src=iss-nextgen`;
|
||||
},
|
||||
payInAdvanceCancelUrl() {
|
||||
const { protocol, host } = window.location;
|
||||
return `${protocol}//${host}/?issPage=${issPageValues.PAYMENT_METHOD}&src=iss-nextgen`;
|
||||
},
|
||||
cartTitle() {
|
||||
return this.getCmsContent('OrderSummaryTextWidget', widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
switchPaymentText() {
|
||||
return this.getCmsContent('SwitchPaymentTextWidget', widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
submitPaymentText() {
|
||||
return this.getCmsContent('SiteFooterWidget', widgetFields.FOOTER_WIDGET.FORWARD_BUTTON_TEXT);
|
||||
},
|
||||
adyenPriceTotal() {
|
||||
return Math.round(this.totalAmount * 100);
|
||||
},
|
||||
workOrderNumberLastSixDigits() {
|
||||
const workOrderNumber = this.workOrderNumber ?? "";
|
||||
const tokens = workOrderNumber.split("-");
|
||||
const lastSegment = tokens[tokens.length - 1] ?? "";
|
||||
const numDigits = lastSegment.length;
|
||||
const numZeroes = 6 - numDigits;
|
||||
|
||||
let result = "";
|
||||
for (let i = 0; i < numZeroes; i++) {
|
||||
result += "0";
|
||||
}
|
||||
|
||||
result += lastSegment;
|
||||
|
||||
return result;
|
||||
},
|
||||
splitStreetAddress() {
|
||||
const address = this.address1;
|
||||
const tokens = address.split(" ") ?? [""];
|
||||
const number = tokens[0];
|
||||
|
||||
const street = tokens.slice(1).join(" ") ?? "";
|
||||
|
||||
return {
|
||||
number: number ?? "",
|
||||
street: street ?? "",
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
// Line Items
|
||||
const packageReqs =
|
||||
!!useMainStore().order.lineItems.supportingItems;
|
||||
|
||||
// Service Location
|
||||
const { serviceLocation } = useMainStore().order;
|
||||
const mobileReqs = !!(
|
||||
serviceLocation.address
|
||||
&& serviceLocation.city
|
||||
&& serviceLocation.state
|
||||
&& serviceLocation.zipCode
|
||||
);
|
||||
|
||||
const providerLocation = serviceLocation.provider.address;
|
||||
const dropOffInshopReqs = !!(
|
||||
providerLocation.streetAddress
|
||||
&& providerLocation.city
|
||||
&& providerLocation.state
|
||||
&& providerLocation.zipCode
|
||||
);
|
||||
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
|
||||
const serviceLocationReqs =
|
||||
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
||||
|
||||
// Insurance
|
||||
const isInsuranceSet =
|
||||
useMainStore().order.payment.isInsurance !== null;
|
||||
|
||||
// Schedule
|
||||
const { schedule } = useMainStore().order;
|
||||
const scheduleReqs = !!(
|
||||
schedule.date
|
||||
&& schedule.startTime
|
||||
&& schedule.endTime
|
||||
&& schedule.jobMaxMinutes
|
||||
&& schedule.jobMinMinutes
|
||||
);
|
||||
|
||||
// Contact Info
|
||||
const { contactInfo } = useMainStore();
|
||||
const contactInfoReqs = !!(
|
||||
contactInfo.firstName
|
||||
&& contactInfo.lastName
|
||||
&& contactInfo.servicePhone
|
||||
&& contactInfo.emailAddress
|
||||
);
|
||||
|
||||
const paymentMethodReqs = useMainStore().isPayInAdvance;
|
||||
|
||||
return (
|
||||
packageReqs
|
||||
&& serviceLocationReqs
|
||||
&& isInsuranceSet
|
||||
&& scheduleReqs
|
||||
&& contactInfoReqs
|
||||
&& paymentMethodReqs
|
||||
);
|
||||
},
|
||||
getWorkOrderNumber() {
|
||||
const { workOrderNumber } = useMainStore().order;
|
||||
if (workOrderNumber) {
|
||||
const items = workOrderNumber.split('-');
|
||||
if (items.length > 1) {
|
||||
return items[1];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
getInvoiceNumber() {
|
||||
const { workOrderNumber } = useMainStore().order;
|
||||
if (workOrderNumber) {
|
||||
return workOrderNumber.replace('-', '');
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
getAddress1() {
|
||||
return (
|
||||
useMainStore().order.serviceLocation.address
|
||||
?? useMainStore().order.serviceLocation.provider.address
|
||||
.streetAddress
|
||||
);
|
||||
},
|
||||
getAddress2() {
|
||||
return useMainStore().order.serviceLocation.address2;
|
||||
},
|
||||
getCity() {
|
||||
return (
|
||||
useMainStore().order.serviceLocation.city
|
||||
?? useMainStore().order.serviceLocation.provider.address.city
|
||||
);
|
||||
},
|
||||
getState() {
|
||||
return (
|
||||
useMainStore().order.serviceLocation.state
|
||||
?? useMainStore().order.serviceLocation.provider.address.state
|
||||
);
|
||||
},
|
||||
getZipCode() {
|
||||
return (
|
||||
useMainStore().order.customer.address.zipCode
|
||||
?? useMainStore().order.serviceLocation.zipCode
|
||||
?? useMainStore().order.serviceLocation.provider.address.zipCode
|
||||
);
|
||||
},
|
||||
getPayInAdvanceLineItems(cartItems) {
|
||||
const { glassParts } = useMainStore().order.lineItems;
|
||||
const lineItems =
|
||||
glassParts === null
|
||||
? [
|
||||
this.getPayInAdvanceFormattedLineItem('Labor', 0, 1),
|
||||
this.getPayInAdvanceFormattedLineItem('Repair supplies', 0, 1)
|
||||
]
|
||||
: [
|
||||
this.getPayInAdvanceFormattedLineItem('Parts and labor', 0, 1)
|
||||
];
|
||||
|
||||
cartItems.forEach((item) => {
|
||||
if (item.name !== null && item.category !== 'promos') {
|
||||
lineItems.push(this.getPayInAdvanceFormattedLineItem(
|
||||
item.name,
|
||||
(item.salesTax + item.subTotal).toFixed(2),
|
||||
1
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
this.payInAdvanceLineItems = lineItems.join('||');
|
||||
},
|
||||
getPayInAdvanceFormattedLineItem(itemName, price, quantity) {
|
||||
return `${itemName}|${price}|${quantity}`;
|
||||
},
|
||||
getAmountDue() {
|
||||
return getCartTotal(useMainStore().order);
|
||||
},
|
||||
getDisplayAmountDue() {
|
||||
return formatAmountInDollars(this.getAmountDue());
|
||||
},
|
||||
async paymentFailedPayLater() {
|
||||
this.showIssLoadingModal(true);
|
||||
this.mainStore.savePaymentMethodChoice(paymentMethods.PAY_AT_TIME_OF_SERVICE);
|
||||
await submitWorkOrder({ submitType: submitType.SAFELITE });
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
backButtonAction() {
|
||||
// page will not render with normal navigation due to navigating from the iframe
|
||||
window.location = this.payInAdvanceCancelUrl;
|
||||
},
|
||||
forwardButtonAction() {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
async initializeAdyen() {
|
||||
const requestBody = this.getAdyenInitRequestInfo();
|
||||
|
||||
const adyenResponse = await this.mainStore.initializeAdyenPayment(requestBody);
|
||||
|
||||
const session = {
|
||||
id: adyenResponse.sessionId,
|
||||
sessionData: adyenResponse.sessionData,
|
||||
};
|
||||
|
||||
this.sessionId = adyenResponse.sessionId;
|
||||
|
||||
const checkout = await createAdyenCheckout({
|
||||
session: session,
|
||||
handlers: {
|
||||
onPaymentCompleted: (result, component) => {
|
||||
this.handleCompletedPayment(result);
|
||||
},
|
||||
onPaymentFailed: (result, component) => {
|
||||
this.handleFailedPayment(result);
|
||||
},
|
||||
onError: (error, component) => {
|
||||
this.handleError(error);
|
||||
},
|
||||
},
|
||||
options: {
|
||||
amount: this.adyenPriceTotal,
|
||||
},
|
||||
});
|
||||
|
||||
const expiryTime = new Date(checkout.options.expiresAt);
|
||||
const expiryInterval = expiryTime.getTime() - new Date().getTime();
|
||||
|
||||
const handleTimeout = () => {
|
||||
this.resetAdyenDropin();
|
||||
};
|
||||
|
||||
if (this.adyenTimeout) {
|
||||
clearTimeout(this.adyenTimeout);
|
||||
}
|
||||
this.adyenTimeout = setTimeout(handleTimeout, expiryInterval);
|
||||
|
||||
const configuration = {
|
||||
paymentMethodsConfiguration: {
|
||||
ideal: {
|
||||
showImage: true,
|
||||
},
|
||||
paypal: {
|
||||
amount: {
|
||||
value: this.adyenPriceTotal,
|
||||
currency: "USD",
|
||||
},
|
||||
environment: applicationConfig.ADYEN_ENVIRONMENT,
|
||||
countryCode: "US", // Only needed for test. This will be automatically retrieved when you are in production.
|
||||
blockPayPalVenmoButton: true,
|
||||
blockPayPalPayLaterButton: true,
|
||||
},
|
||||
card: {
|
||||
hasHolderName: true,
|
||||
holderNameRequired: true,
|
||||
billingAddressRequired: true,
|
||||
name: "Credit or debit card",
|
||||
data: {
|
||||
holderName: `${this.mainStore.contactInfo.firstName} ${this.mainStore.contactInfo.lastName}`,
|
||||
billingAddress: {
|
||||
postalCode: this.zipCode,
|
||||
country: "US"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const adyenPaymentType = mapIssToAdyenPaymentMethod(this.piaType);
|
||||
|
||||
if (adyenPaymentType) {
|
||||
configuration.openPaymentMethod = {
|
||||
type: adyenPaymentType,
|
||||
};
|
||||
}
|
||||
|
||||
const dropin = new Dropin(checkout, configuration);
|
||||
|
||||
this.dropinComponent = dropin;
|
||||
|
||||
dropin.mount("#adyen-container");
|
||||
},
|
||||
getAdyenInitRequestInfo() {
|
||||
const request = {
|
||||
sourceSystem: this.sourceSystem,
|
||||
referralSequenceNumber: this.referralSequenceNumber,
|
||||
workOrderNumber: this.workOrderNumberLastSixDigits,
|
||||
zipCodeCtu: this.ctu,
|
||||
amount: this.adyenPriceTotal,
|
||||
city: this.city,
|
||||
houseNumberOrName: this.splitStreetAddress.number,
|
||||
street: this.splitStreetAddress.street,
|
||||
zipCode: this.zipCode,
|
||||
stateOrProvince: this.state,
|
||||
returnUrl: this.payInAdvanceResponseUrl,
|
||||
email: this.mainStore.contactInfo.emailAddress,
|
||||
firstName: this.mainStore.contactInfo.firstName,
|
||||
lastName: this.mainStore.contactInfo.lastName,
|
||||
idempotencyKey: this.getIdempotencyKey(),
|
||||
};
|
||||
return request;
|
||||
},
|
||||
async resetAdyenDropin() {
|
||||
this?.dropinComponent?.unmount();
|
||||
await this.initializeAdyen();
|
||||
},
|
||||
getIdempotencyKey() {
|
||||
const currentDateTime = new Date();
|
||||
const currentHour = currentDateTime.getUTCHours();
|
||||
const currentDate = currentDateTime.getUTCDate();
|
||||
const id = this?.mainStore?.order?.referralCorrelationId;
|
||||
const system = this.sourceSystem;
|
||||
const total = this.adyenPriceTotal;
|
||||
|
||||
return `${id}-${system}-${currentDate}-${currentHour}-${total}`;
|
||||
},
|
||||
async handleCompletedPayment(result) {
|
||||
// Fetch session info
|
||||
const paymentSessionRequest = {
|
||||
zipCodeCtu: this.ctu,
|
||||
workOrderNumber: this.workOrderNumberLastSixDigits,
|
||||
sourceSystem: this.sourceSystem,
|
||||
sessionId: this.sessionId,
|
||||
sessionResult: result?.sessionResult,
|
||||
};
|
||||
|
||||
showIssLoadingModal(true);
|
||||
|
||||
const adyenResponse = await this.mainStore.getAdyenSessionResult(paymentSessionRequest);
|
||||
|
||||
const ccToken = {
|
||||
subscriptionId: adyenResponse?.storedToken,
|
||||
expMonth: adyenResponse?.cardExpiryMonth,
|
||||
expYear: adyenResponse?.cardExpiryYear,
|
||||
cardType: adyenResponse?.cardType,
|
||||
billToPostalCode: this.zipCode,
|
||||
billToFirstName: this.mainStore.contactInfo.firstName,
|
||||
billToLastName: this.mainStore.contactInfo.lastName,
|
||||
referenceNumber: adyenResponse?.workOrderNumber,
|
||||
authCode: adyenResponse?.authCode,
|
||||
transactionId: adyenResponse?.transactionReference,
|
||||
transReferenceNumber: adyenResponse?.transactionReference,
|
||||
lastFour: adyenResponse?.last4DigitsOfCard,
|
||||
};
|
||||
|
||||
const paymentMethodFromSession = adyenResponse?.paymentMethod;
|
||||
|
||||
const paymentMethod = mapAdyenToIssPaymentMethod(paymentMethodFromSession);
|
||||
|
||||
this.mainStore.savePaymentMethodChoice(paymentMethod);
|
||||
|
||||
if (paymentMethod === paymentMethods.PAYPAL) {
|
||||
this.mainStore.updatePaypalToken(adyenResponse?.storedToken);
|
||||
} else {
|
||||
this.mainStore.updateCreditCardToken(ccToken);
|
||||
}
|
||||
|
||||
this.mainStore.updateNextGenSettledAmount(this.totalAmount);
|
||||
|
||||
await this.saveAndSubmitWorkOrder();
|
||||
},
|
||||
async handleFailedPayment(result) {
|
||||
const wasPaymentCancelled = result?.resultCode === "Cancelled";
|
||||
|
||||
if (!wasPaymentCancelled) {
|
||||
const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${this.sessionId}`;
|
||||
|
||||
await global.$logger.logError(stringToLog);
|
||||
|
||||
this.hasPaymentFailureError = true;
|
||||
}
|
||||
|
||||
this.dropinComponent?.update();
|
||||
},
|
||||
async handleError(error) {
|
||||
const wasPaymentCancelled = error?.name === "CANCEL";
|
||||
|
||||
if (!wasPaymentCancelled) {
|
||||
const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`;
|
||||
|
||||
await global.$logger.logError(stringToLog);
|
||||
|
||||
this.hasPaymentFailureError = true;
|
||||
}
|
||||
|
||||
this.dropinComponent?.update();
|
||||
},
|
||||
async saveAndSubmitWorkOrder() {
|
||||
// Final work order submit after returning from pay in advance.
|
||||
await submitWorkOrder({ submitType: submitType.SAFELITE });
|
||||
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
showIssLoadingModal
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.iss-heritage-container-width.payment-page-container {
|
||||
padding: 0 .9375rem;
|
||||
|
||||
#card-container {
|
||||
padding-top: 1.375rem;
|
||||
margin: 0;
|
||||
> * {
|
||||
padding: 0 .9375rem;
|
||||
}
|
||||
}
|
||||
|
||||
.order-summary-panel {
|
||||
margin-bottom: 1.375rem;
|
||||
}
|
||||
|
||||
.cart-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: .625rem;
|
||||
}
|
||||
|
||||
.cart-dropdown-component.cart-table {
|
||||
font-size: .8125rem;
|
||||
}
|
||||
|
||||
.footer-component:deep(.footer) {
|
||||
margin: 1.25rem 0 0 0;
|
||||
}
|
||||
|
||||
.pay-in-advance-alert {
|
||||
:deep(a) {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fade-on-route-transition {
|
||||
height: unset;
|
||||
}
|
||||
|
||||
.payment p {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -4,26 +4,29 @@
|
|||
<div class="justify-content-center">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
</div>
|
||||
<div class="iss-heritage-container-width">
|
||||
<div class="payment-page-container iss-heritage-content-container-width">
|
||||
<alert
|
||||
v-if="displayPayInAdvanceCreditCardAlert"
|
||||
name="payInAdvanceCreditCardErrorAlert"
|
||||
class="my-4"
|
||||
cmsWidgetName="PayInAdvanceCreditCardErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
@textLinkClicked="paymentFailedPayLater" />
|
||||
<alert
|
||||
v-if="displayPayInAdvanceAfterPayAlert"
|
||||
name="payInAdvanceAfterPayErrorAlert"
|
||||
class="my-4"
|
||||
cmsWidgetName="PayInAdvanceAfterpayErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
@textLinkClicked="paymentFailedPayLater" />
|
||||
|
||||
<div id="card-container">
|
||||
<div class="iss-heritage-container-width payment-page-container">
|
||||
<div id="card-container" class="row">
|
||||
<div class="col-lg-8">
|
||||
<alert
|
||||
v-if="displayPayInAdvanceCreditCardAlert"
|
||||
name="payInAdvanceCreditCardErrorAlert"
|
||||
class="pay-in-advance-alert"
|
||||
cmsWidgetName="PayInAdvanceCreditCardErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
:isCollapsible="true"
|
||||
:preventDefaultOnClick="true"
|
||||
@textLinkClicked="paymentFailedPayLater" />
|
||||
<alert
|
||||
v-if="displayPayInAdvanceAfterPayAlert"
|
||||
name="payInAdvanceAfterPayErrorAlert"
|
||||
class="pay-in-advance-alert"
|
||||
cmsWidgetName="PayInAdvanceAfterpayErrorAlertWidget"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false"
|
||||
:isCollapsible="true"
|
||||
:preventDefaultOnClick="true"
|
||||
@textLinkClicked="paymentFailedPayLater" />
|
||||
<iframe
|
||||
id="card-frame"
|
||||
ref="paymentFrame"
|
||||
|
|
@ -35,20 +38,46 @@
|
|||
allow="payment *; microphone *; geolocation *;">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="px-2">
|
||||
<hr :class="{'my-0': isCreditCard}">
|
||||
<cartDropdown
|
||||
ref="cart"
|
||||
:readOnly="true"
|
||||
:showAsPaid="false"
|
||||
recyclingModalCmsWidgetName="RecycleModal"
|
||||
servicePackageTitleWidgetName="ServicePackageTitle" />
|
||||
<hr class="my-0">
|
||||
<div class="col-lg-4 col-md-10 col-xs-12">
|
||||
<div class="order-summary-panel">
|
||||
<div class="cart-title">{{ cartTitle }}</div>
|
||||
<cartDropdown
|
||||
ref="cart"
|
||||
class="cart-dropdown-component"
|
||||
:readOnly="true"
|
||||
:showAsPaid="false"
|
||||
recyclingModalCmsWidgetName="RecycleModal"
|
||||
servicePackageTitleWidgetName="ServicePackageTitle" />
|
||||
</div>
|
||||
<div class="d-none d-lg-block">
|
||||
<buttonMain
|
||||
v-if="!afterpayModalOpen"
|
||||
class="submit-payment-button"
|
||||
variant="success"
|
||||
:preventDefaultOnClick="true"
|
||||
:buttonText="submitPaymentText"
|
||||
@clickEvent="submitPaymentAction"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="!afterpayModalOpen"
|
||||
class="switch-payment-container">
|
||||
<div class="switch-payment-text">{{ switchPaymentText }}</div>
|
||||
<button
|
||||
class="afterpay-button"
|
||||
@click.prevent="switchToAfterPay">
|
||||
{{ afterpayButtonText }}
|
||||
<img
|
||||
class="afterpay-logo"
|
||||
:src="afterpayLogo"
|
||||
alt="Afterpay Logo" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<siteFooter
|
||||
class="footer-component"
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="true"
|
||||
|
|
@ -70,6 +99,7 @@
|
|||
:target="isPaypal ? '_top' : 'card-frame'"
|
||||
method="POST"
|
||||
:action="checkoutUrl">
|
||||
<input type="hidden" name="paymentType" :value="paymentType" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="sgSessionId"
|
||||
|
|
@ -197,7 +227,7 @@
|
|||
<input
|
||||
type="hidden"
|
||||
name="billTo_postalCode"
|
||||
value="" />
|
||||
:value="zipCode" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="billTo_postalCodeShow"
|
||||
|
|
@ -408,6 +438,10 @@ import alert from '@/ux-components/alert/alert.vue';
|
|||
import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue';
|
||||
import { formatAmountInDollars } from '@/helpers/text-helper';
|
||||
import showIssLoadingModal from '@/helpers/loading-modal-helper';
|
||||
import { supportsApplePay } from '@/helpers/browser-helper';
|
||||
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||
import { submitWorkOrder } from '@/helpers/order-helper';
|
||||
import submitType from '@/constants/submit-type';
|
||||
|
||||
export default {
|
||||
name: 'payment-page',
|
||||
|
|
@ -416,7 +450,8 @@ export default {
|
|||
siteHeader,
|
||||
siteFooter,
|
||||
Form,
|
||||
alert
|
||||
alert,
|
||||
buttonMain
|
||||
},
|
||||
directives: {
|
||||
resize: {
|
||||
|
|
@ -432,6 +467,12 @@ export default {
|
|||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
const paymentType = useMainStore().order.payment.paymentMethod;
|
||||
const alertToDisplay = to.query[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT];
|
||||
if (paymentType === paymentMethods.PAYPAL || alertToDisplay) {
|
||||
useMainStore().savePaymentMethodChoice(paymentMethods.PayNow);
|
||||
}
|
||||
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
|
||||
|
|
@ -456,7 +497,7 @@ export default {
|
|||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.$nextTick(() => {
|
||||
if (vm.$refs.cart) {
|
||||
const cartItems = vm.$refs.cart.allCartItems;
|
||||
const cartItems = vm.$refs.cart.cartItems;
|
||||
vm.getPayInAdvanceLineItems(cartItems);
|
||||
}
|
||||
|
||||
|
|
@ -493,7 +534,10 @@ export default {
|
|||
totalAmount: this.getAmountDue(),
|
||||
displayAmount: this.getDisplayAmountDue(),
|
||||
payInAdvanceLineItems: '',
|
||||
shouldBlockInteraction: false
|
||||
shouldBlockInteraction: false,
|
||||
afterpayModalOpen: false,
|
||||
iframeLoaded: false,
|
||||
iframeResizerLoaded: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -531,6 +575,21 @@ export default {
|
|||
}
|
||||
return '';
|
||||
},
|
||||
cartTitle() {
|
||||
return this.getCmsContent('OrderSummaryTextWidget', widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
switchPaymentText() {
|
||||
return this.getCmsContent('SwitchPaymentTextWidget', widgetFields.TEXT_BLOCK_WIDGET.TEXT);
|
||||
},
|
||||
submitPaymentText() {
|
||||
return this.getCmsContent('SiteFooterWidget', widgetFields.FOOTER_WIDGET.FORWARD_BUTTON_TEXT);
|
||||
},
|
||||
afterpayButtonText() {
|
||||
return this.getCmsContent('AfterpayButtonWidget', widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT);
|
||||
},
|
||||
afterpayLogo() {
|
||||
return this.getCmsContent('AfterpayButtonWidget', widgetFields.CONTENT_GROUP_WIDGET.IMAGE);
|
||||
},
|
||||
isPaypal() {
|
||||
return this.paymentType === paymentMethods.PAYPAL;
|
||||
},
|
||||
|
|
@ -540,6 +599,9 @@ export default {
|
|||
isAfterPay() {
|
||||
return this.paymentType === paymentMethods.AFTERPAY;
|
||||
},
|
||||
isPayNow() {
|
||||
return this.paymentType === paymentMethods.PayNow;
|
||||
},
|
||||
displayPayInAdvanceCreditCardAlert() {
|
||||
return this.displayPayInAdvanceAlert(paymentMethods.CREDIT_CARD);
|
||||
},
|
||||
|
|
@ -651,7 +713,8 @@ export default {
|
|||
},
|
||||
getZipCode() {
|
||||
return (
|
||||
useMainStore().order.serviceLocation.zipCode
|
||||
useMainStore().order.customer.address.zipCode
|
||||
?? useMainStore().order.serviceLocation.zipCode
|
||||
?? useMainStore().order.serviceLocation.provider.address.zipCode
|
||||
);
|
||||
},
|
||||
|
|
@ -703,25 +766,38 @@ export default {
|
|||
if (iframe) {
|
||||
iframe.onload = () => {
|
||||
if (iframe.contentWindow) {
|
||||
iframe.contentWindow.postMessage('hybrid', '*');
|
||||
if (supportsApplePay()) {
|
||||
iframe.contentWindow.postMessage("hybrid-with-applepay", "*");
|
||||
} else {
|
||||
iframe.contentWindow.postMessage('hybrid', '*');
|
||||
}
|
||||
|
||||
if (this.isAfterPay) {
|
||||
this.afterpayModalOpen = true;
|
||||
iframe.contentWindow.postMessage('afterpay', '*');
|
||||
} else {
|
||||
iframe.contentWindow.postMessage('CreditCardChosen', '*');
|
||||
}
|
||||
this.iframeLoaded = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
handleIFrameContentWindowMessage(event) {
|
||||
const iframe = this.$refs.paymentFrame;
|
||||
if (typeof event.data !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data.includes('afterpayClosed')) {
|
||||
this.backButtonAction();
|
||||
this.allowIFrameResize(iframe);
|
||||
if (this.isAfterPay) {
|
||||
this.backButtonAction();
|
||||
} else {
|
||||
iframe.contentWindow.postMessage('CreditCardChosen', '*');
|
||||
this.afterpayModalOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (useMainStore().order.payment.paymentMethod !== paymentMethods.PayNow) {
|
||||
|
|
@ -738,7 +814,6 @@ export default {
|
|||
useMainStore().savePaymentMethodChoice(paymentMethods.AFTERPAY);
|
||||
}
|
||||
if (event.data.includes('applepayOpened')) {
|
||||
this.showIssLoadingModal(true);
|
||||
useMainStore().savePaymentMethodChoice(paymentMethods.APPLEPAY);
|
||||
}
|
||||
if (event.data.includes('showLoaderForPaypal')) {
|
||||
|
|
@ -762,7 +837,10 @@ export default {
|
|||
this.$route.query[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT] === payMethod
|
||||
);
|
||||
},
|
||||
paymentFailedPayLater() {
|
||||
async paymentFailedPayLater() {
|
||||
this.showIssLoadingModal(true);
|
||||
this.mainStore.savePaymentMethodChoice(paymentMethods.PAY_AT_TIME_OF_SERVICE);
|
||||
await submitWorkOrder({ submitType: submitType.SAFELITE });
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
|
|
@ -778,17 +856,108 @@ export default {
|
|||
this.$route
|
||||
);
|
||||
},
|
||||
submitPaymentAction() {
|
||||
const iframe = this.$refs.paymentFrame;
|
||||
if (iframe && iframe.contentWindow && this.iframeLoaded) {
|
||||
iframe.contentWindow.postMessage('submitPayment', '*');
|
||||
}
|
||||
},
|
||||
switchToAfterPay() {
|
||||
const iframe = this.$refs.paymentFrame;
|
||||
if (iframe && iframe.contentWindow && this.iframeLoaded) {
|
||||
this.afterpayModalOpen = true;
|
||||
this.lockIFrameSize(iframe);
|
||||
iframe.contentWindow.postMessage('afterpay-switch', '*');
|
||||
}
|
||||
},
|
||||
lockIFrameSize(iframe) {
|
||||
if (iframe && iframe.iFrameResizer) {
|
||||
iframe.iFrameResizer.removeListeners();
|
||||
}
|
||||
},
|
||||
allowIFrameResize(iframe) {
|
||||
if (iframe) {
|
||||
iframeResize({ checkOrigin: false }, iframe);
|
||||
}
|
||||
},
|
||||
showIssLoadingModal
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.iss-heritage-container-width {
|
||||
.payment-page-container {
|
||||
position: relative;
|
||||
min-height: 1px;
|
||||
padding-left: .9375rem;
|
||||
padding-right: .9375rem;
|
||||
.iss-heritage-container-width.payment-page-container {
|
||||
padding: 0 .9375rem;
|
||||
|
||||
#card-container {
|
||||
padding-top: 1.375rem;
|
||||
margin: 0;
|
||||
> * {
|
||||
padding: 0 .9375rem;
|
||||
}
|
||||
}
|
||||
|
||||
.order-summary-panel {
|
||||
margin-bottom: 1.375rem;
|
||||
}
|
||||
|
||||
.cart-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: .625rem;
|
||||
}
|
||||
|
||||
.cart-dropdown-component.cart-table {
|
||||
font-size: .8125rem;
|
||||
}
|
||||
|
||||
.submit-payment-button {
|
||||
width: 100%;
|
||||
font-weight: $font-weight-normal;
|
||||
}
|
||||
|
||||
.switch-payment-container {
|
||||
@include media-breakpoint-up(lg) {
|
||||
padding-top: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.switch-payment-text {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: .625rem;
|
||||
border-top: 1px solid #f0f1f2;
|
||||
}
|
||||
|
||||
.footer-component:deep(.footer) {
|
||||
margin: 1.25rem 0 0 0;
|
||||
}
|
||||
|
||||
.afterpay-button {
|
||||
width: 100%;
|
||||
height: 2.875rem;
|
||||
border: solid 1px #cacbcc;
|
||||
border-radius: 1.375rem;
|
||||
background-color: white;
|
||||
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||
color: $darker-gray;
|
||||
font-weight: 400;
|
||||
margin-bottom: 1.25rem;
|
||||
padding: .5rem 1rem;
|
||||
|
||||
&:focus {
|
||||
background: $background-color-selected;
|
||||
}
|
||||
&:active {
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
}
|
||||
|
||||
.pay-in-advance-alert {
|
||||
width: 80%;
|
||||
|
||||
@media (max-width: 35rem) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
160
src/layouts/payment-return-adyen/payment-return-adyen.vue
Normal file
160
src/layouts/payment-return-adyen/payment-return-adyen.vue
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<Form
|
||||
ref="theForm"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { useMainStore } from '@/store/index.js';
|
||||
import queryStrings from '@/constants/query-strings';
|
||||
import { getCartTotal } from '@/helpers/cart-helper';
|
||||
import { submitWorkOrder } from '@/helpers/order-helper.js';
|
||||
import { createAdyenCheckout, generateCcToken, getSessionInfo, mapAdyenToIssPaymentMethod } from '@/helpers/adyen-helper';
|
||||
import navigationScenarios from '@/router/router-constants/navigation-scenarios';
|
||||
import submitType from '@/constants/submit-type';
|
||||
import showIssLoadingModal from '@/helpers/loading-modal-helper';
|
||||
import { paymentMethods } from '@/constants/payment-method-constants';
|
||||
|
||||
export default {
|
||||
name: 'payment-return-adyen',
|
||||
components: {
|
||||
Form
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async mounted() {
|
||||
showIssLoadingModal(true);
|
||||
const store = useMainStore();
|
||||
|
||||
const sessionId = this.$route?.query?.sessionId;
|
||||
const redirectResult = this.$route?.query?.redirectResult;
|
||||
|
||||
if (sessionId && redirectResult) {
|
||||
let result = null;
|
||||
|
||||
try {
|
||||
result = await this.finalizeAdyenPayment(sessionId, redirectResult);
|
||||
} catch (unexpectedResult) {
|
||||
// If user cancelled payment, handle without error message
|
||||
if (unexpectedResult.code === "Cancelled" || unexpectedResult.code === "CANCEL") {
|
||||
this.$router.navigate(navigationScenarios.PAY_IN_ADVANCE_CANCEL, this.$route);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, failure scenario.
|
||||
// Payment fails, so return user to payment-page-adyen screen to try again or pay later.
|
||||
this.$router.navigate(
|
||||
navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
const sessionInfo = await getSessionInfo(sessionId, result.sessionResult);
|
||||
|
||||
const paymentMethod = mapAdyenToIssPaymentMethod(sessionInfo?.paymentMethod);
|
||||
const amountDue = getCartTotal(store.order);
|
||||
const ccToken = generateCcToken(sessionInfo);
|
||||
if (paymentMethod === paymentMethods.AFTERPAY) {
|
||||
ccToken.authCode = "831001";
|
||||
ccToken.cardType = "VS";
|
||||
ccToken.lastFour = "1111";
|
||||
ccToken.expMonth = "03";
|
||||
ccToken.expYear = "2030";
|
||||
}
|
||||
|
||||
store.savePaymentMethodChoice(paymentMethod);
|
||||
store.updateCreditCardToken(ccToken);
|
||||
store.updateNextGenSettledAmount(amountDue);
|
||||
store.clearSaveSessionPromise();
|
||||
|
||||
try {
|
||||
await this.saveAndSubmitWorkOrder();
|
||||
return;
|
||||
} catch (error) {
|
||||
this.$router.navigate(
|
||||
navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.$router.navigate(
|
||||
navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
this.$route,
|
||||
{
|
||||
[queryStrings.DISPLAY_PAY_IN_ADVANCE_ALERT]: true
|
||||
}
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
finalizeAdyenPayment(sessionId, redirectResult) {
|
||||
return new Promise((resolve, reject) => {
|
||||
createAdyenCheckout({
|
||||
session: {
|
||||
id: sessionId,
|
||||
},
|
||||
handlers: {
|
||||
onPaymentCompleted: (result, component) => {
|
||||
resolve(result);
|
||||
},
|
||||
onPaymentFailed: (result, component) => {
|
||||
if (result?.resultCode !== "Cancelled") {
|
||||
const stringToLog = `ADYEN PAYMENT NOT AUTHORIZED. Code = ${result?.resultCode}. Id = ${sessionId}`;
|
||||
|
||||
global.$logger.logError(stringToLog);
|
||||
}
|
||||
|
||||
reject({
|
||||
code: result?.resultCode,
|
||||
message: "Payment failed from Adyen",
|
||||
});
|
||||
},
|
||||
onError: (error, component) => {
|
||||
if (error?.name !== "CANCEL") {
|
||||
const stringToLog = `ADYEN ERROR. Name = ${error?.name}. Details = ${error?.message}.`;
|
||||
|
||||
global.$logger.logError(stringToLog);
|
||||
}
|
||||
|
||||
reject({
|
||||
code: error?.name,
|
||||
message: "Error from Adyen",
|
||||
});
|
||||
},
|
||||
},
|
||||
options: {},
|
||||
}).then(
|
||||
(checkout) => {
|
||||
checkout.submitDetails({
|
||||
details: {
|
||||
redirectResult: redirectResult,
|
||||
},
|
||||
});
|
||||
},
|
||||
(error) => {
|
||||
reject(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
async saveAndSubmitWorkOrder() {
|
||||
// Final work order submit after returning from pay in advance.
|
||||
await submitWorkOrder({ submitType: submitType.SAFELITE });
|
||||
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -10,8 +10,6 @@ import { getRandomString, getRandomInt } from '@/helpers/data-generation';
|
|||
import endorsementOptions from '@/constants/endorsement-options';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import vehicleSelectionOptions from '@/constants/vehicle-selection-options';
|
||||
import bailoutCode from '@/constants/bailoutCode';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
import issPageValues from '@/router/router-constants/issPage-values';
|
||||
|
||||
// Mock fetchCmsContentForPage
|
||||
|
|
@ -720,54 +718,4 @@ describe('policy-vehicles.vue', () => {
|
|||
// Assert
|
||||
expect(wrapper.vm.selectedVehicleVin).toBe(vin);
|
||||
});
|
||||
|
||||
test('selected vehicle is a non-serviceable big truck, display no service alert', async () => {
|
||||
// Arrange
|
||||
const vin = getRandomString(17, 17);
|
||||
const policyVehicle = {
|
||||
vin,
|
||||
isBigTruck: true,
|
||||
canSafeliteService: false
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: vin,
|
||||
selectedPolicyVehicle: policyVehicle,
|
||||
policyVehicles: [policyVehicle],
|
||||
policyVinFound: true
|
||||
});
|
||||
|
||||
wrapper.vm.displayNoServiceAlert = true;
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'AlertNoService' }).isVisible()).toBe(true);
|
||||
});
|
||||
|
||||
test('selected vehicle is a serviceable big truck, do not display no service alert', async () => {
|
||||
// Arrange
|
||||
const vin = getRandomString(17, 17);
|
||||
const policyVehicle = {
|
||||
vin,
|
||||
isBigTruck: true,
|
||||
canSafeliteService: true
|
||||
};
|
||||
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: vin,
|
||||
selectedPolicyVehicle: policyVehicle,
|
||||
policyVehicles: [policyVehicle],
|
||||
policyVinFound: true
|
||||
});
|
||||
|
||||
wrapper.vm.displayNoServiceAlert = false;
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.findComponent({ ref: 'AlertNoService' }).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,17 +27,10 @@
|
|||
buttonText="Add another vehicle"
|
||||
class="w-100"
|
||||
@clickEvent="addAnotherVehicle" />
|
||||
<alert
|
||||
v-if="displayNoServiceAlert"
|
||||
ref="AlertNoService"
|
||||
class="mt-3"
|
||||
cmsWidgetName="AlertVehicleSelection"
|
||||
alertClass="alert-danger"
|
||||
:isDismissable="false" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid || displayNoServiceAlert"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="backButtonAction" />
|
||||
</div>
|
||||
|
|
@ -67,10 +60,10 @@ import {
|
|||
} from '@/helpers/policy-vehicle-helper';
|
||||
import coverageType from '@/constants/coverage-type';
|
||||
import coverageStatuses from '@/constants/coverage-statuses';
|
||||
import alert from '@/ux-components/alert/alert.vue';
|
||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
||||
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||
import { buttonVariants } from '@/constants/component-variants';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
|
||||
export default {
|
||||
name: 'policy-vehicles',
|
||||
|
|
@ -80,8 +73,7 @@ export default {
|
|||
siteHeader,
|
||||
siteFooter,
|
||||
policyVehiclesQuestion,
|
||||
Form,
|
||||
alert
|
||||
Form
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
|
|
@ -103,7 +95,6 @@ export default {
|
|||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
},
|
||||
displayNoServiceAlert: false,
|
||||
buttonVariants
|
||||
};
|
||||
},
|
||||
|
|
@ -147,7 +138,6 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
async selectedVehicleVin(value) {
|
||||
this.displayNoServiceAlert = false;
|
||||
if (value === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
||||
// clear previously selected vehicle and image
|
||||
this.mainStore.resetVehicleState();
|
||||
|
|
@ -157,10 +147,6 @@ export default {
|
|||
// get vehicle details from selected VIN
|
||||
try {
|
||||
const vehicle = await this.lookupVehicleByVin(value);
|
||||
if (!vehicle?.data.canSafeliteService) {
|
||||
this.displayNoServiceAlert = true;
|
||||
return;
|
||||
}
|
||||
if (vehicle) {
|
||||
// save selected vehicle to the store
|
||||
useMainStore().updateVehicle({
|
||||
|
|
@ -201,6 +187,11 @@ export default {
|
|||
try {
|
||||
const vehicleLookupResponse = await this.lookupVehicleByVin(this.selectedVehicleVin);
|
||||
|
||||
if (!vehicleLookupResponse?.data.canSafeliteService) {
|
||||
this.mainStore.setBailout(
|
||||
bailoutMessage.HeavyTruckVehicle(vehicleLookupResponse?.data?.carId)
|
||||
);
|
||||
}
|
||||
useMainStore().updateVehicle({
|
||||
...vehicleLookupResponse.data,
|
||||
policyVehicleId: vehicle.id,
|
||||
|
|
@ -242,6 +233,11 @@ export default {
|
|||
{},
|
||||
{}
|
||||
);
|
||||
} else if (this.mainStore.isBailout) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.BAILOUT,
|
||||
this.$route
|
||||
);
|
||||
} else if (this.endorsementsForSelectedVehicle?.length > 0
|
||||
&& (this.endorsementsForSelectedVehicle?.includes(endorsementOptions.PARKING_GUARD)
|
||||
|| this.endorsementsForSelectedVehicle?.includes(endorsementOptions.EDUCATOR))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import ProviderPreference from '@/layouts/provider-preference/provider-preferenc
|
|||
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import settleAllPromises from '@/helpers/layout-helper.js';
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import { fetchCmsContentForPage, processIfStatements } from '@/helpers/cms-content-helper';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
import { useMainStore } from '@/store';
|
||||
import navigationScenarios from '@/router/router-constants/navigation-scenarios';
|
||||
|
|
@ -13,7 +13,8 @@ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
|
|||
// Mock fetchCmsContentForPage
|
||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||
fetchCmsContentForPage: jest.fn(),
|
||||
setupModalLinks: jest.fn()
|
||||
setupModalLinks: jest.fn(),
|
||||
processIfStatements: jest.fn()
|
||||
}));
|
||||
|
||||
/** @ignore */
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@
|
|||
// Import Supporting Files
|
||||
import {
|
||||
fetchCmsContentForPage,
|
||||
processIfStatements,
|
||||
setupModalLinks
|
||||
} from '@/helpers/cms-content-helper';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import errorMessages from '@/constants/error-messages';
|
||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||
import showIssLoadingModal from '@/helpers/loading-modal-helper';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||
|
|
@ -133,26 +133,14 @@ export default {
|
|||
return this.getCmsContent('ScheduleWithSafeliteText', 'BodyText');
|
||||
},
|
||||
scheduleWithOtherText() {
|
||||
return this.getCmsContent('ScheduleWithOtherText', 'BodyText');
|
||||
const text = this.getCmsContent('ScheduleWithOtherText', 'BodyText');
|
||||
return processIfStatements(text, 'custom', this.getStateSpecificText);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
setupModalLinks(this);
|
||||
},
|
||||
methods: {
|
||||
getHeaderTextFromCms(cmsWidgetName) {
|
||||
const headerText = this.getCmsContent(cmsWidgetName, 'HeaderText');
|
||||
return headerText?.replace(
|
||||
'{custom:SafeliteLogo}',
|
||||
"<span class='safeliteLogo'></span>"
|
||||
);
|
||||
},
|
||||
getSubheaderTextFromCms(cmsWidgetName) {
|
||||
return this.getCmsContent(cmsWidgetName, 'SubheaderText');
|
||||
},
|
||||
getBodyTextFromCms(cmsWidgetName) {
|
||||
return this.getCmsContent(cmsWidgetName, 'BodyText');
|
||||
},
|
||||
arePagePrerequisiteValid() {
|
||||
return true;
|
||||
},
|
||||
|
|
@ -191,6 +179,9 @@ export default {
|
|||
},
|
||||
openStateSteeringModal() {
|
||||
this.$refs[STEERING_MODAL_REF_NAME].openModal();
|
||||
},
|
||||
getStateSpecificText(value) {
|
||||
return this.mainStore.order.customer.address.state?.toLowerCase() === value?.toLowerCase();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,21 +1,24 @@
|
|||
<template>
|
||||
<modal
|
||||
:ref="ModalName"
|
||||
:modalId="ModalName"
|
||||
:footerButtonText="ModalCloseButtonText"
|
||||
@footerButtonEvent="footerButtonClick">
|
||||
<h5 class="text-center mb-4">
|
||||
{{ ModalHeadline }}
|
||||
</h5>
|
||||
<div>
|
||||
<div
|
||||
class="mb-4"
|
||||
v-html="ModalBodyText"></div>
|
||||
<div
|
||||
v-if="ModalSubBodyText"
|
||||
v-html="ModalSubBodyText"></div>
|
||||
</div>
|
||||
</modal>
|
||||
<div class="steering-modal-container">
|
||||
<modal
|
||||
:ref="ModalName"
|
||||
:modalId="ModalName"
|
||||
:footerButtonText="ModalCloseButtonText"
|
||||
@footerButtonEvent="footerButtonClick">
|
||||
<h5 class="text-center mb-4 headline-text">
|
||||
{{ ModalHeadline }}
|
||||
</h5>
|
||||
<div>
|
||||
<div
|
||||
class="mb-4"
|
||||
v-html="ModalBodyText"></div>
|
||||
<div
|
||||
class="mb-4"
|
||||
v-if="ModalSubBodyText"
|
||||
v-html="ModalSubBodyText"></div>
|
||||
</div>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -74,24 +77,13 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal {
|
||||
&.modal-component {
|
||||
.modal-dialog {
|
||||
.modal-content {
|
||||
.modal-body {
|
||||
.modal-sub-body {
|
||||
color: $gray-600;
|
||||
}
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p {
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.modal) {
|
||||
.modal-footer {
|
||||
justify-content: center;
|
||||
button {
|
||||
background-color: $heritage-blue-secondary;
|
||||
color: $white;
|
||||
width: 71%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,53 +1,58 @@
|
|||
<template>
|
||||
<modal
|
||||
:ref="ModalName"
|
||||
:modalId="ModalName"
|
||||
:footerButtonText="ModalCloseButtonText"
|
||||
:isButtonDisabled="isButtonDisabled"
|
||||
@footerButtonEvent="footerButtonClick">
|
||||
<div class="form-test-invalid">
|
||||
<h5 class="text-center mb-4">
|
||||
{{ ModalHeadline }}
|
||||
</h5>
|
||||
<div>
|
||||
<div
|
||||
class="mb-4"
|
||||
v-html="ModalBodyText"></div>
|
||||
<tpaRecalToggle
|
||||
class="mb-5"
|
||||
cmsWidgetName="TPARecalModalToggle" />
|
||||
<buttonQuestion
|
||||
ref="tpaRecalQuestion"
|
||||
v-model="tpaRecalAnswer"
|
||||
class="radioQuestion safelite-or-tpa-question windshield-chip-count-question mb-4"
|
||||
:cmsWidgetName="buttonCmsWidgetName"
|
||||
:questionText="tpaRecalQuestionText"
|
||||
:answers="tpaRecalAnswersFromCms"
|
||||
groupName="tpaRecalQuestion"
|
||||
buttonID="tpaRecalQuestion"
|
||||
buttonTypeString="listButtonHorizontal"
|
||||
isRequired></buttonQuestion>
|
||||
<checkBox
|
||||
v-if="showAcknowledgementCheckbox"
|
||||
ref="tpaAcknowledgement"
|
||||
v-model="acknowledged"
|
||||
class="mb-2"
|
||||
:class="showAcknowledgementError && ' has-error'"
|
||||
:validationRules="rules.optionRequired"
|
||||
checkboxName="tpaAcknowledgement"
|
||||
buttonID="tpaAcknowledgement"
|
||||
:tabIndex="0"
|
||||
:checkboxLabel="ModalSubBodyText"
|
||||
:screenReaderOnlyText="ModalSubBodyText"
|
||||
isRequired />
|
||||
<div
|
||||
v-if="showAcknowledgementError || showNoSelectionError"
|
||||
class="row form-test-error mt-1">
|
||||
<p>{{ errorMessage }}</p>
|
||||
<div class="tpa-recal-modal-container">
|
||||
<modal
|
||||
:ref="ModalName"
|
||||
:modalId="ModalName"
|
||||
:footerButtonText="ModalCloseButtonText"
|
||||
:isButtonDisabled="isButtonDisabled"
|
||||
@footerButtonEvent="footerButtonClick"
|
||||
:displayCloseButton="false"
|
||||
:displayCloseLink="true">
|
||||
<div class="form-test-invalid">
|
||||
<h5>
|
||||
{{ ModalHeadline }}
|
||||
</h5>
|
||||
<div>
|
||||
<div
|
||||
class="mb-4"
|
||||
v-html="ModalBodyText"></div>
|
||||
<tpaRecalToggle
|
||||
class="mb-5"
|
||||
cmsWidgetName="TPARecalModalToggle" />
|
||||
<buttonQuestion
|
||||
ref="tpaRecalQuestion"
|
||||
v-model="tpaRecalAnswer"
|
||||
class="tpa-recal-question"
|
||||
:cmsWidgetName="buttonCmsWidgetName"
|
||||
:questionText="tpaRecalQuestionText"
|
||||
:answers="tpaRecalAnswersFromCms"
|
||||
groupName="tpaRecalQuestion"
|
||||
buttonID="tpaRecalQuestion"
|
||||
buttonTypeString="listButtonHorizontal"
|
||||
isRequired>
|
||||
</buttonQuestion>
|
||||
<checkBox
|
||||
v-if="showAcknowledgementCheckbox"
|
||||
ref="tpaAcknowledgement"
|
||||
v-model="acknowledged"
|
||||
class="mb-2 mt-4"
|
||||
:class="showAcknowledgementError && ' has-error'"
|
||||
:validationRules="rules.optionRequired"
|
||||
checkboxName="tpaAcknowledgement"
|
||||
buttonID="tpaAcknowledgement"
|
||||
:tabIndex="0"
|
||||
:checkboxLabel="ModalSubBodyText"
|
||||
:screenReaderOnlyText="ModalSubBodyText"
|
||||
isRequired />
|
||||
<div
|
||||
v-if="showAcknowledgementError || showNoSelectionError"
|
||||
class="row form-test-error mt-1">
|
||||
<p>{{ errorMessage }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -152,39 +157,51 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal {
|
||||
&.modal-component {
|
||||
.modal-dialog {
|
||||
.modal-content {
|
||||
.modal-body {
|
||||
.modal-sub-body {
|
||||
color: $gray-600;
|
||||
}
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p {
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
}
|
||||
:deep(.modal) {
|
||||
h5 {
|
||||
font-size: 1.625rem;
|
||||
margin-bottom: .625rem;
|
||||
}
|
||||
.modal-body {
|
||||
color: #4d4e53;
|
||||
}
|
||||
.modal-footer {
|
||||
padding-top: 22px;
|
||||
button {
|
||||
background-color: $green;
|
||||
color: $white;
|
||||
font-weight: $font-weight-bold;
|
||||
&:hover {
|
||||
background-color: $green;
|
||||
}
|
||||
}
|
||||
}
|
||||
.safelite-or-tpa-question {
|
||||
:deep(.question-text) {
|
||||
span {
|
||||
.tpa-recal-question > div:first-of-type {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.button-question {
|
||||
fieldset {
|
||||
box-shadow: 0px 2px 5px -5px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
}
|
||||
.list-button-horizontal {
|
||||
&.selected {
|
||||
input {
|
||||
background-color: $background-color-selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
.form-check {
|
||||
p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.form-check-input:checked {
|
||||
+ label p {
|
||||
font-size: 1rem;
|
||||
color: #4d4e53;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-test-error {
|
||||
p {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
:schedulingInshopAvailabilityRating="inShopAvailabilityRating"
|
||||
@appointmentTypeChanged="appointmentTypeChangedFromServiceLocation"
|
||||
@cityUpdated="cityUpdatedFromServiceLocation"
|
||||
@clearMobileData="clearMobileDataFromServiceLocation"
|
||||
@inShopZipUpdated="inShopZipUpdatedFromServiceLocation"
|
||||
@mobileZipUpdated="mobileZipUpdatedFromServiceLocation"
|
||||
@providerChanged="providerChangedFromServiceLocation" />
|
||||
|
|
@ -89,9 +90,8 @@ import {
|
|||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import showIssLoadingModal from '@/helpers/loading-modal-helper.js';
|
||||
import {
|
||||
getProviderData,
|
||||
getZipCodeData,
|
||||
onProviderChanged
|
||||
getPricedMobileFeePart,
|
||||
getZipCodeData
|
||||
} from '@/helpers/service-location-helper';
|
||||
import { Form } from 'vee-validate';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
|
|
@ -225,11 +225,24 @@ export default {
|
|||
async beforeRouteEnter(to, from, next) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
const { isMobileAppointment, storeServiceLocation, storeSelectedProvider, serviceZipCode } = getProviderData();
|
||||
const zipCodeData = getZipCodeData(serviceZipCode);
|
||||
const serviceabilityDetailsPromise = useMainStore().getServiceabilityDetails(serviceZipCode);
|
||||
const providersPromise = useMainStore().getSafeliteProviders(serviceZipCode, 150);
|
||||
let storeServiceLocation = useMainStore().order.serviceLocation;
|
||||
let storeSelectedProvider = storeServiceLocation?.provider;
|
||||
|
||||
const storeSelectedSchedule = useMainStore().order.schedule;
|
||||
if (storeSelectedProvider?.providerNumber && !storeSelectedSchedule?.routeCode) {
|
||||
useMainStore().resetServiceLocationProvider();
|
||||
storeServiceLocation = useMainStore().order.serviceLocation;
|
||||
storeSelectedProvider = storeServiceLocation?.provider;
|
||||
}
|
||||
const storeSelectedAppointmentType = storeServiceLocation?.appointmentType;
|
||||
const isMobileAppointment = storeSelectedAppointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| storeSelectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
const serviceZipCode = storeServiceLocation?.zipCode || useMainStore().order.customer.address.zipCode;
|
||||
const zipCodeData = getZipCodeData(serviceZipCode);
|
||||
const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode);
|
||||
const serviceabilityDetailsPromise = useMainStore().getServiceabilityDetails(serviceZipCode);
|
||||
const getGlassFeesPromise = useMainStore().getGlassFees();
|
||||
const providersPromise = useMainStore().getSafeliteProviders(serviceZipCode, 150);
|
||||
const premiumFeePromise = useMainStore().getMobilePremiumFee();
|
||||
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
|
||||
if (result.data) {
|
||||
|
|
@ -244,6 +257,14 @@ export default {
|
|||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'mobileFeePart',
|
||||
promise: mobileFeePartPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'glassFees',
|
||||
promise: getGlassFeesPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'serviceabilityDetails',
|
||||
promise: serviceabilityDetailsPromise
|
||||
|
|
@ -256,10 +277,6 @@ export default {
|
|||
resultKey: 'providers',
|
||||
promise: providersPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'providerChanged',
|
||||
promise: onProviderChanged()
|
||||
},
|
||||
{
|
||||
resultKey: 'premiumFeeWithPrice',
|
||||
promise: premiumFeeWithPricePromise
|
||||
|
|
@ -268,7 +285,7 @@ export default {
|
|||
|
||||
// use resultMap to populate layout content.
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
const providersUnderOneHundredMiles = resultMap.providers?.shopProviders?.filter((provider) => provider.distanceMiles <= 100);
|
||||
const providersUnderOneHundredMiles = resultMap.providers?.shopProviders?.filter((provider) => provider.distanceInMiles <= 100);
|
||||
const serviceLocationData = {
|
||||
defaultMobileZipCode: isMobileAppointment
|
||||
? storeServiceLocation?.zipCode
|
||||
|
|
@ -285,9 +302,9 @@ export default {
|
|||
useMainStore().updateIsSafeliteProvider(true);
|
||||
next(async (vm) => {
|
||||
const foundProviderInFullList = resultMap.providers?.shopProviders
|
||||
.find((provider) => provider.providerNumber === storeSelectedProvider?.providerNumber) || resultMap.providers?.shopProviders[0];
|
||||
.find((provider) => provider.providerNumber === storeSelectedProvider?.providerNumber) || null;
|
||||
const foundProviderInHundredMiles = providersUnderOneHundredMiles
|
||||
.find((provider) => provider.providerNumber === storeSelectedProvider?.providerNumber) || providersUnderOneHundredMiles[0];
|
||||
.find((provider) => provider.providerNumber === storeSelectedProvider?.providerNumber) || null;
|
||||
|
||||
if (!foundProviderInHundredMiles && !foundProviderInFullList) {
|
||||
if (storeSelectedProvider?.providerNumber && resultMap.providers?.shopProviders) {
|
||||
|
|
@ -296,11 +313,12 @@ export default {
|
|||
} else if (!foundProviderInHundredMiles && foundProviderInFullList) {
|
||||
serviceLocationData.providers?.shopProviders.push(foundProviderInFullList);
|
||||
}
|
||||
|
||||
const initialServiceLocationObj = {
|
||||
mobileProviderNumber: isMobileAppointment
|
||||
? storeSelectedProvider?.providerNumber
|
||||
: null,
|
||||
provider: isMobileAppointment ? null : foundProviderInFullList,
|
||||
provider: isMobileAppointment ? null : foundProviderInFullList || resultMap.providers?.shopProviders[0] || null,
|
||||
zipCode: useMainStore().order.serviceLocation.zipCode || useMainStore().order.customer.address.zipCode,
|
||||
zipCodeCtu: resultMap.zipCodeData?.zipCodeCtu
|
||||
};
|
||||
|
|
@ -319,8 +337,10 @@ export default {
|
|||
return {
|
||||
inShopAvailabilityRating: 'high',
|
||||
inShopDatesData: [],
|
||||
isDatePickerRefreshing: false,
|
||||
isMobileView: false,
|
||||
mobileDatesData: [],
|
||||
mobileFeePart: null,
|
||||
mobilePremiumAppointmentFee: null,
|
||||
mobileProviderNumber: null,
|
||||
selectableDatesData: [],
|
||||
|
|
@ -341,14 +361,18 @@ export default {
|
|||
return false;
|
||||
}
|
||||
|
||||
const validMobileAppointmentType = ((this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
|
||||
&& serviceLocationToUse.mobileProviderNumber);
|
||||
const validInShopAppointmentType = ((this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP
|
||||
|| this.selectedAppointmentType === AppointmentTypeStrings.DROP_OFF)
|
||||
&& (this.selectedProvider?.providerNumber || serviceLocationToUse.provider?.providerNumber));
|
||||
|
||||
const serviceLocationPreReqs = serviceLocationToUse.zipCode !== null
|
||||
&& serviceLocationToUse.zipCodeCtu !== null
|
||||
&& serviceLocationToUse.appointmentType !== null
|
||||
&& (((this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
|
||||
&& serviceLocationToUse.mobileProviderNumber)
|
||||
|| ((this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP || this.selectedAppointmentType === AppointmentTypeStrings.DROP_OFF)
|
||||
&& (this.selectedProvider?.providerNumber || serviceLocationToUse.provider?.providerNumber)));
|
||||
&& (validMobileAppointmentType || validInShopAppointmentType)
|
||||
&& !this.isDatePickerRefreshing;
|
||||
|
||||
const damageInfo = useMainStore().order.damage.isRepair
|
||||
|| (useMainStore().order.lineItems?.glassParts != null && useMainStore().order.lineItems.glassParts.length > 0);
|
||||
|
|
@ -453,6 +477,14 @@ export default {
|
|||
cityUpdatedFromServiceLocation(newCity) {
|
||||
this.selectedServiceLocationCity = newCity;
|
||||
},
|
||||
clearMobileDataFromServiceLocation() {
|
||||
if (this.selectedServiceLocation) {
|
||||
this.selectedServiceLocation.mobileProviderNumber = null;
|
||||
}
|
||||
this.mobileDatesData = [];
|
||||
this.mobileProviderNumber = null;
|
||||
this.selectedMobileZipCode = null;
|
||||
},
|
||||
dateSelectedFromPicker(date) {
|
||||
this.selectedDate = date;
|
||||
this.showDatePickerError = false;
|
||||
|
|
@ -531,7 +563,6 @@ export default {
|
|||
daysFromStart: endDateObject.daysFromStart || null
|
||||
}))
|
||||
.catch(() => {
|
||||
console.warn('Error fetching initial available dates...');
|
||||
return {
|
||||
todayDate: todayDateString,
|
||||
initialViewStartDate,
|
||||
|
|
@ -647,9 +678,7 @@ export default {
|
|||
}
|
||||
},
|
||||
mobileZipUpdatedFromServiceLocation(mobileZipServiceLocation) {
|
||||
if (mobileZipServiceLocation
|
||||
&& (this.mobileProviderNumber !== mobileZipServiceLocation.mobileProviderNumber
|
||||
|| !this.hasNeededServiceLocationData)) {
|
||||
if (mobileZipServiceLocation) {
|
||||
this.mobileProviderNumber = mobileZipServiceLocation.mobileProviderNumber;
|
||||
this.selectedMobileZipCode = mobileZipServiceLocation.zipCode;
|
||||
this.selectedServiceLocation = mobileZipServiceLocation;
|
||||
|
|
@ -661,22 +690,27 @@ export default {
|
|||
},
|
||||
async providerChangedFromServiceLocation(newProvider) {
|
||||
this.selectedProvider = newProvider?.provider;
|
||||
if (newProvider?.provider) {
|
||||
this.mainStore.updateServiceLocation(newProvider);
|
||||
if (newProvider?.refreshDatePicker && newProvider.provider) {
|
||||
this.mainStore.updateServiceLocationProvider(newProvider.provider);
|
||||
|
||||
showIssLoadingModal(true);
|
||||
await onProviderChanged();
|
||||
if (newProvider.refreshDatePicker) {
|
||||
await this.refreshDatePicker();
|
||||
} else {
|
||||
showIssLoadingModal(false);
|
||||
}
|
||||
await this.mainStore.getBillToInfo(newProvider.provider?.providerNumber)
|
||||
.then(() => {
|
||||
this.refreshDatePicker();
|
||||
})
|
||||
.catch(() => {
|
||||
console.warn('Error fetching bill to info...');
|
||||
showIssLoadingModal(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
async refreshDatePicker() {
|
||||
this.resetLocalFlags();
|
||||
this.isDatePickerRefreshing = true;
|
||||
await this.getDatePickerInitialData().then((data) => {
|
||||
this.selectableDatesData = data.initialShopTimeSlotsResponse;
|
||||
this.$refs.datePicker.initializeComponent(data);
|
||||
this.isDatePickerRefreshing = false;
|
||||
showIssLoadingModal(false);
|
||||
});
|
||||
},
|
||||
|
|
@ -700,7 +734,7 @@ export default {
|
|||
appointmentTypeToUse = AppointmentTypeStrings.DROP_OFF;
|
||||
}
|
||||
|
||||
this.mainStore.updateAppointmentType(appointmentTypeToUse);
|
||||
await this.$refs.serviceLocation.forwardButtonAction(appointmentTypeToUse);
|
||||
this.mainStore.saveSchedule(this.selectedTimeSlotInfo.timeSlot);
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ const mountOptions = {
|
|||
alert: true,
|
||||
textBlock: true,
|
||||
appointmentTypeQuestion: true,
|
||||
contentGroupModal: true,
|
||||
recalModal: true,
|
||||
siteFooter: true,
|
||||
siteHeader: true,
|
||||
siteSubHeader: true,
|
||||
|
|
@ -203,7 +203,7 @@ describe('service-location.vue', () => {
|
|||
const newMobileServiceZipCode = '45433';
|
||||
|
||||
// Act
|
||||
mobileServiceZipCodeQuestion.vm.$emit('update:modelValue', newMobileServiceZipCode);
|
||||
mobileServiceZipCodeQuestion.vm.$emit('service-zip-code-updated', newMobileServiceZipCode);
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
<template>
|
||||
<div class="service-location">
|
||||
<alert
|
||||
v-if="displayRecalibrationWarning"
|
||||
ref="alertRecalNoMobile"
|
||||
cmsWidgetName="AlertRecalNoMobileWidget"
|
||||
alertClass="alert-warning"
|
||||
@textLinkClicked="openModalAction" />
|
||||
<alert
|
||||
v-if="displayBigTruckNoShops"
|
||||
ref="alertBigTruckNoShops"
|
||||
|
|
@ -19,6 +13,12 @@
|
|||
<span
|
||||
v-if="!requiresInshopRecalibration">{{ appointmentQuestionText }}</span>
|
||||
</div>
|
||||
<alert
|
||||
v-if="displayRecalibrationWarning"
|
||||
ref="alertRecalNoMobile"
|
||||
cmsWidgetName="AlertRecalNoMobileWidget"
|
||||
alertClass="alert-warning"
|
||||
@textLinkClicked="openModalAction" />
|
||||
<alert
|
||||
v-if="displayServiceableInshopOnly"
|
||||
ref="alertInshopOnly"
|
||||
|
|
@ -96,13 +96,14 @@
|
|||
</div>
|
||||
<serviceZipQuestion
|
||||
ref="mobileServiceZipCodeQuestion"
|
||||
v-model="mobileZipCode"
|
||||
customInputId="mobileServiceZipCode"
|
||||
class="mobile-service-zip-question"
|
||||
:parentZipCode="mobileZipCode"
|
||||
:placeholderText="mobileZipPlaceholder"
|
||||
:serviceZipFormatErrorMessage="errorMessages.MOBILE_SERVICE_ZIP_FORMAT"
|
||||
:hasError="mobileZipError !== ''"
|
||||
cmsWidgetName="MobileZipWidget" />
|
||||
cmsWidgetName="MobileZipWidget"
|
||||
@serviceZipCodeUpdated="handleServiceZipCodeChanged" />
|
||||
<div
|
||||
v-if="mobileZipError"
|
||||
ref="errorMessageDiv"
|
||||
|
|
@ -116,9 +117,8 @@
|
|||
cmsWidgetName="MobileFeeDisclaimerWidget"
|
||||
typeStyle="disclaimer" />
|
||||
</div>
|
||||
<contentGroupModal
|
||||
<recalModal
|
||||
:ref="RECAL_MODAL_REF_NAME"
|
||||
cssModalHeadlineClass="text-center"
|
||||
cmsWidgetName="RecalModal" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -139,10 +139,10 @@ import alert from '@/ux-components/alert/alert.vue';
|
|||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||
import appointmentTypeQuestion from '@/layouts/schedule-page/service-location/appointment-type-question/appointment-type-question.vue';
|
||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
|
||||
import shopAddress from '@/layouts/schedule-page/service-location/shop-address/shop-address.vue';
|
||||
import serviceZipQuestion from '@/layouts/schedule-page/service-location/service-zip-question/service-zip-question.vue';
|
||||
import widgetFields from '@/constants/cms-widget-fields';
|
||||
import recalModal from '@/iss-components/recal-modal/recal-modal.vue';
|
||||
|
||||
const RECAL_MODAL_REF_NAME = 'RecalModal';
|
||||
|
||||
|
|
@ -152,12 +152,12 @@ export default {
|
|||
alert,
|
||||
textBlock,
|
||||
appointmentTypeQuestion,
|
||||
contentGroupModal,
|
||||
shopAddress,
|
||||
serviceZipQuestion
|
||||
serviceZipQuestion,
|
||||
recalModal
|
||||
},
|
||||
mixins: [baseFormMixin],
|
||||
emits: ['appointment-type-changed', 'city-updated', 'in-shop-zip-updated', 'mobile-zip-updated', 'provider-changed'],
|
||||
emits: ['appointment-type-changed', 'city-updated', 'clear-mobile-data', 'in-shop-zip-updated', 'mobile-zip-updated', 'provider-changed'],
|
||||
props: {
|
||||
schedulingInshopAvailabilityRating: {
|
||||
type: String,
|
||||
|
|
@ -182,6 +182,7 @@ export default {
|
|||
isRecalibrationServiceableMobile: null,
|
||||
selectedAppointmentType: this.getSelectedAppointmentType(),
|
||||
selectedProvider: this.getSelectedProvider(),
|
||||
mobileFeePart: null,
|
||||
mobileProviderNumber: null,
|
||||
zipContainsMilitaryBase: false,
|
||||
zipCodeCtu: null,
|
||||
|
|
@ -236,7 +237,8 @@ export default {
|
|||
);
|
||||
},
|
||||
isMobile() {
|
||||
return this.selectedAppointmentType === AppointmentTypeStrings.MOBILE;
|
||||
return this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|
||||
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
||||
},
|
||||
isServiceableInshop() {
|
||||
if (this.isRecalibrationServiceableInshop !== null) {
|
||||
|
|
@ -298,16 +300,7 @@ export default {
|
|||
},
|
||||
async mobileZipCode(newZip, oldZip) {
|
||||
if (newZip !== '' && newZip !== oldZip && !this.initializingData) {
|
||||
showIssLoadingModal(true);
|
||||
await this.updateMobileZip();
|
||||
const updateMobileZipServiceLocationObj = {
|
||||
mobileProviderNumber: this.mobileProviderNumber,
|
||||
provider: null,
|
||||
refreshDatePicker: true,
|
||||
zipCode: this.zipCode,
|
||||
zipCodeCtu: this.zipCodeCtu
|
||||
};
|
||||
this.$emit('mobile-zip-updated', updateMobileZipServiceLocationObj);
|
||||
await this.processMobileZipCodeChange();
|
||||
}
|
||||
},
|
||||
schedulingInshopAvailabilityRating(newRating) {
|
||||
|
|
@ -339,27 +332,16 @@ export default {
|
|||
}
|
||||
},
|
||||
selectedProvider(newProvider, oldProvider) {
|
||||
if (newProvider?.providerNumber !== oldProvider?.providerNumber) {
|
||||
if (newProvider?.providerNumber !== oldProvider?.providerNumber || this.availabilityRating === null) {
|
||||
const appointmentIsInshop = this.isInshop;
|
||||
const returnedProvider = {
|
||||
refreshDatePicker: appointmentIsInshop && oldProvider?.providerNumber !== null,
|
||||
state: this.state,
|
||||
zipCode: this.zipCode,
|
||||
zipCodeCtu: this.zipCodeCtu,
|
||||
appointmentType: this.selectedAppointmentType,
|
||||
provider: !this.isMobile ? newProvider : {
|
||||
providerNumber: this.mobileProviderNumber,
|
||||
address: {
|
||||
streetAddress: null,
|
||||
city: null,
|
||||
state: null,
|
||||
zipCode: null,
|
||||
zipCodeCtu: null
|
||||
}
|
||||
}
|
||||
provider: newProvider,
|
||||
refreshDatePicker: appointmentIsInshop && oldProvider?.providerNumber !== null
|
||||
};
|
||||
|
||||
this.$emit('provider-changed', returnedProvider);
|
||||
if (newProvider?.providerNumber !== oldProvider?.providerNumber) {
|
||||
this.$emit('provider-changed', returnedProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -369,6 +351,34 @@ export default {
|
|||
await this.setData(initialData);
|
||||
this.initializingData = false;
|
||||
},
|
||||
async forwardButtonAction(appointmentType) {
|
||||
let provider = this.selectedProvider;
|
||||
this.mainStore.updateMobileFee(null);
|
||||
if (this.isMobile) {
|
||||
if (this.mainStore.isNoComp || this.mainStore.isITAC) {
|
||||
this.mainStore.updateMobileFee(this.mobileFeePart);
|
||||
}
|
||||
|
||||
provider = {
|
||||
providerNumber: this.mobileProviderNumber,
|
||||
address: {
|
||||
streetAddress: null,
|
||||
city: null,
|
||||
state: null,
|
||||
zipCode: null,
|
||||
zipCodeCtu: null
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.mainStore.updateServiceLocation({
|
||||
state: this.state,
|
||||
zipCode: this.zipCode,
|
||||
zipCodeCtu: this.zipCodeCtu,
|
||||
appointmentType: appointmentType || this.selectedAppointmentType,
|
||||
provider
|
||||
});
|
||||
},
|
||||
openModalAction(modalName) {
|
||||
this.$refs[modalName].openModal();
|
||||
},
|
||||
|
|
@ -427,6 +437,32 @@ export default {
|
|||
this.$emit('in-shop-zip-updated', inShopZipServiceLocationObj);
|
||||
});
|
||||
},
|
||||
async handleServiceZipCodeChanged(serviceZipCodeFromQuestion) {
|
||||
if (serviceZipCodeFromQuestion !== this.mobileZipCode) {
|
||||
// Can probs just make this one call but have to think about initialization flow and not wanting to trigger extra calls on load
|
||||
this.mobileZipCode = serviceZipCodeFromQuestion;
|
||||
} else {
|
||||
await this.processMobileZipCodeChange();
|
||||
}
|
||||
},
|
||||
async processMobileZipCodeChange() {
|
||||
showIssLoadingModal(true);
|
||||
await this.updateMobileZip();
|
||||
|
||||
if (!this.mobileZipError) {
|
||||
const updateMobileZipServiceLocationObj = {
|
||||
mobileProviderNumber: this.mobileProviderNumber,
|
||||
provider: null,
|
||||
refreshDatePicker: true,
|
||||
zipCode: this.zipCode,
|
||||
zipCodeCtu: this.zipCodeCtu
|
||||
};
|
||||
this.$emit('mobile-zip-updated', updateMobileZipServiceLocationObj);
|
||||
} else {
|
||||
this.$emit('clear-mobile-data');
|
||||
showIssLoadingModal(false);
|
||||
}
|
||||
},
|
||||
setCtuForMobile(val) {
|
||||
this.zipCodeCtu = val;
|
||||
},
|
||||
|
|
@ -446,6 +482,10 @@ export default {
|
|||
this.setServiceabilityDetails(initialData.serviceabilityDetails);
|
||||
}
|
||||
|
||||
if (initialData.mobileFeePart) {
|
||||
this.mobileFeePart = initialData.mobileFeePart;
|
||||
}
|
||||
|
||||
if (initialData.providers) {
|
||||
this.setMobileProviderNumber(initialData.providers.mobileProviderNumber);
|
||||
let foundMatch = false;
|
||||
|
|
@ -462,12 +502,22 @@ export default {
|
|||
this.selectedProvider = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (initialData.glassFees) {
|
||||
useMainStore().getCombinedQuote(initialData.glassFees)
|
||||
.then((combinedQuote) => {
|
||||
this.setGlassFeeItems(combinedQuote);
|
||||
});
|
||||
}
|
||||
},
|
||||
setContainsMilitaryBase(val) {
|
||||
if (this.zipContainsMilitaryBase !== val) {
|
||||
this.zipContainsMilitaryBase = val;
|
||||
}
|
||||
},
|
||||
setGlassFeeItems(newGlassFeeItems) {
|
||||
this.mainStore.updateGlassFees(newGlassFeeItems);
|
||||
},
|
||||
setMobileProviderNumber(providerNumber) {
|
||||
this.mobileProviderNumber = providerNumber;
|
||||
},
|
||||
|
|
@ -569,7 +619,23 @@ $page-side-padding: 1.5rem;
|
|||
}
|
||||
}
|
||||
div.alert {
|
||||
margin-top: 0.625rem;
|
||||
margin-top: 1.25rem;
|
||||
|
||||
&.widget-name-AlertLowAvailabilityInshopWidget {
|
||||
@include media-breakpoint-up(xs) {
|
||||
:deep(.alert-headline-text-container) {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.375rem;
|
||||
letter-spacing: 0.45px;
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-up(xl) {
|
||||
:deep(.alert-headline-text-container) {
|
||||
padding: 0rem 0.625rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
button.looka-likea-link {
|
||||
background: none;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,25 @@
|
|||
import { mount } from '@vue/test-utils';
|
||||
import crypto from 'crypto';
|
||||
import serviceZipModalQuestion from '@/layouts/schedule-page/service-location/service-zip-modal-question/service-zip-modal-question.vue';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { useMainStore } from '@/store';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import baseMixin from '@/mixins/base-mixin';
|
||||
|
||||
global.crypto = crypto;
|
||||
|
||||
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
|
||||
|
||||
// Mock fetchCmsContentForPage
|
||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||
fetchCmsContentForPage: jest.fn()
|
||||
}));
|
||||
jest.mock('@/global-methods', () => ({
|
||||
callHttpClient: jest.fn()
|
||||
}));
|
||||
|
||||
jest.mock('@/digital-components/textbox-question/textbox-question', () => ({
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => widgetName[cmsFieldName])
|
||||
}));
|
||||
|
|
@ -71,20 +87,48 @@ const mockModalCmsContent = {
|
|||
FooterText: 'Sample modal footer text here.'
|
||||
};
|
||||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||
if (widgetName === linkWidgetName) {
|
||||
return mockLinkCmsContent[cmsFieldName];
|
||||
}
|
||||
function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRunAfterInitializingStore = () => {}, queryString = {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
},
|
||||
route: { query: { issPage: 'page-name', ...queryString }, params: {} }
|
||||
});
|
||||
|
||||
if (widgetName === modalWidgetName) {
|
||||
return mockModalCmsContent[cmsFieldName];
|
||||
}
|
||||
return null;
|
||||
})
|
||||
}
|
||||
};
|
||||
const testingPinia = createTestingPinia({
|
||||
initialState: {
|
||||
main: mainInitialState
|
||||
}
|
||||
});
|
||||
useMainStore(testingPinia);
|
||||
methodToRunAfterInitializingStore();
|
||||
useMainStore().getServiceabilityDetails = jest.fn().mockReturnValue(mockGetServiceabilityDetails);
|
||||
|
||||
mountOptions.global.plugins = [testingPinia];
|
||||
mountOptions.props = initialData
|
||||
|
||||
const apiResponses = { cmsContent: {} };
|
||||
|
||||
settleAllPromises.mockImplementation(() => apiResponses);
|
||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, mountOptions);
|
||||
wrapper.vm.getCmsContent = jest.fn((widgetName, cmsFieldName) => {
|
||||
if (widgetName === linkWidgetName) {
|
||||
return mockLinkCmsContent[cmsFieldName];
|
||||
}
|
||||
|
||||
if (widgetName === modalWidgetName) {
|
||||
return mockModalCmsContent[cmsFieldName];
|
||||
}
|
||||
return null;
|
||||
});
|
||||
wrapper.vm.setCmsContent = jest.fn();
|
||||
wrapper.vm.$router.navigateWithSpinner = jest.fn();
|
||||
wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('service-zip-modal-question.vue', () => {
|
||||
it('Initial state on load with existing location info', async () => {
|
||||
|
|
@ -94,15 +138,13 @@ describe('service-zip-modal-question.vue', () => {
|
|||
zipCode: '43235'
|
||||
};
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
const { wrapper } = getMountedComponent({},
|
||||
{
|
||||
modelValue: serviceZipCodeQuestion,
|
||||
linkWidgetName,
|
||||
modalWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(wrapper.html()).not.toEqual(expect.stringContaining(mockLinkCmsContent.BodyText));
|
||||
|
|
@ -117,15 +159,13 @@ describe('service-zip-modal-question.vue', () => {
|
|||
|
||||
const zip = '43235';
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
const { wrapper } = getMountedComponent({},
|
||||
{
|
||||
modelValue: serviceZipCodeQuestion,
|
||||
mobileFeePart: {},
|
||||
modalWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Act
|
||||
wrapper.vm.internalModel.zipCode = zip;
|
||||
|
|
@ -147,14 +187,12 @@ describe('service-zip-modal-question.vue', () => {
|
|||
|
||||
const zip = '';
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
const { wrapper } = getMountedComponent({},
|
||||
{
|
||||
modelValue: serviceZipCodeQuestion,
|
||||
modalWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Act
|
||||
wrapper.vm.internalModel.zipCode = zip;
|
||||
|
|
@ -173,14 +211,12 @@ describe('service-zip-modal-question.vue', () => {
|
|||
|
||||
const zip = '11111';
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
const { wrapper } = getMountedComponent({},
|
||||
{
|
||||
modelValue: serviceZipCodeQuestion,
|
||||
modalWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Act
|
||||
wrapper.vm.internalModel.zipCode = zip;
|
||||
|
|
@ -199,14 +235,12 @@ describe('service-zip-modal-question.vue', () => {
|
|||
|
||||
const zip = '';
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
const { wrapper } = getMountedComponent({},
|
||||
{
|
||||
modelValue: serviceZipCodeQuestion,
|
||||
modalWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Act
|
||||
wrapper.vm.internalModel.zipCode = zip;
|
||||
|
|
@ -226,14 +260,12 @@ describe('service-zip-modal-question.vue', () => {
|
|||
|
||||
const zip = '123';
|
||||
|
||||
const wrapper = mount(serviceZipModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
const { wrapper } = getMountedComponent({},
|
||||
{
|
||||
modelValue: serviceZipCodeQuestion,
|
||||
modalWidgetName
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Act
|
||||
wrapper.vm.internalModel.zipCode = zip;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
:onModalOpenedCallback="onModalOpened"
|
||||
:onModalClosedCallback="onModalClosed"
|
||||
:footerButtonText="modalFooterText"
|
||||
:modalPosition="'center'"
|
||||
@footerButtonEvent="setZipCode">
|
||||
<serviceZipQuestion
|
||||
ref="serviceZipCodeQuestion"
|
||||
|
|
@ -38,8 +37,9 @@ import textLink from '@/ux-components/text-link/text-link.vue';
|
|||
import serviceZipQuestion from '@/layouts/schedule-page/service-location/service-zip-question/service-zip-question.vue';
|
||||
import modal from '@/digital-components/modal/modal.vue';
|
||||
import alert from '@/ux-components/alert/alert.vue';
|
||||
import { useMainStore } from '@/store';
|
||||
|
||||
import { getServiceabilityDetails, getZipCodeData } from '@/helpers/service-location-helper';
|
||||
import { getZipCodeData } from '@/helpers/service-location-helper';
|
||||
|
||||
export default {
|
||||
name: 'service-zip-modal-question',
|
||||
|
|
@ -153,7 +153,7 @@ export default {
|
|||
const serviceZipCode = this.internalModel.zipCode;
|
||||
|
||||
// retrieve serviceability details
|
||||
const serviceabilityDetails = await getServiceabilityDetails(serviceZipCode);
|
||||
const serviceabilityDetails = await useMainStore().getServiceabilityDetails(serviceZipCode);
|
||||
|
||||
// update content related to service zip code
|
||||
this.$emit('updated-serviceability', serviceabilityDetails.data);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ describe('service-zip-question.vue', () => {
|
|||
const text = '12345';
|
||||
const wrapper = shallowMount(serviceZipQuestion, {
|
||||
props: {
|
||||
modelValue: text
|
||||
parentZipCode: text
|
||||
},
|
||||
attachTo: document.body
|
||||
});
|
||||
|
|
@ -32,9 +32,9 @@ describe('service-zip-question.vue', () => {
|
|||
|
||||
// Act
|
||||
wrapper.vm.internalZipcode = '55555';
|
||||
wrapper.vm.updateModelValue();
|
||||
wrapper.vm.emitZipCodeUpdate();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.emitted('update:modelValue')).toEqual([['55555']]);
|
||||
expect(wrapper.emitted('service-zip-code-updated')).toEqual([['55555']]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
isRequired
|
||||
:hasError="hasError"
|
||||
:validationRules="`zip-required|${cmsWidgetName}-zip-format`"
|
||||
@clickEvent="updateModelValue"
|
||||
@clickEvent="emitZipCodeUpdate"
|
||||
@fieldHasError="handleFieldError" />
|
||||
</template>
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ export default {
|
|||
},
|
||||
// TODO: Correct prop def.
|
||||
props: {
|
||||
modelValue: String,
|
||||
parentZipCode: String,
|
||||
cmsWidgetName: String,
|
||||
serviceZipFormatErrorMessage: {
|
||||
type: String,
|
||||
|
|
@ -43,14 +43,14 @@ export default {
|
|||
default: false
|
||||
}
|
||||
},
|
||||
emits: ['update:modelValue', 'field-has-error'],
|
||||
emits: ['service-zip-code-updated', 'field-has-error'],
|
||||
data() {
|
||||
return {
|
||||
internalZipcode: this.modelValue
|
||||
internalZipcode: this.parentZipCode
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
modelValue(newValue) {
|
||||
parentZipCode(newValue) {
|
||||
if (newValue !== this.internalZipcode) {
|
||||
this.internalZipcode = newValue;
|
||||
}
|
||||
|
|
@ -63,8 +63,8 @@ export default {
|
|||
handleFieldError(hasError) {
|
||||
this.$emit('field-has-error', hasError);
|
||||
},
|
||||
updateModelValue() {
|
||||
this.$emit('update:modelValue', this.internalZipcode);
|
||||
emitZipCodeUpdate() {
|
||||
this.$emit('service-zip-code-updated', this.internalZipcode);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@
|
|||
:headerText="modalHeaderText"
|
||||
:onModalOpenedCallback="onModalOpened"
|
||||
:footerButtonText="modalFooterText"
|
||||
:modalPosition="modalPositions.center"
|
||||
:closeLinkText="modalCloseText"
|
||||
:displayCloseLink="true"
|
||||
:allowInvalidSubmit="true"
|
||||
@footerButtonEvent="updateSelectedProvider">
|
||||
<googleMap
|
||||
|
|
@ -68,17 +69,18 @@
|
|||
groupName="chooseShop"
|
||||
textPosition="text-start"
|
||||
isRequired
|
||||
validationRules="option-required" />
|
||||
validationRules="provider-required" />
|
||||
<span class="service-zip-prompt">
|
||||
{{ serviceZipPrompt }}
|
||||
</span>
|
||||
<serviceZipQuestion
|
||||
v-if="renderServiceZip"
|
||||
:ref="SERVICE_ZIP_QUESTION_REF_NAME"
|
||||
v-model="internalZipcode"
|
||||
:parentZipCode="internalZipcode"
|
||||
customInputId="serviceZipCode"
|
||||
:cmsWidgetName="textboxQuestionWidgetName"
|
||||
@fieldHasError="handleFieldError" />
|
||||
@fieldHasError="handleFieldError"
|
||||
@serviceZipCodeUpdated="handleServiceZipCodeChanged" />
|
||||
<div
|
||||
v-if="errorMessage"
|
||||
ref="errorMessageDiv"
|
||||
|
|
@ -87,6 +89,7 @@
|
|||
class="d-inline-flex mt-0"
|
||||
role="alert">{{ errorMessage }}</span>
|
||||
</div>
|
||||
<hr />
|
||||
</modal>
|
||||
</div>
|
||||
</transition>
|
||||
|
|
@ -110,12 +113,12 @@ import { toTitleCase } from '@/helpers/text-helper.js';
|
|||
import { markRaw } from 'vue';
|
||||
import { useMainStore } from '@/store';
|
||||
import widgetFields from '@/constants/cms-widget-fields';
|
||||
import { dropdownVariants, modalPositions } from '@/constants/component-variants';
|
||||
import { dropdownVariants } from '@/constants/component-variants';
|
||||
import errorMessages from '@/constants/error-messages';
|
||||
import { defineRule } from 'vee-validate';
|
||||
import { required } from '@/helpers/validation-rules';
|
||||
|
||||
defineRule('option-required', required(errorMessages.PROVIDER_REQUIRED));
|
||||
defineRule('provider-required', required(errorMessages.PROVIDER_REQUIRED));
|
||||
|
||||
const SERVICE_ZIP_QUESTION_REF_NAME = 'serviceZipCodeQuestion';
|
||||
|
||||
|
|
@ -154,7 +157,6 @@ export default {
|
|||
shopListButton: markRaw(shopListButton),
|
||||
searchRadiusInMiles: '25',
|
||||
nearbyShops: [],
|
||||
modalPositions,
|
||||
dropdownVariants,
|
||||
renderServiceZip: true,
|
||||
errorMessage: '',
|
||||
|
|
@ -181,6 +183,9 @@ export default {
|
|||
modalFooterText() {
|
||||
return this.getCmsContent(this.modalWidgetName, widgetFields.CONTENT_GROUP_WIDGET.FOOTER_TEXT);
|
||||
},
|
||||
modalCloseText() {
|
||||
return this.getCmsContent(this.modalWidgetName, widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
|
||||
},
|
||||
modalName() {
|
||||
return this.modalWidgetName;
|
||||
},
|
||||
|
|
@ -243,7 +248,7 @@ export default {
|
|||
showIssLoadingModal(false);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
methods: {
|
||||
async updateShops(autoExpand = false) {
|
||||
this.errorMessage = '';
|
||||
let result = await this.getNearbyShops(this.searchRadiusInMiles);
|
||||
|
|
@ -333,6 +338,11 @@ export default {
|
|||
this.errorMessage = '';
|
||||
}
|
||||
},
|
||||
async handleServiceZipCodeChanged(serviceZipCodeFromQuestion) {
|
||||
if (serviceZipCodeFromQuestion !== this.internalZipcode) {
|
||||
this.internalZipcode = serviceZipCodeFromQuestion;
|
||||
}
|
||||
},
|
||||
forceServiceZipRerender() {
|
||||
this.renderServiceZip = false;
|
||||
this.$nextTick(() => {
|
||||
|
|
@ -405,5 +415,33 @@ export default {
|
|||
margin-bottom: 1.25rem;
|
||||
}
|
||||
}
|
||||
:deep(.modal-dialog) {
|
||||
.modal-content {
|
||||
hr {
|
||||
margin: 1.375rem 0;
|
||||
}
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
|
||||
button {
|
||||
background-color: $green;
|
||||
color: $white;
|
||||
font-weight: 600;
|
||||
width: 10.75rem;
|
||||
|
||||
&:hover {
|
||||
background-color: darken($green, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
margin: .5rem 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ export default {
|
|||
`+${formatAmountInDollars(getPriceOfLineItem(this.premiumAppointmentFee))}`;
|
||||
|
||||
return {
|
||||
// Unique value is required for each <input> and the premium appoinment shares an id
|
||||
// Unique value is required for each <input> and the premium appointment shares an id
|
||||
value: this.addPremiumFlagToInput(timeSlotData.id),
|
||||
buttonLabel: this.premiumAppointmentButtonText,
|
||||
buttonLabelSubCopy: formattedPrice,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import servicePackageRadio from '@/layouts/service-packages/service-package-ques
|
|||
import partTypeStrings from '@/constants/part-type-strings';
|
||||
import { useMainStore } from '@/store';
|
||||
import { getPriceOfLineItem } from '@/helpers/price-calculator';
|
||||
import { shallowRef } from 'vue';
|
||||
|
||||
const glassLocations = damageLocationsSelected;
|
||||
|
||||
|
|
@ -31,8 +32,6 @@ const packageNames = {
|
|||
TIER_THREE: 'TierThree'
|
||||
};
|
||||
|
||||
const store = useMainStore();
|
||||
|
||||
export default {
|
||||
name: 'service-package-question',
|
||||
components: {
|
||||
|
|
@ -48,10 +47,14 @@ export default {
|
|||
default: () => []
|
||||
}
|
||||
},
|
||||
emits: ['vapsItemsSelected'],
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
return { mainStore };
|
||||
},
|
||||
emits: ['vapsItemsSelected', 'packageSelected'],
|
||||
data() {
|
||||
return {
|
||||
servicePackageRadio,
|
||||
servicePackageRadio: shallowRef(servicePackageRadio),
|
||||
selectedPackageName: '',
|
||||
questionText: 'Select an option:'
|
||||
};
|
||||
|
|
@ -97,7 +100,7 @@ export default {
|
|||
return modifiedAnswers;
|
||||
},
|
||||
isRecalibrationOnOrder() {
|
||||
return this.lineItemsContainsPartType(partTypeStrings.RECALIBRATION);
|
||||
return this.mainStore.hasRecalibrationPart;
|
||||
},
|
||||
frontWipersApplicableForTierTwo() {
|
||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
|
||||
|
|
@ -147,7 +150,11 @@ export default {
|
|||
selectedPackageName(newValue) {
|
||||
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
||||
this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage);
|
||||
}
|
||||
this.$emit('packageSelected', newValue);
|
||||
},
|
||||
availableLineItems() {
|
||||
this.preselectPackage();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
processIfStatements,
|
||||
|
|
@ -262,8 +269,19 @@ export default {
|
|||
},
|
||||
glassToReplaceContainsGlassLocation(glassLocation) {
|
||||
const glassLocationMatches =
|
||||
store.order.damage.glassToReplace?.filter((glassToReplace) => glassToReplace.glassLocation === glassLocation) ?? [];
|
||||
this.mainStore.order.damage.glassToReplace?.filter((glassToReplace) => glassToReplace.glassLocation === glassLocation) ?? [];
|
||||
return !!glassLocationMatches.length;
|
||||
},
|
||||
preselectPackage() {
|
||||
const savedPackage = this.mainStore.order.servicePackage;
|
||||
|
||||
if (savedPackage && this.servicePackageAnswers.some((answer) => answer.value === savedPackage)) {
|
||||
this.selectedPackageName = savedPackage;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
this.selectedPackageName = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -278,6 +296,7 @@ export default {
|
|||
|
||||
@include media-breakpoint-up(md) {
|
||||
:deep(.package-main) {
|
||||
justify-content: center;
|
||||
padding: 0 1.5rem 0 1.5rem;
|
||||
.package-wrapper:nth-child(2) {
|
||||
margin-left: 0.5rem;
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@
|
|||
</div>
|
||||
<div class="iss-heritage-container-width">
|
||||
<div class="service-packages-container">
|
||||
<siteSubHeader
|
||||
class="subheader mt-5"
|
||||
justification="center"
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
issContainingPage="service-packages" />
|
||||
<h5
|
||||
class="sub-header"
|
||||
v-html="servicePackagesSubHeader"></h5>
|
||||
<div
|
||||
class="mb-4 text-center"
|
||||
v-html="secondaryText">
|
||||
</div>
|
||||
<servicePackageQuestion
|
||||
ref="servicePackage"
|
||||
cmsWidgetName="ServicePackage"
|
||||
|
|
@ -23,6 +25,7 @@
|
|||
:validationRules="rules.optionRequired"
|
||||
isRequired
|
||||
@vapsItemsSelected="vapsItemsSelectedAction"
|
||||
@packageSelected="packageSelectedAction"
|
||||
@link-event="openModalAction" />
|
||||
<div class="d-flex justify-content-center mt-8 mb-4">
|
||||
<buttonMain
|
||||
|
|
@ -55,10 +58,6 @@
|
|||
<contentGroupModal
|
||||
ref="RearWiperModal"
|
||||
cmsWidgetName="RearWiperModal" />
|
||||
<contentGroupModal
|
||||
ref="RecalModal"
|
||||
cssModalHeadlineClass="text-center"
|
||||
cmsWidgetName="RecalModal" />
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
|
@ -89,7 +88,6 @@ export default {
|
|||
components: {
|
||||
siteHeader,
|
||||
siteFooter,
|
||||
siteSubHeader,
|
||||
Form,
|
||||
servicePackageQuestion,
|
||||
loadingModal,
|
||||
|
|
@ -166,6 +164,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
selectedVaps: [],
|
||||
selectedPackageTier: '',
|
||||
availableLineItems: [],
|
||||
loadingText: [
|
||||
'Finding shops near you',
|
||||
|
|
@ -182,6 +181,20 @@ export default {
|
|||
computed: {
|
||||
PriceDisclaimerText() {
|
||||
return this.getCmsContent('PriceDisclaimerWidget', 'Text');
|
||||
},
|
||||
vehicleMake() {
|
||||
return (store.order.vehicle.make ?? '').toUpperCase();
|
||||
},
|
||||
vehicleModel() {
|
||||
return (store.order.vehicle.model ?? '').toUpperCase();
|
||||
},
|
||||
servicePackagesSubHeader() {
|
||||
return this.getCmsContent('SiteSubHeaderWidget', 'SubHeaderText')
|
||||
.replace('{custom:vehicleMake}', this.vehicleMake)
|
||||
.replace('{custom:vehicleModel}', this.vehicleModel);
|
||||
},
|
||||
secondaryText() {
|
||||
return this.getCmsContent('SiteSubHeaderWidget', 'SecondaryText');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -204,6 +217,9 @@ export default {
|
|||
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||
this.selectedVaps = vapsItemsSelected;
|
||||
},
|
||||
packageSelectedAction(packageTier) {
|
||||
this.selectedPackageTier = packageTier;
|
||||
},
|
||||
forwardButtonAction() {
|
||||
const parts = {
|
||||
vaps: this.selectedVaps
|
||||
|
|
@ -212,6 +228,7 @@ export default {
|
|||
window.console.error('One or more items have no price assigned!');
|
||||
}
|
||||
store.updateVaps(this.selectedVaps);
|
||||
store.updateServicePackage(this.selectedPackageTier);
|
||||
|
||||
const scenario = store.isMobileAppointment
|
||||
? this.navigationScenarios.CLICKED_FORWARD_MOBILE
|
||||
|
|
@ -244,7 +261,7 @@ export default {
|
|||
padding-left: .9375rem;
|
||||
padding-right: .9375rem;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
margin: 1.5rem auto;
|
||||
:deep(.subheader-primary) {
|
||||
display: block;
|
||||
}
|
||||
|
|
@ -274,4 +291,10 @@ export default {
|
|||
.back-link {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.sub-header {
|
||||
text-align: center;
|
||||
color: $black;
|
||||
line-height: 2rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
exports[`tpa-submit returns the initial data 1`] = `
|
||||
Object {
|
||||
"modalPositions": Object {
|
||||
"center": "center",
|
||||
"edge": "edge",
|
||||
},
|
||||
"sections": Array [],
|
||||
"widget": Object {
|
||||
"alertIncomplete": "AlertIncompleteWidget",
|
||||
|
|
|
|||
|
|
@ -35,19 +35,18 @@
|
|||
<modal
|
||||
ref="recalModal"
|
||||
class="recal-modal"
|
||||
:modalPosition="modalPositions.center"
|
||||
:headerText="recalModalContent.headerText"
|
||||
:footerButtonText="recalModalContent.footerButtonText"
|
||||
@footerButtonEvent="closeRecalModal">
|
||||
<div class="recal-modal-subheader">
|
||||
{{ recalModalContent.subHeaderText }}
|
||||
</div>
|
||||
{{ recalModalContent.subHeaderText }}
|
||||
</div>
|
||||
<img
|
||||
class="recal-modal-image"
|
||||
:src="recalModalContent.image" />
|
||||
class="recal-modal-image"
|
||||
:src="recalModalContent.image" />
|
||||
<div
|
||||
class="recal-modal-body"
|
||||
v-html="recalModalContent.bodyText"></div>
|
||||
class="recal-modal-body"
|
||||
v-html="recalModalContent.bodyText"></div>
|
||||
</modal>
|
||||
<hr />
|
||||
<div id="serviceSummarySection">
|
||||
|
|
@ -122,7 +121,6 @@ import {
|
|||
import { submitWorkOrder } from '@/helpers/order-helper.js';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
import submitType from '@/constants/submit-type';
|
||||
import { modalPositions } from '@/constants/component-variants';
|
||||
|
||||
const VERIFYING_COVERAGE = 'Verifying coverage';
|
||||
|
||||
|
|
@ -159,8 +157,7 @@ export default {
|
|||
alertRecalWarning: 'AlertRecalWarningWidget',
|
||||
editShopLinkText: 'EditShopLinkTextWidget',
|
||||
contactDetails: 'ContactDetailsSectionWidget'
|
||||
},
|
||||
modalPositions
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -345,7 +342,7 @@ export default {
|
|||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.iss-heritage-container-width {
|
||||
.tpa-submit-container {
|
||||
position: relative;
|
||||
|
|
@ -392,7 +389,7 @@ export default {
|
|||
margin-bottom: .625rem;
|
||||
}
|
||||
|
||||
.modal.recal-modal .modal-dialog {
|
||||
:deep(.modal.recal-modal .modal-dialog) {
|
||||
.modal-header {
|
||||
justify-content: start;
|
||||
margin: 0rem;
|
||||
|
|
@ -403,6 +400,7 @@ export default {
|
|||
line-height: 1.25rem;
|
||||
text-align: start;
|
||||
justify-content: start;
|
||||
padding-left: 0rem;
|
||||
}
|
||||
.btn-close {
|
||||
display: none;
|
||||
|
|
@ -419,7 +417,29 @@ export default {
|
|||
color: $black;
|
||||
}
|
||||
.recal-modal-image {
|
||||
margin: 1.25rem 0rem
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 1.25rem 0rem;
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
width: 16.5rem;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
width: 23.5rem;
|
||||
}
|
||||
}
|
||||
.modal-footer {
|
||||
padding-top: 0;
|
||||
button {
|
||||
background-color: $green;
|
||||
color: $white;
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
background-color: darken($green, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@
|
|||
class="my-5"
|
||||
cmsWidgetName="HasReplacementConflict"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
:isDismissible="false"
|
||||
:isCollapsible="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="justify-content-center">
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@
|
|||
class="mt-5"
|
||||
cmsWidgetName="SplitSingleConflict"
|
||||
alertClass="alert-danger"
|
||||
:isDismissible="false" />
|
||||
:isDismissible="false"
|
||||
:isCollapsible="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -46,18 +46,11 @@
|
|||
:updateValues="updateStyleValues"
|
||||
validationRules="style-required"
|
||||
inputId="styleQuestionField" />
|
||||
<alert
|
||||
v-if="displayNoServiceAlert"
|
||||
ref="AlertNoService"
|
||||
class="mt-5"
|
||||
cmsWidgetName="AlertVehicleSelection"
|
||||
alertClass="alert-danger"
|
||||
:isDismissable="false" />
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid || displayNoServiceAlert"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="navigateBack" />
|
||||
</div>
|
||||
|
|
@ -72,7 +65,6 @@ import siteHeader from '@/iss-components/site-header/site-header.vue';
|
|||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
||||
import vehicleQuestion from '@/layouts/vehicle-selection/vehicle-question/vehicle-question.vue';
|
||||
import alert from '@/ux-components/alert/alert.vue';
|
||||
import { useMainStore } from '@/store';
|
||||
|
||||
// Supporting files
|
||||
|
|
@ -97,8 +89,7 @@ export default {
|
|||
siteSubHeader,
|
||||
siteFooter,
|
||||
Form,
|
||||
vehicleQuestion,
|
||||
alert
|
||||
vehicleQuestion
|
||||
},
|
||||
mixins: [baseFormMixin],
|
||||
|
||||
|
|
@ -131,15 +122,13 @@ export default {
|
|||
selectedYear: year,
|
||||
selectedMake: make,
|
||||
selectedModel: model,
|
||||
selectedStyle: style,
|
||||
displayNoServiceAlert: false
|
||||
selectedStyle: style
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
watch: {
|
||||
selectedYear(value) {
|
||||
this.resetAlert();
|
||||
this.mainStore.updateVehicleYear(value);
|
||||
this.$refs.vehicleMakeQuestion.clearValues();
|
||||
if (value) {
|
||||
|
|
@ -147,7 +136,6 @@ export default {
|
|||
}
|
||||
},
|
||||
selectedMake(value) {
|
||||
this.resetAlert();
|
||||
this.mainStore.updateVehicleMake(value);
|
||||
this.$refs.vehicleModelQuestion.clearValues();
|
||||
if (value) {
|
||||
|
|
@ -155,7 +143,6 @@ export default {
|
|||
}
|
||||
},
|
||||
selectedModel(value) {
|
||||
this.resetAlert();
|
||||
this.mainStore.updateVehicleModel(value);
|
||||
this.$refs.vehicleStyleQuestion.clearValues();
|
||||
if (value) {
|
||||
|
|
@ -164,16 +151,7 @@ export default {
|
|||
},
|
||||
selectedStyle(value) {
|
||||
if (value) {
|
||||
this.resetAlert();
|
||||
this.mainStore.updateVehicleStyle(value);
|
||||
this.mainStore.setVehicle(
|
||||
this.selectedYear,
|
||||
this.selectedMake,
|
||||
this.selectedModel,
|
||||
this.selectedStyle
|
||||
).then((result) => {
|
||||
this.displayNoServiceAlert = !result.data.canSafeliteService;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -188,16 +166,6 @@ export default {
|
|||
if (this.selectedModel) {
|
||||
this.$refs.vehicleStyleQuestion.getNewValues();
|
||||
}
|
||||
if (this.selectedStyle) {
|
||||
this.mainStore.setVehicle(
|
||||
this.selectedYear,
|
||||
this.selectedMake,
|
||||
this.selectedModel,
|
||||
this.selectedStyle
|
||||
).then((result) => {
|
||||
this.displayNoServiceAlert = !result.data.canSafeliteService;
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
|
|
@ -208,12 +176,23 @@ export default {
|
|||
},
|
||||
|
||||
navigateForward() {
|
||||
this.mainStore.setVehicle().then(() => {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.mainStore.setVehicle().then((result) => {
|
||||
if (!result.data.canSafeliteService) {
|
||||
this.mainStore.setBailout(bailoutMessage.HeavyTruckVehicle(this.mainStore.order.vehicle.carId));
|
||||
}
|
||||
|
||||
if (this.mainStore.isBailout) {
|
||||
return this.$router.navigate(
|
||||
this.navigationScenarios.BAILOUT,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
|
||||
return this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
async updateYearValues() {
|
||||
|
|
|
|||
|
|
@ -67,17 +67,4 @@ describe('vin-lookup-alerts.vue', () => {
|
|||
|
||||
expect(twoIdenticalYMMVehicleAlert).toBeVisible();
|
||||
});
|
||||
test('NoServiceAlert is displayed on the screen', () => {
|
||||
mountOptions.props = {
|
||||
activeAlertType: vehicleLookupAlertTypes.NO_SERVICE
|
||||
};
|
||||
mountOptions.global.provide = {
|
||||
vehicleFromLookup: {}
|
||||
};
|
||||
|
||||
const { queryByRole } = render(VinLookupAlertsComponent, mountOptions);
|
||||
const noServiceAlert = queryByRole('alert', { name: 'no-service-alert' });
|
||||
|
||||
expect(noServiceAlert).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -488,36 +488,6 @@ describe('vin-lookup.vue', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
test('Display no service alert if entered vin cannot be serviced', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
|
||||
mountOptions.data = () => ({
|
||||
vinWithNonMatchingCarId: false,
|
||||
isCarIdDifferentFromTheStore: false,
|
||||
vin: mockValidVin
|
||||
});
|
||||
|
||||
getPartsOrQuestions.mockResponse = vehicleWithNoAdditionalPartsOrQuestionsMockResponse;
|
||||
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVinCannotService.mockResponse);
|
||||
jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName)
|
||||
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
|
||||
const vinInput = container.querySelector(vinInputSelector);
|
||||
await user.type(vinInput, mockValidVin);
|
||||
|
||||
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||
await user.click(continueButton);
|
||||
|
||||
await flushPromises();
|
||||
await waitFor(() => {
|
||||
expect(container).toContainHTML('noService');
|
||||
});
|
||||
});
|
||||
|
||||
test('Policy Vehicle with invalid vin corrected. Click "Continue", execute navigate with navigationScenario.CORRECTED_VIN_FROM_POLICY_VEHICLE', async () => {
|
||||
const user = userEvent.setup();
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ export default {
|
|||
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
||||
async forwardButtonAction() {
|
||||
this.resetActiveAlert();
|
||||
this.mainStore.resetBailout();
|
||||
// Temp solution to reset the 'disabled' style on the Continue button
|
||||
this.$refs.siteFooter.enableForwardAction();
|
||||
showIssLoadingModal(true);
|
||||
|
|
@ -179,11 +180,10 @@ export default {
|
|||
const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin);
|
||||
|
||||
if (!vehicleLookupResponse.data.canSafeliteService) {
|
||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NO_SERVICE;
|
||||
this.mainStore.setBailout(bailoutMessage.HeavyTruckVehicle(vehicleLookupResponse.data.carId));
|
||||
this.resetVehicleFromLookup();
|
||||
this.$refs.siteFooter.disableForwardButton();
|
||||
showIssLoadingModal(false);
|
||||
return;
|
||||
return this.navigateForward();
|
||||
}
|
||||
|
||||
// Add vin bcs the response from the service doesn't contain vin
|
||||
|
|
|
|||
|
|
@ -304,6 +304,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async forwardButtonAction() {
|
||||
this.mainStore.resetVehicleState();
|
||||
this.mainStore.updatePolicyData(this.welcomePageModel);
|
||||
|
||||
// We want to await this separately. It's quick and if this has an invalid zip we don't want to be waiting on the slower API calls
|
||||
|
|
@ -425,6 +426,8 @@ export default {
|
|||
async loadReferralFromCookie() {
|
||||
const issCookie = getISSCookie();
|
||||
if (issCookie) {
|
||||
this.$refs.continueModal.closeModal();
|
||||
showIssLoadingModal(true);
|
||||
const cookieReferral = {
|
||||
referralNumber: issCookie.ReferralNumber,
|
||||
responseDate: issCookie.ReferralDate,
|
||||
|
|
@ -446,7 +449,7 @@ export default {
|
|||
console.error(`Error on loading session from cookie ${error}`);
|
||||
this.startNewReferral();
|
||||
} finally {
|
||||
this.$refs.continueModal.closeModal();
|
||||
showIssLoadingModal(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -46,38 +46,45 @@ export default {
|
|||
return '';
|
||||
},
|
||||
logPageView(pageEvent) {
|
||||
const store = useMainStore();
|
||||
const currentPageName = this.getPageNameByQueryString();
|
||||
|
||||
const payload = {
|
||||
userId: getDeviceIdValue(),
|
||||
sessionKey: getSessionKeyValue(),
|
||||
pageName: currentPageName,
|
||||
referralSequenceNumber: store.order.referralSequenceNumber,
|
||||
parentAccountNumber: store.order.parentAccountNumber ?? 0,
|
||||
sessionId: getSessionIdValue(),
|
||||
action: '',
|
||||
event: pageEvent,
|
||||
shouldUseSessionId: false,
|
||||
experimentsForUser: useMainStore().applicationUser.experiments
|
||||
experimentsForUser: store.applicationUser.experiments
|
||||
};
|
||||
|
||||
useMainStore().logPageView(payload);
|
||||
store.logPageView(payload);
|
||||
},
|
||||
|
||||
logCustomEvent(category, action, label, value) {
|
||||
const store = useMainStore();
|
||||
const currentPageName = this.getPageNameByQueryString();
|
||||
|
||||
const payload = {
|
||||
userId: getDeviceIdValue(),
|
||||
sessionKey: getSessionKeyValue(),
|
||||
pageName: currentPageName,
|
||||
referralSequenceNumber: store.order.referralSequenceNumber,
|
||||
parentAccountNumber: store.order.parentAccountNumber ?? 0,
|
||||
sessionId: getSessionIdValue(),
|
||||
category,
|
||||
action,
|
||||
label,
|
||||
value,
|
||||
shouldUseSessionId: false,
|
||||
experimentsForUser: useMainStore().applicationUser.experiments
|
||||
experimentsForUser: store.applicationUser.experiments
|
||||
};
|
||||
|
||||
useMainStore().logCustomEvent(payload);
|
||||
store.logCustomEvent(payload);
|
||||
},
|
||||
|
||||
pushEventToGA(category, action, label, pushToLogApp = false, valueToLogType = null) {
|
||||
|
|
|
|||
|
|
@ -361,6 +361,14 @@ export default {
|
|||
const self = vm ?? this;
|
||||
const currentPage = self.$route.query.issPage;
|
||||
|
||||
if (self.mainStore.isBailout) {
|
||||
self.$router.navigate(
|
||||
self.navigationScenarios.BAILOUT,
|
||||
self.$route
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const hasPartQuestions = this.hasPartQuestions(partsOrQuestions);
|
||||
const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions);
|
||||
const hasChildPartQuestions = this.hasChildPartQuestions(partsOrQuestions);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ const issPageValues = Object.freeze({
|
|||
PAYMENT_METHOD: 'payment-method',
|
||||
PAYMENT_PAGE: 'payment-page',
|
||||
PAYMENT_RETURN: 'payment-return',
|
||||
PAYMENT_PAGE_ADYEN: 'payment-page-adyen',
|
||||
PAYMENT_RETURN_ADYEN: 'payment-return-adyen',
|
||||
PART_QUESTIONS: 'part-questions',
|
||||
POLICY_HOLDER_DETAILS: 'policy-holder-details',
|
||||
PROVIDER_PREFERENCE: 'provider-preference',
|
||||
|
|
|
|||
|
|
@ -102,10 +102,13 @@ const navigationScenarios = Object.freeze({
|
|||
CLICKED_BACK_INSHOP: 'CLICKED_BACK_INSHOP',
|
||||
CLICKED_BACK_MOBILE: 'CLICKED_BACK_MOBILE',
|
||||
CLICKED_PAY_NOW: 'CLICKED_PAY_NOW',
|
||||
CLICKED_PAY_NOW_ADYEN: 'CLICKED_PAY_NOW_ADYEN',
|
||||
PAY_IN_ADVANCE_CANCEL: 'PAY_IN_ADVANCE_CANCEL',
|
||||
PAY_IN_ADVANCE_ERROR: 'PAY_IN_ADVANCE_ERROR',
|
||||
PAY_IN_ADVANCE_CREDIT_CARD_ERROR: 'PAY_IN_ADVANCE_CREDIT_CARD_ERROR',
|
||||
PAY_IN_ADVANCE_SUCCESS: 'PAY_IN_ADVANCE_SUCCESS',
|
||||
EDIT_SERVICE_LOCATION: 'EDIT_SERVICE_LOCATION',
|
||||
EDIT_SERVICE_LOCATION_INSHOP: 'EDIT_SERVICE_LOCATION_INSHOP',
|
||||
EDIT_SERVICE_LOCATION_MOBILE: 'EDIT_SERVICE_LOCATION_MOBILE',
|
||||
EDIT_SCHEDULE: 'EDIT_SCHEDULE',
|
||||
EDIT_WIPERS: 'EDIT_WIPERS',
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ const routingTable = () => [
|
|||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||
destinationIssPageValue: issPageValues.POLICY_HOLDER_DETAILS
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.BAILOUT,
|
||||
destinationIssPageValue: issPageValues.BAILOUT_PAGE
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -638,9 +642,17 @@ const routingTable = () => [
|
|||
destinationIssPageValue: issPageValues.PAYMENT_PAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.EDIT_SERVICE_LOCATION,
|
||||
scenario: navigationScenarios.CLICKED_PAY_NOW_ADYEN,
|
||||
destinationIssPageValue: issPageValues.PAYMENT_PAGE_ADYEN
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.EDIT_SERVICE_LOCATION_INSHOP,
|
||||
destinationIssPageValue: issPageValues.SCHEDULE_PAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.EDIT_SERVICE_LOCATION_MOBILE,
|
||||
destinationIssPageValue: issPageValues.CONTACT_DETAILS
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.EDIT_SCHEDULE,
|
||||
destinationIssPageValue: issPageValues.SCHEDULE_PAGE
|
||||
|
|
@ -668,6 +680,23 @@ const routingTable = () => [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.PAYMENT_PAGE_ADYEN,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationIssPageValue: issPageValues.PAYMENT_METHOD
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||
destinationIssPageValue: issPageValues.ORDER_CONFIRMATION
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
|
||||
destinationIssPageValue: issPageValues.ORDER_CONFIRMATION
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.PAYMENT_RETURN,
|
||||
maps: [
|
||||
|
|
@ -685,6 +714,23 @@ const routingTable = () => [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.PAYMENT_RETURN_ADYEN,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.PAY_IN_ADVANCE_CANCEL,
|
||||
destinationIssPageValue: issPageValues.PAYMENT_PAGE_ADYEN
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.PAY_IN_ADVANCE_ERROR,
|
||||
destinationIssPageValue: issPageValues.PAYMENT_PAGE_ADYEN
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.PAY_IN_ADVANCE_SUCCESS,
|
||||
destinationIssPageValue: issPageValues.ORDER_CONFIRMATION
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.TPA_CONFIRMATION,
|
||||
maps: [
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ export const getDefaultState = () => ({
|
|||
vaps: null,
|
||||
serverData: null
|
||||
},
|
||||
servicePackage: null,
|
||||
insuranceCoverage: {
|
||||
coverageStatus: coverageStatuses.PENDING,
|
||||
coverageType: coverageType.NONE,
|
||||
|
|
@ -1253,7 +1254,7 @@ export const useMainStore = defineStore({
|
|||
},
|
||||
|
||||
async getCombinedQuote(availableLineItems) {
|
||||
if (!availableLineItems || availableLineItems.length === 0) {
|
||||
if (!availableLineItems || availableLineItems.length === 0 || !this.providerNumber) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
@ -1777,6 +1778,9 @@ export const useMainStore = defineStore({
|
|||
updatePaypalToken(token) {
|
||||
this.order.payment.paypalToken = token;
|
||||
},
|
||||
updateNextGenSettledAmount(amount) {
|
||||
this.order.payment.nextGenSettledAmount = amount;
|
||||
},
|
||||
setSaveSessionPromise(promise) {
|
||||
this.applicationUser.saveSessionPromise = promise;
|
||||
},
|
||||
|
|
@ -1842,7 +1846,7 @@ export const useMainStore = defineStore({
|
|||
this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu ?? this.order.serviceLocation.zipCodeCtu;
|
||||
this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType ?? this.order.serviceLocation.appointmentType;
|
||||
this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected ?? this.order.serviceLocation.isVehicleProtected;
|
||||
this.updateServiceLocationProvider(serviceLocationInfo.provider)
|
||||
this.updateServiceLocationProvider(serviceLocationInfo.provider);
|
||||
this.order.serviceLocation.tpaSearchRadius = serviceLocationInfo.tpaSearchRadius;
|
||||
},
|
||||
updateAppointmentType(appointmentType) {
|
||||
|
|
@ -1865,7 +1869,6 @@ export const useMainStore = defineStore({
|
|||
resetState() {
|
||||
Object.assign(this, getDefaultState());
|
||||
},
|
||||
|
||||
resetRegistrationState() {
|
||||
this.order.vehicle.registration.licensePlate = null;
|
||||
this.order.vehicle.registration.address = null;
|
||||
|
|
@ -1904,14 +1907,12 @@ export const useMainStore = defineStore({
|
|||
this.order.serviceLocation.state = null;
|
||||
this.order.serviceLocation.isVehicleProtected = null;
|
||||
},
|
||||
|
||||
resetBailout() {
|
||||
this.updatePageData({
|
||||
page: issPageValues.BAILOUT_PAGE,
|
||||
data: null
|
||||
});
|
||||
},
|
||||
|
||||
resetInsurance() {
|
||||
this.order.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
|
||||
this.order.insuranceCoverage.coverageType = coverageType.NONE;
|
||||
|
|
@ -1943,14 +1944,18 @@ export const useMainStore = defineStore({
|
|||
// Process Recycle Fee
|
||||
this.updateRecycleFee(partsData.find((rf) => rf.partNumber === partNumberStrings.RECYCLE_FEE));
|
||||
|
||||
// Remove RecycleFee from supported items as it's saved in feeItems;
|
||||
this.order.lineItems.supportingItems = partsData.filter((i) => i.partNumber !== partNumberStrings.RECYCLE_FEE);
|
||||
// Remove RecycleFee and Labor2 from supporting items as they're saved in feeItems;
|
||||
this.order.lineItems.supportingItems = partsData.filter((i) => i.partNumber !== partNumberStrings.RECYCLE_FEE && i.partNumber !== partNumberStrings.LABOR2);
|
||||
},
|
||||
|
||||
updateVaps(partsData) {
|
||||
this.order.lineItems.vaps = partsData;
|
||||
},
|
||||
|
||||
updateServicePackage(packageName) {
|
||||
this.order.servicePackage = packageName;
|
||||
},
|
||||
|
||||
updateMobileFee(fee) {
|
||||
const isMobileFeeHidden = getExperimentSettingValue(this.experimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN) === 'true';
|
||||
// Mobile Fee is only added for NO COMP or ITAC and is NOT hidden
|
||||
|
|
@ -2035,6 +2040,7 @@ export const useMainStore = defineStore({
|
|||
|
||||
this.updateSupportingItems(null);
|
||||
this.updateVaps(null);
|
||||
this.updateServicePackage(null);
|
||||
},
|
||||
|
||||
updateVehicleCoverage(coverage) {
|
||||
|
|
@ -2079,6 +2085,7 @@ export const useMainStore = defineStore({
|
|||
this.order.loadedFromDupeCheck = null;
|
||||
this.order.loadedSessionClearedPreviousData = null;
|
||||
this.order.availableVaps = null;
|
||||
this.order.servicePackage = null;
|
||||
this.order.carrierPhoneNumber = null;
|
||||
this.order.customerPortalLoginToken = null;
|
||||
this.order.loadedFromCookie = false;
|
||||
|
|
@ -2364,6 +2371,7 @@ export const useMainStore = defineStore({
|
|||
this.updateCapabilityQuestionAnswers(null);
|
||||
this.updateSupportingItems(null);
|
||||
this.updateVaps(null);
|
||||
this.updateServicePackage(null);
|
||||
|
||||
this.updatePageData({ page: issPageValues.VEHICLE_PARTS, data: null });
|
||||
this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: null });
|
||||
|
|
@ -2519,12 +2527,14 @@ export const useMainStore = defineStore({
|
|||
this.logExperimentExposure(pageName, experiment);
|
||||
}
|
||||
},
|
||||
logPageView({ userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
|
||||
logPageView({ userId, sessionKey, pageName, referralSequenceNumber, parentAccountNumber, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
|
||||
const payload = {
|
||||
userId,
|
||||
sessionKey,
|
||||
sessionId,
|
||||
pageName,
|
||||
referralSequenceNumber,
|
||||
parentAccountNumber,
|
||||
applicationName: applicationConfig.APPLICATION_NAME,
|
||||
action,
|
||||
event,
|
||||
|
|
@ -2536,7 +2546,8 @@ export const useMainStore = defineStore({
|
|||
method: endpoints.LogPageView.method,
|
||||
endpoint: endpoints.LogPageView.url,
|
||||
payload,
|
||||
logApiCall: false
|
||||
logApiCall: false,
|
||||
bailoutOnError: false
|
||||
}).then(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
|
|
@ -2565,7 +2576,8 @@ export const useMainStore = defineStore({
|
|||
method: endpoints.LogCustomEvent.method,
|
||||
endpoint: endpoints.LogCustomEvent.url,
|
||||
payload,
|
||||
logApiCall: false
|
||||
logApiCall: false,
|
||||
bailoutOnError: false
|
||||
}).then(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
|
|
@ -2593,7 +2605,8 @@ export const useMainStore = defineStore({
|
|||
method: endpoints.InitializeSession.method,
|
||||
endpoint: endpoints.InitializeSession.url,
|
||||
payload,
|
||||
logApiCall: false
|
||||
logApiCall: false,
|
||||
bailoutOnError: false
|
||||
}).then(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
|
|
@ -2832,17 +2845,20 @@ export const useMainStore = defineStore({
|
|||
this.resetRegistrationState();
|
||||
this.resetGlassPartsState();
|
||||
this.updateVaps(null);
|
||||
this.updateServicePackage(null);
|
||||
},
|
||||
|
||||
resetDamageAndDependencies() {
|
||||
this.resetDamageState();
|
||||
this.resetGlassPartsState();
|
||||
this.updateVaps(null);
|
||||
this.updateServicePackage(null);
|
||||
},
|
||||
|
||||
resetPartsAndDependencies() {
|
||||
this.resetGlassPartsState();
|
||||
this.updateVaps(null);
|
||||
this.updateServicePackage(null);
|
||||
|
||||
this.resetServiceLocationAndDependencies();
|
||||
},
|
||||
|
|
@ -2883,6 +2899,24 @@ export const useMainStore = defineStore({
|
|||
endpoint: endpoints.GetPaymentSignature.url
|
||||
});
|
||||
},
|
||||
async initializeAdyenPayment(requestBody) {
|
||||
const response = await globalMethods.callHttpClient({
|
||||
method: endpoints.InitializeAdyenPayment.method,
|
||||
endpoint: endpoints.InitializeAdyenPayment.url,
|
||||
payload: requestBody,
|
||||
logApiCall: true
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
async getAdyenSessionResult(paymentSessionRequest) {
|
||||
const response = await globalMethods.callHttpClient({
|
||||
method: endpoints.GetAdyenSessionResult.method,
|
||||
endpoint: endpoints.GetAdyenSessionResult.url,
|
||||
payload: paymentSessionRequest,
|
||||
logApiCall: true
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
hasSubmittedOrder() {
|
||||
return window.sessionStorage.getItem(webStorageConstants.SUBMITTED_ORDER) !== null;
|
||||
|
|
|
|||
|
|
@ -2489,4 +2489,32 @@ describe('Store', () => {
|
|||
expect(store.order.contactInfo.alternativePhone).toBeUndefined();
|
||||
});
|
||||
});
|
||||
describe('updateSupportingItems method', () => {
|
||||
it('updateSupportingItems removes Recyle Fee and Labor2 Fee from supporting items in store', () => {
|
||||
// Arrange
|
||||
const partsData = [
|
||||
{
|
||||
partNumber: 'RECYCLE FEE',
|
||||
partType: 'REPLACE FEE'
|
||||
},
|
||||
{
|
||||
partNumber: 'LABOR2',
|
||||
partType: 'NON_GLASS'
|
||||
}
|
||||
];
|
||||
|
||||
// Act
|
||||
store.updateSupportingItems(partsData);
|
||||
|
||||
// Assert
|
||||
expect.not.objectContaining({
|
||||
partNumber: 'RECYCLE FEE',
|
||||
partType: 'REPLACE FEE'
|
||||
});
|
||||
expect.not.objectContaining({
|
||||
partNumber: 'LABOR2',
|
||||
partType: 'NON_GLASS'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ $alert-red-color: $red;
|
|||
|
||||
//Modal animation
|
||||
// This affects all [Bootstrap] modals
|
||||
$modal-fade-transform: translate(0, 100%);
|
||||
$modal-fade-transform: translate(0, -25%);
|
||||
$modal-backdrop-opacity: 0;
|
||||
|
||||
//Disable default !important behavior
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@
|
|||
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
||||
href="#!"
|
||||
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
||||
:preventDefaultOnClick="preventDefaultOnClick"
|
||||
@clickEvent="$emit('textLinkClicked', getRouterLinkRouteFromCopy(copy))" />
|
||||
</span>
|
||||
<span
|
||||
|
|
@ -172,7 +173,8 @@ export default {
|
|||
startCollapsed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
preventDefaultOnClick: { type: Boolean, required: false, default: false }
|
||||
},
|
||||
emits: ['textLinkClicked'],
|
||||
data() {
|
||||
|
|
|
|||
|
|
@ -192,4 +192,37 @@ describe('buttonMain.vue', () => {
|
|||
// Expect
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('Button Types', () => {
|
||||
it('Should set button type to submit', async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(
|
||||
buttonMain,
|
||||
setupMocks({
|
||||
propsData: {
|
||||
buttonType: 'submit'
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Assert
|
||||
const button = wrapper.find('button');
|
||||
|
||||
// Expect
|
||||
expect(button.attributes('type')).toEqual('submit');
|
||||
});
|
||||
it('Should default button type to button', async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(
|
||||
buttonMain,
|
||||
setupMocks()
|
||||
);
|
||||
|
||||
// Assert
|
||||
const button = wrapper.find('button');
|
||||
|
||||
// Expect
|
||||
expect(button.attributes('type')).toEqual('button');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
:aria-disabled="isDisabled"
|
||||
class="btn d-flex align-items-center justify-content-center delay"
|
||||
:class="[getVariant, `btn-${size}`, canOverride ? 'btn-override' : '']"
|
||||
:type="buttonType"
|
||||
@click="clicked">
|
||||
<span class="m-0">{{ buttonText }}</span>
|
||||
</button>
|
||||
|
|
@ -21,7 +22,9 @@ export default {
|
|||
isDisabled: Boolean,
|
||||
isOutline: Boolean,
|
||||
pushToGA: Boolean,
|
||||
canOverride: { type: Boolean, required: false, default: true }
|
||||
canOverride: { type: Boolean, required: false, default: true },
|
||||
preventDefaultOnClick: { type: Boolean, required: false, default: false },
|
||||
buttonType: { type: String, required: false, default: 'button', validator: (val) => ['button', 'submit', 'reset'].includes(val) }
|
||||
},
|
||||
emits: ['click-event'],
|
||||
computed: {
|
||||
|
|
@ -34,8 +37,11 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
clicked() {
|
||||
clicked(e) {
|
||||
if (!this.isDisabled) {
|
||||
if (this.preventDefaultOnClick) {
|
||||
e.preventDefault();
|
||||
}
|
||||
if (this.pushToGA) {
|
||||
this.pushEventToGA(
|
||||
this.$route.query[this.queryStrings.ISS_PAGE],
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue