You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

764 lines
40 KiB

'use client'
import React, { useState, useEffect } from 'react'
import { Search, User, MapPin, Calendar, Gift, Heart, MessageCircle, Share2, Bell, Settings, TrendingUp, Users, Compass, Camera, Menu, ChevronDown, Loader2, DollarSign, Mail, Phone, Globe, Instagram, Cake, Briefcase, Languages, Plane, X, Link } from 'lucide-react'
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Badge } from "@/components/ui/badge"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Progress } from "@/components/ui/progress"
import { Textarea } from "@/components/ui/textarea"
import { User as UserType } from '@/lib/userDatabase'
import { userDatabase } from '@/lib/userDatabase'
import { CarouselSection } from '@/components/CarouselSection'
import { calculateSimilarity } from '@/lib/matchingAlgorithm';
import { } from '@/components/个人资料'
export function () {
// 定义一个渐变背景样式
const gradientBackground = `
// 从左上角到右下角的渐变,颜色从浅靛蓝过渡到浅紫,最后到浅粉
bg-gradient-to-br from-indigo-200 via-purple-200 to-pink-200
// 从右下角到左上角的渐变,颜色从浅黄过渡到浅红,最后到浅粉
// bg-blend-overlay 使这个渐变与前一个渐变混合
bg-gradient-to-tl from-yellow-100 via-red-100 to-pink-100 bg-blend-overlay
// 将背景不透明度设置为50%,使其半透明
bg-opacity-50
// 应用一个动画效果,可能是使渐变在水平方向上移动
animate-gradient-x
// 确保背景至少占满整个屏幕高度
min-h-screen
// 设置文本颜色为深灰色
text-gray-800
`;
const [, set] = useState('')
const [, set] = useState('')
const [, set] = useState('')
const [isMatching, setIsMatching] = useState(false)
const [matchResult, setMatchResult] = useState<UserType | null>(null)
const [matchingProgress, setMatchingProgress] = useState(0)
const [users, setUsers] = useState<UserType[]>([])
const [selectedEvent, setSelectedEvent] = useState<string | null>(null)
const [selectedInspirationIndex, setSelectedInspirationIndex] = useState<number | null>(null)
const [showProfile, setShowProfile] = useState(false)
const [posts, setPosts] = useState([
{
id: 1,
user: '小明',
avatar: 'https://images.unsplash.com/photo-1599566150163-29194dcaad36?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80',
location: '巴黎',
image: 'https://images.unsplash.com/photo-1499856871958-5b9627545d1a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '巴黎的魅力无处不在!从埃菲尔铁塔到卢浮宫,每一步都是艺术的洗礼。分享我在这座浪漫之都的精彩瞬间! #巴黎梦 #艺术之旅',
likes: 328,
comments: [],
isLiked: false
},
{
id: 2,
user: '小红',
avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80',
location: '东京',
image: 'https://images.unsplash.com/photo-1503899036084-c55cdd92da26?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '东京,一座永不入睡的城市!从繁华的涉谷到宁静的浅草寺,感受这里的无限活力。分享我在东京的精彩旅程! #东京探险 #日本文化',
likes: 256,
comments: [],
isLiked: false
},
{
id: 3,
user: '小李',
avatar: 'https://images.unsplash.com/photo-1552058544-f2b08422138a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1740&q=80',
location: '纽约',
image: 'https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '纽约,梦想之城!从中央公园到百老汇,每一刻都充满可能。在这里,平凡人也能创造非凡故事。分享我的纽约冒险! #纽约生活 #追梦人生',
likes: 412,
comments: [],
isLiked: false
},
{
id: 4,
user: '小张',
avatar: 'https://images.unsplash.com/photo-1554151228-14d9def656e4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1740&q=80',
location: '伦敦',
image: 'https://images.unsplash.com/photo-1513635269975-59663e0ac1ad?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '伦敦,历史与现代的完美融合!从大本钟到泰特现代美术馆,每一步都是文化的碰撞。分享我在伦敦的奇妙时光! #伦敦印象 #英伦风情',
likes: 189,
comments: [],
isLiked: false
},
{
id: 5,
user: '小王',
avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1740&q=80',
location: '悉尼',
image: 'https://images.unsplash.com/photo-1506973035872-a4ec16b8e8d9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '悉尼,阳光与海滩的天堂!从歌剧院到邦迪海滩,处处洋溢着欢乐。分享我在这里的阳光假期! #悉尼生活 #澳洲之美',
likes: 275,
comments: [],
isLiked: false
},
{
id: 6,
user: '小陈',
avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1740&q=80',
location: '罗马',
image: 'https://images.unsplash.com/photo-1552832230-c0197dd311b5?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '罗马,永恒之城!从斗兽场到梵蒂冈,每一处都是历史的见证。分享我在这座古城的深度探索! #罗马假日 #意大利风情',
likes: 301,
comments: [],
isLiked: false
},
{
id: 7,
user: '小林',
avatar: 'https://images.unsplash.com/photo-1547425260-76bcadfb4f2c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1740&q=80',
location: '巴塞罗那',
image: 'https://images.unsplash.com/photo-1583422409516-2895a77efded?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
content: '巴塞罗那,一座充满激情的城市!高迪的建筑让人惊叹,地中海的阳光温暖人心。分享我在这里的精彩冒险! #巴塞罗那风情 #建筑奇迹',
likes: 233,
comments: [],
isLiked: false
},
])
// 创建一个状态来存储新评论
const [newComment, setNewComment] = useState('')
// 组件挂载时,从userDatabase加载用户数据
useEffect(() => {
setUsers(userDatabase);
}, []);
// 处理盲盒匹配的函数
const = () => {
console.log('开始盲盒匹配');
// 设置匹配状态为true,开始匹配进度为0
setIsMatching(true);
setMatchingProgress(0);
// 创建一个定时器,每200毫秒增加10%的进度,直到100%
const intervalId = setInterval(() => {
setMatchingProgress(prev => {
if (prev >= 100) {
clearInterval(intervalId);
return 100;
}
return prev + 10;
});
}, 200);
// 2秒后执行实际的匹配逻辑
setTimeout(() => {
// 构造当前用户对象
const currentUser = {
budget: Number(),
destination: ,
travelDate: new Date(),
interests: ['旅行', '摄影', '美食'], // 这里应该从用户资料中获取
};
console.log('当前用户:', currentUser);
// 对所有用户进行匹配计算
const matchedUsers = users.map(user => {
const matchUser = {
...user,
budget: Number(user.budget),
destination: user.location,
travelDate: new Date(user.travelDate),
interests: user.interests || []
};
console.log('匹配用户:', matchUser);
// 计算相似度
const similarity = calculateSimilarity(currentUser, matchUser);
console.log('相似度分数:', similarity);
return { ...user, similarity };
}).sort((a, b) => b.similarity - a.similarity); // 按相似度降序排序
console.log('匹配结果:', matchedUsers);
// 设置匹配结果
if (matchedUsers.length > 0) {
setMatchResult(matchedUsers[0]);
} else {
setMatchResult(null);
}
// 结束匹配过程
setIsMatching(false);
clearInterval(intervalId);
setMatchingProgress(100);
}, 2000);
};
// 处理点赞功能的函数
const handleLike = (postId: number) => {
setPosts(posts.map(post => {
if (post.id === postId) {
return {
...post,
// 如果已经点赞,则减少点赞数;否则增加点赞数
likes: post.isLiked ? post.likes - 1 : post.likes + 1,
// 切换点赞状态
isLiked: !post.isLiked
}
}
return post
}))
}
// 处理评论功能的函数
const handleComment = (postId: number) => {
// 检查新评论是否为空(去掉首尾空格后)
if (newComment.trim()) {
// 更新帖子列表
setPosts(posts.map(post => {
// 找到要评论的帖子
if (post.id === postId) {
return {
...post,
// 将新评论添加到评论列表中
comments: [...post.comments, newComment]
}
}
// 其他帖子保持不变
return post
}))
// 清空评论输入框
setNewComment('')
}
}
// 处理分享功能的函数
const handleShare = (postId: number) => {
// 构造帖子的URL
const url = `https://yourtravelwebsite.com/post/${postId}`
// 将URL复制到剪贴板
navigator.clipboard.writeText(url).then(() => {
// 复制成功后显示提示
alert('链接已复制到剪贴板!')
})
}
const events = [
{
title: '徒步长城',
description: '体验中国最著名的古代建筑,欣赏壮丽的风景,结识志同道合的徒步爱好者。',
date: '2023年10月15日',
duration: '1天',
difficulty: '中等',
included: ['专业导游', '午餐', '往返交通'],
image: 'https://images.unsplash.com/photo-1508804185872-d7badad00f7d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '樱花季摄影',
description: '在美丽的樱花季节,和其他摄影爱好者一起捕捉最美的樱花景象,提升您的摄影技巧。',
date: '2024年3月20日',
duration: '半天',
difficulty: '简单',
included: ['摄影指导', '下午茶', '照片后期工作坊'],
image: 'https://images.unsplash.com/photo-1522383225653-ed111181a951?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2076&q=80'
},
{
title: '威尼斯狂欢节',
description: '参加世界闻名的威尼斯狂欢节,体验独特的面具文化和浪漫的水城氛围。',
date: '2024年2月10日',
duration: '3天',
difficulty: '简单',
included: ['面具工作坊', '狂欢节游行门票', '威尼斯特色美食品尝'],
image: 'https://images.unsplash.com/photo-1518730518541-d0f4ea9dfab9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '亚马逊丛林探险',
description: '深入世界最大的热带雨林,探索丰富的生物多样性,体验原始部落文化。',
date: '2023年11月5日',
duration: '5天',
difficulty: '高',
included: ['专业向导', '丛林住宿', '野生动物观察', '部落文化体验'],
image: 'https://images.unsplash.com/photo-1516426122078-c23e76319801?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '北极光观测之旅',
description: '前往芬兰拉普兰,在极地玻璃屋中观赏神奇的北极光,体验独特的萨米文化。',
date: '2024年1月15日',
duration: '4天',
difficulty: '中等',
included: ['极光观测', '哈士奇雪橇', '冰钓体验', '萨米文化之夜'],
image: 'https://images.unsplash.com/photo-1531366936337-7c912a4589a7?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '日本寿司制作课程',
description: '在东京学习正宗的寿司制作技巧,深入了解日本饮食文化,品尝自己亲手制作的寿司。',
date: '2023年9月25日',
duration: '1天',
difficulty: '中等',
included: ['专业寿司师指导', '所有食材和工具', '寿司午餐', '参观筑地市场'],
image: 'https://images.unsplash.com/photo-1553621042-f6e147245754?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '马丘比丘徒步之旅',
description: '沿着古老的印加小道徒步,探索神秘的马丘比丘遗址,感受安第斯山脉的壮美。',
date: '2024年4月10日',
duration: '4天',
difficulty: '高',
included: ['专业向导', '露营装备', '餐食', '马丘比丘门票'],
image: 'https://images.unsplash.com/photo-1526392060635-9d6019884377?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
]
const inspirations = [
{
title: '原始森林探索',
description: '深入地球上最古老的原始森林,探索生物多样性的奇迹。在茂密的树冠下徒步,观察珍稀动植物,感受大自然的神奇力量。',
activities: ['丛林徒步', '野生动物观察', '生态摄影', '夜间探险'],
destinations: ['亚马逊雨林', '刚果盆地', '大兴安岭', '婆罗洲'],
image: 'https://images.unsplash.com/photo-1511497584788-876760111969?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1920&q=80'
},
{
title: '极地冰川探险',
description: '前往地球的极端地带,探索壮观的冰川世界。体验极昼或极夜,观察北极熊和企鹅,感受冰雪世界的震撼美景。',
activities: ['冰川徒步', '北极光观测', '冰上皮划艇', '极地野生动物观察'],
destinations: ['南极半岛', '格陵兰', '斯瓦尔巴群岛', '巴塔哥尼亚冰原'],
image: 'https://images.unsplash.com/photo-1494564605686-2e931f77a8e2?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '火山地质探索',
description: '探索地球上最活跃的火山地带,感受大自然的原始力量。观察独特的火山地貌,体验地热温泉,了解火山对生态系统的影响。',
activities: ['火山徒步', '温泉浸泡', '地质考察', '熔岩洞穴探索'],
destinations: ['夏威夷火山国家公园', '冰岛', '印度尼西亚默拉皮火山', '意大利埃特纳火山'],
image: 'https://images.unsplash.com/photo-1462332420958-a05d1e002413?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '沙漠探险之旅',
description: '在广袤的沙漠中体验极致的宁静与壮美。欣赏绚丽的日出日落,探索神秘的绿洲,感受沙漠文化的独特魅力。',
activities: ['沙漠徒步', '骆驼骑行', '沙丘冲浪', '星空观测'],
destinations: ['撒哈拉沙漠', '纳米比亚沙漠', '戈壁沙漠', '澳大利亚辛普森沙漠'],
image: 'https://images.unsplash.com/photo-1682686580391-615b1e32be1d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '海底世界探索',
description: '潜入神秘的海底世界,探索丰富多彩的海洋生态系统。观察五彩斑斓的珊瑚礁,与海洋生物亲密接触,感受海洋的魅力与重要性。',
activities: ['深潜', '浮潜', '珊瑚礁观察', '海洋生物研究'],
destinations: ['大堡礁', '帕劳', '马尔代夫', '加拉帕戈斯群岛'],
image: 'https://images.unsplash.com/photo-1682687982501-1e58ab814714?ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'
},
{
title: '高山探险挑战',
description: '挑战世界上最高的山峰,体验登山的刺激与成就感。欣赏壮丽的高山景色,了解高山生态系统,感受大自然的宏伟。',
activities: ['高山攀登', '冰川徒步', '高山摄影', '野外生存训练'],
destinations: ['珠穆朗玛峰', '乞力马扎罗山', '阿空加瓜山', '勃朗峰'],
image: 'https://images.unsplash.com/photo-1464278533981-50106e6176b1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2074&q=80'
},
{
title: '国家公园探索',
description: '探索世界著名的国家公园,感受大自然的鬼斧神工。观察多样的野生动物,徒步壮丽的山川,体验自然保护的重要性。',
activities: ['野生动物观察', '徒步旅行', '露营', '风景摄影'],
destinations: ['黄石国家公园', '塞伦盖蒂国家公园', '托斯卡纳群岛国家公园', '吉尔吉斯斯坦天山国家公园'],
image: 'https://images.unsplash.com/photo-1472396961693-142e6e269027?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2106&q=80'
}
]
return (
<div className={gradientBackground}>
<header className="bg-white shadow sticky top-0 z-50">
{showProfile && < onClose={() => setShowProfile(false)} />}
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex justify-between items-center">
<div className="flex items-center space-x-4">
<h1 className="text-3xl font-bold text-primary"></h1>
<nav className="hidden md:flex space-x-4">
<Button variant="default" className="bg-black bg-opacity-50 text-white hover:bg-opacity-100"></Button>
<Button variant="default" className="bg-black bg-opacity-50 text-white hover:bg-opacity-100"></Button>
<Button variant="default" className="bg-black bg-opacity-50 text-white hover:bg-opacity-100"></Button>
<Button variant="default" className="bg-black bg-opacity-50 text-white hover:bg-opacity-100"></Button>
</nav>
</div>
<div className="flex items-center space-x-4">
<Button variant="ghost" size="icon"><Bell /></Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon"><User /></Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onSelect={() => setShowProfile(true)}></DropdownMenuItem>
<DropdownMenuItem></DropdownMenuItem>
<DropdownMenuItem></DropdownMenuItem>
<DropdownMenuItem>退</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Button variant="ghost" size="icon" className="md:hidden"><Menu /></Button>
</div>
</div>
</header>
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<section className="mb-12 bg-gradient-to-r from-blue-500 to-purple-600 rounded-xl p-8 text-white relative overflow-hidden">
<img
src="https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2021&q=80"
className="absolute inset-0 w-full h-full object-cover opacity-50"
alt="背景图片"
/>
<div className="relative z-10">
<h2 className="text-4xl font-bold mb-4"></h2>
<p className="text-xl mb-6">使</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<Input
type="text"
placeholder="输入目的地"
value={}
onChange={(e) => set(e.target.value)}
className="bg-white text-black"
icon={<MapPin className="text-gray-400" />}
/>
<Input
type="date"
value={}
onChange={(e) => set(e.target.value)}
className="bg-white text-black"
icon={<Calendar className="text-gray-400" />}
/>
<Input
type="number"
placeholder="输入预算(元)"
value={}
onChange={(e) => set(e.target.value)}
className="bg-white text-black"
icon={<DollarSign className="text-gray-400" />}
/>
<Dialog>
<DialogTrigger asChild>
<Button className="bg-yellow-400 text-black hover:bg-yellow-300 w-full">
<Gift className="mr-2" />
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[600px]">
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
{isMatching ? "正在为你匹配志同道合的旅伴,请稍候..." : "准备好开始新的冒险了吗?"}
</DialogDescription>
</DialogHeader>
<div className="flex justify-center items-center min-h-[400px]">
{isMatching ? (
<div className="text-center">
<Loader2 className="w-16 h-16 text-blue-500 animate-spin mx-auto mb-4" />
<Progress value={matchingProgress} className="w-64 mx-auto mb-2" />
<p>...</p>
</div>
) : matchResult ? (
<div className="w-full">
<div className="text-center mb-6">
<Avatar className="w-32 h-32 mx-auto mb-4">
<AvatarImage src={matchResult.avatar} alt={matchResult.name} />
<AvatarFallback>{matchResult.name[0]}</AvatarFallback>
</Avatar>
<h3 className="text-2xl font-semibold mb-2">{matchResult.name}, {matchResult.age}</h3>
<p className="text-gray-600 mb-2">
<MapPin className="inline-block mr-1" size={16} />
{matchResult.location}
</p>
<p className="text-gray-600 mb-4">
<DollarSign className="inline-block mr-1" size={16} />
: {matchResult.budget}
</p>
<div className="flex justify-center space-x-2 mb-4 flex-wrap">
{matchResult.interests.map((interest, index) => (
<Badge key={index} variant="secondary" className="mb-2">{interest}</Badge>
))}
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div>
<h4 className="font-semibold mb-2"></h4>
<p className="text-gray-600 mb-4">{matchResult.bio}</p>
<h4 className="font-semibold mb-2"></h4>
<p className="text-gray-600 mb-1">
<Briefcase className="inline-block mr-2" size={16} />
{matchResult.occupation}
</p>
<p className="text-gray-600 mb-4">
<Plane className="inline-block mr-2" size={16} />
{matchResult.travelStyle}
</p>
<h4 className="font-semibold mb-2"></h4>
<p className="text-gray-600 mb-4">
<Languages className="inline-block mr-2" size={16} />
{matchResult.languages.join(', ')}
</p>
</div>
<div>
<h4 className="font-semibold mb-2"></h4>
<p className="text-gray-600 mb-1">
<Mail className="inline-block mr-2" size={16} />
{matchResult.email}
</p>
<p className="text-gray-600 mb-1">
<Phone className="inline-block mr-2" size={16} />
{matchResult.phone}
</p>
<p className="text-gray-600 mb-1">
<Instagram className="inline-block mr-2" size={16} />
{matchResult.socialMedia.instagram}
</p>
<p className="text-gray-600 mb-4">
<Globe className="inline-block mr-2" size={16} />
{matchResult.socialMedia.website}
</p>
<h4 className="font-semibold mb-2"></h4>
<div className="flex flex-wrap mb-4">
{matchResult.recentTrips.map((trip, index) => (
<Badge key={index} variant="outline" className="mr-2 mb-2">{trip}</Badge>
))}
</div>
<h4 className="font-semibold mb-2"></h4>
<div className="flex flex-wrap">
{matchResult.upcomingTrips.map((trip, index) => (
<Badge key={index} variant="outline" className="mr-2 mb-2">{trip}</Badge>
))}
</div>
</div>
</div>
<div className="mt-6">
<h4 className="font-semibold mb-2"></h4>
{matchResult.reviews.map((review, index) => (
<div key={index} className="bg-gray-100 rounded-lg p-3 mb-2">
<p className="font-semibold">{review.author} <span className="text-yellow-500">{'★'.repeat(review.rating)}</span></p>
<p className="text-gray-600">{review.content}</p>
</div>
))}
</div>
</div>
) : (
<Gift className="w-24 h-24 text-yellow-400" />
)}
</div>
{!isMatching && (
<Button onClick={} disabled={isMatching || ! || ! || !} className="w-full mt-4">
{matchResult ? "重新匹配" : "开始匹配"}
</Button>
)}
</DialogContent>
</Dialog>
</div>
</div>
</section>
<CarouselSection
title="社区动态"
items={posts}
renderItem={(post) => (
<Card key={post.id}>
<CardHeader>
<div className="flex items-center space-x-4">
<Avatar>
<AvatarImage src={post.avatar} alt={`${post.user}头像`} />
<AvatarFallback>{post.user[0]}</AvatarFallback>
</Avatar>
<div>
<h3 className="font-semibold">{post.user}</h3>
<p className="text-sm text-gray-500">3</p>
</div>
</div>
</CardHeader>
<CardContent>
<p className="mb-2">{post.content}</p>
<img src={post.image} alt="旅行照片" className="w-full h-48 object-cover rounded-lg mb-2" />
<div className="flex space-x-2">
{post.content.split('#').slice(1).map((tag, index) => (
<Badge key={index} variant="secondary">#{tag.trim()}</Badge>
))}
</div>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="ghost" size="sm" onClick={() => handleLike(post.id)}>
<Heart className={`mr-2 ${post.isLiked ? 'fill-red-500 text-red-500' : ''}`} />
{post.likes}
</Button>
<Dialog>
<DialogTrigger asChild>
<Button variant="ghost" size="sm">
<MessageCircle className="mr-2" />
{post.comments.length}
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<div className="max-h-[300px] overflow-y-auto">
{post.comments.map((comment, index) => (
<div key={index} className="mb-2 p-2 bg-gray-100 rounded">
<p>{comment}</p>
</div>
))}
</div>
<div className="mt-4">
<Textarea
placeholder="添加评论..."
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
/>
<Button onClick={() => handleComment(post.id)} className="mt-2">
</Button>
</div>
</DialogContent>
</Dialog>
<Button variant="ghost" size="sm" onClick={() => handleShare(post.id)}>
<Share2 className="mr-2" />
</Button>
</CardFooter>
</Card>
)}
/>
<CarouselSection
title="即将开始的旅行活动"
items={events}
renderItem={(event) => (
<Card key={event.title} className="hover:shadow-lg transition-shadow duration-300">
<CardContent className="p-0">
<img src={event.image} alt={event.title} className="w-full h-40 object-cover" />
<div className="p-4">
<h3 className="font-semibold text-lg mb-2">{event.title}</h3>
<p className="text-sm text-gray-600 mb-2">{event.date}</p>
<Dialog>
<DialogTrigger asChild>
<Button variant="outline" size="sm"></Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>{event.title}</DialogTitle>
</DialogHeader>
<div className="mt-4">
<img src={event.image} alt={event.title} className="w-full h-48 object-cover rounded-lg mb-4" />
<p className="text-gray-700 mb-2">{event.description}</p>
<p className="text-sm text-gray-600 mb-1"><strong></strong>{event.date}</p>
<p className="text-sm text-gray-600 mb-1"><strong></strong>{event.duration}</p>
<p className="text-sm text-gray-600 mb-1"><strong></strong>{event.difficulty}</p>
<h4 className="font-semibold mt-4 mb-2"></h4>
<ul className="list-disc list-inside text-sm text-gray-600">
{event.included.map((item, i) => (
<li key={i}>{item}</li>
))}
</ul>
</div>
</DialogContent>
</Dialog>
</div>
</CardContent>
</Card>
)}
/>
<CarouselSection
title="旅行灵感"
items={inspirations}
renderItem={(inspiration) => (
<Card key={inspiration.title} className="hover:shadow-lg transition-shadow duration-300">
<CardContent className="p-0">
<img src={inspiration.image} alt={inspiration.title} className="w-full h-40 object-cover" />
<div className="p-4">
<h3 className="font-semibold text-lg mb-2">{inspiration.title}</h3>
<p className="text-sm text-gray-600 mb-2">{inspiration.description.substring(0, 100)}...</p>
<Dialog>
<DialogTrigger asChild>
<Button variant="outline" size="sm"></Button>
</DialogTrigger>
<DialogContent className="max-w-3xl">
<DialogHeader>
<DialogTitle>{inspiration.title}</DialogTitle>
</DialogHeader>
<div className="mt-4">
<img src={inspiration.image} alt={inspiration.title} className="w-full h-64 object-cover rounded-lg mb-4" />
<p className="text-gray-700 mb-4">{inspiration.description}</p>
<div className="grid grid-cols-2 gap-4">
<div>
<h4 className="font-semibold mb-2"></h4>
<ul className="list-disc list-inside text-sm text-gray-600">
{inspiration.activities.map((activity, i) => (
<li key={i}>{activity}</li>
))}
</ul>
</div>
<div>
<h4 className="font-semibold mb-2"></h4>
<ul className="list-disc list-inside text-sm text-gray-600">
{inspiration.destinations.map((destination, i) => (
<li key={i}>{destination}</li>
))}
</ul>
</div>
</div>
</div>
</DialogContent>
</Dialog>
</div>
</CardContent>
</Card>
)}
/>
<section>
<h2 className="text-2xl font-semibold mb-4 text-black"></h2>
<div className="bg-white p-6 rounded-lg shadow">
<ul className="list-disc list-inside space-y-2 text-black">
<li></li>
<li></li>
<li>便</li>
<li>使App</li>
<li></li>
<li></li>
</ul>
</div>
</section>
</main>
<footer className="bg-gray-800 text-white mt-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<h3 className="text-lg font-semibold mb-4"></h3>
<p className="text-sm"></p>
</div>
<div>
<h3 className="text-lg font-semibold mb-4"></h3>
<ul className="space-y-2">
<li><a href="#" className="text-sm hover:underline">使</a></li>
<li><a href="#" className="text-sm hover:underline"></a></li>
<li><a href="#" className="text-sm hover:underline"></a></li>
<li><a href="#" className="text-sm hover:underline"></a></li>
</ul>
</div>
<div>
<h3 className="text-lg font-semibold mb-4"></h3>
<div className="flex space-x-4">
<a href="#" className="text-white hover:text-gray-300"><svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path fillRule="evenodd" d="M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12z" clipRule="evenodd" /></svg></a>
<a href="#" className="text-white hover:text-gray-300"><svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path fillRule="evenodd" d="M12.315 2c2.43 0 2.784.013 3.808.06 1.064.049 1.791.218 2.427.465a4.902 4.902 0 011.772 1.153 4.902 4.902 0 011.153 1.772c.247.636.416 1.363.465 2.427.048 1.067.06 1.407.06 4.123v.08c0 2.643-.012 2.987-.06 4.043-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 01-1.153 1.772 4.902 4.902 0 01-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.048-1.407.06-4.123.06h-.08c-2.643 0-2.987-.012-4.043-.06-1.064-.049-1.791-.218-2.427-.465a4.902 4.902 0 01-1.772-1.153 4.902 4.902 0 01-1.153-1.772c-.247-.636-.416-1.363-.465-2.427-.047-1.024-.06-1.379-.06-3.808v-.63c0-2.43.013-2.784.06-3.808.049-1.064.218-1.791.465-2.427a4.902 4.902 0 011.153-1.772A4.902 4.902 0 015.45 2.525c.636-.247 1.363-.416 2.427-.465C8.901 2.013 9.256 2 11.685 2h.63zm-.081 1.802h-.468c-2.456 0-2.784.011-3.807.058-.975.045-1.504.207-1.857.344-.467.182-.8.398-1.15.748-.35.35-.566.683-.748 1.15-.137.353-.3.882-.344 1.857-.047 1.023-.058 1.351-.058 3.807v.468c0 2.456.011 2.784.058 3.807.045.975.207 1.504.344 1.857.182.466.399.8.748 1.15.35.35.683.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058h.08c2.597 0 2.917-.01 3.96-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.683.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041v-.08c0-2.597-.01-2.917-.058-3.96-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 00-.748-1.15 3.098 3.098 0 00-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.023-.047-1.351-.058-3.807-.058zM12 6.865a5.135 5.135 0 110 10.27 5.135 5.135 0 010-10.27zm0 1.802a3.333 3.333 0 100 6.666 3.333 3.333 0 000-6.666zm5.338-3.205a1.2 1.2 0 110 2.4 1.2 1.2 0 010-2.4z" clipRule="evenodd" /></svg></a>
<a href="#" className="text-white hover:text-gray-300"><svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84" /></svg></a>
</div>
</div>
<div>
<h3 className="text-lg font-semibold mb-4"></h3>
<p className="text-sm mb-2"></p>
<form className="flex">
<Input type="email" placeholder="您的邮箱" className="rounded-r-none" />
<Button type="submit" className="rounded-l-none"></Button>
</form>
</div>
</div>
<div className="mt-8 pt-8 border-t border-gray-700 text-center">
<p className="text-sm">&copy; 2023 . </p>
</div>
</div>
</footer>
</div>
)
}