Преглед изворни кода

:recyce: chopping down components using a mixin | removing more cruft and inconsistencies

tags/0.0.1
J пре 4 година
родитељ
комит
b7e6ab337b

+ 19
- 22
frontend/src/components/Messages.vue Прегледај датотеку

@@ -1,34 +1,31 @@
1 1
 <template lang="pug">
2
-.sidebar__messages
3
-  h5.message__title {{ title }}
2
+.sidebar--messages
3
+  h5.message__title messages from matches
4 4
   router-link(
5
-      :to="'/chats/' + user.uid" 
6
-      v-for='user in users' 
7
-      :key='user.uid' 
8
-      :class="[uid == user.uid ? 'active' : '', 'sidebar__message', 'f-col', 'start']"
9
-      )
5
+        :to="`/chats/${profile.profile_id}`" 
6
+        v-for='profile in matches' 
7
+        :key='profile.profile_id' 
8
+        :class="[pid == profile.profile_id ? 'active' : '', 'sidebar__message', 'f-col', 'start']"
9
+    )
10 10
     .f-row.start
11
-      img(:src='user.avatar')
12
-      .message__right.f-col
13
-        h4.message__name {{ user.name }}
14
-        p.message__content
15
-          | {{ user.metadata.rawMetadata || &quot;Hello I&apos;m using tinder!&quot; }}
11
+        img(:src='profile.avatar')
12
+        .message__right.f-col
13
+            h4.message__name {{ profile.name }}
14
+            p.message__content {{ profile.metadata.rawMetadata || &quot;Hello I&apos;m using tinder!&quot; }}
16 15
 </template>
17 16
 
18 17
 <script>
