- Favicon: emoji-based inline SVG (🍯), the old /images/favicon/favicon.ico reference never resolved to an actual file. - Profile picture (the circular image at the top) is now a per-page "profile_image" field editable in /admin, instead of a hardcoded URL in the template. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
214 lines
9.6 KiB
HTML
214 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||
<title>Admin – Honey Links</title>
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
||
<style>
|
||
body {
|
||
display: block;
|
||
padding: 24px;
|
||
max-width: 900px;
|
||
margin: 0 auto;
|
||
overflow-x: visible;
|
||
}
|
||
h1 { text-align: left; }
|
||
h2.section-title { animation: none; }
|
||
.top-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
|
||
.admin-page { margin-bottom: 40px; border: 1px solid #374151; border-radius: 10px; padding: 20px; }
|
||
.admin-page h2 { color: #a5f3fc; margin-bottom: 16px; }
|
||
.admin-section { border: 1px solid #374151; border-radius: 8px; padding: 12px; margin-bottom: 16px; }
|
||
.section-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
|
||
.admin-link-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 8px 0; border-bottom: 1px solid #1f2937; }
|
||
.admin-link-row:last-of-type { border-bottom: none; }
|
||
.admin-link-row form.edit-form {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
align-items: center;
|
||
flex: 1 1 100%;
|
||
}
|
||
.admin-link-row .link-actions {
|
||
display: flex;
|
||
gap: 6px;
|
||
align-items: center;
|
||
}
|
||
form.inline { display: inline-flex; gap: 6px; align-items: center; }
|
||
input[type=text], input[type=url], input[type=password] {
|
||
padding: 6px 8px;
|
||
border-radius: 4px;
|
||
border: 1px solid #4b5563;
|
||
background: #0f172a;
|
||
color: #f3f4f6;
|
||
}
|
||
select {
|
||
padding: 6px 8px;
|
||
border-radius: 4px;
|
||
background: #0f172a;
|
||
color: #f3f4f6;
|
||
border: 1px solid #4b5563;
|
||
}
|
||
button {
|
||
padding: 6px 12px;
|
||
border-radius: 4px;
|
||
border: 1px solid #4b5563;
|
||
background: rgba(255, 255, 255, 0.06);
|
||
color: #f3f4f6;
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
}
|
||
button:hover { background: rgba(255, 255, 255, 0.12); }
|
||
.btn-danger { border-color: #b91c1c; color: #fca5a5; }
|
||
.new-form { margin-top: 12px; padding-top: 12px; border-top: 1px dashed #374151; }
|
||
label.checkbox { display: flex; align-items: center; gap: 4px; font-size: 13px; color: #9ca3af; white-space: nowrap; }
|
||
.field-title { flex: 1 1 130px; min-width: 100px; }
|
||
.field-note { flex: 1 1 150px; min-width: 100px; }
|
||
.field-url { flex: 2 1 180px; min-width: 140px; }
|
||
.quick-nav { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px; }
|
||
.quick-nav a {
|
||
padding: 6px 12px;
|
||
border-radius: 999px;
|
||
border: 1px solid #4b5563;
|
||
background: rgba(255, 255, 255, 0.04);
|
||
color: #a5f3fc;
|
||
text-decoration: none;
|
||
font-size: 13px;
|
||
}
|
||
.quick-nav a:hover { background: rgba(255, 255, 255, 0.1); }
|
||
.view-link { font-size: 13px; color: #21e4d3; text-decoration: none; margin-left: 10px; white-space: nowrap; }
|
||
.view-link:hover { color: #24ffed; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="top-bar">
|
||
<h1>Admin</h1>
|
||
<form method="post" action="{{ url_for('admin_logout') }}"><button type="submit">Logout</button></form>
|
||
</div>
|
||
|
||
<div class="quick-nav">
|
||
{% for page_key in data.keys() %}
|
||
<a href="#page-{{ page_key }}">↓ {{ page_key }}</a>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
<div class="admin-page">
|
||
<h2>Neue Seite anlegen</h2>
|
||
<form method="post" action="{{ url_for('add_page') }}" style="display: flex; gap: 8px; flex-wrap: wrap; align-items: center;">
|
||
<input type="text" name="title" placeholder="Titel der Seite" required>
|
||
<input type="text" name="slug" placeholder="url-slug (z.B. gaming)" pattern="[a-zA-Z0-9-]+" required>
|
||
<button type="submit">+ Seite anlegen</button>
|
||
</form>
|
||
<p style="color:#9ca3af; font-size:13px; margin-top:8px;">Erreichbar danach unter <code>/<slug>.html</code>, z.B. <code>/gaming.html</code>.</p>
|
||
</div>
|
||
|
||
{% for page_key, page in data.items() %}
|
||
<div class="admin-page" id="page-{{ page_key }}">
|
||
<div class="section-head">
|
||
<h2 style="margin-bottom:0;">
|
||
Seite: {{ page_key }} — erreichbar unter {% if page_key == 'index' %}<code>/</code>{% else %}<code>/{{ page_key }}.html</code>{% endif %}
|
||
<a class="view-link" href="{{ '/' if page_key == 'index' else '/' + page_key + '.html' }}" target="_blank">🔗 ansehen</a>
|
||
</h2>
|
||
{% if page_key != 'index' %}
|
||
<form method="post" action="{{ url_for('delete_page', page_key=page_key) }}" onsubmit="return confirm('Seite \'{{ page_key }}\' komplett inkl. aller Sections/Links löschen?');">
|
||
<button type="submit" class="btn-danger">Seite löschen</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<form method="post" action="{{ url_for('edit_header', page_key=page_key) }}" style="margin-bottom: 20px; display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;">
|
||
<div>
|
||
<label class="checkbox">Titel</label>
|
||
<input type="text" name="title" value="{{ page.title }}">
|
||
</div>
|
||
<div>
|
||
<label class="checkbox">Untertitel 1</label>
|
||
<input type="text" name="subtitle" value="{{ page.subtitle or '' }}">
|
||
</div>
|
||
<div>
|
||
<label class="checkbox">Untertitel 2</label>
|
||
<input type="text" name="subtitle2" value="{{ page.subtitle2 or '' }}">
|
||
</div>
|
||
<div>
|
||
<label class="checkbox">Footer-Link-Ziel</label>
|
||
<input type="text" name="footer_href" value="{{ page.footer_href or '' }}" placeholder="z.B. honey.html">
|
||
</div>
|
||
<div>
|
||
<label class="checkbox">Footer-Link-Text</label>
|
||
<input type="text" name="footer_label" value="{{ page.footer_label or '' }}" placeholder="z.B. Honey Version">
|
||
</div>
|
||
<div>
|
||
<label class="checkbox">Profilbild-URL</label>
|
||
<input type="text" name="profile_image" value="{{ page.profile_image or '' }}" placeholder="https://...">
|
||
</div>
|
||
<button type="submit">Header speichern</button>
|
||
</form>
|
||
|
||
{% for section in page.sections %}
|
||
<div class="admin-section">
|
||
<div class="section-head">
|
||
<form method="post" action="{{ url_for('rename_section', page_key=page_key, section_id=section.id) }}" class="inline">
|
||
<input type="text" name="name" value="{{ section.name }}">
|
||
<button type="submit">Umbenennen</button>
|
||
</form>
|
||
<form method="post" action="{{ url_for('delete_section', page_key=page_key, section_id=section.id) }}" onsubmit="return confirm('Section \'{{ section.name }}\' inkl. aller Links wirklich löschen?');">
|
||
<button type="submit" class="btn-danger">Section löschen</button>
|
||
</form>
|
||
</div>
|
||
|
||
{% for link in section.links %}
|
||
<div class="admin-link-row">
|
||
<form method="post" action="{{ url_for('edit_link', page_key=page_key, link_id=link.id) }}" class="edit-form">
|
||
<input class="field-title" type="text" name="title" value="{{ link.title }}">
|
||
<input class="field-note" type="text" name="note" value="{{ link.note or '' }}" placeholder="Notiz">
|
||
<input class="field-url" type="url" name="url" value="{{ link.url }}">
|
||
<select name="color">
|
||
{% for c in colors %}
|
||
<option value="{{ c }}" {% if link.color == c %}selected{% endif %}>{{ c }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
<label class="checkbox"><input type="checkbox" name="half" {% if link.half %}checked{% endif %}> nebeneinander</label>
|
||
<div class="link-actions">
|
||
<button type="submit">Speichern</button>
|
||
</div>
|
||
</form>
|
||
<div class="link-actions">
|
||
<form method="post" action="{{ url_for('move_link', page_key=page_key, link_id=link.id) }}" class="inline">
|
||
<input type="hidden" name="direction" value="up">
|
||
<button type="submit" title="nach oben">↑</button>
|
||
</form>
|
||
<form method="post" action="{{ url_for('move_link', page_key=page_key, link_id=link.id) }}" class="inline">
|
||
<input type="hidden" name="direction" value="down">
|
||
<button type="submit" title="nach unten">↓</button>
|
||
</form>
|
||
<form method="post" action="{{ url_for('delete_link', page_key=page_key, link_id=link.id) }}" class="inline" onsubmit="return confirm('Link \'{{ link.title }}\' wirklich löschen?');">
|
||
<button type="submit" class="btn-danger">Löschen</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
|
||
<form method="post" action="{{ url_for('add_link', page_key=page_key, section_id=section.id) }}" class="new-form" style="display: flex; gap: 8px; flex-wrap: wrap; align-items: center;">
|
||
<input class="field-title" type="text" name="title" placeholder="Titel" required>
|
||
<input class="field-note" type="text" name="note" placeholder="Notiz (optional)">
|
||
<input class="field-url" type="url" name="url" placeholder="https://..." required>
|
||
<select name="color">
|
||
{% for c in colors %}
|
||
<option value="{{ c }}">{{ c }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
<label class="checkbox"><input type="checkbox" name="half"> nebeneinander (halbe Breite)</label>
|
||
<button type="submit">+ Link hinzufügen</button>
|
||
</form>
|
||
</div>
|
||
{% endfor %}
|
||
|
||
<form method="post" action="{{ url_for('add_section', page_key=page_key) }}" style="margin-top: 12px; display: flex; gap: 8px;">
|
||
<input type="text" name="name" placeholder="Neue Section" required>
|
||
<button type="submit">+ Section hinzufügen</button>
|
||
</form>
|
||
</div>
|
||
{% endfor %}
|
||
</body>
|
||
</html>
|