236 lines
5.6 KiB
Vue
236 lines
5.6 KiB
Vue
<script setup>
|
||
|
||
import ShadowedBox from "../../../../Views/Components/ShadowedBox.vue";
|
||
|
||
const props = defineProps({
|
||
events: Array,
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div class="available-events-wrapper">
|
||
|
||
<div v-if="props.events.length === 0" class="available-events-empty">
|
||
Aktuell sind keine Veranstaltungen verfügbar.
|
||
</div>
|
||
|
||
<shadowed-box
|
||
v-for="event in props.events"
|
||
:key="event.id"
|
||
class="available-event-card"
|
||
>
|
||
<div class="available-event-header">
|
||
<div>
|
||
<h2 class="available-event-title">{{ event.name }}</h2>
|
||
<span class="available-event-location">{{ event.postalCode }} {{ event.location }}</span>
|
||
</div>
|
||
<span
|
||
v-if="event.registrationAllowed"
|
||
class="available-event-badge available-event-badge--open"
|
||
>
|
||
Anmeldung offen
|
||
</span>
|
||
<span
|
||
v-else
|
||
class="available-event-badge available-event-badge--closed"
|
||
>
|
||
Anmeldung geschlossen
|
||
</span>
|
||
</div>
|
||
|
||
<hr class="available-event-divider" />
|
||
|
||
<table class="available-event-table">
|
||
<tr>
|
||
<th>Zeitraum</th>
|
||
<td>{{ event.eventBegin }} – {{ event.eventEnd }} ({{ event.duration }} Tage)</td>
|
||
</tr>
|
||
<tr>
|
||
<th>Veranstaltungsort</th>
|
||
<td>{{ event.postalCode }} {{ event.location }}</td>
|
||
</tr>
|
||
<tr>
|
||
<th>Frühbuchen bis</th>
|
||
<td>{{ event.earlyBirdEnd.formatted }}</td>
|
||
</tr>
|
||
<tr>
|
||
<th>Anmeldeschluss</th>
|
||
<td>{{ event.registrationFinalEnd.formatted }}</td>
|
||
</tr>
|
||
<tr v-if="event.email">
|
||
<th>Kontakt</th>
|
||
<td>
|
||
<a :href="'mailto:' + event.email" class="available-event-mail">{{ event.email }}</a>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<div class="available-event-actions">
|
||
<a
|
||
:href="'/event/' + event.identifier + '/signup'"
|
||
class="available-event-button"
|
||
:style="{ opacity: event.registrationAllowed ? '1' : '0.5', pointerEvents: event.registrationAllowed ? 'auto' : 'none' }"
|
||
>
|
||
Zur Anmeldung →
|
||
</a>
|
||
</div>
|
||
</shadowed-box>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.available-events-wrapper {
|
||
width: 95%;
|
||
margin: 20px auto;
|
||
}
|
||
|
||
.available-events-empty {
|
||
text-align: center;
|
||
color: #6b7280;
|
||
padding: 40px 0;
|
||
}
|
||
|
||
.available-event-card {
|
||
padding: 24px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.available-event-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
}
|
||
|
||
.available-event-title {
|
||
margin: 0 0 4px 0;
|
||
font-size: 1.25rem;
|
||
}
|
||
|
||
.available-event-location {
|
||
color: #6b7280;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.available-event-badge {
|
||
padding: 4px 12px;
|
||
border-radius: 999px;
|
||
font-size: 0.8rem;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
}
|
||
.available-event-badge--open { background: #d1fae5; color: #065f46; }
|
||
.available-event-badge--closed { background: #fee2e2; color: #991b1b; }
|
||
|
||
.available-event-divider {
|
||
margin: 16px 0;
|
||
border: none;
|
||
border-top: 1px solid #e5e7eb;
|
||
}
|
||
|
||
.available-event-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
.available-event-table th {
|
||
text-align: left;
|
||
padding: 6px 12px 6px 0;
|
||
width: 220px;
|
||
color: #374151;
|
||
font-weight: 600;
|
||
vertical-align: top;
|
||
}
|
||
|
||
.available-event-table td {
|
||
padding: 6px 0;
|
||
color: #111827;
|
||
word-break: break-word;
|
||
}
|
||
|
||
.available-event-mail {
|
||
color: #2563eb;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.available-event-actions {
|
||
margin-top: 20px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.available-event-button {
|
||
display: inline-block;
|
||
padding: 10px 24px;
|
||
background-color: #2563eb;
|
||
color: white;
|
||
border-radius: 8px;
|
||
text-decoration: none;
|
||
font-weight: 600;
|
||
font-size: 0.95rem;
|
||
transition: background-color 0.2s;
|
||
}
|
||
|
||
/* ─── Tablet ─── */
|
||
@media (max-width: 1023px) {
|
||
.available-events-wrapper {
|
||
width: 100%;
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.available-event-table th {
|
||
width: 160px;
|
||
}
|
||
}
|
||
|
||
/* ─── Smartphone ─── */
|
||
@media (max-width: 639px) {
|
||
.available-event-card {
|
||
padding: 16px;
|
||
margin-bottom: 14px;
|
||
}
|
||
|
||
.available-event-title {
|
||
font-size: 1.05rem;
|
||
}
|
||
|
||
/* Tabelle vertikal stapeln: Label über Wert */
|
||
.available-event-table,
|
||
.available-event-table tbody,
|
||
.available-event-table tr,
|
||
.available-event-table th,
|
||
.available-event-table td {
|
||
display: block;
|
||
width: 100% !important;
|
||
}
|
||
|
||
.available-event-table tr {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.available-event-table th {
|
||
padding: 4px 0 2px 0;
|
||
font-size: 0.78rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.04em;
|
||
color: #6b7280;
|
||
}
|
||
|
||
.available-event-table td {
|
||
padding: 0 0 4px 0;
|
||
}
|
||
|
||
.available-event-actions {
|
||
justify-content: stretch;
|
||
}
|
||
|
||
.available-event-button {
|
||
width: 100%;
|
||
text-align: center;
|
||
padding: 12px 24px;
|
||
}
|
||
}
|
||
</style>
|