Umfangreiche Änderungen für Trainingslogging
This commit is contained in:
@@ -21,7 +21,6 @@ const activate = async (req, res, next) => {
|
||||
};
|
||||
|
||||
const loginUser = async (req, res, next) => {
|
||||
console.log('login');
|
||||
try {
|
||||
const { email, password } = req.body;
|
||||
const result = await login(email, password);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import DiaryService from '../services/diaryService.js';
|
||||
import diaryService from '../services/diaryService.js';
|
||||
import HttpError from '../exceptions/HttpError.js';
|
||||
|
||||
const diaryService = new DiaryService();
|
||||
|
||||
const getDatesForClub = async (req, res) => {
|
||||
try {
|
||||
const { clubId } = req.params;
|
||||
const { clubId } = req.params;
|
||||
const { authcode: userToken } = req.headers;
|
||||
const dates = await diaryService.getDatesForClub(userToken, clubId);
|
||||
res.status(200).json(dates);
|
||||
@@ -34,7 +32,6 @@ const createDateForClub = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const updateTrainingTimes = async (req, res) => {
|
||||
try {
|
||||
const { clubId } = req.params;
|
||||
@@ -51,4 +48,70 @@ const updateTrainingTimes = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
export { getDatesForClub, createDateForClub, updateTrainingTimes };
|
||||
const addDiaryNote = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { diaryDateId, content } = req.body;
|
||||
const notes = await diaryService.addNoteToDate(userToken, diaryDateId, content);
|
||||
res.status(201).json(notes);
|
||||
} catch (error) {
|
||||
console.error('[addDiaryNote] - Error:', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const deleteDiaryNote = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { noteId } = req.params;
|
||||
const notes = await diaryService.deleteNoteFromDate(userToken, noteId);
|
||||
res.status(200).json(notes);
|
||||
} catch (error) {
|
||||
console.error('[deleteDiaryNote] - Error:', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const addDiaryTag = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { diaryDateId, tagName } = req.body;
|
||||
const tags = await diaryService.addTagToDate(userToken, diaryDateId, tagName);
|
||||
res.status(201).json(tags);
|
||||
} catch (error) {
|
||||
console.error('[addDiaryTag] - Error:', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const addTagToDiaryDate = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { clubId } = req.params;
|
||||
const { diaryDateId, tagId } = req.body;
|
||||
if (!diaryDateId || !tagId) {
|
||||
return res.status(400).json({ message: 'diaryDateId and tagId are required.' });
|
||||
}
|
||||
const result = await diaryService.addTagToDiaryDate(userToken, clubId, diaryDateId, tagId);
|
||||
res.status(200).json(result);
|
||||
} catch (error) {
|
||||
console.error('[addTagToDiaryDate] - Error:', error);
|
||||
res.status(500).json({ message: 'An error occurred while adding the tag to the diary date.' });
|
||||
}
|
||||
};
|
||||
|
||||
const deleteTagFromDiaryDate = async (req, res) => {
|
||||
try {
|
||||
const { tagId } = req.query;
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { clubId } = req.params;
|
||||
await diaryService.removeTagFromDiaryDate(userToken, clubId, tagId);
|
||||
res.status(200).json({ message: 'Tag deleted' });
|
||||
} catch (error) {
|
||||
console.error('[deleteTag] - Error:', error);
|
||||
res.status(500).json({ error: 'Error deleting tag' });
|
||||
}
|
||||
};
|
||||
|
||||
export { getDatesForClub, createDateForClub, updateTrainingTimes, addDiaryNote, deleteDiaryNote, addDiaryTag,
|
||||
addTagToDiaryDate, deleteTagFromDiaryDate };
|
||||
|
||||
84
backend/controllers/diaryMemberController.js
Normal file
84
backend/controllers/diaryMemberController.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import DiaryMemberService from '../services/diaryMemberService.js';
|
||||
|
||||
const getMemberTags = async (req, res) => {
|
||||
try {
|
||||
const { diaryDateId, memberId } = req.query;
|
||||
const { clubId } = req.params;
|
||||
const { authcode: userToken } = req.headers;
|
||||
const tags = await DiaryMemberService.getTagsForMemberAndDate(userToken, clubId, diaryDateId, memberId);
|
||||
res.status(200).json(tags);
|
||||
} catch (error) {
|
||||
console.error('[getMemberTags] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const getMemberNotes = async (req, res) => {
|
||||
try {
|
||||
const { diaryDateId, memberId } = req.query;
|
||||
const { clubId } = req.params;
|
||||
const { authcode: userToken } = req.headers;
|
||||
console.log('---------->', userToken, clubId);
|
||||
const notes = await DiaryMemberService.getNotesForMember(userToken, clubId, diaryDateId, memberId);
|
||||
res.status(200).json(notes);
|
||||
} catch (error) {
|
||||
console.error('[getMemberNotes] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const addMemberNote = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { memberId, diaryDateId, content } = req.body;
|
||||
const { clubId } = req.params;
|
||||
await DiaryMemberService.addNoteToMember(userToken, clubId, diaryDateId, memberId, content);
|
||||
const notes = await DiaryMemberService.getNotesForMember(userToken, clubId, diaryDateId, memberId);
|
||||
res.status(201).json(notes);
|
||||
} catch (error) {
|
||||
console.error('[addMemberNote] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const addMemberTag = async (req, res) => {
|
||||
try {
|
||||
const { diaryDateId, memberId, tagId } = req.body;
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { clubId } = req.params;
|
||||
await DiaryMemberService.addTagToMemberAndDate(userToken, clubId, diaryDateId, memberId, tagId);
|
||||
const tags = await DiaryMemberService.getTagsForMemberAndDate(userToken, clubId, diaryDateId, memberId);
|
||||
res.status(201).json(tags);
|
||||
} catch (error) {
|
||||
console.error('[addMemberTag] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const removeMemberNote = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { memberId, diaryDateId, content } = req.body;
|
||||
await DiaryMemberService.removeNoteFromMember(userToken, req.params.clubId, diaryDateId, memberId, content);
|
||||
const notes = await DiaryMemberService.getNotesForMember(userToken, req.params.clubId, diaryDateId, memberId);
|
||||
res.status(200).json(notes);
|
||||
} catch (error) {
|
||||
console.error('[removeMemberNote] - Error: ', error.message);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
const removeMemberTag = async (req, res) => {
|
||||
try {
|
||||
const { diaryDateId, memberId, tagId } = req.body;
|
||||
const { authcode: userToken } = req.headers;
|
||||
await DiaryMemberService.removeTagFromMemberAndDate(userToken, req.params.clubId, diaryDateId, memberId, tagId);
|
||||
const tags = await DiaryMemberService.getTagsForMemberAndDate(userToken, req.params.clubId, diaryDateId, memberId);
|
||||
res.status(200).json(tags);
|
||||
} catch (error) {
|
||||
console.error('[removeMemberTag] - Error: ', error.message);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
export { getMemberTags, getMemberNotes, addMemberNote, addMemberTag, removeMemberNote, removeMemberTag };
|
||||
44
backend/controllers/diaryNoteController.js
Normal file
44
backend/controllers/diaryNoteController.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import { DiaryNote, DiaryTag } from '../models/index.js';
|
||||
import diaryService from '../services/diaryService.js';
|
||||
|
||||
export const getNotes = async (req, res) => {
|
||||
try {
|
||||
const { diaryDateId, memberId } = req.query;
|
||||
if (!diaryDateId || !memberId) {
|
||||
return res.status(400).json({ error: 'diaryDateId and memberId are required.' });
|
||||
}
|
||||
|
||||
const notes = await diaryService.getDiaryNotesForDateAndMember(diaryDateId, memberId);
|
||||
res.status(200).json(notes);
|
||||
} catch (error) {
|
||||
console.error('[getNotes] - Error:', error);
|
||||
res.status(500).json({ error: 'An error occurred while fetching the notes.' });
|
||||
}
|
||||
};
|
||||
|
||||
export const createNote = async (req, res) => {
|
||||
try {
|
||||
const { memberId, content, tags } = req.body;
|
||||
const newNote = await DiaryNote.create({ memberId, content });
|
||||
if (tags && tags.length > 0) {
|
||||
const tagInstances = await DiaryTag.findAll({ where: { id: tags } });
|
||||
await newNote.addTags(tagInstances);
|
||||
}
|
||||
const noteWithTags = await DiaryNote.findByPk(newNote.id, {
|
||||
include: [{ model: DiaryTag, as: 'tags' }],
|
||||
});
|
||||
res.status(201).json(noteWithTags);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Error creating note' });
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
await DiaryNote.destroy({ where: { id: noteId } });
|
||||
res.status(200).json({ message: 'Note deleted' });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Error deleting note' });
|
||||
}
|
||||
};
|
||||
33
backend/controllers/diaryTagController.js
Normal file
33
backend/controllers/diaryTagController.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { DiaryTag, DiaryDateTag } from '../models/index.js';
|
||||
|
||||
export const getTags = async (req, res) => {
|
||||
try {
|
||||
const tags = await DiaryTag.findAll();
|
||||
res.status(200).json(tags);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Error fetching tags' });
|
||||
}
|
||||
};
|
||||
|
||||
export const createTag = async (req, res) => {
|
||||
try {
|
||||
const { name } = req.body;
|
||||
const newTag = await DiaryTag.create({ name });
|
||||
res.status(201).json(newTag);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Error creating tag' });
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteTag = async (req, res) => {
|
||||
try {
|
||||
const { tagId } = req.params;
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { clubId } = req.params;
|
||||
await diaryService.removeTagFromDiaryDate(userToken, clubId, tagId);
|
||||
res.status(200).json({ message: 'Tag deleted' });
|
||||
} catch (error) {
|
||||
console.error('[deleteTag] - Error:', error);
|
||||
res.status(500).json({ error: 'Error deleting tag' });
|
||||
}
|
||||
};
|
||||
47
backend/controllers/memberNoteController.js
Normal file
47
backend/controllers/memberNoteController.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import MemberNoteService from "../services/memberNoteService.js";
|
||||
|
||||
const getMemberNotes = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { memberId } = req.params;
|
||||
const { clubId } = req.query;
|
||||
console.log('[getMemberNotes]', userToken, memberId, clubId);
|
||||
const notes = await MemberNoteService.getNotesForMember(userToken, clubId, memberId);
|
||||
res.status(200).json(notes);
|
||||
} catch (error) {
|
||||
console.log('[getMemberNotes] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const addMemberNote = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { memberId, content, clubId } = req.body;
|
||||
console.log('[addMemberNote]', userToken, memberId, content, clubId);
|
||||
await MemberNoteService.addNoteToMember(userToken, clubId, memberId, content);
|
||||
const notes = await MemberNoteService.getNotesForMember(userToken, clubId, memberId);
|
||||
res.status(201).json(notes);
|
||||
} catch (error) {
|
||||
console.log('[addMemberNote] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
const deleteMemberNote = async (req, res) => {
|
||||
try {
|
||||
const { authcode: userToken } = req.headers;
|
||||
const { noteId } = req.params;
|
||||
const { clubId } = req.body;
|
||||
console.log('[deleteMemberNote]', userToken, noteId, clubId);
|
||||
const memberId = await MemberNoteService.getMemberIdForNote(noteId); // Member ID ermitteln
|
||||
await MemberNoteService.deleteNoteForMember(userToken, clubId, noteId);
|
||||
const notes = await MemberNoteService.getNotesForMember(userToken, clubId, memberId);
|
||||
res.status(200).json(notes);
|
||||
} catch (error) {
|
||||
console.log('[deleteMemberNote] - Error: ', error);
|
||||
res.status(500).json({ error: 'systemerror' });
|
||||
}
|
||||
};
|
||||
|
||||
export { getMemberNotes, addMemberNote, deleteMemberNote };
|
||||
29
backend/models/DiaryDateTag.js
Normal file
29
backend/models/DiaryDateTag.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import DiaryDate from './DiaryDates.js';
|
||||
import { DiaryTag } from './DiaryTag.js'; // Benannter Import
|
||||
|
||||
const DiaryDateTag = sequelize.define('DiaryDateTag', {
|
||||
diaryDateId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: DiaryDate,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
},
|
||||
tagId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: DiaryTag,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'diary_date_tags',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default DiaryDateTag;
|
||||
35
backend/models/DiaryMemberNote.js
Normal file
35
backend/models/DiaryMemberNote.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import Member from './Member.js';
|
||||
import DiaryDate from './DiaryDates.js';
|
||||
|
||||
const DiaryMemberNote = sequelize.define('DiaryMemberNote', {
|
||||
memberId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: Member,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
allowNull: false,
|
||||
},
|
||||
diaryDateId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: DiaryDate,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
allowNull: false,
|
||||
},
|
||||
content: {
|
||||
type: DataTypes.STRING(4096),
|
||||
allowNull: false,
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'diary_member_notes',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default DiaryMemberNote;
|
||||
41
backend/models/DiaryMemberTag.js
Normal file
41
backend/models/DiaryMemberTag.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import Member from './Member.js';
|
||||
import DiaryDate from './DiaryDates.js';
|
||||
import { DiaryTag } from './DiaryTag.js';
|
||||
|
||||
const DiaryMemberTag = sequelize.define('DiaryMemberTag', {
|
||||
memberId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: Member,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
allowNull: false,
|
||||
},
|
||||
diaryDateId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: DiaryDate,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
allowNull: false,
|
||||
},
|
||||
tagId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: DiaryTag,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
allowNull: false,
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'diary_member_tags',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default DiaryMemberTag;
|
||||
43
backend/models/DiaryNote.js
Normal file
43
backend/models/DiaryNote.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// models/DiaryNote.js
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import Member from './Member.js';
|
||||
|
||||
const DiaryNote = sequelize.define('DiaryNote', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
allowNull: false,
|
||||
},
|
||||
content: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false,
|
||||
},
|
||||
memberId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: Member,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'CASCADE',
|
||||
},
|
||||
diaryDateId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: 'diary_dates',
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'CASCADE',
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'diary_notes',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default DiaryNote;
|
||||
46
backend/models/DiaryTag.js
Normal file
46
backend/models/DiaryTag.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import Member from './Member.js';
|
||||
|
||||
const DiaryTag = sequelize.define('DiaryTag', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
allowNull: false,
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'diary_tags',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
const MemberDiaryTag = sequelize.define('MemberDiaryTag', {
|
||||
memberId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: Member,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
},
|
||||
tagId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: DiaryTag,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'member_diary_tags',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export { DiaryTag, MemberDiaryTag };
|
||||
40
backend/models/MemberNote.js
Normal file
40
backend/models/MemberNote.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import Member from './Member.js';
|
||||
import { encryptData, decryptData } from '../utils/encrypt.js';
|
||||
|
||||
const MemberNote = sequelize.define('MemberNote', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
allowNull: false,
|
||||
},
|
||||
content: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false,
|
||||
set(value) {
|
||||
const encryptedValue = encryptData(value);
|
||||
this.setDataValue('content', encryptedValue);
|
||||
},
|
||||
get() {
|
||||
const encryptedValue = this.getDataValue('content');
|
||||
return decryptData(encryptedValue);
|
||||
}
|
||||
},
|
||||
memberId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: Member,
|
||||
key: 'id',
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'member_notes',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default MemberNote;
|
||||
@@ -6,6 +6,12 @@ import DiaryDate from './DiaryDates.js';
|
||||
import Participant from './Participant.js';
|
||||
import Member from './Member.js';
|
||||
import Activity from './Activity.js';
|
||||
import DiaryNote from './DiaryNote.js';
|
||||
import { DiaryTag, MemberDiaryTag } from './DiaryTag.js';
|
||||
import MemberNote from './MemberNote.js';
|
||||
import DiaryDateTag from './DiaryDateTag.js';
|
||||
import DiaryMemberNote from './DiaryMemberNote.js';
|
||||
import DiaryMemberTag from './DiaryMemberTag.js';
|
||||
|
||||
User.hasMany(Log, { foreignKey: 'userId' });
|
||||
Log.belongsTo(User, { foreignKey: 'userId' });
|
||||
@@ -16,11 +22,47 @@ Club.belongsToMany(User, { through: UserClub, foreignKey: 'clubId' });
|
||||
DiaryDate.belongsTo(Club, { foreignKey: 'clubId' });
|
||||
Club.hasMany(DiaryDate, { foreignKey: 'clubId' });
|
||||
|
||||
DiaryDate.belongsToMany(Member, { through: Participant, as: 'participants' });
|
||||
Member.belongsToMany(DiaryDate, { through: Participant, as: 'diaryDates' });
|
||||
DiaryDate.belongsToMany(Member, { through: Participant, as: 'participants', foreignKey: 'diaryDateId' });
|
||||
Member.belongsToMany(DiaryDate, { through: Participant, as: 'diaryDates', foreignKey: 'memberId' });
|
||||
|
||||
DiaryDate.hasMany(Activity, { as: 'activities', foreignKey: 'diaryDateId' });
|
||||
Activity.belongsTo(DiaryDate, { as: 'diaryDate', foreignKey: 'diaryDateId' });
|
||||
|
||||
Member.hasMany(DiaryNote, { as: 'diaryNotes', foreignKey: 'memberId' });
|
||||
DiaryNote.belongsTo(Member, { foreignKey: 'memberId' });
|
||||
|
||||
export { User, Log, Club, UserClub };
|
||||
Member.hasMany(MemberNote, { as: 'memberNotes', foreignKey: 'memberId' });
|
||||
MemberNote.belongsTo(Member, { foreignKey: 'memberId' });
|
||||
|
||||
DiaryDate.hasMany(DiaryNote, { as: 'diaryNotes', foreignKey: 'diaryDateId' });
|
||||
DiaryNote.belongsTo(DiaryDate, { foreignKey: 'diaryDateId' });
|
||||
|
||||
Member.belongsToMany(DiaryTag, { through: MemberDiaryTag, as: 'tags', foreignKey: 'memberId' });
|
||||
DiaryTag.belongsToMany(Member, { through: MemberDiaryTag, as: 'members', foreignKey: 'tagId' });
|
||||
|
||||
DiaryDate.belongsToMany(DiaryTag, { through: DiaryDateTag, as: 'diaryTags', foreignKey: 'diaryDateId' });
|
||||
DiaryTag.belongsToMany(DiaryDate, { through: DiaryDateTag, as: 'diaryDates', foreignKey: 'tagId' });
|
||||
|
||||
DiaryDate.belongsToMany(Member, { through: DiaryMemberNote, as: 'noteMembers', foreignKey: 'diaryDateId' });
|
||||
Member.belongsToMany(DiaryDate, { through: DiaryMemberNote, as: 'noteDates', foreignKey: 'memberId' });
|
||||
|
||||
DiaryTag.hasMany(DiaryMemberTag, { foreignKey: 'tagId', as: 'diaryMemberTags' });
|
||||
DiaryMemberTag.belongsTo(DiaryTag, { foreignKey: 'tagId', as: 'tag' });
|
||||
|
||||
export {
|
||||
User,
|
||||
Log,
|
||||
Club,
|
||||
UserClub,
|
||||
Member,
|
||||
DiaryDate,
|
||||
Participant,
|
||||
Activity,
|
||||
DiaryNote,
|
||||
DiaryTag,
|
||||
MemberDiaryTag,
|
||||
MemberNote,
|
||||
DiaryDateTag,
|
||||
DiaryMemberNote,
|
||||
DiaryMemberTag,
|
||||
};
|
||||
|
||||
15
backend/routes/diaryMemberRoutes.js
Normal file
15
backend/routes/diaryMemberRoutes.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import express from 'express';
|
||||
import { authenticate } from '../middleware/authMiddleware.js';
|
||||
import { getMemberTags, getMemberNotes, addMemberNote, addMemberTag,
|
||||
removeMemberNote, removeMemberTag } from '../controllers/diaryMemberController.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/:clubId/tag', authenticate, getMemberTags);
|
||||
router.get('/:clubId/note', authenticate, getMemberNotes);
|
||||
router.post('/:clubId/note', authenticate, addMemberNote);
|
||||
router.post('/:clubId/tag', authenticate, addMemberTag);
|
||||
router.post('/:clubId/note/remove', authenticate, removeMemberNote);
|
||||
router.post('/:clubId/tag/remove', authenticate, removeMemberTag);
|
||||
|
||||
export default router;
|
||||
11
backend/routes/diaryNoteRoutes.js
Normal file
11
backend/routes/diaryNoteRoutes.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import express from 'express';
|
||||
import { getNotes, createNote, deleteNote } from '../controllers/diaryNoteController.js';
|
||||
import { authenticate } from '../middleware/authMiddleware.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, getNotes);
|
||||
router.post('/', authenticate, createNote);
|
||||
router.delete('/:noteId', authenticate, deleteNote);
|
||||
|
||||
export default router;
|
||||
@@ -1,9 +1,23 @@
|
||||
import express from 'express';
|
||||
import { authenticate } from '../middleware/authMiddleware.js';
|
||||
import { getDatesForClub, createDateForClub, updateTrainingTimes } from '../controllers/diaryController.js';
|
||||
import {
|
||||
getDatesForClub,
|
||||
createDateForClub,
|
||||
updateTrainingTimes,
|
||||
addDiaryNote,
|
||||
deleteDiaryNote,
|
||||
addDiaryTag,
|
||||
addTagToDiaryDate,
|
||||
deleteTagFromDiaryDate
|
||||
} from '../controllers/diaryController.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/note', authenticate, addDiaryNote);
|
||||
router.delete('/note/:noteId', authenticate, deleteDiaryNote);
|
||||
router.post('/tag', authenticate, addDiaryTag);
|
||||
router.post('/tag/:clubId/add-tag', authenticate, addTagToDiaryDate);
|
||||
router.delete('/:clubId/tag', authenticate, deleteTagFromDiaryDate);
|
||||
router.get('/:clubId', authenticate, getDatesForClub);
|
||||
router.post('/:clubId', authenticate, createDateForClub);
|
||||
router.put('/:clubId', authenticate, updateTrainingTimes);
|
||||
|
||||
11
backend/routes/diaryTagRoutes.js
Normal file
11
backend/routes/diaryTagRoutes.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import express from 'express';
|
||||
import { getTags, createTag, deleteTag } from '../controllers/diaryTagController.js';
|
||||
import { authenticate } from '../middleware/authMiddleware.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', authenticate, getTags); // Route to get all tags
|
||||
router.post('/', authenticate, createTag); // Route to create a new tag
|
||||
router.delete('/:tagId', authenticate, deleteTag); // Neue Route zum Löschen eines Tags
|
||||
|
||||
export default router;
|
||||
11
backend/routes/memberNoteRoutes.js
Normal file
11
backend/routes/memberNoteRoutes.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import express from 'express';
|
||||
import { getMemberNotes, addMemberNote, deleteMemberNote } from '../controllers/memberNoteController.js';
|
||||
import { authenticate } from '../middleware/authMiddleware.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/', authenticate, addMemberNote);
|
||||
router.get('/:memberId', authenticate, getMemberNotes);
|
||||
router.delete('/:noteId', authenticate, deleteMemberNote);
|
||||
|
||||
export default router;
|
||||
@@ -2,17 +2,20 @@ import express from 'express';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import sequelize from './database.js';
|
||||
import { User, Log, Club, UserClub } from './models/index.js';
|
||||
import {
|
||||
User, Log, Club, UserClub, Member, DiaryDate, Participant, Activity, MemberNote,
|
||||
DiaryNote, DiaryTag, MemberDiaryTag, DiaryDateTag, DiaryMemberNote, DiaryMemberTag
|
||||
} from './models/index.js';
|
||||
import authRoutes from './routes/authRoutes.js';
|
||||
import clubRoutes from './routes/clubRoutes.js';
|
||||
import diaryRoutes from './routes/diaryRoutes.js';
|
||||
import memberRoutes from './routes/memberRoutes.js';
|
||||
import participantRoutes from './routes/participantRoutes.js';
|
||||
import activityRoutes from './routes/activityRoutes.js';
|
||||
import Member from './models/Member.js';
|
||||
import DiaryDate from './models/DiaryDates.js';
|
||||
import Participant from './models/Participant.js';
|
||||
import Activity from './models/Activity.js';
|
||||
import participantRoutes from './routes/participantRoutes.js';
|
||||
import activityRoutes from './routes/activityRoutes.js';
|
||||
import memberNoteRoutes from './routes/memberNoteRoutes.js';
|
||||
import diaryTagRoutes from './routes/diaryTagRoutes.js';
|
||||
import diaryNoteRoutes from './routes/diaryNoteRoutes.js';
|
||||
import diaryMemberRoutes from './routes/diaryMemberRoutes.js'; // Neue Route
|
||||
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3000;
|
||||
@@ -21,12 +24,17 @@ const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/clubs', clubRoutes);
|
||||
app.use('/api/clubmembers', memberRoutes);
|
||||
app.use('/api/diary', diaryRoutes);
|
||||
app.use('/api/participants', participantRoutes);
|
||||
app.use('/api/activities', activityRoutes);
|
||||
app.use('/api/participants', participantRoutes);
|
||||
app.use('/api/activities', activityRoutes);
|
||||
app.use('/api/membernotes', memberNoteRoutes);
|
||||
app.use('/api/diarynotes', diaryNoteRoutes);
|
||||
app.use('/api/tags', diaryTagRoutes);
|
||||
app.use('/api/diarymember', diaryMemberRoutes); // Neue Route für Diary-Member-Funktionalität
|
||||
|
||||
app.use(express.static(path.join(__dirname, '../frontend/dist')));
|
||||
|
||||
@@ -37,6 +45,7 @@ app.get('*', (req, res) => {
|
||||
(async () => {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
|
||||
await User.sync({ alter: true });
|
||||
await Club.sync({ alter: true });
|
||||
await UserClub.sync({ alter: true });
|
||||
@@ -45,6 +54,14 @@ app.get('*', (req, res) => {
|
||||
await DiaryDate.sync({ alter: true });
|
||||
await Participant.sync({ alter: true });
|
||||
await Activity.sync({ alter: true });
|
||||
await MemberNote.sync({ alter: true });
|
||||
await DiaryNote.sync({ alter: true });
|
||||
await DiaryTag.sync({ alter: true });
|
||||
await MemberDiaryTag.sync({ alter: true });
|
||||
await DiaryDateTag.sync({ alter: true });
|
||||
await DiaryMemberTag.sync({ alter: true });
|
||||
await DiaryMemberNote.sync({ alter: true });
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is running on http://localhost:${port}`);
|
||||
});
|
||||
|
||||
60
backend/services/diaryMemberService.js
Normal file
60
backend/services/diaryMemberService.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import DiaryMemberNote from '../models/DiaryMemberNote.js';
|
||||
import DiaryMemberTag from '../models/DiaryMemberTag.js';
|
||||
import { DiaryTag } from '../models/DiaryTag.js';
|
||||
import { checkAccess } from '../utils/userUtils.js';
|
||||
|
||||
class DiaryMemberService {
|
||||
async addNoteToMember(userToken, clubId, diaryDateId, memberId, content) {
|
||||
await checkAccess(userToken, clubId);
|
||||
const existingNote = await DiaryMemberNote.findOne({ where: { diaryDateId, memberId, content } });
|
||||
if (!existingNote) {
|
||||
await DiaryMemberNote.create({ diaryDateId, memberId, content });
|
||||
}
|
||||
}
|
||||
|
||||
async getNotesForMember(userToken, clubId, diaryDateId, memberId) {
|
||||
await checkAccess(userToken, clubId);
|
||||
return await DiaryMemberNote.findAll({ where: { diaryDateId, memberId }, order: [['createdAt', 'DESC']] });
|
||||
}
|
||||
|
||||
async addTagToMemberAndDate(userToken, clubId, diaryDateId, memberId, tagId) {
|
||||
await checkAccess(userToken, clubId);
|
||||
const existingTag = await DiaryMemberTag.findOne({ where: { diaryDateId, memberId, tagId } });
|
||||
if (!existingTag) {
|
||||
await DiaryMemberTag.create({ diaryDateId, memberId, tagId });
|
||||
}
|
||||
}
|
||||
|
||||
async getTagsForMemberAndDate(userToken, clubId, diaryDateId, memberId) {
|
||||
await checkAccess(userToken, clubId);
|
||||
return await DiaryMemberTag.findAll({
|
||||
where: { diaryDateId, memberId },
|
||||
include: [{ model: DiaryTag, as: 'tag' }]
|
||||
});
|
||||
}
|
||||
|
||||
async removeNoteFromMember(userToken, clubId, diaryDateId, memberId, content) {
|
||||
await checkAccess(userToken, clubId);
|
||||
|
||||
const note = await DiaryMemberNote.findOne({ where: { diaryDateId, memberId, content } });
|
||||
if (note) {
|
||||
await note.destroy();
|
||||
} else {
|
||||
throw new Error('Die Notiz existiert nicht.');
|
||||
}
|
||||
}
|
||||
|
||||
async removeTagFromMemberAndDate(userToken, clubId, diaryDateId, memberId, tag) {
|
||||
await checkAccess(userToken, clubId);
|
||||
const tagLink = await DiaryMemberTag.findOne({ where: { diaryDateId, memberId, tagId: tag.id } });
|
||||
if (tagLink) {
|
||||
await tagLink.destroy();
|
||||
} else {
|
||||
console.log(diaryDateId, memberId, tagId);
|
||||
throw new Error('Das Tag ist nicht verknüpft.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new DiaryMemberService();
|
||||
@@ -1,5 +1,8 @@
|
||||
import DiaryDate from '../models/DiaryDates.js';
|
||||
import Club from '../models/Club.js';
|
||||
import DiaryNote from '../models/DiaryNote.js';
|
||||
import { DiaryTag } from '../models/DiaryTag.js';
|
||||
import DiaryDateTag from '../models/DiaryDateTag.js';
|
||||
import { checkAccess } from '../utils/userUtils.js';
|
||||
import HttpError from '../exceptions/HttpError.js';
|
||||
|
||||
@@ -15,9 +18,12 @@ class DiaryService {
|
||||
console.log('[DiaryService::getDatesForClub] - Load diary dates');
|
||||
const dates = await DiaryDate.findAll({
|
||||
where: { clubId },
|
||||
include: [
|
||||
{ model: DiaryNote, as: 'diaryNotes' }, // Der Alias für DiaryNote ist korrekt
|
||||
{ model: DiaryTag, as: 'diaryTags' }, // Hier muss der Alias auf 'diaryTags' geändert werden
|
||||
],
|
||||
order: [['date', 'ASC'], ['trainingStart', 'ASC']]
|
||||
});
|
||||
|
||||
return dates;
|
||||
}
|
||||
|
||||
@@ -42,7 +48,7 @@ class DiaryService {
|
||||
date: parsedDate,
|
||||
clubId,
|
||||
trainingStart: trainingStart || null,
|
||||
trainingEnd: trainingEnd || null,
|
||||
trainingEnd: trainingEnd || null,
|
||||
});
|
||||
|
||||
return newDate;
|
||||
@@ -65,6 +71,74 @@ class DiaryService {
|
||||
await diaryDate.save();
|
||||
return diaryDate;
|
||||
}
|
||||
|
||||
async addNoteToDate(userToken, diaryDateId, content) {
|
||||
console.log('[DiaryService::addNoteToDate] - Add note');
|
||||
await checkAccess(userToken, diaryDateId);
|
||||
await DiaryNote.create({ diaryDateId, content });
|
||||
return await DiaryNote.findAll({ where: { diaryDateId }, order: [['createdAt', 'DESC']] });
|
||||
}
|
||||
|
||||
async deleteNoteFromDate(userToken, noteId) {
|
||||
console.log('[DiaryService::deleteNoteFromDate] - Delete note');
|
||||
const note = await DiaryNote.findByPk(noteId);
|
||||
if (!note) {
|
||||
throw new HttpError('Note not found', 404);
|
||||
}
|
||||
await checkAccess(userToken, note.diaryDateId);
|
||||
await note.destroy();
|
||||
return await DiaryNote.findAll({ where: { diaryDateId: note.diaryDateId }, order: [['createdAt', 'DESC']] });
|
||||
}
|
||||
|
||||
async addTagToDate(userToken, diaryDateId, tagName) {
|
||||
console.log('[DiaryService::addTagToDate] - Add tag');
|
||||
await checkAccess(userToken, diaryDateId);
|
||||
let tag = await DiaryTag.findOne({ where: { name: tagName } });
|
||||
if (!tag) {
|
||||
tag = await DiaryTag.create({ name: tagName });
|
||||
}
|
||||
const diaryDate = await DiaryDate.findByPk(diaryDateId);
|
||||
await diaryDate.addTag(tag);
|
||||
return await diaryDate.getTags();
|
||||
}
|
||||
|
||||
async addTagToDiaryDate(userToken, clubId, diaryDateId, tagId) {
|
||||
checkAccess(userToken, clubId);
|
||||
console.log(`[DiaryService::addTagToDiaryDate] - diaryDateId: ${diaryDateId}, tagId: ${tagId}`);
|
||||
const diaryDate = await DiaryDate.findByPk(diaryDateId);
|
||||
if (!diaryDate) {
|
||||
throw new HttpError('DiaryDate not found', 404);
|
||||
}
|
||||
const existingEntry = await DiaryDateTag.findOne({
|
||||
where: { diaryDateId, tagId }
|
||||
});
|
||||
if (existingEntry) {
|
||||
return;
|
||||
}
|
||||
const tag = await DiaryTag.findByPk(tagId);
|
||||
if (!tag) {
|
||||
throw new HttpError('Tag not found', 404);
|
||||
}
|
||||
await DiaryDateTag.create({
|
||||
diaryDateId,
|
||||
tagId
|
||||
})
|
||||
return diaryDate.getDiaryTags();
|
||||
}
|
||||
|
||||
async getDiaryNotesForDateAndMember(diaryDateId, memberId) {
|
||||
console.log('[DiaryService::getDiaryNotesForDateAndMember] - Fetching notes');
|
||||
return await DiaryNote.findAll({
|
||||
where: { diaryDateId, memberId },
|
||||
order: [['createdAt', 'DESC']]
|
||||
});
|
||||
}
|
||||
|
||||
async removeTagFromDiaryDate(userToken, clubId, tagId) {
|
||||
await checkAccess(userToken, clubId);
|
||||
await DiaryDateTag.destroy({ where: { tagId } });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default DiaryService;
|
||||
export default new DiaryService();
|
||||
|
||||
29
backend/services/memberNoteService.js
Normal file
29
backend/services/memberNoteService.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import MemberNote from '../models/MemberNote.js';
|
||||
import { checkAccess } from '../utils/userUtils.js';
|
||||
|
||||
class MemberNoteService {
|
||||
async addNoteToMember(userToken, clubId, memberId, content) {
|
||||
await checkAccess(userToken, clubId);
|
||||
return await MemberNote.create({ memberId, content });
|
||||
}
|
||||
|
||||
async getNotesForMember(userToken, clubId, memberId) {
|
||||
console.log(userToken, clubId);
|
||||
await checkAccess(userToken, clubId);
|
||||
return await MemberNote.findAll({
|
||||
where: { memberId },
|
||||
order: [['createdAt', 'DESC']]
|
||||
});
|
||||
}
|
||||
|
||||
async deleteNoteForMember(userToken, clubId, noteId) {
|
||||
await checkAccess(userToken, clubId);
|
||||
const note = await MemberNote.findByPk(noteId);
|
||||
if (!note) {
|
||||
throw new Error('Note not found');
|
||||
}
|
||||
await note.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
export default new MemberNoteService();
|
||||
Reference in New Issue
Block a user