Skip to content

Commit

Permalink
follow user from user-list
Browse files Browse the repository at this point in the history
  • Loading branch information
Bardala committed Nov 17, 2023
1 parent 2145606 commit 43bbabe
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 58 deletions.
29 changes: 29 additions & 0 deletions frontend/src/components/FollowButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useFollow } from '../hooks/useFollow';

export const FollowButton: React.FC<{ userId: string }> = props => {
const { userId } = props;
const { followMutation, unfollowMutation, isFollowing } = useFollow(userId);

return (
<>
{isFollowing ? (
<button
onClick={() => unfollowMutation.mutate()}
disabled={unfollowMutation.isLoading}
className="unfollow"
style={{ backgroundColor: '#41c541' }}
>
Following
</button>
) : (
<button
onClick={() => followMutation.mutate()}
className="follow"
disabled={followMutation.isLoading}
>
Follow
</button>
)}
</>
);
};
49 changes: 6 additions & 43 deletions frontend/src/components/UserInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,24 @@
import { FollowUserRes, GetFollowersRes, UnFollowUserRes, UserCard } from '@nest/shared';
import { useMutation, useQuery } from '@tanstack/react-query';
import { UserCard } from '@nest/shared';
import formatDistanceToNow from 'date-fns/formatDistanceToNow';

import { useAuthContext } from '../context/AuthContext';
import { ApiError } from '../fetch/auth';
import { followUserApi, unfollowUserApi, userFollowersApi } from '../utils/api';
import { useFollow } from '../hooks/useFollow';
import { FollowButton } from './FollowButton';

export const UserInfoCard: React.FC<{ userCard: UserCard; blogsLength: number }> = props => {
const { userCard } = props;
let { currUser } = useAuthContext();
const key = ['followers', userCard.id];

const followersQuery = useQuery<GetFollowersRes, ApiError>(key, userFollowersApi(userCard.id), {
enabled: !!currUser?.jwt && !!userCard.id,
});

const followMutation = useMutation<FollowUserRes, ApiError>(followUserApi(userCard.id), {
onSuccess: () => followersQuery.refetch(),
});
const unfollowMutation = useMutation<UnFollowUserRes, ApiError>(unfollowUserApi(userCard.id), {
onSuccess: () => followersQuery.refetch(),
});

const isFollowing = followersQuery.data?.followers.some(follower => follower.id === currUser?.id);
const { followersQuery } = useFollow(userCard.id);

return (
<div className="user-information">
<div className="card-header">
<h2 className="page">{userCard.username} card</h2>
{currUser && currUser.username !== userCard.username && (
<>
{isFollowing ? (
<button
onClick={() => unfollowMutation.mutate()}
disabled={unfollowMutation.isLoading}
className="unfollow"
style={{ backgroundColor: '#41c541' }}
>
Following
</button>
) : (
<button
onClick={() => followMutation.mutate()}
className="follow"
disabled={followMutation.isLoading}
>
Follow
</button>
)}
</>
<FollowButton userId={userCard.id} />
)}
</div>
{userCard.username === currUser?.username && (
<>
<p>Email: {userCard.email}</p>
</>
)}
{userCard.username === currUser?.username && <p>Email: {userCard.email}</p>}
<p>Username: {userCard.username}</p>
<p>Followers: {followersQuery.data?.followers?.length || 0}</p>
{/* <p>Blogs: {blogsLength}</p> *this should have its own api */}
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/hooks/useFollow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { FollowUserRes, GetFollowersRes, UnFollowUserRes } from '@nest/shared';
import { useMutation, useQuery } from '@tanstack/react-query';

import { useAuthContext } from '../context/AuthContext';
import { ApiError } from '../fetch/auth';
import { followUserApi, unfollowUserApi, userFollowersApi } from '../utils/api';

export const useFollow = (userId: string) => {
const { currUser } = useAuthContext();
const key = ['followers', userId];

const followersQuery = useQuery<GetFollowersRes, ApiError>(key, userFollowersApi(userId), {
enabled: !!currUser?.jwt && !!userId,
});

const followMutation = useMutation<FollowUserRes, ApiError>(followUserApi(userId), {
onSuccess: () => followersQuery.refetch(),
});
const unfollowMutation = useMutation<UnFollowUserRes, ApiError>(unfollowUserApi(userId), {
onSuccess: () => followersQuery.refetch(),
});

const isFollowing = followersQuery.data?.followers.some(follower => follower.id === currUser?.id);

return {
followMutation,
unfollowMutation,
isFollowing,
followersQuery,
};
};
4 changes: 3 additions & 1 deletion frontend/src/pages/UsersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { GetUsersListRes } from '@nest/shared';
import { useQuery } from '@tanstack/react-query';
import { Link } from 'react-router-dom';

import { FollowButton } from '../components/FollowButton';
import { useAuthContext } from '../context/AuthContext';
import { ApiError } from '../fetch/auth';
import '../styles/users-list.css';
Expand All @@ -24,10 +25,11 @@ export const UsersList = () => {
<ul>
{users &&
users.map(user => (
<li key={user.id}>
<li key={user.id} className="user-icon">
<Link to={`/u/${user.id}`}>
<p className="username">{user.username}</p>
</Link>
<FollowButton userId={user.id} />
</li>
))}
</ul>
Expand Down
20 changes: 6 additions & 14 deletions frontend/src/styles/users-list.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,11 @@
padding: 2px;
}

.followers-count::before {
background-image:
url("https://cdn-icons-png.flaticon.com/512/1077/1077035.png");
}

.blogs-count::before {
background-image:
url("https://cdn-icons-png.flaticon.com/512/25/25657.png");
}

.comments-count::before {
background-image:
url("https://cdn-icons-png.flaticon.com/512/25/25663.png");
.user-icon {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
}

@media screen and (max-width: 600px) {
Expand All @@ -108,4 +100,4 @@
.counts-container p {
margin-bottom: 5px;
}
}
}

0 comments on commit 43bbabe

Please sign in to comment.