funnel process

This commit is contained in:
Max 2021-11-04 10:16:02 -04:00
parent a21c5c61c1
commit bd623e09c5
17 changed files with 222 additions and 82 deletions

View file

@ -64,6 +64,6 @@ export default {
buttonPrimary, buttonPrimary,
radioCard, radioCard,
listButton listButton
}, }
}; };
</script> </script>

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45.6 36.1" xml:space="preserve">
<path d="M43.6 0H18.1c-.4 0-.8.1-1.1.4l-.3.3-16 16c-.8.8-.8 2 0 2.8l16 16 .3.3c.3.2.7.4 1.1.4h25.5c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zm-3.4 28.1-1.4 1.4-10-10-10 10-1.4-1.4 10-10-10-10 1.4-1.4 10 10 10-10L40.2 8l-10 10 10 10.1z" fill="#8e9292"/>
</svg>

After

Width:  |  Height:  |  Size: 338 B

View file

@ -5,7 +5,7 @@
background: $white; background: $white;
height: 100%; height: 100%;
form { .list-view {
height: calc(100% - 230px); height: calc(100% - 230px);
overflow-y: scroll; overflow-y: scroll;
overflow-x: hidden; overflow-x: hidden;
@ -27,6 +27,13 @@
position: absolute; position: absolute;
} }
} }
.back-button {
margin-left: 5px;
img {
width: 20px;
}
}
} }
.slide-enter-from { .slide-enter-from {

View file

@ -50,6 +50,9 @@
border-radius: $border-radius-lg; border-radius: $border-radius-lg;
border: 1px solid rgba($gray-300,.3); border: 1px solid rgba($gray-300,.3);
width: 100%; width: 100%;
&:focus, &:focus-visible {
box-shadow: none;
}
&.button-loader { &.button-loader {
padding: 0 40px 0 12px; padding: 0 40px 0 12px;
&:after { &:after {

View file

@ -13,11 +13,14 @@
<transition appear name="fade"> <transition appear name="fade">
<div <div
class="current_car_info-text" class="current_car_info-text"
v-on:click="backFunction ? backFunction() : null" @click="backFunction ? backFunction() : null"
> >
<span class="text-center text-secondary fs-5 d-block">{{ <div class="d-flex align-items-center justify-content-center">
<span class="text-center text-secondary fs-5 d-block">{{
this.currentCarInfo this.currentCarInfo
}}</span> }}</span>
<span v-if="backFunction" class="back-button"><img src="@/assets/img/icons/back-forward.svg" alt="back-button"></span>
</div>
<span v-if="style" class="text-center text-secondary fs-6 mt-2">{{ <span v-if="style" class="text-center text-secondary fs-6 mt-2">{{
style style
}}</span> }}</span>

View file

@ -1,11 +1,11 @@
<template> <template>
<form class="list-view d-flex"> <div class="list-view d-flex">
<div class="car_list"> <div class="car_list">
<div v-for="attritbute in attritbutes" :key="attritbute" class="mb-2"> <div v-for="attritbute in attritbutes" :key="attritbute" class="mb-2">
<listButton :buttonText="attritbute" v-on:click="selectAttribute(attritbute)" /> <listButton :buttonText="attritbute" @click="selectAttribute(attritbute)" />
</div>
</div> </div>
</div> </div>
</form>
</template> </template>
<script> <script>

View file

@ -2,6 +2,22 @@ const endpoints = {
GetRouteInfoEndpoint: { GetRouteInfoEndpoint: {
url: '/content/api/v1/content/RouteInfo', url: '/content/api/v1/content/RouteInfo',
method: 'POST' method: 'POST'
},
GetYears: {
url: '/vehicle/api/v1/vehicle/years',
method: 'GET'
},
GetMakes: {
url: '/vehicle/api/v1/vehicle/Makes',
method: 'POST'
},
GetModels: {
url: '/vehicle/api/v1/vehicle/Models',
method: 'POST'
},
GetStyles: {
url: '/vehicle/api/v1/vehicle/Styles',
method: 'POST'
} }
} }

View file

@ -28,4 +28,9 @@ export default {
); );
}); });
}, },
disableItems(arr) {
arr.forEach( (i) => {
i.disabled = true
})
},
}; };

View file

