225 lines
9 KiB
JavaScript
225 lines
9 KiB
JavaScript
/* ============================================================
|
||
BAN YARO — Öffentliches Züchter-Profil
|
||
Seiten-Modul: Zeigt das verifizierte Profil eines Züchters.
|
||
============================================================ */
|
||
|
||
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;
|
||
|
||
// Zwingername aus params oder URL-Pfad (/breeder/vom-sonnenfeld)
|
||
const zwingername = params?.zwingername
|
||
|| decodeURIComponent((window.location.pathname.split('/breeder/')[1] || '').replace(/\/$/, ''));
|
||
|
||
if (!zwingername) {
|
||
container.innerHTML = '<div style="padding:var(--space-6)">Kein Zwingername angegeben.</div>';
|
||
return;
|
||
}
|
||
|
||
container.innerHTML = `
|
||
<div style="padding:var(--space-3) var(--space-4) 0">
|
||
<button class="btn btn-ghost btn-sm" id="breeder-back-btn">
|
||
${UI.icon('arrow-left')} Zurück zur Wurfbörse
|
||
</button>
|
||
</div>
|
||
<div id="breeder-profile-body" style="padding:0 var(--space-4) var(--space-6);text-align:center">
|
||
${UI.skeleton(3)}
|
||
</div>`;
|
||
|
||
document.getElementById('breeder-back-btn')
|
||
?.addEventListener('click', () => App.navigate('wurfboerse'));
|
||
|
||
try {
|
||
const p = await API.breeder.profile(zwingername);
|
||
_render(p);
|
||
} catch (e) {
|
||
document.getElementById('breeder-profile-body').innerHTML =
|
||
`<p style="padding:var(--space-6);color:var(--c-text-secondary)">${_esc(e.message || 'Züchter nicht gefunden.')}</p>`;
|
||
}
|
||
}
|
||
|
||
// ----------------------------------------------------------
|
||
// RENDER
|
||
// ----------------------------------------------------------
|
||
function _render(p) {
|
||
const verifiedDate = p.verified_at
|
||
? new Date(p.verified_at).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })
|
||
: null;
|
||
|
||
const websiteHtml = p.website
|
||
? `<a href="${_esc(p.website)}" target="_blank" rel="noopener noreferrer"
|
||
style="color:var(--c-primary);text-decoration:none;word-break:break-all">
|
||
${UI.icon('arrow-square-out')} ${_esc(p.website)}
|
||
</a>`
|
||
: '';
|
||
|
||
const beschreibungHtml = p.beschreibung
|
||
? `<div class="card" style="margin-bottom:var(--space-3)">
|
||
<p style="margin:0;white-space:pre-line;color:var(--c-text-secondary)">${_esc(p.beschreibung)}</p>
|
||
</div>`
|
||
: '';
|
||
|
||
const body = document.getElementById('breeder-profile-body') || _container;
|
||
body.innerHTML = `
|
||
<div style="padding:var(--space-4) 0">
|
||
|
||
<!-- Header-Card -->
|
||
<div class="card" style="margin-bottom:var(--space-3)">
|
||
<div style="display:flex;align-items:flex-start;gap:var(--space-3);flex-wrap:wrap">
|
||
<div style="flex:1;min-width:0">
|
||
<h2 style="margin:0 0 var(--space-1);font-size:var(--text-xl);word-break:break-word">
|
||
${UI.icon('certificate')} ${_esc(p.zwingername)}
|
||
</h2>
|
||
<span class="badge badge-primary" style="background:var(--c-success,#22C55E);color:#fff;font-size:var(--text-xs)">
|
||
${UI.icon('seal-check')} Verifizierter Züchter
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Details-Card -->
|
||
<div class="card" style="margin-bottom:var(--space-3)">
|
||
<dl style="margin:0;display:flex;flex-direction:column;gap:var(--space-3)">
|
||
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">Rasse</dt>
|
||
<dd style="margin:0;font-weight:600">${_esc(p.rasse_text || '–')}</dd>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">Verein</dt>
|
||
<dd style="margin:0">${_esc(p.verein || '–')}</dd>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">VDH-Mitglied</dt>
|
||
<dd style="margin:0">
|
||
${p.vdh_mitglied
|
||
? `<span class="badge badge-primary">${UI.icon('check')} Ja</span>`
|
||
: `<span style="color:var(--c-text-secondary)">Nein</span>`}
|
||
</dd>
|
||
</div>
|
||
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">Stadt</dt>
|
||
<dd style="margin:0">${_esc(p.stadt || '–')}</dd>
|
||
</div>
|
||
|
||
${p.website ? `
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">Website</dt>
|
||
<dd style="margin:0">${websiteHtml}</dd>
|
||
</div>` : ''}
|
||
|
||
${verifiedDate ? `
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">Verifiziert</dt>
|
||
<dd style="margin:0;color:var(--c-text-secondary);font-size:var(--text-sm)">${verifiedDate}</dd>
|
||
</div>` : ''}
|
||
|
||
<div style="display:flex;gap:var(--space-2);align-items:baseline">
|
||
<dt style="color:var(--c-text-secondary);min-width:100px;font-size:var(--text-sm);flex-shrink:0">Züchter</dt>
|
||
<dd style="margin:0">${_esc(p.zuechter_name || '–')}</dd>
|
||
</div>
|
||
|
||
</dl>
|
||
</div>
|
||
|
||
<!-- Beschreibung -->
|
||
${beschreibungHtml}
|
||
|
||
<!-- Fotos (werden asynchron nachgeladen) -->
|
||
<div id="breeder-photos-section"></div>
|
||
|
||
<!-- Kontakt-Button -->
|
||
${(() => {
|
||
if (!p.zuechter_user_id) return '';
|
||
const isLoggedIn = !!_appState?.user;
|
||
const isOwnProfile = _appState?.user?.id === p.zuechter_user_id;
|
||
if (isOwnProfile) return '';
|
||
if (isLoggedIn) {
|
||
return `<button class="btn btn-primary breeder-chat-btn" style="width:100%">
|
||
${UI.icon('chat-circle')} Nachricht senden
|
||
</button>`;
|
||
}
|
||
return `<button class="btn btn-primary breeder-login-btn" style="width:100%">
|
||
${UI.icon('sign-in')} Anmelden um zu schreiben
|
||
</button>`;
|
||
})()}
|
||
|
||
</div>
|
||
`;
|
||
|
||
_container.querySelector('.breeder-chat-btn')?.addEventListener('click', () => {
|
||
_contactBreeder(p.zuechter_user_id);
|
||
});
|
||
_container.querySelector('.breeder-login-btn')?.addEventListener('click', () => {
|
||
App.navigate('settings');
|
||
});
|
||
|
||
// Öffentliche Fotos nachladen
|
||
_loadBreederPhotos(p.id);
|
||
}
|
||
|
||
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 || !photos.length) return;
|
||
|
||
section.innerHTML = `
|
||
<div class="card" style="margin-bottom:var(--space-3)">
|
||
<h3 style="margin:0 0 var(--space-3);font-size:var(--text-md);font-weight:var(--weight-semibold)">
|
||
${UI.icon('images')} Fotos
|
||
</h3>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(100px,1fr));gap:var(--space-2)">
|
||
${photos.map(ph => {
|
||
const thumb = ph.thumbnail_url || ph.url || '';
|
||
return `
|
||
<a href="${_esc(ph.url || '')}" target="_blank" rel="noopener noreferrer"
|
||
style="display:block;border-radius:var(--radius-md);overflow:hidden;
|
||
border:1px solid var(--c-border);aspect-ratio:1">
|
||
<img src="${_esc(thumb)}"
|
||
alt="${_esc(ph.caption || '')}"
|
||
loading="lazy"
|
||
style="width:100%;height:100%;object-fit:cover;display:block"
|
||
onerror="this.parentElement.style.display='none'">
|
||
</a>`;
|
||
}).join('')}
|
||
</div>
|
||
</div>`;
|
||
} catch (_) {
|
||
// Fotos sind nicht kritisch — bei Fehler still ignorieren
|
||
}
|
||
}
|
||
|
||
async function _contactBreeder(breederId) {
|
||
if (!_appState?.user) {
|
||
App.navigate('settings');
|
||
return;
|
||
}
|
||
try {
|
||
await API.chat.start(breederId);
|
||
App.navigate('chat');
|
||
} catch (e) {
|
||
UI.toast.error(e.message || 'Chat konnte nicht geöffnet werden.');
|
||
}
|
||
}
|
||
|
||
function refresh() {}
|
||
function onDogChange() {}
|
||
|
||
return { init, refresh, onDogChange };
|
||
|
||
})();
|