199 lines
7.2 KiB
TypeScript
199 lines
7.2 KiB
TypeScript
'use client'
|
||
|
||
import { useEffect, useState, Suspense } from 'react'
|
||
import { useSearchParams, useRouter } from 'next/navigation'
|
||
import { CheckCircle, Download, ArrowRight, Home, Receipt } from 'lucide-react'
|
||
import { Button } from '@/components/ui/button'
|
||
import { Card, CardContent } from '@/components/ui/card'
|
||
|
||
interface PaymentDetails {
|
||
txn: string
|
||
amount: string
|
||
type?: string
|
||
warning?: string
|
||
}
|
||
|
||
// Main payment success component with search params handling
|
||
function PaymentSuccessContent() {
|
||
const searchParams = useSearchParams()
|
||
const router = useRouter()
|
||
const [details, setDetails] = useState<PaymentDetails | null>(null)
|
||
const [countdown, setCountdown] = useState(10)
|
||
|
||
useEffect(() => {
|
||
// Extract payment details from URL parameters
|
||
const txn = searchParams.get('txn')
|
||
const amount = searchParams.get('amount')
|
||
const type = searchParams.get('type') || 'billing'
|
||
const warning = searchParams.get('warning')
|
||
|
||
if (txn && amount) {
|
||
setDetails({
|
||
txn,
|
||
amount,
|
||
type,
|
||
warning: warning || undefined,
|
||
})
|
||
}
|
||
|
||
// Auto-redirect countdown
|
||
const timer = setInterval(() => {
|
||
setCountdown((prev) => {
|
||
if (prev <= 1) {
|
||
router.push('/profile')
|
||
return 0
|
||
}
|
||
return prev - 1
|
||
})
|
||
}, 1000)
|
||
|
||
return () => clearInterval(timer)
|
||
}, [searchParams, router])
|
||
|
||
const handleDashboardRedirect = () => {
|
||
router.push('/profile')
|
||
}
|
||
|
||
const handleDownloadReceipt = () => {
|
||
// TODO: Implement receipt download
|
||
// In real implementation, this would generate and download a PDF receipt
|
||
console.log('Downloading receipt for transaction:', details?.txn)
|
||
alert('Receipt download feature will be implemented')
|
||
}
|
||
|
||
if (!details) {
|
||
return (
|
||
<div className="min-h-screen flex items-center justify-center">
|
||
<div className="text-center">
|
||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-green-500 mx-auto mb-4"></div>
|
||
<p>Loading payment details...</p>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-br from-green-50 to-blue-50 dark:from-green-900/10 dark:to-blue-900/10 flex items-center justify-center p-4">
|
||
<Card className="w-full max-w-lg">
|
||
<CardContent className="p-8 text-center">
|
||
{/* Success Icon */}
|
||
<div className="mb-6">
|
||
<div className="mx-auto w-16 h-16 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center">
|
||
<CheckCircle className="w-10 h-10 text-green-600 dark:text-green-400" />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Success Message */}
|
||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100 mb-2">
|
||
Payment Successful!
|
||
</h1>
|
||
|
||
<p className="text-gray-600 dark:text-gray-400 mb-6">
|
||
{details.type === 'balance'
|
||
? 'Your account balance has been updated successfully.'
|
||
: 'Your payment has been processed successfully.'}
|
||
</p>
|
||
|
||
{/* Warning Message (if any) */}
|
||
{details.warning && (
|
||
<div className="mb-6 p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-700 rounded-md">
|
||
<p className="text-sm text-yellow-800 dark:text-yellow-200">
|
||
⚠️ Payment successful, but there was an issue updating our records. Our team has
|
||
been notified and will resolve this shortly.
|
||
</p>
|
||
</div>
|
||
)}
|
||
|
||
{/* Payment Details */}
|
||
<div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 mb-6 space-y-3">
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">Transaction ID</span>
|
||
<code className="text-sm font-mono text-gray-900 dark:text-gray-100">
|
||
{details.txn}
|
||
</code>
|
||
</div>
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">Amount</span>
|
||
<span className="text-lg font-bold text-green-600 dark:text-green-400">
|
||
₹{parseFloat(details.amount).toLocaleString('en-IN', { minimumFractionDigits: 2 })}
|
||
</span>
|
||
</div>
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">Type</span>
|
||
<span className="text-sm capitalize text-gray-900 dark:text-gray-100">
|
||
{details.type === 'balance' ? 'Balance Addition' : 'Service Payment'}
|
||
</span>
|
||
</div>
|
||
<div className="flex justify-between items-center">
|
||
<span className="text-sm text-gray-600 dark:text-gray-400">Date</span>
|
||
<span className="text-sm text-gray-900 dark:text-gray-100">
|
||
{new Date().toLocaleDateString('en-IN', {
|
||
year: 'numeric',
|
||
month: 'short',
|
||
day: 'numeric',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
})}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Action Buttons */}
|
||
<div className="flex flex-col sm:flex-row gap-3 mb-6">
|
||
<Button onClick={handleDownloadReceipt} variant="outline" className="flex-1">
|
||
<Receipt className="w-4 h-4 mr-2" />
|
||
Download Receipt
|
||
</Button>
|
||
<Button onClick={handleDashboardRedirect} className="flex-1">
|
||
<Home className="w-4 h-4 mr-2" />
|
||
Go to Dashboard
|
||
</Button>
|
||
</div>
|
||
|
||
{/* Auto-redirect Notice */}
|
||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||
Redirecting to dashboard in {countdown} seconds
|
||
</p>
|
||
|
||
{/* Next Steps */}
|
||
<div className="mt-6 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||
<h3 className="text-sm font-medium text-blue-900 dark:text-blue-100 mb-2">
|
||
What's Next?
|
||
</h3>
|
||
<div className="text-sm text-blue-700 dark:text-blue-300 space-y-1">
|
||
{details.type === 'balance' ? (
|
||
<>
|
||
<p>• Your account balance has been updated</p>
|
||
<p>• You can now use your balance for services</p>
|
||
<p>• Check your transaction history in your profile</p>
|
||
</>
|
||
) : (
|
||
<>
|
||
<p>• Your service will be activated shortly</p>
|
||
<p>• Check your email for service details</p>
|
||
<p>• View service status in your dashboard</p>
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
// Wrapper component with Suspense boundary
|
||
export default function PaymentSuccessPage() {
|
||
return (
|
||
<Suspense
|
||
fallback={
|
||
<div className="min-h-screen flex items-center justify-center">
|
||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary"></div>
|
||
</div>
|
||
}
|
||
>
|
||
<PaymentSuccessContent />
|
||
</Suspense>
|
||
)
|
||
}
|