Feat: implement client side functionality for user follow feature

This commit is contained in:
Aaron William Po
2023-11-27 22:04:55 -05:00
parent e0e22ba7af
commit 7c87be09cf
11 changed files with 300 additions and 25 deletions

View File

@@ -0,0 +1,66 @@
import useFollowStatus from '@/hooks/data-fetching/user-follows/useFollowStatus';
import useGetUsersFollowedByUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowedByUser';
import useGetUsersFollowingUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowingUser';
import sendUserFollowRequest from '@/requests/UserFollow/sendUserFollowRequest';
import GetUserSchema from '@/services/User/schema/GetUserSchema';
import { FC, useState } from 'react';
import { FaUserCheck, FaUserPlus } from 'react-icons/fa';
import { z } from 'zod';
interface UserFollowButtonProps {
mutateFollowerCount: ReturnType<typeof useGetUsersFollowingUser>['mutate'];
mutateFollowingCount: ReturnType<typeof useGetUsersFollowedByUser>['mutate'];
user: z.infer<typeof GetUserSchema>;
}
const UserFollowButton: FC<UserFollowButtonProps> = ({
user,
mutateFollowerCount,
mutateFollowingCount,
}) => {
const { isFollowed, mutate: mutateFollowStatus } = useFollowStatus(user.id);
const [isLoading, setIsLoading] = useState(false);
const onClick = async () => {
try {
setIsLoading(true);
await sendUserFollowRequest(user.id);
await Promise.all([
mutateFollowStatus(),
mutateFollowerCount(),
mutateFollowingCount(),
]);
setIsLoading(false);
} catch (e) {
setIsLoading(false);
}
};
return (
<button
type="button"
className={`btn-sm btn gap-2 rounded-2xl lg:btn-md ${
!isFollowed ? 'btn-ghost outline' : 'btn-primary'
}`}
onClick={() => {
onClick();
}}
disabled={isLoading}
>
{isFollowed ? (
<>
<FaUserCheck className="text-xl" />
Followed
</>
) : (
<>
<FaUserPlus className="text-xl" />
Follow
</>
)}
</button>
);
};
export default UserFollowButton;

View File

@@ -1,20 +1,30 @@
import useTimeDistance from '@/hooks/utilities/useTimeDistance';
import useGetUsersFollowedByUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowedByUser';
import useGetUsersFollowingUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowingUser';
import { FC } from 'react';
import { z } from 'zod';
import { format } from 'date-fns';
import GetUserSchema from '@/services/User/schema/GetUserSchema';
import useGetUsersFollowedByUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowedByUser';
import useGetUsersFollowingUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowingUser';
import UserAvatar from '../Account/UserAvatar';
import UserFollowButton from './UserFollowButton';
interface UserHeaderProps {
user: z.infer<typeof GetUserSchema>;
followerCount: ReturnType<typeof useGetUsersFollowingUser>['followerCount'];
followingCount: ReturnType<typeof useGetUsersFollowedByUser>['followingCount'];
}
const UserHeader: FC<UserHeaderProps> = ({ user, followerCount, followingCount }) => {
const UserHeader: FC<UserHeaderProps> = ({ user }) => {
const timeDistance = useTimeDistance(new Date(user.createdAt));
const { followingCount, mutate: mutateFollowingCount } = useGetUsersFollowedByUser({
userId: user.id,
pageSize: 10,
});
const { followerCount, mutate: mutateFollowerCount } = useGetUsersFollowingUser({
userId: user.id,
pageSize: 10,
});
return (
<header className="card text-center items-center">
<div className="card-body items-center w-full">
@@ -42,6 +52,13 @@ const UserHeader: FC<UserHeaderProps> = ({ user, followerCount, followingCount }
</span>
)}
</span>
<div className="h-20 flex items-center justify-center">
<UserFollowButton
mutateFollowerCount={mutateFollowerCount}
user={user}
mutateFollowingCount={mutateFollowingCount}
/>
</div>
</div>
</header>
);