# 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)

