Skip to main content
The Artist Availability Calendar allows artists to set their available time slots for booking tattoo appointments. Artists can set up recurring weekly schedules with multiple time slots per day, making it easy to maintain a consistent availability pattern.

Data Structure

Form Schema

// types.ts
interface TimeSlot {
  startTime: Date;
  endTime: Date;
}

interface DaySchedule {
  timeSlots: TimeSlot[];
}

interface WeeklySchedule {
  weeklySlots: {
    [day: string]: DaySchedule; // e.g., "Monday", "Tuesday", etc.
  };
}

Firestore Collections

// collections/availability.ts
interface Availability {
  artistId: string;
  availabilityId: string; // Unique identifier for this schedule
  isActive: boolean; // Whether this schedule is currently active
  weeklySlots: {
    // Sunday, Monday, etc
    [dayOfWeek: string]: {
      timeSlots: {
        startTime: Date;
        endTime: Date;
      }[];
    };
  };
  effectiveFrom: number; // UTC timestamp in milliseconds
  effectiveUntil?: number; // Optional end date as UTC timestamp in milliseconds
  createdAt: number; // UTC timestamp in milliseconds
  updatedAt: number; // UTC timestamp in milliseconds
}

// For handling exceptions to the weekly schedule
interface AvailabilityException {
  artistId: string;
  isAvailable: boolean;
  // Single time slot for the exception
  startDateTime: number; // UTC timestamp in milliseconds
  endDateTime: number; // UTC timestamp in milliseconds
  reason?: string; // Optional reason for the exception
  createdAt: number; // UTC timestamp in milliseconds
  updatedAt: number; // UTC timestamp in milliseconds
}

Frontend Implementation

Components Structure

components/
  calendar/
    ├── AvailabilityModal/
    │   ├── index.tsx             # Main modal with calendar integration
    │   ├── ManageAvailabilityPanel.tsx # Side panel for managing schedules
    │   ├── types.ts              # Type definitions and form schemas
    │   ├── utils.ts              # Helper functions
    │   └── constants.ts          # Shared constants

Feature Overview

The availability management is implemented as a modal in the calendar page. The modal consists of two main sections:
  1. A calendar view showing the current availability schedule
  2. A side panel for managing weekly schedules

Key Features

  1. Weekly Schedule Management
    • Set multiple time slots per day
    • Mark entire days as unavailable
    • Easy add/remove time slots with 15-minute intervals
    • Default 9 AM to 5 PM schedule for each day
  2. Time Slot Management
    • Intuitive dropdown interface for time selection
    • Validation for time slot ordering (end time must be after start time)
    • Quick actions (delete slots, add new slots)
    • Consistent 15-minute interval options
    • Smart time constraints to prevent overlapping slots
    • Logical time slot creation:
      • First slot defaults to 9 AM - 5 PM
      • Subsequent slots automatically start 1 hour after the latest end time
      • One hour duration for new slots
  3. Form Validation
    • End time must be after start time for each slot
    • Real-time validation feedback

Backend Implementation

API Endpoints Structure

pages/api/
  availability/
    ├── weekly-schedule/
    │   ├── get.ts               # Get artist's weekly schedules
    │   ├── create.ts            # Create new weekly schedule
    │   ├── update.ts            # Update existing schedule
    │   └── delete.ts            # Delete a schedule
    └── exceptions/
        ├── get.ts               # Get availability exceptions
        ├── set.ts               # Set new exception
        └── delete.ts            # Remove exception

Firebase Functions

firebase/
  availability/
    ├── weekly-schedule.ts       # Weekly schedule CRUD operations
    ├── exceptions.ts            # Exception handling operations
    └── utils.ts                 # Helper functions and validation

Key Features

  1. Data Management
    • CRUD operations for weekly schedules
    • Exception handling for specific dates
    • Efficient querying of actual availability
    • Conflict resolution between schedules and exceptions
  2. Business Logic
    • Validation of time slots (no overlaps)
    • Schedule activation/deactivation
    • Exception priority handling
    • Time zone normalization

Calendar Integration

Displaying Availability with Background Events

