Explorar el Código

:poop: pre-refactor survery

tabs-content
j hace 3 años
padre
commit
497d3299b3

+ 8346
- 11
backend/package-lock.json
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 11
- 9
frontend/src/components/onboarding/Aspects.vue Ver fichero

1
 <template lang="pug">
1
 <template lang="pug">
2
-form.questionnaire(@submit.prevent='this.$emit("handle-submit")')
3
-p(v-for='question in aspectQuestions')
4
-    QuestionResponse(
5
-        :question='question' 
6
-        @updated='updateRadio'
7
-        @updateIsAnswered='updateIsAnswered'
8
-        @update-all='updateAll'
9
-        v-if='question.isBeingAnswered' 
10
-    )
2
+p {{ aspectQuestions }}
3
+//- form.questionnaire(@submit.prevent='this.$emit("handle-submit")')
4
+
5
+//- p(v-for='question in aspectQuestions')
6
+//-     QuestionResponse(
7
+//-         :question='question'
8
+//-         @updated='updateRadio'
9
+//-         @updateIsAnswered='updateIsAnswered'
10
+//-         @update-all='updateAll'
11
+//-         v-if='question.isBeingAnswered'
12
+//-     )
11
 </template>
13
 </template>
12
 
14
 
13
 <script>
15
 <script>

+ 33
- 10
frontend/src/components/onboarding/FormInput.vue Ver fichero

1
 <template lang="pug">
1
 <template lang="pug">
2
 .form-input
2
 .form-input
3
-    span(style='text-align:center;') {{ parsedPrompt.start }}
3
+    span(style='text-align: center') {{ parsedPrompt.start }}
4
     br
4
     br
5
     br
5
     br
6
-    span(style='text-align:center;') {{ parsedPrompt.mid }}
7
-    input(v-if="question.survey_stage !== 'image' && question.survey_stage !== 'blurb' && question.survey_stage !== 'password'" :placeholder='question.placeholder' type='text' v-model='input')
8
-    input.pass(v-else-if="question.survey_stage === 'password'" :placeholder='question.placeholder' type='password' v-model='input' style="-webkit-text-security: circle")
9
-    w-button.ma1.grow(v-else-if="question.survey_stage === 'image'" @click="submitImage") UPLOAD IMAGE
10
-    textarea(v-else-if="question.survey_stage === 'blurb'" rows="4" cols="50" v-model='input' :placeholder="`${question.placeholder}`")
11
-    span(style='text-align:center;') {{ parsedPrompt.end }}
12
-    w-button.ma1.grow(@click="handleSubmit({ question, input })") NEXT
13
-    
6
+    span(style='text-align: center') {{ parsedPrompt.mid }}
7
+    input(
8
+        :placeholder='question.placeholder'
9
+        @keyup.enter='handleSubmit({ question, input })'
10
+        type='text'
11
+        v-if='question.survey_stage !== "image" && question.survey_stage !== "blurb" && question.survey_stage !== "password"'
12
+        v-model='input'
13
+    )
14
+    input.pass(
15
+        :placeholder='question.placeholder'
16
+        @keyup.enter='handleSubmit({ question, input })'
17
+        style='-webkit-text-security: circle'
18
+        type='password'
19
+        v-else-if='question.survey_stage === "password"'
20
+        v-model='input'
21
+    )
22
+    w-button.ma1.grow(
23
+        @click='submitImage'
24
+        v-else-if='question.survey_stage === "image"'
25
+    ) UPLOAD IMAGE
26
+    textarea(
27
+        :placeholder='`${question.placeholder}`'
28
+        @keyup.enter='handleSubmit({ question, input })'
29
+        cols='50'
30
+        rows='4'
31
+        v-else-if='question.survey_stage === "blurb"'
32
+        v-model='input'
33
+    )
34
+    span(style='text-align: center') {{ parsedPrompt.end }}
35
+    w-button.ma1.grow(@click='handleSubmit({ question, input })') NEXT
14
 </template>
36
 </template>
15
 <script>
37
 <script>
16
 export default {
38
 export default {
27
         parsedPrompt: {},
49
         parsedPrompt: {},
28
     }),
