CASH-1535: Mobile First Appointment
This commit is contained in:
parent
169d8b8949
commit
387906baa8
5 changed files with 348 additions and 3 deletions
|
|
@ -4,6 +4,7 @@ const experimentUniverses = {
|
||||||
MSR: "MSR",
|
MSR: "MSR",
|
||||||
IGQ_SkipQuote: "NextGen_IGQSkipToInsurance",
|
IGQ_SkipQuote: "NextGen_IGQSkipToInsurance",
|
||||||
AFTERPAY_BREAKOUT_DISPLAY: "AfterpayBreakoutDisplay",
|
AFTERPAY_BREAKOUT_DISPLAY: "AfterpayBreakoutDisplay",
|
||||||
|
MOBILE_FIRST_APPOINTMENT: "MobileFirstAppointment",
|
||||||
};
|
};
|
||||||
|
|
||||||
const experimentSettings = {
|
const experimentSettings = {
|
||||||
|
|
@ -28,6 +29,10 @@ const experimentSettings = {
|
||||||
DISPLAY_AFTERPAY_BREAKOUT_DISPLAY: "Display_AfterpayBreakoutDisplay",
|
DISPLAY_AFTERPAY_BREAKOUT_DISPLAY: "Display_AfterpayBreakoutDisplay",
|
||||||
AFTERPAY_EXTENDED_PAY_OPTION_THRESHOLD: "AfterPayExtendedPayOptionThreshold",
|
AFTERPAY_EXTENDED_PAY_OPTION_THRESHOLD: "AfterPayExtendedPayOptionThreshold",
|
||||||
DYNAMO_LOGGING: "DynamoLogging",
|
DYNAMO_LOGGING: "DynamoLogging",
|
||||||
|
SHOW_MOBILE_FIRST_APPT: "ShowMobileFirstAppt",
|
||||||
|
SHOW_PM_MOBILE_DAYS: "Show_PMmobileDays",
|
||||||
|
SHOW_NO_PM_MOBILE_DAYS: "Show_NoPMmobileDays",
|
||||||
|
SHOW_NO_MOBILE_AVAILABLE_DAYS: "Show_NoMobileAvailableDays",
|
||||||
};
|
};
|
||||||
|
|
||||||
const experimentTriggers = {
|
const experimentTriggers = {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
<div class="modal-dialog" :class="{ 'modal-dialog-centered': !isRecal }">
|
<div class="modal-dialog" :class="{ 'modal-dialog-centered': !isRecal }">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header mb-0 mt-6">
|
<div class="modal-header mb-0 mt-6">
|
||||||
|
<slot name="modal-header-slot"></slot>
|
||||||
<label
|
<label
|
||||||
v-if="headerText"
|
v-if="headerText"
|
||||||
class="modal-title d-flex justify-content-center pb-0 w-100">
|
class="modal-title d-flex justify-content-center pb-0 w-100">
|
||||||
|
|
|
||||||
214
src/layouts/schedule/mobile-first-modal/mobile-first-modal.vue
Normal file
214
src/layouts/schedule/mobile-first-modal/mobile-first-modal.vue
Normal file
|
|
@ -0,0 +1,214 @@
|
||||||
|
<template>
|
||||||
|
<div id="mobile-first-modal-container">
|
||||||
|
<modal
|
||||||
|
:ref="modalName"
|
||||||
|
:headerText="modalHeaderText"
|
||||||
|
suppressPageScroll
|
||||||
|
:onModalClosedCallback="onModalClosed"
|
||||||
|
:footerButtonText="modalFooterText"
|
||||||
|
:isFooterButtonPrimary="true"
|
||||||
|
@footer-button-event="confirmAppointment">
|
||||||
|
<p class="modal-body-inner" v-html="modalBodyText"></p>
|
||||||
|
<template v-slot:modal-header-slot>
|
||||||
|
<span>{{ modalSubHeaderText }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-slot:modal-footer-slot>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-link"
|
||||||
|
id="see-more-options"
|
||||||
|
:disabled="isLoading"
|
||||||
|
@click="closeModal">
|
||||||
|
{{ buttonText }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Supporting files
|
||||||
|
import store from "@/store";
|
||||||
|
import modal from "@/digital-components/modal/modal";
|
||||||
|
import { splitCopyOnCMSPlaceHolder } from "@/helpers/cms-content-helper";
|
||||||
|
import { get12HourTimeFormat } from "@/helpers/date-helper";
|
||||||
|
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
|
||||||
|
|
||||||
|
const INLINE_SERVICETYPE_TOKEN = "custom:serviceType";
|
||||||
|
const INLINE_DAY_TOKEN = "custom:day";
|
||||||
|
const INLINE_DATE_TOKEN = "custom:date";
|
||||||
|
const INLINE_TIMESLOT_TOKEN = "custom:timeslot";
|
||||||
|
const INLINE_SERVICE_LENGTH_TOKEN = "custom:serviceLength";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "mobile-first-modal",
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String,
|
||||||
|
modalWidgetName: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedAppontment: {
|
||||||
|
estimatedServiceMinutes: {
|
||||||
|
minimum: null,
|
||||||
|
maximum: null,
|
||||||
|
},
|
||||||
|
timeSlot: null,
|
||||||
|
date: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
splitCopyOnCMSPlaceHolder,
|
||||||
|
get12HourTimeFormat,
|
||||||
|
openModal() {
|
||||||
|
this.modal.openModal();
|
||||||
|
},
|
||||||
|
onModalClosed() {
|
||||||
|
this.$emit("close-mobile-first-modal");
|
||||||
|
},
|
||||||
|
closeModal() {
|
||||||
|
this.modal.closeModal();
|
||||||
|
},
|
||||||
|
confirmAppointment() {
|
||||||
|
let selectedTimeSlot = {
|
||||||
|
timeSlot: this.selectedAppontment.timeSlot,
|
||||||
|
routeCode: this.selectedAppontment.timeSlot.id,
|
||||||
|
};
|
||||||
|
this.$emit("confirm-appointment", selectedTimeSlot);
|
||||||
|
this.modal.closeModal();
|
||||||
|
},
|
||||||
|
setSelectedAppointment(appointment) {
|
||||||
|
this.selectedAppontment = appointment;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
modalName() {
|
||||||
|
return this.modalWidgetName;
|
||||||
|
},
|
||||||
|
modal() {
|
||||||
|
return this.$refs[this.modalName];
|
||||||
|
},
|
||||||
|
modalSubHeaderText() {
|
||||||
|
return this.getCmsContent(this.modalWidgetName, "SubheaderText");
|
||||||
|
},
|
||||||
|
modalHeaderText() {
|
||||||
|
return this.getCmsContent(this.modalWidgetName, "HeaderText");
|
||||||
|
},
|
||||||
|
modalBodyText() {
|
||||||
|
var tokens = this.splitCopyOnCMSPlaceHolder(
|
||||||
|
this.getCmsContent(this.modalWidgetName, "BodyText")
|
||||||
|
);
|
||||||
|
tokens.forEach((token) => {
|
||||||
|
if (token.includes(INLINE_SERVICETYPE_TOKEN)) {
|
||||||
|
const serviceType = "<b>" + this.getServiceType + "</b>";
|
||||||
|
tokens.splice(tokens.indexOf(token), 1, serviceType);
|
||||||
|
} else if (token.includes(INLINE_DAY_TOKEN) && this.selectedAppontment.date) {
|
||||||
|
const day =
|
||||||
|
"<b>" +
|
||||||
|
new Date(this.selectedAppontment.date).toLocaleDateString("en-US", {
|
||||||
|
weekday: "long",
|
||||||
|
timeZone: "UTC",
|
||||||
|
}) +
|
||||||
|
"</b>";
|
||||||
|
tokens.splice(tokens.indexOf(token), 1, day);
|
||||||
|
} else if (token.includes(INLINE_DATE_TOKEN) && this.selectedAppontment.date) {
|
||||||
|
const date = new Date(this.selectedAppontment.date).toLocaleDateString(
|
||||||
|
"en-US",
|
||||||
|
{ timeZone: "UTC", weekday: "long", month: "long", day: "numeric" }
|
||||||
|
);
|
||||||
|
tokens.splice(tokens.indexOf(token), 1, date);
|
||||||
|
} else if (
|
||||||
|
token.includes(INLINE_TIMESLOT_TOKEN) &&
|
||||||
|
this.selectedAppontment.timeSlot
|
||||||
|
) {
|
||||||
|
const timeslot =
|
||||||
|
this.get12HourTimeFormat(this.selectedAppontment.timeSlot.startTime) +
|
||||||
|
" - " +
|
||||||
|
this.get12HourTimeFormat(this.selectedAppontment.timeSlot.endTime);
|
||||||
|
tokens.splice(tokens.indexOf(token), 1, timeslot);
|
||||||
|
} else if (
|
||||||
|
token.includes(INLINE_SERVICE_LENGTH_TOKEN) &&
|
||||||
|
this.selectedAppontment.estimatedServiceMinutes
|
||||||
|
) {
|
||||||
|
const inshopDurationTime = getDisplayTextForDurationLength(
|
||||||
|
this.selectedAppontment.estimatedServiceMinutes.minimum,
|
||||||
|
this.selectedAppontment.estimatedServiceMinutes.maximum
|
||||||
|
);
|
||||||
|
tokens.splice(tokens.indexOf(token), 1, inshopDurationTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return tokens.join("");
|
||||||
|
},
|
||||||
|
modalFooterText() {
|
||||||
|
return this.getCmsContent(this.modalWidgetName, "FooterText");
|
||||||
|
},
|
||||||
|
buttonText() {
|
||||||
|
return this.getCmsContent(this.modalWidgetName, "FooterText2");
|
||||||
|
},
|
||||||
|
getServiceType() {
|
||||||
|
return store.getters.order.damage.isRepair ? "repair" : "replace";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: { modal },
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
#mobile-first-modal-container {
|
||||||
|
.modal-component {
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
.modal-dialog {
|
||||||
|
left: 0;
|
||||||
|
align-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 22.063rem;
|
||||||
|
transform: translate(0, 0);
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
border-radius: $border-radius-lg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-dialog {
|
||||||
|
.modal-content {
|
||||||
|
.modal-header {
|
||||||
|
flex-direction: column;
|
||||||
|
& > span {
|
||||||
|
color: $red;
|
||||||
|
font-size: $font-size-14;
|
||||||
|
font-weight: $font-weight-600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: $font-size-20;
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-body {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
|
||||||
|
.modal-body-inner {
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
font-size: $font-size-14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
flex-flow: wrap-reverse;
|
||||||
|
|
||||||
|
#see-more-options {
|
||||||
|
width: 100%;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
font-weight: $font-weight-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -32,6 +32,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
|
<div class="col-12 col-md-10 col-lg-8 col-xl-7">
|
||||||
|
<mobileFirstModal
|
||||||
|
modalWidgetName="MobileFirstModalWidget"
|
||||||
|
ref="mobileFirstModal"
|
||||||
|
@confirm-appointment="updateTimeSlotandNavigateForward" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertMobileOnly"
|
ref="alertMobileOnly"
|
||||||
class="mt-5 mb-5"
|
class="mt-5 mb-5"
|
||||||
|
|
@ -183,6 +187,7 @@ import shopListButton from "@/layouts/service-location/shop-question/shop-list-b
|
||||||
import shopLocation from "@/layouts/schedule/shop-location/shop-location";
|
import shopLocation from "@/layouts/schedule/shop-location/shop-location";
|
||||||
import timeSlotQuestion from "@/layouts/schedule/time-slot-question/time-slot-question.vue";
|
import timeSlotQuestion from "@/layouts/schedule/time-slot-question/time-slot-question.vue";
|
||||||
import durationTextBlock from "@/layouts/schedule/duration-text-block/duration-text-block.vue";
|
import durationTextBlock from "@/layouts/schedule/duration-text-block/duration-text-block.vue";
|
||||||
|
import mobileFirstModal from "@/layouts/schedule/mobile-first-modal/mobile-first-modal.vue";
|
||||||
|
|
||||||
import shopQuestion from "@/layouts/service-location/shop-question/shop-question";
|
import shopQuestion from "@/layouts/service-location/shop-question/shop-question";
|
||||||
import shopQuestionPopup from "@/layouts/service-location/shop-question/shop-question-popup";
|
import shopQuestionPopup from "@/layouts/service-location/shop-question/shop-question-popup";
|
||||||
|
|
@ -203,7 +208,7 @@ import mobileFeeWaiverAlert from "./mobile-fee-waiver-alert/mobile-fee-waiver-al
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import experimentMixin from "@/mixins/experiment-mixin.js";
|
import experimentMixin from "@/mixins/experiment-mixin.js";
|
||||||
import { experimentSettings } from "@/constants/experiments";
|
import { experimentUniverses, experimentSettings } from "@/constants/experiments";
|
||||||
import {
|
import {
|
||||||
AppointmentTypeStrings,
|
AppointmentTypeStrings,
|
||||||
RouteCodeFlags,
|
RouteCodeFlags,
|
||||||
|
|
@ -242,6 +247,11 @@ import { getAmountDue, getPricingByDayPartWithPrice } from "@/helpers/pricing-he
|
||||||
import { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
|
import { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
|
||||||
import { deepClone } from "@/helpers/object-helper";
|
import { deepClone } from "@/helpers/object-helper";
|
||||||
import { debugLog } from "@/helpers/debug-log-helper";
|
import { debugLog } from "@/helpers/debug-log-helper";
|
||||||
|
import {
|
||||||
|
getSessionKeyValue,
|
||||||
|
getUserIdValue,
|
||||||
|
getDeviceIdValue,
|
||||||
|
} from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("mobile-location-required", (value) => {
|
defineRule("mobile-location-required", (value) => {
|
||||||
|
|
@ -1172,6 +1182,8 @@ export default {
|
||||||
moreShopTimeSlots.mobileTimeSlotsData.days
|
moreShopTimeSlots.mobileTimeSlotsData.days
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.showMobileFirstModal();
|
||||||
|
|
||||||
return moreShopTimeSlots;
|
return moreShopTimeSlots;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1699,6 +1711,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.appointmentType = AppointmentTypeStrings.MOBILE;
|
this.appointmentType = AppointmentTypeStrings.MOBILE;
|
||||||
this.updateSelectedProvider();
|
this.updateSelectedProvider();
|
||||||
|
this.showMobileFirstModal();
|
||||||
} else if (newAppointmentType) {
|
} else if (newAppointmentType) {
|
||||||
if (this.appointmentType != AppointmentTypeStrings.MOBILE) {
|
if (this.appointmentType != AppointmentTypeStrings.MOBILE) {
|
||||||
// Clear last shop selected if appointment type was changed in any manner other than from Mobile
|
// Clear last shop selected if appointment type was changed in any manner other than from Mobile
|
||||||
|
|
@ -1723,6 +1736,116 @@ export default {
|
||||||
setSelectedDateToFirstAvailable() {
|
setSelectedDateToFirstAvailable() {
|
||||||
this.selectedDate = this.getFirstAvailableDate();
|
this.selectedDate = this.getFirstAvailableDate();
|
||||||
},
|
},
|
||||||
|
showMobileFirstModal() {
|
||||||
|
if (this.appointmentType == AppointmentTypeStrings.MOBILE) {
|
||||||
|
const isShowMobileFirstAppt = experimentMixin.methods.hasSettingEqualTo(
|
||||||
|
experimentSettings.SHOW_MOBILE_FIRST_APPT,
|
||||||
|
"true"
|
||||||
|
);
|
||||||
|
const pmMobileDays = experimentMixin.methods.getSettingValue(
|
||||||
|
experimentSettings.SHOW_PM_MOBILE_DAYS
|
||||||
|
);
|
||||||
|
const noPMMobileDays = experimentMixin.methods.getSettingValue(
|
||||||
|
experimentSettings.SHOW_NO_PM_MOBILE_DAYS
|
||||||
|
);
|
||||||
|
const noMobileAvailableDays = experimentMixin.methods.getSettingValue(
|
||||||
|
experimentSettings.SHOW_NO_MOBILE_AVAILABLE_DAYS
|
||||||
|
);
|
||||||
|
|
||||||
|
let preSelectedMobileAppointment = null;
|
||||||
|
const todaysDate = getTodayDate();
|
||||||
|
let firstMobilePMAppt = this.getFirstAvailableMobileApptByTOD("PM");
|
||||||
|
if (!firstMobilePMAppt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let firstMobilePMDate = firstMobilePMAppt ? firstMobilePMAppt.date : null;
|
||||||
|
let numberOfDaysToFirstMobilePMDate =
|
||||||
|
(new Date(firstMobilePMDate) - todaysDate) / (1000 * 60 * 60 * 24);
|
||||||
|
|
||||||
|
const shouldExposeMobileFirstAppointment = () => {
|
||||||
|
return (
|
||||||
|
firstMobilePMDate &&
|
||||||
|
numberOfDaysToFirstMobilePMDate <= noMobileAvailableDays
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (shouldExposeMobileFirstAppointment()) {
|
||||||
|
const mobileFirstExperiment = store.getters.applicationUser.experiments.find(
|
||||||
|
(e) => e.universeName === experimentUniverses.MOBILE_FIRST_APPOINTMENT
|
||||||
|
);
|
||||||
|
const hasExposedMobileFirst = mobileFirstExperiment?.isExposed;
|
||||||
|
|
||||||
|
if (!hasExposedMobileFirst && mobileFirstExperiment) {
|
||||||
|
baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE,
|
||||||
|
{
|
||||||
|
userId: getUserIdValue(),
|
||||||
|
deviceId: getDeviceIdValue(),
|
||||||
|
sessionKey: getSessionKeyValue(),
|
||||||
|
pageName: "schedule",
|
||||||
|
experiment: mobileFirstExperiment,
|
||||||
|
},
|
||||||
|
"schedule",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isShowMobileFirstAppt) {
|
||||||
|
if (
|
||||||
|
firstMobilePMDate &&
|
||||||
|
numberOfDaysToFirstMobilePMDate <= pmMobileDays
|
||||||
|
) {
|
||||||
|
preSelectedMobileAppointment = firstMobilePMAppt;
|
||||||
|
} else if (
|
||||||
|
firstMobilePMDate &&
|
||||||
|
numberOfDaysToFirstMobilePMDate >= noPMMobileDays
|
||||||
|
) {
|
||||||
|
let firstMobileAMAppt = this.getFirstAvailableMobileApptByTOD("AM");
|
||||||
|
preSelectedMobileAppointment = firstMobileAMAppt
|
||||||
|
? firstMobileAMAppt
|
||||||
|
: null;
|
||||||
|
!preSelectedMobileAppointment &&
|
||||||
|
(preSelectedMobileAppointment = firstMobilePMAppt);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$refs.mobileFirstModal.setSelectedAppointment(
|
||||||
|
preSelectedMobileAppointment
|
||||||
|
);
|
||||||
|
this.$refs.mobileFirstModal.openModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getFirstAvailableMobileApptByTOD(timeOfDay) {
|
||||||
|
if (!this.selectableDatesMobile?.days?.length) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
for (const dateObj of this.selectableDatesMobile.days) {
|
||||||
|
let matchingTimeSlot = {
|
||||||
|
estimatedServiceMinutes: {
|
||||||
|
minimum: this.estimatedServiceMinutesMinimum,
|
||||||
|
maximum: this.estimatedServiceMinutesMaximum,
|
||||||
|
},
|
||||||
|
timeSlot: null,
|
||||||
|
date: null,
|
||||||
|
};
|
||||||
|
const isMatchingApptDay = dateObj.timeSlots.some(
|
||||||
|
(slot) =>
|
||||||
|
slot.id.includes(timeOfDay) &&
|
||||||
|
(matchingTimeSlot.timeSlot = slot) &&
|
||||||
|
(matchingTimeSlot.date = dateObj.date)
|
||||||
|
);
|
||||||
|
if (isMatchingApptDay && matchingTimeSlot) {
|
||||||
|
return matchingTimeSlot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTimeSlotandNavigateForward(timeSlotObj) {
|
||||||
|
this.updateTimeSlot(timeSlotObj);
|
||||||
|
this.forwardButtonAction();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
appointmentTypeFromAppointmentTypeQuestion: {
|
appointmentTypeFromAppointmentTypeQuestion: {
|
||||||
|
|
@ -1767,6 +1890,7 @@ export default {
|
||||||
locationAlerts,
|
locationAlerts,
|
||||||
textBlock,
|
textBlock,
|
||||||
timeSlotQuestion,
|
timeSlotQuestion,
|
||||||
|
mobileFirstModal,
|
||||||
|
|
||||||
alert,
|
alert,
|
||||||
serviceZipModalQuestion,
|
serviceZipModalQuestion,
|
||||||
|
|
|
||||||
|
|
@ -123,14 +123,15 @@ $body-color: $gray-600;
|
||||||
|
|
||||||
//Fonts
|
//Fonts
|
||||||
$font-family-sans-serif: UrbanistRegular, Arial, Helvetica, sans-serif;
|
$font-family-sans-serif: UrbanistRegular, Arial, Helvetica, sans-serif;
|
||||||
$font-family-monospace: UrbanistRegular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
$font-family-monospace:
|
||||||
monospace;
|
UrbanistRegular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
// stylelint-enable value-keyword-case
|
// stylelint-enable value-keyword-case
|
||||||
$font-family-base: $font-family-sans-serif;
|
$font-family-base: $font-family-sans-serif;
|
||||||
$font-family-code: $font-family-monospace;
|
$font-family-code: $font-family-monospace;
|
||||||
$font-size-base: 1rem; // Assumes the browser default, typically `16px`
|
$font-size-base: 1rem; // Assumes the browser default, typically `16px`
|
||||||
|
|
||||||
$font-size-12: $font-size-base * 0.75; // 12px
|
$font-size-12: $font-size-base * 0.75; // 12px
|
||||||
|
$font-size-14: $font-size-base * 0.875; // 14px
|
||||||
$font-size-20: $font-size-base * 1.25; // 20px
|
$font-size-20: $font-size-base * 1.25; // 20px
|
||||||
|
|
||||||
//Custom Font size (extra small)
|
//Custom Font size (extra small)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue