Optimiere das Worship Management-Formular: Entferne redundante Codeabschnitte, verbessere die Benutzeroberfläche durch Anpassungen der Abstände und Padding-Werte, und vereinheitliche die Struktur der Eingabefelder. Füge eine neue Auswahl für das Jahr hinzu, um die liturgischen Daten zu laden.
This commit is contained in:
@@ -1,36 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="worship-management">
|
<div class="worship-management">
|
||||||
<h2>Gottesdienst Verwaltung</h2>
|
<h2>Gottesdienst Verwaltung</h2>
|
||||||
|
<div class="liturgical-loader">
|
||||||
|
<select v-model="selectedYear" class="year-select">
|
||||||
|
<option v-for="year in availableYears" :key="year" :value="year">{{ year }}</option>
|
||||||
|
</select>
|
||||||
|
<button type="button" @click="loadLiturgicalYear" class="load-year-button" :disabled="isLoading">
|
||||||
|
{{ isLoading ? 'Lade...' : 'Kirchenjahr laden' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<form @submit.prevent="saveWorship">
|
<form @submit.prevent="saveWorship">
|
||||||
<label for="eventPlaceId">Veranstaltungsort:</label>
|
<label for="eventPlaceId">Veranstaltungsort:</label>
|
||||||
<multiselect v-model="selectedEventPlace" :options="eventPlaces" label="name" track-by="id"
|
<multiselect v-model="selectedEventPlace" :options="eventPlaces" label="name" track-by="id"
|
||||||
placeholder="Veranstaltungsort wählen"></multiselect>
|
placeholder="Veranstaltungsort wählen"></multiselect>
|
||||||
|
|
||||||
<label for="date">Datum:</label>
|
|
||||||
<input type="date" id="date" v-model="worshipData.date" required @change="updateDayNameFromDate">
|
|
||||||
|
|
||||||
<label for="dayName">Name des Tags:</label>
|
<label for="dayName">Name des Tags:</label>
|
||||||
<div class="liturgical-day-section">
|
<div class="liturgical-day-section">
|
||||||
<multiselect
|
<multiselect v-model="selectedDayName" :options="dayNameOptions" :multiple="false" :taggable="true"
|
||||||
v-model="selectedDayName"
|
@tag="addDayNameTag" placeholder="Tag-Name wählen oder eingeben" label="name" track-by="name">
|
||||||
:options="dayNameOptions"
|
|
||||||
:multiple="false"
|
|
||||||
:taggable="true"
|
|
||||||
@tag="addDayNameTag"
|
|
||||||
placeholder="Tag-Name wählen oder eingeben"
|
|
||||||
label="name"
|
|
||||||
track-by="name">
|
|
||||||
</multiselect>
|
</multiselect>
|
||||||
<div class="liturgical-loader">
|
|
||||||
<select v-model="selectedYear" class="year-select">
|
|
||||||
<option v-for="year in availableYears" :key="year" :value="year">{{ year }}</option>
|
|
||||||
</select>
|
|
||||||
<button type="button" @click="loadLiturgicalYear" class="load-year-button" :disabled="isLoading">
|
|
||||||
{{ isLoading ? 'Lade...' : 'Kirchenjahr laden' }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<label for="date">Datum:</label>
|
||||||
|
<input type="date" id="date" v-model="worshipData.date" required @change="updateDayNameFromDate">
|
||||||
|
|
||||||
<label for="time">Uhrzeit:</label>
|
<label for="time">Uhrzeit:</label>
|
||||||
<input type="time" id="time" v-model="worshipData.time" required>
|
<input type="time" id="time" v-model="worshipData.time" required>
|
||||||
|
|
||||||
@@ -38,27 +31,13 @@
|
|||||||
<input type="text" id="title" v-model="worshipData.title" required>
|
<input type="text" id="title" v-model="worshipData.title" required>
|
||||||
|
|
||||||
<label for="organizer">Gestalter:</label>
|
<label for="organizer">Gestalter:</label>
|
||||||
<multiselect
|
<multiselect v-model="selectedOrganizers" :options="organizerOptions" :multiple="true" :taggable="true"
|
||||||
v-model="selectedOrganizers"
|
@tag="addOrganizerTag" placeholder="Gestalter wählen oder neu eingeben" label="name" track-by="name">
|
||||||
:options="organizerOptions"
|
|
||||||
:multiple="true"
|
|
||||||
:taggable="true"
|
|
||||||
@tag="addOrganizerTag"
|
|
||||||
placeholder="Gestalter wählen oder neu eingeben"
|
|
||||||
label="name"
|
|
||||||
track-by="name">
|
|
||||||
</multiselect>
|
</multiselect>
|
||||||
|
|
||||||
<label for="sacristanService">Küsterdienst:</label>
|
<label for="sacristanService">Küsterdienst:</label>
|
||||||
<multiselect
|
<multiselect v-model="selectedSacristans" :options="sacristanOptions" :multiple="true" :taggable="true"
|
||||||
v-model="selectedSacristans"
|
@tag="addSacristanTag" placeholder="Küsterdienst wählen oder neu eingeben" label="name" track-by="name">
|
||||||
:options="sacristanOptions"
|
|
||||||
:multiple="true"
|
|
||||||
:taggable="true"
|
|
||||||
@tag="addSacristanTag"
|
|
||||||
placeholder="Küsterdienst wählen oder neu eingeben"
|
|
||||||
label="name"
|
|
||||||
track-by="name">
|
|
||||||
</multiselect>
|
</multiselect>
|
||||||
|
|
||||||
<label for="collection">Kollekte:</label>
|
<label for="collection">Kollekte:</label>
|
||||||
@@ -84,17 +63,9 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<input
|
<input v-model="searchDate" type="date" class="search-input" placeholder="Nach Datum suchen..." />
|
||||||
v-model="searchDate"
|
|
||||||
type="date"
|
|
||||||
class="search-input"
|
|
||||||
placeholder="Nach Datum suchen..."
|
|
||||||
/>
|
|
||||||
<label class="checkbox-label">
|
<label class="checkbox-label">
|
||||||
<input
|
<input v-model="showPastWorships" type="checkbox" />
|
||||||
v-model="showPastWorships"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
Vergangene Gottesdienste anzeigen
|
Vergangene Gottesdienste anzeigen
|
||||||
</label>
|
</label>
|
||||||
<button v-if="searchDate" @click="clearSearch" type="button" class="clear-button">
|
<button v-if="searchDate" @click="clearSearch" type="button" class="clear-button">
|
||||||
@@ -103,7 +74,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="worship in filteredWorships" :key="worship.id" :class="dateIsLowerCurrentDate(worship.date) ? 'old-items' : ''">
|
<li v-for="worship in filteredWorships" :key="worship.id"
|
||||||
|
:class="dateIsLowerCurrentDate(worship.date) ? 'old-items' : ''">
|
||||||
<span>{{ worship.title }} - {{ formatDate(worship.date) }}, {{ formatTime(worship.time) }}</span>
|
<span>{{ worship.title }} - {{ formatDate(worship.date) }}, {{ formatTime(worship.time) }}</span>
|
||||||
<button @click="editWorship(worship)">Bearbeiten</button>
|
<button @click="editWorship(worship)">Bearbeiten</button>
|
||||||
<button @click="deleteWorship(worship.id)">Löschen</button>
|
<button @click="deleteWorship(worship.id)">Löschen</button>
|
||||||
@@ -168,7 +140,7 @@ export default {
|
|||||||
if (!this.showPastWorships) {
|
if (!this.showPastWorships) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
today.setHours(0, 0, 0, 0);
|
today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
filtered = filtered.filter(worship => {
|
filtered = filtered.filter(worship => {
|
||||||
if (worship.date) {
|
if (worship.date) {
|
||||||
const worshipDate = new Date(worship.date);
|
const worshipDate = new Date(worship.date);
|
||||||
@@ -183,7 +155,7 @@ export default {
|
|||||||
if (this.searchDate) {
|
if (this.searchDate) {
|
||||||
const searchDateObj = new Date(this.searchDate);
|
const searchDateObj = new Date(this.searchDate);
|
||||||
searchDateObj.setHours(0, 0, 0, 0);
|
searchDateObj.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
filtered = filtered.filter(worship => {
|
filtered = filtered.filter(worship => {
|
||||||
if (worship.date) {
|
if (worship.date) {
|
||||||
const worshipDate = new Date(worship.date);
|
const worshipDate = new Date(worship.date);
|
||||||
@@ -243,20 +215,20 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const response = await axios.get('/liturgical-days');
|
const response = await axios.get('/liturgical-days');
|
||||||
this.liturgicalDays = response.data;
|
this.liturgicalDays = response.data;
|
||||||
|
|
||||||
// Nur zukünftige Tage anzeigen
|
// Nur zukünftige Tage anzeigen
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
today.setHours(0, 0, 0, 0);
|
today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
const futureDays = response.data.filter(day => {
|
const futureDays = response.data.filter(day => {
|
||||||
const dayDate = new Date(day.date);
|
const dayDate = new Date(day.date);
|
||||||
dayDate.setHours(0, 0, 0, 0);
|
dayDate.setHours(0, 0, 0, 0);
|
||||||
return dayDate >= today;
|
return dayDate >= today;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sortiere nach Datum
|
// Sortiere nach Datum
|
||||||
futureDays.sort((a, b) => new Date(a.date) - new Date(b.date));
|
futureDays.sort((a, b) => new Date(a.date) - new Date(b.date));
|
||||||
|
|
||||||
// Erstelle Optionen mit Datum und Name: "30.11.2025 - 1. Advent"
|
// Erstelle Optionen mit Datum und Name: "30.11.2025 - 1. Advent"
|
||||||
this.dayNameOptions = futureDays.map(day => {
|
this.dayNameOptions = futureDays.map(day => {
|
||||||
const date = new Date(day.date);
|
const date = new Date(day.date);
|
||||||
@@ -280,7 +252,7 @@ export default {
|
|||||||
alert('Bitte wählen Sie ein Jahr aus');
|
alert('Bitte wählen Sie ein Jahr aus');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
try {
|
try {
|
||||||
const response = await axios.post('/liturgical-days/load-year', {
|
const response = await axios.post('/liturgical-days/load-year', {
|
||||||
@@ -303,20 +275,20 @@ export default {
|
|||||||
if (!this.worshipData.date) {
|
if (!this.worshipData.date) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setze Flag, um Endlosschleife zu vermeiden
|
// Setze Flag, um Endlosschleife zu vermeiden
|
||||||
this.isUpdatingFromDate = true;
|
this.isUpdatingFromDate = true;
|
||||||
|
|
||||||
// Normalisiere das Datum (HTML input gibt YYYY-MM-DD zurück)
|
// Normalisiere das Datum (HTML input gibt YYYY-MM-DD zurück)
|
||||||
const selectedDate = this.worshipData.date;
|
const selectedDate = this.worshipData.date;
|
||||||
|
|
||||||
// Finde liturgischen Tag für das gewählte Datum
|
// Finde liturgischen Tag für das gewählte Datum
|
||||||
const liturgicalDay = this.liturgicalDays.find(day => {
|
const liturgicalDay = this.liturgicalDays.find(day => {
|
||||||
// Vergleiche nur das Datum (ignoriere mögliche Zeitstempel)
|
// Vergleiche nur das Datum (ignoriere mögliche Zeitstempel)
|
||||||
const dayDate = typeof day.date === 'string' ? day.date : day.date.split('T')[0];
|
const dayDate = typeof day.date === 'string' ? day.date : day.date.split('T')[0];
|
||||||
return dayDate === selectedDate;
|
return dayDate === selectedDate;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (liturgicalDay) {
|
if (liturgicalDay) {
|
||||||
// Finde die passende Option mit formatiertem Datum
|
// Finde die passende Option mit formatiertem Datum
|
||||||
const option = this.dayNameOptions.find(opt => opt.date === selectedDate);
|
const option = this.dayNameOptions.find(opt => opt.date === selectedDate);
|
||||||
@@ -328,7 +300,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
console.log('Kein liturgischer Tag gefunden für:', selectedDate);
|
console.log('Kein liturgischer Tag gefunden für:', selectedDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset Flag nach kurzer Verzögerung
|
// Reset Flag nach kurzer Verzögerung
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.isUpdatingFromDate = false;
|
this.isUpdatingFromDate = false;
|
||||||
@@ -338,7 +310,7 @@ export default {
|
|||||||
if (!this.selectedDayName || !this.selectedDayName.date) {
|
if (!this.selectedDayName || !this.selectedDayName.date) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Das Datum ist bereits in der Option enthalten
|
// Das Datum ist bereits in der Option enthalten
|
||||||
this.worshipData.date = this.selectedDayName.date;
|
this.worshipData.date = this.selectedDayName.date;
|
||||||
this.worshipData.dayName = this.selectedDayName.dayName;
|
this.worshipData.dayName = this.selectedDayName.dayName;
|
||||||
@@ -373,25 +345,25 @@ export default {
|
|||||||
this.worshipData.time = formatTime(worship.time);
|
this.worshipData.time = formatTime(worship.time);
|
||||||
console.log(this.worshipData);
|
console.log(this.worshipData);
|
||||||
this.selectedEventPlace = this.eventPlaces.find(ep => ep.id === worship.eventPlaceId);
|
this.selectedEventPlace = this.eventPlaces.find(ep => ep.id === worship.eventPlaceId);
|
||||||
|
|
||||||
// Konvertiere kommaseparierte Strings zu Arrays für Multiselect
|
// Konvertiere kommaseparierte Strings zu Arrays für Multiselect
|
||||||
this.selectedOrganizers = worship.organizer
|
this.selectedOrganizers = worship.organizer
|
||||||
? worship.organizer.split(',').map(org => ({ name: org.trim() }))
|
? worship.organizer.split(',').map(org => ({ name: org.trim() }))
|
||||||
: [];
|
: [];
|
||||||
this.selectedSacristans = worship.sacristanService
|
this.selectedSacristans = worship.sacristanService
|
||||||
? worship.sacristanService.split(',').map(sac => ({ name: sac.trim() }))
|
? worship.sacristanService.split(',').map(sac => ({ name: sac.trim() }))
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// Setze dayName - finde die passende Option
|
// Setze dayName - finde die passende Option
|
||||||
if (worship.dayName) {
|
if (worship.dayName) {
|
||||||
const option = this.dayNameOptions.find(opt =>
|
const option = this.dayNameOptions.find(opt =>
|
||||||
opt.dayName === worship.dayName && opt.date === this.worshipData.date
|
opt.dayName === worship.dayName && opt.date === this.worshipData.date
|
||||||
);
|
);
|
||||||
this.selectedDayName = option || null;
|
this.selectedDayName = option || null;
|
||||||
} else {
|
} else {
|
||||||
this.selectedDayName = null;
|
this.selectedDayName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editMode = true;
|
this.editMode = true;
|
||||||
this.editId = worship.id;
|
this.editId = worship.id;
|
||||||
},
|
},
|
||||||
@@ -449,7 +421,7 @@ export default {
|
|||||||
},
|
},
|
||||||
addDayNameTag(newTag) {
|
addDayNameTag(newTag) {
|
||||||
// Wenn manuell ein Tag eingegeben wird, ohne Datum
|
// Wenn manuell ein Tag eingegeben wird, ohne Datum
|
||||||
const tag = {
|
const tag = {
|
||||||
name: newTag,
|
name: newTag,
|
||||||
dayName: newTag,
|
dayName: newTag,
|
||||||
date: this.worshipData.date || null
|
date: this.worshipData.date || null
|
||||||
@@ -475,35 +447,41 @@ export default {
|
|||||||
form {
|
form {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 180px 1fr;
|
grid-template-columns: 180px 1fr;
|
||||||
gap: 15px 20px;
|
gap: 8px 20px;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
form > label {
|
form>label {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-top: 8px;
|
padding-top: 6px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
form > input[type="text"],
|
form>input[type="text"],
|
||||||
form > input[type="date"],
|
form>input[type="date"],
|
||||||
form > input[type="time"],
|
form>input[type="time"] {
|
||||||
form > .multiselect,
|
width: 100%;
|
||||||
form > .liturgical-day-section {
|
max-width: 500px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form>.multiselect,
|
||||||
|
form>.liturgical-day-section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form > input[type="checkbox"] {
|
form>input[type="checkbox"] {
|
||||||
justify-self: start;
|
justify-self: start;
|
||||||
margin-top: 8px;
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
form > button {
|
form>button {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
justify-self: start;
|
justify-self: start;
|
||||||
margin-top: 10px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-section {
|
.filter-section {
|
||||||
@@ -563,18 +541,18 @@ form > button {
|
|||||||
.liturgical-day-section {
|
.liturgical-day-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 6px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.liturgical-loader {
|
.liturgical-loader {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.year-select {
|
.year-select {
|
||||||
padding: 8px 12px;
|
padding: 6px 10px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -588,7 +566,7 @@ form > button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.load-year-button {
|
.load-year-button {
|
||||||
padding: 8px 16px;
|
padding: 6px 12px;
|
||||||
background-color: #2196F3;
|
background-color: #2196F3;
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -596,6 +574,7 @@ form > button {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-year-button:hover:not(:disabled) {
|
.load-year-button:hover:not(:disabled) {
|
||||||
@@ -647,7 +626,7 @@ li:hover .tooltip {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
li > span {
|
li>span {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user