@@ -0,0 +1,146 @@
|
||||
import { Form, Head, Link, usePage } from '@inertiajs/react';
|
||||
import { CheckCircle2, Clock3, CreditCard, TriangleAlert } from 'lucide-react';
|
||||
import PublicThemeToggle from '@/components/public-theme-toggle';
|
||||
|
||||
type Order = {
|
||||
uuid: string;
|
||||
plan: string;
|
||||
status: string;
|
||||
total: number;
|
||||
currency: string;
|
||||
checkout_url: string | null;
|
||||
gateway: string;
|
||||
payment_method: string | null;
|
||||
payment_methods: { code: string; name: string; fee: number }[];
|
||||
gateway_error: string | null;
|
||||
};
|
||||
|
||||
export default function CheckoutShow({ order }: { order: Order }) {
|
||||
const { errors } = usePage().props;
|
||||
const paid = order.status === 'paid';
|
||||
const total = new Intl.NumberFormat('id-ID', {
|
||||
style: 'currency',
|
||||
currency: order.currency,
|
||||
maximumFractionDigits: 0,
|
||||
}).format(order.total);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head title="Checkout Lisensi" />
|
||||
<main className="min-h-screen bg-background px-5 py-8 text-foreground">
|
||||
<div className="mx-auto max-w-xl">
|
||||
<header className="mb-10 flex items-center justify-between">
|
||||
<Link href="/" className="flex items-center gap-3">
|
||||
<img
|
||||
src="/images/radiq-ndm-logo.png"
|
||||
alt="RADIQ NDM"
|
||||
className="size-12 object-contain"
|
||||
/>
|
||||
<span className="font-semibold">RADIQ NDM</span>
|
||||
</Link>
|
||||
<PublicThemeToggle />
|
||||
</header>
|
||||
<div className="rounded-2xl border bg-card p-6 shadow-sm">
|
||||
<div className="flex items-center gap-3">
|
||||
{paid ? (
|
||||
<CheckCircle2 className="size-7 text-emerald-500" />
|
||||
) : (
|
||||
<CreditCard className="size-7 text-sky-500" />
|
||||
)}
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Checkout lisensi bulanan
|
||||
</p>
|
||||
<h1 className="text-2xl font-bold">
|
||||
{order.plan}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 rounded-xl bg-muted/50 p-4">
|
||||
<div className="flex justify-between">
|
||||
<span>Total pembayaran</span>
|
||||
<strong>{total}</strong>
|
||||
</div>
|
||||
<div className="mt-2 flex justify-between text-sm text-muted-foreground">
|
||||
<span>Gateway</span>
|
||||
<span>{order.gateway}</span>
|
||||
</div>
|
||||
<div className="mt-2 flex justify-between text-sm text-muted-foreground">
|
||||
<span>Status</span>
|
||||
<span>{order.status}</span>
|
||||
</div>
|
||||
</div>
|
||||
{paid ? (
|
||||
<div className="mt-6">
|
||||
<p className="text-sm text-emerald-600">
|
||||
Pembayaran diterima dan lisensi telah
|
||||
diaktifkan.
|
||||
</p>
|
||||
<Link
|
||||
href="/login"
|
||||
className="mt-4 block rounded-lg bg-sky-500 px-4 py-3 text-center font-semibold text-slate-950"
|
||||
>
|
||||
Login Tenant Admin
|
||||
</Link>
|
||||
</div>
|
||||
) : order.checkout_url ? (
|
||||
<div className="mt-6">
|
||||
<a
|
||||
href={order.checkout_url}
|
||||
className="block rounded-lg bg-sky-500 px-4 py-3 text-center font-semibold text-slate-950"
|
||||
>
|
||||
Lanjut Bayar dengan Duitku
|
||||
</a>
|
||||
<p className="mt-3 text-center text-xs text-muted-foreground">
|
||||
<Clock3 className="mr-1 inline size-3" />
|
||||
Status aktif setelah callback pembayaran
|
||||
terverifikasi.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-6 rounded-lg border p-4 text-sm">
|
||||
{order.gateway_error ? (
|
||||
<p className="text-destructive">
|
||||
<TriangleAlert className="mr-2 inline size-4" />
|
||||
{order.gateway_error}
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-muted-foreground">
|
||||
Pilih kanal pembayaran Duitku. Order ini tetap dapat dilanjutkan tanpa membuat order baru.
|
||||
</p>
|
||||
)}
|
||||
{errors.payment && (
|
||||
<p className="mt-2 text-destructive">{String(errors.payment)}</p>
|
||||
)}
|
||||
<Form
|
||||
action={`/checkout/${order.uuid}/retry`}
|
||||
method="post"
|
||||
className="mt-3"
|
||||
>
|
||||
{order.payment_methods.length > 0 && (
|
||||
<select
|
||||
name="payment_method"
|
||||
defaultValue={order.payment_method ?? ''}
|
||||
required
|
||||
className="mb-3 w-full rounded-md border bg-background px-3 py-2"
|
||||
>
|
||||
<option value="" disabled>Pilih kanal pembayaran</option>
|
||||
{order.payment_methods.map((method) => (
|
||||
<option key={method.code} value={method.code}>
|
||||
{method.name}{method.fee > 0 ? ` (biaya ${new Intl.NumberFormat('id-ID').format(method.fee)})` : ''}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
<button disabled={order.payment_methods.length === 0} className="w-full rounded-md bg-sky-500 px-3 py-2 font-semibold text-slate-950 disabled:opacity-50">
|
||||
Buat dan Lanjutkan Pembayaran
|
||||
</button>
|
||||
</Form>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user