Fix: eagerload series.sets i admin og API (MissingGreenlet i async mode)

This commit is contained in:
2026-07-01 22:15:14 +02:00
parent c0952a3bd3
commit 8361066f2f
20 changed files with 1075 additions and 554 deletions
+38 -22
View File
@@ -2,49 +2,65 @@
{% block title %}Søg{% endblock %}
{% block content %}
<h1>🔍 Søg efter kort</h1>
<p style="color:var(--text-muted);margin-bottom:16px;">Søg på kortkode (f.eks. <strong>CRI-068</strong>) eller kortnavn.</p>
<p style="color:var(--text-muted);margin-bottom:16px;">
Søg på kode (f.eks. <strong>CRI-068</strong>) eller kortnavn (f.eks. <strong>Pikachu</strong>)
</p>
<div class="search-box">
<input type="text" id="search-input" placeholder="CRI-068 eller kortnavn..." autofocus>
<button class="btn btn-primary" onclick="doSearch()">Søg</button>
<input type="text" id="search-input" placeholder="Søg på kortkode eller navn..."
onkeydown="if(event.key==='Enter') search()">
<button class="btn btn-primary" onclick="search()">Søg</button>
</div>
<div id="search-results"></div>
<div id="search-results">
<p style="color:var(--text-muted);text-align:center;padding:40px 0;">
Indtast en søgning for at finde kort.
</p>
</div>
<script>
const input = document.getElementById('search-input');
input.addEventListener('keydown', (e) => { if (e.key === 'Enter') doSearch(); });
async function search() {
const q = document.getElementById('search-input').value.trim();
const el = document.getElementById('search-results');
async function doSearch() {
const q = input.value.trim();
const container = document.getElementById('search-results');
if (!q) { container.innerHTML = ''; return; }
if (!q) {
el.innerHTML = '<p style="color:var(--text-muted);text-align:center;padding:40px 0;">Indtast en søgning.</p>';
return;
}
container.innerHTML = '<p style="color:var(--text-muted);">Søger...</p>';
el.innerHTML = '<p style="color:var(--text-muted);text-align:center;padding:20px 0;">Søger...</p>';
try {
const res = await fetch('/api/search?q=' + encodeURIComponent(q));
const data = await res.json();
container.innerHTML = '';
if (data.length === 0) {
container.innerHTML = '<div class="card"><p style="color:var(--text-muted);">Ingen kort fundet for "<strong>' + q + '</strong>"</p></div>';
el.innerHTML = '<p style="color:var(--text-muted);text-align:center;padding:40px 0;">Ingen resultater.</p>';
return;
}
let html = '<div class="card" style="padding:0;"><div style="padding:10px 14px;border-bottom:1px solid var(--border);font-size:0.85rem;color:var(--text-muted);">' + data.length + ' resultat(er)</div>';
let html = '<p style="margin-bottom:12px;">' + data.length + ' resultat(er)</p>';
data.forEach(c => {
const imgHtml = c.image_url
? '<img src="' + c.image_url + '" alt="' + c.name + '" style="height:50px;border-radius:4px;">'
: '<span style="color:var(--text-muted);font-size:0.8rem;">Intet billede</span>';
html += '<div class="result-row">' +
'<div><span class="tag">' + c.full_code + '</span> <strong>' + c.name + '</strong>' +
' <span style="color:var(--text-muted);font-size:0.85rem;">' + c.set_name + '</span></div>' +
'<div style="font-size:0.85rem;color:var(--text-muted);">' + c.type + ' · ' + c.rarity + '</div>' +
'</div>';
'<div>' +
'<strong>' + c.full_code + '</strong> ' + c.name +
'<br><span style="color:var(--text-muted);font-size:0.8rem;">' +
c.serie_name + ' &middot; ' + c.set_name +
'</span>' +
'</div>' +
'<div style="display:flex;align-items:center;gap:10px;">' +
imgHtml +
'<a href="/card/' + c.set_code + '/' + c.full_code.split('-')[1] + '" class="btn btn-outline btn-sm">Se kort</a>' +
'</div>' +
'</div>';
});
html += '</div>';
container.innerHTML = html;
el.innerHTML = html;
} catch(e) {
container.innerHTML = '<p style="color:var(--accent);">Fejl: kunne ikke søge</p>';
el.innerHTML = '<p style="color:var(--accent);text-align:center;">Fejl ved søgning.</p>';
}
}
</script>
{% endblock %}
{% endblock %}