diff --git a/frontend/src/lib/components/account/UserBookingModal.svelte b/frontend/src/lib/components/account/UserBookingModal.svelte index 715f92d..b684d0c 100644 --- a/frontend/src/lib/components/account/UserBookingModal.svelte +++ b/frontend/src/lib/components/account/UserBookingModal.svelte @@ -9,6 +9,7 @@ import { Input } from '$lib/components/ui/input'; import UserPaymentModal from '$lib/components/payments/UserPaymentModal.svelte'; import EditRequestModal from '$lib/components/account/EditRequestModal.svelte'; + import { computeBalanceDue } from '$lib/utils/booking'; import type { Booking, BookingDiscount, Payment } from '$lib/types/booking'; interface Props { @@ -68,6 +69,14 @@ .reduce((sum, p) => sum + p.amount, 0) || 0 ); + let totalRefunds = $derived( + (selectedBooking?.refunds ?? []) + .filter((r) => r.status === 'completed') + .reduce((sum, r) => sum + r.amount, 0) + ); + + let balanceDue = $derived(selectedBooking ? computeBalanceDue(selectedBooking) : 0); + let depositOutstanding = $derived( selectedBooking?.deposit_required && !selectedBooking?.deposit_paid ); @@ -279,13 +288,13 @@ } } - function getPaymentName(payment: Payment, index: number, payments: Payment[], discounts: BookingDiscount[] | undefined): string { + function getPaymentName(payment: Payment, index: number, payments: Payment[] | undefined, discounts: BookingDiscount[] | undefined): string { if (payment.payment_method === 'online_square') return 'Online Card'; if (payment.payment_method === 'in_person_card') return 'Card Machine'; if (payment.payment_method === 'cash') return 'Cash'; if (payment.payment_method === 'giftcard') return 'Gift Card'; if (payment.payment_method === 'discount') { - const discountPaymentsBefore = payments.slice(0, index).filter(p => p.payment_method === 'discount').length; + const discountPaymentsBefore = (payments ?? []).slice(0, index).filter(p => p.payment_method === 'discount').length; const discountList = (discounts ?? []).filter(d => d.discount_amount > 0.01); if (discountList[discountPaymentsBefore]) { const d = discountList[discountPaymentsBefore]; @@ -365,6 +374,13 @@
Awaiting admin approval
-- {#if timeChanged} - Reschedule requested from {new SvelteDate(pendingEditRequest.original.start_time!).toLocaleString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })} to {new SvelteDate(pendingEditRequest.proposed.start_time!).toLocaleString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })} + {@const originalNames = (pendingEditRequest.original.services ?? []).map(s => s.name)} + {@const proposedNames = (pendingEditRequest.proposed.services ?? []).map(s => s.name)} + {@const addedServices = proposedNames.filter(n => !originalNames.includes(n))} + {@const removedServices = originalNames.filter(n => !proposedNames.includes(n))} + {#if timeChanged || servicesChanged} +
Awaiting admin approval
++ {#if timeChanged} + Reschedule requested from {new SvelteDate(pendingEditRequest.original.start_time!).toLocaleString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })} to {new SvelteDate(pendingEditRequest.proposed.start_time!).toLocaleString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })} + {/if} +
+ {#if addedServices.length > 0} ++ Services added: {addedServices.join(', ')} +
{/if} - {#if servicesChanged} - {timeChanged ? ' • ' : ''}Service change requested + {#if removedServices.length > 0} ++ Services removed: {removedServices.join(', ')} +
{/if} - {pendingEditRequest.notes ? (timeChanged || servicesChanged ? ' — ' : '') + pendingEditRequest.notes : ''} - -We'll let you know once it's been reviewed
+We'll let you know once it's been reviewed
+Applied Discounts
{#each booking.discounts as d}- - {d.discount_source === 'loyalty' ? 'Loyalty Stamp Card' : d.campaign_name || 'Promo Campaign'} + - {d.discount_source === 'loyalty' ? 'Loyalty Stamp Card' : d.discount_source === 'referral' ? 'Referral Discount' : d.campaign_name || 'Promo Campaign'} ({d.discount_percent}% off): -£{d.discount_amount.toFixed(2)}
{/each} diff --git a/frontend/src/lib/components/admin/BookingCreateModal.svelte b/frontend/src/lib/components/admin/BookingCreateModal.svelte index 109aa60..926906e 100644 --- a/frontend/src/lib/components/admin/BookingCreateModal.svelte +++ b/frontend/src/lib/components/admin/BookingCreateModal.svelte @@ -4,6 +4,7 @@ import { SvelteDate } from 'svelte/reactivity'; import { CalendarDate, getLocalTimeZone, type DateValue } from '@internationalized/date'; import { isValidUKPhone, toE164UK } from '$lib/utils/phone'; + import { formatUserName } from '$lib/utils/nameDisplay'; // UI Components import * as Modal from '$lib/components/ui/dialog'; @@ -55,7 +56,7 @@ let userQuery = $state(''); // Updated type to include account_role for filtering let users = $state< - Array<{ id: string; fullName: string; email?: string; phone?: string; account_role: string }> + Array<{ id: string; fullName: string; email?: string; phone?: string; account_role: string; previousFirstName?: string | null; previousLastName?: string | null }> >([]); let selectedUserId = $state