50
     }),
29
     created() {
51
     created() {
30
-        const parsedPromptArr = this.question.response_key_prompt.split('[break]')
52
+        const parsedPromptArr =
53
+            this.question.response_key_prompt.split('[break]')
31
         this.parsedPrompt.start = parsedPromptArr[0]
54
         this.parsedPrompt.start = parsedPromptArr[0]
32
         this.parsedPrompt.mid = parsedPromptArr[1]
55
         this.parsedPrompt.mid = parsedPromptArr[1]
33
         this.parsedPrompt.end = parsedPromptArr[2]
56
         this.parsedPrompt.end = parsedPromptArr[2]

+ 33
- 23
frontend/src/components/onboarding/QuestionResponse.vue Ver fichero

1
 <template lang="pug">
1
 <template lang="pug">
2
 w-card.question
2
 w-card.question
3
-    p {{question.question}} 
3
+    p {{ question }}
4
     section.radio-buttons.w-flex.row.justify-space-between
4
     section.radio-buttons.w-flex.row.justify-space-between
5
-        p(v-for="label in question.labels") {{label}}
6
-    w-radios.w-flex.row.justify-space-between(@update:model-value="onUpdate" :items="radioItems" color="red")
7
-    w-button.ma1.grow(v-if='question.id !== aspectsCount' @click="updateAnswers") NEXT
8
-    w-button.ma1.grow(v-else @click="updateAll") SUBMIT ANSWERS
5
+        p(v-for='label in question.labels') {{ label }}
6
+    w-radios.w-flex.row.justify-space-between(
7
+        :items='radioItems'
8
+        @update:model-value='onUpdate'
9
+        color='red'
10
+    )
11
+    w-button.ma1.grow(
12
+        @click='handleSubmit'
13
+        v-if='question.id !== aspectsCount'
14
+    ) NEXT
15
+    w-button.ma1.grow(@click='updateAll' v-else) SUBMIT ANSWERS
9
     p(v-if='noChoiceMade') Tough choices, we know! Just answer to the best of your ability. The team over at Siimee values the answers you provide us so that we can show you results catered to your specific needs.
16
     p(v-if='noChoiceMade') Tough choices, we know! Just answer to the best of your ability. The team over at Siimee values the answers you provide us so that we can show you results catered to your specific needs.
10
 </template>
17
 </template>
11
 
18
 
19
             required: true,
26
             required: true,
20
         },
27
         },
21
     },
28
     },
22
-    emits: ['updated', 'update-is-answered', 'update-all'],
29
+    emits: ['updated', 'update-answers', 'update-all'],
23
     data: () => ({
30
     data: () => ({
24
-        radioItems: [
25
-            { answer: 1 },
26
-            { answer: 2 },
27
-            { answer: 3 },
28
-            { answer: 4 },
29
-            { answer: 5 },
30
-        ],
31
+        radioItems: [1, 2, 3, 4, 5],
31
         isAnswered: false,
32
         isAnswered: false,
33
+        answer: null,
32
         noChoiceMade: null,
34
         noChoiceMade: null,
33
-        aspectsCount: aspectsArr.length
35
+        aspectsCount: aspectsArr.length,
34
     }),
36
     }),
35
     methods: {
37
     methods: {
36
-        onUpdate(e) {
38
+        onUpdate(index) {
37
             this.isAnswered = true
39
             this.isAnswered = true
38
             this.noChoiceMade = false
40
             this.noChoiceMade = false
39
-            this.$emit('updated', { ...this.question, answer: e + 1 })
41
+            this.answer = this.radioItems[index]
42
+        },
43
+        handleSubmit() {
44
+            const payload = {
45
+                question: this.question,
46
+                input: this.answer,
47
+            }
48
+            console.log('updated payload :>> ', payload)
49
+            this.$emit('update-answers', payload)
40
         },
50
         },
41
         updateAnswers() {
51
         updateAnswers() {
42
-            this.isAnswered ?
43
-            this.$emit('update-is-answered', this.question.id) :
44
-            this.noChoiceMade = true
52
+            this.isAnswered
53
+                ? this.$emit('update-answers', this.question)
54
+                : (this.noChoiceMade = true)
45
         },
55
         },
46
         updateAll() {
56
         updateAll() {
47
-            this.isAnswered ?
48
-            this.$emit('update-all') :
49
-            this.noChoiceMade = true
50
-        }
57
+            this.isAnswered
58
+                ? this.$emit('update-all')
59
+                : (this.noChoiceMade = true)
60
+        },
51
     },
61
     },
