CASH-109 return user page
CASH-109 return user page for when a session times out
This commit is contained in:
parent
66da230cc9
commit
9822cdfedf
11 changed files with 144 additions and 10 deletions
|
|
@ -37,6 +37,8 @@ const applicationConfig = {
|
|||
FRONTEND_LOGGER_PATH: "/analytics/api/v1/logging",
|
||||
AFFILIATE_COOKIE_CONTAINING_NAME: "_Track",
|
||||
COOKIE_NAME_LENGTH_MAX_LIMIT: 44,
|
||||
SESSION_TIMEOUT_MINUTES: process.env.VUE_APP_SESSION_TIMEOUT_MINUTES,
|
||||
RETURN_USER_PAGE: "/fmg/?fmgPage=return-user",
|
||||
};
|
||||
|
||||
export { applicationConfig };
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const cookieNames = {
|
|||
};
|
||||
|
||||
const cookieExpirations = {
|
||||
SESSION_ID: convertToSeconds({ minutes: 30 }),
|
||||
SESSION_ID: convertToSeconds({ minutes: applicationConfig.SESSION_TIMEOUT_MINUTES }),
|
||||
DXDEV: convertToSeconds({ years: 1 }),
|
||||
FUNNEL_USER_ID: convertToSeconds({ weeks: 1 }),
|
||||
FUNNEL_SESSION_KEY: convertToSeconds({ minutes: 30 }),
|
||||
|
|
|
|||
|
|
@ -217,11 +217,11 @@ export default {
|
|||
flex: none;
|
||||
}
|
||||
.textbox-question {
|
||||
padding: .25rem 0;
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.modal-dialog-centered {
|
||||
align-items: flex-end;
|
||||
min-height: 100%;
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ export default {
|
|||
|
||||
// hide save progress button; show success message alert
|
||||
this.isProgressSaved = true;
|
||||
|
||||
|
||||
// communicate to parent the new status
|
||||
this.$emit("save-progress-saved");
|
||||
|
||||
|
||||
this.modal.closeModal();
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export default {
|
|||
currentPage: pageNameToLog,
|
||||
endpoint: endpoint,
|
||||
};
|
||||
|
||||
|
||||
router.navigateError(errorPayload);
|
||||
|
||||
// do not log 404 errors from services because we return NotFound
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ export default {
|
|||
: this.$store.getters.order.serviceLocation?.appointmentType;
|
||||
},
|
||||
ServiceLocationFullAddressText() {
|
||||
return `${this.ServiceLocationAddress.toLowerCase()}${this.ServiceLocationAddress2 ? ", " + this.ServiceLocationAddress2 : ""}, ${this.ServiceLocationCity.toLowerCase()}, ${this.ServiceLocationState} ${this.ServiceLocationZipCode}`;
|
||||
return `${this.ServiceLocationAddress?.toLowerCase()}${this.ServiceLocationAddress2 ? ", " + this.ServiceLocationAddress2 : ""}, ${this.ServiceLocationCity?.toLowerCase()}, ${this.ServiceLocationState} ${this.ServiceLocationZipCode}`;
|
||||
},
|
||||
ServiceLocationFullAddress() {
|
||||
if (this.AppointmentType === AppointmentTypeStrings.MOBILE) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export default {
|
|||
computed: {
|
||||
displayContent() {
|
||||
return [
|
||||
`${this.addressInfo.address.toLowerCase()}${this.addressInfo.address2 ? ", " : ""}${this.addressInfo.address2.toLowerCase()}, ${this.addressInfo.city.toLowerCase()}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`,
|
||||
`${this.addressInfo?.address?.toLowerCase()}${this.addressInfo?.address2 ? ", " : ""}${this.addressInfo?.address2?.toLowerCase()}, ${this.addressInfo?.city?.toLowerCase()}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`,
|
||||
];
|
||||
},
|
||||
addressInfo() {
|
||||
|
|
|
|||
118
src/layouts/return-user/return-user.vue
Normal file
118
src/layouts/return-user/return-user.vue
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<template>
|
||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
|
||||
<div class="return-user small-question-text">
|
||||
<loadingModal ref="loadingModal" />
|
||||
<div class="container-fluid page-container-grouped-styles">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4 mt-4">
|
||||
<funnelSubHeader
|
||||
ref="funnelSubHeader"
|
||||
cmsWidgetName="FunnelSubHeaderWidget" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<navbar
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
ref="navbar"
|
||||
buttonSize
|
||||
:isBackButtonHidden="true"
|
||||
@ForwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 col-xl-4 start-over">
|
||||
<a @click="startOver" alt="Start Over Button"
|
||||
><img v-bind:src="startOverImage" />{{ startOverText }}</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components
|
||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
||||
// Supporting Files
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { Form } from "vee-validate";
|
||||
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
|
||||
export default {
|
||||
name: "return-user",
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: "cmsContent",
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
// Call the "next" function to complete the transition to this page.
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.startOverText = resultMap.cmsContent.StartOverWidget.HeaderText;
|
||||
vm.startOverImage = resultMap.cmsContent.StartOverWidget.Image;
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
startOverText: "",
|
||||
startOverImage: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
return getFunnelCookie() !== null;
|
||||
},
|
||||
|
||||
async forwardButtonAction() {
|
||||
// clicking continue and use no page name to trigger the implicit navigation in router
|
||||
window.location.href = "/fmg/";
|
||||
},
|
||||
|
||||
async startOver() {
|
||||
this.pushEventToGA(
|
||||
this.$route.query[this.queryStrings.FMG_PAGE],
|
||||
this.GaActions.CLICKED,
|
||||
"Start over",
|
||||
true
|
||||
);
|
||||
deleteFunnelCookie();
|
||||
await this.dispatchStoreAction(storeActions.RESET_STATE);
|
||||
window.location.href = "/fmg/";
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Form,
|
||||
funnelHeader,
|
||||
funnelSubHeader,
|
||||
navbar,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.start-over {
|
||||
text-align: center;
|
||||
a {
|
||||
font-weight: 600;
|
||||
color: $black;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -26,6 +26,7 @@ import store from "@/store";
|
|||
|
||||
import baseMixin from "@/mixins/base-mixin";
|
||||
import { applicationConfig } from "../constants/application-config";
|
||||
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
|
|
@ -651,7 +652,6 @@ export default {
|
|||
},
|
||||
|
||||
pushPageErrorToDataLayer(error) {
|
||||
|
||||
pushToDataLayerIfDefined({
|
||||
event: "page-error",
|
||||
error: error,
|
||||
|
|
@ -710,6 +710,17 @@ export default {
|
|||
},
|
||||
|
||||
async validateSession() {
|
||||
// The noSession function checks the cookies related to analytics logging(sid). it is not the funnel info cookie.
|
||||
// The sid cookie for analytics will expire every 30 minutes and get recreated in initSession. If this happens
|
||||
// and we also have the funnel cookie present, that indicates they have an existing session that is now expired
|
||||
// so route them to the return user page.
|
||||
const funnelCookieLastTouched = getFunnelCookie()?.LastTouched;
|
||||
if (this.noSession() && funnelCookieLastTouched !== null && funnelCookieLastTouched !== undefined) {
|
||||
await this.initSession();
|
||||
window.location.href = applicationConfig.RETURN_USER_PAGE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.noSession()) {
|
||||
await this.initSession();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ const fmgPageValues = {
|
|||
PAYMENT: "payment",
|
||||
PAYMENT_PIA_RETURN: "payment-pia-return",
|
||||
CONFIRMATION: "confirmation",
|
||||
RETURN_USER: "return-user",
|
||||
};
|
||||
|
||||
const funnelStartPageName = fmgPageValues.VEHICLE;
|
||||
const returnUserPageName = fmgPageValues.RETURN_USER;
|
||||
|
||||
export { fmgPageValues, funnelStartPageName };
|
||||
export { fmgPageValues, funnelStartPageName, returnUserPageName };
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ process.env.VUE_APP_MY_ACCOUNT = "https://myaccountdev.safelite.com/";
|
|||
//process.env.VUE_APP_SAFELITE_HOP = "http://localhost:60966/fmgCheckoutShared.aspx";
|
||||
process.env.VUE_APP_SAFELITE_HOP = "https://sv2-safelitehop-dev.safelite.com/fmgCheckoutShared.aspx";
|
||||
process.env.VUE_APP_SOLARWINDS_MONITORING = "";
|
||||
process.env.VUE_APP_SESSION_TIMEOUT_MINUTES = 30;
|
||||
|
||||
// GA & GTM
|
||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY =
|
||||
|
|
|
|||
Loading…
Reference in a new issue