From 7660f7cf7b88fd62174029d0516ab2178c5c4fba Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 24 Oct 2025 00:55:04 +0200 Subject: [PATCH] Add 'Spielplan' links to Navigation component; update index page to include 'Spielplan' section; enhance 'spielplaene' page with filtering, loading states, and error handling for improved user experience. --- components/Navigation.vue | 20 + components/Spielplan.vue | 218 +++++ pages/cms/spielplaene.vue | 640 +++++++++++++ pages/index.vue | 8 +- pages/mannschaften/spielplaene.vue | 841 +++++++++++++----- pages/spielplan.vue | 195 ++++ public/data/spielplan.csv | 114 +++ public/documents/spielplaene/README.md | 17 + server/api/cms/save-csv.post.js | 3 +- server/api/cms/upload-spielplan-pdf.post.js | 102 +++ server/api/spielplan.get.js | 61 ++ .../api/spielplan/download/[filename].get.js | 114 +++ server/api/spielplan/pdf.get.js | 352 ++++++++ 13 files changed, 2457 insertions(+), 228 deletions(-) create mode 100644 components/Spielplan.vue create mode 100644 pages/cms/spielplaene.vue create mode 100644 pages/spielplan.vue create mode 100644 public/data/spielplan.csv create mode 100644 public/documents/spielplaene/README.md create mode 100644 server/api/cms/upload-spielplan-pdf.post.js create mode 100644 server/api/spielplan.get.js create mode 100644 server/api/spielplan/download/[filename].get.js create mode 100644 server/api/spielplan/pdf.get.js diff --git a/components/Navigation.vue b/components/Navigation.vue index 3038e31..31e733c 100644 --- a/components/Navigation.vue +++ b/components/Navigation.vue @@ -57,6 +57,12 @@ Termine + + Spielplan + + Termine + + Spielpläne + @@ -403,6 +414,11 @@ Termine + + Spielplan + + Termine + + Spielpläne + Mitglieder diff --git a/components/Spielplan.vue b/components/Spielplan.vue new file mode 100644 index 0000000..dd94a80 --- /dev/null +++ b/components/Spielplan.vue @@ -0,0 +1,218 @@ + + + diff --git a/pages/cms/spielplaene.vue b/pages/cms/spielplaene.vue new file mode 100644 index 0000000..286999e --- /dev/null +++ b/pages/cms/spielplaene.vue @@ -0,0 +1,640 @@ + + + diff --git a/pages/index.vue b/pages/index.vue index 2ae5743..295fe6f 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -6,10 +6,13 @@ - + + + + - + @@ -17,6 +20,7 @@ diff --git a/pages/mannschaften/spielplaene.vue b/pages/mannschaften/spielplaene.vue index 06c5e1c..ba643e2 100644 --- a/pages/mannschaften/spielplaene.vue +++ b/pages/mannschaften/spielplaene.vue @@ -1,268 +1,659 @@ + \ No newline at end of file diff --git a/pages/spielplan.vue b/pages/spielplan.vue new file mode 100644 index 0000000..802aa9f --- /dev/null +++ b/pages/spielplan.vue @@ -0,0 +1,195 @@ + + + diff --git a/public/data/spielplan.csv b/public/data/spielplan.csv new file mode 100644 index 0000000..71de85f --- /dev/null +++ b/public/data/spielplan.csv @@ -0,0 +1,114 @@ +Termin;Saison;Meisterschaft;Altersklasse;Liga;Staffel;Runde;HeimMannschaftAltersklasse;HeimMannschaft;GastMannschaftAltersklasse;GastMannschaft +01.07.2025 00:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Jugend 11;Jugend 11 Kreisliga;Kreisliage Ju11;Pokal;Jugend 11;Harheimer TC;Jugend 11;Eintracht Frankfurt II +01.09.2025 20:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse;Pokal;Erwachsene;Harheimer TC II;Herren;spielfrei +01.09.2025 20:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse;Pokal;Erwachsene;Harheimer TC V;Herren;spielfrei +04.09.2025 19:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse;Pokal;Erwachsene;DJK SW Griesheim;Erwachsene;Harheimer TC IV +04.09.2025 20:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse;Pokal;Erwachsene;Eintracht Frankfurt X;Erwachsene;Harheimer TC III +04.09.2025 20:15;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse;Pokal;Erwachsene;Harheimer TC;Erwachsene;DJK-SG 1929 Zeilsheim II +06.09.2025 10:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 13;TSG Oberrad II;Jugend 11;Harheimer TC +09.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC III;Erwachsene;DJK SW Griesheim +11.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC;Erwachsene;TTC 1957 Nieder-Eschbach +11.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC IV;Erwachsene;TV Niederrad VI +12.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;SV Viktoria Preußen V;Erwachsene;Harheimer TC V +16.09.2025 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;TSG Nordwest Frankfurt III;Erwachsene;Harheimer TC III +16.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC IV;Erwachsene;Turngemeinde Unterliederbach 1887 VI +17.09.2025 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;TSG Oberrad IX;Erwachsene;Harheimer TC II +18.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;Harheimer TC V;Erwachsene;TSG Nieder-Erlenbach IV +19.09.2025 20:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;TS FFM Heddernheim II;Erwachsene;Harheimer TC +22.09.2025 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;TTC 1957 Nieder-Eschbach II;Erwachsene;Harheimer TC V +25.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC;Erwachsene;TG Bornheim 1860 IV +26.09.2025 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;TTC Nordend Frankfurt VI;Erwachsene;Harheimer TC III +28.09.2025 10:30;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 13;TV Niederrad III;Jugend 11;Harheimer TC +29.09.2025 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;TGS Vorwärts Ffm. VI;Erwachsene;Harheimer TC IV +30.09.2025 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 11;Harheimer TC;Jugend 13;Eintracht Frankfurt V +30.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC;Erwachsene;TV 1874 Bergen-Enkheim VI +30.09.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC II;Erwachsene;TSG Nordwest Frankfurt +02.10.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;Harheimer TC V;Erwachsene;Eintracht Frankfurt XII +21.10.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC IV;Erwachsene;TuS Hausen 1860 III +23.10.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;TSG Nieder-Erlenbach;Erwachsene;Harheimer TC +23.10.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC III;Erwachsene;TV Preungesheim 1880 II +23.10.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;Harheimer TC V;Erwachsene;TV Niederrad VII +24.10.2025 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;TTC Nordend Frankfurt IV;Erwachsene;Harheimer TC II +25.10.2025 13:15;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 13;Eintracht Frankfurt IV;Jugend 11;Harheimer TC +27.10.2025 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;TSG Nieder-Erlenbach II;Erwachsene;Harheimer TC III +30.10.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC;Erwachsene;TSG Oberrad X +31.10.2025 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;SG 1878 Sossenheim IV;Erwachsene;Harheimer TC IV +31.10.2025 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;TV Eschersheim 1895 VII;Erwachsene;Harheimer TC II +04.11.2025 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;TG Bornheim 1860 V;Erwachsene;Harheimer TC IV +04.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC II;Erwachsene;DJK-SG 1929 Zeilsheim II +06.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC III;Erwachsene;FTV 1860 Frankfurt II +07.11.2025 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;SG 1878 Sossenheim V;Erwachsene;Harheimer TC V +10.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;TV 1874 Bergen-Enkheim V;Erwachsene;Harheimer TC II +11.11.2025 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 11;Harheimer TC;Jugend 13;TSG Nieder-Erlenbach +11.11.2025 20:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;TSV 1878 Ginnheim II;Erwachsene;Harheimer TC +13.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC III;Erwachsene;TSV Sachsenhausen 1857 II +17.11.2025 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;TGS Vorwärts Ffm. VII;Erwachsene;Harheimer TC V +18.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC IV;Erwachsene;Eintracht Frankfurt XI +25.11.2025 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Turngemeinde Unterliederbach 1887 VII;Erwachsene;Harheimer TC III +25.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC II;Erwachsene;TG Bornheim 1860 III +27.11.2025 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;TSG Nordwest Frankfurt II;Erwachsene;Harheimer TC IV +27.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC;Erwachsene;TG Sachsenhausen 04 IV +27.11.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;Harheimer TC V;Erwachsene;TV Preungesheim 1880 IV +28.11.2025 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;VR;Erwachsene;TTC Nordend Frankfurt V;Erwachsene;Harheimer TC +29.11.2025 13:15;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 11;Eintracht Frankfurt II;Jugend 11;Harheimer TC +02.12.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Harheimer TC III;Erwachsene;TV Eschersheim 1895 VIII +09.12.2025 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;VR;Jugend 11;Harheimer TC;Jugend 13;TV Seckbach 1875 +09.12.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC II;Erwachsene;TV Seckbach 1875 III +09.12.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;VR;Erwachsene;Harheimer TC IV;Erwachsene;TV 1875 Sindlingen III +11.12.2025 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;VR;Erwachsene;Eintracht Frankfurt X;Erwachsene;Harheimer TC III +11.12.2025 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;VR;Erwachsene;Harheimer TC V;Erwachsene;TV 1874 Bergen-Enkheim VII +16.12.2025 20:15;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse;Pokal;Erwachsene;Harheimer TC;Erwachsene;TG Sachsenhausen 04 IV +17.12.2025 20:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse;Pokal;Erwachsene;TSG Oberrad IX;Erwachsene;Harheimer TC II +18.12.2025 19:00;Pokal 2025/26;Kreis Frankfurt Pokal 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse;Pokal;Erwachsene;DJK SW Griesheim II;Erwachsene;Harheimer TC V +20.01.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC IV;Erwachsene;SG 1878 Sossenheim IV +22.01.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC III;Erwachsene;Turngemeinde Unterliederbach 1887 VII +23.01.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;TG Sachsenhausen 04 IV;Erwachsene;Harheimer TC +29.01.2026 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;Eintracht Frankfurt XI;Erwachsene;Harheimer TC IV +29.01.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC III;Erwachsene;TSG Nieder-Erlenbach II +04.02.2026 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;TSG Oberrad X;Erwachsene;Harheimer TC +04.02.2026 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;TV Preungesheim 1880 II;Erwachsene;Harheimer TC III +05.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;TSG Nieder-Erlenbach IV;Erwachsene;Harheimer TC V +06.02.2026 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 13;TV Seckbach 1875;Jugend 11;Harheimer TC +06.02.2026 20:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;TV Seckbach 1875 III;Erwachsene;Harheimer TC II +08.02.2026 13:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;TV Niederrad VI;Erwachsene;Harheimer TC IV +12.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC III;Erwachsene;TTC Nordend Frankfurt VI +12.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;Harheimer TC V;Erwachsene;TGS Vorwärts Ffm. VII +16.02.2026 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 13;TSG Nieder-Erlenbach;Jugend 11;Harheimer TC +16.02.2026 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;TV Preungesheim 1880 IV;Erwachsene;Harheimer TC V +17.02.2026 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;Turngemeinde Unterliederbach 1887 VI;Erwachsene;Harheimer TC IV +17.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC II;Erwachsene;TTC Nordend Frankfurt IV +19.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC;Erwachsene;TTC Nordend Frankfurt V +20.02.2026 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;TV Eschersheim 1895 VIII;Erwachsene;Harheimer TC III +23.02.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;TTC 1957 Nieder-Eschbach;Erwachsene;Harheimer TC +24.02.2026 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 11;Harheimer TC;Jugend 13;TV Niederrad III +24.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC IV;Erwachsene;TGS Vorwärts Ffm. VI +26.02.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC III;Erwachsene;Eintracht Frankfurt X +27.02.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;TSG Nordwest Frankfurt;Erwachsene;Harheimer TC II +03.03.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;TV 1875 Sindlingen III;Erwachsene;Harheimer TC IV +05.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC;Erwachsene;TSG Nieder-Erlenbach +05.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;Harheimer TC V;Erwachsene;SG 1878 Sossenheim V +10.03.2026 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 11;Harheimer TC;Jugend 13;TSG Oberrad II +11.03.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;DJK-SG 1929 Zeilsheim II;Erwachsene;Harheimer TC II +12.03.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;TG Bornheim 1860 IV;Erwachsene;Harheimer TC +13.03.2026 19:45;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;TSV Sachsenhausen 1857 II;Erwachsene;Harheimer TC III +13.03.2026 20:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;Eintracht Frankfurt XII;Erwachsene;Harheimer TC V +17.03.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;TG Bornheim 1860 III;Erwachsene;Harheimer TC II +17.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC IV;Erwachsene;TG Bornheim 1860 V +19.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC;Erwachsene;TS FFM Heddernheim II +20.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;TV 1874 Bergen-Enkheim VII;Erwachsene;Harheimer TC V +24.03.2026 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 11;Harheimer TC;Jugend 13;Eintracht Frankfurt IV +24.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC II;Erwachsene;TV 1874 Bergen-Enkheim V +26.03.2026 19:30;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;TuS Hausen 1860 III;Erwachsene;Harheimer TC IV +26.03.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC III;Erwachsene;TSG Nordwest Frankfurt III +29.03.2026 17:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;TV Niederrad VII;Erwachsene;Harheimer TC V +14.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC II;Erwachsene;TV Eschersheim 1895 VII +14.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;FTV 1860 Frankfurt II;Erwachsene;Harheimer TC III +16.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;Harheimer TC;Erwachsene;TSV 1878 Ginnheim II +16.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;Harheimer TC V;Erwachsene;TTC 1957 Nieder-Eschbach II +18.04.2026 10:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 13;Eintracht Frankfurt V;Jugend 11;Harheimer TC +20.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 1;RR;Erwachsene;TV 1874 Bergen-Enkheim VI;Erwachsene;Harheimer TC +21.04.2026 18:00;2025/26;Kreis Frankfurt 2025/26;Jugend 13;Jugend 13 1.Kreisklasse;Jugend 13 1. Kreisklasse;RR;Jugend 11;Harheimer TC;Jugend 11;Eintracht Frankfurt II +21.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 1. Kreisklasse;1. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC II;Erwachsene;TSG Oberrad IX +23.04.2026 19:00;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 1;RR;Erwachsene;DJK SW Griesheim;Erwachsene;Harheimer TC III +23.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 2. Kreisklasse;2. Kreisklasse Gr. 2;RR;Erwachsene;Harheimer TC IV;Erwachsene;TSG Nordwest Frankfurt II +23.04.2026 20:15;2025/26;Kreis Frankfurt 2025/26;Erwachsene;Erwachsene 3. Kreisklasse (3er);3. Kreisklasse (3er) Gr.1;RR;Erwachsene;Harheimer TC V;Erwachsene;SV Viktoria Preußen V \ No newline at end of file diff --git a/public/documents/spielplaene/README.md b/public/documents/spielplaene/README.md new file mode 100644 index 0000000..39efeee --- /dev/null +++ b/public/documents/spielplaene/README.md @@ -0,0 +1,17 @@ +# Spielplan PDF-Dateien + +Dieses Verzeichnis enthält die PDF-Dateien für die verschiedenen Spielpläne. + +## Erwartete Dateien: + +- `spielplan_gesamt.pdf` - Gesamter Spielplan aller Mannschaften +- `spielplan_erwachsene.pdf` - Spielplan der Erwachsenen-Mannschaften +- `spielplan_nachwuchs.pdf` - Spielplan der Nachwuchs-Mannschaften + +## Upload über CMS: + +Die PDF-Dateien können über das CMS unter "Spielpläne" hochgeladen werden. + +## Download: + +Die PDF-Dateien werden über die Spielpläne-Seite unter "Mannschaften" -> "Spielpläne" heruntergeladen. diff --git a/server/api/cms/save-csv.post.js b/server/api/cms/save-csv.post.js index dc1ae55..d8ee9f6 100644 --- a/server/api/cms/save-csv.post.js +++ b/server/api/cms/save-csv.post.js @@ -16,7 +16,8 @@ export default defineEventHandler(async (event) => { const allowedFiles = [ 'vereinsmeisterschaften.csv', 'mannschaften.csv', - 'termine.csv' + 'termine.csv', + 'spielplan.csv' ] if (!allowedFiles.includes(filename)) { diff --git a/server/api/cms/upload-spielplan-pdf.post.js b/server/api/cms/upload-spielplan-pdf.post.js new file mode 100644 index 0000000..4f3a59e --- /dev/null +++ b/server/api/cms/upload-spielplan-pdf.post.js @@ -0,0 +1,102 @@ +import multer from 'multer' +import fs from 'fs/promises' +import path from 'path' + +// Multer-Konfiguration für PDF-Uploads +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + const uploadPath = path.join(process.cwd(), 'public', 'documents', 'spielplaene') + cb(null, uploadPath) + }, + filename: (req, file, cb) => { + const type = req.body.type + const filename = `spielplan_${type}.pdf` + cb(null, filename) + } +}) + +const upload = multer({ + storage: storage, + fileFilter: (req, file, cb) => { + if (file.mimetype === 'application/pdf') { + cb(null, true) + } else { + cb(new Error('Nur PDF-Dateien sind erlaubt'), false) + } + }, + limits: { + fileSize: 10 * 1024 * 1024 // 10MB Limit + } +}) + +export default defineEventHandler(async (event) => { + try { + // Prüfe Authentifizierung + const authHeader = getHeader(event, 'authorization') + if (!authHeader || !authHeader.startsWith('Bearer ')) { + throw createError({ + statusCode: 401, + statusMessage: 'Nicht autorisiert' + }) + } + + // Multer-Middleware für multipart/form-data + await new Promise((resolve, reject) => { + upload.single('pdf')(event.node.req, event.node.res, (err) => { + if (err) { + reject(err) + } else { + resolve() + } + }) + }) + + const file = event.node.req.file + const type = event.node.req.body.type + + if (!file) { + throw createError({ + statusCode: 400, + statusMessage: 'Keine Datei hochgeladen' + }) + } + + if (!type || !['gesamt', 'erwachsene', 'nachwuchs'].includes(type)) { + // Lösche die hochgeladene Datei + await fs.unlink(file.path) + throw createError({ + statusCode: 400, + statusMessage: 'Ungültiger Typ' + }) + } + + return { + success: true, + message: `PDF für ${type} erfolgreich hochgeladen`, + filename: file.filename, + originalName: file.originalname + } + + } catch (error) { + console.error('Fehler beim PDF-Upload:', error) + + if (error.code === 'LIMIT_FILE_SIZE') { + throw createError({ + statusCode: 413, + statusMessage: 'Datei zu groß (max. 10MB)' + }) + } + + if (error.message === 'Nur PDF-Dateien sind erlaubt') { + throw createError({ + statusCode: 400, + statusMessage: 'Nur PDF-Dateien sind erlaubt' + }) + } + + throw createError({ + statusCode: 500, + statusMessage: 'Fehler beim Hochladen der PDF-Datei' + }) + } +}) diff --git a/server/api/spielplan.get.js b/server/api/spielplan.get.js new file mode 100644 index 0000000..a061052 --- /dev/null +++ b/server/api/spielplan.get.js @@ -0,0 +1,61 @@ +import fs from 'fs/promises' +import path from 'path' + +export default defineEventHandler(async (event) => { + try { + const filePath = path.join(process.cwd(), 'public', 'data', 'spielplan.csv') + + // Prüfe ob Datei existiert + try { + await fs.access(filePath) + } catch (error) { + return { + success: false, + message: 'Spielplan-Datei nicht gefunden', + data: [] + } + } + + // CSV-Datei lesen + const csvContent = await fs.readFile(filePath, 'utf-8') + const lines = csvContent.split('\n').filter(line => line.trim() !== '') + + if (lines.length < 2) { + return { + success: false, + message: 'Spielplan-Datei ist leer oder unvollständig', + data: [] + } + } + + // Header-Zeile parsen + const headers = lines[0].split(';').map(header => header.trim()) + + // Datenzeilen parsen + const data = lines.slice(1).map(line => { + const values = line.split(';').map(value => value.trim()) + const row = {} + + headers.forEach((header, index) => { + row[header] = values[index] || '' + }) + + return row + }) + + return { + success: true, + message: 'Spielplan erfolgreich geladen', + data: data, + headers: headers + } + + } catch (error) { + console.error('Fehler beim Laden des Spielplans:', error) + return { + success: false, + message: 'Fehler beim Laden des Spielplans', + data: [] + } + } +}) diff --git a/server/api/spielplan/download/[filename].get.js b/server/api/spielplan/download/[filename].get.js new file mode 100644 index 0000000..3c00275 --- /dev/null +++ b/server/api/spielplan/download/[filename].get.js @@ -0,0 +1,114 @@ +import fs from 'fs/promises' +import path from 'path' + +export default defineEventHandler(async (event) => { + try { + const filename = getRouterParam(event, 'filename') + + if (!filename) { + throw createError({ + statusCode: 400, + statusMessage: 'Dateiname fehlt' + }) + } + + // Erlaubte Dateinamen für Sicherheit + const allowedFiles = [ + 'spielplan_gesamt.pdf', + 'spielplan_erwachsene.pdf', + 'spielplan_nachwuchs.pdf', + 'spielplan_erwachsene_1.pdf', + 'spielplan_erwachsene_2.pdf', + 'spielplan_erwachsene_3.pdf', + 'spielplan_erwachsene_4.pdf', + 'spielplan_erwachsene_5.pdf', + 'spielplan_jugendmannschaft.pdf' + ] + + // Prüfe ob es eine dynamische Mannschafts-PDF ist + const isDynamicMannschaft = filename.startsWith('spielplan_') && filename.endsWith('.pdf') && + !allowedFiles.includes(filename) + + if (!allowedFiles.includes(filename) && !isDynamicMannschaft) { + throw createError({ + statusCode: 403, + statusMessage: 'Datei nicht erlaubt' + }) + } + + let filePath + + if (isDynamicMannschaft) { + // Für dynamische Mannschafts-PDFs: Verwende Gesamt-Spielplan als Fallback + // Hier könnte später ein PDF-Generator implementiert werden + filePath = path.join(process.cwd(), 'public', 'documents', 'spielplaene', 'spielplan_gesamt.pdf') + } else { + // Für vordefinierte PDFs + filePath = path.join(process.cwd(), 'public', 'documents', 'spielplaene', filename) + } + + // Prüfe ob Datei existiert + try { + await fs.access(filePath) + } catch (error) { + // Fallback: Erstelle eine informative HTML-Seite + const htmlContent = ` + + + + + + PDF nicht verfügbar + + + +
+
📄 PDF-Datei nicht verfügbar
+
+ Die angeforderte PDF-Datei "${filename}" wurde noch nicht hochgeladen. +
+
+ Was können Sie tun?
+ • Laden Sie die PDF-Datei über das CMS hoch
+ • Kontaktieren Sie den Administrator
+ • Versuchen Sie es später erneut +
+
+ +` + + setHeader(event, 'Content-Type', 'text/html; charset=utf-8') + return htmlContent + } + + // Datei lesen + const fileBuffer = await fs.readFile(filePath) + + // Content-Type setzen + setHeader(event, 'Content-Type', 'application/pdf') + setHeader(event, 'Content-Disposition', `attachment; filename="${filename}"`) + setHeader(event, 'Content-Length', fileBuffer.length.toString()) + + return fileBuffer + + } catch (error) { + console.error('Fehler beim Laden der PDF-Datei:', error) + + if (error.statusCode) { + throw error + } + + throw createError({ + statusCode: 500, + statusMessage: 'Fehler beim Laden der PDF-Datei' + }) + } +}) diff --git a/server/api/spielplan/pdf.get.js b/server/api/spielplan/pdf.get.js new file mode 100644 index 0000000..15d9f74 --- /dev/null +++ b/server/api/spielplan/pdf.get.js @@ -0,0 +1,352 @@ +import fs from 'fs/promises' +import path from 'path' + +export default defineEventHandler(async (event) => { + try { + const query = getQuery(event) + const team = query.team + + if (!team) { + throw createError({ + statusCode: 400, + statusMessage: 'Team-Parameter fehlt' + }) + } + + // Lade Spielplandaten + const csvPath = path.join(process.cwd(), 'public/data/spielplan.csv') + let csvContent + + try { + csvContent = await fs.readFile(csvPath, 'utf-8') + } catch (error) { + throw createError({ + statusCode: 404, + statusMessage: 'Spielplandaten nicht gefunden' + }) + } + + // Parse CSV + const lines = csvContent.split('\n').filter(line => line.trim()) + if (lines.length < 2) { + throw createError({ + statusCode: 400, + statusMessage: 'Keine Spielplandaten verfügbar' + }) + } + + const headers = lines[0].split(';') + const dataRows = lines.slice(1).map(line => { + const values = line.split(';') + const row = {} + headers.forEach((header, index) => { + row[header] = values[index] || '' + }) + return row + }) + + // Filtere Daten basierend auf Team + let filteredData = dataRows + + if (team !== 'all') { + filteredData = dataRows.filter(row => { + const heimMannschaft = (row.HeimMannschaft || '').toLowerCase() + const gastMannschaft = (row.GastMannschaft || '').toLowerCase() + const heimAltersklasse = (row.HeimMannschaftAltersklasse || '').toLowerCase() + const gastAltersklasse = (row.GastMannschaftAltersklasse || '').toLowerCase() + + // Prüfe ob eine der Mannschaften Harheimer TC ist + const isHarheimerHeim = heimMannschaft.includes('harheimer tc') + const isHarheimerGast = gastMannschaft.includes('harheimer tc') + + if (!isHarheimerHeim && !isHarheimerGast) { + return false // Kein Harheimer TC Spiel + } + + // Mapping zwischen Team-Namen und CSV-Daten + const mannschaftMapping = { + 'erwachsene': ['harheimer tc'], // Alle Erwachsenen-Mannschaften + 'nachwuchs': ['harheimer tc'], // Alle Jugend-Mannschaften + 'erwachsene_1': ['harheimer tc'], // Nur ohne römische Zahl + 'erwachsene_2': ['harheimer tc ii'], + 'erwachsene_3': ['harheimer tc iii'], + 'erwachsene_4': ['harheimer tc iv'], + 'erwachsene_5': ['harheimer tc v'], + 'jugendmannschaft': ['harheimer tc'] // Jugend hat keine römische Zahl + } + + const csvVariants = mannschaftMapping[team] || [] + + if (csvVariants.length === 0) { + return false + } + + // Prüfe Mannschafts-Zuordnung UND Altersklasse + const mannschaftMatch = csvVariants.some(variant => { + // Strikte Übereinstimmung: Prüfe exakte Mannschaftsnamen + if (isHarheimerHeim) { + // Für "harheimer tc" (Erwachsene 1): Nur wenn KEINE römische Zahl folgt + if (variant === 'harheimer tc') { + return heimMannschaft === 'harheimer tc' || + heimMannschaft.startsWith('harheimer tc ') && + !heimMannschaft.match(/harheimer tc\s+[ivx]+/i) + } + // Für andere Mannschaften: Exakte Übereinstimmung + return heimMannschaft === variant || heimMannschaft.startsWith(variant + ' ') + } + if (isHarheimerGast) { + // Für "harheimer tc" (Erwachsene 1): Nur wenn KEINE römische Zahl folgt + if (variant === 'harheimer tc') { + return gastMannschaft === 'harheimer tc' || + gastMannschaft.startsWith('harheimer tc ') && + !gastMannschaft.match(/harheimer tc\s+[ivx]+/i) + } + // Für andere Mannschaften: Exakte Übereinstimmung + return gastMannschaft === variant || gastMannschaft.startsWith(variant + ' ') + } + return false + }) + + if (!mannschaftMatch) { + return false + } + + // Zusätzliche Altersklassen-Prüfung für spezifische Mannschaften + if (team.startsWith('erwachsene')) { + // Erwachsenen-Mannschaften: MUSS Erwachsene sein, DARF NICHT Jugend sein + const isErwachsenenHeim = isHarheimerHeim && + heimAltersklasse.includes('erwachsene') && + !heimAltersklasse.includes('jugend') + const isErwachsenenGast = isHarheimerGast && + gastAltersklasse.includes('erwachsene') && + !gastAltersklasse.includes('jugend') + + return isErwachsenenHeim || isErwachsenenGast + } else if (team === 'jugendmannschaft' || team === 'nachwuchs') { + // Jugend-Mannschaft: MUSS Jugend sein + const isJugendHeim = isHarheimerHeim && + (heimAltersklasse.includes('jugend') || heimMannschaft.includes('jugend')) + const isJugendGast = isHarheimerGast && + (gastAltersklasse.includes('jugend') || gastMannschaft.includes('jugend')) + + return isJugendHeim || isJugendGast + } + + return true // Fallback für unbekannte Mannschaften + }) + } + + // Filtere nach Wettbewerb (Standard: Punktrunde) + const wettbewerb = query.wettbewerb || 'punktrunde' + if (wettbewerb !== 'alle') { + filteredData = filteredData.filter(row => { + const runde = (row.Runde || '').toLowerCase() + + if (wettbewerb === 'punktrunde') { + return runde === 'vr' || + runde.includes('vorrunde') || + runde === 'rr' || + runde.includes('rückrunde') || + runde.includes('verbandsrunde') + } else if (wettbewerb === 'pokal') { + return runde === 'pokal' || runde.includes('pokal') + } + + return true + }) + } + + // Filtere nach aktueller Saison (2025/26) + const currentSaisonStart = new Date(2025, 6, 1) // 01.07.2025 + const currentSaisonEnd = new Date(2026, 5, 30) // 30.06.2026 + + filteredData = filteredData.filter(row => { + const termin = row.Termin + if (!termin) return false + + try { + let spielDatum + + if (termin.includes(' ')) { + const datumTeil = termin.split(' ')[0] + const [tag, monat, jahr] = datumTeil.split('.') + spielDatum = new Date(jahr, monat - 1, tag) + } else { + spielDatum = new Date(termin) + } + + if (isNaN(spielDatum.getTime())) return false + + return spielDatum >= currentSaisonStart && spielDatum <= currentSaisonEnd + } catch (error) { + return false + } + }) + + // Generiere LaTeX-Code für PDF + const teamName = team.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()) + const currentDate = new Date().toLocaleDateString('de-DE') + + let latexContent = ` +\\documentclass[9pt,a4paper]{article} +\\usepackage[utf8]{inputenc} +\\usepackage[ngerman]{babel} +\\usepackage{geometry} +\\usepackage{array} +\\usepackage{longtable} +\\usepackage{helvet} +\\renewcommand{\\familydefault}{\\sfdefault} + +\\geometry{margin=2cm} + +\\title{Spielplan ${teamName}} +\\author{Harheimer TC} +\\date{Saison 2025/26 - Stand: ${currentDate}} + +\\begin{document} +\\maketitle + +\\section*{Spielplan ${teamName}} +\\vspace{0.5cm} + +${filteredData.length > 0 ? ` +\\renewcommand{\\arraystretch}{1.3} +\\begin{longtable}{|p{1.8cm}|p{1.1cm}|p{6.5cm}|p{6.5cm}|} +\\hline +\\textbf{Datum} & \\textbf{Uhrzeit} & \\textbf{Heim} & \\textbf{Gast} \\\\ +\\hline +\\endhead + +${filteredData.map(row => { + const termin = row.Termin || '' + const datum = termin.includes(' ') ? termin.split(' ')[0] : termin + const uhrzeit = termin.includes(' ') ? termin.split(' ')[1] : '' + const heim = (row.HeimMannschaft || '').replace(/&/g, '\\&') + const gast = (row.GastMannschaft || '').replace(/&/g, '\\&') + const heimAltersklasse = (row.HeimMannschaftAltersklasse || '').toLowerCase() + const gastAltersklasse = (row.GastMannschaftAltersklasse || '').toLowerCase() + + // Prüfe ob es Jugend-Mannschaften sind + const isHeimJugend = heimAltersklasse.includes('jugend') || heim.toLowerCase().includes('jugend') + const isGastJugend = gastAltersklasse.includes('jugend') || gast.toLowerCase().includes('jugend') + + // Füge "(J) " vor Jugendmannschaften hinzu (nur bei Gesamtspielplan) + let heimFormatted = heim + let gastFormatted = gast + + if (team === 'all') { + if (isHeimJugend) { + heimFormatted = `(J) ${heim}` + } + if (isGastJugend) { + gastFormatted = `(J) ${gast}` + } + } + + const heimBold = heimFormatted.toLowerCase().includes('harheimer tc') ? `\\textbf{${heimFormatted}}` : heimFormatted + const gastBold = gastFormatted.toLowerCase().includes('harheimer tc') ? `\\textbf{${gastFormatted}}` : gastFormatted + + return `${datum} & ${uhrzeit} & ${heimBold} & ${gastBold} \\\\ \\hline` +}).join('\n')} + +\\end{longtable} +` : ` +\\begin{center} +\\textit{Keine Spiele für ${teamName} gefunden.} +\\end{center} +`} + +\\vfill +\\begin{center} +\\small Generiert am ${currentDate} | Harheimer TC +\\end{center} + +\\end{document}` + + // Schreibe LaTeX-Datei temporär + const tempDir = path.join(process.cwd(), 'temp') + try { + await fs.mkdir(tempDir, { recursive: true }) + } catch (error) { + // Verzeichnis existiert bereits + } + + const tempTexFile = path.join(tempDir, `spielplan_${team}_${Date.now()}.tex`) + await fs.writeFile(tempTexFile, latexContent, 'utf-8') + + // Kompiliere LaTeX zu PDF + const { exec } = await import('child_process') + const { promisify } = await import('util') + const execAsync = promisify(exec) + + try { + const { stdout, stderr } = await execAsync(`pdflatex -interaction=nonstopmode -output-directory=${tempDir} "${tempTexFile}"`) + + // PDF-Datei lesen + const pdfFile = tempTexFile.replace('.tex', '.pdf') + const pdfBuffer = await fs.readFile(pdfFile) + + // Cleanup: Lösche temporäre Dateien + setTimeout(async () => { + try { + await fs.unlink(tempTexFile) + await fs.unlink(pdfFile) + await fs.unlink(tempTexFile.replace('.tex', '.log')) + await fs.unlink(tempTexFile.replace('.tex', '.aux')) + } catch (error) { + console.error('Fehler beim Löschen temporärer Dateien:', error) + } + }, 5000) + + // Setze PDF-Headers + setHeader(event, 'Content-Type', 'application/pdf') + setHeader(event, 'Content-Disposition', `attachment; filename="spielplan_${team}.pdf"`) + setHeader(event, 'Content-Length', pdfBuffer.length.toString()) + + return pdfBuffer + + } catch (compileError) { + console.error('LaTeX-Kompilierung fehlgeschlagen:', compileError) + + // Fallback: HTML-Response mit Fehlermeldung + const errorHtml = ` + + + + + PDF-Generierung fehlgeschlagen + + + +
+
❌ PDF-Generierung fehlgeschlagen
+
+ Die PDF-Generierung für "${teamName}" ist fehlgeschlagen.
+ Bitte kontaktieren Sie den Administrator. +
+
+ +` + + setHeader(event, 'Content-Type', 'text/html; charset=utf-8') + return errorHtml + } + + } catch (error) { + console.error('Fehler beim Generieren des Spielplans:', error) + + if (error.statusCode) { + throw error + } + + throw createError({ + statusCode: 500, + statusMessage: 'Fehler beim Generieren des Spielplans' + }) + } +})