Files
PIbd-22_Ulybin_A.A._Interne…/js/view.js
qkrlnt 9c80373c59 lab_4
2025-05-20 16:04:25 +04:00

125 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// js/view.js
export default {
renderProductList(products, onEdit, onDelete) {
const list = document.getElementById('productsList');
list.innerHTML = '';
products.forEach(product => {
const col = document.createElement('div');
col.className = 'col';
// Если image не начинается с "data:" — выводим как есть (старые товары), иначе как base64
const imgSrc = product.image?.startsWith('data:') ? product.image : (product.image || 'images/no-image.png');
col.innerHTML = `
<div class="card h-100">
<img src="${imgSrc}" class="card-img-top" alt="${product.name}" style="width: 100%; height: 300px; object-fit: cover;">
<div class="card-body">
<h5 class="card-title">${product.name}</h5>
<p class="card-text">${product.price} руб</p>
<p class="card-text">
<small class="text-muted">Категория: ${product.category?.name || '-'}</small><br>
<small class="text-muted">Бренд: ${product.brand?.name || '-'}</small>
</p>
<button class="btn btn-primary btn-sm me-2 edit-btn"><i class="bi bi-pencil"></i> Редактировать</button>
<button class="btn btn-danger btn-sm delete-btn"><i class="bi bi-trash"></i> Удалить</button>
</div>
</div>
`;
// Навесить обработчики
col.querySelector('.edit-btn').onclick = () => onEdit(product.id);
col.querySelector('.delete-btn').onclick = () => onDelete(product.id);
list.appendChild(col);
});
},
showProductModal({ product = {}, categories = [], brands = [] }, onSubmit) {
const modalContent = document.getElementById('productModalContent');
modalContent.innerHTML = `
<div class="modal-header">
<h5 class="modal-title">${product.id ? 'Редактировать' : 'Добавить'} товар</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="productForm">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Название товара</label>
<input type="text" class="form-control" name="name" value="${product.name || ''}" required>
</div>
<div class="mb-3">
<label class="form-label">Цена (руб)</label>
<input type="number" class="form-control" name="price" value="${product.price || ''}" required>
</div>
<div class="mb-3">
<label class="form-label">Изображение</label>
<input type="file" class="form-control" name="image" accept="image/*" ${product.id ? "" : "required"}>
<img id="previewImage" src="${product.image || ''}" style="max-width:100%;margin-top:10px;${product.image ? '' : 'display:none;'}"/>
</div>
<div class="mb-3">
<label class="form-label">Категория</label>
<select class="form-select" name="categoryId" required>
<option value="">Выберите категорию</option>
${categories.map(cat => `
<option value="${cat.id}" ${product.categoryId == cat.id ? 'selected' : ''}>${cat.name}</option>
`).join('')}
</select>
</div>
<div class="mb-3">
<label class="form-label">Бренд</label>
<select class="form-select" name="brandId" required>
<option value="">Выберите бренд</option>
${brands.map(br => `
<option value="${br.id}" ${product.brandId == br.id ? 'selected' : ''}>${br.name}</option>
`).join('')}
</select>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">${product.id ? 'Сохранить' : 'Добавить'}</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
</div>
</form>
`;
// Показываем модалку через Bootstrap JS
const modal = new bootstrap.Modal(document.getElementById('productModal'));
modal.show();
// Предпросмотр выбранной картинки
const fileInput = modalContent.querySelector('input[type="file"]');
const preview = modalContent.querySelector('#previewImage');
fileInput.onchange = () => {
const file = fileInput.files[0];
if (file) {
const reader = new FileReader();
reader.onload = e => {
preview.src = e.target.result;
preview.style.display = '';
};
reader.readAsDataURL(file);
}
};
// Обработка формы (с поддержкой base64-картинки)
document.getElementById('productForm').onsubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const obj = Object.fromEntries(formData.entries());
obj.price = +obj.price;
obj.categoryId = +obj.categoryId;
obj.brandId = +obj.brandId;
if (fileInput.files.length) {
const file = fileInput.files[0];
const reader = new FileReader();
reader.onload = function(event) {
obj.image = event.target.result; // base64
onSubmit(obj, modal);
};
reader.readAsDataURL(file);
} else {
obj.image = product.image || '';
onSubmit(obj, modal);
}
};
}
};