52
 }
62
 }
53
 </script>
63
 </script>

+ 2
- 0
frontend/src/components/onboarding/index.js Ver fichero

10
 import FormInput from './FormInput.vue'
10
 import FormInput from './FormInput.vue'
11
 import FormTags from './FormTags.vue'
11
 import FormTags from './FormTags.vue'
12
 import FormDropdown from './FormDropdown.vue'
12
 import FormDropdown from './FormDropdown.vue'
13
+import QuestionResponse from './QuestionResponse.vue'
13
 
14
 
14
 export default {
15
 export default {
15
     Splash,
16
     Splash,
24
     FormDropdown,
25
     FormDropdown,
25
     FormTags,
26
     FormTags,
26
     FormInput,
27
     FormInput,
28
+    QuestionResponse,
27
 }
29
 }

+ 0
- 31
frontend/src/entities/survey/survey.answer.schema.js Ver fichero

1
-import Joi from 'joi'
2
-
3
-/**
4
- * answers schema object
5
- */
6
-const answersSchema = {
7
-    type: 'object',
8
-    properties: Joi.object().keys({
9
-        name: Joi.string().required(),
10
-        email: Joi.string().email({ minDomainSegments: 2, tlds: false }),
11
-        // TODO: Refine password regex to have more secure requirements
12
-        password: Joi.string().min(10).max(30).pattern(new RegExp('[a-zA-Z0-9]+')),
13
-        // TODO: Change if going international (only works in usa)
14
-        zipcode: Joi.string().min(5).max(5).pattern(new RegExp('^[0-9]{5}$')),
15
-        seeking: Joi.string(),
16
-        urgency: Joi.string(),
17
-        presence: Joi.string(),
18
-        duration: Joi.string(),
19
-        pronouns: Joi.string(),
20
-        language: Joi.string(),
21
-        image: Joi.any(),
22
-        distance: Joi.string(),
23
-        blurb: Joi.string(),
24
-        aspects: Joi.array().items(Joi.number().allow(null))
25
-    }),
26
-    validate(instance) {
27
-        return this.properties.validate(instance)
28
-    },
29
-}
30
-
31
-export { answersSchema }

+ 15
- 5
frontend/src/entities/survey/survey.js Ver fichero

1
 /** @module survey/survey */
1
 /** @module survey/survey */
2
 import { _baseRecord } from '../index.js'
2
 import { _baseRecord } from '../index.js'
3
 import { surveySchema } from './survey.schema.js'
3
 import { surveySchema } from './survey.schema.js'
4
-import { answersSchema } from './survey.answer.schema.js'
4
+import { answerValidator } from './survey.answer.validator.js'
5
 import { aspectsArr } from '../../utils/lang.js'
5
 import { aspectsArr } from '../../utils/lang.js'
6
 
6
 
7
 const SCORED = aspectsArr
7
 const SCORED = aspectsArr
37
         /**  Fields */
37
         /**  Fields */
38
         this.steps = [...questionSteps] // ! required
38
         this.steps = [...questionSteps] // ! required
39
         this.aspectQuestions = _formatAspectQuestions(this.steps)
39
         this.aspectQuestions = _formatAspectQuestions(this.steps)
40
-        console.log('this.aspectQuestions: ', JSON.stringify(this.aspectQuestions))
40
+        console.log(
41
+            'this.aspectQuestions: ',
42
+            JSON.stringify(this.aspectQuestions),
43
+        )
41
     }
44
     }
42
 
45
 
