class WardrobeConfigurator {
constructor(config) {
this.config = config;
this.selectedOptions = {
facadeColor: config.facadeColor.default,
bodyColor: config.bodyColor.default,
doorSystem: config.doorSystem.default,
interior: {},
additionalOptions: {},
services: config.services.default
};
this.quantities = {};
this.init();
}
init() {
this.renderAllOptions();
this.setupEventListeners();
this.calculatePrice();
}
renderAllOptions() {
this.renderOptions('facadeColor', 'facade-color-options');
this.renderOptions('bodyColor', 'body-color-options');
this.renderOptions('doorSystem', 'door-system-options');
this.renderOptions('interior', 'interior-options', true);
this.renderOptions('additionalOptions', 'additional-options');
this.renderOptions('services', 'services-options');
}
renderOptions(configKey, containerId, showQuantity = false) {
const config = this.config[configKey];
const container = document.getElementById(containerId);
if (!container) {
console.error(Container #${containerId} not found);
return;
}
container.innerHTML = '';
config.options.forEach(option => {
const optionElement = document.createElement('div');
optionElement.className = option-item ${option.inStock ? '' : 'out-of-stock'};
if (config.type === 'radio') {
const isChecked = option.id === this.selectedOptions[configKey];
optionElement.innerHTML = `
${option.name}
${option.material ? (${option.material}) : ''}
${option.price > 0 ? +${this.formatPrice(option.price)} руб. : 'Включено в стоимость'}
${option.description ?
${option.description}
: ''}
`;
} else {
const isChecked = this.selectedOptions[configKey]?.[option.id] false;
if (isChecked && showQuantity) {
this.quantities[option.id] = option.quantity 1;
}
let quantityControls = '';
if (showQuantity && option.addable) {
quantityControls = `
-
${this.quantities[option.id] 1}
+
`;
}
optionElement.innerHTML = `
${option.name}
${option.price > 0 ? `+${this.formatPrice(option.price)} руб.` : 'Включено в стоимость'}
${option.description ? `
${option.description}
` : ''}
${quantityControls}
`;
}
container.appendChild(optionElement);
});
this.setupOptionListeners(configKey);
}
setupOptionListeners(configKey) {
const inputs = document.querySelectorAll(`input[name="${configKey}"]`);
inputs.forEach(input => {
input.addEventListener('change', (e) => {
if (this.config[configKey].type === 'radio') {
this.selectedOptions[configKey] = e.target.value;
} else {
// Инициализируем объект, если его нет
if (!this.selectedOptions[configKey]) {
this.selectedOptions[configKey] = {};
}
if (e.target.checked) {
this.selectedOptions[configKey][e.target.value] = true;
} else {
delete this.selectedOptions[configKey][e.target.value];
}
}
this.calculatePrice();
});
});
}
setupEventListeners() {
// Слайдеры размеров
['width', 'height', 'depth'].forEach(dimension => {
const slider = document.getElementById(`${dimension}-slider`);
const valueSpan = document.getElementById(`${dimension}-value`);
if (!slider !valueSpan) {
console.warn(Element for dimension ${dimension} not found);
return;
}
slider.addEventListener('input', (e) => {
const value = parseInt(e.target.value);
valueSpan.textContent = value;
this.config.dimensions[dimension].value = value;
this.calculatePrice();
});
});
// Кнопка добавления в корзину
const addToCartBtn = document.getElementById('add-to-cart');
if (addToCartBtn) {
addToCartBtn.addEventListener('click', () => {
this.addToCart();
});
}
}
increaseQuantity(optionId, max) {
if (!this.quantities[optionId]) {
this.quantities[optionId] = 1;
}
if (this.quantities[optionId] < max) {
this.quantities[optionId]++;
this.updateQuantityDisplay(optionId);
this.calculatePrice();
}
}
decreaseQuantity(optionId) {
if (this.quantities[optionId] && this.quantities[optionId] > 1) {
this.quantities[optionId]--;
this.updateQuantityDisplay(optionId);
this.calculatePrice();
}
}
updateQuantityDisplay(optionId) {
const quantityElement = document.getElementById(quantity-${optionId});
if (quantityElement) {
quantityElement.textContent = this.quantities[optionId];
}
}
calculatePrice() {
let total = this.config.basePrice;
// Расчет цены за размеры
total += this.calculateSizePrice('width');
total += this.calculateSizePrice('height');
total += this.calculateSizePrice('depth');
// Расчет цены за выбранные опции
total += this.calculateOptionsPrice();
this.config.currentPrice = total;
this.updatePriceDisplay(total);
return total;
}
calculateSizePrice(dimension) {
const dim = this.config.dimensions[dimension];
const baseSize = dim.min;
const currentSize = dim.value;
const steps = (currentSize - baseSize) / dim.step;
return steps * dim.pricePerStep;
}
calculateOptionsPrice() {
let optionsPrice = 0;
// Обработка радио-кнопок
['facadeColor', 'bodyColor', 'doorSystem', 'services'].forEach(configKey => {
const selectedId = this.selectedOptions[configKey];
const option = this.config[configKey].options.find(opt => opt.id === selectedId);
if (option) {
optionsPrice += option.price 0;
}
});
// Обработка чекбоксов
['interior', 'additionalOptions'].forEach(configKey => {
const selectedOptions = this.selectedOptions[configKey];
if (selectedOptions) {
Object.keys(selectedOptions).forEach(optionId => {
const option = this.config[configKey].options.find(opt => opt.id === optionId);
if (option) {
if (option.addable && this.quantities[optionId]) {
// Для опций с количеством
const baseQty = option.quantity 1;
const extraQty = this.quantities[optionId] - baseQty;
optionsPrice += option.price + (extraQty > 0 ? extraQty * option.addPrice : 0);
} else {
// Для обычных опций
optionsPrice += option.price 0;
}
}
});
}
});
return optionsPrice;
}
updatePriceDisplay(price) {
const priceElement = document.getElementById('total-price');
if (priceElement) {
priceElement.textContent = this.formatPrice(price);
}
}
formatPrice(price) {
return new Intl.NumberFormat('ru-RU').format(price);
}
addToCart() {
const cartItem = {
productId: this.config.productId,
productName: this.config.productName,
price: this.config.currentPrice,
dimensions: { ...this.config.dimensions },
selectedOptions: { ...this.selectedOptions },
quantities: { ...this.quantities },
timestamp: Date.now()
};
console.log('Добавлено в корзину:', cartItem);
alert(`Товар "${this.config.productName}" добавлен в корзину!\nЦена: ${this.formatPrice(this.config.currentPrice)} руб.`);
// Здесь можно добавить логику для реального сохранения в корзину
this.saveToCart(cartItem);
}
saveToCart(item) {
// Сохранение в localStorage
let cart = JSON.parse(localStorage.getItem('wardrobe_cart') '[]');
cart.push(item);
localStorage.setItem('wardrobe_cart', JSON.stringify(cart));
}
}
// Инициализация конфигуратора после загрузки DOM
document.addEventListener('DOMContentLoaded', () => {
window.configurator = new WardrobeConfigurator(productConfig);
});