diff --git a/src/app/(main)/profile/page.tsx b/src/app/(main)/profile/page.tsx index cf31fdb..f0644fa 100644 --- a/src/app/(main)/profile/page.tsx +++ b/src/app/(main)/profile/page.tsx @@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Skeleton } from "@/components/ui/skeleton" -import { BarChart3, Eye, Calendar, Plus, ArrowRight, RefreshCw, LogIn } from "lucide-react" +import { BarChart3, Eye, Calendar, Plus, RefreshCw, LogIn } from "lucide-react" import Link from "next/link" import { useSession } from "@/lib/auth-client" @@ -17,7 +17,8 @@ interface Comparison { items: string[] tags: string[] viewCount: number - overallScore: number + status: string + isPublic: boolean createdAt: string } @@ -25,6 +26,7 @@ interface UserComparisonsResponse { comparisons: Comparison[] total: number page: number + limit: number } interface UserStats { @@ -33,21 +35,102 @@ interface UserStats { } export default function ProfilePage() { - // TODO: Replace with real auth session data - const user = { name: "Demo User", email: "demo@example.com", avatar: "" } - const stats = [ - { label: "Comparisons", value: "0", icon: BarChart3 }, - { label: "Total Views", value: "0", icon: Eye }, + const { data: session, isPending: sessionLoading } = useSession() + const [comparisons, setComparisons] = useState([]) + const [total, setTotal] = useState(0) + const [page, setPage] = useState(1) + const [stats, setStats] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + + const limit = 20 + + const fetchComparisons = useCallback(async (pageNum: number) => { + setLoading(true) + setError(null) + try { + const params = new URLSearchParams({ + page: pageNum.toString(), + limit: limit.toString(), + }) + const res = await fetch(`/api/user/comparisons?${params}`) + if (res.status === 401) { + setError("Not authenticated") + return + } + if (!res.ok) throw new Error("Failed to fetch comparisons") + const data: UserComparisonsResponse = await res.json() + setComparisons(data.comparisons) + setTotal(data.total) + setPage(pageNum) + } catch (err) { + setError(err instanceof Error ? err.message : "Something went wrong") + } finally { + setLoading(false) + } + }, []) + + const fetchStats = useCallback(async () => { + try { + const res = await fetch("/api/user/stats") + if (res.ok) { + const data: UserStats = await res.json() + setStats(data) + } + } catch { + // Stats are non-critical, don't block the page + } + }, []) + + useEffect(() => { + if (!sessionLoading && session?.user) { + fetchComparisons(1) + fetchStats() + } else if (!sessionLoading && !session?.user) { + setLoading(false) + } + }, [sessionLoading, session, fetchComparisons, fetchStats]) + + // Not authenticated — show sign-in prompt + if (!sessionLoading && !session?.user) { + return ( +
+ +
+
+ +
+
+

Sign in to view your profile

+

+ View your comparisons and stats +

+
+ + + +
+
+
+ ) + } + + const user = session.user + const statsCards = [ + { label: "Comparisons", value: stats?.totalComparisons ?? 0, icon: BarChart3 }, + { label: "Total Views", value: stats?.totalViews ?? 0, icon: Eye }, ] - const comparisons: Comparison[] = [] return (
- + - {user.name.split(" ").map((n) => n[0]).join("")} + {user.name?.split(" ").map((n) => n[0]).join("") ?? "?"}
@@ -56,15 +139,18 @@ export default function ProfilePage() {
+ {/* Stats cards */}
- {stats.map((stat) => ( + {statsCards.map((stat) => (
-

{stat.value}

+

+ {loading ? : stat.value.toLocaleString()} +

{stat.label}

@@ -72,6 +158,7 @@ export default function ProfilePage() { ))}
+ {/* User comparisons */}

My Comparisons

@@ -83,16 +170,50 @@ export default function ProfilePage() {
- {comparisons.length > 0 ? ( + {loading ? ( +
+ {[...Array(4)].map((_, i) => ( + + + + + + +
+ + +
+ +
+
+ ))} +
+ ) : error ? ( + +
+
+ +
+
+

Failed to load comparisons

+

{error}

+
+ +
+
+ ) : comparisons.length > 0 ? (
{comparisons.map((comparison) => ( - + {comparison.title} - {comparison.createdAt} + {new Date(comparison.createdAt).toLocaleDateString()} @@ -112,9 +233,9 @@ export default function ProfilePage() { {comparison.viewCount.toLocaleString()} - - {comparison.overallScore}/10 - + {!comparison.isPublic && ( + Draft + )}
@@ -143,7 +264,20 @@ export default function ProfilePage() {
)} + + {/* Pagination */} + {!loading && comparisons.length > 0 && comparisons.length < total && ( +
+ +
+ )} ) -} \ No newline at end of file +}