359 lines
13 KiB
HTML
359 lines
13 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="{{ language() }}">
|
||
|
||
<head>
|
||
|
||
<meta charset="UTF-8">
|
||
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1.0"
|
||
>
|
||
|
||
<title>MetalCircle</title>
|
||
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
|
||
|
||
<link
|
||
rel="stylesheet"
|
||
href="/static/css/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; align-items:start; }
|
||
.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:
|
||
linear-gradient(rgba(4, 4, 6, .58), rgba(4, 4, 6, .72)),
|
||
url('/static/images/crowd-stage-background.webp') center top / cover fixed no-repeat,
|
||
#050505;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.page-header { padding: 24px; border: 1px solid #5f1515; border-left: 4px solid #dc2626; border-radius: 14px; background: linear-gradient(110deg, rgba(10,10,10,.9), rgba(69,10,10,.28)); box-shadow: 0 12px 30px rgba(0,0,0,.3); }
|
||
.page-header h1 { font-family: "Nimbus Sans Narrow", 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>
|
||
|
||
<link rel="stylesheet" href="/static/css/language.css">
|
||
</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 | t }}</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 %}<img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle">{% endif %}
|
||
</h1>
|
||
|
||
<div class="subtitle">
|
||
<strong>Enter the Pit. Join the Circle.</strong>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="header-actions">
|
||
|
||
<a href="{% if archive %}/{% else %}/events/past{% endif %}" class="admin-button">
|
||
{% if archive %}{{ _('⚡ Bevorstehend') }}{% else %}{{ _('☠ Vergangene') }}{% endif %}
|
||
</a>
|
||
|
||
<a
|
||
href="/concerts/new"
|
||
class="new-concert-button"
|
||
>
|
||
{{ _('+ Veranstaltung hinzufügen') }}
|
||
</a>
|
||
|
||
{% include '_header_controls.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>
|
||
<details class="advanced-filters" {% if filters.date_from or filters.date_to or filters.venue or filters.country or filters.category %}open{% endif %}>
|
||
<summary>{{ _('Weitere Filter') }}{% if filters.date_from or filters.date_to or filters.venue or filters.country or filters.category %} {{ _('· aktiv') }}{% endif %}</summary>
|
||
<div class="advanced-filter-fields">
|
||
<label>{{ _('Von Datum') }}<input type="date" name="date_from" value="{{ filters.date_from }}"></label>
|
||
<label>{{ _('Bis Datum') }}<input type="date" name="date_to" value="{{ filters.date_to }}"></label>
|
||
<label>{{ _('Ort / Location') }}<input type="search" name="venue" value="{{ filters.venue }}" placeholder="{{ _('z. B. Düsseldorf') }}"></label>
|
||
<label>{{ _('Land') }}<input type="search" name="country" value="{{ filters.country }}" placeholder="{{ _('z. B. Deutschland') }}"></label>
|
||
<label>{{ _('Kategorie') }}<select name="category"><option value="">{{ _('Alle Kategorien') }}</option><option value="concert" {% if filters.category == 'concert' %}selected{% endif %}>{{ _('Konzert') }}</option><option value="festival" {% if filters.category == 'festival' %}selected{% endif %}>Festival</option><option value="other" {% if filters.category == 'other' %}selected{% endif %}>{{ _('Sonstiges') }}</option></select></label>
|
||
</div>
|
||
{% if filters.date_from or filters.date_to or filters.venue or filters.country or filters.category %}<a class="clear-filters" href="{% if archive %}/events/past{% else %}/{% endif %}{% if search_query %}?q={{ search_query|urlencode }}{% endif %}">{{ _('Filter löschen') }}</a>{% endif %}
|
||
</details>
|
||
</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>
|