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.9KB

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