@ -6,36 +6,72 @@
> >
<div class="damage-section text-center"> <div class="damage-section text-center">
<div class="choose-damage row"> <div class="choose-damage row">
<div class="col"> <radioCard
<radioCard /> radioLabel="Windshield"
</div> radioImage="windshield-damage.svg"
<div class="col"> altText="Windshield"
<radioCard /> groupName="damageKey"
</div> radioID="windshield"
<div class="col"> name="damage"
<radioCard /> @click="chooseDamage('windshield')"
</div> />
<radioCard
radioLabel="Side Window"
radioImage="side-window-damage.svg"
altText="Side Window"
groupName="damageKey"
radioID="sidewindow"
name="damage"
@click="chooseDamage('side-window')"
/>
<radioCard
radioLabel="Back Glass"
radioImage="back-glass-damage.svg"
altText="Back Glass"
groupName="damageKey"
radioID="backglass"
name="damage"
@click="chooseDamage('side-glass')"
/>
</div> </div>
<transition name="fade"> <transition name="fade">
<div v-if="damage" class="how-bad mt-3"> <div v-if="damage" class="how-bad mt-3">
<span class="text-center fs-6 fw-bold">How bad is it?</span> <span class="text-center fs-6 fw-bold">How bad is it?</span>
<div class="choose-how-bad row mt-2"> <div class="choose-how-bad row mt-2">
<div class="col"> <radioCard
<radioCard /> radioLabel="Crack"
</div> radioImage="windshield-damage.svg"
<div class="col"> altText="Crack"
<radioCard /> groupName="severityKey"
</div> radioID="Crack"
name="severity"
@click="chooseSeverity(Crack)"
/>
<radioCard
radioLabel="Chip(s)"
radioImage="side-window-damage.svg"
altText="Chips"
groupName="severityKey"
radioID="Chips"
name="severity"
@click="chooseSeverity(Chips)"
/>
</div> </div>
</div> </div>
</transition> </transition>
<div class="next-action row"> <transition appear name="fade">
<div class="col"> <div class="next-action d-flex align-items-center justify-content-around fixed-bottom py-3 border border-top-1 border-top-light">
<div v-on:click="goBack" class="change"> <div v-on:click="goBack" class="change">
<span>Change Vehicle</span> <span class="fw-bold text-decoration-underline">Change Vehicle</span>
</div>
<div>
<buttonPrimary
buttonText="Get your estimate"
:isDisabled="this.isDisabled"
/>
</div> </div>
</div> </div>
</div> </transition>
</div> </div>
</baseTemplate> </baseTemplate>
</div> </div>
@ -44,6 +80,7 @@
<script> <script>
import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate"; import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate";
import radioCard from "@/uxComponents/radioCard/radioCard"; import radioCard from "@/uxComponents/radioCard/radioCard";
import buttonPrimary from "@/uxComponents/buttonPrimary/buttonPrimary";
import { mapState } from "vuex"; import { mapState } from "vuex";
export default { export default {
@ -54,12 +91,17 @@ export default {
data() { data() {
return { return {
damage: "", damage: "",
severity: "",
isDisabled: true
}; };
}, },
methods: { methods: {
chooseDamage(damage) { chooseDamage(damage) {
this.damage = damage; this.damage = damage;
console.log(this.damage); },
chooseSeverity(severity){
this.severity = severity;
this.isDisabled = false;
}, },
goBack() { goBack() {
this.$store.state.slideTransition = "slide_reverse"; this.$store.state.slideTransition = "slide_reverse";
@ -72,6 +114,7 @@ export default {
components: { components: {
baseTemplate, baseTemplate,
radioCard, radioCard,
buttonPrimary,
}, },
}; };
</script> </script>

View file

@ -9,6 +9,7 @@
<script> <script>
import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate"; import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate";
import carAttributes from "@/commonComponents/carAttributes/carAttributes"; import carAttributes from "@/commonComponents/carAttributes/carAttributes";
import globalMethods from "@/global-methods";
import { import {
mapState mapState
} from "vuex"; } from "vuex";
@ -20,7 +21,9 @@ export default {
}, },
methods: { methods: {
selectMake(make) { selectMake(make) {
this.$store.dispatch("selectMake", make); const listButtons = document.querySelectorAll('.list-button');
globalMethods.disableItems(listButtons);
this.dispatchNonBlockingStoreAction("selectMake", { make: make })
}, },
goBack() { goBack() {
this.$store.state.slideTransition = "slide_reverse"; this.$store.state.slideTransition = "slide_reverse";

View file

@ -13,6 +13,7 @@
<script> <script>
import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate"; import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate";
import carAttributes from "@/commonComponents/carAttributes/carAttributes"; import carAttributes from "@/commonComponents/carAttributes/carAttributes";
import globalMethods from "@/global-methods";
import { mapState } from "vuex"; import { mapState } from "vuex";
export default { export default {
@ -22,7 +23,9 @@ export default {
}, },
methods: { methods: {
selectModel(model) { selectModel(model) {
this.$store.dispatch("selectModel", model); const listButtons = document.querySelectorAll('.list-button');
globalMethods.disableItems(listButtons);
this.dispatchNonBlockingStoreAction("selectModel", { model: model })
}, },
goBack() { goBack() {
this.$store.state.slideTransition = "slide_reverse"; this.$store.state.slideTransition = "slide_reverse";

View file

@ -13,6 +13,7 @@
<script> <script>
import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate"; import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate";
import carAttributes from "@/commonComponents/carAttributes/carAttributes"; import carAttributes from "@/commonComponents/carAttributes/carAttributes";
import globalMethods from "@/global-methods";
import { mapState } from "vuex"; import { mapState } from "vuex";
export default { export default {
@ -22,7 +23,9 @@ export default {
}, },
methods: { methods: {
selectStyle(style) { selectStyle(style) {
this.$store.dispatch("selectStyle", style); const listButtons = document.querySelectorAll('.list-button');
globalMethods.disableItems(listButtons);
this.dispatchNonBlockingStoreAction("selectStyle", { style: style })
}, },
goBack() { goBack() {
this.$store.state.slideTransition = "slide_reverse"; this.$store.state.slideTransition = "slide_reverse";

View file

@ -12,7 +12,8 @@
<script> <script>
import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate"; import baseTemplate from "@/commonComponents/baseTemplate/baseTemplate";
import carAttributes from "@/commonComponents/carAttributes/carAttributes"; import carAttributes from "@/commonComponents/carAttributes/carAttributes";
import axios from "axios"; import { endpoints } from "@/constants/endpoints.js";
import globalMethods from "@/global-methods";
export default { export default {
name: "SelectCar", name: "SelectCar",
@ -22,14 +23,21 @@ export default {
}; };
}, },
mounted() { mounted() {
axios.get("https://consumerapidev.safelite.com/vehicle/api/v1/vehicle/years").then((response) => { return globalMethods.callHttpClient({
this.years = response.data.Result; method: endpoints.GetYears.method,
}); endpoint: endpoints.GetYears.url,
payload:{}
})
.then( (response) => {
this.years = response.data.Result;
});
}, },
methods: { methods: {
selectYear(year) { selectYear(year) {
this.$store.dispatch("selectYear", year); const listButtons = document.querySelectorAll('.list-button');
}, globalMethods.disableItems(listButtons);
this.dispatchNonBlockingStoreAction("selectYear", { year: year });
}
}, },
components: { components: {
baseTemplate, baseTemplate,

View file

@ -4,8 +4,11 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"
import NotFound from "@/layouts/notFound/notFound.vue"; import NotFound from "@/layouts/notFound/notFound.vue";
import Home from "@/layouts/home/home.vue"; import Home from "@/layouts/home/home.vue";
import store from "@/store"; import store from "@/store";
import selectYear from "@/layouts/selectYear/selectYear.vue" import selectYear from "@/layouts/selectYear/selectYear.vue";
import selectMake from "@/layouts/selectMake/selectMake.vue" import selectMake from "@/layouts/selectMake/selectMake.vue";
import selectModel from "@/layouts/selectModel/selectModel.vue";
import selectStyle from "@/layouts/selectStyle/selectStyle.vue";
import selectDamage from "@/layouts/selectDamage/selectDamage.vue";
const routes = [ const routes = [
{ {
@ -28,6 +31,21 @@ const routes = [
name: "selectMake", name: "selectMake",
component: selectMake, component: selectMake,
}, },
{
path: "/select-model",
name: "selectModel",
component: selectModel,
},
{
path: "/select-style",
name: "selectStyle",
component: selectStyle,
},
{
path: "/select-damage",
name: "selectDamage",
component: selectDamage,
},
]; ];
const router = createRouter({ const router = createRouter({
@ -36,7 +54,9 @@ const router = createRouter({
}); });
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
NavigateToDynamicCmsRoute(to, next); console.log(to);
console.log(from);
next();
}); });
// Go to route if page exists in the CMS. // Go to route if page exists in the CMS.

View file

@ -1,7 +1,6 @@
import { createStore } from "vuex"; import { createStore } from "vuex";
import { endpoints } from "@/constants/endpoints.js"; import { endpoints } from "@/constants/endpoints.js";
import createPersistedState from "vuex-persistedstate"; import createPersistedState from "vuex-persistedstate";
import axios from "axios";
import globalMethods from "@/global-methods"; import globalMethods from "@/global-methods";
import router from "@/router"; import router from "@/router";
@ -55,41 +54,65 @@ export default createStore({
}, },
}, },
actions: { actions: {
async selectYear(context, year) { selectYear(context, { year }) {
const makes = await axios.get(`https://mockey.qa.sagaws.net/service/makes/year=${year}`); return globalMethods.callHttpClient({
context.commit("updateYear", { year, makes }); method: endpoints.GetMakes.method,
router.push(`/select-make?year=${year}`); endpoint: endpoints.GetMakes.url,
}, payload:{
async selectMake({ commit, state }, make) { "Year": year
const models = await axios.get( }
`https://mockey.qa.sagaws.net/service/models/year=${state.year}/make=${make}` })
); .then( (response) => {
commit("updateMake", { make, models }); const makes = response;
router.push(`/select-model?year=${state.year}&make=${make}`); context.commit('updateYear', {year, makes});
}, router.push(`select-make?year=${year}`);
async selectModel({ commit, state }, model) { });
const styles = await axios.get( },
`https://mockey.qa.sagaws.net/service/styles/year=${state.year}/make=${state.make}/model=${model}` selectMake({ commit, state }, { make }) {
); return globalMethods.callHttpClient({
commit("updateModel", { model, styles }); method: endpoints.GetModels.method,
router.push( endpoint: endpoints.GetModels.url,
`/select-style?year=${state.year}&make=${state.make}&model=${model}` payload:{
); "Year": state.year,
}, "Make": make
selectStyle({ commit, state }, style) { }
commit("updateStyle", { style }); })
router.push( .then( (response) => {
`/damage?year=${state.year}&make=${state.make}&model=${state.model}&style=${style}` const models = response;
); commit("updateMake", { make, models });
}, router.push(`/select-model?year=${state.year}&make=${make}`);
getRouteInfo(context, { relativeUrl }) { });
return globalMethods.callHttpClient({ },
method: endpoints.GetRouteInfoEndpoint.method, selectModel({ commit, state }, { model }) {
endpoint: endpoints.GetRouteInfoEndpoint.url, return globalMethods.callHttpClient({
payload: { method: endpoints.GetStyles.method,
relativeUrl: relativeUrl, endpoint: endpoints.GetStyles.url,
}, payload:{
}); "Year": state.year,
}, "Make": state.make,
"Model": model
}
})
.then( (response) => {
const styles = response;
commit("updateModel", { model, styles });
router.push(`/select-style?year=${state.year}&make=${state.make}&model=${model}`);
});
},
selectStyle({ commit, state }, { style }) {
commit("updateStyle", { style });
router.push(
`/select-damage?year=${state.year}&make=${state.make}&model=${state.model}&style=${style}`
);
},
getRouteInfo(context, { relativeUrl }) {
return globalMethods.callHttpClient({
method: endpoints.GetRouteInfoEndpoint.method,
endpoint: endpoints.GetRouteInfoEndpoint.url,
payload: {
relativeUrl: relativeUrl,
},
});
},
}, },
}); });

View file

@ -14,12 +14,12 @@
export default { export default {
name: "buttonPrimary", name: "buttonPrimary",
props: { props: {
buttonText: String buttonText: String,
isDisabled: Boolean
}, },
data() { data() {
return { return {
isLoading: false, isLoading: false
isDisabled: false,
}; };
}, },
methods: { methods: {

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="col-4 mb-3 d-flex radio-card"> <div class="col mb-3 d-flex radio-card">
<input <input
type="radio" type="radio"
class="position-absolute opacity-0" class="position-absolute opacity-0"