diff --git a/src/helpers/date-helper.js b/src/helpers/date-helper.js
index 1b062c85..be8161e8 100644
--- a/src/helpers/date-helper.js
+++ b/src/helpers/date-helper.js
@@ -72,3 +72,35 @@ export function sumDateString(dateString, daysToAdd) {
date.setDate(date.getDate() + daysToAdd);
return convertDateToDateString(date);
}
+
+export function get12HourTimeMobileFormat(time) {
+ // Check correct time format and split into components
+ let timeString = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time];
+
+ if (timeString.length > 1) {
+ // If time format correct
+ const min = timeString[3];
+ timeString = timeString.slice(1); // Remove full string match value
+ if (Number(min) === 0) {
+ timeString = timeString.slice(0, 1); // Remove minute value
+ timeString[1] = +timeString[0] < 12 ? ' AM' : ' PM'; // Set AM/PM
+ } else {
+ timeString[5] = +timeString[0] < 12 ? ' AM' : ' PM'; // Set AM/PM
+ }
+ timeString[0] = +timeString[0] % 12 || 12; // Adjust hours
+ }
+ return timeString.join(''); // return adjusted time or original string
+}
+
+export function get12HourTimeFormat(time) {
+ // Check correct time format and split into components
+ let timeString = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time];
+
+ if (timeString.length > 1) {
+ // If time format correct
+ timeString = timeString.slice(1); // Remove full string match value
+ timeString[5] = +timeString[0] < 12 ? ' AM' : ' PM'; // Set AM/PM
+ timeString[0] = +timeString[0] % 12 || 12; // Adjust hours
+ }
+ return timeString.join(''); // return adjusted time or original string
+}
diff --git a/src/layouts/order-confirmation/order-confirmation.spec.js b/src/layouts/order-confirmation/order-confirmation.spec.js
index fe981266..b71dbcb4 100644
--- a/src/layouts/order-confirmation/order-confirmation.spec.js
+++ b/src/layouts/order-confirmation/order-confirmation.spec.js
@@ -14,10 +14,11 @@ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
jest.mock('@/helpers/cms-content-helper', () => ({
fetchCmsContentForPage: jest.fn()
}));
+const wordingText = 'wording Text {custom:address}';
const mockMixin = {
methods: {
- getCmsContent: jest.fn().mockImplementation(() => ''),
+ getCmsContent: jest.fn().mockImplementation(() => wordingText),
setCmsContent: jest.fn()
}
};
@@ -33,6 +34,32 @@ const headerStub = {
render: () => {}
};
+const initialStore = {
+ order: {
+ schedule: {
+ date: '2024-03-01',
+ startTime: '09:00',
+ endTime: '10:00'
+ },
+ serviceLocation: {
+ address: '123 Test Way',
+ address2: '#1',
+ city: 'Mesa',
+ state: 'AZ',
+ zipCode: '12345',
+ appointmentType: 'Inshop',
+ provider: {
+ address: {
+ streetAddress: '123 Safelite Street',
+ city: 'Mesa',
+ state: 'AZ',
+ zipCode: '12345'
+ }
+ }
+ }
+ }
+};
+
function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRun = () => {}) {
const mountOptions = getMountOptions({
router: {
@@ -75,7 +102,7 @@ describe('OrderConfirmation.vue', () => {
describe('Rendering', () => {
test('Should render Site Header', () => {
// Arrange
- const { wrapper } = getMountedComponent({});
+ const { wrapper } = getMountedComponent(initialStore);
// Act
const siteHeader = wrapper.findComponent(headerStub);
@@ -85,13 +112,21 @@ describe('OrderConfirmation.vue', () => {
});
test('If Advanced flow, should display Site Footer', () => {
// Arrange
- const carrierReturnUrl = 'testURL';
- const initialStore = {
+ const testStore = {
+ order: {
+ schedule: {
+ date: '2019-01-01',
+ startTime: '09:00'
+ },
+ serviceLocation: {
+ appointmentType: 'Inshop'
+ }
+ },
issConfig: {
- successReturnURL: carrierReturnUrl
+ successReturnURL: 'testURL'
}
};
- const { wrapper } = getMountedComponent(initialStore);
+ const { wrapper } = getMountedComponent(testStore);
// Act
const siteFooter = wrapper.findComponent({ ref: 'siteFooter' });
@@ -101,7 +136,7 @@ describe('OrderConfirmation.vue', () => {
});
test('If Essential flow, should not display Site Footer', () => {
// Arrange
- const { wrapper } = getMountedComponent();
+ const { wrapper } = getMountedComponent(initialStore);
// Act
const siteFooter = wrapper.findComponent({ ref: 'siteFooter' });
@@ -114,12 +149,21 @@ describe('OrderConfirmation.vue', () => {
test('If Advanced flow, forward button action navigates to carrier URL', () => {
// Arrange
const carrierReturnUrl = 'testURL';
- const initialStore = {
+ const testStore = {
+ order: {
+ schedule: {
+ date: '2019-01-01',
+ startTime: '09:00'
+ },
+ serviceLocation: {
+ appointmentType: 'Inshop'
+ }
+ },
issConfig: {
successReturnURL: carrierReturnUrl
}
};
- const { wrapper } = getMountedComponent(initialStore);
+ const { wrapper } = getMountedComponent(testStore);
// Act
wrapper.vm.forwardButtonAction();
@@ -128,4 +172,157 @@ describe('OrderConfirmation.vue', () => {
expect(wrapper.vm.$router.navigateToExternalUrl).toHaveBeenCalledWith(carrierReturnUrl);
});
});
+ describe('Computed properties', () => {
+ test('appointmentDateFormatted should return date in expected format', () => {
+ // Arrange
+ const { wrapper } = getMountedComponent(initialStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentDateFormatted;
+
+ // Assert
+ expect(testValue).toEqual('Friday, March 1');
+ });
+ test('appointmentTimeFormatted should return Mobile time in expected format', () => {
+ // Arrange
+ const testStore = {
+ order: {
+ schedule: {
+ date: '2019-01-01',
+ startTime: '09:00',
+ endTime: '10:00'
+ },
+ serviceLocation: {
+ appointmentType: 'Mobile'
+ }
+ }
+ };
+ const { wrapper } = getMountedComponent(testStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentTimeFormatted;
+
+ // Assert
+ expect(testValue).toEqual('Between 9 AM - 10 AM');
+ });
+ test('appointmentTimeFormatted should return Drop Off time in expected format', () => {
+ // Arrange
+ const testStore = {
+ order: {
+ schedule: {
+ date: '2019-01-01',
+ startTime: '09:00',
+ endTime: '10:00'
+ },
+ serviceLocation: {
+ appointmentType: 'Drop Off'
+ }
+ }
+ };
+ const { wrapper } = getMountedComponent(testStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentTimeFormatted;
+
+ // Assert
+ expect(testValue).toEqual('Drop off before 9:30 AM');
+ });
+ test('appointmentTimeFormatted should return In Shop time in expected format', () => {
+ // Arrange
+ const { wrapper } = getMountedComponent(initialStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentTimeFormatted;
+
+ // Assert
+ expect(testValue).toEqual('at 9:00 AM');
+ });
+ test('appointmentWordingText should return Mobile text in expected format', () => {
+ // Arrange
+ const testStore = {
+ order: {
+ schedule: {
+ date: '2019-01-01',
+ startTime: '09:00',
+ endTime: '10:00'
+ },
+ serviceLocation: {
+ address: '123 Test Way',
+ address2: '#1',
+ city: 'Mesa',
+ state: 'AZ',
+ zipCode: '12345',
+ appointmentType: 'Mobile'
+ }
+ }
+ };
+ const { wrapper } = getMountedComponent(testStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentWordingText;
+
+ // Assert
+ expect(testValue).toEqual('wording Text
123 Test Way, #1,
Mesa, AZ 12345
');
+ });
+ test('appointmentWordingText should return Drop Off text in expected format', () => {
+ // Arrange
+ const testStore = {
+ order: {
+ schedule: {
+ date: '2019-01-01',
+ startTime: '09:00',
+ endTime: '10:00'
+ },
+ serviceLocation: {
+ provider: {
+ address: {
+ streetAddress: '123 Safelite Street',
+ city: 'Mesa',
+ state: 'AZ',
+ zipCode: '12345'
+ }
+ },
+ appointmentType: 'Drop Off'
+ }
+ }
+ };
+ const { wrapper } = getMountedComponent(testStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentWordingText;
+
+ // Assert
+ expect(testValue).toEqual('wording Text 123 Safelite Street,
Mesa, AZ 12345');
+ });
+ test('appointmentWordingText should return In Shop text in expected format', () => {
+ // Arrange
+ const { wrapper } = getMountedComponent(initialStore);
+
+ // Act
+ const testValue = wrapper.vm.appointmentWordingText;
+
+ // Assert
+ expect(testValue).toEqual('wording Text 123 Safelite Street,
Mesa, AZ 12345');
+ });
+ test('serviceLocationFullAddress should return text in expected format', () => {
+ // Arrange
+ const { wrapper } = getMountedComponent(initialStore);
+
+ // Act
+ const testValue = wrapper.vm.serviceLocationFullAddress;
+
+ // Assert
+ expect(testValue).toEqual('
123 Test Way, #1,
Mesa, AZ 12345
');
+ });
+ test('providerFullAddress should return text in expected format', () => {
+ // Arrange
+ const { wrapper } = getMountedComponent(initialStore);
+
+ // Act
+ const testValue = wrapper.vm.providerFullAddress;
+
+ // Assert
+ expect(testValue).toEqual('123 Safelite Street,
Mesa, AZ 12345');
+ });
+ });
});
diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue
index 63b028eb..86670ff5 100644
--- a/src/layouts/order-confirmation/order-confirmation.vue
+++ b/src/layouts/order-confirmation/order-confirmation.vue
@@ -8,7 +8,28 @@
-
Placeholder for order confirmation page
+
+
![]()
+
+
+
+
+
+
+
+
+
{{ appointmentDateFormatted }}
+
{{ appointmentTimeFormatted }}
+
+
+
+
// Components
import siteHeader from '@/iss-components/site-header/site-header.vue';
+import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
@@ -32,11 +54,13 @@ import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
+import { get12HourTimeFormat, get12HourTimeMobileFormat, convertDateStringToDate } from '@/helpers/date-helper.js';
export default {
name: 'order-confirmation',
components: {
siteHeader,
+ vehicleBanner,
siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names
Form
@@ -67,6 +91,81 @@ export default {
},
carrierUrl() {
return this.mainStore.issConfig.successReturnURL;
+ },
+ orderConfirmationHeaderText() {
+ return this.getCmsContent('OrderConfirmationContent', 'HeaderText');
+ },
+ orderConfirmationImage() {
+ return this.getCmsContent('OrderConfirmationContent', 'Image');
+ },
+ appointmentType() {
+ return this.mainStore.order.serviceLocation.appointmentType.toUpperCase();
+ },
+ appointmentDate() {
+ return this.mainStore.order.schedule.date;
+ },
+ appointmentStartTime() {
+ return this.mainStore.order.schedule.startTime;
+ },
+ appointmentEndTime() {
+ return this.mainStore.order.schedule.endTime;
+ },
+ appointmentDateFormatted() {
+ // This conversion ensures we don't get get GMT induced date changes
+ const dateObject = convertDateStringToDate(this.appointmentDate);
+ // Ex: Tuesday, April 22
+ return dateObject.toLocaleDateString('en-us', {
+ weekday: 'long',
+ month: 'long',
+ day: 'numeric'
+ });
+ },
+ appointmentTimeFormatted() {
+ const formattedTime = this.formatAppointmentTime(this.appointmentType);
+ return formattedTime;
+ },
+ mobileWordingText() {
+ return this.getCmsContent('MobileWordingWidget', 'BodyText');
+ },
+ dropOffAndInShopWordingText() {
+ return this.getCmsContent('DropOffAndInShopWordingWidget', 'BodyText');
+ },
+ serviceLocationAddress() {
+ return this.mainStore.order.serviceLocation.address;
+ },
+ serviceLocationAddress2() {
+ return this.mainStore.order.serviceLocation.address2;
+ },
+ serviceLocationCity() {
+ return this.mainStore.order.serviceLocation.city;
+ },
+ serviceLocationState() {
+ return this.mainStore.order.serviceLocation.state;
+ },
+ serviceLocationZipCode() {
+ return this.mainStore.order.serviceLocation.zipCode;
+ },
+ serviceLocationFullAddress() {
+ // eslint-disable-next-line max-len
+ return `
${this.serviceLocationAddress}, ${this.serviceLocationAddress2 ? `${this.serviceLocationAddress2},` : ''}
${this.serviceLocationCity}, ${this.serviceLocationState} ${this.serviceLocationZipCode}
`;
+ },
+ providerAddress() {
+ return this.mainStore.order.serviceLocation.provider.address.streetAddress;
+ },
+ providerCity() {
+ return this.mainStore.order.serviceLocation.provider.address.city;
+ },
+ providerState() {
+ return this.mainStore.order.serviceLocation.provider.address.state;
+ },
+ providerZipCode() {
+ return this.mainStore.order.serviceLocation.provider.address.zipCode;
+ },
+ providerFullAddress() {
+ return `${this.providerAddress},
${this.providerCity}, ${this.providerState} ${this.providerZipCode}`;
+ },
+ appointmentWordingText() {
+ return this.formatWordingText(this.appointmentType);
}
},
mounted() {
@@ -77,6 +176,40 @@ export default {
methods: {
forwardButtonAction() {
this.$router.navigateToExternalUrl(this.carrierUrl);
+ },
+ formatAppointmentTime(appointmentType) {
+ switch (appointmentType) {
+ case 'MOBILE':
+ // eslint-disable-next-line max-len
+ return `Between ${get12HourTimeMobileFormat(this.appointmentStartTime)} - ${get12HourTimeMobileFormat(this.appointmentEndTime)}`;
+ case 'DROP OFF':
+ return 'Drop off before 9:30 AM';
+ case 'INSHOP':
+ return `at ${get12HourTimeFormat(this.appointmentStartTime)}`;
+ default:
+ return null;
+ }
+ },
+ formatWordingText(appointmentType) {
+ switch (appointmentType) {
+ case 'MOBILE':
+ return this.mobileWordingText?.replaceAll(
+ '{custom:address}',
+ this.serviceLocationFullAddress
+ );
+ case 'DROP OFF':
+ return this.dropOffAndInShopWordingText?.replaceAll(
+ '{custom:address}',
+ this.providerFullAddress
+ );
+ case 'INSHOP':
+ return this.dropOffAndInShopWordingText?.replaceAll(
+ '{custom:address}',
+ this.providerFullAddress
+ );
+ default:
+ return null;
+ }
}
}
};
@@ -91,4 +224,34 @@ $page-side-padding: 1.5rem;
padding: 0 1.5rem !important;
}
}
+
+.text-color--black {
+ color: $black;
+}
+
+.appointment-details {
+ margin-bottom: 1.5rem;
+ padding: 1rem 1.5rem 1.5rem;
+ box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
+ border-radius: 5px;
+}
+
+.appointment-date-time P {
+ color: $black;
+ font-size: $h5-font-size;
+ line-height: map-get($spacers, 6);
+ margin-bottom: 0.5rem;
+
+ + p {
+ font-size: map-get($spacers, 4);
+ line-height: 1.625rem;
+ font-weight: $font-weight-bold;
+ }
+}
+
+.appointment-text {
+ :deep(strong) {
+ font-weight: $font-weight-bold;
+ }
+}