Bilder Aspect + name centered + Preview

This commit is contained in:
2026-09-07 18:53:41 +02:00
parent a426d5d779
commit b639c03ef8
7 changed files with 130 additions and 14 deletions

View File

@@ -26,7 +26,7 @@
background: var(--paper-2); border-radius: 10px; box-shadow: var(--shadow);
padding: 1em; width: 220px; position: relative;
}
.block-item img { width: 100%; height: 140px; object-fit: cover; border-radius: 6px; }
.block-item img { display: block; max-width: 100%; max-height: 220px; width: auto; height: auto; margin: 0 auto; border-radius: 6px; }
.block-item audio { width: 100%; margin-top: 0.4em; }
.block-item textarea { min-height: 4em; font-size: 0.9rem; }
.block-item .block-caption { font-size: 0.82rem; margin-top: 0.5em; }
@@ -36,3 +36,23 @@
position: absolute; top: -8px; left: 10px; font-size: 0.7rem; font-weight: 700;
background: var(--mustard); color: #533; padding: 0.1em 0.6em; border-radius: 999px;
}
.preview-modal-backdrop {
position: fixed; inset: 0; background: rgba(75,59,107,0.45);
display: flex; align-items: flex-start; justify-content: center;
z-index: 100; padding: 2em 1em; overflow-y: auto;
}
.preview-modal {
background: var(--paper);
border-radius: 16px;
box-shadow: 0 12px 40px rgba(0,0,0,0.3);
width: 100%; max-width: 780px;
max-height: calc(100vh - 4em);
display: flex; flex-direction: column; overflow: hidden;
}
.preview-modal-head {
display: flex; align-items: center; justify-content: space-between;
gap: 1em; padding: 1em 1.4em; background: var(--paper-2);
border-bottom: 2px solid var(--line); flex-wrap: wrap;
}
.preview-modal-body { overflow-y: auto; padding: 0.5em; }

View File

@@ -278,4 +278,80 @@ async function moveBlock(id, dir) {
if (res.ok) { currentFriend = data.friend; renderBlocks(); }
}
// --- Vorschau: rendert die Seite genauso wie später im Freundesbuch-Viewer ---
function randomRotation(seed) {
const angles = [-6, -4, -2, 2, 4, 6, -3, 3, 5, -5];
return angles[seed % angles.length];
}
function renderPreview() {
const f = currentFriend;
const container = document.getElementById('previewContent');
const profileHtml = f.profileImage
? `<img class="page-profile-pic" src="${uploadUrl(f.profileImage)}" />`
: `<div class="page-profile-pic placeholder">${(f.name || '?')[0].toUpperCase()}</div>`;
const sbEntries = STECKBRIEF_FIELDS
.map(([key, label]) => [label, (f.steckbrief || {})[key]])
.filter(([, v]) => v && String(v).trim());
const sbHtml = sbEntries.length
? `<div class="sb-grid">${sbEntries.map(([label, v]) => `
<div class="sb-row"><span class="sb-key">${escapeHtml(label)}</span><span class="sb-val">${escapeHtml(v)}</span></div>
`).join('')}</div>`
: `<p class="muted">Noch nichts eingetragen.</p>`;
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 `<div class="scrap-item polaroid" style="transform: rotate(${rot}deg);">
<img src="${uploadUrl(b.filename)}" />
${b.caption ? `<div class="scrap-caption">${escapeHtml(b.caption)}</div>` : ''}
</div>`;
}
if (b.type === 'audio') {
return `<div class="scrap-item audio-note" style="transform: rotate(${rot * 0.5}deg);">
${b.coverFilename ? `<img class="audio-cover" src="${uploadUrl(b.coverFilename)}" />` : ''}
<div>🎙️${b.caption ? ' ' + escapeHtml(b.caption) : ''}</div>
<audio controls src="${uploadUrl(b.filename)}"></audio>
</div>`;
}
return `<div class="scrap-item text-note" style="transform: rotate(${rot * 0.5}deg);">
<p>${escapeHtml(b.content).replace(/\n/g, '<br/>')}</p>
${b.caption ? `<div class="scrap-caption">${escapeHtml(b.caption)}</div>` : ''}
</div>`;
}).join('')
: '<p class="muted">Noch keine Erinnerungen hinzugefügt.</p>';
container.innerHTML = `
<div class="friend-page">
<div class="page-head">
<div class="tape"></div>
${profileHtml}
<h1>${escapeHtml(f.name)}</h1>
</div>
<div class="steckbrief-card">
<h2>Steckbrief</h2>
${sbHtml}
</div>
<div class="scrap-grid">
${blocksHtml}
</div>
</div>
`;
}
document.getElementById('previewBtn').addEventListener('click', () => {
renderPreview();
document.getElementById('previewModal').style.display = 'flex';
});
document.getElementById('previewCloseBtn').addEventListener('click', () => {
document.getElementById('previewModal').style.display = 'none';
});
document.getElementById('previewModal').addEventListener('click', (e) => {
if (e.target.id === 'previewModal') document.getElementById('previewModal').style.display = 'none';
});
init();

View File

@@ -6,6 +6,7 @@
<title>Freundesbuch</title>
<link rel="stylesheet" href="/assets/style.css" />
<link rel="stylesheet" href="/friend/friend.css" />
<link rel="stylesheet" href="/book/book.css" />
</head>
<body>
@@ -26,7 +27,10 @@
<div id="editorRoot" style="display:none;">
<div class="top-bar card" style="border-radius:0;">
<h1 style="margin:0;" id="pageTitle">📖 Freund</h1>
<div id="adminBackWrap"><a class="btn secondary" href="/admin">← Zur Übersicht</a></div>
<div style="display:flex; gap:0.6em; flex-wrap:wrap;">
<button type="button" class="secondary" id="previewBtn">👀 Vorschau</button>
<div id="adminBackWrap"><a class="btn secondary" href="/admin">← Zur Übersicht</a></div>
</div>
</div>
<div class="container">
@@ -82,6 +86,19 @@
</div>
</div>
<!-- Vorschau-Modal: zeigt die Seite so, wie sie später im Freundesbuch aussieht -->
<div id="previewModal" class="preview-modal-backdrop" style="display:none;">
<div class="preview-modal">
<div class="preview-modal-head">
<h2 style="margin:0;">👀 So sieht deine Seite im Freundesbuch aus</h2>
<button type="button" class="secondary" id="previewCloseBtn">Schließen</button>
</div>
<div class="preview-modal-body">
<div id="previewContent" class="book-root" style="padding:1.5em 0.5em;"></div>
</div>
</div>
</div>
<script src="/friend/friend.js"></script>
</body>
</html>