154 lines
5.9 KiB
TypeScript
154 lines
5.9 KiB
TypeScript
'use client';
|
|
|
|
import React, { useEffect, useState } from "react";
|
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
import axios from "axios";
|
|
import IconCircleCheck from "@/components/icon/icon-circle-check";
|
|
import { ApiServerBaseUrl } from "@/utils/baseurl.utils";
|
|
|
|
const PaymentSuccess: React.FC = () => {
|
|
const [payment, setPayment] = useState<any>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
const sessionId = searchParams.get("session_id");
|
|
|
|
useEffect(() => {
|
|
if (!sessionId) {
|
|
setError("No session_id provided");
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
const fetchPaymentDetails = async () => {
|
|
try {
|
|
const res: any = await axios.get(
|
|
`${ApiServerBaseUrl}/payment/details`,
|
|
{ params: { session_id: sessionId } }
|
|
);
|
|
setPayment(res.data.data);
|
|
localStorage.setItem('payment_session', res.data.data?.stripeSessionId);
|
|
} catch (err: any) {
|
|
console.error(err);
|
|
setError(err.response?.data?.error || "Failed to fetch payment details");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchPaymentDetails();
|
|
}, [sessionId]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="flex items-center justify-center min-h-[88vh] text-gray-400 bg-[#111111]">
|
|
Loading payment details...
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="flex items-center justify-center min-h-[88vh] text-red-500 bg-[#111111]">
|
|
{error}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="relative flex flex-col items-center justify-center min-h-[88vh] bg-[#111111] px-4 overflow-hidden">
|
|
|
|
{/* ------------------ GLOWING BUBBLES ------------------ */}
|
|
<div className="absolute bottom-[-100px] left-[10%] w-[70px] h-[70px] rounded-full bg-pink-500/60 blur-3xl shadow-lg animate-floatUp mix-blend-add"></div>
|
|
<div className="absolute bottom-[-120px] left-[30%] w-[90px] h-[90px] rounded-full bg-blue-500/60 blur-3xl shadow-lg animate-floatUpSlow mix-blend-add"></div>
|
|
<div className="absolute bottom-[-110px] left-[60%] w-[60px] h-[60px] rounded-full bg-green-400/60 blur-3xl shadow-lg animate-floatUpFast mix-blend-add"></div>
|
|
<div className="absolute bottom-[-130px] left-[80%] w-[100px] h-[100px] rounded-full bg-purple-500/60 blur-3xl shadow-lg animate-floatUpSlow mix-blend-add"></div>
|
|
<div className="absolute bottom-[-140px] left-[45%] w-[50px] h-[50px] rounded-full bg-yellow-400/60 blur-3xl shadow-lg animate-floatUp mix-blend-add"></div>
|
|
|
|
{/* Extra scattered bubbles */}
|
|
<div className="absolute bottom-[-150px] left-[20%] w-[40px] h-[40px] rounded-full bg-red-500/50 blur-2xl shadow-lg animate-floatUpFast mix-blend-add"></div>
|
|
<div className="absolute bottom-[-160px] left-[70%] w-[55px] h-[55px] rounded-full bg-cyan-400/50 blur-2xl shadow-lg animate-floatUp mix-blend-add"></div>
|
|
|
|
{/* ✅ Success Icon */}
|
|
<div className="animate-bounce mb-3 z-10">
|
|
<IconCircleCheck className="w-24 h-24 text-green-400 drop-shadow-lg" />
|
|
</div>
|
|
|
|
{/* ✅ Title */}
|
|
<h1 className="text-3xl font-bold text-white mb-2 text-center z-10">
|
|
Payment Successful 🎉
|
|
</h1>
|
|
|
|
{/* ✅ Subtitle */}
|
|
<p className="text-gray-300 mb-6 text-center max-w-md z-10">
|
|
Thank you for your purchase! Your payment has been processed successfully.
|
|
</p>
|
|
|
|
{/* Card with Details */}
|
|
<div className="bg-[#242424] shadow-xl rounded-2xl p-6 w-full max-w-md border border-gray-700 transition-transform duration-300 hover:scale-[1.02] space-y-3 z-10">
|
|
|
|
<div className="flex justify-between items-start mb-3">
|
|
<span className="text-gray-400">Transaction ID:</span>
|
|
<span className="font-semibold text-white break-all max-w-[60%]">
|
|
{payment?.stripeSessionId}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="flex justify-between items-start mb-3">
|
|
<span className="text-gray-400">Email:</span>
|
|
<span className="font-semibold text-white break-words max-w-[60%]">
|
|
{payment?.email}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="flex justify-between items-start mb-3">
|
|
<span className="text-gray-400">Plan:</span>
|
|
<span className="font-semibold text-white break-words max-w-[60%]">
|
|
{payment?.planId}
|
|
</span>
|
|
</div>
|
|
|
|
{/* <div className="flex justify-between items-start mb-3">
|
|
<span className="text-gray-400">Amount:</span>
|
|
<span className="font-semibold text-white break-words max-w-[60%]">
|
|
${payment?.amount}
|
|
</span>
|
|
</div> */}
|
|
|
|
<div className="flex justify-between items-start mb-3">
|
|
<span className="text-gray-400">Payment Status:</span>
|
|
<span className="font-semibold text-green-400 break-words max-w-[60%]">
|
|
{payment?.status}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="flex justify-between">
|
|
<span className="text-gray-400">Subscription:</span>
|
|
<span className="font-semibold text-white">
|
|
{payment?.startDate
|
|
? `${new Date(payment.startDate).toLocaleDateString()} → ${new Date(payment.endDate).toLocaleDateString()}`
|
|
: "Pending activation"}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* ✅ Button */}
|
|
<button
|
|
onClick={() => router.push("/")}
|
|
className="mt-8 bg-green-500 hover:bg-green-600 text-white px-6 py-3 rounded-xl shadow-lg font-medium transition-all duration-200 hover:shadow-2xl z-10"
|
|
>
|
|
Go to Dashboard
|
|
</button>
|
|
|
|
{/* ✅ Footer Text */}
|
|
<p className="mt-6 text-sm text-gray-400 text-center z-10">
|
|
You can view your payment history anytime from your dashboard.
|
|
</p>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PaymentSuccess;
|