diff --git a/src/app/u/[username]/page.tsx b/src/app/u/[username]/page.tsx index 4ad8b075..1c64a4bb 100644 --- a/src/app/u/[username]/page.tsx +++ b/src/app/u/[username]/page.tsx @@ -1,35 +1,45 @@ import { Metadata } from "next"; import BadgeSection from "@/components/BadgeSection"; -import StatsCard from "@/components/StatsCard"; -import CopyLinkButton from "@/components/CopyLinkButton"; -import { getUserByUsername } from "@/lib/supabase"; -import { - fetchPublicTopRepos, - fetchPublicContributions, - fetchPublicStreak, - type PublicProfileData, -} from "@/lib/public-profile-data"; +import BackToDashboard from "@/components/BackToDashboard"; +interface PublicProfileData { + username: string; + userId: string; + repos: Array<{ name: string; commits: number; url: string }>; + contributions: { + days: number; + total: number; + data: Record; + }; + streak: { + current: number; + longest: number; + lastCommitDate: string | null; + totalActiveDays: number; + }; +} async function fetchPublicProfile( - username: string + username: string, ): Promise { - const user = await getUserByUsername(username); - if (!user) return null; + const baseUrl = + process.env.NEXT_PUBLIC_APP_URL || + process.env.NEXTAUTH_URL || + "http://localhost:3000"; - const githubToken = process.env.GITHUB_TOKEN; - const [repos, contributions, streak] = await Promise.all([ - fetchPublicTopRepos(user.github_login, githubToken, 30), - fetchPublicContributions(user.github_login, githubToken, 30), - fetchPublicStreak(user.github_login, githubToken), - ]); + try { + const res = await fetch(`${baseUrl}/api/public/${username}`, { + cache: "no-store", + }); - return { - username: user.github_login, - userId: user.id, - repos, - contributions, - streak, - }; + if (!res.ok) { + return null; + } + + return res.json(); + } catch (error) { + console.error(`Error fetching public profile for ${username}:`, error); + return null; + } } export async function generateMetadata({ @@ -40,7 +50,10 @@ export async function generateMetadata({ const { username } = params; const profile = await fetchPublicProfile(username); - const baseUrl = process.env.NEXT_PUBLIC_APP_URL || process.env.NEXTAUTH_URL || "http://localhost:3000"; + const baseUrl = + process.env.NEXT_PUBLIC_APP_URL || + process.env.NEXTAUTH_URL || + "http://localhost:3000"; const profileUrl = `${baseUrl}/u/${username}`; if (!profile) { @@ -79,22 +92,12 @@ export default async function PublicProfilePage({ if (!profile) { return (
-
+

Profile Not Found

-

- This profile is not available or has not been made public. -

-

- If this is your profile, go to{" "} - - Settings - {" "} - and enable Public Profile. +

+ This profile is not available or is private.

-
-
-
-

- @{profile.username}'s Profile -

- -
-

- GitHub activity and coding stats -

-
- {/* Download stats card button — client component */} - -
+ {/* Header */} + +
+ + +
+

+ @{profile.username}'s Profile +

+ +

+ GitHub activity and coding stats +

+
+
{/* Row 1: Contribution graph + Streak */}
@@ -205,11 +198,9 @@ function PublicContributionGraph({ className="aspect-square rounded-sm" style={{ backgroundColor: - day.commits > 0 ? "var(--accent)" : "var(--control)", - opacity: day.commits > 0 - ? Math.max(0.2, Math.min(day.commits / 10, 1)) - : 1, + ? `hsl(var(--accent) / ${Math.min(day.commits / 10, 1)})` + : "var(--control)", }} title={`${day.day}: ${day.commits} commits`} /> @@ -225,7 +216,16 @@ function PublicContributionGraph({ * Public variant of StreakTracker component. * Displays data passed as props. */ -function PublicStreakTracker({ streak }: { streak: any }) { +function PublicStreakTracker({ + streak, +}: { + streak: { + current: number; + longest: number; + lastCommitDate: string | null; + totalActiveDays: number; + }; +}) { const stats = [ { label: "Current Streak", @@ -321,7 +321,7 @@ function PublicTopRepos({ {repos.map((repo, idx) => { const barWidth = Math.max( Math.round((repo.commits / maxCommits) * 100), - 4 + 4, ); const shortName = repo.name.split("/")[1] ?? repo.name; return ( @@ -357,3 +357,8 @@ function PublicTopRepos({
); } + + + + + diff --git a/src/components/BackToDashboard.tsx b/src/components/BackToDashboard.tsx new file mode 100644 index 00000000..d7c45a0a --- /dev/null +++ b/src/components/BackToDashboard.tsx @@ -0,0 +1,26 @@ +"use client"; + +import Link from "next/link"; +import { useSession } from "next-auth/react"; + +interface Props { + username: string; +} + +export default function BackToDashboard({ username }: Props) { + const { data: session } = useSession(); + +const currentUser = session?.githubLogin; + const isOwner = currentUser === username; + + if (!isOwner) return null; + + return ( + + ← Back to dashboard + + ); +} \ No newline at end of file