> ## Documentation Index
> Fetch the complete documentation index at: https://developer.meetergo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Availability Picker

> Interactive component for setting weekly availability

<Note>
  This component is coming soon. This page documents the planned API and usage. [Join the developer preview](mailto:api-support@meetergo.com) for early access.
</Note>

The Availability Picker lets users visually set their weekly schedule with an intuitive drag-to-select interface.

## Features

* **Drag-to-select** - Click and drag to set available hours
* **Copy schedule** - Duplicate one day's schedule to others
* **Timezone support** - Display in user's local timezone
* **Presets** - Quick-select common schedules
* **Date exceptions** - Override availability for specific dates
* **Real-time sync** - Changes saved automatically

## Component Usage (Coming Soon)

### Basic Embed

```html theme={null}
<div id="availability-picker"></div>

<script src="https://cdn.meetergo.com/components.js"></script>
<script>
  Meetergo.AvailabilityPicker({
    container: '#availability-picker',
    userId: 'user-uuid',
    availabilityId: 'availability-uuid',
    onSave: (availability) => {
      console.log('Saved:', availability);
    }
  });
</script>
```

### React Component

```jsx theme={null}
import { AvailabilityPicker } from '@meetergo/react';

function AvailabilitySettings() {
  return (
    <AvailabilityPicker
      userId={userId}
      availabilityId={availabilityId}
      timezone="Europe/Berlin"
      format="24h"
      minInterval={30}
      onChange={(schedule) => {
        console.log('Changed:', schedule);
      }}
      onSave={(availability) => {
        toast.success('Availability saved!');
      }}
    />
  );
}
```

### Configuration Options

```javascript theme={null}
Meetergo.AvailabilityPicker({
  // Required
  container: '#availability-picker',
  userId: 'user-uuid',

  // Optional - if not provided, uses user's default availability
  availabilityId: 'availability-uuid',

  // Display options
  timezone: 'Europe/Berlin',     // User's timezone
  format: '24h',                 // '24h' or '12h'
  weekStartsOn: 'monday',        // 'monday' or 'sunday'
  minInterval: 30,               // Minimum interval in minutes (15, 30, 60)
  dayStartHour: 6,               // First hour to show
  dayEndHour: 22,                // Last hour to show

  // Features
  showPresets: true,             // Show preset schedule buttons
  showCopyDay: true,             // Show "copy to other days" option
  showExceptions: true,          // Show date exception management
  autoSave: true,                // Save automatically on change
  autoSaveDelay: 1000,           // Debounce delay in ms

  // Styling
  theme: {
    primaryColor: '#2563eb',
    availableColor: '#22c55e',
    unavailableColor: '#f3f4f6',
    borderRadius: '8px'
  },

  // Labels (for i18n)
  labels: {
    title: 'Set your availability',
    save: 'Save',
    reset: 'Reset',
    copyDay: 'Copy to other days',
    presets: {
      businessHours: 'Business hours (9-17)',
      mornings: 'Mornings only',
      afternoons: 'Afternoons only',
      clear: 'Clear all'
    },
    days: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },

  // Callbacks
  onChange: (schedule) => {},    // Called on every change
  onSave: (availability) => {},  // Called when saved
  onError: (error) => {}
});
```

## Schedule Data Format

The component works with this schedule format:

```javascript theme={null}
const schedule = {
  monday: { enabled: true, hours: [{ start: '09:00', end: '12:00' }, { start: '13:00', end: '17:00' }] },
  tuesday: { enabled: true, hours: [{ start: '09:00', end: '17:00' }] },
  wednesday: { enabled: true, hours: [{ start: '09:00', end: '17:00' }] },
  thursday: { enabled: true, hours: [{ start: '09:00', end: '17:00' }] },
  friday: { enabled: true, hours: [{ start: '09:00', end: '17:00' }] },
  saturday: { enabled: false, hours: [] },
  sunday: { enabled: false, hours: [] }
};
```

## Current API Implementation

While the component is in development, use the API:

### Get Availability

```javascript theme={null}
async function getAvailability(userId, availabilityId) {
  const response = await fetch(
    `https://api.meetergo.com/v4/availability/${availabilityId}`,
    {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'x-meetergo-api-user-id': userId
      }
    }
  );

  return response.json();
}
```

### Update Availability

```javascript theme={null}
async function updateAvailability(userId, availabilityId, schedule) {
  const response = await fetch(
    `https://api.meetergo.com/v4/availability/${availabilityId}`,
    {
      method: 'PATCH',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
        'x-meetergo-api-user-id': userId
      },
      body: JSON.stringify({ schedule })
    }
  );

  return response.json();
}

// Usage
await updateAvailability(userId, availabilityId, {
  monday: { enabled: true, hours: [{ start: '09:00', end: '17:00' }] },
  tuesday: { enabled: true, hours: [{ start: '09:00', end: '17:00' }] },
  wednesday: { enabled: false, hours: [] },
  thursday: { enabled: false, hours: [] },
  friday: { enabled: false, hours: [] },
  saturday: { enabled: false, hours: [] },
  sunday: { enabled: false, hours: [] }
});
```

### Add Date Exception

```javascript theme={null}
async function addException(userId, startDate, endDate, isAvailable, name) {
  const response = await fetch(
    'https://api.meetergo.com/availability-exception/user',
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
        'x-meetergo-api-user-id': userId
      },
      body: JSON.stringify({
        startDate,
        endDate,
        isAvailable,
        name
      })
    }
  );

  return response.json();
}

