/* ============================================================
BAN YARO — Öffentliches Züchter-Profil (Visitenkarte)
============================================================ */
window.Page_breeder = (() => {
let _container = null;
let _appState = null;
const _esc = s => UI.esc ? UI.esc(s) : String(s ?? '').replace(/[&<>"']/g,
c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
// ----------------------------------------------------------
// INIT
// ----------------------------------------------------------
async function init(container, appState, params = {}) {
_container = container;
_appState = appState;
const zwingername = params?.zwingername
|| decodeURIComponent((window.location.pathname.split('/breeder/')[1] || '').replace(/\/$/, ''));
if (!zwingername) {
container.innerHTML = '
Kein Zwingername angegeben.
';
return;
}
container.innerHTML = `
${UI.skeleton(5)}
`;
document.getElementById('breeder-back-fab')
?.addEventListener('click', () => App.navigate('wurfboerse'));
try {
const p = await API.breeder.profile(zwingername);
_render(p);
} catch (e) {
document.getElementById('breeder-profile-body').innerHTML =
`
${UI.icon('magnifying-glass')} ${_esc(e.message || 'Züchter nicht gefunden.')}
`;
}
}
// ----------------------------------------------------------
// RENDER
// ----------------------------------------------------------
function _render(p) {
const body = document.getElementById('breeder-profile-body') || _container;
const seit = p.verified_at
? new Date(p.verified_at).toLocaleDateString('de-DE', { month: 'long', year: 'numeric' })
: null;
const isLoggedIn = !!_appState?.user;
const isOwnProfile = _appState?.user?.id === p.zuechter_user_id;
body.innerHTML = `
${UI.icon('seal-check')} Verifizierter Züchter
${_esc(p.zwingername)}
${p.rasse_text ? `${_esc(p.rasse_text)}` : ''}
${p.vdh_mitglied ? `${UI.icon('certificate')} VDH` : ''}
${p.stadt ? `${UI.icon('map-pin')} ${_esc(p.stadt)}` : ''}
${seit ? `Züchter seit ${_esc(seit)}` : ''}
${p.logo_url
? `
})
`
: `
`
}
${!isOwnProfile ? `
` : ''}
${p.beschreibung ? `
` : ''}
${p.hunde?.length ? `
${UI.icon('dog')} Unsere Zuchthunde
${p.hunde.length} Hunde
${p.hunde.map(h => _hundCard(h)).join('')}
` : ''}
${p.wuerfe?.length ? `
${UI.icon('baby')} Aktuelle Würfe
${p.wuerfe.map(w => _wurfCard(w)).join('')}
` : ''}
${(p.hd_stats?.length || p.ed_stats?.length) ? `
${UI.icon('heartbeat')} Gesundheits-Transparenz
${_statsSection('HD-Ergebnisse', p.hd_stats)}
${p.hd_stats?.length && p.ed_stats?.length ? '
' : ''}
${_statsSection('ED-Ergebnisse', p.ed_stats)}
` : ''}
${UI.icon('info')} Über den Züchter
${_dl('Züchter', p.zuechter_name)}
${_dl('Rasse(n)', p.rasse_text)}
${_dl('Verein', p.verein)}
${_dl('VDH-Mitglied', p.vdh_mitglied ? '✓ Ja' : 'Nein')}
${_dl('Stadt', p.stadt)}
${p.website ? `
` : ''}
${seit ? _dl('Züchter seit', seit) : ''}
${p.fotos?.length ? `
${UI.icon('images')} Galerie
${p.fotos.length} Fotos
` : ''}
`;
// Events
body.querySelector('.breeder-chat-btn')?.addEventListener('click', () => _contactBreeder(p.zuechter_user_id));
body.querySelector('.breeder-login-btn')?.addEventListener('click', () => App.navigate('settings'));
_loadBreederPhotos(p.id);
}
// ----------------------------------------------------------
// Hund-Karte
// ----------------------------------------------------------
function _hundCard(h) {
const alter = h.geburtsdatum
? Math.floor((Date.now() - new Date(h.geburtsdatum)) / 31557600000)
: null;
const gIcon = h.geschlecht === 'maennlich' ? UI.icon('gender-male') : UI.icon('gender-female');
const hdTest = h.health_tests?.find(t => t.test_typ === 'HD');
const edTest = h.health_tests?.find(t => t.test_typ === 'ED');
const augeTest = h.health_tests?.find(t => t.test_typ === 'augen');
const testPills = [
hdTest ? `HD ${_esc(hdTest.ergebnis)}` : '',
edTest ? `ED ${_esc(edTest.ergebnis)}` : '',
augeTest ? `Augen ✓` : '',
].filter(Boolean).join('');
const titlePills = (h.titel || []).map(t =>
`${_esc(t)}`
).join('');
const genBadge = h.gentests_total > 0
? `
${h.gentests_clear}/${h.gentests_total} Gentests frei
`
: '';
return `
${gIcon}
${_esc(h.name)}
${h.rufname ? `"${_esc(h.rufname)}"` : ''}
${alter !== null ? `${alter} J.` : ''}
${h.farbe ? `
${_esc(h.farbe)}
` : ''}
${testPills ? `
${testPills}
` : ''}
${titlePills ? `
${titlePills}
` : ''}
${genBadge}
`;
}
function _testPillStyle(ergebnis, typ) {
const e = (ergebnis || '').toUpperCase();
let bg = '#6b72801a', color = '#6b7280', border = '#6b728040';
if (typ === 'HD') {
if (['A','A1','A2'].includes(e)) { bg='#16a34a1a';color='#16a34a';border='#16a34a40'; }
else if (e === 'B' || e === 'B1' || e === 'B2') { bg='#86efac1a';color='#15803d';border='#86efac40'; }
else if (e === 'C') { bg='#eab3081a';color='#a16207';border='#eab30840'; }
else if (e === 'D' || e === 'E') { bg='#ef44441a';color='#dc2626';border='#ef444440'; }
} else if (typ === 'ED') {
if (e === '0' || e === 'ED 0') { bg='#16a34a1a';color='#16a34a';border='#16a34a40'; }
else if (e === '1') { bg='#eab3081a';color='#a16207';border='#eab30840'; }
else if (e === '2' || e === '3') { bg='#ef44441a';color='#dc2626';border='#ef444440'; }
} else if (typ === 'augen' || ergebnis === 'clear') {
bg='#16a34a1a';color='#16a34a';border='#16a34a40';
}
return `background:${bg};color:${color};border:1px solid ${border};border-radius:999px;padding:1px 8px;font-size:11px;font-weight:600`;
}
// ----------------------------------------------------------
// Wurf-Karte
// ----------------------------------------------------------
const _STATUS_LABEL = { geplant: 'Geplant', geboren: 'Geboren', verfuegbar: 'Verfügbar', abgeschlossen: 'Abgeschlossen' };
const _STATUS_COLOR = { geplant: '#6b7280', geboren: '#3b82f6', verfuegbar: '#16a34a', abgeschlossen: '#9ca3af' };
function _wurfCard(w) {
const eltern = [w.vater_name, w.mutter_name].filter(Boolean).join(' × ') || '—';
const datum = w.geburt_datum
? `Geburt: ${_fmtDate(w.geburt_datum)}`
: w.erwartetes_datum ? `Erwartet: ${_fmtDate(w.erwartetes_datum)}` : '';
const sc = _STATUS_COLOR[w.status] || '#6b7280';
const sl = _STATUS_LABEL[w.status] || w.status;
return `
${_esc(eltern)}
${sl}
${datum ? `${UI.icon('calendar-dots')} ${_esc(datum)}` : ''}
${w.welpen_gesamt ? `${UI.icon('dog')} ${w.welpen_verfuegbar ?? '?'}/${w.welpen_gesamt} verfügbar` : ''}
${w.preis_spanne ? `${UI.icon('currency-eur')} ${_esc(w.preis_spanne)}` : ''}
${w.beschreibung ? `
${_esc(w.beschreibung)}
` : ''}
`;
}
// ----------------------------------------------------------
// Statistik-Sektion
// ----------------------------------------------------------
function _statsSection(label, stats) {
if (!stats?.length) return '';
const total = stats.reduce((s, r) => s + r.cnt, 0);
return `
${_esc(label)}
${stats.map(r => `
${_esc(r.ergebnis || '—')}
${r.cnt}×
`).join('')}
`;
}
// ----------------------------------------------------------
// Hilfsfunktionen
// ----------------------------------------------------------
function _dl(label, value) {
if (!value) return '';
return `
${_esc(label)}
${_esc(String(value))}
`;
}
function _fmtDate(iso) {
if (!iso) return '—';
const [y,m,d] = iso.slice(0,10).split('-');
return `${d}.${m}.${y}`;
}
async function _loadBreederPhotos(breederId) {
const section = document.getElementById('breeder-photos-section');
if (!section) return;
try {
const photos = await API.breederPhotos.list('breeder', breederId);
if (!photos?.length) return;
section.innerHTML = `
${UI.icon('images')} Fotos
${photos.map(ph => `
`).join('')}
`;
} catch (_) {}
}
async function _contactBreeder(userId) {
if (!_appState?.user) { App.navigate('settings'); return; }
try {
await API.chat.start(userId);
App.navigate('chat');
} catch (e) { UI.toast.error(e.message || 'Chat konnte nicht geöffnet werden.'); }
}
function refresh() {}
function onDogChange() {}
function destroy() { document.getElementById('breeder-back-fab')?.remove(); }
return { init, refresh, onDogChange, destroy };
})();