From f935c72f569f8c584b2156f3a1638b5bc3d1263f Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Mon, 17 Mar 2025 23:42:22 +0100 Subject: [PATCH 01/10] Diary fix --- backend/services/accidentService.js | 3 +- frontend/src/views/DiaryView.vue | 75 +++++++++++++++++------------ 2 files changed, 45 insertions(+), 33 deletions(-) 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/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue index a46821e..5b06864 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; @@ -1100,12 +1112,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 ); }, @@ -1188,7 +1200,8 @@ h3 { .column:first-child { flex: 1; overflow: hidden; - height: 100%;justify-self: start; + height: 100%; + justify-self: start; display: flex; flex-direction: column; } From 9ba39f9f4717adc946907374332b74e9a6068441 Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 15:46:43 +0200 Subject: [PATCH 02/10] Added missing addAddress method --- frontend/src/views/ScheduleView.vue | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index 7649010..408578e 100644 --- a/frontend/src/views/ScheduleView.vue +++ b/frontend/src/views/ScheduleView.vue @@ -178,7 +178,25 @@ export default { }); return uniqueLocations; - } + }, + addAddress(clubName, addressLines) { + if (!this.addressY) { + this.addressY = 30; + } + + this.doc.setFontSize(14); + this.doc.setFont(undefined, 'bold'); + this.doc.text(clubName, 20, this.addressY); + + this.doc.setFontSize(12); + this.doc.setFont(undefined, 'normal'); + addressLines.forEach(line => { + this.addressY += 7; + this.doc.text(line, 20, this.addressY); + }); + + this.addressY += 10; // Abstand zur nächsten Adresse + }, }, async created() { await this.loadLeagues(); From 9f17f2399a1a8f4876609f0ee50353f2d24517ab Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 15:56:45 +0200 Subject: [PATCH 03/10] Moved addAddress to PDFGenerator class --- frontend/src/components/PDFGenerator.js | 19 +++++++++++++++++++ frontend/src/views/ScheduleView.vue | 18 ------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index dd0ec41..f4144fc 100644 --- a/frontend/src/components/PDFGenerator.js +++ b/frontend/src/components/PDFGenerator.js @@ -175,6 +175,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.doc.setFontSize(14); + this.doc.setFont(undefined, 'bold'); + this.doc.text(clubName, 20, this.addressY); + + this.doc.setFontSize(12); + this.doc.setFont(undefined, 'normal'); + addressLines.forEach(line => { + this.addressY += 7; + this.doc.text(line, 20, this.addressY); + }); + + this.addressY += 10; // Abstand zur nächsten Adresse + }, } export default PDFGenerator; diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index 408578e..83fea52 100644 --- a/frontend/src/views/ScheduleView.vue +++ b/frontend/src/views/ScheduleView.vue @@ -179,24 +179,6 @@ export default { return uniqueLocations; }, - addAddress(clubName, addressLines) { - if (!this.addressY) { - this.addressY = 30; - } - - this.doc.setFontSize(14); - this.doc.setFont(undefined, 'bold'); - this.doc.text(clubName, 20, this.addressY); - - this.doc.setFontSize(12); - this.doc.setFont(undefined, 'normal'); - addressLines.forEach(line => { - this.addressY += 7; - this.doc.text(line, 20, this.addressY); - }); - - this.addressY += 10; // Abstand zur nächsten Adresse - }, }, async created() { await this.loadLeagues(); From 81cf94cebcf9756919e2967965e0df83ecc69eec Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 15:57:30 +0200 Subject: [PATCH 04/10] Fixed bug --- frontend/src/components/PDFGenerator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index f4144fc..160330c 100644 --- a/frontend/src/components/PDFGenerator.js +++ b/frontend/src/components/PDFGenerator.js @@ -193,7 +193,7 @@ class PDFGenerator { }); this.addressY += 10; // Abstand zur nächsten Adresse - }, + } } export default PDFGenerator; From 549147cfb3ef57c10323a65be4c34f2102663086 Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 16:00:45 +0200 Subject: [PATCH 05/10] Fixed used variable in class --- frontend/src/components/PDFGenerator.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index 160330c..b19c337 100644 --- a/frontend/src/components/PDFGenerator.js +++ b/frontend/src/components/PDFGenerator.js @@ -181,15 +181,15 @@ class PDFGenerator { this.addressY = 30; } - this.doc.setFontSize(14); - this.doc.setFont(undefined, 'bold'); - this.doc.text(clubName, 20, this.addressY); + this.pdf.setFontSize(14); + this.pdf.setFont(undefined, 'bold'); + this.pdf.text(clubName, 20, this.addressY); - this.doc.setFontSize(12); - this.doc.setFont(undefined, 'normal'); + this.pdf.setFontSize(12); + this.pdf.setFont(undefined, 'normal'); addressLines.forEach(line => { this.addressY += 7; - this.doc.text(line, 20, this.addressY); + this.pdf.text(line, 20, this.addressY); }); this.addressY += 10; // Abstand zur nächsten Adresse From f753d45e17b56ad545f87989cfcb4bd9fed0d6ee Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 16:14:43 +0200 Subject: [PATCH 06/10] Fix for address problem --- frontend/src/views/ScheduleView.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index 83fea52..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); From 68725af6303842027446ee6ed77b559532271c9a Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 16:22:14 +0200 Subject: [PATCH 07/10] Fixed UTF8 import --- backend/services/matchService.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) 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); From f3a41595368081c240673273367a0663f80ea697 Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 18:08:17 +0200 Subject: [PATCH 08/10] font size change for pdf --- frontend/src/components/PDFGenerator.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index b19c337..8417260 100644 --- a/frontend/src/components/PDFGenerator.js +++ b/frontend/src/components/PDFGenerator.js @@ -27,6 +27,7 @@ class PDFGenerator { 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; From 39089a70d390e6c5ce0340a5f503e2f29fa0cd9f Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 18:17:02 +0200 Subject: [PATCH 09/10] fix --- frontend/src/components/PDFGenerator.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index 8417260..a0a659c 100644 --- a/frontend/src/components/PDFGenerator.js +++ b/frontend/src/components/PDFGenerator.js @@ -20,7 +20,20 @@ class PDFGenerator { } async addSchedule(element) { - const canvas = await html2canvas(element, { scale: 2 }); + 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 imgData = canvas.toDataURL('image/png'); const imgWidth = 210 - this.margin * 2; const imgHeight = (canvas.height * imgWidth) / canvas.width; From eba160c43d9840d7e5f552ab330e446b3575a8be Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Tue, 15 Jul 2025 18:19:30 +0200 Subject: [PATCH 10/10] fix --- frontend/src/components/PDFGenerator.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/PDFGenerator.js b/frontend/src/components/PDFGenerator.js index a0a659c..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,17 +23,19 @@ 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;