diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 3e06d0dc..8843c001 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -85,6 +85,7 @@ stages:
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
+ __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
indexDeployVariables:
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
@@ -135,6 +136,7 @@ stages:
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
+ __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
indexDeployVariables:
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
@@ -185,6 +187,7 @@ stages:
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
+ __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
indexDeployVariables:
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
@@ -235,6 +238,7 @@ stages:
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
+ __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
indexDeployVariables:
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
diff --git a/package-lock.json b/package-lock.json
index de029cb4..26792b8c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"axios": "^1.4.0",
"axios-retry": "^3.5.0",
"bootstrap": "^5.3",
+ "iframe-resizer": "^4.3.9",
"maska": "^1.5.0",
"pinia": "^2.1.4",
"pinia-plugin-persistedstate": "^2.2.0",
@@ -9734,6 +9735,18 @@
}
]
},
+ "node_modules/iframe-resizer": {
+ "version": "4.3.9",
+ "resolved": "https://registry.npmjs.org/iframe-resizer/-/iframe-resizer-4.3.9.tgz",
+ "integrity": "sha512-MCt+V/THB4a9OcAdrWo5NsI2CRpeMM4ijhTfiLtsdgDJXWYXf62Ve8yO8rKGmYNs991zty/EolYOxActlkfU+A==",
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://github.com/davidjbradshaw/iframe-resizer/blob/master/FUNDING.md"
+ }
+ },
"node_modules/ignore": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
diff --git a/package.json b/package.json
index 36f4c832..9c287dc0 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"axios": "^1.4.0",
"axios-retry": "^3.5.0",
"bootstrap": "^5.3",
+ "iframe-resizer": "^4.3.9",
"maska": "^1.5.0",
"pinia": "^2.1.4",
"pinia-plugin-persistedstate": "^2.2.0",
diff --git a/public/css/README.md b/public/css/README.md
new file mode 100644
index 00000000..74cd82e3
--- /dev/null
+++ b/public/css/README.md
@@ -0,0 +1,13 @@
+# Using Sass in this folder
+
+This public/css folder uses a standalone .scss > .css setup.
+## Usage
+
+From a Terminal window, run the Sass Watch command from the public folder only:
+
+```bash
+sass --no-source-map --watch scss:css
+```
+This will compile and output .css files (into the public/css folder) that can be consumed by the Payment page.
+
+# Do not use the .css files on their own. You must use the .scss files and have Sass compile them to .css files.
diff --git a/public/css/hop-styling.css b/public/css/hop-styling.css
new file mode 100644
index 00000000..c81dda28
--- /dev/null
+++ b/public/css/hop-styling.css
@@ -0,0 +1,205 @@
+/* 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! */
+/* 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! */
+body {
+ font-family: Roboto;
+ font-weight: 400;
+ color: #000;
+ margin: 0;
+ background-color: white;
+ padding: 8px;
+}
+body .validation-info {
+ display: none;
+}
+body .italicSmall {
+ font-style: normal;
+ font-size: 14px;
+}
+body span {
+ line-height: 24px;
+}
+body a {
+ color: #1574A1;
+ text-decoration: none;
+}
+body .form-group {
+ display: flex;
+ flex-direction: column;
+}
+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;
+}
+body input,
+body select {
+ border-radius: 8px;
+ border: 1px solid #8E9292;
+ padding: 16px;
+ font-size: 16px;
+ color: #000;
+ background-color: #fff;
+}
+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;
+ 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: 8px;
+ 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;
+ appearance: none;
+ font-size: 16px;
+ color: #000;
+}
+body .creditCardSpecific div {
+ padding: 8px 0;
+}
+body .creditCardSpecific div .headerlinecontainer {
+ display: none;
+}
+body .creditCardSpecific div label {
+ font-weight: 500;
+}
+body .creditCardSpecific #infoRow2 {
+ margin-bottom: 0;
+}
+body #cardExpirationContainer {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 0;
+}
+@media (min-width: 400px) {
+ body #cardExpirationContainer {
+ flex-direction: row;
+ }
+ body #cardExpirationContainer .card_expirationYear,
+ body #cardExpirationContainer .card_expirationMonth {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ }
+ body #cardExpirationContainer .card_expirationYear {
+ margin-left: 16px;
+ }
+}
+body .optional-label span {
+ display: none;
+}
+body .optional-label:after {
+ content: " (optional)";
+ font-weight: 300;
+ font-style: normal;
+ font-size: 15px;
+}
+body .buttonContainer {
+ height: 48px;
+}
+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;
+ height: 48px;
+}
+@media (hover: hover) {
+ body .buttonContainer button {
+ background: linear-gradient(270deg, #1574a1 0%, #003d58 100%);
+ }
+}
+body .buttonContainer button:focus {
+ box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
+}
+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%);
+}
+body .buttonContainer button: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;
+}
+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 button.delay {
+ transition: background 0s 0s ease-in-out;
+}
+body .has-error input,
+body .has-error select {
+ border: 1px solid #d4281c;
+}
+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 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;
+}
+body .has-error small {
+ margin-top: 4px;
+ color: #d4281c;
+}
+body .cc-error-container #alert-message {
+ background-color: #fcbfbb;
+ border: 1px solid #d4281c;
+}
diff --git a/public/css/site-2020Styling.css b/public/css/site-2020Styling.css
new file mode 100644
index 00000000..07d33158
--- /dev/null
+++ b/public/css/site-2020Styling.css
@@ -0,0 +1,114 @@
+/* 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! */
+/* 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! */
+/* 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%;
+}
+.buy-backdrop #afterpay__iframe-checkout-container .style_closeWrapper__lIHJe {
+ display: none;
+}
+
+.buy-container-closer {
+ display: none;
+}
+
+@keyframes rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+.creditCardSpecific {
+ display: none;
+}
diff --git a/public/scss/hop-styling.scss b/public/scss/hop-styling.scss
new file mode 100644
index 00000000..a71e4aa4
--- /dev/null
+++ b/public/scss/hop-styling.scss
@@ -0,0 +1,224 @@
+/* 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! */
+/* 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! */
+body {
+ font-family: Roboto;
+ font-weight: 400;
+ color: #000;
+ margin: 0;
+ background-color: white;
+ padding: 8px;
+
+ .validation-info {
+ display: none;
+ }
+
+ .italicSmall {
+ font-style: normal;
+ font-size: 14px;
+ }
+
+ span {
+ line-height: 24px;
+ }
+
+ a {
+ color: #1574A1;
+ text-decoration: none;
+ }
+
+ .form-group {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .headerlinecontainer {
+ .headerline1 {
+ font-size: 20px;
+ line-height: 32px;
+ font-weight: 400;
+ margin: 24px 0;
+ text-align: center;
+ }
+ }
+
+ input,
+ select {
+ margin-top: 4px;
+ }
+
+ input,
+ select {
+ border-radius: 8px;
+ border: 1px solid #8E9292;
+ padding: 16px;
+ font-size: 16px;
+ color: #000;
+ background-color: #fff;
+ &:focus,
+ &:focus-visible {
+ box-shadow: 0 0 0 2.5px #1574a1;
+ border: 1px solid transparent;
+ 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: 8px;
+ 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;
+ appearance: none;
+ font-size: 16px;
+ color: #000;
+ }
+
+ .creditCardSpecific {
+ div {
+ padding: 8px 0;
+ .headerlinecontainer {
+ display: none;
+ }
+ label {
+ font-weight: 500;
+ }
+ }
+ #infoRow2 {
+ margin-bottom: 0;
+ }
+ }
+
+ #cardExpirationContainer {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 0;
+ @media (min-width: 400px) {
+ flex-direction: row;
+ .card_expirationYear,
+ .card_expirationMonth {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ }
+ .card_expirationYear {
+ margin-left: 16px;
+ }
+ }
+ }
+
+ .optional-label {
+ 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%);
+ border: none;
+ border-radius: 8px;
+ color: #fff;
+ justify-content: center;
+ font-weight: 500;
+ font-size: 16px;
+ height: 48px;
+ @media (hover: hover) {
+ background: linear-gradient(270deg, #1574a1 0%, #003d58 100%);
+ }
+ &:focus {
+ box-shadow: 0 0 0 3px, 0 0 0 5.5px #06577c;
+ }
+ &:focus, // Mouse, touch, stylus focus
+ &:focus-visible {
+ // Keyboard focus for accessibility
+ 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;
+ }
+ }
+ }
+
+ //Error Styling
+ .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;
+ }
+ }
+ 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;
+ }
+ small {
+ margin-top: 4px;
+ color: #d4281c;
+ }
+ }
+
+ .cc-error-container {
+ #alert-message {
+ background-color: #fcbfbb;
+ border: 1px solid #d4281c;
+ }
+ }
+
+}
diff --git a/public/scss/site-2020Styling.scss b/public/scss/site-2020Styling.scss
new file mode 100644
index 00000000..3cd0839b
--- /dev/null
+++ b/public/scss/site-2020Styling.scss
@@ -0,0 +1,118 @@
+/* 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! */
+/* 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! */
+
+/* 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;
+ }
+}
+
+// AfterPay Styles
+
+.buy-backdrop {
+ background-color: rgba(0,0,0,.3)!important;
+ #afterpay__iframe-checkout-container {
+ width: 100%;
+ .style_closeWrapper__lIHJe {
+ display: none;
+ }
+ }
+}
+
+.buy-container-closer {
+ display: none;
+}
+
+// Modal Spinner
+
+@keyframes rotate {
+ 0% { transform: rotate(0)}
+ 100% { transform: rotate(360deg)}
+}
+
+.creditCardSpecific {
+ display: none;
+}
diff --git a/src/constants/application-config.js b/src/constants/application-config.js
index 06fd28b5..ce39577b 100644
--- a/src/constants/application-config.js
+++ b/src/constants/application-config.js
@@ -15,8 +15,11 @@ const applicationConfig = Object.freeze({
PAGE_QUERYSTRING: 'issPage',
CLIENTTAG_QUERYSTRING: 'ClientTag',
GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY,
+ SAFELITE_HOP: process.env.VUE_APP_SAFELITE_HOP,
ISS_DEV_CMS_DOMAIN: 'https://digitalisscms.dev.safelite.io',
- CASH_PARENT_ACCOUNT_NUMBER: 167132
+ CASH_PARENT_ACCOUNT_NUMBER: 167132,
+ ITAC_FAIR_AND_REASONABLE_BILLTO: '214616', // Lib Mutal FnR BillTo
+ ITAC_CASH_BILLTO: '283393' // Lib Mutal ITAC Cash BillTo
});
export default applicationConfig;
diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js
index de544f57..5f3b1a91 100644
--- a/src/constants/endpoints.js
+++ b/src/constants/endpoints.js
@@ -182,6 +182,10 @@ const endpoints = Object.freeze({
FinalDeductible: {
url: '/coverage/api/v1/coverage/final-deductible',
method: 'POST'
+ },
+ GetPaymentSignature: {
+ url: '/order/api/v1/order/sign',
+ method: 'POST'
}
});
diff --git a/src/constants/payment-method-constants.js b/src/constants/payment-method-constants.js
index 0af1a4de..48aa5008 100644
--- a/src/constants/payment-method-constants.js
+++ b/src/constants/payment-method-constants.js
@@ -1,3 +1,9 @@
+const hopPaymentMethods = Object.freeze({
+ CREDIT_CARD: 'cc',
+ PAYPAL: 'pp',
+ AFTERPAY: 'ap'
+});
+
const paymentMethods = Object.freeze({
NONE: null,
PAY_AT_TIME_OF_SERVICE: 'PayAtTimeOfService',
@@ -6,4 +12,4 @@ const paymentMethods = Object.freeze({
AFTERPAY: 'Afterpay'
});
-export default paymentMethods;
+export { hopPaymentMethods, paymentMethods };
diff --git a/src/layouts/payment-method/payment-method.spec.js b/src/layouts/payment-method/payment-method.spec.js
index dc31f064..01e06a1e 100644
--- a/src/layouts/payment-method/payment-method.spec.js
+++ b/src/layouts/payment-method/payment-method.spec.js
@@ -5,7 +5,7 @@ import paymentMethod from '@/layouts/payment-method/payment-method.vue';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { useMainStore } from '@/store';
-import paymentMethods from '@/constants/payment-method-constants';
+import { paymentMethods } from '@/constants/payment-method-constants';
function setupMocks() {
const mountOptions = getMountOptions();
diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue
index 2beb7322..5d50380d 100644
--- a/src/layouts/payment-method/payment-method.vue
+++ b/src/layouts/payment-method/payment-method.vue
@@ -42,6 +42,7 @@
diff --git a/src/router/index.js b/src/router/index.js
index bef88b03..4cd2dc45 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -129,6 +129,14 @@ router.beforeEach(async (to, from) => {
showIssLoadingModal(true);
}
+ const isInIframe = fromQueryPage === IssPageValues.PAYMENT_PAGE;
+ if (isInIframe) {
+ // need to set window.top.location.href directly when navigating out of an iframe
+ // especially when navigating with browser buttons
+ const newUrl = `${window.top.location.origin}${to.href}`;
+ window.top.location.href = newUrl;
+ }
+
const store = useMainStore();
// Prevent navigating backwards if we enter a bailout that we are not allowed to go back on
if (store.isBailout && from.name === IssPageValues.BAILOUT_PAGE && to.name !== 'root' && to.name !== IssPageValues.CONTACT_CONFIRMATION
diff --git a/src/router/router-constants/externalUrl-values.js b/src/router/router-constants/externalUrl-values.js
new file mode 100644
index 00000000..428f4922
--- /dev/null
+++ b/src/router/router-constants/externalUrl-values.js
@@ -0,0 +1,7 @@
+import applicationConfig from '@/constants/application-config';
+
+const externalUrls = {
+ SAFELITE_HOP: applicationConfig.SAFELITE_HOP
+};
+
+export default externalUrls;
diff --git a/src/router/router-constants/issPage-values.js b/src/router/router-constants/issPage-values.js
index 419d44f3..b44a9a9d 100644
--- a/src/router/router-constants/issPage-values.js
+++ b/src/router/router-constants/issPage-values.js
@@ -18,6 +18,7 @@ const issPageValues = Object.freeze({
ORDER_CONFIRMATION: 'order-confirmation',
PAYMENT_METHOD: 'payment-method',
PAYMENT_PAGE: 'payment-page',
+ PAYMENT_RETURN: 'payment-return',
PART_QUESTIONS: 'part-questions',
POLICY_HOLDER_DETAILS: 'policy-holder-details',
PROVIDER_PREFERENCE: 'provider-preference',
diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js
index f71a452a..1406498e 100644
--- a/src/router/router-constants/navigation-scenarios.js
+++ b/src/router/router-constants/navigation-scenarios.js
@@ -89,6 +89,9 @@ const navigationScenarios = Object.freeze({
CLICKED_SERVICE_PACKAGE_EDIT: 'CLICKED_SERVICE_PACKAGE_EDIT',
CLICKED_VEHICLE_EDIT: 'CLICKED_VEHICLE_EDIT',
+ // Payment
+ CLICKED_PAY_NOW: 'CLICKED_PAY_NOW',
+
// Bailout
CLICKED_FORWARD_WITH_BAILOUT: 'CLICKED_FORWARD_WITH_BAILOUT'
});
diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js
index 0badb2e7..df960f77 100644
--- a/src/router/router-constants/routing-table.js
+++ b/src/router/router-constants/routing-table.js
@@ -609,6 +609,10 @@ const routingTable = () => [
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationIssPageValue: issPageValues.ORDER_CONFIRMATION
+ },
+ {
+ scenario: navigationScenarios.CLICKED_PAY_NOW,
+ destinationIssPageValue: issPageValues.PAYMENT_PAGE
}
]
},
@@ -617,7 +621,7 @@ const routingTable = () => [
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
- destinationIssPageValue: issPageValues.REVIEW_PAGE
+ destinationIssPageValue: issPageValues.PAYMENT_METHOD
},
{
scenario: navigationScenarios.CLICKED_FORWARD,
diff --git a/src/store/index.js b/src/store/index.js
index fa1e57e9..06da1c35 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -13,7 +13,7 @@ import damageLocationsSelected from '@/constants/damage-locations-selected';
import coverageStatuses from '@/constants/coverage-statuses';
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants';
import { convertDateStringToDate, getDateDifferenceInDays, militaryToTwelveHourTime } from '@/helpers/date-helper';
-import paymentMethods from '@/constants/payment-method-constants';
+import { paymentMethods } from '@/constants/payment-method-constants';
const storeId = 'main';
@@ -839,7 +839,7 @@ export const useMainStore = defineStore({
endDate,
shopAppointmentType,
applicationName: applicationConfig.APPLICATION_NAME,
- billToAccountNumber: this.issConfig.parentAccountNumber.toString(), // TODO: MAKE THIS REAL
+ billToAccountNumber: order.policy.isITAC ? applicationConfig.ITAC_CASH_BILLTO : applicationConfig.ITAC_FAIR_AND_REASONABLE_BILLTO, // TODO: MAKE THIS REAL
parentAccountNumber: this.issConfig.parentAccountNumber, // this.payment.parentAccountNumber,
carId: vehicle.carId,
lineItems,
@@ -2153,6 +2153,13 @@ export const useMainStore = defineStore({
const isPayInAdvance = paymentMethod !== paymentMethods.PAY_AT_TIME_OF_SERVICE;
this.order.payment.isPayInAdvance = isPayInAdvance;
this.order.payment.payInAdvanceType = isPayInAdvance ? paymentMethod : null;
+ },
+
+ getPaymentSignature() {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetPaymentSignature.method,
+ endpoint: endpoints.GetPaymentSignature.url
+ });
}
},
diff --git a/src/store/store.spec.js b/src/store/store.spec.js
index 108b5900..98f2fd09 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -3,7 +3,7 @@ import { useMainStore } from '@/store/index.js';
import globalMethods from '@/global-methods.js';
import { getRandomString, getRandomGuid, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js';
import coverageStatuses from '@/constants/coverage-statuses.js';
-import paymentMethods from '@/constants/payment-method-constants';
+import { paymentMethods } from '@/constants/payment-method-constants';
import { endpoints } from '@/constants/endpoints';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
diff --git a/vue.config.js b/vue.config.js
index dcc30a25..0a7711e6 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -2,6 +2,7 @@
process.env.VUE_APP_CONSUMER_CF_DISTRO = 'https://digitalapi.dev.safelite.io';
process.env.VUE_APP_CURRENT_ENVIRONMENT = 'Localhost';
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = 'AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0';
+process.env.VUE_APP_SAFELITE_HOP = 'https://iss-hop-sys.glassclaim.com/fmgCheckoutEmbedded.aspx';
// GA & GTM
// NOTE: Using the old ISS site GTM Cotnainer ID for now, will create a new one soon.
diff --git a/vue.release.config.js b/vue.release.config.js
index c3c79a75..2cfed6dd 100644
--- a/vue.release.config.js
+++ b/vue.release.config.js
@@ -1,6 +1,7 @@
process.env.VUE_APP_CONSUMER_CF_DISTRO = "__VUE_APP_CONSUMER_CF_DISTRO__";
process.env.VUE_APP_CURRENT_ENVIRONMENT = "__VUE_APP_CURRENT_ENVIRONMENT__";
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "__VUE_APP_GOOGLE_PLACES_API_KEY__";
+process.env.VUE_APP_SAFELITE_HOP = "__VUE_APP_SAFELITE_HOP__";
// GA & GTM
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__";