351 lines
11 KiB
HTML
351 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
|
||
<head>
|
||
|
||
<meta charset="UTF-8">
|
||
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1.0"
|
||
>
|
||
|
||
<title>Pingu Concerts</title>
|
||
|
||
<link
|
||
rel="stylesheet"
|
||
href="/static/style.css"
|
||
>
|
||
|
||
<style>
|
||
|
||
.page-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 20px;
|
||
margin-bottom: 35px;
|
||
}
|
||
|
||
.page-header h1 {
|
||
margin: 0;
|
||
font-size: 2.5rem;
|
||
}
|
||
|
||
.subtitle {
|
||
color: #8b949e;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
.new-concert-button {
|
||
display: inline-block;
|
||
padding: 12px 18px;
|
||
background: #238636;
|
||
color: white;
|
||
text-decoration: none;
|
||
border-radius: 10px;
|
||
font-weight: bold;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.new-concert-button:hover {
|
||
background: #2ea043;
|
||
}
|
||
|
||
.header-actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
align-items: center;
|
||
}
|
||
|
||
.admin-button {
|
||
display: inline-block;
|
||
padding: 12px 18px;
|
||
border: 1px solid #30363d;
|
||
border-radius: 10px;
|
||
color: #b8c1cc;
|
||
text-decoration: none;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.admin-button:hover {
|
||
color: #ffffff;
|
||
border-color: #58a6ff;
|
||
}
|
||
|
||
.concert-list {
|
||
display: grid;
|
||
gap: 15px;
|
||
}
|
||
|
||
.event-group { display: grid; gap: 8px; }
|
||
|
||
.linked-events {
|
||
display: grid;
|
||
gap: 7px;
|
||
margin-left: 30px;
|
||
}
|
||
|
||
.concert-card.linked-event {
|
||
padding: 14px 18px;
|
||
border-left: 3px solid #a78bfa;
|
||
background: #121720;
|
||
}
|
||
|
||
.linked-event .concert-artist { font-size: 1.05rem; margin-bottom: 5px; }
|
||
.linked-event .concert-meta { font-size: .9rem; }
|
||
|
||
.event-category {
|
||
display: inline-block;
|
||
margin-bottom: 7px;
|
||
color: #aab4c3;
|
||
font-size: .78rem;
|
||
font-weight: 700;
|
||
letter-spacing: .04em;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.past-concerts-title {
|
||
margin: 28px 0 0;
|
||
}
|
||
|
||
.concert-card {
|
||
display: block;
|
||
padding: 22px;
|
||
background: #161b22;
|
||
border: 1px solid #30363d;
|
||
border-radius: 14px;
|
||
text-decoration: none;
|
||
transition:
|
||
transform 0.15s ease,
|
||
border-color 0.15s ease,
|
||
background 0.15s ease;
|
||
}
|
||
|
||
.concert-card:hover {
|
||
transform: translateY(-2px);
|
||
border-color: #58a6ff;
|
||
background: #1b222c;
|
||
}
|
||
|
||
.concert-artist {
|
||
font-size: 1.4rem;
|
||
font-weight: bold;
|
||
color: #ffffff;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.concert-meta {
|
||
color: #b8c1cc;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.concert-date {
|
||
color: #58a6ff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.empty-state {
|
||
padding: 40px;
|
||
text-align: center;
|
||
background: #161b22;
|
||
border: 1px dashed #30363d;
|
||
border-radius: 14px;
|
||
color: #8b949e;
|
||
}
|
||
|
||
.search-panel { margin-bottom: 26px; padding: 16px; background: rgba(16,16,16,.92); border: 1px solid #3a3030; border-radius: 14px; }
|
||
.search-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; }
|
||
.search-form input { margin: 0; }
|
||
.search-results-title { margin: 24px 0 12px; font-size: 1.15rem; }
|
||
.user-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; margin-bottom: 24px; }
|
||
.user-result { display: flex; align-items: center; gap: 11px; padding: 12px; background: #101010; border: 1px solid #3a3030; border-radius: 11px; }
|
||
.user-result:hover { border-color: #dc2626; }
|
||
.user-result-avatar { width: 44px; height: 44px; flex: 0 0 44px; object-fit: cover; border-radius: 50%; background: #292524; display: grid; place-items: center; font-weight: 800; }
|
||
.user-result-name { min-width: 0; }
|
||
.user-result-name strong, .user-result-name span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||
.user-result-name span { color: #a8a29e; font-size: .86rem; }
|
||
|
||
body {
|
||
background: radial-gradient(circle at 50% -20%, #3a0909 0, transparent 34rem), #050505;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.page-header { padding-bottom: 22px; border-bottom: 1px solid #3f2424; }
|
||
.page-header h1 { font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif; letter-spacing: .05em; text-transform: uppercase; text-shadow: 0 2px 18px rgba(185, 28, 28, .45); }
|
||
.new-concert-button { background: #991b1b; border: 1px solid #dc2626; }
|
||
.new-concert-button:hover { background: #b91c1c; }
|
||
.admin-button:hover { border-color: #dc2626; }
|
||
.concert-card { background: linear-gradient(145deg, #101010, #181313); border-color: #3a3030; }
|
||
.concert-card:hover { border-color: #dc2626; background: #1c1212; }
|
||
.concert-date { color: #ef4444; }
|
||
.concert-card.linked-event { border-left-color: #dc2626; background: #0d0d0d; }
|
||
|
||
@media (max-width: 600px) {
|
||
|
||
.page-header {
|
||
align-items: flex-start;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.new-concert-button {
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
|
||
.linked-events { margin-left: 16px; }
|
||
.search-form { grid-template-columns: 1fr; }
|
||
|
||
}
|
||
|
||
</style>
|
||
|
||
</head>
|
||
|
||
{% macro event_card(concert, linked=false) %}
|
||
<a href="/concerts/{{ concert.id }}" class="concert-card{% if linked %} linked-event{% endif %}">
|
||
<span class="event-category">{{ concert.event_type_label }}</span>
|
||
{% if concert.is_invited %}<span class="event-category"> · ✉ Eingeladen</span>{% elif concert.visibility == 'friends' %}<span class="event-category"> · 🔒 Nur Freunde</span>{% elif concert.visibility == 'private' %}<span class="event-category"> · 🔐 Privat</span>{% endif %}
|
||
<div class="concert-artist">
|
||
{% if concert.event_type == 'festival' %}🎪{% elif concert.event_type == 'other' %}🥂{% else %}🎸{% endif %}
|
||
{{ concert.artist }}
|
||
</div>
|
||
<div class="concert-meta">
|
||
<div class="concert-date">
|
||
📅 {{ concert.date }}{% if concert.end_date %} – {{ concert.end_date }}{% else %} um {{ concert.time }} Uhr{% endif %}
|
||
</div>
|
||
<div>📍 {{ concert.venue }}</div>
|
||
</div>
|
||
</a>
|
||
{% endmacro %}
|
||
|
||
|
||
<body>
|
||
|
||
<div class="container">
|
||
|
||
<header class="page-header">
|
||
|
||
<div>
|
||
|
||
<h1>
|
||
{% if archive %}☠ Vergangene Veranstaltungen{% else %}🐧 Pingu Concerts{% endif %}
|
||
</h1>
|
||
|
||
<div class="subtitle">
|
||
{% if archive %}Das Archiv vergangener Nächte{% else %}Konzerte, Festivals und alles davor{% endif %}
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="header-actions">
|
||
|
||
<a href="{% if archive %}/{% else %}/events/past{% endif %}" class="admin-button">
|
||
{% if archive %}⚡ Bevorstehend{% else %}☠ Vergangene{% endif %}
|
||
</a>
|
||
|
||
{% if user.is_admin %}
|
||
|
||
<a href="/admin" class="admin-button">
|
||
⚙️ Verwaltung
|
||
</a>
|
||
|
||
{% endif %}
|
||
|
||
<a
|
||
href="/concerts/new"
|
||
class="new-concert-button"
|
||
>
|
||
+ Veranstaltung hinzufügen
|
||
</a>
|
||
|
||
{% include '_user_menu.html' %}
|
||
|
||
</div>
|
||
|
||
</header>
|
||
|
||
<section class="search-panel" aria-label="Suche">
|
||
<form class="search-form" method="get" action="{% if archive %}/events/past{% else %}/{% endif %}">
|
||
<input type="search" name="q" value="{{ search_query }}" placeholder="Veranstaltungen, Orte oder User suchen …" aria-label="Veranstaltungen oder User suchen">
|
||
<button class="new-concert-button" type="submit">Suchen</button>
|
||
</form>
|
||
</section>
|
||
|
||
{% if search_query %}
|
||
<h2 class="search-results-title">User zu „{{ search_query }}“</h2>
|
||
{% if user_results %}
|
||
<div class="user-results">
|
||
{% for result in user_results %}
|
||
<a class="user-result" href="/users/{{ result.username }}">
|
||
{% if result.avatar_path %}<img class="user-result-avatar" src="{{ result.avatar_path }}" alt="">{% else %}<span class="user-result-avatar">{{ result.display_name[:1] }}</span>{% endif %}
|
||
<span class="user-result-name"><strong>{{ result.display_name }}</strong><span>@{{ result.username }}</span></span>
|
||
</a>
|
||
{% endfor %}
|
||
</div>
|
||
{% else %}<p class="subtitle">Keine passenden User gefunden.</p>{% endif %}
|
||
<h2 class="search-results-title">Veranstaltungen zu „{{ search_query }}“</h2>
|
||
{% endif %}
|
||
|
||
|
||
{% if upcoming_concerts or past_concerts %}
|
||
|
||
<div class="concert-list" id="event-invitations">
|
||
|
||
{% for concert in upcoming_concerts %}
|
||
<div class="event-group">
|
||
{{ event_card(concert) }}
|
||
{% if concert.children %}
|
||
<div class="linked-events">
|
||
{% for child in concert.children %}{{ event_card(child, true) }}{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% endfor %}
|
||
|
||
{% if archive and past_concerts %}
|
||
|
||
<h2 class="past-concerts-title">
|
||
Archiv
|
||
</h2>
|
||
|
||
{% for concert in past_concerts %}
|
||
<div class="event-group">
|
||
{{ event_card(concert) }}
|
||
{% if concert.children %}
|
||
<div class="linked-events">
|
||
{% for child in concert.children %}{{ event_card(child, true) }}{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% endfor %}
|
||
|
||
{% endif %}
|
||
|
||
</div>
|
||
|
||
{% else %}
|
||
|
||
<div class="empty-state">
|
||
|
||
<h2>
|
||
{% if archive %}Noch keine vergangenen Veranstaltungen ☠{% else %}Noch keine Veranstaltungen 🎸{% endif %}
|
||
</h2>
|
||
|
||
<p>
|
||
{% if archive %}Hier erscheinen abgeschlossene Veranstaltungen.{% else %}Leg die erste Veranstaltung an!{% endif %}
|
||
</p>
|
||
|
||
</div>
|
||
|
||
{% endif %}
|
||
|
||
</div>
|
||
|
||
</body>
|
||
|
||
</html>
|