43
-    validateAnswer(answer) {
44
-        const validate = answersSchema.validate(answer)
46
+    validateAnswer(payload) {
47
+        const { question, input } = payload
48
+
49
+        // Continue our ugly hacks
50
+        const validationType =
51
+            question.category == 'aspect'
52
+                ? question.category
53
+                : question.survey_stage
54
+        const validate = answerValidator[validationType].validate(input)
45
         if (validate.error) {
55
         if (validate.error) {
46
             console.error(`error: ${validate.error}`)
56
             console.error(`error: ${validate.error}`)
47
         }
57
         }
48
-        return !validate.error ? true: false
58
+        return !validate.error ? true : false
49
     }
59
     }
50
 
60
 
51
     isValid() {
61
     isValid() {

+ 48
- 23
frontend/src/utils/lang.js Ver fichero

7
     usa: {
7
     usa: {
8
         splash: 'splash',
8
         splash: 'splash',
9
         name: 'name',
9
         name: 'name',
10
-        email: 'email',
10
+        aspect01: 'aspect-1',
11
+        aspect02: 'aspect-2',
12
+        aspect03: 'aspect-3',
11
         password: 'password',
13
         password: 'password',
12
         zipcode: 'zipcode',
14
         zipcode: 'zipcode',
13
         seeking: 'seeking',
15
         seeking: 'seeking',
14
         urgency: 'urgency',
16
         urgency: 'urgency',
17
+        aspect04: 'aspect-4',
18
+        aspect05: 'aspect-5',
19
+        aspect06: 'aspect-6',
20
+        email: 'email',
15
         presence: 'presence',
21
         presence: 'presence',
16
         duration: 'duration',
22
         duration: 'duration',
17
         pronouns: 'pronouns',
23
         pronouns: 'pronouns',
19
         image: 'image',
25
         image: 'image',
20
         distance: 'distance',
26
         distance: 'distance',
21
         blurb: 'blurb',
27
         blurb: 'blurb',
22
-        aspects: 'aspects',
23
         // experience: 'experience',
28
         // experience: 'experience',
24
         // roles: 'role',
29
         // roles: 'role',
25
     },
30
     },
27
 
32
 
28
 const promptToComponent = {
33
 const promptToComponent = {
29
     splash: 'Splash',
34
     splash: 'Splash',
35
+    aspect: 'QuestionResponse', // Special hacky case
30
     name: 'FormInput',
36
     name: 'FormInput',
31
     email: 'FormInput',
37
     email: 'FormInput',
32
     password: 'FormInput',
38
     password: 'FormInput',
40
     image: 'FormInput',
46
     image: 'FormInput',
41
     distance: 'FormInput',
47
     distance: 'FormInput',
42
     blurb: 'FormInput',
48
     blurb: 'FormInput',
43
-    aspects: 'Aspects',
44
     // experience: 'FormTags',
49
     // experience: 'FormTags',
45
     // role: 'FormDropdown',
50
     // role: 'FormDropdown',
46
 }
51
 }
91
             'analyst',
96
             'analyst',
92
             'architect',
97
             'architect',
93
             'developer',
98
             'developer',
94
-            'engineer', 'manager', 'technician', ],
99
+            'engineer',
100
+            'manager',
101
+            'technician',
102
+        ],
95
         candidate: ['hiring_manager', 'recruiter'],
103
         candidate: ['hiring_manager', 'recruiter'],
96
     },
104
     },
97
     pronouns: ['she/her', 'she/they', 'he/him', 'he/they', 'they/them'],
105
     pronouns: ['she/her', 'she/they', 'he/him', 'he/they', 'they/them'],
103
 // TODO: set up a separate object of similar prompts based off of
111
 // TODO: set up a separate object of similar prompts based off of
104
 // employer/employee, right now is generic
112
 // employer/employee, right now is generic
