# Book Slot Hook Migration to Shared Package **Date:** 2025-11-08 **Status:** ✅ Completed ## Overview Moved the `useBookSlot` hook from `apps/main/src/hooks/book.ts` to the `@xtablo/shared` package, making it available to all apps in the monorepo. Updated the `@xtablo/external` app to use this shared hook instead of the non-existent `useCreateTabloWithOwner` hook. ## Changes Made ### 1. Created Shared Hook Created `/packages/shared/src/hooks/book.ts` with: - Exported `useBookSlot` hook with improved API signature - Added optional `onSuccess` callback parameter for custom success handling - Made hook flexible to work in different contexts (embedded widgets, modal views, default navigation) **Hook Signature:** ```typescript export const useBookSlot = ( api: AxiosInstance, accessToken?: string, onSuccess?: (data: BookSlotResponse) => void ) => { /* ... */ } ``` ### 2. Updated Main App **File: `apps/main/src/hooks/book.ts`** - Replaced entire implementation with re-export from `@xtablo/shared` - Maintains backward compatibility for existing imports **File: `apps/main/src/pages/PublicBookingPage.tsx`** - Updated `useBookSlot()` call to pass required arguments: `useBookSlot(api, session?.access_token)` ### 3. Updated External App **Files Modified:** - `apps/external/src/FloatingBookingWidget.tsx` - `apps/external/src/EmbeddedBookingPage.tsx` **Changes:** 1. Removed non-existent `useCreateTabloWithOwner` import 2. Added `useBookSlot` import from `@xtablo/shared/hooks/book` 3. Refactored booking logic to use the booking slot API endpoint instead of direct tablo creation 4. Updated both logged-in and non-logged-in user flows 5. Maintained custom success callbacks for modal/widget closing behavior **Before:** ```typescript const { mutateAsync: createTabloWithOwner } = useCreateTabloWithOwner(api, () => { handleCloseModal(); }); await createTabloWithOwner({ name: eventType?.name || "", status: "todo", owner_short_id: shortUserId || "", event: { /* ... */ }, access_token: session?.access_token || "", }); ``` **After:** ```typescript const { mutateAsync: bookSlot } = useBookSlot(api, session?.access_token, () => { handleCloseModal(); }); await bookSlot({ event_type_standard_name: eventTypeStandardName || "", owner_short_id: shortUserId || "", event_details: { start_date: selectedSlot?.slot.date || "", start_time: startTime, end_time: endTime, }, user_details: { name: formData.name, email: formData.email, }, }); ``` ### 4. Updated Shared Package Exports **File: `packages/shared/src/index.ts`** - Added export for `./hooks/book` - Added export for `./hooks/public` (for `invalidatePublicSlots`) - Added exports for all type files to ensure proper type resolution ### 5. Fixed Import Dependencies **File: `packages/shared/src/hooks/book.ts`** - Fixed import of `queryClient` from `../lib/api` (not from `../lib/supabase`) - Imported `invalidatePublicSlots` from `./public` to avoid duplicate exports ## Benefits 1. **Code Reuse** - Single implementation of booking logic shared across all apps 2. **Consistency** - All apps use the same booking API and error handling 3. **Maintainability** - One place to update booking logic 4. **Flexibility** - Custom success callbacks allow different behavior per context 5. **Fixed Bug** - Replaced non-existent `useCreateTabloWithOwner` with working implementation ## Verification All packages pass verification: ```bash turbo typecheck lint --filter=@xtablo/shared --filter=@xtablo/external --filter=@xtablo/main ``` ✅ **Results:** - `@xtablo/shared` - typecheck ✓ lint ✓ - `@xtablo/main` - typecheck ✓ lint ✓ - `@xtablo/external` - typecheck ✓ lint ✓ ## API Contract ### Request Payload ```typescript { event_type_standard_name: string; owner_short_id: string; event_details: { start_date: string; // YYYY-MM-DD start_time: string; // HH:MM end_time: string; // HH:MM }; user_details: { name: string; email: string; }; } ``` ### Response ```typescript { tablo_id: string; hasCreatedAccount: boolean; email: string; } ``` ## Usage Examples ### Basic Usage (with default navigation) ```typescript const { mutateAsync: bookSlot } = useBookSlot(api, session?.access_token); await bookSlot({ event_type_standard_name: "consultation", owner_short_id: "abc123", event_details: { /* ... */ }, user_details: { /* ... */ }, }); // Default: navigates to /login or /tablos/:id based on hasCreatedAccount ``` ### Custom Success Handler (for widgets) ```typescript const { mutateAsync: bookSlot } = useBookSlot(api, session?.access_token, (data) => { handleCloseModal(); if (view === "modal") { window.parent.postMessage("xtablo:close", "*"); } }); ``` ## Related Documentation - [API Shared Types Migration](./API_SHARED_TYPES_MIGRATION.md) - [Shared Types Integration](./SHARED_TYPES_INTEGRATION.md) - [Types Package](./TYPES_PACKAGE.md)