"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { cancelBookingWithRefundAction } from "@/features/booking/actions"; import { formatRupiah } from "@/lib/utils"; interface CancelBookingButtonProps { tripId: string; /** Hasil preview server-side (dihitung di trip detail page). */ preview: { days: number; refundAmount: number; bookingAmount: number; tierLabel: string; }; } type ServerResult = | { kind: "REFUND_PENDING"; refundAmount: number; days: number } | { kind: "CANCELLED_NO_REFUND"; days: number }; export function CancelBookingButton({ tripId, preview }: CancelBookingButtonProps) { const router = useRouter(); const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [result, setResult] = useState(null); async function handleConfirm() { setLoading(true); setError(""); const res = await cancelBookingWithRefundAction(tripId); setLoading(false); if ("error" in res) { setError(res.error ?? "Terjadi kesalahan"); return; } setResult({ kind: res.kind, refundAmount: res.refundAmount, days: res.days, } as ServerResult); router.refresh(); } if (result?.kind === "REFUND_PENDING") { return (

Request refund dibuat.

Refund {formatRupiah(result.refundAmount)}{" "} menunggu review admin. Setelah disetujui dan ditransfer manual, slot kamu di trip akan otomatis dibebaskan.

); } if (result?.kind === "CANCELLED_NO_REFUND") { return (

Booking dibatalkan.

Pembatalan di H-{result.days} berada di luar window refund — tidak ada nominal yang dikembalikan.

); } if (!open) { return ( ); } const percentage = preview.bookingAmount ? Math.floor((preview.refundAmount * 100) / preview.bookingAmount) : 0; const noRefund = preview.refundAmount === 0; return (

Cancel booking?

Kamu cancel di H-{preview.days}{" "} dari tanggal berangkat.

Estimasi refund (sesuai policy)

{formatRupiah(preview.refundAmount)} {!noRefund && ( ({percentage}% dari {formatRupiah(preview.bookingAmount)}) )}

Tier: {preview.tierLabel}

{noRefund ? (

⚠️ Di luar window refund — uang tidak dikembalikan. Booking akan di-cancel langsung.

) : (

Refund akan masuk antrian review admin. Setelah disetujui & uang ditransfer, booking otomatis ditandai{" "} {percentage === 100 ? "REFUNDED" : "PARTIALLY_REFUNDED"}.

)}
{error && (
{error}
)}
); }