Create a new Profile folder inside src/components/User. All profile related components will be inside the folder.

User Profile Header

We'll start by creating a UserProfileHeader component and paste the code below into it:

// src/components/User/Profile/UserProfileHeader.vue

<template>
  <div class="ui segment">
    <div class="ui grid container">
      <div class="four wide column">
        <img class="ui tiny avatar image" src="https://www.gravatar.com/avatar/default?s=200&r=pg&d=mm">
      </div>
      <div class="bottom aligned twelve wide column">
        <div class="ui horizontal relaxed link list">
          <div class="item">
            <div class="content">
              <router-link :to="`/${user.username}`">
                <div class="header">Tweets</div>
                <strong>{{ user.tweets.length }}</strong>
              </router-link>
            </div>
          </div>
          <div class="item">
            <div class="content">
              <router-link :to="isOwner ? `/following` : `/${user.username}/following`">
                <div class="header">Following</div>
                <strong>{{ user.following.length }}</strong>
              </router-link>
            </div>
          </div>
          <div class="item">
            <div class="content">
              <router-link :to="isOwner ? `/followers` : `/${user.username}/followers`">
                <div class="header">Followers</div>
                <strong>{{ user.followers.length }}</strong>
              </router-link>
            </div>
          </div>
          <div class="item">
            <div class="content">
              <router-link :to="isOwner ? `/favorites` : `/${user.username}/favorites`">
                <div class="header">Favorites</div>
                <strong>{{ user.favorites.length }}</strong>
              </router-link>
            </div>
          </div>
        </div>
        <div class="ui right floated horizontal list" v-if="isOwner">
          <router-link to="/settings/profile" class="ui button primary">Edit profile</router-link>
        </div>
        <div class="ui right floated horizontal list" v-if="isLoggedIn && !isOwner">
          <button class="ui tiny primary button" v-if="isFollowing" @click="unFollow(user.id)">Unfollow</button>
          <button class="ui tiny primary button" v-else @click="follow(user.id)">Follow</button>
        </div>
      </div>
    </div>
  </div>
</template>

This header contain the user image, tweets, following, followers and favorites counts. Depending on whether a user is viewing his/her profile or another user's profile, we made the links to reflect that. If a user is viewing his/her own profile, we display a link to edit profile. If a user is logged in and is viewing another user's profile, we display a button to either follow or unfollow the user depending on whether he/she is already following the user or not.

Table of Contents

    Next, let's add the corresponding JavaScript to the component. Still within src/components/User/Profile/UserProfileHeader.vue, add the code below just after the template section:

    // src/components/User/Profile/UserProfileHeader.vue
    
    <script>
        export default {
            name: 'UserProfileHeader',
            props: {
                user: {
                    type: Object,
                    required: true
                },
                authUser: {
                    type: Object,
                    required: true
                }
            },
            computed: {
                isOwner () {
                    return this.user.id === this.authUser.id
                },
                isLoggedIn () {
                    return !!this.authUser
                },
                isFollowing () {
                    for (const following of this.authUser.following) {
                        if (following.id === this.user.id) {
                            return true
                        }
                    }
    
                    return false
                }
            },
            methods: {
                follow (userId) {
                    const token = localStorage.getItem('tweetr-token')
    
                    axios
                        .post(
                            '/users/follow',
                            { user_id: userId },
                            {
                                headers: {
                                    Authorization: `Bearer ${token}`
                                }
                            }
                        )
                        .then(response => {
                            this.authUser.following.push({ id: userId })
                        })
                },
                unFollow (userId) {
                    const token = localStorage.getItem('tweetr-token')
    
                    axios
                        .delete(`/users/unfollow/${userId}`, {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        })
                        .then(response => {
                            this.authUser.following = this.authUser.following.filter(u => {
                                return u.id !== userId
                            })
                        })
                }
            }
        }
    </script>

    This accepts two props: user and the authenticated user. Then we define some computed properties to help determine if a user is viewing his/her own profile, if the user is logged in, and if the user is already following the user been view respectively. When the follow button is clicked, a follow method is called which makes a request to our API and on success adds the followed user to the array of users the authenticated user is following. On the other hand, when the unfollow button is clicked, a unFollow method is called which makes a request to our API and on success removes the unfollowed user from the array of users the authenticated user is following.

    User Profile Sidebar Details

    Next, let's create a UserProfileSidebarDetails component within the Profile folder and paste the code below into it:

    // src/components/User/Profile/UserProfileSidebarDetails.vue
    
    <template>
        <div>
            <router-link class="ui button mini primary" to="/">Back Home</router-link>
            <div class="ui segment">
                <h2 class="ui medium header">
                    <router-link :to="`/${user.username}`">{{ user.name }}</router-link>
                    <div class="sub header">
                        <router-link :to="`/${user.username}`">{{ `@${user.username}` }}</router-link>
                    </div>
                </h2>
    
                <p v-show="user.bio">{{ user.bio }}</p>
    
                <div class="ui list">
                    <div class="item" v-show="user.location">
                        <i class="marker icon"></i>
                        <div class="content">
                            {{ user.location }}
                        </div>
                    </div>
                    <div class="item" v-show="user.website_url">
                        <i class="linkify icon"></i>
                        <div class="content">
                            <a :href="user.website_url" target="_blank">{{ user.website_url }}</a>
                        </div>
                    </div>
                    <div class="item" v-show="user.created_at">
                        <i class="calendar icon"></i>
                        <div class="content">
                            Joined {{ user.created_at | joined }}
                        </div>
                    </div>
                    <div class="item" v-show="user.dob">
                        <i class="birthday icon"></i>
                        <div class="content">
                            {{ user.dob | dob }}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: 'UserProfileSidebarDetails',
            props: {
                user: {
                    type: Object,
                    required: true
                }
            }
        }
    </script>

    This take a user as its only props. This user props is used to display the user details.

    Chimezie Enyinnaya

    19 posts

    Software Developer [PHP Laravel JavaScript NodeJS AdonisJS VueJS] | movie lover | run http://openlaravel.com