ai-wpa/app/payment/success/page.tsx

199 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

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