import { useCallback } from 'react'; import { usePersSDK } from '../providers/PersSDKProvider'; import type { BookingDTO, CreateBookingDTO, UpdateBookingDTO } from '@explorins/pers-shared'; import type { BookingQueryOptions, BookingValidationOptions } from '@explorins/pers-sdk'; // Re-export for consumers export type { BookingQueryOptions, BookingValidationOptions } from '@explorins/pers-sdk'; /** * Hook interface for booking operations */ export interface BookingHook { /** Get all bookings with optional filters */ getBookings: (options?: BookingQueryOptions) => Promise; /** Get a single booking by ID */ getBookingById: (id: string) => Promise; /** Create a new booking */ createBooking: (data: CreateBookingDTO) => Promise; /** Update an existing booking */ updateBooking: (id: string, data: UpdateBookingDTO) => Promise; /** Delete a booking */ deleteBooking: (id: string) => Promise; /** Check if a user has a valid booking */ hasValidBooking: (userId: string, options?: BookingValidationOptions) => Promise; /** Whether the SDK is initialized */ isInitialized: boolean; /** Whether the user is authenticated */ isAuthenticated: boolean; } /** * React hook for booking management operations * * Provides methods to create, read, update, and delete bookings, * as well as checking if a user has a valid booking for redemption eligibility. * * @example * ```typescript * import { useBookings } from '@explorins/pers-sdk-react-native'; * * function BookingScreen() { * const { getBookings, createBooking, hasValidBooking } = useBookings(); * * // List all bookings for a user * const userBookings = await getBookings({ userId: 'user-123' }); * * // Create a booking * const newBooking = await createBooking({ * userId: 'user-123', * locationName: 'Resort Hotel', * checkInDate: '2026-06-01', * checkOutDate: '2026-06-05' * }); * * // Check if user has valid booking for redemption * const isEligible = await hasValidBooking('user-123', { status: 'active' }); * } * ``` */ export const useBookings = (): BookingHook => { const { sdk, isInitialized, isAuthenticated } = usePersSDK(); /** * Get all bookings with optional filters * * @param options - Query options including userId, businessId, status filters * @returns Array of booking DTOs */ const getBookings = useCallback(async (options?: BookingQueryOptions): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { return await sdk.bookings.getAll(options); } catch (error) { console.error('Failed to fetch bookings:', error); throw error; } }, [sdk, isInitialized]); /** * Get a single booking by ID * * @param id - Booking UUID * @returns Booking DTO */ const getBookingById = useCallback(async (id: string): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { return await sdk.bookings.getById(id); } catch (error) { console.error('Failed to fetch booking:', error); throw error; } }, [sdk, isInitialized]); /** * Create a new booking * * @param data - Booking data including userId, locationName, dates * @returns Created booking DTO */ const createBooking = useCallback(async (data: CreateBookingDTO): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { return await sdk.bookings.create(data); } catch (error) { console.error('Failed to create booking:', error); throw error; } }, [sdk, isInitialized]); /** * Update an existing booking * * @param id - Booking UUID * @param data - Partial booking data to update * @returns Updated booking DTO */ const updateBooking = useCallback(async (id: string, data: UpdateBookingDTO): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { return await sdk.bookings.update(id, data); } catch (error) { console.error('Failed to update booking:', error); throw error; } }, [sdk, isInitialized]); /** * Delete a booking * * @param id - Booking UUID */ const deleteBooking = useCallback(async (id: string): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { await sdk.bookings.delete(id); } catch (error) { console.error('Failed to delete booking:', error); throw error; } }, [sdk, isInitialized]); /** * Check if a user has a valid booking * * @param userId - User ID to check * @param options - Validation options including status filter * @returns true if user has valid booking matching criteria */ const hasValidBooking = useCallback(async ( userId: string, options?: BookingValidationOptions ): Promise => { if (!isInitialized || !sdk) { throw new Error('SDK not initialized. Call initialize() first.'); } try { return await sdk.bookings.hasValidBooking(userId, options); } catch (error) { console.error('Failed to check booking validity:', error); throw error; } }, [sdk, isInitialized]); return { getBookings, getBookingById, createBooking, updateBooking, deleteBooking, hasValidBooking, isInitialized, isAuthenticated, }; };