Fügt Unterstützung für parallele Entwicklungsumgebungen hinzu und aktualisiert die Benutzeroberfläche. Neue Routen und Komponenten für Trainingsstatistiken implementiert. Fehlerbehebungen und Verbesserungen in der Benutzeroberfläche vorgenommen.

This commit is contained in:
Torsten Schulz (local)
2025-08-22 15:47:16 +02:00
parent e827964688
commit 8bd05e4e38
40 changed files with 4670 additions and 346 deletions

View File

@@ -0,0 +1,121 @@
import { DiaryDate, Member, Participant } from '../models/index.js';
import { Op } from 'sequelize';
class TrainingStatsController {
async getTrainingStats(req, res) {
try {
const { clubId } = req.params;
// Aktuelle Datum für Berechnungen
const now = new Date();
const twelveMonthsAgo = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate());
const threeMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 3, now.getDate());
// Alle aktiven Mitglieder des Vereins laden
const members = await Member.findAll({
where: {
active: true
}
});
const stats = [];
for (const member of members) {
// Trainingsteilnahmen der letzten 12 Monate über Participant-Model
const participation12Months = await Participant.count({
include: [{
model: DiaryDate,
as: 'diaryDate',
where: {
clubId: parseInt(clubId),
date: {
[Op.gte]: twelveMonthsAgo
}
}
}],
where: {
memberId: member.id
}
});
// Trainingsteilnahmen der letzten 3 Monate über Participant-Model
const participation3Months = await Participant.count({
include: [{
model: DiaryDate,
as: 'diaryDate',
where: {
clubId: parseInt(clubId),
date: {
[Op.gte]: threeMonthsAgo
}
}
}],
where: {
memberId: member.id
}
});
// Trainingsteilnahmen insgesamt über Participant-Model
const participationTotal = await Participant.count({
include: [{
model: DiaryDate,
as: 'diaryDate',
where: {
clubId: parseInt(clubId)
}
}],
where: {
memberId: member.id
}
});
// Detaillierte Trainingsdaten (absteigend sortiert) über Participant-Model
const trainingDetails = await Participant.findAll({
include: [{
model: DiaryDate,
as: 'diaryDate',
where: {
clubId: parseInt(clubId)
}
}],
where: {
memberId: member.id
},
order: [['diaryDate', 'date', 'DESC']],
limit: 50 // Begrenzen auf die letzten 50 Trainingseinheiten
});
// Trainingsteilnahmen für den Member formatieren
const formattedTrainingDetails = trainingDetails.map(participation => ({
id: participation.id,
date: participation.diaryDate.date,
activityName: 'Training',
startTime: '--:--',
endTime: '--:--'
}));
stats.push({
id: member.id,
firstName: member.firstName,
lastName: member.lastName,
birthDate: member.birthDate,
participation12Months,
participation3Months,
participationTotal,
trainingDetails: formattedTrainingDetails
});
}
// Nach Gesamtteilnahme absteigend sortieren
stats.sort((a, b) => b.participationTotal - a.participationTotal);
res.json(stats);
} catch (error) {
console.error('Fehler beim Laden der Trainings-Statistik:', error);
res.status(500).json({ error: 'Fehler beim Laden der Trainings-Statistik' });
}
}
}
export default new TrainingStatsController();