11import { useCallback , useState } from 'react'
2- import type { AppointmentLocation , BookingResponse , ClientInfo , TimeSlot } from '../api-types'
2+ import type { AppointmentLocation , ClientInfo , TimeSlot } from '../api-types'
33import { useTebutoContext } from './TebutoProvider'
44
5- type BookingState = {
6- booking : BookingResponse | null
5+ type BookingRequestState = {
76 isLoading : boolean
87 error : Error | null
98 isSuccess : boolean
@@ -15,61 +14,49 @@ type BookAppointmentParams = {
1514 locationSelection ?: AppointmentLocation
1615}
1716
18- type UseBookAppointmentReturn = BookingState & {
19- /** Book the appointment */
20- book : ( params : BookAppointmentParams ) => Promise < BookingResponse | null >
21- /** Reset the booking state */
17+ type UseBookAppointmentReturn = BookingRequestState & {
18+ /** Submit booking request - returns true on success */
19+ book : ( params : BookAppointmentParams ) => Promise < boolean >
20+ /** Reset the state */
2221 reset : ( ) => void
23- /** Download the calendar file (.ics) */
24- downloadCalendar : ( ) => void
2522}
2623
2724/**
28- * useBookAppointment - Complete the booking process
25+ * useBookAppointment - Submit a public booking request
2926 *
30- * Submits the booking with client information and handles
31- * the response including calendar download .
27+ * Submits a booking request with client information. For public bookings,
28+ * the client will receive a confirmation email to verify the appointment .
3229 *
3330 * @example
3431 * ```tsx
35- * const { book, booking, isLoading, isSuccess, downloadCalendar , reset } = useBookAppointment()
32+ * const { book, isLoading, isSuccess, error , reset } = useBookAppointment()
3633 *
3734 * const handleSubmit = async (clientInfo: ClientInfo) => {
38- * const result = await book({
35+ * const success = await book({
3936 * slot: claimedSlot,
4037 * client: clientInfo,
4138 * locationSelection: selectedLocation
4239 * })
4340 *
44- * if (result ) {
41+ * if (success ) {
4542 * setStep('confirmation')
4643 * }
4744 * }
48- *
49- * if (isSuccess) {
50- * return (
51- * <SuccessMessage>
52- * <button onClick={downloadCalendar}>Add to Calendar</button>
53- * <button onClick={reset}>Book Another</button>
54- * </SuccessMessage>
55- * )
56- * }
5745 * ```
5846 */
5947export function useBookAppointment ( ) : UseBookAppointmentReturn {
6048 const { therapistUUID, buildUrl, fingerprint } = useTebutoContext ( )
61- const [ state , setState ] = useState < BookingState > ( {
62- booking : null ,
49+ const [ state , setState ] = useState < BookingRequestState > ( {
6350 isLoading : false ,
6451 error : null ,
6552 isSuccess : false
6653 } )
6754
6855 const book = useCallback (
69- async ( params : BookAppointmentParams ) : Promise < BookingResponse | null > => {
56+ async ( params : BookAppointmentParams ) : Promise < boolean > => {
7057 const { slot, client, locationSelection } = params
7158
72- setState ( prev => ( { ... prev , isLoading : true , error : null } ) )
59+ setState ( { isLoading : true , error : null , isSuccess : false } )
7360
7461 try {
7562 const response = await fetch ( buildUrl ( `/events/${ therapistUUID } /book` ) , {
@@ -89,52 +76,33 @@ export function useBookAppointment(): UseBookAppointmentReturn {
8976 throw new Error ( `Booking failed: ${ response . statusText } ` )
9077 }
9178
92- const booking = ( await response . json ( ) ) as BookingResponse
93-
9479 setState ( {
95- booking,
9680 isLoading : false ,
9781 error : null ,
9882 isSuccess : true
9983 } )
10084
101- return booking
85+ return true
10286 } catch ( err ) {
10387 const error = err instanceof Error ? err : new Error ( 'Unknown error occurred' )
104- setState ( prev => ( { ... prev , isLoading : false , error, isSuccess : false } ) )
105- return null
88+ setState ( { isLoading : false , error, isSuccess : false } )
89+ return false
10690 }
10791 } ,
10892 [ therapistUUID , buildUrl , fingerprint ]
10993 )
11094
11195 const reset = useCallback ( ( ) => {
11296 setState ( {
113- booking : null ,
11497 isLoading : false ,
11598 error : null ,
11699 isSuccess : false
117100 } )
118101 } , [ ] )
119102
120- const downloadCalendar = useCallback ( ( ) => {
121- if ( ! state . booking ?. ics ) return
122-
123- const blob = new Blob ( [ state . booking . ics ] , { type : 'text/calendar;charset=utf-8' } )
124- const url = window . URL . createObjectURL ( blob )
125- const link = document . createElement ( 'a' )
126- link . href = url
127- link . setAttribute ( 'download' , 'appointment.ics' )
128- document . body . appendChild ( link )
129- link . click ( )
130- document . body . removeChild ( link )
131- window . URL . revokeObjectURL ( url )
132- } , [ state . booking ] )
133-
134103 return {
135104 ...state ,
136105 book,
137- reset,
138- downloadCalendar
106+ reset
139107 }
140108}
0 commit comments