Admin: serie-detail, billedhåndtering, dark mode fix, source_url kolonne + verify
- Serie-detail side: sæt under serie + enkelt/bulk opret - Billedhentning: URL→lokal download med source_url til re-sync - Advarselsbadge (⚠) på kort med eksterne URLs (ingen streaming) - Sync/Verify endpoints + knapper i admin UI - Brugerstyring: opret/slet (self-delete beskyttet) - Dark mode flash fix: render-blokerende script i <head> - Persistent volume til billeder (pokedexter_images)
This commit is contained in:
@@ -31,6 +31,15 @@
|
||||
</form>
|
||||
<div id="cards-import-result" style="margin-top:8px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="flex:1;min-width:280px;">
|
||||
<h3>Synkronisér billeder</h3>
|
||||
<p style="font-size:0.85rem;color:var(--text-muted);margin:8px 0;">
|
||||
Hent alle eksterne billeder for {{ set.code }} og gem lokalt.
|
||||
</p>
|
||||
<button class="btn btn-primary" onclick="syncImages('{{ set.code }}')">📥 Synkronisér</button>
|
||||
<div id="sync-result" style="margin-top:8px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Kort i {{ set.code }}</h2>
|
||||
@@ -45,7 +54,11 @@
|
||||
<td><a href="/card/{{ set.code }}/{{ card.number }}" style="color:var(--text);">{{ card.name }}</a></td>
|
||||
<td><span class="tag">{{ card.full_code }}</span></td>
|
||||
<td>
|
||||
{% if card.image_url %}
|
||||
{% if card.image_path and (card.image_path.startswith('http://') or card.image_path.startswith('https://')) %}
|
||||
<span class="warning-badge" title="Billede ikke synkroniseret — eksternt URL: {{ card.image_path }}">⚠️</span>
|
||||
<span style="color:var(--accent);font-size:0.75rem;cursor:help;"
|
||||
onclick="alert('{{ card.image_path }}')">eksternt</span>
|
||||
{% elif card.image_url %}
|
||||
<a href="{{ card.image_url }}" target="_blank">
|
||||
<img src="{{ card.image_url }}" alt="{{ card.name }}"
|
||||
style="height:40px;border-radius:4px;">
|
||||
@@ -142,5 +155,25 @@ async function uploadImage(e, cardId) {
|
||||
alert(data.detail || 'Fejl ved upload');
|
||||
}
|
||||
}
|
||||
|
||||
async function syncImages(setCode) {
|
||||
const btn = event.target;
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Synkroniserer...';
|
||||
const res = await fetch('/api/admin/sets/' + setCode + '/sync-images', {method: 'POST'});
|
||||
const data = await res.json();
|
||||
const el = document.getElementById('sync-result');
|
||||
if (data.ok) {
|
||||
let msg = '\u2713 ' + data.downloaded + ' billed(er) downloadet';
|
||||
if (data.skipped > 0) msg += ', ' + data.skipped + ' sprunget over (allerede lokale)';
|
||||
if (data.errors.length) msg += '<br><span style="color:var(--accent);">' + data.errors.join('<br>') + '</span>';
|
||||
el.innerHTML = '<p style="color:green;">' + msg + '</p>';
|
||||
setTimeout(() => location.reload(), 1500);
|
||||
} else {
|
||||
el.innerHTML = '<p style="color:var(--accent);">Fejl: ' + (data.detail || 'Ukendt') + '</p>';
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.textContent = '\ud83d\udce5 Synkronis\u00e9r';
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user