305 lines
11 KiB
TypeScript
305 lines
11 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
|
||
type TabType = "friends" | "dating";
|
||
|
||
interface Profile {
|
||
id: string;
|
||
name: string;
|
||
age: number;
|
||
location: string;
|
||
tags: string[];
|
||
bio: string;
|
||
gradient: string;
|
||
initial: string;
|
||
avatarColor: string;
|
||
photo: string;
|
||
}
|
||
|
||
interface MatchCard {
|
||
id: string;
|
||
name: string;
|
||
location: string;
|
||
timeAgo: string;
|
||
initial: string;
|
||
color: string;
|
||
photo: string;
|
||
}
|
||
|
||
const MOCK_PROFILES: Profile[] = [
|
||
{
|
||
id: "1",
|
||
name: "林晓雨",
|
||
age: 28,
|
||
location: "大理",
|
||
tags: ["本科学历", "远程工作者", "数字游民", "咖啡爱好者"],
|
||
bio: "数字游民三年,目前在云南大理远程做产品设计。喜欢爬山、摄影,周末常去洱海边发呆。",
|
||
gradient: "from-rose-400 via-pink-400 to-fuchsia-400",
|
||
initial: "林",
|
||
avatarColor: "bg-rose-500",
|
||
photo: "https://i.pravatar.cc/150?img=1",
|
||
},
|
||
{
|
||
id: "2",
|
||
name: "陈浩然",
|
||
age: 32,
|
||
location: "成都",
|
||
tags: ["硕士学历", "独立开发者", "自由职业者", "素食主义"],
|
||
bio: "在成都住了两年,做独立开发。喜欢冲浪和冥想,寻找志同道合的旅伴一起探索世界。",
|
||
gradient: "from-amber-400 via-orange-400 to-red-400",
|
||
initial: "陈",
|
||
avatarColor: "bg-amber-500",
|
||
photo: "https://i.pravatar.cc/150?img=3",
|
||
},
|
||
{
|
||
id: "3",
|
||
name: "王思琪",
|
||
age: 26,
|
||
location: "深圳",
|
||
tags: ["本科学历", "内容创作者", "数字游民", "环保主义者"],
|
||
bio: "自由撰稿人,在深圳写写画画。热爱瑜伽和冥想,相信慢生活才是真正的奢侈。",
|
||
gradient: "from-emerald-400 via-teal-400 to-cyan-400",
|
||
initial: "王",
|
||
avatarColor: "bg-emerald-500",
|
||
photo: "https://i.pravatar.cc/150?img=5",
|
||
},
|
||
{
|
||
id: "4",
|
||
name: "张明远",
|
||
age: 30,
|
||
location: "杭州",
|
||
tags: ["MBA学历", "创业中", "自由职业者", "徒步爱好者"],
|
||
bio: "正在杭州创业,做远程团队协作工具。周末喜欢去西湖徒步,偶尔品鉴龙井茶。",
|
||
gradient: "from-violet-400 via-purple-400 to-indigo-400",
|
||
initial: "张",
|
||
avatarColor: "bg-violet-500",
|
||
photo: "https://i.pravatar.cc/150?img=7",
|
||
},
|
||
{
|
||
id: "5",
|
||
name: "李雅婷",
|
||
age: 27,
|
||
location: "厦门",
|
||
tags: ["本科学历", "UI设计师", "数字游民", "摄影爱好者"],
|
||
bio: "在厦门远程做UI设计,业余时间探索闽南美食。喜欢用相机记录生活,寻找一起探店的朋友。",
|
||
gradient: "from-rose-500 via-red-400 to-orange-500",
|
||
initial: "李",
|
||
avatarColor: "bg-rose-500",
|
||
photo: "https://i.pravatar.cc/150?img=9",
|
||
},
|
||
{
|
||
id: "6",
|
||
name: "刘子轩",
|
||
age: 33,
|
||
location: "昆明",
|
||
tags: ["博士学历", "数据科学家", "远程工作者", "户外爱好者"],
|
||
bio: "在昆明远程工作,热爱户外运动。正在探索云南各地,希望认识更多志同道合的朋友。",
|
||
gradient: "from-blue-400 via-indigo-400 to-violet-500",
|
||
initial: "刘",
|
||
avatarColor: "bg-blue-500",
|
||
photo: "https://i.pravatar.cc/150?img=11",
|
||
},
|
||
];
|
||
|
||
const MOCK_MATCHES: MatchCard[] = [
|
||
{ id: "m1", name: "周雨桐", location: "杭州", timeAgo: "2天前", initial: "周", color: "bg-pink-400", photo: "https://i.pravatar.cc/150?img=29" },
|
||
{ id: "m2", name: "吴俊杰", location: "成都", timeAgo: "1周前", initial: "吴", color: "bg-amber-400", photo: "https://i.pravatar.cc/150?img=34" },
|
||
{ id: "m3", name: "郑诗涵", location: "上海", timeAgo: "3周前", initial: "郑", color: "bg-emerald-400", photo: "https://i.pravatar.cc/150?img=36" },
|
||
{ id: "m4", name: "孙宇航", location: "深圳", timeAgo: "1月前", initial: "孙", color: "bg-violet-400", photo: "https://i.pravatar.cc/150?img=38" },
|
||
{ id: "m5", name: "赵梦琪", location: "厦门", timeAgo: "1年前", initial: "赵", color: "bg-rose-400", photo: "https://i.pravatar.cc/150?img=41" },
|
||
];
|
||
|
||
export default function DatingPage() {
|
||
const [activeTab, setActiveTab] = useState<TabType>("friends");
|
||
const [currentIndex, setCurrentIndex] = useState(0);
|
||
|
||
const currentProfile = MOCK_PROFILES[currentIndex];
|
||
const hasMoreProfiles = currentIndex < MOCK_PROFILES.length - 1;
|
||
|
||
const handleLike = () => {
|
||
if (hasMoreProfiles) {
|
||
setCurrentIndex((i) => i + 1);
|
||
} else {
|
||
setCurrentIndex(0);
|
||
}
|
||
};
|
||
|
||
const handleDislike = () => {
|
||
if (hasMoreProfiles) {
|
||
setCurrentIndex((i) => i + 1);
|
||
} else {
|
||
setCurrentIndex(0);
|
||
}
|
||
};
|
||
|
||
const badgeText =
|
||
activeTab === "dating"
|
||
? "你们都在寻找 🌹 约会"
|
||
: "你们都在寻找 🤝 交友";
|
||
|
||
return (
|
||
<div className="min-h-screen bg-[#fafafa]">
|
||
{/* Tabs */}
|
||
<div className="flex justify-center pt-6 pb-4 px-4">
|
||
<div className="inline-flex rounded-full bg-white p-1 shadow-sm border border-gray-100">
|
||
<button
|
||
onClick={() => setActiveTab("friends")}
|
||
className={`px-6 py-2.5 rounded-full text-sm font-medium transition-all duration-200 ${
|
||
activeTab === "friends"
|
||
? "bg-[#ff4d4f] text-white shadow-sm"
|
||
: "text-gray-600 hover:text-gray-900"
|
||
}`}
|
||
>
|
||
交友
|
||
</button>
|
||
<button
|
||
onClick={() => setActiveTab("dating")}
|
||
className={`px-6 py-2.5 rounded-full text-sm font-medium transition-all duration-200 ${
|
||
activeTab === "dating"
|
||
? "bg-[#ff4d4f] text-white shadow-sm"
|
||
: "text-gray-600 hover:text-gray-900"
|
||
}`}
|
||
>
|
||
约会
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex flex-col md:flex-row gap-6 max-w-7xl mx-auto px-4 pb-12">
|
||
{/* Left Sidebar - hidden on mobile */}
|
||
<aside className="hidden md:block w-72 flex-shrink-0">
|
||
<div className="sticky top-24">
|
||
<h2 className="text-lg font-semibold text-gray-900 mb-1">
|
||
约会匹配 💕
|
||
</h2>
|
||
<p className="text-sm text-gray-500 mb-4">这些人喜欢了你</p>
|
||
<div className="space-y-3">
|
||
{MOCK_MATCHES.map((match) => (
|
||
<div
|
||
key={match.id}
|
||
className="flex items-center gap-3 p-3 rounded-xl bg-white border border-gray-100 shadow-sm hover:shadow-md transition-shadow cursor-pointer"
|
||
>
|
||
<img
|
||
src={match.photo}
|
||
alt={match.name}
|
||
className="w-12 h-12 rounded-full object-cover shadow-sm flex-shrink-0"
|
||
/>
|
||
<div className="flex-1 min-w-0">
|
||
<p className="font-medium text-gray-900 truncate">
|
||
{match.name}
|
||
</p>
|
||
<p className="text-xs text-gray-500 truncate">
|
||
{match.location}
|
||
</p>
|
||
</div>
|
||
<span className="text-xs text-gray-400 bg-gray-50 px-2 py-1 rounded-full flex-shrink-0">
|
||
{match.timeAgo}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
{/* Center - Main Card */}
|
||
<main className="flex-1 min-w-0 flex flex-col items-center">
|
||
<div className="w-full max-w-md mx-auto">
|
||
<div
|
||
className={`relative rounded-2xl overflow-hidden bg-gradient-to-br ${currentProfile.gradient} p-8 pb-6 shadow-xl border border-white/20`}
|
||
>
|
||
{/* Top right: badge + report */}
|
||
<div className="absolute top-4 right-4 flex flex-col items-end gap-1">
|
||
<span className="px-3 py-1.5 rounded-full bg-white/90 text-gray-800 text-xs font-medium backdrop-blur-sm">
|
||
{badgeText}
|
||
</span>
|
||
<a
|
||
href="#"
|
||
className="text-[#ff4d4f] hover:text-red-600 text-sm font-medium"
|
||
>
|
||
举报资料
|
||
</a>
|
||
</div>
|
||
|
||
{/* Avatar */}
|
||
<div className="flex justify-center mt-12 mb-6">
|
||
<img
|
||
src={currentProfile.photo}
|
||
alt={currentProfile.name}
|
||
className="w-28 h-28 rounded-full shadow-lg border-4 border-white/50 object-cover"
|
||
/>
|
||
</div>
|
||
|
||
{/* Name, age, location */}
|
||
<div className="text-center mb-4">
|
||
<h3 className="text-xl font-bold text-white drop-shadow-sm">
|
||
{currentProfile.name},{currentProfile.age}
|
||
</h3>
|
||
<p className="text-white/90 text-sm mt-1">
|
||
📍 {currentProfile.location}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Tags */}
|
||
<div className="mb-4">
|
||
<p className="text-white/90 text-xs font-medium mb-2">
|
||
匹配标签:
|
||
</p>
|
||
<div className="flex flex-wrap gap-2 justify-center">
|
||
{currentProfile.tags.map((tag) => (
|
||
<span
|
||
key={tag}
|
||
className="px-3 py-1 rounded-full bg-white/80 text-gray-800 text-xs font-medium"
|
||
>
|
||
{tag}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bio */}
|
||
<p className="text-white/95 text-sm leading-relaxed text-center mb-8 px-2">
|
||
{currentProfile.bio}
|
||
</p>
|
||
|
||
{/* Action buttons */}
|
||
<div className="flex items-center justify-center gap-8">
|
||
<div className="flex flex-col items-center gap-2">
|
||
<button
|
||
onClick={handleDislike}
|
||
className="w-16 h-16 rounded-full bg-white shadow-lg flex items-center justify-center text-[#ff4d4f] hover:bg-red-50 hover:scale-105 active:scale-95 transition-all"
|
||
aria-label="不感兴趣"
|
||
>
|
||
<span className="text-2xl">✕</span>
|
||
</button>
|
||
<span className="text-xs text-white/80 font-medium">
|
||
不感兴趣
|
||
</span>
|
||
</div>
|
||
<div className="flex flex-col items-center gap-2">
|
||
<button
|
||
onClick={handleLike}
|
||
className="w-16 h-16 rounded-full bg-[#22c55e] shadow-lg flex items-center justify-center text-white hover:bg-[#16a34a] hover:scale-105 active:scale-95 transition-all"
|
||
aria-label="喜欢"
|
||
>
|
||
<span className="text-2xl">💚</span>
|
||
</button>
|
||
<span className="text-xs text-white/80 font-medium">喜欢</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Progress indicator */}
|
||
<p className="text-center text-sm text-gray-500 mt-4">
|
||
{currentIndex + 1} / {MOCK_PROFILES.length}
|
||
</p>
|
||
</div>
|
||
</main>
|
||
|
||
{/* Right spacer for desktop balance */}
|
||
<div className="hidden lg:block w-72 flex-shrink-0" />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|