import * as React from 'react'; import { __ } from '@wordpress/i18n'; import { BookingApi } from './api'; import { majorText, minorAmount, money } from './pricing'; import type { Booking } from './types'; export interface FinancialState { required_amount: number; paid_amount: number; refunded_amount: number; net_paid_amount: number; outstanding_amount: number; refund_due: number; payment_status: string; } interface CancellationQuote extends FinancialState { standard_fee: number; calculated_fee: number; minutes_before_start: number; } export function FinancialSummary({ booking: b }: { booking: Booking; }) { return
{__('Original booking price', 'abece-booking')}
{money(b.final_amount, b.currency)}
{__('Paid', 'abece-booking')}
{money(b.financial.paid_amount, b.currency)}
{__('Refunded', 'abece-booking')}
{money(b.financial.refunded_amount, b.currency)}
{b.status === 'cancelled' && <>
{__('Cancellation fee', 'abece-booking')}
{money(b.cancellation_fee, b.currency)}
}{b.status === 'no_show' && <>
{__('No-show fee', 'abece-booking')}
{money(b.no_show_fee, b.currency)}
}
{__('Outstanding', 'abece-booking')}
{money(b.financial.outstanding_amount, b.currency)}
{__('Refund due', 'abece-booking')}
{money(b.financial.refund_due, b.currency)}
; } export function CancellationForm({ booking: b, api, onChanged }: { booking: Booking; api: BookingApi; onChanged: (b: Booking) => void; }) { const [scopeOpen, setScopeOpen] = React.useState(false); const scoped = false; const [reason, setReason] = React.useState(''); const [mode, setMode] = React.useState('standard'); const [custom, setCustom] = React.useState('0'); const [quote, setQuote] = React.useState<{ key: string; value: CancellationQuote; } | null>(null); const [error, setError] = React.useState(''); const [busy, setBusy] = React.useState(false); const [revision, setRevision] = React.useState(0); const key = JSON.stringify([b.id, mode, custom, reason, revision]); function payload() { return { mode, reason, ...(mode === 'custom' ? { custom_fee: minorAmount(custom, b.currency, true) } : {}) }; } React.useEffect(() => { let live = true; setQuote(null); setError(''); const timer = window.setTimeout(() => { let body; try { body = payload(); } catch (e) { setError((e as Error).message); return; } api.request(`bookings/${b.id}/cancellation-quote`, 'POST', body).then(value => { if (live) setQuote({ key, value }); }).catch(e => { if (live) setError(e.message); }); }, 200); return () => { live = false; window.clearTimeout(timer); }; }, [api, key]); async function confirm() { if (quote?.key !== key) return; setBusy(true); setError(''); try { onChanged(await api.request(`bookings/${b.id}/cancel`, 'POST', { ...payload(), expected_fee: quote.value.calculated_fee })); } catch (e) { setError((e as Error).message); setRevision(v => v + 1); } finally { setBusy(false); } } const current = quote?.key === key ? quote.value : null; return <>
{ event.preventDefault(); if (scoped) setScopeOpen(true); else void confirm(); }}>

{__('Cancellation quote', 'abece-booking')}

{b.can_override_cancellation_fee && } {mode === 'custom' && }