Revamp UI for profile page

pull/5494/head
Kamran Ahmed 8 months ago
parent e7277585d0
commit 634af33756
  1. 48
      src/components/UserPublicProfile/UserPublicActivityHeatmap.tsx
  2. 8
      src/components/UserPublicProfile/UserPublicProfileHeader.tsx
  3. 36
      src/components/UserPublicProfile/UserPublicProfilePage.tsx
  4. 83
      src/components/UserPublicProfile/UserPublicProgresses.tsx

@ -9,6 +9,15 @@ import dayjs from 'dayjs';
type UserActivityHeatmapProps = { type UserActivityHeatmapProps = {
activity: UserActivityCount; activity: UserActivityCount;
}; };
const legends = [
{ count: '1-2', color: 'bg-gray-200' },
{ count: '3-4', color: 'bg-gray-300' },
{ count: '5-9', color: 'bg-gray-500' },
{ count: '10-19', color: 'bg-gray-600' },
{ count: '20+', color: 'bg-gray-800' },
];
export function UserActivityHeatmap(props: UserActivityHeatmapProps) { export function UserActivityHeatmap(props: UserActivityHeatmapProps) {
const { activity } = props; const { activity } = props;
const data = Object.entries(activity.activityCount).map(([date, count]) => ({ const data = Object.entries(activity.activityCount).map(([date, count]) => ({
@ -20,7 +29,16 @@ export function UserActivityHeatmap(props: UserActivityHeatmapProps) {
const endDate = dayjs().toDate(); const endDate = dayjs().toDate();
return ( return (
<> <div className="rounded-lg border bg-white p-4">
<div className="-mx-4 mb-8 flex justify-between border-b px-4 pb-3">
<div className="">
<h2 className="mb-0.5 font-semibold">Activity</h2>
<p className="text-sm text-gray-500">
Progress updates over the past year
</p>
</div>
<span className="text-sm text-gray-400">Member since: June 2021</span>
</div>
<CalendarHeatmap <CalendarHeatmap
startDate={startDate} startDate={startDate}
endDate={endDate} endDate={endDate}
@ -51,7 +69,7 @@ export function UserActivityHeatmap(props: UserActivityHeatmapProps) {
const formattedDate = formatActivityDate(value.date); const formattedDate = formatActivityDate(value.date);
return { return {
'data-tooltip-id': 'user-activity-tip', 'data-tooltip-id': 'user-activity-tip',
'data-tooltip-content': `${value.count} Progress Update on ${formattedDate}`, 'data-tooltip-content': `${value.count} Updates - ${formattedDate}`,
}; };
}} }}
/> />
@ -60,6 +78,30 @@ export function UserActivityHeatmap(props: UserActivityHeatmapProps) {
id="user-activity-tip" id="user-activity-tip"
className="!rounded-lg !bg-gray-900 !p-1 !px-2 !text-sm" className="!rounded-lg !bg-gray-900 !p-1 !px-2 !text-sm"
/> />
</>
<div className="mt-4 flex items-center justify-between">
<span className="text-sm text-gray-400">
Number of topics marked as learning, or completed by day
</span>
<div className="flex items-center">
<span className="mr-2 text-xs text-gray-500">Less</span>
{legends.map((legend) => (
<div
key={legend.count}
className="flex items-center"
data-tooltip-id="user-activity-tip"
data-tooltip-content={`${legend.count} Updates`}
>
<div className={`h-3 w-3 ${legend.color} mr-1 rounded-sm`}></div>
</div>
))}
<span className="ml-2 text-xs text-gray-500">More</span>
<ReactTooltip
id="user-activity-tip"
className="!rounded-lg !bg-gray-900 !p-1 !px-2 !text-sm"
/>
</div>
</div>
</div>
); );
} }

@ -12,7 +12,7 @@ export function UserPublicProfileHeader(props: UserPublicProfileHeaderProps) {
const { headline, isAvailableForHire, isEmailVisible } = publicConfig!; const { headline, isAvailableForHire, isEmailVisible } = publicConfig!;
return ( return (
<div className="flex items-center gap-8"> <div className="flex items-center gap-6 container bg-white border p-8 rounded-xl">
<img <img
src={ src={
avatar avatar
@ -25,12 +25,12 @@ export function UserPublicProfileHeader(props: UserPublicProfileHeaderProps) {
<div> <div>
{isAvailableForHire && ( {isAvailableForHire && (
<span className="mb-1 inline-block rounded-md bg-green-100 px-2 py-1 text-xs font-medium text-green-700"> <span className="mb-1 inline-block rounded-md bg-green-100 px-2 py-1 text-sm text-green-700">
Available for hire Available for hire
</span> </span>
)} )}
<h1 className="text-2xl font-bold">{name}</h1> <h1 className="text-3xl font-bold">{name}</h1>
<p className="mt-1 text-sm text-gray-500">{headline}</p> <p className="mt-1 text-base text-gray-500">{headline}</p>
<div className="mt-3 flex items-center gap-2"> <div className="mt-3 flex items-center gap-2">
{links?.github && <UserLink href={links?.github} icon={Github} />} {links?.github && <UserLink href={links?.github} icon={Github} />}
{links?.linkedin && ( {links?.linkedin && (

@ -16,25 +16,23 @@ export function UserPublicProfilePage(props: UserPublicProfilePageProps) {
} = props; } = props;
return ( return (
<> <div className="bg-gray-200/40">
<PrivateProfileBanner <div className="container flex flex-col gap-8">
isOwnProfile={isOwnProfile} <PrivateProfileBanner
profileVisibility={profileVisibility} isOwnProfile={isOwnProfile}
/> profileVisibility={profileVisibility}
<section className="container mt-5 pb-10"> />
<UserPublicProfileHeader userDetails={props!} /> <UserPublicProfileHeader userDetails={props!} />
<div className="mt-10">
<UserActivityHeatmap activity={activity!} /> <UserActivityHeatmap activity={activity!} />
</div> <UserPublicProgresses
<div className="mt-10"> username={username!}
<UserPublicProgresses userId={userId!}
username={username!} roadmaps={props.roadmaps}
userId={userId!} publicConfig={props.publicConfig}
roadmaps={props.roadmaps} />
publicConfig={props.publicConfig} </div>
/> </div>
</div>
</section>
</>
); );
} }

@ -24,19 +24,50 @@ export function UserPublicProgresses(props: UserPublicProgressesProps) {
(roadmap) => roadmap.isCustomResource, (roadmap) => roadmap.isCustomResource,
); );
// <UserPublicProgressStats
// updatedAt={roadmap.updatedAt}
// title={roadmap.title}
// totalCount={roadmap.total}
// doneCount={roadmap.done}
// learningCount={roadmap.learning}
// skippedCount={roadmap.skipped}
// resourceId={roadmap.id}
// resourceType="roadmap"
// roadmapSlug={roadmap.roadmapSlug}
// username={username!}
// isCustomResource={true}
// userId={userId}
// />
return ( return (
<div> <div>
{roadmapVisibility !== 'none' && ( {customRoadmapVisibility !== 'none' && customRoadmaps?.length > 0 && (
<> <div className='mb-5'>
<h2 className="text-xs uppercase text-gray-400">My Skills</h2> <h2 className="mb-2 text-xs uppercase tracking-wide text-gray-400">
{roadmaps?.length === 0 ? ( Roadmaps made by me
<div className="mt-4 text-sm text-gray-500"> </h2>
No skills added yet. <div className="grid grid-cols-3">
</div> {customRoadmaps.map((roadmap, counter) => (
) : ( <a
<ul className="mt-4 grid grid-cols-2 gap-2 max-md:grid-cols-1"> target="_blank"
href={`/r/${roadmap.roadmapSlug}`}
key={roadmap.id + counter}
className="rounded-md border bg-white px-3 py-2 text-left text-sm shadow-sm transition-all hover:border-gray-300 hover:bg-gray-50"
>
{roadmap.title}
</a>
))}
</div>
</div>
)}
<div>
{roadmapVisibility !== 'none' && (
<>
<h2 className="text-xs uppercase text-gray-400">My Skills</h2>
<ul className="">
{roadmaps.map((roadmap, counter) => ( {roadmaps.map((roadmap, counter) => (
<li key={roadmap.id + counter}> <li key={roadmap.id + counter} className="bg-white">
<UserPublicProgressStats <UserPublicProgressStats
updatedAt={roadmap.updatedAt} updatedAt={roadmap.updatedAt}
title={roadmap.title} title={roadmap.title}
@ -54,35 +85,9 @@ export function UserPublicProgresses(props: UserPublicProgressesProps) {
</li> </li>
))} ))}
</ul> </ul>
)} </>
</> )}
)} </div>
{customRoadmapVisibility !== 'none' && customRoadmaps?.length > 0 && (
<>
<h2 className="mt-6 text-xs uppercase text-gray-400">My Roadmaps</h2>
<ul className="mt-4 grid grid-cols-2 gap-2 max-md:grid-cols-1">
{customRoadmaps.map((roadmap, counter) => (
<li key={roadmap.id + counter}>
<UserPublicProgressStats
updatedAt={roadmap.updatedAt}
title={roadmap.title}
totalCount={roadmap.total}
doneCount={roadmap.done}
learningCount={roadmap.learning}
skippedCount={roadmap.skipped}
resourceId={roadmap.id}
resourceType="roadmap"
roadmapSlug={roadmap.roadmapSlug}
username={username!}
isCustomResource={true}
userId={userId}
/>
</li>
))}
</ul>
</>
)}
</div> </div>
); );
} }

Loading…
Cancel
Save