Booking Details {#if selectedBooking}
ID: {selectedBooking.id}
{/if}
{#if selectedBooking} {@const isPastBooking = new SvelteDate(selectedBooking.start_time) < new SvelteDate()} {@const isUnpaid = selectedBooking.amount_due > 0} {@const showChip = !isPastBooking || isUnpaid} {@const isConfirmedOrLater = ['confirmed', 'in_progress', 'completed'].includes( selectedBooking.status )} {#if showChip}
{isPastBooking ? 'Unpaid' : selectedBooking.status.replace('_', ' ')} {#if selectedBooking.deposit_required} {#if selectedBooking.status === 'pending'} Will Require Deposit {:else if isConfirmedOrLater} {selectedBooking.deposit_paid ? 'Deposit Paid' : 'Deposit Due'} {/if} {/if}
{/if} {/if}
{#if loading}
Loading...
{:else if selectedBooking}

Appointment Details

Scheduled Date & Time
{(() => { const date = new SvelteDate(selectedBooking.start_time); const dateStr = date.toLocaleDateString('en-US', { weekday: 'long', day: 'numeric', month: 'short' }); const timeStr = date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true }); return `${dateStr} at ${timeStr}`; })()}
Duration
{totalDuration} minutes
{#if selectedBooking.notes}
Notes
{selectedBooking.notes}
{/if}
{#if selectedBooking.services && selectedBooking.services.length > 0}

Services

{#each selectedBooking.services as service, index (index)}
{service.service_name || '—'}
{#if service.service_description}
{service.service_description}
{/if}
{service.override_duration_minutes ?? service.duration_minutes} min £{(service.override_price ?? service.price ?? 0).toFixed(2)}
{/each}
{/if}

Financial Summary

{#if ['confirmed', 'in_progress', 'completed'].includes(selectedBooking.status) && selectedBooking.deposit_required}
Deposit Required
£{selectedBooking.deposit_amount?.toFixed(2) || '0.00'}
{selectedBooking.deposit_paid ? 'Paid' : 'Outstanding'} {#if !selectedBooking.deposit_paid && selectedBooking.deposit_deadline} • Due: {new SvelteDate(selectedBooking.deposit_deadline).toLocaleDateString( 'en-GB', { weekday: 'short', day: 'numeric', month: 'short', year: 'numeric' } )} at {new SvelteDate(selectedBooking.deposit_deadline).toLocaleTimeString( 'en-GB', { hour: 'numeric', minute: '2-digit', hour12: true } )} {/if}
{/if}
Subtotal (Services) £{selectedBooking.total_amount.toFixed(2)}
{#if selectedBooking.discounts && selectedBooking.discounts.length > 0}
{#each selectedBooking.discounts as d}
{#if d.discount_source === 'loyalty'} Loyalty Stamp Card (10% Off) {:else if d.campaign_name} {d.campaign_name} ({d.discount_percent}% Off) {:else} Promo Campaign ({d.discount_percent}% Off) {/if} -£{d.discount_amount.toFixed(2)}
{/each}
Net Total £{(selectedBooking.total_amount - selectedBooking.discounts.reduce((sum, d) => sum + d.discount_amount, 0)).toFixed(2)}
{/if}
Amount Paid (Card/Cash) £{(selectedBooking.payments ?? []).filter(p => p.payment_method !== 'discount' && p.status === 'completed').reduce((sum, p) => sum + p.amount, 0).toFixed(2)}
{#if Math.max(0, selectedBooking.total_amount - (selectedBooking.discounts ?? []).reduce((sum, d) => sum + d.discount_amount, 0) - (selectedBooking.payments ?? []).filter(p => p.payment_method !== 'discount' && p.status === 'completed').reduce((sum, p) => sum + p.amount, 0)) > 0.01}
{isFutureBooking ? 'Estimated Subtotal' : 'Amount Due'} £{Math.max(0, selectedBooking.total_amount - (selectedBooking.discounts ?? []).reduce((sum, d) => sum + d.discount_amount, 0) - (selectedBooking.payments ?? []).filter(p => p.payment_method !== 'discount' && p.status === 'completed').reduce((sum, p) => sum + p.amount, 0)).toFixed(2)}
{/if}
{#if selectedBooking.payments && selectedBooking.payments.length > 0}

Payment History

{#each selectedBooking.payments as payment, index (index)}
{getPaymentName(payment, index, selectedBooking.payments, selectedBooking.discounts)} {payment.status}
{#if payment.payment_method === 'discount'} Applied automatically on completion {:else} {payment.payment_type.charAt(0).toUpperCase() + payment.payment_type.slice(1)} payment {#if payment.card_last4} , Card ending in {payment.card_last4} {/if} {/if}
{#if payment.is_vat_applicable}
Net: £{payment.net_amount?.toFixed(2) || '0.00'}
{#if payment.vat_amount}
VAT ({(payment.vat_rate || 0) * 100}%): £{payment.vat_amount.toFixed( 2 )}
{/if}
{/if}
{new SvelteDate(payment.created_at).toLocaleString()}
{payment.payment_method === 'discount' ? '-' : ''}£{payment.amount.toFixed(2)}
{/each}
{/if}
{/if}
{#if isCancellable} {#if canEditBooking} {/if} {/if}
{#if isCompleted} {/if} {#if depositOutstanding} {:else if canPayEarly && !hasPendingEditRequest} {/if}
{#if showEditModal && selectedBooking} { showEditModal = false; fetchBookingDetails(); }} /> {/if} {#if showPaymentModal && selectedBooking} (showPaymentModal = false)} onComplete={handlePaymentComplete} {canSaveCards} /> {/if} (showCancelConfirm = v)}> Cancel Booking {#if hasPayments}

Are you sure you want to cancel this booking? You have already made payments totalling £{totalPaid.toFixed(2)}.

{:else} Are you sure you want to cancel this booking? {/if} {#if hasPayments}

Please note:

Any amounts paid (£{totalPaid.toFixed(2)}) will not be refunded, but will be retained as credit towards a future appointment.

{#if selectedBooking} {#if selectedBooking.deposit_paid}

The deposit of £{selectedBooking.deposit_amount?.toFixed(2)} paid for this booking may be forfeited.

{/if} {#if selectedBooking.deposit_required && !selectedBooking.deposit_paid}

Any outstanding deposit will no longer be due.

{/if} {/if}
{/if}
{ if (!v) { showTipModal = false; tipAmount = 0; selectedTipPreset = null; customTipInput = ''; } }} > Leave a Tip Show your appreciation for great service
{#each tipPresets as preset (preset.pct)} {/each}
£