From 6defb7ea9c04babaf5dbc32a952501226991545e Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 19 Oct 2023 17:28:09 +0530 Subject: [PATCH 01/14] Calendar content Calendar content from CMS --- .../add-to-calendar/add-to-calendar.spec.js | 187 ++++++------------ .../add-to-calendar/add-to-calendar.vue | 142 +------------ src/layouts/confirmation/confirmation.spec.js | 16 +- src/layouts/confirmation/confirmation.vue | 165 ++++++++++++++-- 4 files changed, 223 insertions(+), 287 deletions(-) diff --git a/src/layouts/add-to-calendar/add-to-calendar.spec.js b/src/layouts/add-to-calendar/add-to-calendar.spec.js index 645e3b12f..14b6d978b 100644 --- a/src/layouts/add-to-calendar/add-to-calendar.spec.js +++ b/src/layouts/add-to-calendar/add-to-calendar.spec.js @@ -69,7 +69,23 @@ afterEach(() => { describe("Add-to-calendar methods...", () => { test("Add-to-calendar should trigger openModal method", () => { //Arrange - const { wrapper } = setupMocks({}); + + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + appointment: { + RefrrlSeqNum: "123456", + StartDate: new Date(2023, 9, 11, 12, 0, 0), + EndDate: new Date(2023, 9, 11, 13, 0, 0), + Subject: "Meeting with John", + Location: "Conference Room", + Body: "Discuss the project progress", + IsHTML: true, + Duration: "1220", + }, + }, + }, + }); //Act wrapper.vm.openCalendarModal(); @@ -77,45 +93,26 @@ describe("Add-to-calendar methods...", () => { //Assert expect(wrapper.vm.$refs.calendarModalQuestion.openModal).toBeCalled(); }); - test("serviceType should return 'replacement and recalibration' when isRepair is false and funnelHasRecalibrationPart true.", () => { - //Arrange - store.getters.order.damage.isRepair = false; - store.getters.funnelHasRecalibrationPart = true; - const { wrapper } = setupMocks({}); - //Act - const testValue = wrapper.vm.serviceType(); - - //Assert - expect(testValue).toEqual("replacement and recalibration"); - }); - test("serviceType should return 'replacement' when isRepair is false and funnelHasRecalibrationPart is false.", () => { - //Arrange - store.getters.order.damage.isRepair = false; - store.getters.funnelHasRecalibrationPart = false; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.serviceType(); - - //Assert - expect(testValue).toEqual("replacement"); - }); - test("serviceType should return 'repair' when isRepair is true.", () => { - //Arrange - store.getters.order.damage.isRepair = true; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.serviceType(); - - //Assert - expect(testValue).toEqual("repair"); - }); test("getCalendarData should return expected model value.", () => { //Arrange const type = calendarOptions.OUTLOOKCOM; - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + appointment: { + RefrrlSeqNum: "123456", + StartDate: new Date(2023, 9, 11, 12, 0, 0), + EndDate: new Date(2023, 9, 11, 13, 0, 0), + Subject: "Meeting with John", + Location: "Conference Room", + Body: "Discuss the project progress", + IsHTML: true, + Duration: "1220", + }, + }, + }, + }); //Act const testValue = wrapper.vm.getCalendarData(type); @@ -123,95 +120,26 @@ describe("Add-to-calendar methods...", () => { //Assert expect(testValue.name).toEqual(calendarOptions.OUTLOOKCOM); }); - test("getappointmentData should return expected model value for appointmentType mobile.", () => { - //Arrange - store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE; - store.getters.order.damage.isRepair = false; - store.getters.funnelHasRecalibrationPart = true; - const { wrapper } = setupMocks({}); - //Act - const testValue = wrapper.vm.getappointmentData(); - - //Assert - expect(testValue.Subject).toEqual("Safelite replacement and recalibration appointment"); - }); - test("getappointmentData should return expected model value for appointmentType DROP_OFF and OVERNIGHT_DROP_OFF.", () => { - //Arrange - store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF; - store.getters.order.schedule.routeCode = RouteCodeFlags.OVERNIGHT_DROP_OFF; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.getappointmentData(); - - //Assert - expect(testValue.Subject).toEqual("Drop off your vehicle by 5:30 PM"); - }); - test("getappointmentData should return expected model value for appointmentType DROP_OFF and ALL_DAY_DROP_OFF and isSameDayDropOff.", () => { - //Arrange - store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF; - store.getters.order.schedule.routeCode = RouteCodeFlags.ALL_DAY_DROP_OFF; - store.getters.order.schedule.date = new Date().toISOString().split("T")[0]; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.getappointmentData(); - - //Assert - expect(testValue.Subject).toEqual("Drop off your vehicle in the next 30 - 60 minutes"); - }); - test("getappointmentData should return expected model value for appointmentType DROP_OFF and ALL_DAY_DROP_OFF.", () => { - //Arrange - store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF; - store.getters.order.schedule.routeCode = RouteCodeFlags.ALL_DAY_DROP_OFF; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.getappointmentData(); - - //Assert - expect(testValue.Subject).toEqual("Drop off your vehicle between 9:00 AM - 11:00 AM"); - }); - test("getappointmentData should return expected model value for appointmentType DROP_OFF.", () => { - //Arrange - store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF; - store.getters.order.damage.isRepair = true; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.getappointmentData(); - - //Assert - expect(testValue.Subject).toEqual("Safelite repair appointment"); - }); - test("getappointmentData should return expected model value for appointmentType IN_SHOP.", () => { - //Arrange - store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP; - store.getters.order.damage.isRepair = true; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.getappointmentData(); - - //Assert - expect(testValue.Subject).toEqual("Safelite repair appointment"); - }); - test("isSameDayDropOff should return true for current schedule date.", () => { - //Arrange - store.getters.order.schedule.date = new Date().toISOString().split("T")[0]; - const { wrapper } = setupMocks({}); - - //Act - const testValue = wrapper.vm.isSameDayDropOff(); - - //Assert - expect(testValue).toEqual(true); - }); test("setCalendarAppointment should call getAppointment method for iCAL and Outlook.", () => { //Arrange const newValue = { name: calendarOptions.OUTLOOK }; - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + appointment: { + RefrrlSeqNum: "123456", + StartDate: new Date(2023, 9, 11, 12, 0, 0), + EndDate: new Date(2023, 9, 11, 13, 0, 0), + Subject: "Meeting with John", + Location: "Conference Room", + Body: "Discuss the project progress", + IsHTML: true, + Duration: "1220", + }, + }, + }, + }); wrapper.vm.getAppointment = jest.fn(); //Act wrapper.vm.setCalendarAppointment(newValue); @@ -222,7 +150,22 @@ describe("Add-to-calendar methods...", () => { test("setCalendarAppointment should call window.open for Google, yahoo and Outlook.com.", () => { //Arrange const newValue = { name: calendarOptions.GOOGLE }; - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + appointment: { + RefrrlSeqNum: "123456", + StartDate: new Date(2023, 9, 11, 12, 0, 0), + EndDate: new Date(2023, 9, 11, 13, 0, 0), + Subject: "Meeting with John", + Location: "Conference Room", + Body: "Discuss the project progress", + IsHTML: true, + Duration: "1220", + }, + }, + }, + }); window.open = jest.fn(); //Act diff --git a/src/layouts/add-to-calendar/add-to-calendar.vue b/src/layouts/add-to-calendar/add-to-calendar.vue index 3f32a525b..afd9942ea 100644 --- a/src/layouts/add-to-calendar/add-to-calendar.vue +++ b/src/layouts/add-to-calendar/add-to-calendar.vue @@ -22,26 +22,19 @@ import { calendarOptions } from "@/constants/calendar-options"; import { calendarStatus } from "@/constants/calendar-status"; import calendarModalQuestion from "@/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question"; -import { - getDateFormat, - calculateDuration, - combineDateAndTime, - shortTimeString, - addMinutes, -} from "@/helpers/date-helper"; +import { getDateFormat } from "@/helpers/date-helper"; import { getCalendarFile, download } from "@/helpers/add-to-calendar-helper"; -import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants"; -import store from "@/store"; -import { serviceType } from "@/constants/service-type"; export default { name: "add-to-calendar", components: { calendarModalQuestion, }, + props: { + appointment: Object, + }, data() { return { - appointment: this.getappointmentData(), selectedCalendarOption: null, }; }, @@ -83,67 +76,6 @@ export default { openCalendarModal() { this.$refs["calendarModalQuestion"].openModal(); }, - scheduleDate() { - return store.getters.order.schedule.date; - }, - scheduleStartTime() { - return store.getters.order.schedule.startTime; - }, - scheduleEndTime() { - return store.getters.order.schedule.endTime; - }, - 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; - }, - appointmentType() { - return store.getters.order.serviceLocation.appointmentType; - }, - uniqueId() { - return store.getters.order.referralNumber?.toString(); - }, - serviceType() { - const isRepair = store.getters.order.damage.isRepair; - const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart; - if (!isRepair) { - if (funnelHasRecalibrationPart) { - return serviceType.REPLACEMENT_AND_RECALIBRATION; - } else { - return serviceType.REPLACEMENT; - } - } - return serviceType.REPAIR; - }, - routeCode() { - return store.getters.order.schedule.routeCode; - }, - isSameDayDropOff() { - const todaysDate = new Date().toISOString().split("T")[0]; - return this.scheduleDate() === todaysDate; - }, getCalendarData(type) { var URL = ""; const dateFormat = "yyyyMMddTHHmmss"; @@ -185,72 +117,6 @@ export default { icon: require(`@/assets/img/icons/${type}.svg`), }; }, - getappointmentData() { - var subject = ""; - var location = ""; - var startDateTime = combineDateAndTime(this.scheduleDate(), this.scheduleStartTime()); - var endDateTime = combineDateAndTime(this.scheduleDate(), this.scheduleEndTime()); - var body = ""; - var isHTML = false; - var duration = ""; - - if (this.appointmentType() === AppointmentTypeStrings.MOBILE) { - location = `${ - this.ServiceLocationAddress2() ? this.ServiceLocationAddress2() + ", " : "" - }${this.serviceLocationAddress()}, ${this.serviceLocationCity()}, ${this.serviceLocationState()} ${this.serviceLocationZipCode()}`; - subject = `Safelite ${this.serviceType()} appointment`; - - body = - "Your safety is our top priority, so we'll let you know who's coming to you and your tech will reach out to let you know when they're on the way."; - } else { - location = `${this.providerAddress()}, ${this.providerCity()}, ${this.providerState()} ${this.providerZipCode()}`; - if (this.appointmentType() === AppointmentTypeStrings.DROP_OFF) { - if (this.routeCode().includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) { - subject = "Drop off your vehicle by 5:30 PM"; - - body = - "Drop off your vehicle by 5:30 PM the night of your scheduled appointment. The shop will work with you on a convenient pick-up time."; - } else if (this.routeCode().includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) { - if (this.isSameDayDropOff()) { - subject = "Drop off your vehicle in the next 30 - 60 minutes"; - endDateTime = addMinutes(startDateTime, 120); - body = - "Drop your vehicle off in the next 30 - 60 minutes. We'll work your vehicle into our day's schedule. The shop will work with you on a convenient pick-up time."; - } else { - endDateTime = addMinutes(startDateTime, 120); - subject = - "Drop off your vehicle between " + - shortTimeString(startDateTime) + - " - " + - shortTimeString(endDateTime); - - body = `Drop off your vehicle by ${shortTimeString( - endDateTime - )} and pick it up later in the day. When you arrive, park in an open space and follow the key drop instructions. We'll text you when your vehicle is ready.`; - } - } //normal time slot - else { - subject = `Safelite ${this.serviceType()} appointment`; - body = "Just a reminder that you're coming to us at " + location + "."; - } - } else { - subject = `Safelite ${this.serviceType()} appointment`; - body = "Just a reminder that you're coming to us at " + location + "."; - } - duration = calculateDuration(startDateTime, endDateTime); - } - return { - Subject: subject, - Location: location, - StartDate: startDateTime, - EndDate: endDateTime, - RefrrlSeqNum: this.uniqueId(), - Body: body, - IsHTML: isHTML, - Duration: duration, - }; - }, - getAppointment() { let body = this.appointment.Body; body = body.replace("|", "<").replace("~", ">"); diff --git a/src/layouts/confirmation/confirmation.spec.js b/src/layouts/confirmation/confirmation.spec.js index eb77afcb1..4bef5f8a3 100644 --- a/src/layouts/confirmation/confirmation.spec.js +++ b/src/layouts/confirmation/confirmation.spec.js @@ -115,16 +115,16 @@ describe("confirmation.vue", () => { }); }); describe("computed properties...", () => { - // test("ScheduleDateFormatted should return date in expected format.", () => { - // //Arrange - // const { wrapper } = setupMocks({}); + test("ScheduleDateFormatted should return date in expected format.", () => { + //Arrange + const { wrapper } = setupMocks({}); - // // Act - // const testValue = wrapper.vm.ScheduleDateFormatted; + // Act + const testValue = wrapper.vm.ScheduleDateFormatted; - // // Assert - // expect(testValue).toEqual("Sunday, January 1"); - // }); + // Assert + expect(testValue).toEqual("Sunday, January 1"); + }); test("ScheduleTimeFormatted should return mobile time in expected format.", () => { //Arrange store.getters.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE; diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 5fa24856d..1fbcbe4fc 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -10,10 +10,6 @@ -
-
-

{{ this.ScheduleDateFormatted }}

-

{{ this.ScheduleTimeFormatted }}

+

{{ ScheduleDateFormatted }}

+

{{ ScheduleTimeFormatted }}

- + -
+
-
+
"); + ?.replaceAll("{custom:MY_ACCOUNT_URL}", applicationConfig.MY_ACCOUNT) + ?.replaceAll("<", "<") + ?.replaceAll(">", ">"); }, ScheduleDate() { return store.getters.order.schedule.date; @@ -143,17 +143,17 @@ export default { }, AppointmentWordingText() { if (this.AppointmentType == AppointmentTypeStrings.MOBILE) { - return this.MobileWordingText.replaceAll( + return this.MobileWordingText?.replaceAll( "{custom:ADDRESS}", this.ServiceLocationFullAddress ); } else if (this.AppointmentType == AppointmentTypeStrings.DROP_OFF) { - return this.DropOffWordingText.replaceAll( + return this.DropOffWordingText?.replaceAll( "{custom:ADDRESS}", this.ProviderFullAddress ); } else { - return this.InShopWordingText.replaceAll( + return this.InShopWordingText?.replaceAll( "{custom:ADDRESS}", this.ProviderFullAddress ); @@ -190,6 +190,133 @@ export default { return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`; } }, + IsSameDayDropOff() { + const todaysDate = new Date().toISOString().split("T")[0]; + return this.ScheduleDate === todaysDate; + }, + Mobile_Appointment_Subject() { + return this.getCmsContent("Mobile_Appointment_Widget", "HeaderText"); + }, + Mobile_Appointment_Body() { + return this.getCmsContent("Mobile_Appointment_Widget", "BodyText"); + }, + InShop_Appointment_Subject() { + return this.getCmsContent("InShop_Appointment_Widget", "HeaderText"); + }, + InShop_Appointment_Body() { + return this.getCmsContent("InShop_Appointment_Widget", "BodyText"); + }, + Drop_Off_Appointment_Subject() { + return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText"); + }, + Drop_Off_Appointment_Body() { + return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText"); + }, + Overnight_Drop_Off_Appointment_Subject() { + return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText"); + }, + Overnight_Drop_Off_Appointment_Body() { + return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText"); + }, + All_Day_Drop_Off_Appointment_Subject() { + return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "HeaderText"); + }, + All_Day_Drop_Off_Appointment_Body() { + return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "BodyText"); + }, + Same_Day_Drop_Off_Appointment_Subject() { + return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "HeaderText"); + }, + Same_Day_Drop_Off_Appointment_Body() { + return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "BodyText"); + }, + UniqueId() { + return store.getters.order.referralNumber?.toString(); + }, + ServiceType() { + const isRepair = store.getters.order.damage.isRepair; + const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart; + if (!isRepair) { + if (funnelHasRecalibrationPart) { + return serviceType.REPLACEMENT_AND_RECALIBRATION; + } else { + return serviceType.REPLACEMENT; + } + } + return serviceType.REPAIR; + }, + RouteCode() { + return store.getters.order.schedule.routeCode; + }, + AppointmentData() { + var subject = ""; + var location = ""; + var startDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleStartTime); + var endDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleEndTime); + var body = ""; + var isHTML = false; + var duration = ""; + + if (this.AppointmentType === AppointmentTypeStrings.MOBILE) { + location = this.ServiceLocationFullAddress?.replace("
", ""); + subject = this.Mobile_Appointment_Subject?.replace( + "{custom:SERVICETYPE}", + this.ServiceType + ); + body = this.Mobile_Appointment_Body; + } else { + location = this.ProviderFullAddress?.replace("
", ""); + if (this.AppointmentType === AppointmentTypeStrings.DROP_OFF) { + if (this.RouteCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) { + subject = this.Overnight_Drop_Off_Appointment_Subject; + body = this.Overnight_Drop_Off_Appointment_Body; + } else if (this.RouteCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) { + if (this.IsSameDayDropOff) { + subject = this.Same_Day_Drop_Off_Appointment_Subject; + endDateTime = addMinutes(startDateTime, 120); + body = this.Same_Day_Drop_Off_Appointment_Body; + } else { + endDateTime = addMinutes(startDateTime, 120); + subject = this.All_Day_Drop_Off_Appointment_Subject?.replace( + "{custom:STARTDATETIME}", + shortTimeString(startDateTime) + ).replace("{custom:ENDDATETIME}", shortTimeString(endDateTime)); + body = this.All_Day_Drop_Off_Appointment_Body?.replace( + "{custom:ENDDATETIME}", + shortTimeString(endDateTime) + ); + } + } //normal time slot + else { + subject = this.Drop_Off_Appointment_Subject?.replace( + "{custom:SERVICETYPE}", + this.ServiceType + ); + body = this.Drop_Off_Appointment_Body?.replace( + "{custom:ADDRESS}", + location + ); + } + } else { + subject = this.InShop_Appointment_Subject?.replace( + "{custom:SERVICETYPE}", + this.ServiceType + ); + body = this.InShop_Appointment_Body?.replace("{custom:ADDRESS}", location); + } + duration = calculateDuration(startDateTime, endDateTime); + } + return { + Subject: subject, + Location: location, + StartDate: startDateTime, + EndDate: endDateTime, + RefrrlSeqNum: this.UniqueId, + Body: body, + IsHTML: isHTML, + Duration: duration, + }; + }, }, data() { return { From fa1472ad7e5c45d5dccb2d9707ba78a8d51fdf9d Mon Sep 17 00:00:00 2001 From: CarlNation <32103961+CarlNation@users.noreply.github.com> Date: Thu, 19 Oct 2023 08:54:18 -0400 Subject: [PATCH 02/14] CSR-1390 add second hop style sheet --- public/css/hop-styling.css | 336 ++++++++++++++++++++++++++++++++ src/layouts/payment/payment.vue | 8 +- 2 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 public/css/hop-styling.css diff --git a/public/css/hop-styling.css b/public/css/hop-styling.css new file mode 100644 index 000000000..c307731f6 --- /dev/null +++ b/public/css/hop-styling.css @@ -0,0 +1,336 @@ +.btn-group-lg > .btn { + padding: 10px 20px; + font-size: 20px; + line-height: 1.3; + border-radius: 5px; +} +.btn-group-sm > .btn { + padding: 3px 6px; + font-size: 13px; + line-height: 1.5; + border-radius: 3px; +} +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 13px; + line-height: 1.5; + border-radius: 3px; +} +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +[data-icon]:before, +[data-icon-after]:after, +.ico:before { + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-transform: none !important; + font-weight: normal !important; + font-style: normal !important; + font-variant: normal !important; + font-size: 20px !important; + font-family: "safelite-ico" !important; + line-height: 20px !important; +} +html { + position: static !important; + height: auto !important; +} +html, +body { + background-color: #ffffff !important; +} +body { + margin-bottom: 16px !important; +} +.headerlinecontainer { + color: #000000; + font-family: Roboto, Arial, "Helvetica Neue", Helvetica, Tahoma, Verdana, sans-serif; +} +.headerline1 { + display: block; + margin-bottom: 11.5px; + font-weight: 300; + font-size: 20px; + line-height: 30px; +} +.headerline2, +.headerline3, +.headerline4, +.headerline5 { + margin-bottom: 11.5px; + font-size: 16px; +} +.headerline3 { + color: #0c7e47; +} +.headerline5 { + display: block; + padding: 11.5px 0; + color: #167cac; + font-style: italic; +} +.headerline5v2 { + display: block; + padding: 11.5px 0; + color: #da291c; + font-style: italic; + font-size: 12px; +} +.form-group { + margin-bottom: 10px; +} +.form-group .control-label { + display: block; + margin-bottom: 2px; +} +.form-group .form-control { + margin-bottom: 2px; +} +@media (min-width: 500px) { + .form-group { + width: 80%; + } +} +@media (min-width: 800px) { + .form-group { + width: 60%; + } +} +@media (min-width: 576px) { + #cardExpirationContainer .card_expirationMonth, + #cardExpirationContainer .card_expirationYear { + position: relative; + width: 49%; + } + #cardExpirationContainer .card_expirationMonth { + float: left; + } + #cardExpirationContainer .card_expirationYear { + float: right; + } +} +.totalContainer { + margin: 16px 0; + padding: 8px; + border-radius: 5px; + background-color: #0c7e47; + color: #ffffff; + font-size: 16px; +} +.totalContainer em { + font-weight: 500; +} +.totalContainer .strikeThrough { + padding-left: 8px; + text-decoration: line-through; + font-size: 14px; +} +.callerDisplayTextContainer { + margin: 16px 0; + font-style: italic; +} +.disclaimerContainer { + margin: 16px 0; + padding: 8px; + border-radius: 5px; + background-color: #f0f1f2; +} +.disclaimerContainerv2 { + margin: 16px 0; + border-radius: 5px; +} +.buttonContainer #sghopcancelbutton { + float: left; +} +.buttonContainer #sghopsubmitbutton { + float: right; +} +.buttonContainer #sghopsubmitbutton.creditCardSpecific { + float: right; +} +@media (max-width: 500px) { + .buttonContainer #sghopsubmitbutton.creditCardSpecific { + float: left; + width: 100%; + } +} +.buttonContainer #selectPaymentTypeButton { + float: right; +} +@media (max-width: 500px) { + .buttonContainer #selectPaymentTypeButton { + float: left; + width: 100%; + } +} +.globalMessage .message { + padding-left: 0; + line-height: 1.25; +} +.globalMessage .message strong { + color: #da291c; +} +.italicSmall { + font-weight: 300; + font-style: normal; + font-size: 15px; +} +#pageLoadingModal { + background-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="); +} +#pageLoadingModal .modal-content { + margin-top: 100px; +} +#paypalParentDiv { + margin-bottom: 20px; +} +#creditCardParentDiv { + margin-bottom: 0; +} +.radio .list-group.paymentSelection, +.radio.list-group.paymentSelection { + margin-top: 0; + margin-bottom: 0; +} +@media (max-width: 33.9em) { + .radio .list-group.paymentSelection label, + .radio.list-group.paymentSelection label, + .radio .list-group.paymentSelection a, + .radio.list-group.paymentSelection a { + max-height: 52px; + } +} +#creditCardParentLink { + margin-bottom: 0; +} +@media (max-width: 33.9em) { + #creditCardParentLink { + min-height: 57px; + } +} +#creditCardImages, +#paypalImageSpan { + padding-right: 0; +} +@media (max-width: 33.9em) { + .paymentOptionText { + padding-left: 5px; + } +} +.extraPaddingTop { + padding-top: 20px; +} +.extraPaddingBottom { + padding-bottom: 20px; +} +@media (min-width: 33.9em) { + #paypalImage { + max-width: 22%; + } +} +@media (max-width: 33.9em) { + #paypalImage { + max-width: 55px; + } +} +label.centerme { + position: inherit; + display: table-cell; + width: 9999px !important; + /*This is kind of a hack*/ + vertical-align: middle; +} +input[name="rdioCreditCard"] { + display: block; +} +@media (min-width: 33.9em) { + input[name="rdioCreditCard"] { + margin-top: 10px; + } +} +@media (min-width: 33.9em) { + span.paymentOptionText { + margin-top: 6px; + } +} +.headerline1.safelitehop { + margin-top: 20px; +} +@media (max-width: 499px) { + #buttonContainer { + width: 100%; + } +} +.has-success .control-label { + color: #4d4e53; +} +#thm_fp { + display: block; +} +#paypalParentLink label, +#creditCardParentLink label { + padding-top: 9px; + padding-bottom: 9px; +} +#paypalParentLink label .paymentOptionText, +#creditCardParentLink label .paymentOptionText { + padding-left: 20px; + text-align: left; +} +#paypalParentLink { + margin-top: 12px; +} +html #creditCardParentLink.list-group-item { + border-radius: 48px; + text-align: center; +} +.optional-label span { + display: none; +} +.optional-label::after { + content: " (optional)"; + font-weight: 300; + font-style: normal; + font-size: 15px; +} +.creditCardSpecific { + display: none; +} +@media (max-width: 500px) { + .buy-backdrop.afterpay-checkout-wrapper { + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + } +} \ No newline at end of file diff --git a/src/layouts/payment/payment.vue b/src/layouts/payment/payment.vue index 81c298d11..d6a6394fe 100644 --- a/src/layouts/payment/payment.vue +++ b/src/layouts/payment/payment.vue @@ -56,7 +56,7 @@ - + @@ -229,7 +229,11 @@ export default { computed: { dynamicCSSUrl() { const { protocol, hostname, port } = window.location; - return `${protocol}//${hostname}:${port}/css/site-2020Styling.css`; + return `${protocol}//${hostname}:${port}/fmg/css/site-2020Styling.css`; + }, + dynamicHopCSSUrl() { + const { protocol, hostname, port } = window.location; + return `${protocol}//${hostname}:${port}/fmg/css/hop-styling.css`; }, }, methods: { From f8819c36903fbb844ddd6b41853b7cd807c8adde Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 19 Oct 2023 11:27:17 -0400 Subject: [PATCH 03/14] CSR-1384: possible temporary fix for lineItems while cart.vue is in development --- src/layouts/payment-method/payment-method.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index a29862882..9bdd66fca 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -27,7 +27,7 @@ @@ -183,7 +183,8 @@ export default { vm.setCmsContent(resultMap.cmsContent); vm.availableLineItems = pricedAvailableLineItems; - vm.lineItems = taxedLineItems; + vm.taxedLineItems = taxedLineItems; + vm.lineItems = lineItems; }); }, data() { @@ -191,6 +192,7 @@ export default { cartItems: [], // TOBEREMOVED BY AJC IN CSR-1384 lineItems: [], + taxedLineItems: [], // temporary, for use by cart.vue availableLineItems: [], paymentMethodInternalModel: this.getPaymentMethodFromStore(), displayPiaAlert: this.getPiaAlert(), From 3d0bdb734c61262731ad1b8826a299775cc4f1e8 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 19 Oct 2023 15:00:26 -0400 Subject: [PATCH 04/14] CSR-1712 add copy to vehicle page. --- src/layouts/vehicle/vehicle.vue | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index e064250bd..fe0f86dc5 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -9,6 +9,10 @@
+

From 86a8acd194d56d29d6bd53506522a6b6cd554977 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 19 Oct 2023 16:40:48 -0400 Subject: [PATCH 05/14] CSR-1384: fixes to keep dev working --- .../add-vaps-modal-buttons/add-vaps-modal-buttons.vue | 4 ++-- src/layouts/payment-method/payment-method.vue | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/fmg-components/add-vaps-modal-buttons/add-vaps-modal-buttons.vue b/src/fmg-components/add-vaps-modal-buttons/add-vaps-modal-buttons.vue index 4240e3514..05ea8504b 100644 --- a/src/fmg-components/add-vaps-modal-buttons/add-vaps-modal-buttons.vue +++ b/src/fmg-components/add-vaps-modal-buttons/add-vaps-modal-buttons.vue @@ -44,13 +44,13 @@ export default { showAddRainDefense() { // if not found in the cart return !this.cartItems.some((vap) => { - return vap.partType === "RAIN DEFENSE"; + return vap?.partType === "RAIN DEFENSE"; }); }, showAddWipers() { // if not found in the cart return !this.cartItems.some((vap) => { - return vap.partType.includes(" WIPER"); + return vap?.partType?.includes(" WIPER"); }); }, rainDefensePrice() { diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 9bdd66fca..45565d536 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -159,7 +159,10 @@ export default { const lineItems = store.getters.order.lineItems; - const combinedLineItems = [...glassParts, ...lineItems.supportingItems, ...lineItems.vaps]; + const combinedLineItems = []; + combinedLineItems.push(lineItems.glassParts ?? []); + combinedLineItems.push(lineItems.supportingItems ?? []); + combinedLineItems.push(lineItems.vaps ?? []); const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA, @@ -175,11 +178,9 @@ export default { false ); - const cartItems = [...glassParts, ...lineItems.supportingItems, ...lineItems.vaps]; // TOBEREMOVED BY AJC IN CSR-1384 - // Call the "next" function to complete the transition to this page. next((vm) => { - vm.cartItems = cartItems; // TOBEREMOVED BY AJC IN CSR-1384 + vm.cartItems = combinedLineItems; // TOBEREMOVED BY AJC IN CSR-1384 vm.setCmsContent(resultMap.cmsContent); vm.availableLineItems = pricedAvailableLineItems; From 61c2c039cc76350b2f61a7468a509108e61a748a Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 19 Oct 2023 17:49:10 -0400 Subject: [PATCH 06/14] Change P to div. --- src/layouts/vehicle/vehicle.vue | 4 ++-- src/ux-components/alert/alert.vue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index fe0f86dc5..1754a3a91 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -9,10 +9,10 @@
-

+ class="mt-2 mb-4 small">
- - - diff --git a/src/layouts/add-to-calendar/add-to-calendar.spec.js b/src/layouts/confirmation/add-to-calendar/add-to-calendar.spec.js similarity index 94% rename from src/layouts/add-to-calendar/add-to-calendar.spec.js rename to src/layouts/confirmation/add-to-calendar/add-to-calendar.spec.js index 14b6d978b..c55b170cd 100644 --- a/src/layouts/add-to-calendar/add-to-calendar.spec.js +++ b/src/layouts/confirmation/add-to-calendar/add-to-calendar.spec.js @@ -1,5 +1,5 @@ // Components -import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar.vue"; +import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar.vue"; import { calendarOptions } from "@/constants/calendar-options"; import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants"; @@ -176,11 +176,20 @@ describe("Add-to-calendar methods...", () => { }); }); +var appointmentText = "Appointment content"; function setupMocks({ customMountOptions }) { const mountOptions = getMountOptions({ ...customMountOptions, }); - + mountOptions.mixins = [ + { + methods: { + getCmsContent: jest.fn().mockImplementation(() => { + return appointmentText; + }), + }, + }, + ]; const wrapper = shallowMount(addToCalendar, mountOptions); wrapper.vm.$refs.calendarModalQuestion.openModal = jest.fn(); return { wrapper }; diff --git a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue new file mode 100644 index 000000000..48e67b72b --- /dev/null +++ b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue @@ -0,0 +1,313 @@ + + + diff --git a/src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-list-button/calendar-modal-list-button.vue b/src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-list-button/calendar-modal-list-button.vue similarity index 100% rename from src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-list-button/calendar-modal-list-button.vue rename to src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-list-button/calendar-modal-list-button.vue diff --git a/src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.spec.js b/src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.spec.js similarity index 92% rename from src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.spec.js rename to src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.spec.js index d28c2442f..2f0a51a33 100644 --- a/src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.spec.js +++ b/src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.spec.js @@ -1,6 +1,6 @@ import { shallowMount } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; -import calendarModalQuestion from "@/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.vue"; +import calendarModalQuestion from "@/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.vue"; describe("calendar-modal-question.vue", () => { test("When selected calendar option is changed, a correctly selectedCalendarOption should be emitted", async () => { diff --git a/src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.vue b/src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.vue similarity index 100% rename from src/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.vue rename to src/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.vue diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 1fbcbe4fc..87d4d41ea 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -20,7 +20,19 @@

{{ ScheduleDateFormatted }}

{{ ScheduleTimeFormatted }}

- +
@@ -43,22 +55,17 @@ 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"; -import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar"; +import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar"; //Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; -import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants"; +import { AppointmentTypeStrings } from "@/constants/schedule-constants"; import { settleAllPromises } from "@/helpers/layout-helper"; import { applicationConfig } from "@/constants/application-config.js"; import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper"; -import { - calculateDuration, - combineDateAndTime, - shortTimeString, - addMinutes, -} from "@/helpers/date-helper"; + import { Form } from "vee-validate"; import store from "@/store"; -import { serviceType } from "@/constants/service-type"; + import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper"; export default { name: "confirmation", @@ -190,138 +197,6 @@ export default { return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`; } }, - IsSameDayDropOff() { - const todaysDate = new Date().toISOString().split("T")[0]; - return this.ScheduleDate === todaysDate; - }, - Mobile_Appointment_Subject() { - return this.getCmsContent("Mobile_Appointment_Widget", "HeaderText"); - }, - Mobile_Appointment_Body() { - return this.getCmsContent("Mobile_Appointment_Widget", "BodyText"); - }, - InShop_Appointment_Subject() { - return this.getCmsContent("InShop_Appointment_Widget", "HeaderText"); - }, - InShop_Appointment_Body() { - return this.getCmsContent("InShop_Appointment_Widget", "BodyText"); - }, - Drop_Off_Appointment_Subject() { - return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText"); - }, - Drop_Off_Appointment_Body() { - return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText"); - }, - Overnight_Drop_Off_Appointment_Subject() { - return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText"); - }, - Overnight_Drop_Off_Appointment_Body() { - return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText"); - }, - All_Day_Drop_Off_Appointment_Subject() { - return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "HeaderText"); - }, - All_Day_Drop_Off_Appointment_Body() { - return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "BodyText"); - }, - Same_Day_Drop_Off_Appointment_Subject() { - return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "HeaderText"); - }, - Same_Day_Drop_Off_Appointment_Body() { - return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "BodyText"); - }, - UniqueId() { - return store.getters.order.referralNumber?.toString(); - }, - ServiceType() { - const isRepair = store.getters.order.damage.isRepair; - const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart; - if (!isRepair) { - if (funnelHasRecalibrationPart) { - return serviceType.REPLACEMENT_AND_RECALIBRATION; - } else { - return serviceType.REPLACEMENT; - } - } - return serviceType.REPAIR; - }, - RouteCode() { - return store.getters.order.schedule.routeCode; - }, - AppointmentData() { - var subject = ""; - var location = ""; - var startDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleStartTime); - var endDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleEndTime); - var body = ""; - var isHTML = false; - var duration = ""; - - if (this.AppointmentType === AppointmentTypeStrings.MOBILE) { - location = this.ServiceLocationFullAddress?.replace("
", ""); - subject = this.Mobile_Appointment_Subject?.replace( - "{custom:SERVICETYPE}", - this.ServiceType - ); - body = this.Mobile_Appointment_Body; - } else { - location = this.ProviderFullAddress?.replace("
", ""); - if (this.AppointmentType === AppointmentTypeStrings.DROP_OFF) { - if (this.RouteCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) { - subject = this.Overnight_Drop_Off_Appointment_Subject; - body = this.Overnight_Drop_Off_Appointment_Body; - } else if (this.RouteCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) { - if (this.IsSameDayDropOff) { - subject = this.Same_Day_Drop_Off_Appointment_Subject; - endDateTime = addMinutes(startDateTime, 120); - body = this.Same_Day_Drop_Off_Appointment_Body; - } else { - endDateTime = addMinutes(startDateTime, 120); - subject = this.All_Day_Drop_Off_Appointment_Subject?.replace( - "{custom:STARTDATETIME}", - shortTimeString(startDateTime) - ).replace("{custom:ENDDATETIME}", shortTimeString(endDateTime)); - body = this.All_Day_Drop_Off_Appointment_Body?.replace( - "{custom:ENDDATETIME}", - shortTimeString(endDateTime) - ); - } - } //normal time slot - else { - subject = this.Drop_Off_Appointment_Subject?.replace( - "{custom:SERVICETYPE}", - this.ServiceType - ); - body = this.Drop_Off_Appointment_Body?.replace( - "{custom:ADDRESS}", - location - ); - } - } else { - subject = this.InShop_Appointment_Subject?.replace( - "{custom:SERVICETYPE}", - this.ServiceType - ); - body = this.InShop_Appointment_Body?.replace("{custom:ADDRESS}", location); - } - duration = calculateDuration(startDateTime, endDateTime); - } - return { - Subject: subject, - Location: location, - StartDate: startDateTime, - EndDate: endDateTime, - RefrrlSeqNum: this.UniqueId, - Body: body, - IsHTML: isHTML, - Duration: duration, - }; - }, - }, - data() { - return { - workOrderNumber: store.getters.order.workOrderNumber, - }; }, methods: { arePagePrerequisitesValid() { From 2404c5f9f2d0448855d080fbdc139622075afab2 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Fri, 20 Oct 2023 19:10:19 +0530 Subject: [PATCH 08/14] move external links to Vue config move external links to Vue config --- src/constants/application-config.js | 3 +++ .../confirmation/add-to-calendar/add-to-calendar.vue | 11 ++++++----- vue.config.js | 3 +++ vue.release.config.js | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index b4c0d9a1e..438cc9885 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -21,6 +21,9 @@ const applicationConfig = { "//" + location.host + "/fmg/?fmgPage=payment-method&src=concept-funnel", + GOOGLE_CALENDAR: process.env.VUE_APP_GOOGLE_CALENDAR, + YAHOO_CALENDAR: process.env.VUE_APP_YAHOO_CALENDAR, + OUTLOOK_CALENDAR: process.env.VUE_APP_OUTLOOK_CALENDAR, }; export { applicationConfig }; diff --git a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue index 48e67b72b..24427b2d5 100644 --- a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue +++ b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue @@ -33,6 +33,7 @@ import { } from "@/helpers/date-helper"; import store from "@/store"; import { serviceType } from "@/constants/service-type"; +import { applicationConfig } from "@/constants/application-config.js"; export default { name: "add-to-calendar", components: { @@ -207,8 +208,8 @@ export default { methods: { setCalendarAppointment(calendarOption) { if ( - calendarOption.name.includes(calendarOptions.ICAL) || - calendarOption.name.includes(calendarOptions.OUTLOOK) + calendarOption.name == calendarOptions.ICAL || + calendarOption.name == calendarOptions.OUTLOOK ) { this.getAppointment(); } else { @@ -227,7 +228,7 @@ export default { const dateFormat = "yyyyMMddTHHmmss"; const outlookComTimeSpanFormat = "yyyy-MM-ddTHH:mm:ss"; if (type == calendarOptions.OUTLOOKCOM) { - URL = `https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent&startdt=${encodeURIComponent( + URL = `${applicationConfig.OUTLOOK_CALENDAR}&startdt=${encodeURIComponent( getDateFormat(this.Appointment.StartDate, outlookComTimeSpanFormat) )}&enddt=${encodeURIComponent( getDateFormat(this.Appointment.EndDate, outlookComTimeSpanFormat) @@ -238,7 +239,7 @@ export default { )}`; } if (type == calendarOptions.GOOGLE) { - URL = `https://www.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent( + URL = `${applicationConfig.GOOGLE_CALENDAR}&text=${encodeURIComponent( this.Appointment.Subject )}&dates=${encodeURIComponent( getDateFormat(this.Appointment.StartDate, dateFormat) @@ -249,7 +250,7 @@ export default { )}&location=${encodeURIComponent(this.Appointment.Location)}&sf=true&output=xml`; } if (type == calendarOptions.YAHOO) { - URL = `https://calendar.yahoo.com/?v=60&TITLE=${encodeURIComponent( + URL = `${applicationConfig.YAHOO_CALENDAR}&TITLE=${encodeURIComponent( this.Appointment.Subject )}&DESC=${encodeURIComponent(this.Appointment.Body)}&ST=${encodeURIComponent( getDateFormat(this.Appointment.StartDate, dateFormat) diff --git a/vue.config.js b/vue.config.js index a8c6ee8f8..f105d8e30 100644 --- a/vue.config.js +++ b/vue.config.js @@ -6,6 +6,9 @@ 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"; +process.env.VUE_APP_GOOGLE_CALENDAR = "https://www.google.com/calendar/render?action=TEMPLATE"; +process.env.VUE_APP_YAHOO_CALENDAR = "https://calendar.yahoo.com/?v=60"; +process.env.VUE_APP_OUTLOOK_CALENDAR = "https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent"; // GA & GTM process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = diff --git a/vue.release.config.js b/vue.release.config.js index ec84c2d2a..d3a16cc35 100644 --- a/vue.release.config.js +++ b/vue.release.config.js @@ -5,6 +5,9 @@ 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_GOOGLE_CALENDAR = "__VUE_APP_GOOGLE_CALENDAR__"; +process.env.VUE_APP_YAHOO_CALENDAR = "__VUE_APP_YAHOO_CALENDAR__"; +process.env.VUE_APP_OUTLOOK_CALENDAR = "__VUE_APP_OUTLOOK_CALENDAR__"; // GA & GTM process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__"; From 820a4387ac800623de33dbb501a29b43c1986e74 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 20 Oct 2023 09:56:38 -0400 Subject: [PATCH 09/14] CSR-1384: adding modals with add to cart buttons --- .../content-group-modal.vue | 15 +- .../add-vaps-button/add-vaps-button.vue | 0 .../add-vaps-modal-buttons.vue | 177 ++++++++++++++++++ src/layouts/payment-method/payment-method.vue | 22 +-- 4 files changed, 194 insertions(+), 20 deletions(-) rename src/{fmg-components => layouts/payment-method}/add-vaps-modal-buttons/add-vaps-button/add-vaps-button.vue (100%) create mode 100644 src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue diff --git a/src/fmg-components/content-group-modal/content-group-modal.vue b/src/fmg-components/content-group-modal/content-group-modal.vue index d9d9da937..a64d10fa3 100644 --- a/src/fmg-components/content-group-modal/content-group-modal.vue +++ b/src/fmg-components/content-group-modal/content-group-modal.vue @@ -12,6 +12,7 @@ class="my-4 caption modal-sub-body" v-if="ModalSubBodyText" v-html="ModalSubBodyText">

+ @@ -22,6 +23,10 @@ export default { name: "content-group-modal", props: { cmsWidgetName: String, + footerButtonActionName: { + type: String, + default: null, + }, }, computed: { ModalName() { @@ -50,10 +55,16 @@ export default { openModal() { this.$refs[this.ModalName].openModal(); }, - - footerButtonClick() { + closeModal() { this.$refs[this.ModalName].closeModal(); }, + footerButtonClick() { + if (this.footerButtonActionName) { + this.$emit(this.footerButtonActionName, this.ModalName); + } else { + this.closeModal(); + } + }, }, components: { modal, diff --git a/src/fmg-components/add-vaps-modal-buttons/add-vaps-button/add-vaps-button.vue b/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-button/add-vaps-button.vue similarity index 100% rename from src/fmg-components/add-vaps-modal-buttons/add-vaps-button/add-vaps-button.vue rename to src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-button/add-vaps-button.vue diff --git a/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue b/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue new file mode 100644 index 000000000..a01d2d39f --- /dev/null +++ b/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue @@ -0,0 +1,177 @@ + + + diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 45565d536..e0bf475ac 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -42,12 +42,10 @@
+ vapsTilesCmsName="VapsProductTiles" /> - { @@ -320,7 +308,6 @@ export default { ); } }, - async piaSetup(payNowType) { this.$refs.loadingModal.showModal(); @@ -398,7 +385,6 @@ export default { cart, alert, addVapsModalButtons, - contentGroupModal, paymentMethodQuestion, }, }; From 8c7e1953a96f5911fa91a46b37eee2cf49415566 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Fri, 20 Oct 2023 10:11:15 -0400 Subject: [PATCH 10/14] Update unit test. --- src/layouts/vehicle/vehicle.spec.js | 38 ++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/layouts/vehicle/vehicle.spec.js b/src/layouts/vehicle/vehicle.spec.js index 56b46292d..e8671b7a8 100644 --- a/src/layouts/vehicle/vehicle.spec.js +++ b/src/layouts/vehicle/vehicle.spec.js @@ -5,17 +5,25 @@ import vehicle from "@/layouts/vehicle/vehicle.vue"; import { shallowMount } from "@vue/test-utils"; import { nextTick } from "vue"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; +import baseMixin from "../../mixins/base-mixin"; // Mock our module for promises. jest.mock("@/helpers/layout-helper.js", () => ({ settleAllPromises: jest.fn(), })); +// Mock fetchCmsContentForPage +jest.mock("@/helpers/cms-content-helper", () => ({ + fetchCmsContentForPage: jest.fn(), +})); + describe("vehicle.vue", () => { test("arePagePrerequisitesValid should be true ", async () => { //Arrange const { wrapper } = setupMocks(); + //Act let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); await nextTick(); @@ -40,17 +48,25 @@ describe("vehicle.vue", () => { }); function setupMocks() { - const wrapper = shallowMount( - vehicle, - getMountOptions({ - router: { - navigate: jest.fn(), - navigate: jest.fn(), - navigateWithSaving: jest.fn(), - navigateWithoutSaving: jest.fn(), - }, - }) - ); + + const mountOptions = getMountOptions({ + router: { + navigate: jest.fn(), + navigate: jest.fn(), + navigateWithSaving: jest.fn(), + navigateWithoutSaving: jest.fn(), + }, + }); + + //Mock props + const mockMixin = { + methods: { + getCmsContent: jest.fn(), + }, + }; + + mountOptions.mixins = [mockMixin]; + const wrapper = shallowMount(vehicle, mountOptions); return { wrapper }; } From b16c36d2cf33b4ae8065c024cb7f6d78117367a3 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Fri, 20 Oct 2023 10:17:25 -0400 Subject: [PATCH 11/14] format code. --- src/layouts/vehicle/vehicle.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/layouts/vehicle/vehicle.spec.js b/src/layouts/vehicle/vehicle.spec.js index e8671b7a8..74d29071a 100644 --- a/src/layouts/vehicle/vehicle.spec.js +++ b/src/layouts/vehicle/vehicle.spec.js @@ -23,7 +23,6 @@ describe("vehicle.vue", () => { //Arrange const { wrapper } = setupMocks(); - //Act let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); await nextTick(); @@ -48,7 +47,6 @@ describe("vehicle.vue", () => { }); function setupMocks() { - const mountOptions = getMountOptions({ router: { navigate: jest.fn(), From 047ed9855054b44f639820e1757da615b1d411f4 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Fri, 20 Oct 2023 19:51:09 +0530 Subject: [PATCH 12/14] remove calendar url from vue config remove calendar url from vue config --- src/constants/application-config.js | 7 ++++--- vue.config.js | 3 --- vue.release.config.js | 3 --- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 438cc9885..7105e63bd 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -21,9 +21,10 @@ const applicationConfig = { "//" + location.host + "/fmg/?fmgPage=payment-method&src=concept-funnel", - GOOGLE_CALENDAR: process.env.VUE_APP_GOOGLE_CALENDAR, - YAHOO_CALENDAR: process.env.VUE_APP_YAHOO_CALENDAR, - OUTLOOK_CALENDAR: process.env.VUE_APP_OUTLOOK_CALENDAR, + GOOGLE_CALENDAR: "https://www.google.com/calendar/render?action=TEMPLATE", + YAHOO_CALENDAR: "https://calendar.yahoo.com/?v=60", + OUTLOOK_CALENDAR: + "https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent", }; export { applicationConfig }; diff --git a/vue.config.js b/vue.config.js index f105d8e30..a8c6ee8f8 100644 --- a/vue.config.js +++ b/vue.config.js @@ -6,9 +6,6 @@ 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"; -process.env.VUE_APP_GOOGLE_CALENDAR = "https://www.google.com/calendar/render?action=TEMPLATE"; -process.env.VUE_APP_YAHOO_CALENDAR = "https://calendar.yahoo.com/?v=60"; -process.env.VUE_APP_OUTLOOK_CALENDAR = "https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent"; // GA & GTM process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = diff --git a/vue.release.config.js b/vue.release.config.js index d3a16cc35..ec84c2d2a 100644 --- a/vue.release.config.js +++ b/vue.release.config.js @@ -5,9 +5,6 @@ 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_GOOGLE_CALENDAR = "__VUE_APP_GOOGLE_CALENDAR__"; -process.env.VUE_APP_YAHOO_CALENDAR = "__VUE_APP_YAHOO_CALENDAR__"; -process.env.VUE_APP_OUTLOOK_CALENDAR = "__VUE_APP_OUTLOOK_CALENDAR__"; // GA & GTM process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__"; From 2be4b378c136af2874297d20a162260e49df9f08 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 20 Oct 2023 10:38:13 -0400 Subject: [PATCH 13/14] CSR-1384: remove outdated code --- .../add-vaps-modal-buttons.vue | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue b/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue index a01d2d39f..3fc426d63 100644 --- a/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue +++ b/src/layouts/payment-method/add-vaps-modal-buttons/add-vaps-modal-buttons.vue @@ -73,21 +73,8 @@ export default { }, }, computed: { - currentCartItems: { - get: function () { - return this.modelValue; - }, - set: function (newValue) { - // does this.modelValue.vaps have this vap in it already? - const inCart = this.currentCartItems.vaps?.some((vap) => { - return vap.partType === "RAIN DEFENSE"; - }); - const newCartItems = this.currentCartItems; - if (!inCart) { - newCartItems.vaps.push(newValue); - } - this.$emit("update:modelValue", newCartItems); - }, + currentCartItems() { + return this.modelValue; }, showAddRainDefense() { // show if not in cart From 7c60a4c0698fbc9d2ea7021682dff2d4e20d8506 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Fri, 20 Oct 2023 11:20:03 -0400 Subject: [PATCH 14/14] Fixed the NaN issue that was introduced with Tax stuff --- src/store/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 852bb1570..9a2e8054d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2516,8 +2516,7 @@ function convertGlassPieceNamingFromApi(glassArray) { } function addPricesToLineItems(lineItems, pricingLineItems) { - const pricedLineItems = deepClone(lineItems); - pricedLineItems.forEach((lineItem) => { + lineItems.forEach((lineItem) => { let lineItemIndex = pricingLineItems.findIndex( (pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber ); @@ -2533,7 +2532,7 @@ function addPricesToLineItems(lineItems, pricingLineItems) { lineItem.salesTax = pricedLineItem.salesTax; }); - return pricedLineItems; + return lineItems; } function addTaxesToPricedLineItems(lineItems, taxingLineItems) {