You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OnboardingView.vue 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template lang="pug">
  2. main.view--onboarding
  3. article(
  4. style='display: flex; flex-direction: column; align-items: center'
  5. v-if='currentStep !== survey.steps.length'
  6. )
  7. .answers(v-for='(value, key) in answered')
  8. span(v-if='key == "name" && value && currentStep == 2') Hi {{ value }}!
  9. br
  10. .step(v-for='(step, i) in survey.steps')
  11. component(
  12. :answered='answered'
  13. :currentStep='currentStep'
  14. :is='step.component'
  15. :question='step'
  16. :responses='responses'
  17. :survey='survey'
  18. :surveyStepsCount='survey.steps.length'
  19. @handle-submit='onSubmit'
  20. @update-answers='updateAnswers'
  21. v-if='step && currentStep == i'
  22. )
  23. .invalidResponseMessage(
  24. style='text-align: center'
  25. v-if='invalidResponse'
  26. )
  27. p {{ survey.steps[currentStep].invalidInputPrompt }}
  28. footer
  29. p(v-if='currentStep != 0') You have completed: {{ currentStep }} / {{ survey.steps.length }} survey steps
  30. article(v-else)
  31. SurveyCompleteView(:answers='answered' :surveySteps='survey.steps')
  32. </template>
  33. <script>
  34. import { Authenticator } from '../services/auth.service.js'
  35. import { surveyFactory } from '@/utils'
  36. import stepViews from '@/components/onboarding'
  37. import SurveyCompleteView from './SurveyCompleteView.vue'
  38. let hashedAccessToken = null
  39. let currentProfileId = null
  40. // import savesurveybyprfileid - call it on submit
  41. // paginate to save every steps answers
  42. export default {
  43. name: 'OnboardingView',
  44. components: {
  45. ...stepViews,
  46. SurveyCompleteView,
  47. },
  48. data: () => ({
  49. answered: {},
  50. aspectQuestions: [],
  51. responses: [],
  52. currentStep: 0,
  53. survey: null,
  54. invalidResponse: false,
  55. authenticator: {},
  56. }),
  57. async created() {
  58. this.survey = await surveyFactory.createSurvey()
  59. this.authenticator = new Authenticator()
  60. hashedAccessToken = this.grabStoredCookie('siimee_access')
  61. try {
  62. const sessionData = await this.verifySession(hashedAccessToken)
  63. currentProfileId = sessionData.profileId
  64. this.responses = sessionData.responses
  65. this.currentStep = this.responses.length + 3
  66. this.goToStep(this.currentStep)
  67. } catch (err) {
  68. console.error('ERROR :=>', err)
  69. this.goToStep(0)
  70. }
  71. },
  72. methods: {
  73. onSubmit() {
  74. console.log(JSON.stringify(this.answered))
  75. },
  76. async goToStep(num) {
  77. this.currentStep = num
  78. },
  79. grabStoredCookie(cookieKey) {
  80. const cookies = document.cookie
  81. .split('; ')
  82. .reduce((prev, current) => {
  83. const [name, ...value] = current.split('=')
  84. prev[name] = value.join('=')
  85. return prev
  86. }, {})
  87. const cookieVal =
  88. cookieKey in cookies ? cookies[`${cookieKey}`] : undefined
  89. return cookieVal
  90. },
  91. async verifySession(hashedAccessToken) {
  92. if (!hashedAccessToken)
  93. return console.warn('WARNING :=> accessToken is not defined')
  94. const validatedToken = await this.authenticator.validateSession(
  95. hashedAccessToken,
  96. )
  97. if (validatedToken.error) {
  98. throw new Error(validatedToken.error)
  99. } else {
  100. return validatedToken
  101. }
  102. },
  103. async updateAnswers(payload) {
  104. if (payload) {
  105. const k = payload.question.survey_stage
  106. this.answered[k] = payload.input
  107. // Once validated, don't log password in answered object
  108. this.answered[k] = k === 'password' ? undefined : payload.input
  109. // Hacky WorkAround for Validating Answers
  110. if (!this.survey.validateAnswer(payload)) {
  111. this.invalidResponse = true
  112. return
  113. }
  114. // Formats initial responses for response table
  115. const response = {}
  116. response.response_key_id = payload.question.response_key_id
  117. response.val = payload.input
  118. this.responses.push(response)
  119. if (k === 'aspects') return
  120. }
  121. // NOTE: If user has finished minimum profile creation,
  122. // Adds survey answers to responses table and verifies tokens on each step
  123. if (currentProfileId) {
  124. await surveyFactory.addNewSurveyAnswer(
  125. this.responses[this.responses.length - 1],
  126. currentProfileId,
  127. )
  128. try {
  129. await this.verifySession(hashedAccessToken)
  130. } catch (err) {
  131. this.currentStep = 0
  132. this.goToStep(this.currentStep)
  133. throw new Error(err)
  134. }
  135. }
  136. if (this.currentStep > this.survey.steps.length) {
  137. this.onSubmit(this.answered)
  138. } else {
  139. this.goToStep(this.currentStep + 1)
  140. }
  141. },
  142. },
  143. }
  144. </script>
  145. <style lang="sass">
  146. .view--onboarding
  147. width: 100%
  148. max-width: 428px
  149. background-color: #fff
  150. color: #1F2024
  151. font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif
  152. margin: 0 auto
  153. article
  154. height: 100vh
  155. .answers
  156. text-align: center
  157. .w-button
  158. display: flex
  159. width: 315px
  160. height: 60px
  161. border-radius: 6
  162. background-color: #D5D5D5
  163. color: #1F2024
  164. margin: 11px auto
  165. font-weight: bold
  166. font-size: 16px
  167. text-transform: uppercase
  168. &.next-btn
  169. border-radius: 6px
  170. background-color: #5BA626
  171. color: #1F2024
  172. height: 50px
  173. width: 315px
  174. font-size: 18px
  175. padding: 7px
  176. .w-card
  177. background-color: #1F2024
  178. justify-content: center
  179. align-items: center
  180. width: 100%
  181. h3
  182. text-transform: uppercase
  183. text-align: center
  184. font-size: 28px
  185. font-weight: bold
  186. color: white
  187. margin-top: 88px
  188. p
  189. color: white
  190. font-size: 18px
  191. padding: 11px
  192. text-align: center
  193. margin: 22px auto
  194. font-weight: bold
  195. input
  196. display: flex
  197. width: 315px
  198. height: 60px
  199. padding: 11px
  200. border-radius: 6
  201. background-color: #D5D5D5
  202. color: #1F2024
  203. margin: 11px auto
  204. font-weight: bold
  205. font-size: 16px
  206. .w-select
  207. padding: 11px
  208. color: #1F2024
  209. .search-type
  210. color: #1F2024
  211. height: 50px
  212. &.question
  213. p
  214. font-size: 18px
  215. text-align: left
  216. margin: 7px auto
  217. font-weight: normal
  218. section
  219. p
  220. margin: 0
  221. font-weight: bold
  222. text-transform: capitalize
  223. .w-radio__input
  224. &.primary
  225. background-color: #FFFFFF
  226. border: #BCC5D3 1px solid
  227. .w-card__content
  228. .w-button
  229. height: 50px
  230. background-color: #5BA626
  231. </style>