diff --git a/frontend/src/app/(public)/pay/[id]/cancelled/page.tsx b/frontend/src/app/(public)/pay/[id]/cancelled/page.tsx new file mode 100644 index 0000000..36168d8 --- /dev/null +++ b/frontend/src/app/(public)/pay/[id]/cancelled/page.tsx @@ -0,0 +1,30 @@ +"use client"; + +import { useEffect, useState } from "react"; + +export default function CancelledPage() { + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) return null; + + return ( + + + Payment Cancelled + + You have successfully cancelled this payment. You may now safely close this tab. + + window.close()} + className="inline-flex h-11 items-center justify-center rounded-xl border border-white/15 bg-white/5 px-6 text-sm font-semibold text-white transition hover:bg-white/10" + > + Close Tab + + + + ); +} diff --git a/frontend/src/app/(public)/pay/[id]/page.tsx b/frontend/src/app/(public)/pay/[id]/page.tsx index 95c8c4f..a41209d 100644 --- a/frontend/src/app/(public)/pay/[id]/page.tsx +++ b/frontend/src/app/(public)/pay/[id]/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useEffect, useState, type CSSProperties } from "react"; -import { useParams } from "next/navigation"; +import { useParams, useRouter } from "next/navigation"; import { useLocale, useTranslations } from "next-intl"; import { useWallet } from "@/lib/wallet-context"; import { Spinner } from "@/components/ui/Spinner"; @@ -401,6 +401,7 @@ export default function PaymentPage() { const locale = localeToLanguageTag(useLocale()); const params = useParams(); const paymentId = params.id as string; + const router = useRouter(); const [payment, setPayment] = useState(null); const [loading, setLoading] = useState(true); @@ -411,6 +412,7 @@ export default function PaymentPage() { const [showConfetti, setShowConfetti] = useState(false); const [isDownloadingReceipt, setIsDownloadingReceipt] = useState(false); const [isPayModalOpen, setIsPayModalOpen] = useState(false); + const [isCancelModalOpen, setIsCancelModalOpen] = useState(false); const [networkFee, setNetworkFee] = useState(null); const [networkFeeLoading, setNetworkFeeLoading] = useState(false); @@ -1064,6 +1066,15 @@ export default function PaymentPage() { onConnected={() => {}} /> )} + + {/* Cancel Payment Link */} + setIsCancelModalOpen(true)} + className="mt-2 text-center text-sm font-medium text-slate-500 hover:text-white transition-colors" + > + Cancel Payment + )} @@ -1172,6 +1183,37 @@ export default function PaymentPage() { + + setIsCancelModalOpen(false)} + title="Cancel Payment" + > + + + Are you sure you want to cancel this payment? + + + setIsCancelModalOpen(false)} + className="flex h-11 flex-1 items-center justify-center rounded-xl border border-white/15 bg-white/5 px-4 text-sm font-semibold text-white transition hover:bg-white/10" + > + No, go back + + { + setIsCancelModalOpen(false); + router.push(`/pay/${paymentId}/cancelled`); + }} + className="flex h-11 flex-1 items-center justify-center rounded-xl bg-red-500/20 text-red-400 border border-red-500/30 px-4 text-sm font-semibold transition hover:bg-red-500/30" + > + Yes, cancel + + + + > ); }
+ You have successfully cancelled this payment. You may now safely close this tab. +
+ Are you sure you want to cancel this payment? +