25. Show group members

Now we need to show all members. First, we need to go to the group detail page where we can show group details and also a button to display members of that group. So open your GroupsComponent.vue and inside the loop where we are displaying all groups, change the following line:

<span v-text="group.name"></span>

With the following:

<router-link v-text="group.name" v-bind:to="'/groups/detail/' + group._id"></router-link>

So we will make the group name clickable. Then we need to create this route in our main.js:

import GroupDetailComponent from "./components/GroupDetailComponent.vue"

const routes = [
    ...

    { path: "/groups/detail/:_id", component: GroupDetailComponent },
];

After that, create a new file named GroupDetailComponent.vue in your components folder. And write the following code in this component:

<template>
    <!-- check if group data has been fetched from the API -->
    <template v-if="group != null">

        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <!-- show group name -->
                    <h1 v-text="group.name" class="text-center"></h1>

                    <!-- show group picture if uploaded -->
                    <template v-if="typeof group.picture !== 'undefined'">
                        <p class="text-center"><img v-bind:src="$apiURL + '/' + group.picture.path" style="height: 300px;" /></p>
                    </template>

                    <!-- button to show group members -->
                    <a class="btn btn-link" v-on:click.prevent="groupMembers">Group members</a>
                </div>
            </div>  
        </div>
    </template>
</template>

<script>

    // import required modules
    import axios from "axios"
    import swal from "sweetalert2"

    export default {
        data() {
            return {
                // get ID from URL
                _id: this.$route.params._id,

                // group object
                group: null,

                // logged-in user object
                user: null
            }
        },

        methods: {

            // get group document from AJAX
            getData: async function () {
                const formData = new FormData()
                formData.append("_id", this._id)

                const response = await axios.post(
                    this.$apiURL + "/groups/detail",
                    formData,
                    {
                        headers: this.$headers
                    }
                )

                if (response.data.status == "success") {
                    this.group = response.data.group
                    this.user = response.data.user
                } else {
                    swal.fire("Error", response.data.message, "error")
                }
            }
        },

        // get data when component is loaded
        mounted: function () {
            this.getData()
        }
    }
</script>

Then we need to create an API that will handle this request. The following code goes in the api/modules/groups.js file:

// POST API to fetch group details
router.post("/detail", auth, async function (request, result) {
    const user = request.user;
    const _id = request.fields._id;

    // check if group exists
    const group = await db.collection("groups").findOne({
        _id: ObjectId(_id)
    });

    if (group == null) {
        result.json({
            status: "error",
            message: "Group does not exists."
        });
        return;
    }

    // check if user is an admin or a member of the group
    let isMember = false;
    for (let a = 0; a < group.members.length; a++) {
        if (group.members[a].user._id.toString() == user._id.toString()) {
            isMember = true;
            break;
        }
    }

    if (group.createdBy._id.toString() != user._id.toString() && !isMember) {
        result.json({
            status: "error",
            message: "You are not a member of this group."
        });
        return;
    }

    result.json({
        status: "success",
        message: "Data has been fetched.",
        group: group,
        user: user
    });
});

If you have uploaded a picture of any group, you will not see it right now. Because we are using Node JS as the backend and Express framework, by default, does not allow direct access to the files. So we need to tell manually that we will allow the files inside the uploads/groups folder.

So open your api/server.js file and write the following line before starting the HTTP server.

// allow to read pictures from uploads/groups folder publicly
app.use("/uploads/groups", express.static(__dirname + "/uploads/groups"))

You need to refresh the front-end page again. And now you will see the group picture. You will see the group name, picture, and a button that says “Group members”. When clicked, we will show a modal and inside that modal, we will show all members of this group.

group detail
group detail

Before that, need to install the jQuery module in our Vue JS app. So run the following command in your terminal opened in the web folder:

> npm install jquery

After that, open your App.vue file and comment or remove the following line:

import "../public/assets/js/jquery-3.1.1.js"

And in your main.js file, add the following line:

// include jquery
window.$ = window.jQuery = require("jquery")

So back to your GroupDetailComponent.vue, we will create a method that will be called when the “Group members” button is clicked. And when it is clicked, we will show the bootstrap modal. The following code goes in the methods object:

// method to show modal to show all members
groupMembers: function () {
    jQuery("#group-members-modal").modal("show")
},

Then in your HTML code, we need to create a modal. It will be inside the <template> tag.

<!-- Modal -->
<div class="modal" id="group-members-modal">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Group members</h5>
                
                <!-- modal close button -->
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>

            <div class="modal-body">
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>User</th>
                            <th>Invited by</th>
                            <th>Status</th>
                            <th>Actions</th>
                        </tr>
                    </thead>

                    <tbody>
                        <!-- loop through all members -->
                        <tr v-for="member in group.members" v-bind:key="member._id">
                            <td v-text="member.user.name"></td>
                            <td v-text="member.sentBy.name"></td>
                            <td v-text="member.status"></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

Test the app now and click on the “Group members” button. You will see a list of all group members in a modal.





Please disable your adblocker or whitelist this site!