feat: complete frontend UI - comparison views, profile, explore, layout
This commit is contained in:
157
src/app/(main)/profile/page.tsx
Normal file
157
src/app/(main)/profile/page.tsx
Normal file
@@ -0,0 +1,157 @@
|
||||
"use client"
|
||||
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { BarChart3, Eye, Calendar, Plus, ArrowRight } from "lucide-react"
|
||||
import Link from "next/link"
|
||||
|
||||
const mockUser = {
|
||||
name: "Alex Johnson",
|
||||
email: "alex@example.com",
|
||||
avatar: "/placeholder-avatar.png",
|
||||
}
|
||||
|
||||
const mockComparisons = [
|
||||
{
|
||||
id: "1",
|
||||
title: "React vs Vue vs Svelte",
|
||||
items: ["React", "Vue", "Svelte"],
|
||||
tags: ["Tech", "JavaScript"],
|
||||
overallScore: 8.5,
|
||||
views: 1247,
|
||||
createdAt: "2024-01-15",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "GPT-4 vs Claude vs Gemini",
|
||||
items: ["GPT-4", "Claude 3", "Gemini Pro"],
|
||||
tags: ["AI", "Products"],
|
||||
overallScore: 8.8,
|
||||
views: 3891,
|
||||
createdAt: "2024-01-10",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "Notion vs Obsidian vs Roam",
|
||||
items: ["Notion", "Obsidian", "Roam Research"],
|
||||
tags: ["Productivity"],
|
||||
overallScore: 7.5,
|
||||
views: 892,
|
||||
createdAt: "2024-01-05",
|
||||
},
|
||||
]
|
||||
|
||||
const stats = [
|
||||
{ label: "Total Comparisons", value: 12, icon: BarChart3 },
|
||||
{ label: "Total Views", value: "8.2K", icon: Eye },
|
||||
]
|
||||
|
||||
export default function ProfilePage() {
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto p-4 sm:p-6 space-y-8">
|
||||
<div className="flex items-center gap-6">
|
||||
<Avatar className="size-20">
|
||||
<AvatarImage src={mockUser.avatar} />
|
||||
<AvatarFallback className="text-2xl bg-primary/10 text-primary font-semibold">
|
||||
{mockUser.name.split(" ").map((n) => n[0]).join("")}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="space-y-1.5">
|
||||
<h1 className="text-2xl font-bold">{mockUser.name}</h1>
|
||||
<p className="text-muted-foreground">{mockUser.email}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
{stats.map((stat) => (
|
||||
<Card key={stat.label}>
|
||||
<CardContent className="flex items-center gap-4 p-4">
|
||||
<div className="size-10 rounded-lg bg-primary/10 flex items-center justify-center">
|
||||
<stat.icon className="size-5 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-bold">{stat.value}</p>
|
||||
<p className="text-sm text-muted-foreground">{stat.label}</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="text-xl font-semibold">My Comparisons</h2>
|
||||
<Link href="/compare">
|
||||
<Button size="sm" className="gap-2">
|
||||
<Plus className="size-4" />
|
||||
New Comparison
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{mockComparisons.length > 0 ? (
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
{mockComparisons.map((comparison) => (
|
||||
<Link key={comparison.id} href={`/compare/${comparison.id}`}>
|
||||
<Card className="h-full transition-all hover:border-primary hover:shadow-md">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base line-clamp-1">{comparison.title}</CardTitle>
|
||||
<CardDescription className="flex items-center gap-2 text-xs">
|
||||
<Calendar className="size-3.5" />
|
||||
{comparison.createdAt}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{comparison.tags.map((tag) => (
|
||||
<Badge key={tag} variant="secondary" className="text-xs">
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{comparison.items.join(" vs ")}
|
||||
</span>
|
||||
<div className="flex items-center gap-3 text-sm text-muted-foreground">
|
||||
<span className="flex items-center gap-1">
|
||||
<Eye className="size-3.5" />
|
||||
{comparison.views.toLocaleString()}
|
||||
</span>
|
||||
<span className="font-semibold text-foreground">
|
||||
{comparison.overallScore}/10
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<Card className="p-8 text-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="size-12 rounded-full bg-muted flex items-center justify-center">
|
||||
<BarChart3 className="size-6 text-muted-foreground" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium">No comparisons yet</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Create your first comparison to get started
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/compare">
|
||||
<Button className="gap-2">
|
||||
<Plus className="size-4" />
|
||||
Create Comparison
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user