Files
gitlab-instance-0a899031_no…/app/paid/page.tsx
2026-03-10 08:31:24 -05:00

118 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect, useState } from "react";
import { usePayStatusPoll } from "@/app/lib/usePayStatusPoll";
const COOKIE_NAME = "nomadvip_pay_order";
function getCookie(name: string): string | null {
if (typeof document === "undefined") return null;
const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
return match ? decodeURIComponent(match[1]) : null;
}
function parseUserIdFromOrderId(orderId: string): string {
if (!orderId?.includes("_order_")) return "";
const prefix = orderId.split("_order_")[0];
const parts = prefix.split("_");
return parts.length >= 2 ? parts.slice(0, -1).join("_") : "";
}
function SuccessWithRedirect() {
useEffect(() => {
const t = setTimeout(() => {
window.location.href = "/";
}, 2000);
return () => clearTimeout(t);
}, []);
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f4f8] px-4">
<div className="w-full max-w-md rounded-2xl bg-white p-10 text-center shadow-lg">
<div className="mx-auto mb-5 flex h-20 w-20 items-center justify-center rounded-full bg-emerald-50 text-5xl">
✅
</div>
<h2 className="text-2xl font-bold text-slate-800">支付成功</h2>
<p className="mt-3 text-slate-500">感谢您的支持,VIP 权益已开通</p>
<p className="mt-2 text-xs text-slate-400">2 秒后自动返回首页</p>
<a
href="/"
onClick={(e) => { e.preventDefault(); window.location.href = "/"; }}
className="mt-8 inline-flex items-center gap-2 rounded-full bg-sky-500 px-8 py-3 font-semibold text-white transition-colors hover:bg-sky-600"
>
← 立即返回首页
</a>
</div>
</div>
);
}
export default function PaidPage() {
const [status, setStatus] = useState<"pending" | "success" | "fail">("pending");
const [fromUrl, setFromUrl] = useState<string | null>(null);
usePayStatusPoll((orderId) => {
const uid = parseUserIdFromOrderId(orderId || "");
const raw = getCookie(COOKIE_NAME);
const oid = raw?.split("|")[0]?.trim() || orderId || "";
const userId = uid || parseUserIdFromOrderId(oid);
if (userId) {
try {
localStorage.setItem("paidType", "vip");
localStorage.setItem("userName", userId);
} catch {}
}
setStatus("success");
}, () => { window.location.href = "/"; });
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const paid = params.get("paid");
const fail = params.get("fail");
const from = params.get("from");
if (paid === "1") setStatus("success");
else if (fail === "1") setStatus("fail");
if (from) setFromUrl(decodeURIComponent(from));
}, []);
if (status === "pending") {
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f4f8] px-4">
<div className="w-full max-w-md rounded-2xl bg-white p-10 text-center shadow-lg">
<div className="mx-auto mb-5 flex h-16 w-16 animate-spin items-center justify-center rounded-full border-4 border-sky-200 border-t-sky-500" />
<h2 className="text-xl font-bold text-slate-800">支付结果确认中</h2>
<p className="mt-3 text-sm text-slate-500">
正在查询支付状态,请稍候…
<br />
(支付完成后将自动跳转,1 分钟内未支付将返回首页)
</p>
</div>
</div>
);
}
if (status === "success") {
return (
<SuccessWithRedirect />
);
}
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f4f8] px-4">
<div className="w-full max-w-md rounded-2xl bg-white p-10 text-center shadow-lg">
<div className="mx-auto mb-5 flex h-20 w-20 items-center justify-center rounded-full bg-amber-50 text-5xl">
⚠️
</div>
<h2 className="text-2xl font-bold text-slate-800">支付未完成</h2>
<p className="mt-3 text-slate-500">支付已取消或未成功,请重试</p>
<a
href="/"
onClick={(e) => { e.preventDefault(); window.location.href = "/"; }}
className="mt-8 inline-flex items-center gap-2 rounded-full border-2 border-slate-300 px-8 py-3 font-semibold text-slate-700 transition-colors hover:border-slate-400 hover:bg-slate-50"
>
← 返回首页
</a>
</div>
</div>
);
}