Browse Source

:recycle: creating complete profiles with description, image, language, etc responses

tags/0.0.1
J 4 years ago
parent
commit
570b84bcdc

+ 0
- 1
backend/lib/models/profile.js View File

40
         return Joi.object({
40
         return Joi.object({
41
             profile_id: Joi.number(),
41
             profile_id: Joi.number(),
42
             user_id: Joi.number(),
42
             user_id: Joi.number(),
43
-            user_media: Joi.string(),
44
         })
43
         })
45
     }
44
     }
46
 }
45
 }

+ 1
- 0
backend/lib/plugins/survey.js View File

24
 
24
 
25
         await server.route(ResponseQuestionsRoute)
25
         await server.route(ResponseQuestionsRoute)
26
     },
26
     },
27
+    models: { ReponseKeyModel }
27
 }
28
 }

+ 2
- 10
backend/lib/routes/profile/get.js View File

3
 const Joi = require('joi')
3
 const Joi = require('joi')
4
 const apiSchema = require('../../schemas/api')
4
 const apiSchema = require('../../schemas/api')
5
 const errorSchema = require('../../schemas/errors')
5
 const errorSchema = require('../../schemas/errors')
6
+const profileSchema = require('../../schemas/profiles')
6
 
7
 
7
 const pluginConfig = {
8
 const pluginConfig = {
8
     handlerType: 'profile',
9
     handlerType: 'profile',
13
 }
14
 }
14
 
15
 
15
 const responseSchemas = {
16
 const responseSchemas = {
16
-    profile: Joi.object({
17
-        profile_id: Joi.number(),
18
-        user_id: Joi.number(),
19
-        user_name: Joi.string(),
20
-        responses: Joi.array().items(),
21
-        tags: Joi.array().items(),
22
-        user_media: Joi.string(),
23
-        user_type: Joi.any(),
24
-        user: Joi.object(),
25
-    }),
17
+    profile: profileSchema.single,
26
     error: errorSchema.single,
18
     error: errorSchema.single,
27
 }
19
 }
28
 
20
 

+ 2
- 1
backend/lib/routes/profile/match.js View File

3
 const Joi = require('joi')
3
 const Joi = require('joi')
4
 const apiSchema = require('../../schemas/api')
4
 const apiSchema = require('../../schemas/api')
5
 const errorSchema = require('../../schemas/errors')
5
 const errorSchema = require('../../schemas/errors')
6
+const surveyResponseSchema = require('../../schemas/responses') 
6
 
7
 
