rushe-ui/src/pages/user/group/PackageDetailPage.tsx

134 lines
5.1 KiB
TypeScript
Raw Normal View History

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>
)
}