UX: Würfe-Stats-Chips klickbar (Status-Filter), Wurfbörse Testdaten (SW by-v895)
This commit is contained in:
parent
f3308a6a94
commit
0f230b9ddc
5 changed files with 79 additions and 62 deletions
|
|
@ -5,10 +5,11 @@
|
|||
|
||||
window.Page_litters = (() => {
|
||||
|
||||
let _container = null;
|
||||
let _appState = null;
|
||||
let _litters = []; // geladene Würfe
|
||||
let _openId = null; // aufgeklappter Wurf
|
||||
let _container = null;
|
||||
let _appState = null;
|
||||
let _litters = []; // geladene Würfe
|
||||
let _openId = null; // aufgeklappter Wurf
|
||||
let _filterStatus = null; // aktiver Status-Filter
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Hilfsfunktionen
|
||||
|
|
@ -142,22 +143,59 @@ window.Page_litters = (() => {
|
|||
const welpen = _litters.reduce((s, l) => s + (l.welpen_gesamt || 0), 0);
|
||||
const verfuegb = _litters.reduce((s, l) => s + (l.welpen_verfuegbar || 0), 0);
|
||||
const statItems = [
|
||||
{ icon: 'list-bullets', label: 'Würfe gesamt', val: total },
|
||||
{ icon: 'baby', label: 'Aktiv', val: aktiv, color: 'var(--c-success)' },
|
||||
{ icon: 'calendar-dots',label: 'Geplant', val: geplant },
|
||||
{ icon: 'dog', label: 'Welpen', val: welpen },
|
||||
{ icon: 'tag', label: 'Verfügbar', val: verfuegb, color: verfuegb > 0 ? 'var(--c-primary)' : undefined },
|
||||
{ icon: 'list-bullets', label: 'Alle Würfe', val: total, filter: null },
|
||||
{ icon: 'baby', label: 'Aktiv', val: aktiv, filter: ['verfuegbar','geboren'], color: 'var(--c-success)' },
|
||||
{ icon: 'calendar-dots',label: 'Geplant', val: geplant, filter: ['geplant'] },
|
||||
{ icon: 'dog', label: 'Welpen ges.', val: welpen, filter: null },
|
||||
{ icon: 'tag', label: 'Verfügbar', val: verfuegb,filter: ['verfuegbar'], color: verfuegb > 0 ? 'var(--c-primary)' : undefined },
|
||||
];
|
||||
bar.style.display = 'flex';
|
||||
bar.innerHTML = statItems.map(s => `
|
||||
<div style="background:var(--c-bg-secondary);border:1px solid var(--c-border);border-radius:var(--radius-md);
|
||||
padding:var(--space-3) var(--space-4);display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:100px">
|
||||
<span style="color:${s.color || 'var(--c-text-muted)'};opacity:.8">${UI.icon(s.icon)}</span>
|
||||
<div>
|
||||
<div style="font-size:var(--text-lg);font-weight:700;color:${s.color || 'var(--c-text);line-height:1'}">${s.val}</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">${s.label}</div>
|
||||
</div>
|
||||
</div>`).join('');
|
||||
bar.innerHTML = statItems.map((s, i) => {
|
||||
const isActive = JSON.stringify(_filterStatus) === JSON.stringify(s.filter);
|
||||
const clickable = s.filter !== undefined && !(s.label === 'Welpen ges.');
|
||||
return `
|
||||
<div data-stat-idx="${i}"
|
||||
style="background:${isActive ? 'var(--c-primary)' : 'var(--c-bg-secondary)'};
|
||||
border:1px solid ${isActive ? 'var(--c-primary)' : 'var(--c-border)'};
|
||||
border-radius:var(--radius-md);padding:var(--space-3) var(--space-4);
|
||||
display:flex;align-items:center;gap:var(--space-2);flex:1;min-width:90px;
|
||||
${clickable ? 'cursor:pointer;user-select:none;transition:opacity .15s' : ''}">
|
||||
<span style="color:${isActive ? 'white' : (s.color || 'var(--c-text-muted)')};opacity:.9">${UI.icon(s.icon)}</span>
|
||||
<div>
|
||||
<div style="font-size:var(--text-lg);font-weight:700;
|
||||
color:${isActive ? 'white' : (s.color || 'var(--c-text)')};line-height:1">${s.val}</div>
|
||||
<div style="font-size:var(--text-xs);color:${isActive ? 'rgba(255,255,255,.75)' : 'var(--c-text-muted)'}">${s.label}</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
|
||||
bar.querySelectorAll('[data-stat-idx]').forEach(chip => {
|
||||
const s = statItems[parseInt(chip.dataset.statIdx)];
|
||||
if (!s.filter && s.label !== 'Alle Würfe') return;
|
||||
chip.addEventListener('click', () => {
|
||||
_filterStatus = JSON.stringify(_filterStatus) === JSON.stringify(s.filter) ? null : s.filter;
|
||||
_renderStats();
|
||||
_renderFilteredList();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _renderFilteredList() {
|
||||
const el = document.getElementById('litters-list');
|
||||
if (!el) return;
|
||||
const visible = _filterStatus
|
||||
? _litters.filter(l => _filterStatus.includes(l.status))
|
||||
: _litters;
|
||||
if (!visible.length) {
|
||||
el.innerHTML = `
|
||||
<div style="text-align:center;padding:var(--space-8) var(--space-4);
|
||||
border:1px dashed var(--c-border);border-radius:var(--radius-lg)">
|
||||
<p style="color:var(--c-text-muted)">Keine Würfe für diesen Filter.</p>
|
||||
</div>`;
|
||||
return;
|
||||
}
|
||||
el.innerHTML = visible.map(l => _litterCardHTML(l)).join('');
|
||||
_bindCardEvents(el, visible);
|
||||
}
|
||||
|
||||
function _renderList() {
|
||||
|
|
@ -178,73 +216,52 @@ window.Page_litters = (() => {
|
|||
}
|
||||
|
||||
_renderStats();
|
||||
_filterStatus = null;
|
||||
el.innerHTML = _litters.map(l => _litterCardHTML(l)).join('');
|
||||
_bindCardEvents(el, _litters);
|
||||
if (_openId) _togglePuppies(_openId, true);
|
||||
}
|
||||
|
||||
// Events
|
||||
function _bindCardEvents(el, litters) {
|
||||
el.querySelectorAll('.litters-card-toggle').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
_togglePuppies(id);
|
||||
});
|
||||
btn.addEventListener('click', () => _togglePuppies(parseInt(btn.dataset.id)));
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-photos-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
const litter = _litters.find(l => l.id === id);
|
||||
if (litter) _showPhotosModal('litter', litter.id, litter.zwingername || `Wurf #${litter.id}`);
|
||||
const l = litters.find(x => x.id === id);
|
||||
if (l) _showPhotosModal('litter', l.id, l.zwingername || `Wurf #${l.id}`);
|
||||
});
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-parent-photos-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
const litter = _litters.find(l => l.id === id);
|
||||
if (!litter) return;
|
||||
const label = [litter.vater_name, litter.mutter_name].filter(Boolean).join(' × ') || `Eltern Wurf #${id}`;
|
||||
_showPhotosModal('parent', litter.id, label);
|
||||
const l = litters.find(x => x.id === id);
|
||||
if (!l) return;
|
||||
_showPhotosModal('parent', l.id, [l.vater_name, l.mutter_name].filter(Boolean).join(' × ') || `Eltern #${id}`);
|
||||
});
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-edit-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
const litter = _litters.find(l => l.id === id);
|
||||
if (litter) _showLitterForm(litter);
|
||||
const l = litters.find(x => x.id === parseInt(btn.dataset.id));
|
||||
if (l) _showLitterForm(l);
|
||||
});
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-delete-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
_deleteLitter(id);
|
||||
});
|
||||
btn.addEventListener('click', () => _deleteLitter(parseInt(btn.dataset.id)));
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-ki-announce-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
_showKiAnnouncement(id);
|
||||
});
|
||||
btn.addEventListener('click', () => _showKiAnnouncement(parseInt(btn.dataset.id)));
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-add-puppy-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const id = parseInt(btn.dataset.id);
|
||||
_showPuppyForm(id, null);
|
||||
});
|
||||
btn.addEventListener('click', () => _showPuppyForm(parseInt(btn.dataset.id), null));
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-waitlist-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => _toggleWaitlist(parseInt(btn.dataset.id)));
|
||||
});
|
||||
|
||||
el.querySelectorAll('.litters-add-waitlist-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => _showWaitlistForm(parseInt(btn.dataset.id), null));
|
||||
});
|
||||
|
||||
// Aufgeklappten Wurf wiederherstellen
|
||||
if (_openId) _togglePuppies(_openId, true);
|
||||
}
|
||||
|
||||
function _daysUntil(dateStr) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue