175 lines
8.9 KiB
TypeScript
175 lines
8.9 KiB
TypeScript
import React, { useState } from 'react';
|
||
import { ChevronLeft, Check, Crown, Zap, Star, Shield, Smartphone, Infinity } from 'lucide-react';
|
||
|
||
interface SubscriptionProps {
|
||
onBack: () => void;
|
||
}
|
||
|
||
const PLANS = [
|
||
{
|
||
id: 'month',
|
||
name: '月度协议',
|
||
price: '¥28',
|
||
period: '/月',
|
||
desc: '灵便之选,随时取消',
|
||
isPopular: false
|
||
},
|
||
{
|
||
id: 'year',
|
||
name: '年度神经连接',
|
||
price: '¥298',
|
||
period: '/年',
|
||
desc: '节省 20%,尊享全年',
|
||
originalPrice: '¥336',
|
||
isPopular: true
|
||
},
|
||
];
|
||
|
||
const PRIVILEGES = [
|
||
{ icon: Infinity, title: '剧本库无限畅玩', desc: '解锁全部付费/限定剧本' },
|
||
{ icon: Zap, title: '高频信号通道', desc: '解锁 Extreme 级震动强度' },
|
||
{ icon: Smartphone, title: '多设备同步', desc: '支持多台 Link-X 设备同时控制' },
|
||
{ icon: Star, title: 'AI 专属人格', desc: '解锁隐藏性格与深度记忆模式' },
|
||
{ icon: Crown, title: '尊贵身份标识', desc: '专属头像框与社区徽章' },
|
||
{ icon: Shield, title: '隐私加密通道', desc: '端对端加密,无痕浏览' },
|
||
];
|
||
|
||
const Subscription: React.FC<SubscriptionProps> = ({ onBack }) => {
|
||
const [selectedPlan, setSelectedPlan] = useState('year');
|
||
const [isProcessing, setIsProcessing] = useState(false);
|
||
|
||
const handleSubscribe = () => {
|
||
setIsProcessing(true);
|
||
setTimeout(() => {
|
||
setIsProcessing(false);
|
||
alert('订阅成功!欢迎加入神经连接计划。');
|
||
onBack();
|
||
}, 1500);
|
||
};
|
||
|
||
return (
|
||
<div className="fixed inset-0 z-[60] bg-[#0F1014] flex flex-col h-full overflow-hidden animate-in slide-in-from-bottom-10 duration-300 fade-in">
|
||
|
||
{/* Header */}
|
||
<div className="relative z-20 pt-safe-top px-4 py-3 flex items-center justify-between border-b border-white/5 bg-[#0F1014]/80 backdrop-blur-md">
|
||
<button onClick={onBack} className="p-2 -ml-2 text-white/70 hover:text-white active:scale-95 transition-transform">
|
||
<ChevronLeft size={24} />
|
||
</button>
|
||
<h1 className="text-base font-bold text-white tracking-wider">订阅管理</h1>
|
||
<div className="w-8"></div>
|
||
</div>
|
||
|
||
<div className="flex-1 overflow-y-auto no-scrollbar pb-32">
|
||
|
||
{/* Hero Section */}
|
||
<div className="relative h-48 overflow-hidden mb-6 shrink-0">
|
||
<div className="absolute inset-0 bg-gradient-to-br from-[#1C1F26] via-[#0F1014] to-[#0F1014]"></div>
|
||
{/* Gold Glow */}
|
||
<div className="absolute top-[-50%] left-1/2 -translate-x-1/2 w-[120%] h-full bg-[#F59E0B]/10 blur-[60px] rounded-full"></div>
|
||
|
||
<div className="relative z-10 h-full flex flex-col items-center justify-center text-center px-6">
|
||
<div className="w-12 h-12 rounded-full bg-gradient-to-tr from-[#F59E0B] to-[#FCD34D] flex items-center justify-center mb-3 shadow-[0_0_20px_rgba(245,158,11,0.3)]">
|
||
<Crown size={24} className="text-black" fill="currentColor" />
|
||
</div>
|
||
<h2 className="text-xl font-bold text-white tracking-wide">升级至 Wei AI Pro</h2>
|
||
<p className="text-xs text-[#94A3B8] mt-2 max-w-[200px]">解锁全部感官限制,获得更加深度的沉浸式体验。</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Plan Selection */}
|
||
<div className="px-4 space-y-4 mb-8">
|
||
{PLANS.map((plan) => {
|
||
const isSelected = selectedPlan === plan.id;
|
||
return (
|
||
<div
|
||
key={plan.id}
|
||
onClick={() => setSelectedPlan(plan.id)}
|
||
className={`relative p-0.5 rounded-2xl transition-all duration-300 active:scale-[0.99] ${
|
||
isSelected
|
||
? 'bg-gradient-to-r from-[#F59E0B] to-[#FCD34D] shadow-[0_0_20px_rgba(245,158,11,0.15)]'
|
||
: 'bg-white/10'
|
||
}`}
|
||
>
|
||
<div className="bg-[#1C1F26] rounded-[14px] p-4 flex items-center justify-between relative z-10">
|
||
<div className="flex items-center gap-4">
|
||
<div className={`w-5 h-5 rounded-full border-2 flex items-center justify-center transition-colors shrink-0 ${
|
||
isSelected ? 'border-[#F59E0B] bg-[#F59E0B]' : 'border-[#64748B]'
|
||
}`}>
|
||
{isSelected && <Check size={12} className="text-black stroke-[3]" />}
|
||
</div>
|
||
<div>
|
||
<div className="flex items-center gap-2">
|
||
<h3 className={`text-base font-bold ${isSelected ? 'text-white' : 'text-[#94A3B8]'}`}>{plan.name}</h3>
|
||
{plan.isPopular && (
|
||
<span className="text-[9px] font-bold bg-[#F59E0B] text-black px-1.5 py-0.5 rounded tracking-wide shrink-0">
|
||
超值推荐
|
||
</span>
|
||
)}
|
||
</div>
|
||
<p className="text-xs text-[#64748B] mt-1 line-clamp-1">{plan.desc}</p>
|
||
</div>
|
||
</div>
|
||
<div className="text-right shrink-0">
|
||
{plan.originalPrice && (
|
||
<span className="block text-[10px] text-[#64748B] line-through mb-0.5">{plan.originalPrice}</span>
|
||
)}
|
||
<div className="flex items-end justify-end">
|
||
<span className={`text-xl font-bold font-mono ${isSelected ? 'text-[#F59E0B]' : 'text-white'}`}>{plan.price}</span>
|
||
<span className="text-xs text-[#64748B] mb-1 ml-0.5">{plan.period}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
{/* Privileges Grid */}
|
||
<div className="px-5">
|
||
<h3 className="text-xs font-bold text-[#64748B] uppercase tracking-widest mb-4 flex items-center gap-2">
|
||
<Star size={12} /> 会员特权
|
||
</h3>
|
||
<div className="grid grid-cols-2 gap-x-4 gap-y-6">
|
||
{PRIVILEGES.map((item, idx) => (
|
||
<div key={idx} className="flex gap-3">
|
||
<div className="shrink-0 w-8 h-8 rounded-lg bg-[#F59E0B]/10 flex items-center justify-center text-[#F59E0B]">
|
||
<item.icon size={16} />
|
||
</div>
|
||
<div>
|
||
<h4 className="text-xs font-bold text-white mb-0.5">{item.title}</h4>
|
||
<p className="text-[10px] text-[#64748B] leading-tight">{item.desc}</p>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Terms */}
|
||
<div className="px-6 mt-8 mb-4 text-[10px] text-[#475569] text-center leading-relaxed">
|
||
<p>订阅将自动续费。取消需在当前周期结束前24小时内操作。</p>
|
||
<p className="mt-2">点击下方按钮即代表同意《会员服务协议》</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bottom Action Bar */}
|
||
<div className="absolute bottom-0 left-0 w-full p-4 bg-[#0F1014]/90 backdrop-blur-xl border-t border-white/5 z-30">
|
||
<button
|
||
onClick={handleSubscribe}
|
||
disabled={isProcessing}
|
||
className="w-full h-12 rounded-xl bg-gradient-to-r from-[#F59E0B] to-[#FBBF24] text-black font-bold tracking-wide shadow-[0_0_20px_rgba(245,158,11,0.2)] active:scale-[0.98] transition-transform flex items-center justify-center gap-2 disabled:opacity-70 disabled:cursor-not-allowed"
|
||
>
|
||
{isProcessing ? (
|
||
<span className="animate-pulse">正在激活神经通道...</span>
|
||
) : (
|
||
<>
|
||
<Zap size={18} fill="currentColor" />
|
||
立即开启 {PLANS.find(p => p.id === selectedPlan)?.price}
|
||
</>
|
||
)}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default Subscription; |