105
 const promptOverrides = {
113
 const promptOverrides = {
106
-    name: "First things first, could you provide us with your name? [break] I am called [break] when others address me.",
114
+    name: 'First things first, could you provide us with your name? [break] I am called [break] when others address me.',
107
     email: "In order for others to reach out to you on Siimee, you'll need to provide your email address.[break]When reaching out to me, [break] is my preferred email.",
115
     email: "In order for others to reach out to you on Siimee, you'll need to provide your email address.[break]When reaching out to me, [break] is my preferred email.",
108
     password:
116
     password:
109
         "So far so good! Next we'll need you to establish a super secret password. Your password should be at least 10 characters long and have at least 2 special characters.[break]My [break] is a very secure passcode that only I will have access to!",
117
         "So far so good! Next we'll need you to establish a super secret password. Your password should be at least 10 characters long and have at least 2 special characters.[break]My [break] is a very secure passcode that only I will have access to!",
110
-    zipcode: "Looking good! You're doing great. The next piece of info we'll need is your zip code. That way we can be sure to only show you other people in your area.[break]My zip code, [break] is the general area where I wish to see results in.",
111
-    seeking: "Alright, let's continue! What are you seeking? Are you looking to find a position to be employed in, or are you looking to employ a candidate?[break] I am a [break] seeking an employer/employee.",
118
+    zipcode:
119
+        "Looking good! You're doing great. The next piece of info we'll need is your zip code. That way we can be sure to only show you other people in your area.[break]My zip code, [break] is the general area where I wish to see results in.",
120
+    seeking:
121
+        "Alright, let's continue! What are you seeking? Are you looking to find a position to be employed in, or are you looking to employ a candidate?[break] I am a [break] seeking an employer/employee.",
112
     blurb: "Please provide us with a short blurb about yourself. What's your backstory?[break] My origin story starts like this:[break]",
122
     blurb: "Please provide us with a short blurb about yourself. What's your backstory?[break] My origin story starts like this:[break]",
113
     image: "Hey, you're almost done! Please provide an image of yourself so others can recognize you if you ever meet up IRL:",
123
     image: "Hey, you're almost done! Please provide an image of yourself so others can recognize you if you ever meet up IRL:",
114
-    pronouns: 'When others refer to you, what pronouns do you prefer they use?[break]I prefer to be called [break] when others refer to me.',
115
-    urgency: "How soon do you need the position filled or you need to be employed? [break]I am currently [break] when it comes to employment opportunities right now.",
116
-    presence: "Would you prefer remote, hybrid, in-person work?[break] Personally I'd prefer a [break] job right now. It's just what works best for me.",
117
-    duration: "What kind of duration would you prefer? Are you looking for part-time, full-time, other?[break] Currently, I'm looking for a [break] job at this time.",
118
-    language: "What language is your native language?[break] I consider [break] language as my native language.",
119
-    distance: "What distance from your home are you looking to work in?[break] Preferably, I'd like to work [break] from my place of residence.",
124
+    pronouns:
125
+        'When others refer to you, what pronouns do you prefer they use?[break]I prefer to be called [break] when others refer to me.',
126
+    urgency:
127
+        'How soon do you need the position filled or you need to be employed? [break]I am currently [break] when it comes to employment opportunities right now.',
128
+    presence:
129
+        "Would you prefer remote, hybrid, in-person work?[break] Personally I'd prefer a [break] job right now. It's just what works best for me.",
130
+    duration:
131
+        "What kind of duration would you prefer? Are you looking for part-time, full-time, other?[break] Currently, I'm looking for a [break] job at this time.",
132
+    language:
133
+        'What language is your native language?[break] I consider [break] language as my native language.',
134
+    distance:
135
+        "What distance from your home are you looking to work in?[break] Preferably, I'd like to work [break] from my place of residence.",
120
 }
136
 }
121
 
137
 