The artist’s weekly schedule will be displayed as background events in the calendar using react-big-calendar’s background events feature. This provides a visual distinction between available time slots and actual bookings. We calculate the unavailibity based on the weekly reccuring slots and the exceptions. We transform those into background events.

Integration with BigCalendar

The calendar page will combine both booking events and availability background events:
// pages/calendar.tsx
export const FullCalendar = ({ events, initialDate }) => {
  const [currentDate, setCurrentDate] = useState(initialDate || new Date());

  // Calculate visible range (e.g., current week)
  const visibleRange = useMemo(() => {
    const start = startOfWeek(currentDate);
    const end = endOfWeek(currentDate);
    return { start, end };
  }, [currentDate]);

  // Get active weekly schedule
  const { data: weeklySchedule } = useActiveWeeklySchedule();

  // Convert weekly schedule to background events
  const availabilityEvents = useAvailabilityEvents(
    weeklySchedule,
    visibleRange.start,
    visibleRange.end
  );

  return (
    <BigCalendar
      events={events}
      backgroundEvents={availabilityEvents}
      // ... other props
    />
  );
};

Performance Considerations

  1. Background Event Generation
    • Generate background events only for the visible range
    • Cache generated events to prevent unnecessary recalculations
    • Update only when the schedule or visible range changes
  2. Rendering Optimization
    • Use React.memo for background event components
    • Implement virtual scrolling for large datasets
    • Lazy load events outside the visible range

Implementation Steps

  1. Phase 1: Weekly Schedule Editor
    • Implement WeeklyScheduleEditor components
    • Build time slot management UI
    • Add validation logic
    • Create basic CRUD operations
  2. Phase 2: Schedule Management
    • Implement schedule templates
    • Add exception handling
    • Build schedule activation system
    • Create schedule conflict detection
  3. Phase 3: Calendar Integration
    • Show actual availability in calendar
    • Implement exception UI
    • Add drag-and-drop support
    • Build bulk operations interface
  4. Phase 4: Optimization
    • Add real-time updates
    • Implement caching strategy
    • Optimize queries
    • Add batch operations

Technical Considerations

  1. Performance
    • Cache active weekly schedule
    • Lazy load exceptions
    • Optimize availability calculations
    • Use efficient date-time operations
  2. Scalability
    • Support multiple active schedules
    • Handle large numbers of exceptions
    • Efficient schedule querying
    • Batch updates for bulk changes
  3. User Experience
    • Immediate feedback on changes
    • Intuitive time slot management
    • Clear visual feedback
  4. Time Slot Management
    • Dynamic time constraints based on existing slots
    • Prevents overlapping slots by filtering available times
    • Smart defaults for new slots:
      • Uses business hours (9-5) for first slot
      • Calculates appropriate gaps between slots
      • Maintains consistent one-hour duration for new slots
    • Efficient time range validation using Date objects
    • Preserves existing slot structure while adding new slots

Dependencies

  • @tanstack/react-query - For data fetching and caching
  • date-fns - For date manipulation
  • @radix-ui/react-select - For time selection dropdowns
  • zod - For schema validation
  • @dnd-kit/core - For drag and drop functionality

Future Features

Advanced Scheduling Controls

  1. Minimum Notice Period
    • Allow artists to set a minimum advance notice required for bookings
    • Configurable per schedule or globally
    • Option to override for specific clients or booking types
    • Automatic enforcement during booking process
  2. Buffer Times
    • Set automatic buffer times between appointments
    • Configurable buffer duration before and after appointments
    • Different buffer times based on tattoo type/size
    • Smart buffer calculation based on booking history
  3. Booking Duration Templates
    • Preset duration templates based on tattoo size and complexity
    • Custom templates for common tattoo types
    • Integration with pricing calculator
    • Historical data analysis for accurate duration estimates
  4. Bulk Exception Management
    • Batch create/edit exceptions for holidays and time off
    • Import calendar events (iCal/Google Calendar)
    • Recurring exception patterns
    • Conflict resolution with existing bookings

Implementation Priority

  1. Minimum Notice Period - Essential for managing booking lead times
  2. Buffer Times - Critical for realistic scheduling
  3. Booking Duration Templates - Improves scheduling accuracy
  4. Bulk Exception Management - Enhances administrative efficiency
These features will be implemented after the core availability system is stable and tested.