| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- <template lang="pug">
- main.view--onboarding
- article(
- style='display: flex; flex-direction: column; align-items: center'
- v-if='currentStep !== survey.steps.length'
- )
- .answers(v-for='(value, key) in answered')
- span(v-if='key == "name" && value && currentStep == 2') Hi {{ value }}!
- br
- .step(v-for='(step, i) in survey.steps')
- component(
- :is='step.component'
- :question='step'
- :answered='answered'
- :responses='responses'
- :survey='survey'
- :currentStep='currentStep'
- :surveyStepsCount='survey.steps.length'
- @handle-submit='onSubmit'
- @update-answers='updateAnswers'
- v-if='step && currentStep == i'
- )
- .invalidResponseMessage(
- style='text-align: center'
- v-if='invalidResponse'
- )
- p {{ survey.steps[currentStep].invalidInputPrompt }}
-
- footer
- p(v-if='currentStep != 0') You have completed: {{ currentStep }} / {{ survey.steps.length }} survey steps
-
- article(v-else)
- SurveyCompleteView(:answers='answered' :surveySteps='survey.steps' :currentProfileId='currentProfileId')
- </template>
-
- <script>
- import { Authenticator } from '../services/auth.service.js'
- import { surveyFactory } from '@/utils'
- import { currentProfile } from '../services/'
- import stepViews from '@/components/onboarding'
- import SurveyCompleteView from './SurveyCompleteView.vue'
-
- // import savesurveybyprofileid - call it on submit
- // paginate to save every steps answers
- export default {
- name: 'OnboardingView',
- components: {
- ...stepViews,
- SurveyCompleteView,
- },
- data: () => ({
- answered: {},
- aspectQuestions: [],
- responses: [],
- currentStep: 0,
- survey: null,
- currentProfileId: null,
- invalidResponse: false,
- authenticator: {},
- sessionToken: '',
- accessToken: '',
- }),
- computed: {
- cP() {
- return currentProfile ? currentProfile : null
- },
- },
- async created() {
- this.survey = await surveyFactory.createSurvey()
- this.authenticator = new Authenticator()
-
- if (document.cookie.length) {
- // TODO: Heavy Refactor needed, obvious code smells
- // BUG: NEEDS BROWSER REFRESH AFTER VERIFYING EMAIL AND REDIRECT BACK TO ONBOARDING
- // BUG: CURRENT IMPLEMENTATION HAS COOKIES THAT NEVER EXPIRE
- const siimeeAnswered = this.grabCookie('siimee_answered')
- const myCurrentStep = this.grabCookie('siimee_current_step')
- const myCurrentAnswers = this.grabCookie('siimee_cache_answered')
- const myCurrentResponses = this.grabCookie('siimee_cache_responses')
- this.sessionToken = this.grabCookie('siimee_session') || ''
- // TODO: START REFACTOR HERE...
- if (siimeeAnswered) {
- const siimeeAnswers = JSON.parse(siimeeAnswered)
- const sessionTokenIsValid =
- await this.authenticator.validateJwt(this.sessionToken)
- this.accessToken = this.grabCookie('siimee_access')
- if (sessionTokenIsValid.isValid) {
- this.answered = {
- name: siimeeAnswers.name,
- email: siimeeAnswers.email,
- seeking: siimeeAnswers.seeking,
- }
- this.currentProfileId = siimeeAnswers.profile_id
- this.responses = [
- { response_key_id: 8, val: siimeeAnswers.email },
- { response_key_id: 7, val: siimeeAnswers.name },
- { response_key_id: 11, val: siimeeAnswers.seeking },
- ]
- document.cookie = `siimee_current_step=${this.currentStep}; max-age=600 ; path=/onboarding ; secure`
- document.cookie = `siimee_cache_answered=${JSON.stringify(
- this.answered,
- )}; max-age=600 ; path=/onboarding ; secure`
- document.cookie = `siimee_cache_responses=${JSON.stringify(
- this.responses,
- )}; max-age=600 ; path=/onboarding ; secure`
- document.cookie = 'siimee_answered='
- this.currentStep = 6
- this.goToStep(this.currentStep)
- }
- } else if (myCurrentStep) {
- this.answered = JSON.parse(myCurrentAnswers)
- this.responses = JSON.parse(myCurrentResponses)
- this.currentStep = myCurrentStep
- this.goToStep(Number(myCurrentStep) + 1)
- } else {
- this.currentStep = 0
- this.goToStep(this.currentStep)
- }
- }
- },
- methods: {
- onSubmit() {
- console.log(JSON.stringify(this.answered))
- },
- async goToStep(num, maxAge) {
- maxAge = 600 // temp measure
- document.cookie = `siimee_current_step=${Number(
- this.currentStep,
- )}; max-age=${maxAge} ; path=/onboarding ; secure`
- document.cookie = `siimee_cache_answered=${JSON.stringify(
- this.answered,
- )}; max-age=${maxAge} ; path=/onboarding ; secure`
- document.cookie = `siimee_cache_responses=${JSON.stringify(
- this.responses,
- )}; max-age=${maxAge} ; path=/onboarding ; secure`
-
- if (num > 6) {
- this.validateAccessToken()
- }
- this.currentStep = num
- },
- // TODO: Refactor to use cookie's max-age attribute instead of network call for jwt auth
- async validateAccessToken() {
- const validatedAccessToken = await this.authenticator.validateJwt(
- this.accessToken,
- )
- if (!validatedAccessToken || !validatedAccessToken.isValid) {
- const sessionTokenIsValid = await this.validateSessionToken()
- if (!sessionTokenIsValid) {
- this.goToStep(0)
- }
- }
- },
- async validateSessionToken() {
- const validatedSessionToken = await this.authenticator.validateJwt(
- this.sessionToken,
- )
- if (!validatedSessionToken || validatedSessionToken.isValid) {
- this.accessToken = await this.authenticator.generateJwt({
- ...this.answered,
- expiration: 60 * 3,
- })
- return true
- } else return false
- },
- grabCookie(cookieKey) {
- const cookies = document.cookie
- .split('; ')
- .reduce((prev, current) => {
- const [name, ...value] = current.split('=')
- prev[name] = value.join('=')
- return prev
- }, {})
- const cookieVal =
- cookieKey in cookies ? cookies[`${cookieKey}`] : undefined
- return cookieVal
- },
- async updateAnswers(payload) {
- if (payload) {
- // this.invalidResponse = false
- const k = payload.question.survey_stage
- this.answered[k] = payload.input
-
- if (!this.survey.validateAnswer(payload)) {
- this.invalidResponse = true
- return
- }
-
- // once validated, don't log password in answered object
- this.answered[k] = k === 'password' ? undefined : payload.input
-
- // formats initial responses for response table
- const response = {}
- response.response_key_id = payload.question.response_key_id
- response.val = payload.input
- this.responses.push(response)
-
- // sends latest survey response to db
- if (this.currentProfileId) {
- surveyFactory.addNewSurveyAnswer(
- this.responses[this.responses.length - 1],
- this.currentProfileId,
- )
- }
-
- if (k === 'aspects') return
- }
- if (this.currentStep > this.survey.steps.length) {
- this.onSubmit(this.answered)
- } else {
- this.goToStep(this.currentStep + 1)
- }
- },
- },
- }
- </script>
-
- <style lang="sass">
- .view--onboarding
- width: 100%
- max-width: 428px
- background-color: #fff
- color: #1F2024
- font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif
- margin: 0 auto
-
- article
- height: 100vh
-
- .answers
- text-align: center
-
- .w-button
- display: flex
- width: 315px
- height: 60px
- border-radius: 6
- background-color: #D5D5D5
- color: #1F2024
- margin: 11px auto
- font-weight: bold
- font-size: 16px
- text-transform: uppercase
- &.next-btn
- border-radius: 6px
- background-color: #5BA626
- color: #1F2024
- height: 50px
- width: 315px
- font-size: 18px
- padding: 7px
-
- .w-card
- background-color: #1F2024
- justify-content: center
- align-items: center
- width: 100%
-
-
- h3
- text-transform: uppercase
- text-align: center
- font-size: 28px
- font-weight: bold
- color: white
- margin-top: 88px
-
- p
- color: white
- font-size: 18px
- padding: 11px
- text-align: center
- margin: 22px auto
- font-weight: bold
-
- input
- display: flex
- width: 315px
- height: 60px
- padding: 11px
- border-radius: 6
- background-color: #D5D5D5
- color: #1F2024
- margin: 11px auto
- font-weight: bold
- font-size: 16px
-
- .w-select
- padding: 11px
- color: #1F2024
-
- .search-type
- color: #1F2024
- height: 50px
-
- &.question
- p
- font-size: 18px
- text-align: left
- margin: 7px auto
- font-weight: normal
- section
- p
- margin: 0
- font-weight: bold
- text-transform: capitalize
- .w-radio__input
-
- &.primary
- background-color: #FFFFFF
- border: #BCC5D3 1px solid
-
- .w-card__content
- .w-button
- height: 50px
- background-color: #5BA626
- </style>
|