mirror of
https://github.com/superschnups/Emy.git
synced 2026-06-22 03:13:10 +00:00
Auto-backup: 2026-04-12 00:36
This commit is contained in:
parent
ddbe56763d
commit
9899b947a8
2 changed files with 89 additions and 7 deletions
90
admin.html
90
admin.html
|
|
@ -232,10 +232,28 @@ tailwind.config = {
|
||||||
|
|
||||||
<!-- Kategorie-Übersicht -->
|
<!-- Kategorie-Übersicht -->
|
||||||
<div class="bg-surface-container-low rounded-xl p-6 mb-8">
|
<div class="bg-surface-container-low rounded-xl p-6 mb-8">
|
||||||
<h3 class="text-lg font-extrabold font-lexend mb-4">Fotos nach Kategorie</h3>
|
<div class="flex items-center justify-between mb-4">
|
||||||
|
<h3 class="text-lg font-extrabold font-lexend">Fotos nach Kategorie</h3>
|
||||||
|
<button type="button" id="overviewAddCatBtn"
|
||||||
|
class="flex items-center gap-1 text-xs font-bold text-primary hover:bg-pink-50 px-3 py-1.5 rounded-full transition-all">
|
||||||
|
<span class="material-symbols-outlined text-sm">add</span> Neue Kategorie
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="space-y-4" id="catOverviewList">
|
<div class="space-y-4" id="catOverviewList">
|
||||||
<p class="text-sm text-on-surface-variant">Wird geladen…</p>
|
<p class="text-sm text-on-surface-variant">Wird geladen…</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="overviewAddCatForm" class="hidden mt-4 flex gap-2">
|
||||||
|
<input id="overviewNewCatInput" type="text" placeholder="Kategoriename…"
|
||||||
|
class="flex-1 bg-surface-container rounded-DEFAULT px-3 py-2 text-on-surface placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary/30 text-sm"/>
|
||||||
|
<button type="button" id="overviewSaveCatBtn"
|
||||||
|
class="px-4 py-2 rounded-xl font-bold text-sm bg-primary text-on-primary active:scale-95 transition-all">
|
||||||
|
Hinzufügen
|
||||||
|
</button>
|
||||||
|
<button type="button" id="overviewCancelCatBtn"
|
||||||
|
class="px-3 py-2 rounded-xl font-bold text-sm bg-surface-container text-on-surface-variant">
|
||||||
|
✕
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -659,6 +677,49 @@ tailwind.config = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ─── Schnell-Kategorie aus Übersicht ─────────────────────
|
||||||
|
document.getElementById('overviewAddCatBtn').addEventListener('click', function () {
|
||||||
|
document.getElementById('overviewAddCatForm').classList.remove('hidden');
|
||||||
|
document.getElementById('overviewNewCatInput').focus();
|
||||||
|
});
|
||||||
|
document.getElementById('overviewCancelCatBtn').addEventListener('click', function () {
|
||||||
|
document.getElementById('overviewAddCatForm').classList.add('hidden');
|
||||||
|
document.getElementById('overviewNewCatInput').value = '';
|
||||||
|
});
|
||||||
|
async function overviewSaveCat() {
|
||||||
|
const input = document.getElementById('overviewNewCatInput');
|
||||||
|
const name = input.value.trim();
|
||||||
|
if (!name) return;
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/categories', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ name })
|
||||||
|
});
|
||||||
|
const data = await r.json();
|
||||||
|
if (r.ok) {
|
||||||
|
allCategories = data.categories;
|
||||||
|
input.value = '';
|
||||||
|
document.getElementById('overviewAddCatForm').classList.add('hidden');
|
||||||
|
renderKatButtons();
|
||||||
|
renderFilterButtons();
|
||||||
|
renderEditKatOptions();
|
||||||
|
renderCatManage();
|
||||||
|
loadStats();
|
||||||
|
showToast('✓ Kategorie "' + name + '" hinzugefügt');
|
||||||
|
} else {
|
||||||
|
showToast(data.error || 'Fehler');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showToast('Verbindungsfehler');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.getElementById('overviewSaveCatBtn').addEventListener('click', overviewSaveCat);
|
||||||
|
document.getElementById('overviewNewCatInput').addEventListener('keydown', function (e) {
|
||||||
|
if (e.key === 'Enter') overviewSaveCat();
|
||||||
|
if (e.key === 'Escape') document.getElementById('overviewCancelCatBtn').click();
|
||||||
|
});
|
||||||
|
|
||||||
// ─── Drag & Drop ──────────────────────────────────────────
|
// ─── Drag & Drop ──────────────────────────────────────────
|
||||||
const dropZone = document.getElementById('dropZone');
|
const dropZone = document.getElementById('dropZone');
|
||||||
const fileInput = document.getElementById('fileInput');
|
const fileInput = document.getElementById('fileInput');
|
||||||
|
|
@ -878,17 +939,32 @@ tailwind.config = {
|
||||||
const photos = data.photos || [];
|
const photos = data.photos || [];
|
||||||
document.getElementById('statPhotos').textContent = photos.length;
|
document.getElementById('statPhotos').textContent = photos.length;
|
||||||
|
|
||||||
const counts = { Training: 0, 'Wettkämpfe': 0, 'Gürtelprüfungen': 0 };
|
const counts = {};
|
||||||
let lastDate = null;
|
let lastDate = null;
|
||||||
photos.forEach(p => {
|
photos.forEach(p => {
|
||||||
if (counts[p.kategorie] !== undefined) counts[p.kategorie]++;
|
counts[p.kategorie] = (counts[p.kategorie] || 0) + 1;
|
||||||
const ts = parseInt(p.id);
|
const ts = parseInt(p.id);
|
||||||
if (!isNaN(ts) && (!lastDate || ts > lastDate)) lastDate = ts;
|
if (!isNaN(ts) && (!lastDate || ts > lastDate)) lastDate = ts;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('catTraining').textContent = counts['Training'] + ' Fotos';
|
const icons = ['fitness_center', 'emoji_events', 'workspace_premium', 'sports_martial_arts', 'star', 'label'];
|
||||||
document.getElementById('catWettkampf').textContent = counts['Wettkämpfe'] + ' Fotos';
|
const colors = ['bg-pink-100 text-primary', 'bg-purple-100 text-secondary', 'bg-amber-100 text-amber-600', 'bg-blue-100 text-blue-600', 'bg-green-100 text-green-600', 'bg-surface-container text-on-surface-variant'];
|
||||||
document.getElementById('catGuertel').textContent = counts['Gürtelprüfungen'] + ' Fotos';
|
const list = document.getElementById('catOverviewList');
|
||||||
|
list.innerHTML = '';
|
||||||
|
allCategories.forEach(function (kat, i) {
|
||||||
|
const colorClass = colors[i % colors.length];
|
||||||
|
const icon = icons[i % icons.length];
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'flex items-center justify-between';
|
||||||
|
row.innerHTML =
|
||||||
|
'<div class="flex items-center gap-3">' +
|
||||||
|
'<div class="w-8 h-8 ' + colorClass + ' rounded flex items-center justify-center">' +
|
||||||
|
'<span class="material-symbols-outlined text-sm">' + icon + '</span></div>' +
|
||||||
|
'<span class="font-bold text-sm">' + escHtml(kat) + '</span>' +
|
||||||
|
'</div>' +
|
||||||
|
'<span class="text-sm font-black">' + (counts[kat] || 0) + ' Fotos</span>';
|
||||||
|
list.appendChild(row);
|
||||||
|
});
|
||||||
|
|
||||||
if (lastDate) {
|
if (lastDate) {
|
||||||
const d = new Date(lastDate);
|
const d = new Date(lastDate);
|
||||||
|
|
@ -1047,7 +1123,7 @@ tailwind.config = {
|
||||||
});
|
});
|
||||||
|
|
||||||
// ─── Init ─────────────────────────────────────────────────
|
// ─── Init ─────────────────────────────────────────────────
|
||||||
loadStats();
|
loadCategories().then(function () { loadStats(); });
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
6
hp_emy_restartAdmin.sh
Executable file
6
hp_emy_restartAdmin.sh
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#/bin/bash
|
||||||
|
|
||||||
|
pkill -f admin-server.js; cd /Users/jessi/karatehp && node admin-server.js &
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in a new issue