122
 const inputPlaceholders = {
138
 const inputPlaceholders = {
131
 const invalidInputPrompts = {
147
 const invalidInputPrompts = {
132
     name: "So sorry, but what's your name?",
148
     name: "So sorry, but what's your name?",
133
     email: "It looks like that email isn't valid, try en email that is formatted like so: joe@joe.com",
149
     email: "It looks like that email isn't valid, try en email that is formatted like so: joe@joe.com",
134
-    password: "That password doesn't fit our requirements, please follow the above instructions to generate a secure password.",
135
-    zipcode: "Oops! That isn't a recognized zipcode, please enter a 5 digit zipcode like: 97869",
136
-    blurb: "Whoa! Cool story. Unfortunately your backstory is either too long or too short. Please tell us a bit about yourself between 1 and 100 characters.",
150
+    password:
151
+        "That password doesn't fit our requirements, please follow the above instructions to generate a secure password.",
152
+    zipcode:
153
+        "Oops! That isn't a recognized zipcode, please enter a 5 digit zipcode like: 97869",
154
+    blurb: 'Whoa! Cool story. Unfortunately your backstory is either too long or too short. Please tell us a bit about yourself between 1 and 100 characters.',
137
     image: "It appears you didn't upload an image. Please provide Siimee with an image in case you want to show others what you look like.",
155
     image: "It appears you didn't upload an image. Please provide Siimee with an image in case you want to show others what you look like.",
138
-    seeking: "In order to provide you with the best results, Siimee will need to know whether you're an employer looking to fill a position, or a candidate looking for an employment. Please take a look at our above options and choose one.",
139
-    pronouns: "Ensuring that others on our platform are aware of what your preferred pronouns are is important to us. Please choose from one of the above options.",
140
-    urgency: "Looks like you left this field blank. Take a look at our provided options and tell us when you'd like be employed.",
141
-    presence: "Hold up! So sorry to put a pause here, but it looks like you haven't chosen whether to work remotely or in person. No worries, if you're unsure, just choose the 'flexible' option.",
142
-    duration: "Looks like you haven't filled out what kind of work you're most interested in. As in, part-time, full-time. Take a look at our above options and choose whatever feels right for you right now. You can always edit them later!",
143
-    language: "We try our best to provide results in the language of your choosing. ¿Prefieres ver resultados en español? Or would you prefer to see results in english?",
144
-    distance: "Whoa! You either left this field blank or tried to input an astronomically large distance you'd like to see results from. Please input a distance you'd like to see results in.",
156
+    seeking:
157
+        "In order to provide you with the best results, Siimee will need to know whether you're an employer looking to fill a position, or a candidate looking for an employment. Please take a look at our above options and choose one.",
158
+    pronouns:
159
+        'Ensuring that others on our platform are aware of what your preferred pronouns are is important to us. Please choose from one of the above options.',
160
+    urgency:
161
+        "Looks like you left this field blank. Take a look at our provided options and tell us when you'd like be employed.",
162
+    presence:
163
+        "Hold up! So sorry to put a pause here, but it looks like you haven't chosen whether to work remotely or in person. No worries, if you're unsure, just choose the 'flexible' option.",
164
+    duration:
165
+        "Looks like you haven't filled out what kind of work you're most interested in. As in, part-time, full-time. Take a look at our above options and choose whatever feels right for you right now. You can always edit them later!",
166
+    language:
167
+        'We try our best to provide results in the language of your choosing. ¿Prefieres ver resultados en español? Or would you prefer to see results in english?',
168
+    distance:
169
+        "Whoa! You either left this field blank or tried to input an astronomically large distance you'd like to see results from. Please input a distance you'd like to see results in.",
145
 }
170
 }
146
 
171
 
147
 export {
172
 export {

+ 37
- 6
frontend/src/utils/survey.js Ver fichero

1
 import { Survey } from '../entities/index.js'
1
 import { Survey } from '../entities/index.js'
2
 import { fetchQuestions } from '../services/index.js'
2
 import { fetchQuestions } from '../services/index.js'
3
-import { promptOverrides, promptToComponent, inputPlaceholders, invalidInputPrompts ,possible, aspectsArr } from './lang.js'
3
+import {
4
+    allSteps,
5
+    promptOverrides,
6
+    promptToComponent,
7
+    inputPlaceholders,
8
+    invalidInputPrompts,
9
+    possible,
10
+    aspectsArr,
11
+} from './lang.js'
4
 
12
 
5
 /**
13
 /**
6
  * Make a step from match or step information
14
  * Make a step from match or step information
16
         response_key_prompt: match ? match.response_key_prompt : step,
24
         response_key_prompt: match ? match.response_key_prompt : step,
17
         response_key_description: match ? match.response_key_description : null,
25
         response_key_description: match ? match.response_key_description : null,
18
     }
26
     }
27
+    // Embarassing hack
28
+    const uglyMatch = step.split('-')
29
+    if (uglyMatch.length > 1 && uglyMatch[0] == 'aspect') {
30
+        responseKey.aspect = match.response_key_category
31
+        responseKey.category = 'aspect'
32
+    }
19
     return {
33
     return {
20
         ...responseKey,
34
         ...responseKey,
21
         responses: responsesByCategory[step] ? responsesByCategory[step] : [],
35
         responses: responsesByCategory[step] ? responsesByCategory[step] : [],
23
 }
37
 }
24
 const associateWithComponent = responseKeyLike => {
38
 const associateWithComponent = responseKeyLike => {
25
     let component = promptToComponent[responseKeyLike.response_key_prompt]
39
     let component = promptToComponent[responseKeyLike.response_key_prompt]
40
+    // Embarassing hack
41
+    if (responseKeyLike.category == 'aspect') {
42
+        component = promptToComponent[responseKeyLike.category]
43
+    }
26
     return { ...responseKeyLike, component }
44
     return { ...responseKeyLike, component }
27
 }
45
 }
28
 
46
 
29
 const hasMatch = (step, inArray) => {
47
 const hasMatch = (step, inArray) => {
30
-    return inArray.find(q => q.response_key_prompt == step)
48
+    const uglyMatch = step.split('-')
49
+    // Embarassing hack
50
+    if (uglyMatch.length > 1 && uglyMatch[0] == 'aspect') {
51
+        return inArray.find(q => q.response_key_id == uglyMatch[1])
52
+    } else {
53
+        return inArray.find(q => q.response_key_prompt == step)
54
+    }
31
 }
55
 }
32
 
56
 
33
 class SurveyFactory {
57
 class SurveyFactory {
43
             if (match) {
67
             if (match) {
44
                 seenIds.push(match.response_key_id)
68
                 seenIds.push(match.response_key_id)
45
             }
69
             }
70
+            // Reformat something from the db into something the gui likes
46
             const responseKeyLike = formatStep(match, step)
71
             const responseKeyLike = formatStep(match, step)
72
+
73
+            // Lookup a matching component
47
             const withComponent = associateWithComponent(responseKeyLike)
74
             const withComponent = associateWithComponent(responseKeyLike)
48
 
75
 
49
             // Mutate the object with extra stuff
76
             // Mutate the object with extra stuff
77
+            const langStub = responseKeyLike.response_key_prompt
78
+            withComponent.survey_stage = langStub
50
             if (promptOverrides[responseKeyLike.response_key_prompt]) {
79
             if (promptOverrides[responseKeyLike.response_key_prompt]) {
51
-                const langStub = responseKeyLike.response_key_prompt
52
                 withComponent.response_key_prompt = promptOverrides[langStub]
80
                 withComponent.response_key_prompt = promptOverrides[langStub]
53
                 withComponent.placeholder = inputPlaceholders[langStub]
81
                 withComponent.placeholder = inputPlaceholders[langStub]
54
                 withComponent.invalidInputPrompt = invalidInputPrompts[langStub]
82
                 withComponent.invalidInputPrompt = invalidInputPrompts[langStub]
55
-                withComponent.survey_stage = langStub
83
+            } else {
84
+                console.warn(
85
+                    `WARN: ${withComponent.survey_stage} must have promptOverride`,
86
+                )
56
             }
87
             }
57
 
88
 
58
             return withComponent
89
             return withComponent
61
         let unseen = this.questionsFromDb.filter(
92
         let unseen = this.questionsFromDb.filter(
62
             q =>
93
             q =>
63
                 !seenIds.includes(q.response_key_id) &&
94
                 !seenIds.includes(q.response_key_id) &&
64
-                aspectsArr.includes(q.response_key_id)
95
+                aspectsArr.includes(q.response_key_id),
65
         )
96
         )
66
         return [...stepsInCommon, ...unseen]
97
         return [...stepsInCommon, ...unseen]
67
     }
98
     }
73
             console.error(err)
104
             console.error(err)
74
         }
105
         }
75
     }
106
     }
76
-    async createSurvey(langFile, roleTree) {
107
+    async createSurvey(langFile = allSteps['usa'], roleTree) {
77
         if (!this.questionsFromDb.length) {
108
         if (!this.questionsFromDb.length) {
78
             const res = await this.getQuestions()
109
             const res = await this.getQuestions()
79
             console.warn(
110
             console.warn(

+ 6
- 8
frontend/src/views/OnboardingView.vue Ver fichero

7
         .answers(v-for='(value, key) in answered')
7
         .answers(v-for='(value, key) in answered')
8
             span(v-if='key == "name" && value && currentStep == 2') Hi {{ value }}!
8
             span(v-if='key == "name" && value && currentStep == 2') Hi {{ value }}!
9
             span(v-if='key == "email" && value && currentStep == 3') Thanks for the contact info, {{ answered.name }}!
9
             span(v-if='key == "email" && value && currentStep == 3') Thanks for the contact info, {{ answered.name }}!
10
-            
11
-        h3(v-if="currentStep == 1") Welcome to Siimee Onboarding! Let's get started!
10
+
11
+        //- h3(v-if='currentStep == 1') Welcome to Siimee Onboarding! Let's get started!
12
         br
12
         br
13
         .step(v-for='(step, i) in survey.steps')
13
         .step(v-for='(step, i) in survey.steps')
14
             component(
14
             component(
15
-                :aspect-questions='step.component == "Aspects" ? survey.aspectQuestions : null'
16
                 :is='step.component'
15
                 :is='step.component'
17
                 :question='step'
16
                 :question='step'
18
                 @handle-submit='onSubmit'
17
                 @handle-submit='onSubmit'
26
             p {{ survey.steps[currentStep].invalidInputPrompt }}
25
             p {{ survey.steps[currentStep].invalidInputPrompt }}
27
 
26
 
28
         footer
27
         footer
29
-            p(v-if='currentStep != 0') You have completed: {{ currentStep - 1 }} / {{ survey.steps.length -2 }} survey steps
28
+            p(v-if='currentStep != 0') You have completed: {{ currentStep - 1 }} / {{ survey.steps.length - 2 }} survey steps
30
 
29
 
31
     article(v-else)
30
     article(v-else)
32
         SurveyCompleteView(:answers='answered' :surveySteps='survey.steps')
31
         SurveyCompleteView(:answers='answered' :surveySteps='survey.steps')
34
 
33
 
35
 <script>
34
 <script>
36
 import { surveyFactory } from '@/utils'
35
 import { surveyFactory } from '@/utils'
37
-import { allSteps } from '@/utils/lang'
38
 import stepViews from '@/components/onboarding'
36
 import stepViews from '@/components/onboarding'
39
 import SurveyCompleteView from './SurveyCompleteView.vue'
37
 import SurveyCompleteView from './SurveyCompleteView.vue'
40
 
38
 
55
         invalidResponse: false,
53
         invalidResponse: false,
56
     }),
54
     }),
57
     async created() {
55
     async created() {
58
-        this.survey = await surveyFactory.createSurvey(allSteps['usa'])
56
+        this.survey = await surveyFactory.createSurvey()
59
     },
57
     },
60
     methods: {
58
     methods: {
61
         onSubmit() {
59
         onSubmit() {
72
                 const k = payload.question.survey_stage
70
                 const k = payload.question.survey_stage
73
                 this.answered[k] = payload.input
71
                 this.answered[k] = payload.input
74
 
72
 
75
-                if (!this.survey.validateAnswer(this.answered)) {
73
+                if (!this.survey.validateAnswer(payload)) {
76
                     this.invalidResponse = true
74
                     this.invalidResponse = true
77
                     return
75
                     return
78
                 }
76
                 }
79
 
77
 
80
                 // once validated, don't log password in answered object
78
                 // once validated, don't log password in answered object
81
-                this.answered[k] = k === 'password' ? undefined : payload.input 
79
+                this.answered[k] = k === 'password' ? undefined : payload.input
82
                 console.log(`Updated answers: ${JSON.stringify(this.answered)}`)
80
                 console.log(`Updated answers: ${JSON.stringify(this.answered)}`)
83
                 if (k === 'aspects') return
81
                 if (k === 'aspects') return
84
             }
82
             }

Loading…
Cancelar
Guardar