First steps for tournament

This commit is contained in:
Torsten Schulz
2025-03-13 16:19:07 +01:00
parent df41720b50
commit 821f9d24f5
5 changed files with 111 additions and 16 deletions

View File

@@ -121,13 +121,26 @@ export const getTournamentMatches = async (req, res) => {
export const addMatchResult = async (req, res) => {
const { authcode: token } = req.headers;
const { clubId, tournamentId, matchId, result } = req.body;
const { clubId, tournamentId, matchId, set, result } = req.body;
try {
await tournamentService.addMatchResult(token, clubId, tournamentId, matchId, result);
await tournamentService.addMatchResult(token, clubId, tournamentId, matchId, set, result);
res.status(200).json({ message: "Result added successfully" });
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message });
}
};
export const finishMatch = async (req, res) => {
const { authcode: token } = req.headers;
const { clubId, tournamentId, matchId } = req.body;
try {
await tournamentService.finishMatch(token, clubId, tournamentId, matchId);
res.status(200).json({ message: "Match finished successfully" });
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message });
}
}

View File

@@ -22,6 +22,15 @@ const TournamentMatch = sequelize.define('TournamentMatch', {
type: DataTypes.INTEGER,
allowNull: false,
},
isFinished: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
result: {
type: DataTypes.STRING,
allowNull: true,
},
}, {
underscored: true,
tableName: 'tournament_match',

View File

@@ -11,6 +11,7 @@ import {
getTournament,
getTournamentMatches,
addMatchResult,
finishMatch,
} from '../controllers/tournamentController.js';
import { authenticate } from '../middleware/authMiddleware.js';
@@ -23,6 +24,7 @@ router.put('/groups', authenticate, createGroups);
router.post('/groups', authenticate, fillGroups);
router.get('/groups', authenticate, getGroups);
router.post('/match/result', authenticate, addMatchResult);
router.post('/match/finish', authenticate, finishMatch);
router.get('/matches/:clubId/:tournamentId', authenticate, getTournamentMatches);
router.get('/:clubId/:tournamentId', authenticate, getTournament);
router.get('/:clubId', authenticate, getTournaments);

View File

@@ -4,6 +4,7 @@ import Tournament from "../models/Tournament.js";
import TournamentGroup from "../models/TournamentGroup.js";
import TournamentMatch from "../models/TournamentMatch.js";
import TournamentMember from "../models/TournamentMember.js";
import TournamentResult from "../models/TournamentResult.js";
import { checkAccess } from '../utils/userUtils.js';
class TournamentService {
@@ -226,6 +227,11 @@ class TournamentService {
model: Member,
as: 'member',
}
},
{
model: TournamentResult,
as: 'tournamentResults',
order: [['set', 'ASC']]
}
],
order: [['id', 'ASC']]
@@ -233,16 +239,67 @@ class TournamentService {
return matches;
}
async addMatchResult(token, clubId, tournamentId, matchId, result) {
async addMatchResult(token, clubId, tournamentId, matchId, set, result) {
await checkAccess(token, clubId);
const match = await TournamentMatch.findByPk(matchId);
if (!match || match.tournamentId != tournamentId) {
throw new Error("Match not found or doesn't belong to this tournament");
const matches = await TournamentMatch.findAll({
where: { id: matchId, tournamentId },
});
if (matches.length > 0) {
const match = matches[0];
const tournamentResult = await TournamentResult.findOne({where: {
matchId: match.id,
set: set,
}
});
if (tournamentResult && tournamentResult.set == set) {
tournamentResult.result = result;
await tournamentResult.save();
} else {
const points = result.split(':');
await TournamentResult.create({
matchId,
set,
pointsPlayer1: points[0],
pointsPlayer2: points[1],
});
}
return;
}
match.result = result;
await match.save();
throw new Error('Match not found');
}
async finishMatch(token, clubId, tournamentId, matchId) {
await checkAccess(token, clubId);
const matches = await TournamentMatch.findAll({
where: { id: matchId, tournamentId },
include: [
{
model: TournamentResult,
as: 'tournamentResults'
}
],
order: [[{ model: TournamentResult, as: 'tournamentResults' }, 'set', 'ASC']]
});
let win = 0;
let lose = 0;
for (const results of matches[0].tournamentResults) {
if (results.pointsPlayer1 > results.pointsPlayer2) {
win++;
} else {
lose++;
}
}
const result = win.toString() + ':' + lose.toString();
if (matches.length == 1) {
const match = matches[0];
match.isFinished = true;
match.result = result;
await match.save();
return;
}
throw new Error('Match not found');
}
}

View File

@@ -82,15 +82,16 @@
<th>&nbsp;</th>
<th>Begegnung</th>
<th>Sätze</th>
<th>Ergebnis</th>
</tr>
</thead>
<tbody>
<tr v-for="match in matches" :key="match.id">
<td>{{ match.groupId ? "Gr " + match.groupId : match.round }}</td>
<td>{{ getPlayerName(match.player1) }} - {{ getPlayerName(match.player2) }}</td>
<td><input size="5" type="text" v-model="match.result" @keyup.enter="saveMatchResult(match, match.result)" /></td>
<td></td>
<td v-for="result in match.tournamentResults">{{ result.pointsPlayer1 }}:{{ result.pointsPlayer2 }}</td>
<td><input size="5" type="text" v-model="match.result" @keyup.enter="saveMatchResult(match, match.tournamentResults.length + 1, match.result)" /></td>
<td v-if="match.isFinished">{{ match.result ?? '0:0' }}</td>
<td v-else><button @click="finishMatch(match)">Abschließen</button></td>
</tr>
</tbody>
</table>
@@ -249,19 +250,32 @@ export default {
getPlayerName(player) {
return player.member.firstName + ' ' + player.member.lastName;
},
async saveMatchResult(match, result) {
async saveMatchResult(match, set, result) {
try {
await apiClient.post('/tournament/match/result', {
clubId: this.currentClub,
tournamentId: this.selectedDate,
matchId: match.matchId,
matchId: match.id,
set,
result: result,
});
match.result = result; // Aktualisiere das Match in der UI
this.fetchGroups();
} catch (error) {
console.error('Error saving match result:', error);
}
}
},
async finishMatch(match) {
try {
await apiClient.post('/tournament/match/finish', {
clubId: this.currentClub,
tournamentId: this.selectedDate,
matchId: match.id,
});
this.fetchGroups();
} catch (error) {
console.error('Error finishing match:', error);
}
},
},
};
</script>