/** * AvailabilityChecker - Компонент для проверки доступности гидов * Используется в формах бронирования для быстрой проверки */ class AvailabilityChecker { constructor(options = {}) { this.container = options.container || document.body; this.mode = options.mode || 'simple'; // 'simple', 'detailed', 'inline' this.onAvailabilityCheck = options.onAvailabilityCheck || null; this.showSuggestions = options.showSuggestions !== false; this.maxSuggestions = options.maxSuggestions || 3; this.guides = []; this.schedules = []; this.holidays = []; this.bookings = []; this.init(); } async init() { this.render(); await this.loadData(); this.bindEvents(); } render() { const modeClass = `availability-checker-${this.mode}`; this.container.innerHTML = `
${this.mode === 'detailed' ? `

Проверка доступности

Укажите дату и тип тура для проверки доступности гидов

` : ''}
${this.mode === 'detailed' ? `
` : ''}
${this.showSuggestions ? ` ` : ''}
`; this.injectStyles(); } getId() { if (!this._id) { this._id = 'availability-checker-' + Math.random().toString(36).substr(2, 9); } return this._id; } injectStyles() { if (document.getElementById('availability-checker-styles')) return; const styles = ` `; document.head.insertAdjacentHTML('beforeend', styles); } async loadData() { try { const [guidesRes, holidaysRes, bookingsRes] = await Promise.all([ fetch('/api/guides'), fetch('/api/holidays'), fetch('/api/bookings') ]); const guidesData = await guidesRes.json(); const holidaysData = await holidaysRes.json(); const bookingsData = await bookingsRes.json(); this.guides = Array.isArray(guidesData) ? guidesData : (guidesData.data || []); this.holidays = Array.isArray(holidaysData) ? holidaysData : (holidaysData.data || []); this.bookings = Array.isArray(bookingsData) ? bookingsData : (bookingsData.data || []); } catch (error) { console.error('Ошибка загрузки данных:', error); } } bindEvents() { const checkButton = this.container.querySelector(`#checkButton-${this.getId()}`); checkButton.addEventListener('click', () => this.checkAvailability()); } async checkAvailability() { const dateInput = this.container.querySelector(`#checkDate-${this.getId()}`); const date = dateInput.value; if (!date) { alert('Выберите дату'); return; } const availableGuides = this.getAvailableGuides(date); const resultsContainer = this.container.querySelector(`#checkerResults-${this.getId()}`); const resultsContent = resultsContainer.querySelector('.results-content'); if (availableGuides.length === 0) { resultsContent.innerHTML = `
Нет доступных гидов на выбранную дату
`; } else { resultsContent.innerHTML = `
Доступно ${availableGuides.length} гидов
${availableGuides.map(guide => `
${guide.name}
${guide.specialization || 'Универсальный'}
${guide.hourly_rate ? guide.hourly_rate + '₩/час' : 'По договоренности'}
`).join('')} `; } resultsContainer.style.display = 'block'; } getAvailableGuides(date) { return this.guides.filter(guide => { const holiday = this.holidays.find(h => h.guide_id === guide.id && h.holiday_date === date); if (holiday) return false; const booking = this.bookings.find(b => b.guide_id === guide.id && new Date(b.preferred_date).toISOString().split('T')[0] === date ); if (booking) return false; return true; }); } getId() { if (!this._id) { this._id = 'checker-' + Math.random().toString(36).substr(2, 9); } return this._id; } } if (typeof window !== 'undefined') { window.AvailabilityChecker = AvailabilityChecker; }