diff --git a/backend/controllers/tournamentController.js b/backend/controllers/tournamentController.js
new file mode 100644
index 0000000..91755d7
--- /dev/null
+++ b/backend/controllers/tournamentController.js
@@ -0,0 +1,133 @@
+import tournamentService from "../services/tournamentService.js";
+
+export const getTournaments = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const clubId = req.params.clubId;
+ try {
+ const tournaments = await tournamentService.getTournaments(token, clubId);
+ res.status(200).json(tournaments);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+};
+
+export const addTournament = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentName, date } = req.body;
+ try {
+ const tournament = await tournamentService.addTournament(token, clubId, tournamentName, date);
+ res.status(200).json(tournament);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const addParticipant = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId, participant: participantId } = req.body;
+ try {
+ await tournamentService.addParticipant(token, clubId, tournamentId, participantId);
+ const participants = await tournamentService.getParticipants(token, clubId, tournamentId);
+ res.status(200).json(participants);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const getParticipants = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId } = req.body;
+ try {
+ const participants = await tournamentService.getParticipants(token, clubId, tournamentId);
+ res.status(200).json(participants);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const setModus = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId, type, numberOfGroups } = req.body;
+ try {
+ await tournamentService.setModus(token, clubId, tournamentId, type, numberOfGroups);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const createGroups = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId } = req.body;
+ try {
+ await tournamentService.createGroups(token, clubId, tournamentId);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const fillGroups = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId } = req.body;
+ try {
+ const updatedMembers = await tournamentService.fillGroups(token, clubId, tournamentId);
+ res.status(200).json(updatedMembers);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const getGroups = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId } = req.query;
+ try {
+ const groups = await tournamentService.getGroupsWithParticipants(token, clubId, tournamentId);
+ res.status(200).json(groups);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+};
+
+export const getTournament = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId } = req.params;
+ try {
+ const tournament = await tournamentService.getTournament(token, clubId, tournamentId);
+ res.status(200).json(tournament);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const getTournamentMatches = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId } = req.params;
+ try {
+ const matches = await tournamentService.getTournamentMatches(token, clubId, tournamentId);
+ res.status(200).json(matches);
+ } catch (error) {
+ console.log(error);
+ res.status(500).json({ error: error.message });
+ }
+}
+
+export const addMatchResult = async (req, res) => {
+ const { authcode: token } = req.headers;
+ const { clubId, tournamentId, matchId, result } = req.body;
+
+ try {
+ await tournamentService.addMatchResult(token, clubId, tournamentId, matchId, result);
+ res.status(200).json({ message: "Result added successfully" });
+ } catch (error) {
+ console.error(error);
+ res.status(500).json({ error: error.message });
+ }
+};
diff --git a/backend/models/Tournament.js b/backend/models/Tournament.js
new file mode 100644
index 0000000..f93c286
--- /dev/null
+++ b/backend/models/Tournament.js
@@ -0,0 +1,37 @@
+import { DataTypes } from 'sequelize';
+import sequelize from '../database.js';
+
+const Tournament = sequelize.define('Tournament', {
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ },
+ date: {
+ type: DataTypes.DATEONLY,
+ allowNull: false,
+ },
+ type: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ },
+ bestOfEndroundSize: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ },
+ numberOfGroups: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ defaultValue: 0,
+ },
+ clubId: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: 1
+ }
+}, {
+ underscored: true,
+ tableName: 'tournament',
+ timestamps: true,
+});
+
+export default Tournament;
diff --git a/backend/models/TournamentGroup.js b/backend/models/TournamentGroup.js
new file mode 100644
index 0000000..f095e77
--- /dev/null
+++ b/backend/models/TournamentGroup.js
@@ -0,0 +1,21 @@
+import { DataTypes } from 'sequelize';
+import sequelize from '../database.js';
+
+const TournamentGroup = sequelize.define('TournamentGroup', {
+ id: {
+ type: DataTypes.INTEGER,
+ primaryKey: true,
+ autoIncrement: true,
+ allowNull: false
+ },
+ tournamentId : {
+ type: DataTypes.INTEGER,
+ allowNull: false
+ },
+ }, {
+ underscored: true,
+ tableName: 'tournament_group',
+ timestamps: true,
+});
+
+export default TournamentGroup;
diff --git a/backend/models/TournamentMatch.js b/backend/models/TournamentMatch.js
new file mode 100644
index 0000000..d05f6a3
--- /dev/null
+++ b/backend/models/TournamentMatch.js
@@ -0,0 +1,31 @@
+import { DataTypes } from 'sequelize';
+import sequelize from '../database.js';
+
+const TournamentMatch = sequelize.define('TournamentMatch', {
+ tournamentId: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ },
+ groupId: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ },
+ round: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ },
+ player1Id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ },
+ player2Id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ },
+}, {
+ underscored: true,
+ tableName: 'tournament_match',
+ timestamps: true,
+});
+
+export default TournamentMatch;
diff --git a/backend/models/TournamentMember.js b/backend/models/TournamentMember.js
new file mode 100644
index 0000000..528a53d
--- /dev/null
+++ b/backend/models/TournamentMember.js
@@ -0,0 +1,26 @@
+import { DataTypes } from 'sequelize';
+import sequelize from '../database.js';
+
+const TournamentMember = sequelize.define('TournamentMember', {
+ tournamentId: {
+ type: DataTypes.INTEGER,
+ autoIncrement: false,
+ allowNull: true
+ },
+ groupId : {
+ type: DataTypes.INTEGER,
+ autoIncrement: false,
+ allowNull: true
+ },
+ clubMemberId: {
+ type: DataTypes.INTEGER,
+ autoIncrement: false,
+ allowNull: false
+ }
+ }, {
+ underscored: true,
+ tableName: 'tournament_member',
+ timestamps: true,
+});
+
+export default TournamentMember;
diff --git a/backend/models/TournamentResult.js b/backend/models/TournamentResult.js
new file mode 100644
index 0000000..82ed514
--- /dev/null
+++ b/backend/models/TournamentResult.js
@@ -0,0 +1,24 @@
+import { DataTypes } from 'sequelize';
+import sequelize from '../database.js';
+
+const TournamentResult = sequelize.define('TournamentResult', {
+ matchId: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ },
+ set: {
+ type: DataTypes.INTEGER,
+ },
+ pointsPlayer1: {
+ type: DataTypes.INTEGER,
+ },
+ pointsPlayer2: {
+ type: DataTypes.INTEGER,
+ },
+ }, {
+ underscored: true,
+ tableName: 'tournament_result',
+ timestamps: true,
+});
+
+export default TournamentResult;
diff --git a/backend/models/index.js b/backend/models/index.js
index 2d3486c..d7533a1 100644
--- a/backend/models/index.js
+++ b/backend/models/index.js
@@ -21,6 +21,11 @@ import Season from './Season.js';
import Location from './Location.js';
import Group from './Group.js';
import GroupActivity from './GroupActivity.js';
+import Tournament from './Tournament.js';
+import TournamentGroup from './TournamentGroup.js';
+import TournamentMember from './TournamentMember.js';
+import TournamentMatch from './TournamentMatch.js';
+import TournamentResult from './TournamentResult.js';
User.hasMany(Log, { foreignKey: 'userId' });
Log.belongsTo(User, { foreignKey: 'userId' });
@@ -114,6 +119,43 @@ DiaryDateTag.belongsTo(DiaryTag, { foreignKey: 'tagId', as: 'tag' });
DiaryMemberTag.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDates' });
DiaryDate.hasMany(DiaryMemberTag, { foreignKey: 'diaryDateId', as: 'diaryMemberTags' });
+Tournament.belongsTo(Club, { foreignKey: 'clubId', as: 'tournamentclub' });
+Club.hasMany(Tournament, { foreignKey: 'clubId', as: 'tournaments' });
+
+TournamentGroup.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournaments' });
+Tournament.hasMany(TournamentGroup, { foreignKey: 'tournamentId', as: 'tournamentGroups' });
+
+TournamentMember.belongsTo(TournamentGroup, {
+ foreignKey: 'groupId',
+ targetKey: 'id',
+ as: 'group',
+ constraints: false
+});
+TournamentGroup.hasMany(TournamentMember, {
+ foreignKey: 'groupId',
+ as: 'tournamentGroupMembers'
+});
+
+TournamentMember.belongsTo(Member, { foreignKey: 'clubMemberId', as: 'member' });
+Member.hasMany(TournamentMember, { foreignKey: 'clubMemberId', as: 'tournamentGroupMembers' });
+
+TournamentMember.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
+Tournament.hasMany(TournamentMember, { foreignKey: 'tournamentId', as: 'tournamentMembers' });
+
+TournamentMatch.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
+Tournament.hasMany(TournamentMatch, { foreignKey: 'tournamentId', as: 'tournamentMatches' });
+
+TournamentMatch.belongsTo(TournamentGroup, { foreignKey: 'groupId', as: 'group' });
+TournamentGroup.hasMany(TournamentMatch, { foreignKey: 'groupId', as: 'tournamentMatches' });
+
+TournamentResult.belongsTo(TournamentMatch, { foreignKey: 'matchId', as: 'match' });
+TournamentMatch.hasMany(TournamentResult, { foreignKey: 'matchId', as: 'tournamentResults' });
+
+TournamentMatch.belongsTo(TournamentMember, { foreignKey: 'player1Id', as: 'player1' });
+TournamentMatch.belongsTo(TournamentMember, { foreignKey: 'player2Id', as: 'player2' });
+TournamentMember.hasMany(TournamentMatch, { foreignKey: 'player1Id', as: 'player1Matches' });
+TournamentMember.hasMany(TournamentMatch, { foreignKey: 'player2Id', as: 'player2Matches' });
+
export {
User,
Log,
@@ -137,4 +179,9 @@ export {
Team,
Group,
GroupActivity,
+ Tournament,
+ TournamentGroup,
+ TournamentMember,
+ TournamentMatch,
+ TournamentResult,
};
diff --git a/backend/routes/tournamentRoutes.js b/backend/routes/tournamentRoutes.js
new file mode 100644
index 0000000..3c9799a
--- /dev/null
+++ b/backend/routes/tournamentRoutes.js
@@ -0,0 +1,31 @@
+import express from 'express';
+import {
+ getTournaments,
+ addTournament,
+ addParticipant,
+ getParticipants,
+ setModus,
+ createGroups,
+ fillGroups,
+ getGroups,
+ getTournament,
+ getTournamentMatches,
+ addMatchResult,
+} from '../controllers/tournamentController.js';
+import { authenticate } from '../middleware/authMiddleware.js';
+
+const router = express.Router();
+
+router.post('/participant', authenticate, addParticipant);
+router.post('/participants', authenticate, getParticipants);
+router.post('/modus', authenticate, setModus);
+router.put('/groups', authenticate, createGroups);
+router.post('/groups', authenticate, fillGroups);
+router.get('/groups', authenticate, getGroups);
+router.post('/match/result', authenticate, addMatchResult);
+router.get('/matches/:clubId/:tournamentId', authenticate, getTournamentMatches);
+router.get('/:clubId/:tournamentId', authenticate, getTournament);
+router.get('/:clubId', authenticate, getTournaments);
+router.post('/', authenticate, addTournament);
+
+export default router;
diff --git a/backend/server.js b/backend/server.js
index 46b1825..4fd1bb3 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -7,7 +7,12 @@ import {
User, Log, Club, UserClub, Member, DiaryDate, Participant, Activity, MemberNote,
DiaryNote, DiaryTag, MemberDiaryTag, DiaryDateTag, DiaryMemberNote, DiaryMemberTag,
PredefinedActivity, DiaryDateActivity, Match, League, Team, Group,
- GroupActivity
+ GroupActivity,
+ Tournament,
+ TournamentGroup,
+ TournamentMatch,
+ TournamentResult,
+ TournamentMember
} from './models/index.js';
import authRoutes from './routes/authRoutes.js';
import clubRoutes from './routes/clubRoutes.js';
@@ -27,6 +32,7 @@ import Location from './models/Location.js';
import groupRoutes from './routes/groupRoutes.js';
import diaryDateTagRoutes from './routes/diaryDateTagRoutes.js';
import sessionRoutes from './routes/sessionRoutes.js';
+import tournamentRoutes from './routes/tournamentRoutes.js';
const app = express();
const port = process.env.PORT || 3000;
@@ -53,6 +59,7 @@ app.use('/api/matches', matchRoutes);
app.use('/api/group', groupRoutes);
app.use('/api/diarydatetags', diaryDateTagRoutes);
app.use('/api/session', sessionRoutes);
+app.use('/api/tournament', tournamentRoutes);
app.use(express.static(path.join(__dirname, '../frontend/dist')));
@@ -88,6 +95,11 @@ app.get('*', (req, res) => {
await Match.sync({ alter: true });
await Group.sync({ alter: true });
await GroupActivity.sync({ alter: true });
+ await Tournament.sync({ alter: true });
+ await TournamentGroup.sync({ alter: true });
+ await TournamentMember.sync({ alter: true });
+ await TournamentMatch.sync({ alter: true });
+ await TournamentResult.sync({ alter: true });
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
diff --git a/backend/services/tournamentService.js b/backend/services/tournamentService.js
new file mode 100644
index 0000000..978e341
--- /dev/null
+++ b/backend/services/tournamentService.js
@@ -0,0 +1,249 @@
+import Club from "../models/Club.js";
+import Member from "../models/Member.js";
+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 { checkAccess } from '../utils/userUtils.js';
+
+class TournamentService {
+ async getTournaments(userToken, clubId) {
+ await checkAccess(userToken, clubId);
+ const tournaments = await Tournament.findAll(
+ {
+ where: { clubId },
+ order: [['date', 'DESC']],
+ attributes: ['id', 'name', 'date']
+ }
+ );
+ return JSON.parse(JSON.stringify(tournaments));
+ }
+
+ async addTournament(userToken, clubId, tournamentName, date) {
+ await checkAccess(userToken, clubId);
+ const club = await Club.findByPk(clubId);
+ await Tournament.create({
+ name: tournamentName,
+ date: date,
+ clubId: club.id,
+ bestOfEndroundSize: 0,
+ type: '',
+ name: '',
+ });
+ return await this.getTournaments(userToken, clubId);
+ }
+
+ async addParticipant(token, clubId, tournamentId, participantId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ const participant = TournamentMember.findAll({
+ where: { tournamentId: tournamentId, groupId: participantId, clubMemberId: participantId },
+ });
+ if (participant) {
+ throw new Error('Participant already exists');
+ }
+ await TournamentMember.create({
+ tournamentId: tournamentId,
+ groupId: participantId,
+ clubMemberId: participantId,
+ });
+ }
+
+ async getParticipants(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ return await TournamentMember.findAll({
+ where: {
+ tournamentId: tournamentId,
+ },
+ include: [
+ {
+ model: Member,
+ as: 'member',
+ attributes: ['id', 'lastName', 'firstName'],
+ order: [['firstName', 'ASC'], ['lastName', 'ASC']],
+ }
+ ]
+ });
+ }
+
+ async setModus(token, clubId, tournamentId, type, numberOfGroups) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ await tournament.update({ type, numberOfGroups });
+ }
+
+ async createGroups(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ const existingGroups = await TournamentGroup.findAll({ where: { tournamentId } });
+ const desiredGroupCount = tournament.numberOfGroups;
+ if (existingGroups.length < desiredGroupCount) {
+ const missingGroups = desiredGroupCount - existingGroups.length;
+ for (let i = 0; i < missingGroups; i++) {
+ await TournamentGroup.create({ tournamentId });
+ }
+ } else if (existingGroups.length > desiredGroupCount) {
+ existingGroups.sort((a, b) => a.id - b.id);
+ const groupsToRemove = existingGroups.slice(desiredGroupCount);
+ for (const group of groupsToRemove) {
+ await group.destroy();
+ }
+ }
+ }
+
+ async fillGroups(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ const groups = await TournamentGroup.findAll({ where: { tournamentId } });
+ if (!groups || groups.length === 0) {
+ throw new Error('No groups available. Please create groups first.');
+ }
+ const members = await TournamentMember.findAll({ where: { tournamentId } });
+ if (!members || members.length === 0) {
+ throw new Error('No tournament members found.');
+ }
+ await TournamentMatch.destroy({ where: { tournamentId } });
+ const shuffledMembers = [...members];
+ for (let i = shuffledMembers.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [shuffledMembers[i], shuffledMembers[j]] = [shuffledMembers[j], shuffledMembers[i]];
+ }
+ const numberOfGroups = groups.length;
+ for (let i = 0; i < shuffledMembers.length; i++) {
+ const groupAssignment = groups[i % numberOfGroups].id;
+ await shuffledMembers[i].update({ groupId: groupAssignment });
+ }
+ for (const group of groups) {
+ const groupMembers = await TournamentMember.findAll({ where: { groupId: group.id } });
+ for (let i = 0; i < groupMembers.length; i++) {
+ for (let j = i + 1; j < groupMembers.length; j++) {
+ await TournamentMatch.create({
+ tournamentId: tournamentId,
+ groupId: group.id,
+ round: 'group',
+ player1Id: groupMembers[i].id,
+ player2Id: groupMembers[j].id,
+ });
+ }
+ }
+ }
+ return await TournamentMember.findAll({ where: { tournamentId } });
+ }
+
+ async getGroups(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ const groups = await TournamentGroup.findAll({ where: { tournamentId } });
+ return groups;
+ }
+
+ async getGroupsWithParticipants(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findByPk(tournamentId);
+ if (!tournament || tournament.clubId != clubId) {
+ throw new Error('Tournament not found');
+ }
+ const groups = await TournamentGroup.findAll({
+ where: { tournamentId },
+ include: [
+ {
+ model: TournamentMember,
+ as: 'tournamentGroupMembers',
+ required: false,
+ include: [
+ {
+ model: Member,
+ as: 'member',
+ attributes: ['id', 'firstName', 'lastName']
+ }
+ ]
+ }
+ ],
+ order: [['id', 'ASC']]
+ });
+ return groups.map(group => ({
+ groupId: group.id,
+ participants: group.tournamentGroupMembers.map(p => ({
+ id: p.id,
+ name: `${p.member.firstName} ${p.member.lastName}`
+ }))
+ }));
+ }
+
+ async getTournament(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findOne({
+ where: { id: tournamentId, clubId },
+ });
+ if (!tournament) {
+ throw new Error('Tournament not found');
+ }
+ return tournament;
+ }
+
+ async getTournamentMatches(token, clubId, tournamentId) {
+ await checkAccess(token, clubId);
+ const tournament = await Tournament.findOne({
+ where: { id: tournamentId, clubId },
+ });
+ if (!tournament) {
+ throw new Error('Tournament not found');
+ }
+ const matches = await TournamentMatch.findAll({
+ where: { tournamentId },
+ include: [
+ {
+ model: TournamentMember,
+ as: 'player1',
+ include: {
+ model: Member,
+ as: 'member',
+ }
+ },
+ {
+ model: TournamentMember,
+ as: 'player2',
+ include: {
+ model: Member,
+ as: 'member',
+ }
+ }
+ ],
+ order: [['id', 'ASC']]
+ });
+ return matches;
+ }
+
+ async addMatchResult(token, clubId, tournamentId, matchId, 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");
+ }
+
+ match.result = result;
+ await match.save();
+ }
+}
+
+export default new TournamentService();
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 6f6e907..5221c58 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -22,6 +22,7 @@
Tagebuch
Freigaben
Spielpläne
+ Turniere
diff --git a/frontend/src/router.js b/frontend/src/router.js
index 955b0ff..f966c87 100644
--- a/frontend/src/router.js
+++ b/frontend/src/router.js
@@ -9,6 +9,7 @@ import MembersView from './views/MembersView.vue';
import DiaryView from './views/DiaryView.vue';
import PendingApprovalsView from './views/PendingApprovalsView.vue';
import ScheduleView from './views/ScheduleView.vue';
+import TournamentsView from './views/TournamentsView.vue';
const routes = [
{ path: '/register', component: Register },
@@ -21,6 +22,7 @@ const routes = [
{ path: '/diary', component: DiaryView },
{ path: '/pending-approvals', component: PendingApprovalsView},
{ path: '/schedule', component: ScheduleView},
+ { path: '/tournaments', component: TournamentsView },
];
const router = createRouter({
diff --git a/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue
index 2fb055a..89103db 100644
--- a/frontend/src/views/DiaryView.vue
+++ b/frontend/src/views/DiaryView.vue
@@ -1004,23 +1004,11 @@ export default {
},
playBellSound() {
- this.bellSound.play()
- .then(() => {
- console.log("Bell sound played successfully");
- })
- .catch(error => {
- console.error("Error playing bell sound:", error);
- });
+ this.bellSound.play();
},
playThumbSound() {
- this.thumbSound.play()
- .then(() => {
- console.log("Thumb sound played successfully");
- })
- .catch(error => {
- console.error("Error playing thumb sound:", error);
- });
+ this.thumbSound.play();
},
calculateIntermediateTimes() {
diff --git a/frontend/src/views/TournamentsView.vue b/frontend/src/views/TournamentsView.vue
new file mode 100644
index 0000000..e6d856d
--- /dev/null
+++ b/frontend/src/views/TournamentsView.vue
@@ -0,0 +1,289 @@
+
+
+
Turnier
+
+
+
Datum
+
+
+
+
+
+
+
+
+
+
+
+
Turnier
+
+
+
+
+
+
Teilnehmer
+
+ -
+ {{ participant.member.firstName }} {{ participant.member.lastName }}
+
+
+
+
+
+
+
+
+
+
+
+
Gruppen
+
+ -
+
Gruppe {{ group.groupId }}
+
+
+
+ | Spielername |
+ Bilanz |
+
+
+
+
+ | {{ participant.name }} |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file