This commit is contained in:
141
pages/PricingPage.tsx
Normal file
141
pages/PricingPage.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { useAuth } from '../AuthContext';
|
||||
import { Check, Shield, ArrowLeft } from 'lucide-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Layout } from '../components/Layout';
|
||||
|
||||
const PricingPage: React.FC = () => {
|
||||
const { user, refreshUser } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [loading, setLoading] = useState<string | null>(null);
|
||||
|
||||
const handlePurchase = async (plan: string, credits: number, price: number) => {
|
||||
setLoading(plan);
|
||||
try {
|
||||
const token = localStorage.getItem('token');
|
||||
// MOCK PURCHASE ENDPOINT
|
||||
await axios.post('/api/user/purchase', { plan, credits, price }, {
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
await refreshUser();
|
||||
alert(`Successfully purchased ${plan}! ${credits} credits added.`);
|
||||
navigate('/');
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
alert("Purchase failed: " + (err.response?.data?.error || err.message));
|
||||
} finally {
|
||||
setLoading(null);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="max-w-5xl mx-auto p-8 pt-12">
|
||||
<div className="flex items-center gap-4 mb-12">
|
||||
<button
|
||||
onClick={() => navigate('/')}
|
||||
className="p-3 bg-white hover:bg-stone-100 border border-stone-200 rounded-2xl transition-all shadow-sm group"
|
||||
>
|
||||
<ArrowLeft className="w-5 h-5 text-stone-600 group-hover:-translate-x-1 transition-transform" />
|
||||
</button>
|
||||
<div>
|
||||
<h1 className="text-3xl font-black tracking-tighter text-stone-900">Upgrade Your Engine</h1>
|
||||
<p className="text-stone-500 font-medium text-sm">Unlock higher limits and premium features.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{/* ... tier content remains same ... */}
|
||||
{/* Free Tier */}
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-stone-200 p-8 flex flex-col">
|
||||
<div className="mb-4">
|
||||
<h3 className="text-lg font-bold text-stone-500 uppercase tracking-wider">Starter</h3>
|
||||
<p className="text-4xl font-black mt-2">$0</p>
|
||||
<p className="text-sm text-stone-400">Forever free</p>
|
||||
</div>
|
||||
<ul className="space-y-4 mb-8 flex-1">
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-green-100 text-green-600 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
10 Free Credits / Month
|
||||
</li>
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-green-100 text-green-600 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
Standard Quality
|
||||
</li>
|
||||
</ul>
|
||||
<button disabled className="w-full py-3 bg-stone-100 text-stone-400 font-bold rounded-xl cursor-not-allowed">
|
||||
Current Plan
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Pro Tier */}
|
||||
<div className="bg-stone-900 text-white rounded-2xl shadow-xl border border-stone-800 p-8 flex flex-col relative transform scale-105">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-gradient-to-r from-purple-500 to-indigo-500 text-white px-4 py-1 rounded-full text-xs font-bold uppercase tracking-widest shadow-lg">
|
||||
Most Popular
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-lg font-bold text-purple-400 uppercase tracking-wider">Professional</h3>
|
||||
<p className="text-4xl font-black mt-2">$29</p>
|
||||
<p className="text-sm text-stone-400">per month</p>
|
||||
</div>
|
||||
<ul className="space-y-4 mb-8 flex-1">
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-purple-500/20 text-purple-400 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
1,000 Credits / Month
|
||||
</li>
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-purple-500/20 text-purple-400 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
Priority Generation
|
||||
</li>
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-purple-500/20 text-purple-400 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
Access to Beta Features
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
onClick={() => handlePurchase('PRO', 1000, 29)}
|
||||
disabled={loading === 'PRO'}
|
||||
className="w-full py-3 bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-500 hover:to-indigo-500 text-white font-bold rounded-xl transition-all shadow-lg hover:shadow-purple-500/25 disabled:opacity-50"
|
||||
>
|
||||
{loading === 'PRO' ? 'Processing...' : 'Upgrade Now'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Enterprise/Bulk */}
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-stone-200 p-8 flex flex-col">
|
||||
<div className="mb-4">
|
||||
<h3 className="text-lg font-bold text-stone-500 uppercase tracking-wider">Credit Pack</h3>
|
||||
<p className="text-4xl font-black mt-2">$10</p>
|
||||
<p className="text-sm text-stone-400">One-time purchase</p>
|
||||
</div>
|
||||
<ul className="space-y-4 mb-8 flex-1">
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-green-100 text-green-600 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
+300 Credits
|
||||
</li>
|
||||
<li className="flex items-center gap-3 text-sm">
|
||||
<span className="p-1 bg-green-100 text-green-600 rounded-full"><Check className="w-3 h-3" /></span>
|
||||
Never Expires
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
onClick={() => handlePurchase('PACK', 300, 10)}
|
||||
disabled={loading === 'PACK'}
|
||||
className="w-full py-3 bg-white border-2 border-stone-200 text-stone-700 hover:border-stone-900 hover:text-stone-900 font-bold rounded-xl transition-all disabled:opacity-50"
|
||||
>
|
||||
{loading === 'PACK' ? 'Processing...' : 'Buy Pack'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 text-center text-xs text-stone-400 bg-stone-100 p-4 rounded-lg inline-flex items-center gap-2">
|
||||
<Shield className="w-4 h-4" />
|
||||
Secure Payment Processing via MockStripe (Test Mode)
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default PricingPage;
|
||||
Reference in New Issue
Block a user