Änderungen am TAgebuch
This commit is contained in:
@@ -1,15 +1,29 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div v-if="isAuthenticated" class="navigation">
|
||||
Verein:
|
||||
<select v-model="selectedClub">
|
||||
<option value="">---</option>
|
||||
<option value="new">Neuer Verein</option>
|
||||
<option v-for="club in clubs" :key="club.id" :value="club.id">{{ club.name }}</option>
|
||||
</select>
|
||||
<button @click="loadClub">-></button>
|
||||
<div>
|
||||
Verein:
|
||||
<select v-model="selectedClub">
|
||||
<option value="">---</option>
|
||||
<option value="new">Neuer Verein</option>
|
||||
<option v-for="club in clubs" :key="club.id" :value="club.id">{{ club.name }}</option>
|
||||
</select>
|
||||
<button @click="loadClub">-></button>
|
||||
</div>
|
||||
<template v-if="selectedClub">
|
||||
<a href="/members">Mitglieder</a>
|
||||
<a href="/diary">Tagebuch</a>
|
||||
<button>Freigaben</button>
|
||||
</template>
|
||||
<div>
|
||||
<button @click="logout()">Ausloggen</button>
|
||||
</div>
|
||||
</div>
|
||||
<router-view></router-view>
|
||||
<div v-else class="navigation">
|
||||
<a href="/login">Einloggen</a>
|
||||
<a href="/register">Registrieren</a>
|
||||
</div>
|
||||
<router-view class="content"></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -40,7 +54,7 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['setCurrentClub', 'setClubs']),
|
||||
...mapActions(['setCurrentClub', 'setClubs', 'logout']),
|
||||
loadClub() {
|
||||
this.setCurrentClub(this.currentClub);
|
||||
this.$router.push(`/showclub/${this.currentClub}`);
|
||||
@@ -61,13 +75,14 @@ export default {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
.navigation {
|
||||
width: 10em;
|
||||
background-color: #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
router-view {
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,6 +5,8 @@ import Activate from './views/Activate.vue';
|
||||
import Home from './views/Home.vue';
|
||||
import CreateClub from './views/CreateClub.vue';
|
||||
import ClubView from './views/ClubView.vue';
|
||||
import MembersView from './views/MembersView.vue';
|
||||
import DiaryView from './views/DiaryView.vue';
|
||||
|
||||
const routes = [
|
||||
{ path: '/register', component: Register },
|
||||
@@ -13,6 +15,8 @@ const routes = [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/createclub', component: CreateClub },
|
||||
{ path: '/showclub/:1', component: ClubView },
|
||||
{ path: '/members', component: MembersView },
|
||||
{ path: '/diary', component: DiaryView },
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -44,6 +44,7 @@ const store = createStore({
|
||||
logout({ commit }) {
|
||||
commit('clearToken');
|
||||
commit('clearUsername');
|
||||
router.push("/");
|
||||
},
|
||||
setCurrentClub({ commit }, club) {
|
||||
console.log('action', club);
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
</div>
|
||||
<div>
|
||||
<h3>Mitglieder</h3>
|
||||
<!-- Hier könntest du die Mitglieder anzeigen -->
|
||||
<ul>
|
||||
<li v-for="member in club.members" :key="member.id">{{ member.lastName }}, {{ member.firstName }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Trainingstagebuch</h3>
|
||||
@@ -78,4 +80,10 @@ export default {
|
||||
h2 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
158
frontend/src/views/DiaryView.vue
Normal file
158
frontend/src/views/DiaryView.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Trainingstagebuch</h2>
|
||||
<div>
|
||||
<label>Datum:
|
||||
<select v-model="date" @change="handleDateChange">
|
||||
<option value="new">Neu anlegen</option>
|
||||
<option v-for="date in dates" :key="date" :value="date">{{ date }}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div v-if="showForm && date === 'new'">
|
||||
<h3>Neues Datum anlegen</h3>
|
||||
<form @submit.prevent="createDate">
|
||||
<div>
|
||||
<label for="newDate">Datum:</label>
|
||||
<input type="date" id="newDate" v-model="newDate" required />
|
||||
<button type="button" @click="setCurrentDate">Heute</button>
|
||||
</div>
|
||||
<div>
|
||||
<label for="trainingStart">Trainingsbeginn:</label>
|
||||
<input type="time" id="trainingStart" v-model="trainingStart" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="trainingEnd">Trainingsende:</label>
|
||||
<input type="time" id="trainingEnd" v-model="trainingEnd" />
|
||||
</div>
|
||||
<button type="submit">Datum anlegen</button>
|
||||
</form>
|
||||
</div>
|
||||
<div v-if="!showForm && date !== null && date !== 'new'">
|
||||
<h3>Trainingszeiten bearbeiten</h3>
|
||||
<form @submit.prevent="updateTrainingTimes">
|
||||
<div>
|
||||
<label for="editTrainingStart">Trainingsbeginn:</label>
|
||||
<input type="time" id="editTrainingStart" v-model="trainingStart" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="editTrainingEnd">Trainingsende:</label>
|
||||
<input type="time" id="editTrainingEnd" v-model="trainingEnd" />
|
||||
</div>
|
||||
<button type="submit">Zeiten aktualisieren</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import apiClient from '../apiClient.js';
|
||||
|
||||
export default {
|
||||
name: 'DiaryView',
|
||||
data() {
|
||||
return {
|
||||
date: null,
|
||||
dates: [],
|
||||
showForm: false,
|
||||
newDate: '',
|
||||
trainingStart: '',
|
||||
trainingEnd: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isAuthenticated', 'currentClub']),
|
||||
},
|
||||
methods: {
|
||||
async init() {
|
||||
if (this.isAuthenticated && this.currentClub) {
|
||||
const response = await apiClient.get(`/diary/${this.currentClub}`);
|
||||
this.dates = response.data.map(entry => entry.date);
|
||||
}
|
||||
},
|
||||
async handleDateChange() {
|
||||
this.showForm = this.date === 'new';
|
||||
if (this.date && this.date !== 'new') {
|
||||
const selectedDate = this.dates.find(d => d === this.date);
|
||||
if (selectedDate) {
|
||||
const response = await apiClient.get(`/diary/${this.currentClub}`);
|
||||
const dateData = response.data.find(entry => entry.date === this.date);
|
||||
this.trainingStart = dateData.trainingStart;
|
||||
this.trainingEnd = dateData.trainingEnd;
|
||||
}
|
||||
} else {
|
||||
this.newDate = '';
|
||||
this.trainingStart = '';
|
||||
this.trainingEnd = '';
|
||||
}
|
||||
},
|
||||
setCurrentDate() {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
this.newDate = today;
|
||||
},
|
||||
async createDate() {
|
||||
try {
|
||||
const response = await apiClient.post(`/diary/${this.currentClub}`, {
|
||||
date: this.newDate,
|
||||
trainingStart: this.trainingStart || null,
|
||||
trainingEnd: this.trainingEnd || null,
|
||||
});
|
||||
this.dates.push(response.data.date);
|
||||
this.date = response.data.date;
|
||||
this.showForm = false;
|
||||
this.newDate = '';
|
||||
this.trainingStart = '';
|
||||
this.trainingEnd = '';
|
||||
console.log(this.date);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Erstellen des Datums:', error);
|
||||
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
|
||||
}
|
||||
},
|
||||
async updateTrainingTimes() {
|
||||
try {
|
||||
const response = await apiClient.put(`/diary/${this.currentClub}`, {
|
||||
date: this.date,
|
||||
trainingStart: this.trainingStart || null,
|
||||
trainingEnd: this.trainingEnd || null,
|
||||
});
|
||||
|
||||
alert('Trainingszeiten erfolgreich aktualisiert.');
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Aktualisieren der Trainingszeiten:', error);
|
||||
alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
|
||||
}
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
await this.init();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
form {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
form div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button[type="button"] {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
</style>
|
||||
175
frontend/src/views/MembersView.vue
Normal file
175
frontend/src/views/MembersView.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Mitglieder</h2>
|
||||
<div class="newmember">
|
||||
<div class="toggle-new-member"><span @click="toggleNewMember"><span class="add">{{ memberFormIsOpen ? '-' :
|
||||
'+' }}</span>{{ memberToEdit === null ? "Neues Mitglied" : "Mitglied bearbeiten" }}</span>
|
||||
<button v-if="memberToEdit !== null" @click="resetToNewMember">Neues Mitglied anlegen</button></div>
|
||||
<div v-if="memberFormIsOpen" class="new-member-form">
|
||||
<label><span>Vorname:</span> <input type="text" v-model="newFirstname"></label>
|
||||
<label><span>Nachname:</span> <input type="text" v-model="newLastname"></label>
|
||||
<label><span>Straße:</span> <input type="text" v-model="newStreet"></label>
|
||||
<label><span>Ort:</span> <input type="text" v-model="newCity"></label>
|
||||
<label><span>Geburtsdatum:</span> <input type="date" v-model="newBirthdate"></label>
|
||||
<label><span>Telefon-Nr.:</span> <input type="text" v-model="newPhone"></label>
|
||||
<label><span>Email-Adresse:</span> <input type="email" v-model="newEmail"></label>
|
||||
<div>
|
||||
<button @click="addNewMember">Anlegen</button>
|
||||
<button @click="resetNewMember" v-if="memberToEdit === null">Felder leeren</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name, Vorname</th>
|
||||
<th>Adresse</th>
|
||||
<th>Geburtsdatum</th>
|
||||
<th>Telefon-Nr.</th>
|
||||
<th>Email-Adresse</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="member in members" :key="member.id" @click="editMember(member)">
|
||||
<td>{{ member.lastName }}, {{ member.firstName }}</td>
|
||||
<td>{{ member.street }}, {{ member.city }}</td>
|
||||
<td>{{ member.birthDate }}</td>
|
||||
<td>{{ member.phone }}</td>
|
||||
<td>{{ member.email }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import apiClient from '../apiClient.js';
|
||||
|
||||
export default {
|
||||
name: 'MembersView',
|
||||
computed: {
|
||||
...mapGetters(['isAuthenticated', 'currentClub']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
members: [],
|
||||
memberFormIsOpen: false,
|
||||
newFirstname: '',
|
||||
newLastname: '',
|
||||
newStreet: '',
|
||||
newCity: '',
|
||||
newBirthdate: '01.01.2010',
|
||||
newEmail: '',
|
||||
memberToEdit: null
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.init();
|
||||
},
|
||||
methods: {
|
||||
async init() {
|
||||
const response = await apiClient.get(`/clubmembers/${this.currentClub}`);
|
||||
this.members = response.data;
|
||||
},
|
||||
toggleNewMember() {
|
||||
this.memberFormIsOpen = !this.memberFormIsOpen;
|
||||
},
|
||||
resetNewMember() {
|
||||
this.newFirstname = '';
|
||||
this.newLastname = '';
|
||||
this.newStreet = '';
|
||||
this.newCity = '';
|
||||
this.newBirthdate = '01.01.2010';
|
||||
this.newPhone = '';
|
||||
this.newEmail = '';
|
||||
},
|
||||
async addNewMember() {
|
||||
const response = await apiClient.post(`/clubmembers/${this.currentClub}`, {
|
||||
firstname: this.newFirstname,
|
||||
lastname: this.newLastname,
|
||||
street: this.newStreet,
|
||||
city: this.newCity,
|
||||
birthdate: this.newBirthdate,
|
||||
phone: this.newPhone,
|
||||
email: this.newEmail,
|
||||
id: this.memberToEdit ? this.memberToEdit.id : null,
|
||||
});
|
||||
this.members = response.data;
|
||||
this.resetNewMember();
|
||||
this.memberFormIsOpen = false;
|
||||
},
|
||||
async editMember(member) {
|
||||
this.memberToEdit = member;
|
||||
this.memberFormIsOpen = true;
|
||||
this.newFirstname = member.firstName;
|
||||
this.newLastname = member.lastName;
|
||||
this.newStreet = member.street;
|
||||
this.newCity = member.city;
|
||||
this.newPhone = member.phone;
|
||||
this.newEmail = member.email;
|
||||
},
|
||||
resetToNewMember() {
|
||||
this.memberToEdit = null;
|
||||
this.newFirstname = '';
|
||||
this.newLastname = '';
|
||||
this.newStreet = '';
|
||||
this.newCity = '';
|
||||
this.newBirthdate = '01.01.2010';
|
||||
this.newPhone = '';
|
||||
this.newEmail = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
thead > tr> th {
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
table td {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle-new-member {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.add {
|
||||
border: 1px solid #999;
|
||||
margin: 0 6px 4px 0;
|
||||
border-radius: 50%;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
display: inline-block;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
box-shadow: 2px 2px 2px #bbb;
|
||||
}
|
||||
|
||||
.newmember {
|
||||
border: 1px solid #999;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
.new-member-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.new-member-form > label > span {
|
||||
width: 10em;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user