63 lines
1.7 KiB
TypeScript
63 lines
1.7 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import Link from 'next/link';
|
|
|
|
export default function BillingSuccessPage() {
|
|
const [status, setStatus] = useState<'pending' | 'ok' | 'error'>('pending');
|
|
const [message, setMessage] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const session =
|
|
typeof window !== 'undefined'
|
|
? new URLSearchParams(window.location.search).get('session')
|
|
: null;
|
|
(async () => {
|
|
try {
|
|
const res = await fetch('/api/billing/finalize', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ session }),
|
|
});
|
|
if (!res.ok) {
|
|
const body = (await res.json().catch(() => ({}))) as {
|
|
error?: string;
|
|
};
|
|
setStatus('error');
|
|
setMessage(body.error ?? `Finalize failed (${res.status})`);
|
|
return;
|
|
}
|
|
setStatus('ok');
|
|
} catch (e) {
|
|
setStatus('error');
|
|
setMessage((e as Error).message);
|
|
}
|
|
})();
|
|
}, []);
|
|
|
|
return (
|
|
<div>
|
|
<h1>Upgrade complete</h1>
|
|
<div className="card">
|
|
{status === 'pending' && <p>Finalizing your upgrade…</p>}
|
|
{status === 'ok' && (
|
|
<>
|
|
<p className="success">Your account has been upgraded.</p>
|
|
<Link className="btn" href="/dashboard">
|
|
Back to dashboard
|
|
</Link>
|
|
</>
|
|
)}
|
|
{status === 'error' && (
|
|
<>
|
|
<p className="error">{message}</p>
|
|
<Link className="btn secondary" href="/billing">
|
|
Try again
|
|
</Link>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|