diff --git a/backend/services/accidentService.js b/backend/services/accidentService.js index 3be7273..c2b8437 100644 --- a/backend/services/accidentService.js +++ b/backend/services/accidentService.js @@ -8,8 +8,7 @@ class AccidentService { await checkAccess(userToken, clubId); const user = await getUserByToken(userToken); if (!user) { - console.log('---------------'); - throw new Error('User not found'); + throw new Error('User not found'); } const member = await Member.findByPk(memberId); if (!member || member.clubId != clubId) { diff --git a/backend/services/matchService.js b/backend/services/matchService.js index 3bb3deb..ffb0aab 100644 --- a/backend/services/matchService.js +++ b/backend/services/matchService.js @@ -31,7 +31,7 @@ class MatchService { const matches = []; try { const fileStream = fs.createReadStream(filePath) - .pipe(iconv.decodeStream('ISO-8859-15')) + .pipe(iconv.decodeStream('utf8')) .pipe(csv({ separator: ';' })); for await (const row of fileStream) { const parsedDate = parse(row['Termin'], 'dd.MM.yyyy HH:mm', new Date()); @@ -67,15 +67,11 @@ class MatchService { clubId: clubId, }); } + let season = null; if (seasonString) { - const season = await Season.findOne({ where: { season: seasonString } }); + season = await Season.findOne({ where: { season: seasonString } }); if (season) { - await Match.destroy({ - where: { - clubId: clubId, - seasonId: season.id, - } - }); + await Match.destroy({ where: { clubId, seasonId: season.id } }); } } const result = await Match.bulkCreate(matches); diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index 8909a3b..c396fe8 100644 --- a/frontend/src/components/PDFGenerator.js +++ b/frontend/src/components/PDFGenerator.js @@ -6,7 +6,7 @@ class PDFGenerator { this.pdf = new jsPDF('p', 'mm', 'a4'); this.margin = margin; this.columnGap = columnGap; - this.pageHeight = 297 - margin * 2; + this.pageHeight = 297 - margin * 2; this.columnWidth = (210 - margin * 2 - columnGap) / 2; this.position = margin; this.yPos = this.position; @@ -23,23 +23,26 @@ class PDFGenerator { const canvas = await html2canvas(element, { scale: 2, onclone: (clonedDoc) => { - // Klon des Wurzel-Elements - const tbl = clonedDoc.getElementById(element.id); - if (!tbl) return; - - // Alle Zellen und Überschriften-Elemente auswählen - const cells = tbl.querySelectorAll('td, th'); - cells.forEach(cell => { - cell.style.fontSize = '12pt'; - }); + const clonedEl = clonedDoc.getElementById('schedule'); + if (clonedEl) clonedEl.style.fontSize = '12pt'; + // Klon des Wurzel-Elements + const tbl = clonedDoc.getElementById(element.id); + if (!tbl) return; + + // Alle Zellen und Überschriften-Elemente auswählen + const cells = tbl.querySelectorAll('td, th'); + cells.forEach(cell => { + cell.style.fontSize = '12pt'; + }); } - }); + }); const imgData = canvas.toDataURL('image/png'); const imgWidth = 210 - this.margin * 2; const imgHeight = (canvas.height * imgWidth) / canvas.width; let heightLeft = imgHeight; let position = this.margin; this.pdf.addImage(imgData, 'PNG', this.margin, position, imgWidth, imgHeight); + this.pdf.setFontSize(12); heightLeft -= this.pageHeight; while (heightLeft >= 0) { position = heightLeft - imgHeight + this.margin; @@ -188,6 +191,25 @@ class PDFGenerator { this.pdf.text(phoneNumber, this.margin + 120, this.yPos); this.yPos += this.LINE_HEIGHT; } + + addAddress(clubName, addressLines) { + if (!this.addressY) { + this.addressY = 30; + } + + this.pdf.setFontSize(14); + this.pdf.setFont(undefined, 'bold'); + this.pdf.text(clubName, 20, this.addressY); + + this.pdf.setFontSize(12); + this.pdf.setFont(undefined, 'normal'); + addressLines.forEach(line => { + this.addressY += 7; + this.pdf.text(line, 20, this.addressY); + }); + + this.addressY += 10; // Abstand zur nächsten Adresse + } } export default PDFGenerator; diff --git a/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue index f8568f0..0f6f24e 100644 --- a/frontend/src/views/DiaryView.vue +++ b/frontend/src/views/DiaryView.vue @@ -32,7 +32,7 @@

Trainingszeiten bearbeiten {{ showGeneralData ? - '-' : '+' }}

+ '-' : '+' }}
@@ -54,7 +54,7 @@
  • {{ group.name - }} + }} @@ -88,6 +88,7 @@ + @@ -98,6 +99,7 @@ + +
    Startzeit Aktivität / Zeitblock Gruppe
    {{ calculateNextTime }} @@ -140,7 +148,7 @@ - @@ -154,7 +162,8 @@
    + @click="generatePDF">Als PDF + herunterladen
@@ -181,9 +190,9 @@ :checked="isParticipant(member.id)"> {{ - member ? member.firstName : '' + member ? member.firstName : '' }} {{ - member ? member.lastName : '' }} + member ? member.lastName : '' }} 📝 🖼 ℹ️ @@ -252,18 +261,21 @@
- +
@@ -856,7 +868,7 @@ export default { return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`; }, calculateDuration() { - const input = this.newPlanItem.durationInput; + const input = this.newPlanItem.durationText; let calculatedDuration = 0; const multiplyPattern = /(\d+)\s*[x*]\s*(\d+)/i; const match = input.match(multiplyPattern); @@ -893,17 +905,17 @@ export default { alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.'); } }, -/* async loadMemberImage(member) { - try { - const response = await apiClient.get(`/clubmembers/image/${this.currentClub}/${member.id}`, { - responseType: 'blob', - }); - const imageUrl = URL.createObjectURL(response.data); - member.imageUrl = imageUrl; - } catch (error) { - member.imageUrl = null; - } - },*/ + /* async loadMemberImage(member) { + try { + const response = await apiClient.get(`/clubmembers/image/${this.currentClub}/${member.id}`, { + responseType: 'blob', + }); + const imageUrl = URL.createObjectURL(response.data); + member.imageUrl = imageUrl; + } catch (error) { + member.imageUrl = null; + } + },*/ async generatePDF() { const pdf = new PDFGenerator(); pdf.addTrainingPlan(this.currentClubName, this.date.date, this.trainingStart, this.trainingEnd, this.trainingPlan); @@ -985,7 +997,7 @@ export default { this.showGeneralData = !this.showGeneralData; }, getFormattedDate(date) { - return (new Date(date)).toLocaleDateString('de-DE', { year: 'numeric', month: '2-digit', day: '2-digit'}); + return (new Date(date)).toLocaleDateString('de-DE', { year: 'numeric', month: '2-digit', day: '2-digit' }); }, editGroup(groupId) { this.editingGroupId = groupId; @@ -998,14 +1010,14 @@ export default { clubid: this.currentClub, dateid: this.date.id, }); - this.editingGroupId = null; + this.editingGroupId = null; } catch (error) { console.error('Fehler beim Speichern der Gruppendaten:', error); alert('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.'); } }, cancelEditGroup() { - this.editingGroupId = null; + this.editingGroupId = null; }, async openTagInfos(member) { if (!member) { @@ -1029,7 +1041,7 @@ export default { }, async addNewTagForDay(tag) { await apiClient.post(`/diarydatetags/${this.currentClub}`, { - dateId:this.date.id, + dateId: this.date.id, memberId: this.tagHistoryMember.id, tag: tag, }); @@ -1047,7 +1059,7 @@ export default { if (this.timeChecker) clearInterval(this.timeChecker); this.timeChecker = setInterval(() => { const currentTime = new Date().toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); - if (!this.trainingStart || ! this.trainingEnd) { + if (!this.trainingStart || !this.trainingEnd) { return; } let startCheckTime = this.trainingStart; @@ -1088,12 +1100,12 @@ export default { let times = []; let currentTime = new Date("2025-01-01 " + this.trainingStart); this.trainingPlan.forEach(item => { - const rawItem = JSON.parse(JSON.stringify(item)); + const rawItem = JSON.parse(JSON.stringify(item)); currentTime.setMinutes(currentTime.getMinutes() + item.duration); times.push(currentTime.toTimeString({ hours: '2-digit', minutes: '2-digit', seconds: '2-digit' }).slice(0, 8)); }); times = [...new Set(times)].sort(); - this.intermediateTimes = times.filter(time => + this.intermediateTimes = times.filter(time => time !== this.trainingStart && time !== this.trainingEnd ); }, @@ -1176,7 +1188,8 @@ h3 { .column:first-child { flex: 1; overflow: hidden; - height: 100%;justify-self: start; + height: 100%; + justify-self: start; display: flex; flex-direction: column; } diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index 7649010..d07605e 100644 --- a/frontend/src/views/ScheduleView.vue +++ b/frontend/src/views/ScheduleView.vue @@ -150,7 +150,6 @@ export default { const pdfGen = new PDFGenerator(); await pdfGen.addSchedule(element); pdfGen.addNewPage(); - pdfGen.addHeader('Hallen-Adressen'); const uniqueLocations = this.getUniqueLocations(); uniqueLocations.forEach((addressLines, clubName) => { pdfGen.addAddress(clubName, addressLines); @@ -178,7 +177,7 @@ export default { }); return uniqueLocations; - } + }, }, async created() { await this.loadLeagues();