Fügt die Funktionalität zur Aktualisierung des Teilnehmerstatus in officialTournamentController.js hinzu. Implementiert die Route zum Aktualisieren des Status eines Teilnehmers in officialTournamentRoutes.js und passt die Benutzeroberfläche in OfficialTournaments.vue an, um den neuen Status anzuzeigen und Aktionen wie Anmelden, Teilnehmen und Zurücksetzen zu ermöglichen.
This commit is contained in:
@@ -163,8 +163,8 @@
|
||||
<th>Mitglied</th>
|
||||
<th>Konkurrenz</th>
|
||||
<th>Startzeit</th>
|
||||
<th>Angemeldet</th>
|
||||
<th>Teilgenommen</th>
|
||||
<th>Status</th>
|
||||
<th>Aktion</th>
|
||||
<th>Platzierung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -175,9 +175,53 @@
|
||||
<td v-if="idx === 0" :rowspan="group.items.length" class="member-cell">{{ group.memberName }}</td>
|
||||
<td class="indented">{{ item.competitionName }}</td>
|
||||
<td>{{ item.start }}</td>
|
||||
<td>{{ item.registered ? 'Ja' : 'Nein' }}</td>
|
||||
<td>{{ item.participated ? 'Ja' : 'Nein' }}</td>
|
||||
<td>{{ item.placement || '–' }}</td>
|
||||
<td class="status-cell">
|
||||
<span v-if="item.participated" class="status-badge status-played">Hat gespielt</span>
|
||||
<span v-else-if="item.registered" class="status-badge status-registered">Angemeldet</span>
|
||||
<span v-else-if="item.wants" class="status-badge status-wants">Möchte teilnehmen</span>
|
||||
<span v-else class="status-badge status-none">Nicht interessiert</span>
|
||||
</td>
|
||||
<td class="action-cell">
|
||||
<button
|
||||
v-if="!item.participated && !item.registered && item.wants"
|
||||
@click="updateStatus(item, 'register')"
|
||||
class="btn-status btn-register"
|
||||
title="Als angemeldet markieren">
|
||||
Anmelden
|
||||
</button>
|
||||
<button
|
||||
v-else-if="item.registered && !item.participated"
|
||||
@click="updateStatus(item, 'participate')"
|
||||
class="btn-status btn-participate"
|
||||
title="Als teilgenommen markieren">
|
||||
Teilgenommen
|
||||
</button>
|
||||
<button
|
||||
v-else-if="item.participated"
|
||||
@click="updateStatus(item, 'reset')"
|
||||
class="btn-status btn-reset"
|
||||
title="Status zurücksetzen">
|
||||
Zurücksetzen
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
@click="updateStatus(item, 'register')"
|
||||
class="btn-status btn-register"
|
||||
title="Teilnahme anmelden">
|
||||
Anmelden
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
v-if="item.participated"
|
||||
type="text"
|
||||
:value="item.placement || ''"
|
||||
@change="updatePlacement(item, $event.target.value)"
|
||||
placeholder="z.B. 3. Platz"
|
||||
class="placement-input"
|
||||
/>
|
||||
<span v-else>{{ item.placement || '–' }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</template>
|
||||
@@ -756,6 +800,43 @@ export default {
|
||||
this.getParticipation(c.id, m.id).placement = v || null;
|
||||
this.saveParticipation(c.id, m.id);
|
||||
},
|
||||
async updateStatus(item, action) {
|
||||
try {
|
||||
const [competitionId, memberId] = item.key.split('-');
|
||||
const response = await apiClient.post(`/official-tournaments/${this.currentClub}/${this.uploadedId}/status`, {
|
||||
competitionId: parseInt(competitionId),
|
||||
memberId: parseInt(memberId),
|
||||
action: action
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
// Aktualisiere den lokalen Status
|
||||
const key = `${competitionId}-${memberId}`;
|
||||
const participation = this.getParticipation(competitionId, memberId);
|
||||
participation.wants = response.data.status.wants;
|
||||
participation.registered = response.data.status.registered;
|
||||
participation.participated = response.data.status.participated;
|
||||
participation.placement = response.data.status.placement;
|
||||
|
||||
// Aktualisiere auch die participationMap
|
||||
this.participationMap[key] = participation;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Aktualisieren des Status:', error);
|
||||
alert('Fehler beim Aktualisieren des Status: ' + (error.response?.data?.error || error.message));
|
||||
}
|
||||
},
|
||||
async updatePlacement(item, value) {
|
||||
try {
|
||||
const [competitionId, memberId] = item.key.split('-');
|
||||
const participation = this.getParticipation(competitionId, memberId);
|
||||
participation.placement = value.trim() || null;
|
||||
await this.saveParticipation(competitionId, memberId);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Aktualisieren der Platzierung:', error);
|
||||
alert('Fehler beim Aktualisieren der Platzierung: ' + (error.response?.data?.error || error.message));
|
||||
}
|
||||
},
|
||||
// Auswahl Helfer + PDF-Generierung
|
||||
openMemberDialog() { this.showMemberDialog = true; },
|
||||
closeMemberDialog() { this.showMemberDialog = false; },
|
||||
@@ -1024,6 +1105,112 @@ th, td { border-bottom: 1px solid var(--border-color); padding: 0.5rem; text-ali
|
||||
.dialog-col h4 { margin: 0 0 .5rem 0; }
|
||||
.members-col .check-item span.active { font-weight: bold; }
|
||||
.recommendations-col .check-item { padding: .15rem 0; }
|
||||
|
||||
/* Status Management Styles */
|
||||
.status-cell {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.status-badge.status-played {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
|
||||
.status-badge.status-registered {
|
||||
background-color: #d1ecf1;
|
||||
color: #0c5460;
|
||||
border: 1px solid #bee5eb;
|
||||
}
|
||||
|
||||
.status-badge.status-wants {
|
||||
background-color: #fff3cd;
|
||||
color: #856404;
|
||||
border: 1px solid #ffeaa7;
|
||||
}
|
||||
|
||||
.status-badge.status-none {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
||||
.action-cell {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn-status {
|
||||
padding: 0.4rem 0.8rem;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.5s ease;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.btn-status:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.btn-status:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.btn-register {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-register:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.btn-participate {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-participate:hover {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
|
||||
.btn-reset {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-reset:hover {
|
||||
background-color: #545b62;
|
||||
}
|
||||
|
||||
.placement-input {
|
||||
width: 120px;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.placement-input:focus {
|
||||
outline: none;
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0,123,255,0.25);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user