let friends = [];
let currentIndex = 0;
const STECKBRIEF_LABELS = {
spitzname: 'Spitzname',
geburtstag: 'Geburtstag',
adresse: 'Adresse / Wohnort',
lieblingsfarbe: 'Lieblingsfarbe',
lieblingsessen: 'Lieblingsessen',
lieblingstier: 'Lieblingstier',
hobbys: 'Hobbys',
lieblingsmusik: 'Lieblingsmusik',
lieblingsfilm: 'Lieblingsfilm/-serie',
traumberuf: 'Traumberuf',
bestefreunde: 'Beste Freunde',
motto: 'Motto / Lebensweisheit',
sonstiges: 'Sonstiges',
};
function escapeHtml(str) {
const div = document.createElement('div');
div.textContent = str || '';
return div.innerHTML;
}
function randomRotation(seed) {
const angles = [-6, -4, -2, 2, 4, 6, -3, 3, 5, -5];
return angles[seed % angles.length];
}
async function load() {
const res = await fetch('/api/book');
if (res.status === 401) { window.location.href = '/'; return; }
const data = await res.json();
friends = data.friends || [];
if (!friends.length) {
document.getElementById('bookRoot').innerHTML = `
Noch ist dieses Buch leer 📖
Lege im Admin-Bereich Freunde an und teile den Link mit ihnen.
`;
return;
}
document.getElementById('bookNav').style.display = 'flex';
renderPage();
}
function uploadUrl(folder, filename) {
return `/uploads/${encodeURIComponent(folder)}/${encodeURIComponent(filename)}`;
}
function renderPage() {
const f = friends[currentIndex];
const root = document.getElementById('bookRoot');
const profileHtml = f.profileImage
? `
`
: `${(f.name || '?')[0].toUpperCase()}
`;
const sbEntries = Object.entries(f.steckbrief || {}).filter(([, v]) => v && String(v).trim());
const sbHtml = sbEntries.length
? `${sbEntries.map(([k, v]) => `
${escapeHtml(STECKBRIEF_LABELS[k] || k)}${escapeHtml(v)}
`).join('')}
`
: `Noch nichts eingetragen.
`;
const blocks = [...(f.blocks || [])].sort((a, b) => a.order - b.order);
const blocksHtml = blocks.length
? blocks.map((b, i) => {
const rot = randomRotation(i + f.id.length);
if (b.type === 'image') {
return `
})
${b.caption ? `
${escapeHtml(b.caption)}
` : ''}
`;
}
if (b.type === 'audio') {
return `
🎙️ ${b.caption ? escapeHtml(b.caption) : 'Sprachnachricht'}
`;
}
return `
${escapeHtml(b.content).replace(/\n/g, '
')}
${b.caption ? `
${escapeHtml(b.caption)}
` : ''}
`;
}).join('')
: 'Noch keine Erinnerungen hinzugefügt.
';
root.innerHTML = `
${profileHtml}
${escapeHtml(f.name)}
Steckbrief
${sbHtml}
${blocksHtml}
`;
document.getElementById('pageIndicator').textContent = `Seite ${currentIndex + 1} von ${friends.length}`;
document.getElementById('prevBtn').disabled = currentIndex === 0;
document.getElementById('nextBtn').disabled = currentIndex === friends.length - 1;
}
document.getElementById('prevBtn').addEventListener('click', () => {
if (currentIndex > 0) { currentIndex--; renderPage(); window.scrollTo({ top: 0, behavior: 'smooth' }); }
});
document.getElementById('nextBtn').addEventListener('click', () => {
if (currentIndex < friends.length - 1) { currentIndex++; renderPage(); window.scrollTo({ top: 0, behavior: 'smooth' }); }
});
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') document.getElementById('prevBtn').click();
if (e.key === 'ArrowRight') document.getElementById('nextBtn').click();
});
document.getElementById('pdfBtn').addEventListener('click', async () => {
const btn = document.getElementById('pdfBtn');
btn.disabled = true;
btn.textContent = 'Erzeuge PDF...';
try {
const res = await fetch('/api/book/pdf');
if (!res.ok) throw new Error('PDF-Export fehlgeschlagen.');
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'freundesbuch.pdf';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
} catch (err) {
alert(err.message);
} finally {
btn.disabled = false;
btn.textContent = '⬇️ Als PDF exportieren';
}
});
load();