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