diff --git a/src/assets/img/icons/add-to-calendar.svg b/src/assets/img/icons/add-to-calendar.svg
new file mode 100644
index 000000000..fd621c5c5
--- /dev/null
+++ b/src/assets/img/icons/add-to-calendar.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/constants/application-config.js b/src/constants/application-config.js
index 4c5305783..808acfe0a 100644
--- a/src/constants/application-config.js
+++ b/src/constants/application-config.js
@@ -10,6 +10,7 @@ const applicationConfig = {
PAGE_QUERYSTRING: "fmgPage",
SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass",
CASH_PARENT_ACCOUNT_NUMBER: 167132,
+ MY_ACCOUNT: process.env.VUE_APP_MY_ACCOUNT,
};
export { applicationConfig };
diff --git a/src/helpers/date-helper.js b/src/helpers/date-helper.js
index dce497231..48b3122ab 100644
--- a/src/helpers/date-helper.js
+++ b/src/helpers/date-helper.js
@@ -8,3 +8,57 @@ export function getDateDifferenceInDays(startDate, endDate) {
// To calculate the no. of days between two dates
return Difference_In_Time / (1000 * 3600 * 24);
}
+
+export function getFullDayName(date) {
+ if (date instanceof Date !== true) return;
+ const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+ return days[date.getDay()];
+}
+export function getFullMonthName(date) {
+ if (date instanceof Date !== true) return;
+ const monthNames = [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+ ];
+ return monthNames[date.getMonth()];
+}
+export function get12HourTimeFormat(time) {
+ // Check correct time format and split into components
+ time = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time];
+
+ if (time.length > 1) {
+ // If time format correct
+ time = time.slice(1); // Remove full string match value
+ time[5] = +time[0] < 12 ? " AM" : " PM"; // Set AM/PM
+ time[0] = +time[0] % 12 || 12; // Adjust hours
+ }
+ return time.join(""); // return adjusted time or original string
+}
+export function get12HourTimeMobileFormat(time) {
+ // Check correct time format and split into components
+ time = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time];
+
+ if (time.length > 1) {
+ // If time format correct
+ const min = time[3];
+ time = time.slice(1); // Remove full string match value
+ if (Number(min) == 0) {
+ time = time.slice(0, 1); // Remove minute value
+ time[1] = +time[0] < 12 ? " AM" : " PM"; // Set AM/PM
+ } else {
+ time[5] = +time[0] < 12 ? " AM" : " PM"; // Set AM/PM
+ }
+ time[0] = +time[0] % 12 || 12; // Adjust hours
+ }
+ return time.join(""); // return adjusted time or original string
+}
diff --git a/src/layouts/confirmation/confirmation.spec.js b/src/layouts/confirmation/confirmation.spec.js
index 1f71aa033..c60b19c26 100644
--- a/src/layouts/confirmation/confirmation.spec.js
+++ b/src/layouts/confirmation/confirmation.spec.js
@@ -6,6 +6,7 @@ import { shallowMount } from "@vue/test-utils";
import { nextTick } from "vue";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
+import router from "@/router";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
@@ -54,6 +55,14 @@ beforeEach(() => {
isRepair: false,
},
referralNumber: "1234567",
+ vehicle: {
+ year: "2004",
+ make: "Ford",
+ model: "F Series F250",
+ },
+ customer: {
+ emailAddress: "test@test.com",
+ },
},
payment: {
isInsurance: true,
@@ -71,9 +80,19 @@ afterEach(() => {
});
describe("confirmation.vue", () => {
+ const realLocation = window.location;
+
+ beforeAll(() => {
+ delete window.location;
+ window.location = { ...realLocation, assign: jest.fn() };
+ });
+
+ afterAll(() => {
+ window.location = realLocation;
+ });
test("arePagePrerequisitesValid should be true ", async () => {
//Arrange
- const { wrapper } = setupMocks();
+ const { wrapper } = setupMocks({});
//Act
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
@@ -82,20 +101,33 @@ describe("confirmation.vue", () => {
//Assert
expect(arePagePrerequisitesValid).toBe(true);
});
+ test("'Back to safelite.com' button should take user back to safelite.com", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ await wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(window.location.assign).toHaveBeenCalled();
+ });
});
-function setupMocks() {
- const wrapper = shallowMount(
- confirmation,
- getMountOptions({
- router: {
- navigate: jest.fn(),
- navigate: jest.fn(),
- navigateWithSaving: jest.fn(),
- navigateWithoutSaving: jest.fn(),
- },
- })
- );
+const wordingText = "wording Text";
+function setupMocks({ customMountOptions }) {
+ const mountOptions = getMountOptions({
+ ...customMountOptions,
+ });
+ mountOptions.mixins = [
+ {
+ methods: {
+ getCmsContent: jest.fn().mockImplementation(() => {
+ return wordingText;
+ }),
+ },
+ },
+ ];
+ const wrapper = shallowMount(confirmation, mountOptions);
return { wrapper };
}
diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue
index 6e913fdf5..059c09230 100644
--- a/src/layouts/confirmation/confirmation.vue
+++ b/src/layouts/confirmation/confirmation.vue
@@ -5,6 +5,40 @@
+
+
+
+
+
+
+
{{ this.getScheduleDate() }}
+
{{ this.getScheduleTime() }}
+
+
+
+
+
+
+
+
+
+
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
+import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
import navbar from "@/fmg-components/nav-bar/nav-bar";
//Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { settleAllPromises } from "@/helpers/layout-helper";
+import { applicationConfig } from "@/constants/application-config.js";
import store from "@/store";
+
+import {
+ getFullDayName,
+ getFullMonthName,
+ get12HourTimeFormat,
+ get12HourTimeMobileFormat,
+} from "@/helpers/date-helper";
export default {
name: "confirmation",
async beforeRouteEnter(to, from, next) {
@@ -47,6 +90,77 @@ export default {
vm.setCmsContent(resultMap.cmsContent);
});
},
+ computed: {
+ ScheduleConfirmationText() {
+ return this.getCmsContent("ScheduleConfirmationWidget", "BodyText");
+ },
+ ScheduleConfirmationImage() {
+ return this.getCmsContent("ScheduleConfirmationWidget", "Image");
+ },
+ ConfirmationEmailText() {
+ return this.getCmsContent("ConfirmationEmailWidget", "BodyText");
+ },
+ ScheduleDate() {
+ return store.getters.order.schedule.date;
+ },
+ AppointmentType() {
+ return store.getters.order.serviceLocation.appointmentType;
+ },
+ ScheduleStartTime() {
+ return store.getters.order.schedule.startTime;
+ },
+ ScheduleEndTime() {
+ return store.getters.order.schedule.endTime;
+ },
+ InShopWordingText() {
+ return this.getCmsContent("InShopWordingWidget", "BodyText");
+ },
+ MobileWordingText() {
+ return this.getCmsContent("MobileWordingWidget", "BodyText");
+ },
+ DropOffWordingText() {
+ return this.getCmsContent("DropOffWordingWidget", "BodyText");
+ },
+ ServiceLocationAddress() {
+ return store.getters.order.serviceLocation.address;
+ },
+ ServiceLocationAddress2() {
+ return store.getters.order.serviceLocation.address2;
+ },
+ ServiceLocationCity() {
+ return store.getters.order.serviceLocation.city;
+ },
+ ServiceLocationState() {
+ return store.getters.order.serviceLocation.state;
+ },
+ ServiceLocationZipCode() {
+ return store.getters.order.serviceLocation.zipCode;
+ },
+ ProviderAddress() {
+ return store.getters.order.serviceLocation.provider.address.streetAddress;
+ },
+ ProviderCity() {
+ return store.getters.order.serviceLocation.provider.address.city;
+ },
+ ProviderState() {
+ return store.getters.order.serviceLocation.provider.address.state;
+ },
+ ProviderZipCode() {
+ return store.getters.order.serviceLocation.provider.address.zipCode;
+ },
+ Year() {
+ return store.getters.order.vehicle.year;
+ },
+ Make() {
+ return store.getters.order.vehicle.make;
+ },
+ Model() {
+ return store.getters.order.vehicle.model;
+ },
+ Email() {
+ return store.getters.order.customer.emailAddress;
+ },
+ },
methods: {
arePagePrerequisitesValid() {
// Service Location
@@ -78,12 +192,136 @@ export default {
return serviceLocationReqs && scheduleReqs;
},
forwardButtonAction() {
- window.location.replace("https://safelite.com");
+ window.location.assign("//www.safelite.com/");
+ },
+ getScheduleDate() {
+ const scheduleDate = new Date(this.ScheduleDate);
+ return `${getFullDayName(scheduleDate)}, ${getFullMonthName(
+ scheduleDate
+ )} ${scheduleDate.getDate()}`;
+ },
+ getScheduleTime() {
+ if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
+ return `Between ${get12HourTimeMobileFormat(
+ this.ScheduleStartTime
+ )} - ${get12HourTimeMobileFormat(this.ScheduleEndTime)}`;
+ } else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
+ return `Drop off before 9:30 AM`;
+ } else {
+ return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`;
+ }
+ },
+
+ getAppointmentWordingText() {
+ const ymm = `${this.Year} ${this.Make} ${this.Model}`;
+ if (this.AppointmentType == AppointmentTypeStrings.MOBILE) {
+ const address = `${
+ this.ServiceLocationAddress2 ? this.ServiceLocationAddress2 + "," : ""
+ } ${this.ServiceLocationAddress},
${this.ServiceLocationCity}, ${
+ this.ServiceLocationState
+ } ${this.ServiceLocationZipCode}`;
+ return this.MobileWordingText.replace("#ADDRESS", address).replace("#YMM", ymm);
+ } else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) {
+ const address = `${this.ProviderAddress},
${this.ProviderCity}, ${this.ProviderState} ${this.ProviderZipCode}`;
+ return this.DropOffWordingText.replace("#ADDRESS", address).replace("#YMM", ymm);
+ } else {
+ const address = `${this.ProviderAddress},
${this.ProviderCity}, ${this.ProviderState} ${this.ProviderZipCode}`;
+ return this.InShopWordingText.replace("#ADDRESS", address).replace("#YMM", ymm);
+ }
+ },
+ getConfirmationEmailText() {
+ return this.ConfirmationEmailText.replace("#EMAIL", this.Email)
+ .replace("#MY_ACCOUNT_URL", applicationConfig.MY_ACCOUNT)
+ .replace(/</g, "<")
+ .replace(/>/g, ">");
},
},
components: {
funnelHeader,
navbar,
+ vehicleBanner,
},
};
+
+
diff --git a/vue.config.js b/vue.config.js
index e8b1a489f..70350b717 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,10 +1,8 @@
-process.env.VUE_APP_CONSUMER_CF_DISTRO =
- "https://digitalapi.dev.safelite.io";
-process.env.VUE_APP_HERITAGE_FUNNEL =
- "http://localhost:38000/default.aspx";
-process.env.VUE_APP_GOOGLE_PLACES_API_KEY =
- "AIzaSyDptGCkOPgN2uWJOy4ou4M33phRD4MAoJo";
+process.env.VUE_APP_CONSUMER_CF_DISTRO = "https://digitalapi.dev.safelite.io";
+process.env.VUE_APP_HERITAGE_FUNNEL = "http://localhost:38000/default.aspx";
+process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "AIzaSyDptGCkOPgN2uWJOy4ou4M33phRD4MAoJo";
process.env.VUE_APP_CURRENT_ENVIRONMENT = "Localhost";
+process.env.VUE_APP_MY_ACCOUNT = "https://myaccountdev.safelite.com/";
//process.env.VUE_APP_SAFELITE_HOP = "http://localhost:60966/fmgCheckoutEmbedded.aspx";
process.env.VUE_APP_SAFELITE_HOP = "https://sv2-safelitehop-sys.safelite.com/fmgCheckoutEmbedded.aspx";
@@ -12,30 +10,31 @@ process.env.VUE_APP_PAYPAL_SUCCESS_URL = "http://localhost:8080/fmg/?fmgPage=pay
process.env.VUE_APP_PAYPAL_CANCEL_URL = "http://localhost:8080/fmg/?fmgPage=payment-method&src=concept-funnel";
// GA & GTM
-process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl+ '>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x';f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-M6XCRH');";
-
-process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC = "https://www.googletagmanager.com/ns.html?id=GTM-M6XCRH>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x";
+process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY =
+ "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl+ '>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x';f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-M6XCRH');";
+process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC =
+ "https://www.googletagmanager.com/ns.html?id=GTM-M6XCRH>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x";
module.exports = {
- outputDir: "dist/fmg",
- publicPath: "/fmg",
- css: {
- loaderOptions: {
- sass: {
- // Load Order Matters!!!
- // Note: only include functions, variables and mixins here
- prependData: `
+ outputDir: "dist/fmg",
+ publicPath: "/fmg",
+ css: {
+ loaderOptions: {
+ sass: {
+ // Load Order Matters!!!
+ // Note: only include functions, variables and mixins here
+ prependData: `
@import "./node_modules/bootstrap/scss/functions";
@import "@/styles/ux-variables.scss";
@import "./node_modules/bootstrap/scss/variables";
@import "./node_modules/bootstrap/scss/mixins";
@import "@/styles/mixins/customMixins";
`,
- },
+ },
+ },
+ },
+ configureWebpack: {
+ devtool: "source-map",
},
- },
- configureWebpack: {
- devtool: 'source-map'
- },
};
diff --git a/vue.release.config.js b/vue.release.config.js
index a9ddd5a5c..4cad6611a 100644
--- a/vue.release.config.js
+++ b/vue.release.config.js
@@ -2,6 +2,7 @@ process.env.VUE_APP_CONSUMER_CF_DISTRO = "__VUE_APP_CONSUMER_CF_DISTRO__";
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "__VUE_APP_GOOGLE_PLACES_API_KEY__";
process.env.VUE_APP_HERITAGE_FUNNEL = "__VUE_APP_HERITAGE_FUNNEL__";
process.env.VUE_APP_CURRENT_ENVIRONMENT = "__VUE_APP_CURRENT_ENVIRONMENT__";
+process.env.VUE_APP_MY_ACCOUNT = "__VUE_APP_MY_ACCOUNT__";
process.env.VUE_APP_SAFELITE_HOP = "__VUE_APP_SAFELITE_HOP__";
process.env.VUE_APP_PAYPAL_SUCCESS_URL = "__VUE_APP_PAYPAL_SUCCESS_URL__";
@@ -9,24 +10,25 @@ process.env.VUE_APP_PAYPAL_CANCEL_URL = "__VUE_APP_PAYPAL_CANCEL_URL__";
// GA & GTM
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__";
-process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC = "__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__"
+process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC =
+ "__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__";
module.exports = {
- outputDir: "dist/fmg",
- publicPath: "/fmg",
- css: {
- loaderOptions: {
- sass: {
- // Load Order Matters!!!
- // Note: only include functions, variables and mixins here
- prependData: `
+ outputDir: "dist/fmg",
+ publicPath: "/fmg",
+ css: {
+ loaderOptions: {
+ sass: {
+ // Load Order Matters!!!
+ // Note: only include functions, variables and mixins here
+ prependData: `
@import "./node_modules/bootstrap/scss/functions";
@import "@/styles/ux-variables.scss";
@import "./node_modules/bootstrap/scss/variables";
@import "./node_modules/bootstrap/scss/mixins";
@import "@/styles/mixins/customMixins";
`,
- },
+ },
+ },
},
- },
};