/**
* 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.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;
}