7
 const pluginConfig = {
8
 const pluginConfig = {
8
     handlerType: 'match',
9
     handlerType: 'match',
15
 const validators = {}
16
 const validators = {}
16
 
17
 
17
 const responseSchemas = {
18
 const responseSchemas = {
18
-    response: Joi.array().items(Joi.object()),
19
+    response: surveyResponseSchema.list,
19
     error: errorSchema.single
20
     error: errorSchema.single
20
 }
21
 }
21
 
22
 

+ 2
- 10
backend/lib/routes/profile/patch-queue.js View File

1
 'use strict'
1
 'use strict'
2
 
2
 
3
 const Joi = require('joi')
3
 const Joi = require('joi')
4
-
5
 const apiSchema = require('../../schemas/api')
4
 const apiSchema = require('../../schemas/api')
6
 const errorSchema = require('../../schemas/errors')
5
 const errorSchema = require('../../schemas/errors')
6
+const profileSchema = require('../../schemas/profiles')
7
 
7
 
8
 const pluginConfig = {
8
 const pluginConfig = {
9
     handlerType: 'profile',
9
     handlerType: 'profile',
17
     response: Joi.array().items(
17
     response: Joi.array().items(
18
         Joi.alternatives().try(
18
         Joi.alternatives().try(
19
             Joi.number(),
19
             Joi.number(),
20
-            Joi.object({
21
-                profile_id: Joi.number(),
22
-                user_id: Joi.number(),
23
-                user_name: Joi.string(),
24
-                responses: Joi.array().items(),
25
-                tags: Joi.array().items(),
26
-                user_media: Joi.string(),
27
-                user_type: Joi.any(),
28
-            }),
20
+            profileSchema.single,
29
         ),
21
         ),
30
     ),
22
     ),
31
     error: errorSchema.single
23
     error: errorSchema.single

+ 2
- 10
backend/lib/routes/profile/queue.js View File

3
 const Joi = require('joi')
3
 const Joi = require('joi')
4
 const apiSchema = require('../../schemas/api')
4
 const apiSchema = require('../../schemas/api')
5
 const errorSchema = require('../../schemas/errors')
5
 const errorSchema = require('../../schemas/errors')
6
+const profileSchema = require('../../schemas/profiles')
6
 
7
 
7
 const pluginConfig = {
8
 const pluginConfig = {
8
     handlerType: 'profile',
9
     handlerType: 'profile',
16
     response: Joi.array().items(
17
     response: Joi.array().items(
17
         Joi.alternatives().try(
18
         Joi.alternatives().try(
18
             Joi.number(),
19
             Joi.number(),
19
-            Joi.object({
20
-                profile_id: Joi.number(),
21
-                user_id: Joi.number(),
22
-                user_name: Joi.string(),
23
-                responses: Joi.array().items(),
24
-                tags: Joi.array().items(),
25
-                user_media: Joi.string(),
26
-                user_type: Joi.any(),
27
-                user: Joi.object()
28
-            }),
20
+            profileSchema.single,
29
         )
21
         )
30
     ),
22
     ),
31
     error: errorSchema.single
23
     error: errorSchema.single

+ 0
- 1
backend/lib/routes/user/list-profiles.js View File

36
         // and getCompleteProfiles utilizes CompleteProfile
36
         // and getCompleteProfiles utilizes CompleteProfile
37
         // and this route utilizes getCompleteProfiles
37
         // and this route utilizes getCompleteProfiles
38
         user_name: Joi.string(),
38
         user_name: Joi.string(),
39
-        user_media: Joi.string(),
40
         tags: Joi.array().items(),
39
         tags: Joi.array().items(),
41
         responses: Joi.array().items(
40
         responses: Joi.array().items(
42
             Joi.object({
41
             Joi.object({

+ 23
- 0
backend/lib/schemas/profiles.js View File

1
+'use strict'
2
+
3
+const Joi = require('joi')
4
+const surveyResponseSchema = require('./responses')
5
+
6
+const singleProfile = Joi.object({
7
+    profile_id: Joi.number(),
8
+    user_id: Joi.number(),
9
+    user_name: Joi.string(),
10
+    responses: surveyResponseSchema.list,
11
+    tags: Joi.array().items(),
12
+    user_type: Joi.any(),
13
+    user: Joi.object(),
14
+    profile_description: Joi.string().allow(null, ''),
15
+    profile_prefs: Joi.object(),
16
+    profile_media: Joi.array().items(),
17
+    profile_languages: Joi.array().items(),
18
+}).label('profile_single')
19
+
20
+module.exports = {
21
+    single: singleProfile,
22
+    list: Joi.array().items(singleProfile).label('profile_list')
23
+}

+ 1
- 1
backend/lib/schemas/responses.js View File

21
     list: Joi.array().items(singleResponse).label('response_list'),
21
     list: Joi.array().items(singleResponse).label('response_list'),
22
     key: singleResponseKey,
22
     key: singleResponseKey,
23
     keys: Joi.array().items(singleResponseKey).label('question_list')
23
     keys: Joi.array().items(singleResponseKey).label('question_list')
24
-}
24
+}

+ 30
- 16
backend/lib/services/profile.js View File

1
 const Schmervice = require('@hapipal/schmervice')
1
 const Schmervice = require('@hapipal/schmervice')
2
 const haversine = require('haversine')
2
 const haversine = require('haversine')
3
 
3
 
4
+// Keys that are profile data responses
5
+const _TEMP_RES_KEYS = [8, 9, 10, 11, 12]
4
 const _ZIPCODEKEY = 7
6
 const _ZIPCODEKEY = 7
5
 const scoreResponses = (seeker, potentialMatch, prescoreLookup) => {
7
 const scoreResponses = (seeker, potentialMatch, prescoreLookup) => {
6
     if (seeker.responses.length != potentialMatch.responses.length)
8
     if (seeker.responses.length != potentialMatch.responses.length)
8
             error: `complete responses for profile: ${seeker.profile_id} unqeual to profile: ${potentialMatch.profile_id} | ${seeker.responses.length}:${potentialMatch.responses.length}`,
10
             error: `complete responses for profile: ${seeker.profile_id} unqeual to profile: ${potentialMatch.profile_id} | ${seeker.responses.length}:${potentialMatch.responses.length}`,
9
         }
11
         }
10
 
12
 
11
-    const aRes = [...seeker.responses]
12
-    const bRes = [...potentialMatch.responses]
13
+    const aRes = seeker.responses.filter(res => !_TEMP_RES_KEYS.includes(res.response_key_id))
14
+    const bRes = potentialMatch.responses.filter(res => !_TEMP_RES_KEYS.includes(res.response_key_id))
13
 
15
 
14
     const composite = []
16
     const composite = []
15
     while (aRes.length + bRes.length > 0) {
17
     while (aRes.length + bRes.length > 0) {
89
         this.user_id = profile.user_id // int user_id
91
         this.user_id = profile.user_id // int user_id
90
         this.profile_id = profile.profile_id // int profile_id
92
         this.profile_id = profile.profile_id // int profile_id
91
         this.user_name = profile.user.user_name // string user_name
93
         this.user_name = profile.user.user_name // string user_name
92
-        this.user_media = profile.user_media // string user_media
93
-        this.responses = profile.responses // [] of all responses
94
+        this.responses = []
94
         this.tags = profile.tags // [] of all tags
95
         this.tags = profile.tags // [] of all tags
95
         this.user_type = type
96
         this.user_type = type
97
+
98
+        // TODO: generalize this for multiple images, and languages
99
+        this.profile_description = ''
100
+        this.profile_media = []
101
+        this.profile_languages = []
102
+        this.profile_prefs = {}
103
+        if(profile?.responses?.length) {
104
+            this.responses = profile.responses.filter(res => !_TEMP_RES_KEYS.includes(res.response_key_id)) // [] of all responses
105
+            const [image, language, duration, location, description]  = profile.responses.filter(res => _TEMP_RES_KEYS.includes(res.response_key_id))
106
+            this.profile_prefs.location = location.val
107
+            this.profile_prefs.duration = duration.val
108
+            this.profile_prefs.zip = profile.responses.filter(res => res.response_key_id == 7)[0].val // [] of all responses
109
+            this.profile_description = description.val
110
+            this.profile_media.push(image.val)
111
+            this.profile_languages.push(language.val)
112
+        }
96
     }
113
     }
97
 }
114
 }
98
 
115
 
101
         super(...args)
118
         super(...args)
102
         this.scoreLookup = {}
119
         this.scoreLookup = {}
103
         this.tagLookup = {}
120
         this.tagLookup = {}
121
+
122
+        // this.responseKeyLookup = ResponseKey.query()
104
     }
123
     }
105
     async _setScoreLookup() {
124
     async _setScoreLookup() {
106
         if (!Object.keys(this.scoreLookup).length) {
125
         if (!Object.keys(this.scoreLookup).length) {
144
     async getProfile(profileId) {
163
     async getProfile(profileId) {
145
         const { Profile } = this.server.models()
164
         const { Profile } = this.server.models()
146
         await this._setTagLookup()
165
         await this._setTagLookup()
147
-
166
+        
148
         const matchingProfile = await Profile.query()
167
         const matchingProfile = await Profile.query()
149
             .where('profile_id', profileId)
168
             .where('profile_id', profileId)
150
             .first()
169
             .first()
189
         await this._setTagLookup()
208
         await this._setTagLookup()
190
 
209
 
191
         // profilesEntries is profiles in dataaspect_labelsbase row order
210
         // profilesEntries is profiles in dataaspect_labelsbase row order
192
-        const profilesEntries = includeResponses
193
-            ? await Profile.query()
194
-                  .whereIn('profile_id', profileIdArray)
195
-                  .withGraphFetched('tags')
196
-                  .withGraphFetched('responses')
197
-                  .withGraphFetched('user')
198
-            : await Profile.query()
199
-                  .whereIn('profile_id', profileIdArray)
200
-                  .withGraphFetched('tags')
201
-                  .withGraphFetched('user')
202
-
211
+        const profilesEntries = await Profile.query()
212
+            .whereIn('profile_id', profileIdArray)
213
+            .withGraphFetched('tags')
214
+            .withGraphFetched('responses')
215
+            .withGraphFetched('user')
216
+            
203
         // taking the info from profilesEntries
217
         // taking the info from profilesEntries
204
         // to repack into completeProfiles
218
         // to repack into completeProfiles
205
         // in same order as profileIdArray
219
         // in same order as profileIdArray

+ 1
- 1
frontend/src/utils/login.js View File

29
             return {
29
             return {
30
                 pid: profile.profile_id,
30
                 pid: profile.profile_id,
31
                 name: profile.user_name,
31
                 name: profile.user_name,
32
-                avatar: profile.user_media,
32
+                avatar: '',
33
             }
33
             }
34
         })
34
         })
35
         return formattedList
35
         return formattedList

+ 2
- 2
frontend/src/views/HomeView.vue View File

39
                 return {
39
                 return {
40
                     pid: profile.profile_id,
40
                     pid: profile.profile_id,
41
                     name: profile.user_name,
41
                     name: profile.user_name,
42
-                    avatar: profile.user_media,
42
+                    avatar: profile.profile_media[0],
43
                 }
43
                 }
44
             })
44
             })
45
         },
45
         },
79
                 p.pid = p.profile_id
79
                 p.pid = p.profile_id
80
                 p.name = user.user_name
80
                 p.name = user.user_name
81
                 p.email = user.user_email
81
                 p.email = user.user_email
82
-                p.avatar = p.user_media[0]
82
+                p.avatar = p.profile_media[0]
83
                 p.responses = parsed.responses.filter(
83
                 p.responses = parsed.responses.filter(
84
                     r => r.profile_id == p.profile_id,
84
                     r => r.profile_id == p.profile_id,
85
                 )
85
                 )

+ 1
- 1
frontend/src/views/Matches.vue View File

29
             return this.matches.map(m => {
29
             return this.matches.map(m => {
30
                 return {
30
                 return {
31
                     pid: m.profile.profile_id,
31
                     pid: m.profile.profile_id,
32
-                    avatar: m.profile.user_media,
32
+                    avatar: m.profile.profile_media[0],
33
                     name: m.profile.user_name,
33
                     name: m.profile.user_name,
34
                 }
34
                 }
35
             })
35
             })

+ 128
- 0
frontend/src/views/home.vue View File

1
+<template lang="pug">
2
+sidebar(v-if='!loading' :pid="pid" @updatePid="setPid")
3
+main.f-col.start.w-full
4
+    article#home(v-if='!loading')
5
+        h1 Queue Page
6
+        profile-card-list(:profiles='swipables' :pid='parseInt(pid)' @reload-queue='getQueue')
7
+    p(v-else) Loading...
8
+    main-nav(v-if='!loading' :pid="pid")
9
+</template>
10
+
11
+<script>
12
+import sidebar from '../components/Sidebar.vue'
13
+import mainNav from '../components/MainNav.vue'
14
+import profileCardList from '../components/ProfileCardList.vue'
15
+
16
+import { Chatter, StonkAlert } from '../services'
17
+import { loginHandler, authHandler } from '../utils'
18
+
19
+import batch_10 from '../../../backend/db/generated/_batch_10.js.ref'
20
+import batch_20 from '../../../backend/db/generated/_batch_20.js.ref'
21
+import batch_30 from '../../../backend/db/generated/_batch_30.js.ref'
22
+
23
+const DEFAULT_PID = 45
24
+
25
+export default {
26
+    name: 'HomeView',
27
+    components: { profileCardList, sidebar, mainNav },
28
+    data: () => ({
29
+        swipables: [],
30
+        loading: true,
31
+        pid: null
32
+    }),
33
+    mounted() {
34
+        // Uncomment below to use API
35
+        let pid
36
+        if(!loginHandler.currentProfileId) {
37
+            pid  = authHandler.currentUser?.pid || DEFAULT_PID
38
+        } else {
39
+            pid = loginHandler.currentProfileId
40
+        }
41
+        this.setPid(pid)
42
+
43
+        // Uncomment below to use for batch file data
44
+        // this.processProfilesFromBatch(this.parseBatch([batch_10, batch_20, batch_30]))
45
+
46
+        this.setupChatter()
47
+        this.setupToaster()
48
+    },
49
+    methods: {
50
+        setPid(pid) {
51
+            loginHandler.login(pid)
52
+            this.pid = loginHandler.currentProfileId
53
+            this.getQueue()
54
+        },
55
+        async getQueue() {
56
+            this.loading = true
57
+            try {
58
+                await loginHandler.getQueue()
59
+                this.swipables = loginHandler.queue
60
+            } catch (err) {
61
+                console.error(err)
62
+            }
63
+            this.loading = false
64
+        },
65
+        // For push notifications and chat 
66
+        setupToaster() {
67
+            const t = new StonkAlert(this.pid)
68
+        },
69
+        setupChatter() {
70
+            const c = new Chatter()
71
+            const testAccountUUID = import.meta.env.VITE_TEST_ACCOUNT_UUID
72
+            c.setup(testAccountUUID)
73
+            console.log('---')
74
+        },
75
+        // For Batch Data Parsing & Processing
76
+        parseBatch(allBatches) {
77
+            const finished = { profiles: [], users: [], responses: [] }
78
+            allBatches.forEach(batch => {
79
+                const split = batch.value.split('\n')
80
+                split.splice(0, 5)
81
+                split.unshift('{')
82
+                const p = JSON.parse(split.join(''))
83
+                finished.profiles = [...p.profiles, ...finished.profiles]
84
+                finished.users = [...p.users, ...finished.users]
85
+                finished.responses = [...p.responses, ...finished.responses]
86
+            })
87
+            // console.log('parsed batch', finished)
88
+            return finished
89
+        },
90
+        processProfilesFromBatch(parsed) {
91
+            const findUser = profile => {
92
+                return parsed.users.filter(u => u.user_id == profile.user_id)[0]
93
+            }
94
+            parsed.profiles.forEach(p => {
95
+                // console.log(parsed)
96
+                const user = findUser(p)
97
+                p.pid = p.profile_id
98
+                p.name = user.user_name
99
+                p.email = user.user_email
100
+                p.avatar = p.profile_media[0]
101
+                p.responses = parsed.responses.filter(
102
+                    r => r.profile_id == p.profile_id,
103
+                )
104
+                p.responses.forEach(r => {
105
+                    if (r.response_key_id == 7) {
106
+                        p.zipcode = r.val
107
+                    }
108
+                })
109
+                this.swipables.push(p)
110
+            })
111
+        },
112
+    },
113
+}
114
+</script>
115
+
116
+<style lang="postcss">
117
+main
118
+    position: relative
119
+    height: 100%
120
+    > article
121
+        height: 100%
122
+        width: 100%
123
+        flex-direction: column
124
+
125
+    input, button
126
+        position: relative
127
+        z-index: 1000
128
+</style>

Loading…
Cancel
Save