SEction 4 completeed

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-27 02:59:27 +00:00
parent 178b7c23ce
commit 74a3441ee4
6 changed files with 326 additions and 446 deletions

View File

@@ -9,7 +9,7 @@ import { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import {
CreditCard, Package, TrendingUp, FileText, Wallet, ArrowUpCircle,
Loader2, AlertCircle, CheckCircle, Download, Zap, Globe, Users
Loader2, AlertCircle, CheckCircle, Download, Zap, Globe, Users, X
} from 'lucide-react';
import { Card } from '../../components/ui/card';
import Badge from '../../components/ui/badge/Badge';
@@ -55,6 +55,7 @@ export default function PlansAndBillingPage() {
const [error, setError] = useState<string>('');
const [planLoadingId, setPlanLoadingId] = useState<number | null>(null);
const [purchaseLoadingId, setPurchaseLoadingId] = useState<number | null>(null);
const [showCancelConfirm, setShowCancelConfirm] = useState(false);
// Data states
const [creditBalance, setCreditBalance] = useState<CreditBalance | null>(null);
@@ -493,16 +494,9 @@ export default function PlansAndBillingPage() {
variant="outline"
tone="neutral"
disabled={planLoadingId === currentSubscription?.id}
onClick={handleCancelSubscription}
onClick={() => setShowCancelConfirm(true)}
>
{planLoadingId === currentSubscription?.id ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Cancelling...
</>
) : (
'Cancel Plan'
)}
Cancel Plan
</Button>
)}
</div>
@@ -839,6 +833,73 @@ export default function PlansAndBillingPage() {
</div>
)}
</div>
{/* Cancellation Confirmation Modal */}
{showCancelConfirm && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-md">
<div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">Cancel Subscription</h2>
<button
onClick={() => setShowCancelConfirm(false)}
className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
>
<X className="w-5 h-5 text-gray-500" />
</button>
</div>
<div className="p-6 space-y-4">
<div className="flex items-start gap-3 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg">
<AlertCircle className="w-5 h-5 text-amber-600 dark:text-amber-400 mt-0.5 flex-shrink-0" />
<div className="text-sm text-amber-800 dark:text-amber-200">
<p className="font-medium mb-1">Are you sure you want to cancel?</p>
<p>Your subscription will remain active until the end of your current billing period. After that:</p>
</div>
</div>
<ul className="text-sm text-gray-600 dark:text-gray-400 space-y-2 pl-2">
<li className="flex items-start gap-2">
<span className="text-red-500 mt-1"></span>
<span>You'll lose access to premium features</span>
</li>
<li className="flex items-start gap-2">
<span className="text-red-500 mt-1">•</span>
<span>Remaining credits will be preserved for 30 days</span>
</li>
<li className="flex items-start gap-2">
<span className="text-red-500 mt-1">•</span>
<span>You can resubscribe anytime to restore access</span>
</li>
</ul>
</div>
<div className="flex items-center justify-end gap-3 p-6 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 rounded-b-xl">
<Button
variant="outline"
tone="neutral"
onClick={() => setShowCancelConfirm(false)}
>
Keep Subscription
</Button>
<Button
variant="solid"
tone="danger"
onClick={async () => {
setShowCancelConfirm(false);
await handleCancelSubscription();
}}
disabled={planLoadingId === currentSubscription?.id}
>
{planLoadingId === currentSubscription?.id ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Cancelling...
</>
) : (
'Yes, Cancel Subscription'
)}
</Button>
</div>
</div>
</div>
)}
</div>
);
}