md into dynamic routing
This commit is contained in:
commit
7f3134a929
31 changed files with 569 additions and 257 deletions
11
package.json
11
package.json
|
|
@ -14,12 +14,13 @@
|
|||
"canvas-confetti": "^1.4.0",
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^3.0.0",
|
||||
"vue-router": "^4.0.11"
|
||||
"vue-router": "^4.0.11",
|
||||
"vuex": "^4.0.2",
|
||||
"vuex-persistedstate": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-unit-jest": "^4.5.13",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/compiler-sfc": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
|
|
@ -27,16 +28,10 @@
|
|||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"jest-junit": "^12.3.0",
|
||||
"prettier": "^2.2.1",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2"
|
||||
},
|
||||
"jest-junit": {
|
||||
"suiteNameTemplate": "{filepath}",
|
||||
"outputDirectory": ".",
|
||||
"outputName": "junit.xml"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="Funnel1"></div>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
18
src/App.vue
18
src/App.vue
|
|
@ -1,26 +1,16 @@
|
|||
<template>
|
||||
<HeaderNav/>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<HelloWorld msg="VueJS with Bootstrap"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-lg">
|
||||
<router-view />
|
||||
</div>
|
||||
<Colors/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HelloWorld from './components/HelloWorld.vue';
|
||||
import HeaderNav from '@/components/HeaderNav/HeaderNav.vue';
|
||||
import Colors from './components/Colors';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
HelloWorld,
|
||||
HeaderNav,
|
||||
Colors
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
<template>
|
||||
<router-view></router-view>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex justify-content-center">
|
||||
<vehicleImage/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p class="text-center text-secondary fs-5 mb-4">Select a year to get started</p>
|
||||
<p class="text-center fs-6 fw-bold">What year is your vehichle?</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<buttonFunnel/>
|
||||
<confetti/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-5">
|
||||
<imageButton
|
||||
btnText="windshield-damage.svg"
|
||||
altText="Windshield"
|
||||
damageTitle="Windshield"
|
||||
ariaLabel="Windshield"
|
||||
/>
|
||||
<imageButton
|
||||
btnText="side-window-damage.svg"
|
||||
altText="Side Window"
|
||||
damageTitle="Side door"
|
||||
ariaLabel="Side door"
|
||||
/>
|
||||
<imageButton
|
||||
btnText="back-glass-damage.svg"
|
||||
altText="Back Glass"
|
||||
damageTitle="Back glass"
|
||||
ariaLabel="Back glass"
|
||||
/>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary
|
||||
buttonText="Primary"
|
||||
buttonType="btn-primary"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary
|
||||
buttonText="Primary Focus"
|
||||
buttonType="btn-primary-focus"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<buttonPrimary
|
||||
buttonText="Disabled"
|
||||
buttonType="disabled"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col my-3 d-flex align-items-center">
|
||||
<a href="#">Text Link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import buttonFunnel from './components/buttons/buttonFunnel';
|
||||
import vehicleImage from './components/vehicleImage';
|
||||
import imageButton from './components/imageButton';
|
||||
import confetti from './components/confetti';
|
||||
import buttonPrimary from './components/buttons/buttonPrimary';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
buttonFunnel,
|
||||
vehicleImage,
|
||||
imageButton,
|
||||
confetti,
|
||||
buttonPrimary
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -12,3 +12,7 @@ a {
|
|||
color: $blue-400;
|
||||
}
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
|||
61
src/assets/scss/components/_SelectCar.scss
Normal file
61
src/assets/scss/components/_SelectCar.scss
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
.select-car {
|
||||
height: 100vh;
|
||||
|
||||
.select-car-form {
|
||||
background: $white;
|
||||
height: 100%;
|
||||
|
||||
form {
|
||||
height: calc(100% - 230px);
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.car_list, .current_car_info-text, .needed_car_info-text {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
transition: transform .3s;
|
||||
}
|
||||
}
|
||||
|
||||
.current_car_info {
|
||||
position: relative;
|
||||
min-height: 2.5rem;
|
||||
|
||||
.current_car_info-text {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slide-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(30vw);
|
||||
}
|
||||
.slide-enter-active, .slide-leave-active {
|
||||
transition: all .4s;
|
||||
}
|
||||
.slide-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-30vw);
|
||||
}
|
||||
|
||||
.slide_reverse-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(-30vw);
|
||||
}
|
||||
.slide_reverse-enter-active, .slide_reverse-leave-active {
|
||||
transition: all .4s;
|
||||
}
|
||||
.slide_reverse-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(30vw);
|
||||
}
|
||||
|
||||
.fade-enter-from, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: all .5s ease;
|
||||
}
|
||||
|
|
@ -52,6 +52,10 @@
|
|||
z-index: -1;
|
||||
}
|
||||
}
|
||||
&.btn-funnel {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
// Non-Bootstrap button
|
||||
// Intended to be used without .btn class
|
||||
|
|
@ -69,3 +73,20 @@
|
|||
box-shadow: 0 0 0 2px $blue;
|
||||
}
|
||||
}
|
||||
|
||||
// Non-Bootstrap button
|
||||
// Intended to be used without .btn class
|
||||
.btn-damage {
|
||||
width: 100%;
|
||||
background-color: $white;
|
||||
border: 1px solid #b3b4b5;
|
||||
&:focus {
|
||||
background-color: #e7f1f6;
|
||||
border: 1px solid $blue;
|
||||
}
|
||||
&:focus-visible { // For keyboard/screenreader
|
||||
background-color: #e7f1f6;
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px $blue;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,5 +18,6 @@
|
|||
|
||||
//Custom Components CSS
|
||||
@import "./components/_navbar";
|
||||
@import "./components/_SelectCar";
|
||||
@import "./components/_buttons";
|
||||
@import "./components/_vehicle-image";
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
<template>
|
||||
<div class="container my-4">
|
||||
<div class="row">
|
||||
<h4>Colors</h4>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-primary text-white">Primary #DA291C</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-secondary text-white">Secondary #525656</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-success text-white">Success #098649</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-danger text-white">Danger #AF2117</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-warning text-dark">Warning #F88F1C</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-info text-dark">Info #0DCAF0</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-light text-dark">Light #F4F4F4</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-3 mb-3 bg-dark text-white">Dark #525656</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Colors'
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<template>
|
||||
|
||||
<h2>{{ msg }}</h2>
|
||||
|
||||
<h4 class="mt-3">Grid</h4>
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col">
|
||||
One
|
||||
</div>
|
||||
<div class="col">
|
||||
Two
|
||||
</div>
|
||||
<div class="col">
|
||||
Three
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4 class="mt-3">Buttons</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<button type="button" class="btn btn-primary">Primary</button>
|
||||
<button type="button" class="btn btn-secondary">Secondary</button>
|
||||
<button type="button" class="btn btn-success">Success</button>
|
||||
<button type="button" class="btn btn-danger">Danger</button>
|
||||
<button type="button" class="btn btn-warning">Warning</button>
|
||||
<button type="button" class="btn btn-info">Info</button>
|
||||
<button type="button" class="btn btn-light">Light</button>
|
||||
<button type="button" class="btn btn-dark">Dark</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<template>
|
||||
<button type="button" class="btn btn-funnel border rounded w-100 text-start">2021</button>
|
||||
</template>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<template>
|
||||
<button
|
||||
type="button"
|
||||
class="btn d-flex align-items-center"
|
||||
v-on:click="showLoader()"
|
||||
v-bind:class="[(this.isLoading ? 'button-loader' : 'not-loading'),this.buttonType]"
|
||||
>
|
||||
{{ this.buttonText }}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'buttonPrimary',
|
||||
props: {
|
||||
buttonText: String,
|
||||
buttonType: String
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showLoader(){
|
||||
this.isLoading = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<template>
|
||||
<img class="vehicle-image blur img-fluid" src="https://placekitten.com/600/300" />
|
||||
</template>
|
||||
47
src/layouts/CarFunnel/BaseTemplate.vue
Normal file
47
src/layouts/CarFunnel/BaseTemplate.vue
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div class="select-car sticky-lg-top py-4">
|
||||
<div class="select-car-form overflow-hidden p-3 rounded">
|
||||
<div class="car_info text-center">
|
||||
<div class="car-image mb-3">
|
||||
<img
|
||||
class="vehicle-image img-fluid"
|
||||
:class="{ blur: blurImg }"
|
||||
:src="carImg"
|
||||
/>
|
||||
</div>
|
||||
<div class="current_car_info">
|
||||
<transition appear name="fade">
|
||||
<div class="current_car_info-text" v-on:click="backFunction ? backFunction() : null">
|
||||
<span class="text-center text-secondary fs-5 d-block">{{ this.currentCarInfo }}</span>
|
||||
<span v-if="style" class="text-center text-secondary fs-6 mt-2">{{ style }}</span>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<transition appear :name="slideTransition">
|
||||
<div class="needed_car_info d-flex overflow-hidden mt-4 mb-3">
|
||||
<span class="text-center fs-6 fw-bold needed_car_info-text">{{ this.neededCarInfo }}</span>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<transition appear :name="slideTransition">
|
||||
<slot></slot>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'BaseTemplate',
|
||||
computed: {
|
||||
...mapState(['slideTransition', 'carImg', 'blurImg', 'style'])
|
||||
},
|
||||
props: {
|
||||
currentCarInfo: String,
|
||||
neededCarInfo: String,
|
||||
backFunction: Function
|
||||
}
|
||||
}
|
||||
</script>
|
||||
104
src/layouts/CarFunnel/Damage/SelectDamage.vue
Normal file
104
src/layouts/CarFunnel/Damage/SelectDamage.vue
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<template>
|
||||
<div>
|
||||
<baseTemplate
|
||||
:currentCarInfo="year + ' ' + make + ' ' + model"
|
||||
neededCarInfo="What is your damage?"
|
||||
>
|
||||
<div class="damage-section text-center">
|
||||
<div class="choose-damage row">
|
||||
<div class="col">
|
||||
<imageButton
|
||||
btnImg="windshield-damage.svg"
|
||||
altText="Windshield"
|
||||
damageTitle="Windshield"
|
||||
ariaLabel="Windshield"
|
||||
v-on:click="chooseDamage('windshield')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<imageButton
|
||||
btnImg="side-window-damage.svg"
|
||||
altText="Side Window"
|
||||
damageTitle="Side door"
|
||||
ariaLabel="Side door"
|
||||
v-on:click="chooseDamage('side-window')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<imageButton
|
||||
btnImg="back-glass-damage.svg"
|
||||
altText="Back Glass"
|
||||
damageTitle="Back glass"
|
||||
ariaLabel="Back glass"
|
||||
v-on:click="chooseDamage('side-glass')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<div v-if="damage" class="how-bad mt-3">
|
||||
<span class="text-center fs-6 fw-bold">How bad is it?</span>
|
||||
<div class="choose-how-bad row mt-2">
|
||||
<div class="col">
|
||||
<imageButton
|
||||
btnImg="windshield-damage.svg"
|
||||
altText="Windshield"
|
||||
damageTitle="Windshield"
|
||||
ariaLabel="Windshield"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<imageButton
|
||||
btnImg="side-window-damage.svg"
|
||||
altText="Side Window"
|
||||
damageTitle="Side door"
|
||||
ariaLabel="Side door"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="next-action row">
|
||||
<div class="col">
|
||||
<div v-on:click="goBack" class="change">
|
||||
<span>Change Vehicle</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</baseTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseTemplate from '../BaseTemplate';
|
||||
import imageButton from '@/sharedcomponents/Buttons/ImageButton'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'SelectCar',
|
||||
computed: {
|
||||
...mapState(['year', 'make', 'model'])
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
damage: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
chooseDamage(damage){
|
||||
this.damage = damage
|
||||
console.log(this.damage)
|
||||
},
|
||||
goBack(){
|
||||
this.$store.state.slideTransition = 'slide_reverse';
|
||||
this.$store.commit('removeStyle')
|
||||
this.$router.push(`/select-style?year=${this.$store.state.year}&make=${this.$store.state.make}`);
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTemplate,
|
||||
imageButton
|
||||
}
|
||||
}
|
||||
</script>
|
||||
28
src/layouts/CarFunnel/SelectCar/CarAttributes.vue
Normal file
28
src/layouts/CarFunnel/SelectCar/CarAttributes.vue
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<form class="list-view d-flex">
|
||||
<div class="car_list">
|
||||
<div v-for="attritbute in attritbutes" :key="attritbute" class="mb-2">
|
||||
<Button
|
||||
:buttonText="attritbute"
|
||||
v-on:click="selectAttribute(attritbute)"
|
||||
buttonType="btn-funnel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Button from '@/sharedcomponents/Buttons/Button';
|
||||
|
||||
export default {
|
||||
name: 'CarAttributes',
|
||||
props: {
|
||||
attritbutes: Array,
|
||||
selectAttribute: Function
|
||||
},
|
||||
components: {
|
||||
Button
|
||||
}
|
||||
}
|
||||
</script>
|
||||
40
src/layouts/CarFunnel/SelectCar/SelectMake.vue
Normal file
40
src/layouts/CarFunnel/SelectCar/SelectMake.vue
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div>
|
||||
<baseTemplate
|
||||
:currentCarInfo="year"
|
||||
neededCarInfo="What make is your vehicle?"
|
||||
:backFunction="goBack"
|
||||
>
|
||||
<CarAttributes
|
||||
:attritbutes="makes"
|
||||
:selectAttribute="selectMake"
|
||||
/>
|
||||
</baseTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseTemplate from '../BaseTemplate';
|
||||
import CarAttributes from './CarAttributes'
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'SelectCar',
|
||||
computed: {
|
||||
...mapState(['year', 'makes'])
|
||||
},
|
||||
methods: {
|
||||
selectMake(make){
|
||||
this.$store.dispatch('selectMake', make);
|
||||
},
|
||||
goBack(){
|
||||
this.$store.state.slideTransition = 'slide_reverse';
|
||||
this.$router.push('/select-year');
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTemplate,
|
||||
CarAttributes
|
||||
}
|
||||
}
|
||||
</script>
|
||||
40
src/layouts/CarFunnel/SelectCar/SelectModel.vue
Normal file
40
src/layouts/CarFunnel/SelectCar/SelectModel.vue
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div>
|
||||
<baseTemplate
|
||||
:currentCarInfo="year + ' ' + make"
|
||||
:neededCarInfo="'What is the model of your ' + make + '?'"
|
||||
:backFunction="goBack"
|
||||
>
|
||||
<CarAttributes
|
||||
:attritbutes="models"
|
||||
:selectAttribute="selectModel"
|
||||
/>
|
||||
</baseTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseTemplate from '../BaseTemplate';
|
||||
import CarAttributes from './CarAttributes'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'SelectCar',
|
||||
computed: {
|
||||
...mapState(['year', 'make', 'models'])
|
||||
},
|
||||
methods: {
|
||||
selectModel(model){
|
||||
this.$store.dispatch('selectModel', model);
|
||||
},
|
||||
goBack(){
|
||||
this.$store.state.slideTransition = 'slide_reverse';
|
||||
this.$router.push(`/select-make?year=${this.$store.state.year}`);
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTemplate,
|
||||
CarAttributes
|
||||
}
|
||||
}
|
||||
</script>
|
||||
40
src/layouts/CarFunnel/SelectCar/SelectStyle.vue
Normal file
40
src/layouts/CarFunnel/SelectCar/SelectStyle.vue
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div>
|
||||
<baseTemplate
|
||||
:currentCarInfo="year + ' ' + make + ' ' + model"
|
||||
:neededCarInfo="'What style is your ' + model + '?'"
|
||||
:backFunction="goBack"
|
||||
>
|
||||
<CarAttributes
|
||||
:attritbutes="styles"
|
||||
:selectAttribute="selectStyle"
|
||||
/>
|
||||
</baseTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseTemplate from '../BaseTemplate';
|
||||
import CarAttributes from './CarAttributes'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'SelectCar',
|
||||
computed: {
|
||||
...mapState(['year', 'make', 'model', 'styles'])
|
||||
},
|
||||
methods: {
|
||||
selectStyle(style){
|
||||
this.$store.dispatch('selectStyle', style);
|
||||
},
|
||||
goBack(){
|
||||
this.$store.state.slideTransition = 'slide_reverse';
|
||||
this.$router.push(`/select-model?year=${this.$store.state.year}&make=${this.$store.state.make}`);
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTemplate,
|
||||
CarAttributes
|
||||
}
|
||||
}
|
||||
</script>
|
||||
42
src/layouts/CarFunnel/SelectCar/SelectYear.vue
Normal file
42
src/layouts/CarFunnel/SelectCar/SelectYear.vue
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<div>
|
||||
<baseTemplate
|
||||
currentCarInfo="Select a year to get started"
|
||||
neededCarInfo="What year is your vehicle?"
|
||||
>
|
||||
<CarAttributes
|
||||
:attritbutes="years"
|
||||
:selectAttribute="selectYear"
|
||||
/>
|
||||
</baseTemplate>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseTemplate from '../BaseTemplate';
|
||||
import CarAttributes from './CarAttributes'
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: 'SelectCar',
|
||||
data() {
|
||||
return {
|
||||
years: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
axios.get("https://mockey.qa.sagaws.net/service/years").then((response) => {
|
||||
this.years = response.data.Result;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
selectYear(year){
|
||||
this.$store.dispatch('selectYear', year);
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTemplate,
|
||||
CarAttributes
|
||||
}
|
||||
}
|
||||
</script>
|
||||
6
src/layouts/ContentSite/Home.vue
Normal file
6
src/layouts/ContentSite/Home.vue
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<div class="home">
|
||||
<h1>Home</h1>
|
||||
<router-link to="/select-year">SelectCar</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { createApp } from "vue";
|
||||
import Funnel1 from "./Funnel1.vue";
|
||||
import router from '@/router';
|
||||
import App from "./App.vue";
|
||||
import router from './router';
|
||||
import store from '@/store';
|
||||
|
||||
//Bootstrap JavaScript
|
||||
import "../node_modules/bootstrap/dist/js/bootstrap.js";
|
||||
|
|
@ -8,4 +9,4 @@ import "../node_modules/bootstrap/dist/js/bootstrap.js";
|
|||
//Get Bootstrap and Custom Styles
|
||||
import "./assets/scss/custom.scss";
|
||||
|
||||
createApp(Funnel1).use(router).mount("#Funnel1");
|
||||
createApp(App).use(router).use(store).mount("#app");
|
||||
|
|
|
|||
37
src/sharedcomponents/Buttons/Button.vue
Normal file
37
src/sharedcomponents/Buttons/Button.vue
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<button
|
||||
type="button"
|
||||
class="btn"
|
||||
v-bind:class="[(this.buttonType === 'btn-funnel' ? ['btn-funnel', 'border', 'rounded', 'w-100', 'text-start'] : this.buttonType)]"
|
||||
v-on:click="this.buttonType === 'btn-funnel' ? showLoader() : null"
|
||||
>
|
||||
{{ this.buttonText }}
|
||||
|
||||
|
||||
<!-- Spinner for funnel Button -->
|
||||
<div v-if="this.buttonType === 'btn-funnel' && this.isLoading" class="spinner-border spinner-border-sm text-success" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'button',
|
||||
props: {
|
||||
buttonText: String,
|
||||
buttonType: String
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showLoader(){
|
||||
this.isLoading = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
13
src/sharedcomponents/Buttons/ImageButton.vue
Normal file
13
src/sharedcomponents/Buttons/ImageButton.vue
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
<button class="btn-damage d-flex flex-column align-items-center rounded-3 h-100" v-bind:aria-label="ariaLabel">
|
||||
<img class="px-1 pt-3 pb-1 mt-auto" v-bind:src="require(`@/assets/img/icons/${btnImg}`)" v-bind:alt="altText"/>
|
||||
<p class="mt-auto">{{damageTitle}}</p>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'imageButton',
|
||||
props: ['btnImg', 'altText', 'damageTitle', 'ariaLabel']
|
||||
}
|
||||
</script>
|
||||
72
src/store/index.js
Normal file
72
src/store/index.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { createStore } from 'vuex';
|
||||
import createPersistedState from 'vuex-persistedstate';
|
||||
import axios from 'axios';
|
||||
import router from '@/router';
|
||||
|
||||
export default createStore({
|
||||
plugins: [createPersistedState({
|
||||
storage: window.sessionStorage,
|
||||
})],
|
||||
state: {
|
||||
makes: [],
|
||||
models: [],
|
||||
styles: [],
|
||||
year: '',
|
||||
make: '',
|
||||
model: '',
|
||||
style: '',
|
||||
slideTransition: 'none',
|
||||
carImg: "https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg",
|
||||
blurImg: true
|
||||
},
|
||||
mutations: {
|
||||
updateYear(state, data){
|
||||
state.year = data.year;
|
||||
state.makes = data.makes.data.Result;
|
||||
state.slideTransition = 'slide'
|
||||
},
|
||||
updateMake(state, data){
|
||||
state.make = data.make;
|
||||
state.models = data.models.data.Result;
|
||||
state.slideTransition = 'slide';
|
||||
},
|
||||
updateModel(state, data){
|
||||
state.model = data.model;
|
||||
state.styles = data.styles.data.Result;
|
||||
state.slideTransition = 'slide';
|
||||
},
|
||||
updateStyle(state, data){
|
||||
state.style = data.style;
|
||||
state.carImg = "https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg";
|
||||
state.blurImg = false;
|
||||
state.slideTransition = 'slide';
|
||||
},
|
||||
removeStyle(state) {
|
||||
state.style = '';
|
||||
state.blurImg = true;
|
||||
state.carImg = 'https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg'
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async selectYear(context, year){
|
||||
const makes = await axios.get(`https://mockey.qa.sagaws.net/service/makes/year=${year}`);
|
||||
context.commit('updateYear', {year, makes});
|
||||
router.push(`/select-make?year=${year}`);
|
||||
},
|
||||
async selectMake({commit, state}, make){
|
||||
const models = await axios.get(`https://mockey.qa.sagaws.net/service/models/year=${state.year}/make=${make}`);
|
||||
commit('updateMake', {make, models});
|
||||
router.push(`/select-model?year=${state.year}&make=${make}`);
|
||||
},
|
||||
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}`);
|
||||
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(`/damage?year=${state.year}&make=${state.make}&model=${state.model}&style=${style}`);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
Loading…
Reference in a new issue