DigitalConsumer.FixMyGlass/src/layouts/schedule/schedule.vue
2023-05-08 09:25:57 -04:00

316 lines
12 KiB
Vue

<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<!-- <h3>shopTimeSlots: {{ shopTimeSlots }}</h3> -->
<div class="page-container-grouped-styles">
<loadingModal ref="loadingModal" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-5" />
<div class="text-center mt-1 mb-3" v-if="ChangeShopLink.length">
<span v-for="copy in ChangeShopLink" :key="copy">
<span v-if="doesCopyContainRouterLink(copy)" class="text-body">
<router-link
:to="{
query: { fmgPage: `${getRouterLinkRouteFromCopy(copy)}` },
name: 'root',
}"
>{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link
>
</span>
<span v-else class="m-0 text-body" v-html="copy"></span>
</span>
</div>
<date-picker
selectableDatesSetting="custom"
v-model="selectedDate"
:customSelectableDatesCallback="getAvailableDates" />
<time-slot-selection-modal
ref="timeSlotModal"
v-model="selectedTimeSlot"
:dateForTimeSlotPicker="dateForTimeSlotPicker"
:availableTimeSlots="availableTimeSlots"
estimatedServiceMinutesMinimum="90"
estimatedServiceMinutesMaximum="180" />
<button @click="openModal">Click for timeslots</button>
<funnel-footer
cmsWidgetName="FunnelFooterWidget"
ref="funnelFooter"
:isForwardActionDisabled="!meta.valid"
@back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" />
</div>
</Form>
</template>
<script>
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import { Form, defineRule } from "vee-validate";
import datePicker from "@/digital-components/date-picker/date-picker";
import timeSlotSelectionModal from "./time-slot-selection-modal/time-slot-selection-modal";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import baseMixin from "@/mixins/base-mixin.js";
import { storeActions } from "@/constants/store-actions";
import { settleAllPromises } from "@/helpers/layout-helper";
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
import {
doesCopyContainRouterLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
} from "@/helpers/cms-content-helper";
import { errorMessages } from "@/constants/error-messages";
import { required } from "@/helpers/validation-rules";
import { daysOfWeek, monthsOfYear } from "@/constants/scheduling.js";
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
export default {
name: "schedule",
data() {
return {
selectedDate: null,
selectedTimeSlot: null,
dateForTimeSlotPicker: new Date("May 23 2023"),
availableTimeSlots: [
"8:00 AM",
"10:30 AM",
"11:00 AM",
"12:30 AM",
"1:00 PM",
"2:00 PM",
"4:30 PM",
"8:00 AM",
"10:30 AM",
"11:00 AM",
"12:30 AM",
"1:00 PM",
"2:00 PM",
"4:30 PM",
"8:00 AM",
"10:30 AM",
"11:00 AM",
"12:30 AM",
"1:00 PM",
"2:00 PM",
"4:30 PM",
],
mockSelectableDatesData: [
{ dateString: "2023-04-28" },
{ dateString: "2023-05-04" },
{ dateString: "2023-05-09" },
{ dateString: "2023-05-11" },
{ dateString: "2023-05-17" },
{ dateString: "2023-05-18" },
{ dateString: "2023-05-19" },
{ dateString: "2023-05-23" },
{ dateString: "2023-05-24" },
{ dateString: "2023-05-25" },
{ dateString: "2023-05-30" },
{ dateString: "2023-05-31" },
{ dateString: "2023-06-01" },
{ dateString: "2023-06-02" },
{ dateString: "2023-06-06" },
{ dateString: "2023-06-07" },
{ dateString: "2023-06-09" },
{ dateString: "2023-06-12" },
{ dateString: "2023-06-13" },
{ dateString: "2023-06-15" },
{ dateString: "2023-06-16" },
{ dateString: "2023-06-17" },
{ dateString: "2023-06-20" },
{ dateString: "2023-06-21" },
{ dateString: "2023-06-22" },
{ dateString: "2023-06-23" },
{ dateString: "2023-06-26" },
{ dateString: "2023-06-27" },
{ dateString: "2023-06-28" },
{ dateString: "2023-06-29" },
{ dateString: "2023-06-30" },
{ dateString: "2023-07-01" },
{ dateString: "2023-07-03" },
{ dateString: "2023-07-04" },
{ dateString: "2023-07-05" },
{ dateString: "2023-07-06" },
{ dateString: "2023-07-07" },
{ dateString: "2023-07-10" },
{ dateString: "2023-07-11" },
{ dateString: "2023-07-12" },
{ dateString: "2023-07-13" },
{ dateString: "2023-07-14" },
{ dateString: "2023-07-15" },
{ dateString: "2023-07-17" },
{ dateString: "2023-07-18" },
{ dateString: "2023-07-19" },
{ dateString: "2023-07-20" },
{ dateString: "2023-07-21" },
{ dateString: "2023-07-24" },
{ dateString: "2023-07-25" },
{ dateString: "2023-07-26" },
{ dateString: "2023-07-27" },
{ dateString: "2023-07-28" },
{ dateString: "2023-07-29" },
{ dateString: "2023-07-31" },
],
selectableDatesData: [],
};
/*
shopTimeSlots: {
estimatedServiceMinutesMinimum: 120,
estimatedServiceMinutesMaximum: 180,
days: [
{
date: "2023-04-25",
timeSlots: [
{
id: 12001400,
startTime: "12:00:00Z",
endTime: "14:00:00Z",
offerPremium: false,
},
],
},
{
date: "2023-04-26",
timeSlots: [
{ id: 12001400,
startTime: "12:00:00Z",
endTime: "14:00:00Z",
offerPremium: false,
},
{ id: 12001400,
startTime: "14:30:00Z",
endTime: "17:30:00Z",
offerPremium: false,
}
],
},
],
}
*/
},
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
const getShopTimeSlotsPromise = baseMixin.methods.dispatchStoreAction(
storeActions.GET_SHOP_TIME_SLOTS,
{
startDate: "2023-01-01",
endDate: "2023-05-01",
shopAppointmentType: "ZZZZ",
}
);
// Settle promises and get results
const promiseResultMap = [
{
resultKey: "cmsContent",
promise: cmsContentPromise,
},
{
resultKey: "shopTimeSlots",
promise: getShopTimeSlotsPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.shopTimeSlots = resultMap.shopTimeSlots;
});
},
computed: {
ChangeShopLinkText() {
return this.getCmsContent("ChangeShopLink", "Text");
},
ChangeShopLink() {
// Splits content when brackets are found in text so that text can be looped through and router-link can be injected when needed
return this.splitCopyOnCMSPlaceHolder(this.ChangeShopLinkText);
},
DateSelectedReadableDate() {
const dayOfWeek = this.dateForTimeSlotPicker.getDay();
const month = this.dateForTimeSlotPicker.getMonth();
const dayOfMonth = this.dateForTimeSlotPicker.getDate();
return `${daysOfWeek[dayOfWeek]}, ${monthsOfYear[month]} ${dayOfMonth}`;
},
},
methods: {
doesCopyContainRouterLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
arePagePrerequisitesValid() {
return true;
// NEED TODO - WHAT ARE PAGE REQ'S FOR THIS PAGE?
},
async getAvailableDates(startDate, endDate) {
// console.log("S- async getAvailableDates");
// USING DATES PASSED, MAKE AN API CALL
const newShopTimeSlotsResponse = await baseMixin.methods.dispatchStoreAction(
storeActions.GET_SHOP_TIME_SLOTS,
{
startDate: startDate,
endDate: endDate,
shopAppointmentType: "ZZZZ",
},
false
);
const newShopTimeSlots = newShopTimeSlotsResponse.data;
// console.log("newShopTimeSlots ", newShopTimeSlots)
// ADD API CALL RESULTS TO EXISTING DATE DATA
const currentData = [
...this.selectableDatesData,
this.convertApiResponse(newShopTimeSlots.days),
];
// RETURN ALL THE DATE DATA (THE AGGREGATE)
return this.mockSelectableDatesData; // TODO REMOVE MOCK DATA
// return currentData;
},
convertApiResponse(responseData) {
// DATA CONVERSION
responseData?.forEach((date) => {
const dateString = date.date;
date.dateString = dateString;
const dateStringPieces = dateString.split("-");
date.year = Number(dateStringPieces[0]);
date.month = Number(dateStringPieces[1]);
date.date = Number(dateStringPieces[2]);
});
return responseData;
},
openModal() {
this.$refs["timeSlotModal"].openModal();
},
backButtonAction() {
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal });
},
},
components: {
funnelHeader,
funnelFooter,
funnelSubHeader,
Form,
loadingModal,
datePicker,
timeSlotSelectionModal,
},
};
</script>
<style lang="scss"></style>