/* hd-commerce — Wiederverwendbarer Medien-Picker (Admin).
API: window.HDCMedia.pick({ multiple, onPick(url|urls) }) öffnet ein Modal mit
Bibliothek (/api/admin/media), Inline-Upload (WebP) und Auswahl. */
(function () {
var overlay = null, listEl = null, state = { multiple: false, onPick: null, selected: [] };
function el(tag, cls, html) { var e = document.createElement(tag); if (cls) e.className = cls; if (html != null) e.innerHTML = html; return e; }
function build() {
overlay = el('div', 'mp-overlay');
overlay.innerHTML =
'
' +
'
' +
'
Medien-Bibliothek' +
'
' +
'' +
'' +
'
' +
'
' +
'
Bilder hierher ziehen oder „Hochladen" — JPG/PNG werden automatisch zu WebP.
' +
'
' +
'
' +
'' +
'
';
document.body.appendChild(overlay);
listEl = overlay.querySelector('[data-grid]');
overlay.querySelector('.mp-close').addEventListener('click', close);
overlay.querySelector('.mp-cancel').addEventListener('click', close);
overlay.addEventListener('click', function (e) { if (e.target === overlay) close(); });
overlay.querySelector('.mp-confirm').addEventListener('click', confirmSel);
var fileInput = overlay.querySelector('.mp-upbtn input');
fileInput.addEventListener('change', function () { upload(fileInput.files); fileInput.value = ''; });
var drop = overlay.querySelector('[data-drop]');
['dragover', 'dragenter'].forEach(function (ev) { drop.addEventListener(ev, function (e) { e.preventDefault(); drop.classList.add('over'); }); });
['dragleave', 'drop'].forEach(function (ev) { drop.addEventListener(ev, function (e) { e.preventDefault(); drop.classList.remove('over'); }); });
drop.addEventListener('drop', function (e) { if (e.dataTransfer && e.dataTransfer.files) upload(e.dataTransfer.files); });
document.addEventListener('keydown', function (e) { if (overlay && overlay.classList.contains('open') && e.key === 'Escape') close(); });
}
function msg(text, kind) {
var m = overlay.querySelector('[data-msg]');
m.textContent = text || '';
m.className = 'mp-msg' + (kind ? ' ' + kind : '') + (text ? ' show' : '');
}
function load() {
listEl.innerHTML = 'Lädt …
';
fetch('/api/admin/media', { headers: { 'Accept': 'application/json' } })
.then(function (r) { return r.json(); })
.then(function (d) { renderGrid((d && d.media) || []); })
.catch(function () { listEl.innerHTML = 'Konnte Medien nicht laden.
'; });
}
function renderGrid(media) {
if (!media.length) { listEl.innerHTML = 'Noch keine Medien. Lade oben welche hoch.
'; return; }
listEl.innerHTML = '';
media.forEach(function (m) {
var card = el('div', 'mp-card');
if (state.selected.indexOf(m.url) > -1) card.classList.add('sel');
card.innerHTML =
'' +
'' + (m.filename || '') + '' +
'' + Math.round((m.size || 0) / 1024) + ' KB' + (m.width ? ' · ' + m.width + '×' + m.height : '') + '
' +
'' +
'' +
'' +
'
';
card.querySelector('.mp-thumb').addEventListener('click', function () { toggle(m.url, card); });
card.querySelector('[data-copy]').addEventListener('click', function (e) {
e.stopPropagation();
try { navigator.clipboard.writeText(location.origin + m.url); msg('URL kopiert.', 'ok'); } catch (x) {}
});
card.querySelector('[data-del]').addEventListener('click', function (e) {
e.stopPropagation();
if (!confirm('Dieses Medium löschen?')) return;
fetch('/api/admin/media?id=' + m.id, { method: 'DELETE' }).then(function (r) { return r.json(); })
.then(function (d) { if (d.ok) { state.selected = state.selected.filter(function (u) { return u !== m.url; }); load(); } else msg(d.error || 'Löschen fehlgeschlagen.', 'err'); });
});
listEl.appendChild(card);
});
updateSelCount();
}
function toggle(url, card) {
if (state.multiple) {
var i = state.selected.indexOf(url);
if (i > -1) { state.selected.splice(i, 1); card.classList.remove('sel'); }
else { state.selected.push(url); card.classList.add('sel'); }
} else {
state.selected = [url];
Array.prototype.forEach.call(listEl.querySelectorAll('.mp-card'), function (c) { c.classList.remove('sel'); });
card.classList.add('sel');
}
updateSelCount();
}
function updateSelCount() {
var s = overlay.querySelector('[data-sel]');
s.textContent = state.selected.length ? state.selected.length + ' ausgewählt' : '';
}
function upload(files) {
if (!files || !files.length) return;
var fd = new FormData();
Array.prototype.forEach.call(files, function (f) { fd.append('files', f); });
msg('Lädt ' + files.length + ' Datei(en) hoch …');
fetch('/api/upload', { method: 'POST', body: fd }).then(function (r) { return r.json(); })
.then(function (d) {
if (d && d.results) {
var conv = d.results.filter(function (r) { return r.converted; }).length;
msg('Hochgeladen' + (conv ? ' (' + conv + '× zu WebP konvertiert)' : '') + '.', 'ok');
// Neu hochgeladene direkt vorauswählen
d.results.forEach(function (r) { if (r.ok && r.url && state.selected.indexOf(r.url) < 0) { if (state.multiple) state.selected.push(r.url); else state.selected = [r.url]; } });
load();
} else { msg((d && d.error) || 'Upload fehlgeschlagen.', 'err'); }
})
.catch(function () { msg('Upload fehlgeschlagen.', 'err'); });
}
function confirmSel() {
if (!state.selected.length) { close(); return; }
var cb = state.onPick;
var sel = state.selected.slice();
close();
if (cb) cb(state.multiple ? sel : sel[0]);
}
function open() { if (!overlay) build(); overlay.classList.add('open'); msg(''); load(); }
function close() { if (overlay) overlay.classList.remove('open'); }
window.HDCMedia = {
pick: function (opts) {
opts = opts || {};
state.multiple = !!opts.multiple;
state.onPick = opts.onPick || null;
state.selected = [];
open();
}
};
})();