19 18
 export default {
20
-    name: 'UserMessages',
19
+    name: 'ProfileMessages',
21 20
     props: {
22
-        title: { type: String, default: 'Messages' },
23
-        users: {
21
+        matches: {
24 22
             type: [Object, Array],
25
-            default: []
26
-        },
27
-    },
28
-    computed: {
29
-        uid() {
30
-            return this.$route.params.uid
23
+            default: () => []
31 24
         },
25
+        pid: {
26
+            required: true,
27
+            type: Number
28
+        }
32 29
     },
33 30
 }
34 31
 </script>
@@ -36,7 +33,7 @@ export default {
36 33
 <style lang="postcss">
37 34
 
38 35
 .sidebar
39
-    &__messages
36
+    &--messages
40 37
         padding: 20px 10px
41 38
         /* overflow-y: scroll */
42 39
         text-align: left

+ 3
- 3
frontend/src/components/ProfileCardList.vue Прегледај датотеку

@@ -43,7 +43,7 @@ import {
43 43
 } from '../services'
44 44
 
45 45
 const router = useRouter()
46
-const emit = defineEmits(['reload-queue'])
46
+const emit = defineEmits(['reload'])
47 47
 // TODO: Please review this conversion from script to script setup
48 48
 // converted from the props section
49 49
 const props = defineProps({
@@ -95,7 +95,7 @@ const accept = async () => {
95 95
         console.log('Make membership')
96 96
         postMembershipByProfileId({ profileId, targetId })
97 97
     }
98
-    emit('reload-queue')
98
+    emit('reload')
99 99
 }
100 100
 const view = pid => {
101 101
     router.push({
@@ -109,7 +109,7 @@ const pass = () => {
109 109
     const profileId = props.pid
110 110
     const targetId = props.profiles[0].pid
111 111
     updateQueueByProfileId(profileId, targetId, true)
112
-    emit('reload-queue')
112
+    emit('reload')
113 113
 }
114 114
 
115 115
 // from the data() section

+ 11
- 12
frontend/src/components/SideBar.vue Прегледај датотеку

@@ -1,19 +1,19 @@
1 1
 <template lang="pug">
2
-aside.sidebar.p-1.f-col.between
3
-    h3 Profile: {{ pid }}
4
-    button(@click="$emit('hide')") hide
5
-    messages(:title="title" :users="users")
6
-    .spacer.f-grow
2
+aside.sidebar.p-1.f-col
7 3
     .temp-control-box.f-row.start.center
8
-        input(v-model='switchToPID' style="width: 50px")
4
+        input(v-model="switchToPID")
9 5
         button(@click="$emit('updatePid', switchToPID)").t-up.p-0 switch profile
6
+    
7
+    Messages(:matches="matches" :pid="pid")
8
+    
9
+    .spacer.f-grow
10 10
 </template>
11 11
 
12 12
 <script>
13
-import messages from './Messages.vue'
13
+import Messages from './Messages.vue'
14 14
 
15 15
 export default {
16
-    components: { messages }, 
16
+    components: { Messages }, 
17 17
     props: {
18 18
         pid: {
19 19
             required: true,
@@ -21,18 +21,17 @@ export default {
21 21
         }
22 22
     },
23 23
     data: () => ({
24
-        title:'Messages from Matches',
25 24
         switchToPID: null,
26
-        users: [
25
+        matches: [
27 26
             {
28 27
                 name: 'Bob McRob',
29
-                uid: 111,
28
+                profile_id: 111,
30 29
                 avatar: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/newborn-baby-boy-sleeping-peacefully-wearing-knit-royalty-free-image-1589459736.jpg?crop=0.669xw:1.00xh;0.228xw,0&resize=640:*',
31 30
                 metadata: { rawMetadata: 'howdy howdy howdy' },
32 31
             },
33 32
             {
34 33
                 name: 'Rob Bebob',
35
-                uid: 112,
34
+                profile_id: 112,
36 35
                 avatar: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/newborn-baby-boy-sleeping-peacefully-wearing-knit-royalty-free-image-1589459736.jpg?crop=0.669xw:1.00xh;0.228xw,0&resize=640:*',
37 36
                 metadata: { rawMetadata: 'this is the last message' },
38 37
             },

+ 21
- 0
frontend/src/entities/card/card.js Прегледај датотеку

@@ -0,0 +1,21 @@
1
+/** @module entities/card */
2
+
3
+/** Class representing a card */
4
+class Card {
5
+    /**
6
+     * Create the a card object.
7
+     * @param {number} pid
8
+     * @param {string} name
9
+     * @param {string} avatar
10
+     * @return {Card} the card instance object
11
+     */
12
+    constructor({ pid, name, avatar }) {
13
+        this.pid = pid
14
+        this.name = name
15
+        this.avatar = avatar
16
+
17
+        return this
18
+    }
19
+}
20
+
21
+export { Card }

+ 1
- 0
frontend/src/entities/card/index.js Прегледај датотеку

@@ -0,0 +1 @@
1
+export * from './card'

+ 2
- 1
frontend/src/entities/index.js Прегледај датотеку

@@ -4,4 +4,5 @@ export * from './_modules'
4 4
 export * from './response'
5 5
 export * from './profile'
6 6
 export * from './survey'
7
-export * from './grouping'
7
+export * from './grouping'
8
+export * from './card'

+ 6
- 0
frontend/src/entities/profile/profile.schema.js Прегледај датотеку

@@ -24,9 +24,15 @@ const profileSchema = {
24 24
         }),
25 25
 
26 26
         /** fields that should match backend service*/
27
+        user_name: Joi.string(),
27 28
         user_id: Joi.number(),
28 29
         profile_id: Joi.number(),
30
+        profile_description: Joi.string(),
31
+        profile_media: Joi.array().items(Joi.string()),
32
+        profile_languages: Joi.array().items(Joi.string()),
33
+        profile_prefs: Joi.object(),
29 34
         responses: Joi.array().items(responseSchema), // response entity schema goes here
35
+        tags: Joi.array().items(),
30 36
         user_type: Joi.string(),
31 37
 
32 38
         /** tricky module system fields */

+ 11
- 2
frontend/src/services/grouping.service.js Прегледај датотеку

@@ -1,5 +1,5 @@
1 1
 import { db } from '../utils/db'
2
-import { Grouping } from '../entities'
2
+import { Grouping, Profile } from '../entities'
3 3
 
4 4
 /**
5 5
  * Get Memberships associated with a single Profile from the database and
@@ -14,12 +14,21 @@ const fetchMembershipsByProfileId = async profileId => {
14 14
     for (let membership of membershipsForProfileId) {
15 15
         const grouping = new Grouping(membership)
16 16
         if (grouping.isValid()) {
17
+            // Reformat incoming profile data into Profile entity
18
+            grouping.profile = new Profile(grouping.profile)
17 19
             validGroupingInstances.push(grouping)
18 20
         }
19 21
     }
20 22
     return validGroupingInstances
21 23
 }
22 24
 
25
+/**
26
+ * Create memberships to a grouping between profileId and targetId
27
+ * @param {number} profileId
28
+ * @param {number} targetId
29
+ * @param {string} groupingType
30
+ * @returns {object} the created membership
31
+ */
23 32
 const postMembershipByProfileId = async ({
24 33
     profileId,
25 34
     targetId,
@@ -31,7 +40,7 @@ const postMembershipByProfileId = async ({
31 40
         grouping_type: groupingType,
32 41
         grouping_name: `${utcDateInSeconds}_${profileId}_${targetId}`,
33 42
     }
34
-    console.log('Membership Created')
43
+    console.warn(`${groupingType} created between ${profileId} and ${targetId}`)
35 44
     const createdMembershipRecord = await db.post(
36 45
         `/membership/${profileId}/join`,
37 46
         membership,

+ 6
- 1
frontend/src/services/login.service.js Прегледај датотеку

@@ -1,7 +1,12 @@
1 1
 import { ref } from 'vue'
2
-import { fetchQueueByProfileId, fetchResponsesByProfileId } from '../services'
2
+import { fetchResponsesByProfileId } from '../services'
3 3
 import { surveyFactory } from '../utils'
4 4
 
5
+/**
6
+ * Logged in profile state manager
7
+ * Sort of a util and service hybrid
8
+ * @returns {array} profiles
9
+ */
5 10
 class Login {
6 11
     constructor() {
7 12
         this._loading = false

+ 18
- 18
frontend/src/services/queue.service.js Прегледај датотеку

@@ -1,7 +1,11 @@
1 1
 import { db } from '../utils/db'
2 2
 import { Profile } from '../entities'
3 3
 
4
-// TODO: queue services
4
+/**
5
+ * Get a match queue of profiles
6
+ * @param {number} profileId
7
+ * @returns {array} profiles
8
+ */
5 9
 const fetchQueueByProfileId = async profileId => {
6 10
     let queue
7 11
     
@@ -10,36 +14,32 @@ const fetchQueueByProfileId = async profileId => {
10 14
             `/profile/${profileId}/queue?include_profile=true`,
11 15
         )
12 16
         if(!queue?.length) {
13
-            throw 'could not retrieve match queue. Please take the survey and rescore.'
17
+            throw 'Could not retrieve match queue. Please take the survey and rescore.'
14 18
         }
15 19
     } catch (err) {
16 20
         console.error(err)
17 21
     }
18 22
 
19 23
     return queue ? queue.map(profileData => {
20
-        return new Profile({ email: null, ...profileData })
24
+        return new Profile({ email: 'fixme@gmail.com', ...profileData })
21 25
     }) : []
22 26
 }
23 27
 
28
+/**
29
+ * Remove or reinsert a profile in match queue
30
+ * @param {number} profileId profile viewing the queue
31
+ * @param {number} targetId
32
+ * @param {boolean} reinsert FALSE if profileId accepted targetId; TRUE to reinsert into match queue
33
+ * @returns {array} profiles
34
+ */
24 35
 const updateQueueByProfileId = async (profileId, targetId, reinsert) => {
25
-    // Arguments
26
-    // profileId - the id of the profile viewing the queue
27
-    // targetId - the id of the profile viewed by the profileId
28
-    // reinsert - if profileId accepted targetId, FALSE reinsert so no reinsert; if profileId passed targetId, TRUE reinsert so reinsert at end
29
-    //
30 36
     const updateQueue = await db.patch(
31 37
         `/profile/${profileId}/queue/${targetId}/delete?include_profile=true&reinsert=${reinsert}`,
32
-        // HELP: responseScheme says the structure should be array of either:
33
-        // 1) NUMBER
34
-        // or
35
-        // 2) {profile_id, user_id, user_name, user_media, responses, user_type}
36
-        // ~However~ how do we call (2) here? It seems too much to call another API just to fill out a payload, so I just went with (1)
37
-        [
38
-            targetId,
39
-        ],
38
+        [ targetId ],
40 39
     )
41
-    console.log('updateQueue', updateQueue)
42
-    return updateQueue
40
+    return updateQueue ? updateQueue.map(profileData => {
41
+        return new Profile({ email: 'fixme@gmail.com', ...profileData })
42
+    }) : []
43 43
 }
44 44
 
45 45
 export { fetchQueueByProfileId, updateQueueByProfileId }

+ 0
- 1
frontend/src/utils/index.js Прегледај датотеку

@@ -1,5 +1,4 @@
1 1
 import Joi from 'joi'
2
-import { fetchQuestions } from '../services'
3 2
 
4 3
 import { Connector } from './db'
5 4
 import { SurveyFactory } from './survey'

+ 23
- 32
frontend/src/views/HomeView.vue Прегледај датотеку

@@ -4,7 +4,7 @@ main.view--home.f-col.start.w-full
4 4
         h2 home - profile: {{ pid }}
5 5
 
6 6
     article(v-if="cards.length && !loading")
7
-        ProfileCardList(:profiles="cards" :pid="pid" @reload-queue="getQueue")
7
+        ProfileCardList(:profiles="cards" :pid="pid" @reload="getCards")
8 8
 
9 9
     p(v-else) Loading...
10 10
 
@@ -14,46 +14,37 @@ main.view--home.f-col.start.w-full
14 14
 <script>
15 15
 import ProfileCardList from '../components/ProfileCardList.vue'
16 16
 
17
+import { Card } from '../entities'
17 18
 import { fetchQueueByProfileId } from '../services'
19
+import { pidMixin } from './mixins'
20
+
21
+/** Callback used to format incoming into card */
22
+const convertToCard = profile => {
23
+    if(profile.type !== 'profile') {
24
+        console.error(`Cannot convert ${profile} to Card. Invalid entity.`)
25
+    }
26
+    if(!profile.isValid()) {
27
+        console.warn(`Profile ${profile.profile_id} is not a valid profile.`)
28
+    }
29
+    return new Card({
30
+        pid: profile.profile_id,
31
+        name: profile.user_name,
32
+        avatar: profile.profile_media[0],
33
+    })
34
+}
18 35
 
19 36
 export default {
20 37
     name: 'HomeView',
21 38
     components: { ProfileCardList },
22
-    props: {
23
-        pid: {
24
-            type: Number,
25
-            required: true,
26
-        },
27
-    },
28
-    data: () => ({
29
-        cards: [],
30
-        loading: true,
31
-    }),
32
-    watch: {
33
-        /** Fetch the queue if pid changes */
34
-        async pid() { await this.getQueue() },
35
-    },
36
-    async mounted() {
37
-        await this.getQueue()
38
-    },
39
+    mixins: [ pidMixin ],
39 40
     methods: {
40
-        _reformatProfiles(profiles) {
41
-            return profiles.map(profile => {
42
-                return {
43
-                    pid: profile.profile_id,
44
-                    name: profile.user_name,
45
-                    avatar: profile.profile_media[0],
46
-                }
47
-            })
48
-        },
49
-        async getQueue() {
41
+        /** Gets called from pidMixins */
42
+        async getCards() {
50 43
             this.loading = true
51 44
             try {
52 45
                 const queueList = await fetchQueueByProfileId(this.pid)
53
-                this.cards = this._reformatProfiles(queueList)
54
-            } catch (err) {
55
-                console.error(err)
56
-            }
46
+                this.cards = this._reformat(queueList, convertToCard)
47
+            } catch (err) { console.error(err) }
57 48
             this.loading = false
58 49
         },
59 50
     },

+ 24
- 31
frontend/src/views/MatchesView.vue Прегледај датотеку

@@ -13,45 +13,38 @@ main.view--matches.f-col.start.w-full
13 13
 
14 14
 <script>
15 15
 import ProfileCardList from '../components/ProfileCardList.vue'
16
+
17
+import { Card } from '../entities'
16 18
 import { fetchMembershipsByProfileId } from '../services'
19
+import { pidMixin } from './mixins'
20
+
21
+/** Callback used to format incoming into card */
22
+const convertToCard = grouping => {
23
+    if(grouping.type !== 'grouping') {
24
+        console.error(`Cannot convert ${grouping} to Card. Invalid entity.`)
25
+    }
26
+    if(!grouping.profile.isValid()) {
27
+        console.warn(`Profile in ${grouping} is not a valid profile.`)
28
+    }
29
+    return new Card({
30
+        pid: grouping.profile.profile_id,
31
+        name: grouping.profile.user_name,
32
+        avatar: grouping.profile.profile_media[0],
33
+    })
34
+}
17 35
 
18 36
 export default {
37
+    name: 'MatchView',
19 38
     components: { ProfileCardList },
20
-    props: {
21
-        pid: {
22
-            type: Number,
23
-            required: true,
24
-        },
25
-    },
26
-    data: () => ({
27
-        cards: [],
28
-        loading: true,
29
-    }),
30
-    watch: {
31
-        pid() { this.getMatches() },
32
-    },
33
-    async created() {
34
-        await this.getMatches()
35
-    },
39
+    mixins: [ pidMixin ],
36 40
     methods: {
37
-        _reformatMatches(matches) {
38
-            return matches.map(m => {
39
-                return {
40
-                    pid: m.profile.profile_id,
41
-                    name: m.profile.user_name,
42
-                    avatar: m.profile.profile_media[0],
43
-                }
44
-            })
45
-        },
46
-        async getMatches() {
41
+        /** Gets called from pidMixins */
42
+        async getCards() {
47 43
             this.loading = true
48 44
             try {
49 45
                 const matchList = await fetchMembershipsByProfileId(this.pid)
50
-                console.log('matchList :', matchList)
51
-                this.cards = this._reformatMatches(matchList)
52
-            } catch (err) {
53
-                console.error(err)
54
-            }
46
+                this.cards = this._reformat(matchList, convertToCard)
47
+            } catch (err) { console.error(err) }
55 48
             this.loading = false
56 49
         },
57 50
     },

+ 27
- 0
frontend/src/views/mixins.js Прегледај датотеку

@@ -0,0 +1,27 @@
1
+const pidMixin = {
2
+    props: {
3
+        pid: {
4
+            type: Number,
5
+            required: true,
6
+            validator: prop => typeof prop === 'number' || prop === null
7
+        },
8
+    },
9
+    data: () => ({
10
+        cards: [],
11
+        loading: true,
12
+    }),
13
+    watch: {
14
+        /** Fetch the queue if pid changes */
15
+        pid() { this.getCards() },
16
+    },
17
+    async created() {
18
+        await this.getCards()
19
+    },
20
+    methods: {
21
+        _reformat(data, mapCb) {
22
+            return data.map(mapCb)
23
+        }
24
+    }
25
+}
26
+
27
+export { pidMixin }

Loading…
Откажи
Сачувај