Skip to content

Commit

Permalink
Merge pull request #29 from fiit-tp7-2023/AB#352-display-user-followers
Browse files Browse the repository at this point in the history
  • Loading branch information
brano-hozza authored Apr 29, 2024
2 parents 8b09dc7 + 06a3cab commit 34b80a9
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 11 deletions.
156 changes: 151 additions & 5 deletions pages/profile/[address].vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
<div class="info ml-6">
<h2 class="text-xl font-mono">{{ userProfile.address }}</h2>
<div class="follow-info mt-4">
<h3>Followers: {{ userProfile.followerCount }}</h3>
<h3>Following: {{ userProfile.followingCount }}</h3>
<h3 @click="toggleFollowersModal">Followers: {{ userProfile.followerCount }}</h3>
<h3 @click="toggleFollowingModal">Following: {{ userProfile.followingCount }}</h3>
</div>
<button v-if="!myProfile" class="follow-button" @click="toggleFollow">
{{ userProfile.isFollowed ? 'Unfollow' : 'Follow' }}
Expand All @@ -31,21 +31,95 @@
/>
<button v-if="hasMore" class="text-white bg-pink-500 rounded p-2 w-full" @click="loadMore">Load more</button>
</div>
<div v-if="showFollowersModal" class="modal">
<div v-if="showFollowersModal && userProfile.followerCount > 0" class="modal">
<div class="modal-content">
<span class="close" @click="showFollowersModal = false">&times;</span>
<h1 class="p-2">Followers</h1>
<ul>
<li v-for="follower in userFollowers" :key="follower.follower.address">
<hr />
<div class="flex">
<div class="follower-avatar-container p-2">
<img
v-if="follower.follower.profilePicture"
:src="follower.follower.profilePicture"
alt="Profile Picture"
class="follower-avatar"
/>
<span v-else class="follower-avatar placeholder"></span>
</div>
<div class="follower-info">
<a :href="`/profile/${follower.follower.address}`" class="follower-link">
<p>{{ follower.follower.address }}</p>
</a>
</div>
</div>
</li>
</ul>
</div>
</div>
<div v-else-if="showFollowersModal && userProfile.followerCount === 0" class="modal">
<div class="modal-content">
<span class="close" @click="showFollowersModal = false">&times;</span>
<h1 class="p-2">Followers</h1>
<p class="p-2">No followers found.</p>
</div>
</div>
</div>
<div v-if="showFollowingModal" class="modal">
<div v-if="showFollowingModal && userProfile.followingCount > 0" class="modal">
<div class="modal-content">
<span class="close" @click="showFollowingModal = false">&times;</span>
<h1 class="p-2">Following</h1>
<ul>
<li v-for="following in userFollowing" :key="following.followedUser.address">
<hr />
<div class="flex">
<div class="follower-avatar-container p-2">
<img
v-if="following.followedUser.profilePicture"
:src="following.followedUser.profilePicture"
alt="Profile Picture"
class="follower-avatar"
/>
<span v-else class="follower-avatar placeholder"></span>
</div>
<div class="follower-info">
<a :href="`/profile/${following.followedUser.address}`" class="follower-link">
<p>{{ following.followedUser.address }}</p>
</a>
</div>
</div>
</li>
</ul>
</div>
</div>
<div v-else-if="showFollowingModal && userProfile.followingCount === 0" class="modal">
<div class="modal-content">
<span class="close" @click="showFollowingModal = false">&times;</span>
<h1 class="p-2">Following</h1>
<p class="p-2">No profiles followed.</p>
</div>
</div>
</div>
</div>
</template>

<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useAccountStore } from '~/store';
import type { UserPostResponseDTO, UserProfileDTO } from '~/types/dtos';
import type { UserFollowersDTO, UserFollowingDTO, UserPostResponseDTO, UserProfileDTO } from '~/types/dtos';
import NftPost from '~/components/posts/NftPost.vue';
const error = ref<Error | null>(null);
const route = useRoute();
const accountStore = useAccountStore();
const userProfile = ref<UserProfileDTO | null>(null);
const userFollowers = ref<UserFollowersDTO | null>(null);
const userFollowing = ref<UserFollowingDTO | null>(null);
const fetchUserProfile = async () => {
const address = route.params.address; // Get the address from the URL parameter
Expand All @@ -72,6 +146,23 @@ const toggleFollow = async () => {
}
};
const showFollowersModal = ref(false);
const showFollowingModal = ref(false);
const toggleFollowersModal = async () => {
showFollowersModal.value = !showFollowersModal.value;
if (showFollowersModal.value) {
await getFollowers();
}
};
const toggleFollowingModal = async () => {
showFollowingModal.value = !showFollowingModal.value;
if (showFollowingModal.value) {
await getFollowing();
}
};
const unfollowUser = async () => {
await $fetch(`/api/user/${route.params.address}/following`, {
method: 'DELETE',
Expand All @@ -92,6 +183,24 @@ const followUser = async () => {
fetchUserProfile(); // Re-fetch or adjust local state to show updated follower count
};
const getFollowers = async () => {
const data = await $fetch(`/api/user/${route.params.address}/followers`, {
headers: {
Authorization: `Bearer ${accountStore.accessToken}`,
},
});
userFollowers.value = data;
};
const getFollowing = async () => {
const data = await $fetch(`/api/user/${route.params.address}/following`, {
headers: {
Authorization: `Bearer ${accountStore.accessToken}`,
},
});
userFollowing.value = data;
};
const posts = ref<UserPostResponseDTO[]>([]);
const pageSize = 20;
const pageNumber = ref(1);
Expand Down Expand Up @@ -185,7 +294,7 @@ h2 {
.follow-button {
@apply mt-5 py-2.5 px-5 bg-[#f472b6] text-white border-none rounded cursor-pointer transition-colors;
width: 100%; /* Ensures the button stretches to fill its container */
width: 100%;
}
.follow-button:hover {
Expand All @@ -194,7 +303,7 @@ h2 {
.follow-info {
@apply flex gap-5 mt-2.5 justify-end items-center;
width: 100%; /* This ensures the flex container takes full width */
width: 100%;
}
.follow-info h3 {
Expand All @@ -218,4 +327,41 @@ hr {
@apply justify-center;
}
}
.modal {
@apply fixed top-0 left-0 w-full h-full bg-[rgba(0,0,0,0.5)] flex items-start p-48 justify-center;
}
.modal-content {
@apply bg-[#1e293b] p-5 rounded w-11/12 max-w-5xl relative;
}
.close {
@apply absolute top-2 right-2 text-xl cursor-pointer;
}
.follower-item {
@apply flex items-center mt-2;
}
.follower-info {
@apply flex flex-col;
}
.follower-avatar-container {
@apply flex-shrink-0; /* Prevents the avatar container from shrinking */
}
.follower-avatar,
.follower-avatar.placeholder {
@apply w-8 h-8 rounded-full bg-gray-300; /* Sets the width and height, and background color for placeholder */
display: inline-block; /* Ensures that the img element behaves like a block element filling the container */
}
.follower-avatar img {
@apply w-full h-full object-cover; /* Ensures the image covers the entire area of the avatar */
}
.follower-link {
@apply text-white no-underline hover:underline py-3;
}
</style>
Loading

0 comments on commit 34b80a9

Please sign in to comment.