// Gallery uploader nativo (drag&drop + click) que ACUMULA archivos.
// No depende de Dropzone. Usado por create y edit.
document.addEventListener('DOMContentLoaded', function () {
var dzEl = document.getElementById('gallery_dropzone');
var hidden = document.getElementById('gallery_images_input');
var preview = document.getElementById('gallery_selected_preview');
var form = document.getElementById('{{ $formId }}');
if (!dzEl || !hidden || !preview) return;
var toDelInput = document.getElementById('gallery_images_to_delete'); // solo en edit
var existingWrap = document.getElementById('gallery_existing'); // solo en edit
var MAX = 12;
var MAX_SIZE = 4 * 1024 * 1024;
var ACCEPT = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
var files = [];
var toDelete = [];
var existingCount = existingWrap ? existingWrap.querySelectorAll('.gallery-existing-item').length : 0;
function slotsLeft() { return MAX - existingCount - files.length; }
function syncInput() {
var dt = new DataTransfer();
files.forEach(function (f) { if (f instanceof File) dt.items.add(f); });
hidden.files = dt.files;
}
function render() {
preview.innerHTML = '';
files.forEach(function (file, index) {
var url = URL.createObjectURL(file);
var col = document.createElement('div');
col.className = 'col-6 col-md-3';
col.innerHTML =
'
' +
'' +
'
' + file.name + '
' +
'' +
'
';
preview.appendChild(col);
});
}
function addFiles(fileList) {
var arr = Array.prototype.slice.call(fileList || []);
for (var i = 0; i < arr.length; i++) {
var f = arr[i];
if (ACCEPT.indexOf(f.type) === -1) continue;
if (f.size > MAX_SIZE) { alert('{{ __('La imagen supera 4MB:') }} ' + f.name); continue; }
if (slotsLeft() <= 0) { alert('{{ __('Máximo 12 imágenes en la galería.') }}'); break; }
var dup = files.some(function (x) { return x.name === f.name && x.size === f.size && x.lastModified === f.lastModified; });
if (!dup) files.push(f);
}
syncInput();
render();
}
// Click → abrir selector
dzEl.addEventListener('click', function () { hidden.click(); });
hidden.addEventListener('change', function () { addFiles(hidden.files); });
// Drag & drop
['dragenter', 'dragover'].forEach(function (ev) {
dzEl.addEventListener(ev, function (e) { e.preventDefault(); e.stopPropagation(); dzEl.classList.add('dragover'); });
});
['dragleave', 'dragend'].forEach(function (ev) {
dzEl.addEventListener(ev, function (e) { e.preventDefault(); e.stopPropagation(); dzEl.classList.remove('dragover'); });
});
dzEl.addEventListener('drop', function (e) {
e.preventDefault(); e.stopPropagation(); dzEl.classList.remove('dragover');
if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length) addFiles(e.dataTransfer.files);
});
// Quitar imagen nueva (preview)
preview.addEventListener('click', function (e) {
var b = e.target.closest('[data-remove-index]');
if (!b) return;
var i = Number(b.getAttribute('data-remove-index'));
if (Number.isNaN(i)) return;
files.splice(i, 1);
syncInput();
render();
});
// Quitar imagen existente (solo edit)
if (existingWrap) {
existingWrap.addEventListener('click', function (e) {
var b = e.target.closest('.remove-existing-gallery-image');
if (!b) return;
var id = b.getAttribute('data-image-id');
if (id && toDelete.indexOf(id) === -1) toDelete.push(id);
if (toDelInput) toDelInput.value = JSON.stringify(toDelete);
var item = b.closest('.gallery-existing-item');
if (item) item.remove();
existingCount = Math.max(0, existingCount - 1);
});
}
if (form) form.addEventListener('submit', syncInput);
});