Files
conve-x/src/components/UserProfile.tsx
T

120 lines
3.9 KiB
TypeScript
Raw Normal View History

'use client';
import { UserDto } from '@/app/types';
import { useUser } from '@clerk/nextjs';
import { useMutation, useQuery } from 'convex/react';
2023-09-11 00:40:14 -05:00
import Image from 'next/image';
import { AiFillCalendar } from 'react-icons/ai';
import { api } from '../../convex/_generated/api';
2023-09-11 00:40:14 -05:00
2023-09-11 13:49:13 -05:00
export default function UserProfile({ user }: { user: UserDto }) {
const { isLoaded, isSignedIn, user: currentUser } = useUser();
const addFollow = useMutation(api.follows.addFollow);
const removeFollow = useMutation(api.follows.removeFollow);
const followerCount = useQuery(api.follows.getUserFollowerCount, {
userId: user._id,
});
const followingCount = useQuery(api.follows.getUserFollowingCount, {
userId: user._id,
});
const isFollowing = useQuery(api.follows.getFollowing, {
followingId: user._id,
});
const postCount = useQuery(api.posts.getUserPostCount, { userId: user._id });
const username = user.clerkUsername ?? user._id;
2023-09-11 00:40:14 -05:00
const userCreatedDate = new Date(user._creationTime);
2023-09-11 00:40:14 -05:00
const monthJoined = userCreatedDate.toLocaleString(undefined, {
month: 'short',
});
2023-09-11 00:40:14 -05:00
const yearJoined = userCreatedDate.getFullYear();
const countDataLoaded =
postCount !== undefined &&
followerCount !== undefined &&
followingCount !== undefined;
async function handleFollowButtonClick() {
if (isFollowing) {
await removeFollow({ followingId: user._id });
return;
}
await addFollow({ followingId: user._id });
}
2023-09-11 00:40:14 -05:00
return (
<div className='w-full'>
2023-09-12 23:12:12 -05:00
<div className='shadow-md bg-gradient-to-r from-violet-600 via-violet-600 to-indigo-600 rounded-t-md pt-20 px-5'>
2023-09-11 00:40:14 -05:00
<div className='flex items-center gap-4 -mb-[25px]'>
2023-09-12 23:12:12 -05:00
<div className='flex-shrink-0'>
2023-09-11 00:40:14 -05:00
<Image
alt='user profile image'
src={user.clerkImageUrl}
2023-09-11 00:40:14 -05:00
width={100}
height={100}
className='rounded-full object-cover border-4 border-primary-accent'
/>
</div>
<div className='flex flex-col-reverse mb-[25px] flex-1 min-w-0 gap-0.5 md:flex-row md:mb-0 md:gap-2'>
<div className='flex flex-col min-w-0 text-white'>
<h1
className='font-bold overflow-hidden text-ellipsis'
title={username}
>
{username}
</h1>
<div className='flex gap-2 items-center text-sm'>
<AiFillCalendar className='w-4 h-4' />
{`Joined ${monthJoined} ${yearJoined}`}
</div>
</div>
<div>
{isLoaded && isSignedIn && currentUser.id !== user.clerkUserId ? (
<button
onClick={handleFollowButtonClick}
type='button'
className={`py-0.5 px-3 rounded-full text-sm border border-white text-white ${
isFollowing ? 'bg-primary-accent' : 'o'
}`}
>
Follow
</button>
) : null}
2023-09-11 00:40:14 -05:00
</div>
</div>
</div>
</div>
<div className='flex flex-1 bg-white dark:bg-primary-gray pl-5 border border-gray-600 border-b-0'>
<div className='flex flex-col min-h-[25px] items-start gap-1 py-1 pl-[116px] md:flex-row md:items-center md:gap-4'>
{countDataLoaded ? (
<>
<div>
<span className='font-bold whitespace-nowrap'>{postCount}</span>{' '}
posts
</div>
<div className='min-w-0'>
<span className='font-bold whitespace-nowrap'>
{followerCount}
</span>{' '}
followers
</div>
<div>
<span className='font-bold whitespace-nowrap'>
{followingCount}
</span>{' '}
following
</div>
</>
) : null}
</div>
</div>
2023-09-11 00:40:14 -05:00
</div>
);
}