134 lines
5.1 KiB
TypeScript
134 lines
5.1 KiB
TypeScript
import { useNavigate, useParams } from 'react-router-dom'
|
|
import { motion } from 'framer-motion'
|
|
import { ChevronLeft, Star, Check, Share2 } from 'lucide-react'
|
|
import { groupBuyPackages, renovationSchemes } from '@/mock/groupData'
|
|
|
|
export default function PackageDetailPage() {
|
|
const navigate = useNavigate()
|
|
const { id } = useParams()
|
|
|
|
const pkg = groupBuyPackages.find((p) => p.id === parseInt(id || '1')) || groupBuyPackages[0]
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 pb-20">
|
|
<div className="relative">
|
|
<img
|
|
src={pkg.image}
|
|
alt={pkg.title}
|
|
className="w-full h-56 object-cover"
|
|
/>
|
|
<div className="absolute top-0 left-0 right-0 bg-gradient-to-b from-black/50 to-transparent p-4 pt-12">
|
|
<button onClick={() => navigate(-1)} className="p-1">
|
|
<ChevronLeft size={24} className="text-white" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="px-4 -mt-6 relative">
|
|
<div className="bg-white rounded-xl shadow-sm p-4">
|
|
<div className="flex items-start justify-between">
|
|
<div>
|
|
<h1 className="text-xl font-bold text-gray-800">{pkg.title}</h1>
|
|
<p className="text-sm text-gray-500 mt-1">{pkg.subtitle}</p>
|
|
</div>
|
|
<motion.button
|
|
className="p-2 rounded-full bg-gray-50"
|
|
whileTap={{ scale: 0.9 }}
|
|
>
|
|
<Share2 size={20} className="text-gray-500" />
|
|
</motion.button>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2 mt-3">
|
|
<div className="flex items-center gap-1">
|
|
<Star size={14} className="text-yellow-400 fill-yellow-400" />
|
|
<span className="text-sm text-gray-600">{pkg.rating}</span>
|
|
</div>
|
|
<span className="text-sm text-gray-400">| 已售{pkg.sales}套</span>
|
|
</div>
|
|
|
|
<div className="flex items-baseline gap-2 mt-3">
|
|
<span className="text-2xl font-bold text-primary-500">
|
|
¥{pkg.price.toLocaleString()}
|
|
</span>
|
|
<span className="text-sm text-gray-400 line-through">
|
|
¥{pkg.originalPrice.toLocaleString()}
|
|
</span>
|
|
<span className="px-2 py-0.5 bg-red-50 text-red-500 text-xs rounded">
|
|
省¥{(pkg.originalPrice - pkg.price).toLocaleString()}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-white rounded-xl shadow-sm p-4 mt-4">
|
|
<h3 className="font-bold text-gray-800 mb-3">套餐包含</h3>
|
|
<div className="space-y-2">
|
|
{pkg.features.map((feature, index) => (
|
|
<div key={index} className="flex items-center gap-2">
|
|
<Check size={16} className="text-primary-500" />
|
|
<span className="text-sm text-gray-600">{feature}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-white rounded-xl shadow-sm p-4 mt-4">
|
|
<h3 className="font-bold text-gray-800 mb-3">改造方案</h3>
|
|
<div className="space-y-3">
|
|
{renovationSchemes.map((scheme) => (
|
|
<motion.div
|
|
key={scheme.id}
|
|
className="flex gap-3 p-3 bg-gray-50 rounded-xl"
|
|
whileTap={{ scale: 0.98 }}
|
|
>
|
|
<img
|
|
src={scheme.image}
|
|
alt={scheme.title}
|
|
className="w-20 h-20 rounded-lg object-cover"
|
|
/>
|
|
<div className="flex-1">
|
|
<h4 className="font-medium text-gray-800">{scheme.title}</h4>
|
|
<p className="text-xs text-gray-500 mt-1">{scheme.description}</p>
|
|
<div className="flex items-center gap-2 mt-2">
|
|
<span className="text-primary-500 font-medium">
|
|
¥{scheme.price.toLocaleString()}
|
|
</span>
|
|
<span className="text-xs text-gray-400">{scheme.duration}</span>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-primary-50 rounded-xl p-4 mt-4">
|
|
<h4 className="font-medium text-primary-700 mb-2">服务保障</h4>
|
|
<ul className="text-sm text-primary-600 space-y-1">
|
|
<li>· 30天无理由退换</li>
|
|
<li>· 终身质保服务</li>
|
|
<li>· 专业施工团队</li>
|
|
<li>· 一站式售后服务</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 p-4 safe-bottom">
|
|
<div className="flex gap-3 max-w-lg mx-auto">
|
|
<motion.button
|
|
className="flex-1 h-12 rounded-xl border border-primary-500 text-primary-500 font-medium"
|
|
whileTap={{ scale: 0.98 }}
|
|
>
|
|
加入购物车
|
|
</motion.button>
|
|
<motion.button
|
|
className="flex-1 h-12 rounded-xl bg-primary-500 text-white font-medium"
|
|
whileTap={{ scale: 0.98 }}
|
|
>
|
|
立即购买
|
|
</motion.button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|