// Block off vacation
await addException(userId, '2024-12-24', '2024-12-26', false, 'Christmas');

// Add extra availability
await addException(userId, '2024-12-28', '2024-12-28', true, 'Saturday coverage');
```

## Building Your Own UI

Example React implementation:

```jsx theme={null}
import { useState, useEffect } from 'react';

const DAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
const HOURS = Array.from({ length: 24 }, (_, i) => i);

function AvailabilityPickerCustom({ userId, availabilityId }) {
  const [schedule, setSchedule] = useState({});
  const [isDragging, setIsDragging] = useState(false);
  const [dragValue, setDragValue] = useState(true);

  useEffect(() => {
    loadAvailability();
  }, [userId, availabilityId]);

  async function loadAvailability() {
    const response = await fetch(`/api/availability/${availabilityId}`);
    const data = await response.json();

    // Convert to grid format
    const grid = {};
    DAYS.forEach(day => {
      grid[day] = {};
      HOURS.forEach(hour => {
        grid[day][hour] = false;
      });
    });

    data.schedule.forEach(daySchedule => {
      daySchedule.intervals.forEach(interval => {
        const startHour = parseInt(interval.from.split(':')[0]);
        const endHour = parseInt(interval.to.split(':')[0]);
        for (let h = startHour; h < endHour; h++) {
          grid[daySchedule.dayOfWeek][h] = true;
        }
      });
    });

    setSchedule(grid);
  }

  function handleMouseDown(day, hour) {
    setIsDragging(true);
    setDragValue(!schedule[day][hour]);
    toggleHour(day, hour);
  }

  function handleMouseEnter(day, hour) {
    if (isDragging) {
      setSchedule(prev => ({
        ...prev,
        [day]: { ...prev[day], [hour]: dragValue }
      }));
    }
  }

  function handleMouseUp() {
    setIsDragging(false);
    saveSchedule();
  }

  function toggleHour(day, hour) {
    setSchedule(prev => ({
      ...prev,
      [day]: { ...prev[day], [hour]: !prev[day][hour] }
    }));
  }

  async function saveSchedule() {
    // Convert grid back to intervals
    const newSchedule = DAYS.map(day => {
      const intervals = [];
      let start = null;

      HOURS.forEach(hour => {
        if (schedule[day][hour] && start === null) {
          start = hour;
        } else if (!schedule[day][hour] && start !== null) {
          intervals.push({
            from: `${start.toString().padStart(2, '0')}:00`,
            to: `${hour.toString().padStart(2, '0')}:00`
          });
          start = null;
        }
      });

      if (start !== null) {
        intervals.push({
          from: `${start.toString().padStart(2, '0')}:00`,
          to: '24:00'
        });
      }

      return { dayOfWeek: day, intervals };
    });

    await fetch(`/api/availability/${availabilityId}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ schedule: newSchedule })
    });
  }

  return (
    <div
      className="availability-grid"
      onMouseUp={handleMouseUp}
      onMouseLeave={handleMouseUp}
    >
      <div className="header-row">
        <div className="time-column"></div>
        {DAYS.map(day => (
          <div key={day} className="day-header">
            {day.slice(0, 3)}
          </div>
        ))}
      </div>

      {HOURS.filter(h => h >= 6 && h <= 22).map(hour => (
        <div key={hour} className="hour-row">
          <div className="time-column">
            {hour.toString().padStart(2, '0')}:00
          </div>
          {DAYS.map(day => (
            <div
              key={`${day}-${hour}`}
              className={`cell ${schedule[day]?.[hour] ? 'available' : ''}`}
              onMouseDown={() => handleMouseDown(day, hour)}
              onMouseEnter={() => handleMouseEnter(day, hour)}
            />
          ))}
        </div>
      ))}
    </div>
  );
}
```

### Styles

```css theme={null}
.availability-grid {
  display: flex;
  flex-direction: column;
  user-select: none;
}

.header-row, .hour-row {
  display: flex;
}

.time-column {
  width: 60px;
  font-size: 12px;
  color: #666;
}

.day-header {
  flex: 1;
  text-align: center;
  font-weight: 600;
  padding: 8px;
}

.cell {
  flex: 1;
  height: 24px;
  border: 1px solid #e5e7eb;
  cursor: pointer;
  transition: background-color 0.1s;
}

.cell:hover {
  background-color: #dbeafe;
}

.cell.available {
  background-color: #22c55e;
}
```

## Best Practices

<Check>
  **Show timezone** - Always display which timezone the schedule is in
</Check>

<Check>
  **Auto-save** - Save changes automatically with debouncing
</Check>

<Check>
  **Provide presets** - Quick buttons for common schedules
</Check>

<Check>
  **Copy functionality** - Let users copy one day to others
</Check>

<Check>
  **Mobile support** - Touch-friendly for mobile users
</Check>

## Next Steps

<CardGroup cols={2}>
  <Card title="Availability API" icon="clock" href="/developer-docs/core-concepts/availability">
    Full availability API documentation
  </Card>

  <Card title="Components Overview" icon="puzzle-piece" href="/developer-docs/components/overview">
    See all available components
  </Card>
</CardGroup>
