ledgerone_frontend/app/pricing/pricing-actions.tsx

55 lines
1.5 KiB
TypeScript

"use client";
import Link from "next/link";
import { useState } from "react";
import { apiFetch } from "@/lib/api";
type PricingActionProps = {
plan: "free" | "pro" | "elite";
label: string;
primary: boolean;
};
export function PricingAction({ plan, label, primary }: PricingActionProps) {
const [status, setStatus] = useState("");
const [loading, setLoading] = useState(false);
const className = `mt-8 block w-full text-center ${primary ? "btn-primary" : "btn-secondary"} disabled:opacity-60`;
if (plan === "free") {
return (
<Link href="/register" className={className}>
{label}
</Link>
);
}
const startCheckout = async () => {
setLoading(true);
setStatus("Opening checkout...");
const appUrl = window.location.origin;
const response = await apiFetch<{ url: string }>("/api/billing/checkout", {
method: "POST",
body: JSON.stringify({
plan,
successUrl: `${appUrl}/settings/subscription?upgraded=1`,
cancelUrl: `${appUrl}/pricing`,
}),
});
setLoading(false);
if (response.error || !response.data?.url) {
setStatus(response.error?.message ?? "Sign in before choosing a paid plan.");
return;
}
window.location.href = response.data.url;
};
return (
<>
<button type="button" onClick={startCheckout} disabled={loading} className={className}>
{loading ? "Opening..." : label}
</button>
{status ? <p className="mt-3 text-center text-xs text-muted-foreground">{status}</p> : null}
</>
);
}