From 2a578fb614da71b67198f291a81e9b809771497b Mon Sep 17 00:00:00 2001 From: atrip0305 Date: Wed, 20 May 2026 15:10:32 +0530 Subject: [PATCH] feat: show contributor join date on public profile --- src/app/[handle]/page.tsx | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/app/[handle]/page.tsx b/src/app/[handle]/page.tsx index 1c75591..e58148f 100644 --- a/src/app/[handle]/page.tsx +++ b/src/app/[handle]/page.tsx @@ -29,6 +29,32 @@ function timeAgo(dateStr: string): string { const months = Math.floor(days / 30); return `${months} month${months > 1 ? 's' : ''} ago`; } +function formatJoinDate(dateStr: string): string { + const joined = new Date(dateStr); + const now = new Date(); + + const diffMs = now.getTime() - joined.getTime(); + const days = Math.floor(diffMs / 86400000); + + if (days === 0) { + return 'Joined today'; + } + + if (days < 30) { + return `Joined ${days} day${days > 1 ? 's' : ''} ago`; + } + + const months = Math.floor(days / 30); + + if (months < 12) { + return `Joined ${months} month${months > 1 ? 's' : ''} ago`; + } + + return `Joined ${joined.toLocaleDateString('en-US', { + month: 'long', + year: 'numeric', + })}`; +} type Achievement = { id: string; @@ -64,6 +90,7 @@ type ProfileData = { githubHandle: string; displayName: string | null; avatarUrl: string | null; + joinedAt: string; level: number; xp: number; prsMerged: number; @@ -89,7 +116,7 @@ async function loadProfileData(handle: string): Promise { const { data: profile } = await service .from('profiles') - .select('id, github_handle, display_name, avatar_url, level, xp, github_streak') + .select('id, github_handle, display_name, avatar_url, level, xp, github_streak, created_at') .eq('github_handle', handle) .maybeSingle(); @@ -254,6 +281,7 @@ async function loadProfileData(handle: string): Promise { githubHandle: profile.github_handle, displayName: profile.display_name, avatarUrl: profile.avatar_url, + joinedAt: profile.created_at, level: profile.level, xp: profile.xp, prsMerged, @@ -360,6 +388,9 @@ export default async function PublicProfile({ params }: { params: { handle: stri textToCopy={`${process.env.NEXT_PUBLIC_APP_URL ?? 'https://mergeship.dev'}/@${profile.githubHandle}`} />

+

+ {formatJoinDate(profile.joinedAt)} +

{profile.prsMerged} PRS MERGED