Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

OnboardingView.vue 7.9KB

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