Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

OnboardingView.vue 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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. :is='step.component'
  13. :question='step'
  14. :answered='answered'
  15. :responses='responses'
  16. :survey='survey'
  17. :currentStep='currentStep'
  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 { fetchUserByEmail } from '../services/user.service.js'
  36. import {
  37. fetchProfilesByUserId,
  38. fetchProfileByProfileId,
  39. } from '../services/profile.service.js'
  40. import { surveyFactory } from '@/utils'
  41. import stepViews from '@/components/onboarding'
  42. import SurveyCompleteView from './SurveyCompleteView.vue'
  43. let sessionToken = null
  44. let accessToken = null
  45. // import savesurveybyprofileid - call it on submit
  46. // paginate to save every steps answers
  47. export default {
  48. name: 'OnboardingView',
  49. components: {
  50. ...stepViews,
  51. SurveyCompleteView,
  52. },
  53. data: () => ({
  54. answered: {},
  55. aspectQuestions: [],
  56. responses: [],
  57. currentStep: 0,
  58. currentProfileId: null,
  59. survey: null,
  60. invalidResponse: false,
  61. userEmail: null,
  62. emailIsRegistered: false,
  63. authenticator: {},
  64. }),
  65. async created() {
  66. this.survey = await surveyFactory.createSurvey()
  67. this.authenticator = new Authenticator()
  68. // TODO: Once tokens are coming through headers, refactor all of this into methods, etc.
  69. // TODO: Consider switch/case() depending on what tokens exist/are valid...
  70. const sessionToken = this.grabStoredCookie('siimee_session')
  71. if (!sessionToken) {
  72. console.warn('WARNING :=> sessionToken not in stored Cookies')
  73. this.goToStep(0)
  74. }
  75. // const accessToken = this.grabStoredCookie('siimee_access')
  76. // if (!accessToken) {
  77. // check if sessionToken is valid jwt
  78. // // blow up
  79. // }
  80. let sessionData
  81. if (sessionToken) {
  82. sessionData = await this.authenticator.validateSession(sessionToken)
  83. console.log('sessionData :=>', sessionData)
  84. }
  85. // if (sessionData && !accessToken) {
  86. if (sessionData) {
  87. this.userEmail = sessionData.payload.email
  88. this.emailIsRegistered =
  89. await this.authenticator.checkIfEmailIsRegistered(
  90. this.userEmail,
  91. )
  92. }
  93. // TODO: EVERY ROUTE WE HIT AFTER THIS HAS TO BE AUTHENTICATED
  94. // ACCESS TOKEN WORKS
  95. if (this.emailIsRegistered) {
  96. const user = await fetchUserByEmail(this.userEmail)
  97. const userId = user.user_id
  98. const profilesFromUserId = await fetchProfilesByUserId(userId)
  99. let profileId
  100. if (profilesFromUserId.length === 1) {
  101. profileId = profilesFromUserId[0].profile_id
  102. this.currentProfileId = profileId
  103. }
  104. // if (!profileId) {
  105. // throw new Error
  106. // }
  107. const profile = await fetchProfileByProfileId(profileId)
  108. profile.responses.forEach(response => {
  109. this.responses.push({
  110. response_key_id: response.response_key_id,
  111. val: response.val,
  112. })
  113. })
  114. this.currentStep = this.responses.length + 3
  115. this.goToStep(this.currentStep)
  116. } else {
  117. // TODO: CHECK SESSION
  118. }
  119. },
  120. methods: {
  121. onSubmit() {
  122. console.log(JSON.stringify(this.answered))
  123. },
  124. async goToStep(num) {
  125. this.currentStep = num
  126. },
  127. grabStoredCookie(cookieKey) {
  128. const cookies = document.cookie
  129. .split('; ')
  130. .reduce((prev, current) => {
  131. const [name, ...value] = current.split('=')
  132. prev[name] = value.join('=')
  133. return prev
  134. }, {})
  135. const cookieVal =
  136. cookieKey in cookies ? cookies[`${cookieKey}`] : undefined
  137. return cookieVal
  138. },
  139. async updateAnswers(payload) {
  140. if (payload) {
  141. // this.invalidResponse = false
  142. const k = payload.question.survey_stage
  143. this.answered[k] = payload.input
  144. if (!this.survey.validateAnswer(payload)) {
  145. this.invalidResponse = true
  146. return
  147. }
  148. // once validated, don't log password in answered object
  149. this.answered[k] = k === 'password' ? undefined : payload.input
  150. // formats initial responses for response table
  151. const response = {}
  152. response.response_key_id = payload.question.response_key_id
  153. response.val = payload.input
  154. this.responses.push(response)
  155. console.log('this.answered :=>', this.answered)
  156. console.log('this.responses :=>', this.responses)
  157. // sends latest survey response to db
  158. if (this.currentProfileId) {
  159. surveyFactory.addNewSurveyAnswer(
  160. this.responses[this.responses.length - 1],
  161. this.currentProfileId,
  162. )
  163. }
  164. if (k === 'aspects') return
  165. }
  166. if (this.currentStep > this.survey.steps.length) {
  167. this.onSubmit(this.answered)
  168. } else {
  169. this.goToStep(this.currentStep + 1)
  170. }
  171. },
  172. },
  173. }
  174. </script>
  175. <style lang="sass">
  176. .view--onboarding
  177. width: 100%
  178. max-width: 428px
  179. background-color: #fff
  180. color: #1F2024
  181. font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif
  182. margin: 0 auto
  183. article
  184. height: 100vh
  185. .answers
  186. text-align: center
  187. .w-button
  188. display: flex
  189. width: 315px
  190. height: 60px
  191. border-radius: 6
  192. background-color: #D5D5D5
  193. color: #1F2024
  194. margin: 11px auto
  195. font-weight: bold
  196. font-size: 16px
  197. text-transform: uppercase
  198. &.next-btn
  199. border-radius: 6px
  200. background-color: #5BA626
  201. color: #1F2024
  202. height: 50px
  203. width: 315px
  204. font-size: 18px
  205. padding: 7px
  206. .w-card
  207. background-color: #1F2024
  208. justify-content: center
  209. align-items: center
  210. width: 100%
  211. h3
  212. text-transform: uppercase
  213. text-align: center
  214. font-size: 28px
  215. font-weight: bold
  216. color: white
  217. margin-top: 88px
  218. p
  219. color: white
  220. font-size: 18px
  221. padding: 11px
  222. text-align: center
  223. margin: 22px auto
  224. font-weight: bold
  225. input
  226. display: flex
  227. width: 315px
  228. height: 60px
  229. padding: 11px
  230. border-radius: 6
  231. background-color: #D5D5D5
  232. color: #1F2024
  233. margin: 11px auto
  234. font-weight: bold
  235. font-size: 16px
  236. .w-select
  237. padding: 11px
  238. color: #1F2024
  239. .search-type
  240. color: #1F2024
  241. height: 50px
  242. &.question
  243. p
  244. font-size: 18px
  245. text-align: left
  246. margin: 7px auto
  247. font-weight: normal
  248. section
  249. p
  250. margin: 0
  251. font-weight: bold
  252. text-transform: capitalize
  253. .w-radio__input
  254. &.primary
  255. background-color: #FFFFFF
  256. border: #BCC5D3 1px solid
  257. .w-card__content
  258. .w-button
  259. height: 50px
  260. background-color: #5BA626
  261. </style>