diff --git a/backend/app.js b/backend/app.js index 77d5c65..869cc66 100644 --- a/backend/app.js +++ b/backend/app.js @@ -16,6 +16,7 @@ import match3Router from './routers/match3Router.js'; import taxiRouter from './routers/taxiRouter.js'; import taxiMapRouter from './routers/taxiMapRouter.js'; import taxiHighscoreRouter from './routers/taxiHighscoreRouter.js'; +import termineRouter from './routers/termineRouter.js'; import cors from 'cors'; import './jobs/sessionCleanup.js'; @@ -52,6 +53,7 @@ app.use('/api/forum', forumRouter); app.use('/api/falukant', falukantRouter); app.use('/api/friendships', friendshipRouter); app.use('/api/blog', blogRouter); +app.use('/api/termine', termineRouter); // Serve frontend SPA for non-API routes to support history mode clean URLs const frontendDir = path.join(__dirname, '../frontend'); diff --git a/backend/controllers/termineController.js b/backend/controllers/termineController.js new file mode 100644 index 0000000..d8e2578 --- /dev/null +++ b/backend/controllers/termineController.js @@ -0,0 +1,43 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +class TermineController { + async getTermine(req, res) { + try { + const csvPath = path.join(__dirname, '../data/termine.csv'); + const csvContent = fs.readFileSync(csvPath, 'utf-8'); + + const lines = csvContent.trim().split('\n'); + const headers = lines[0].split(','); + + const termine = lines.slice(1).map(line => { + const values = line.split(','); + const termin = {}; + headers.forEach((header, index) => { + termin[header] = values[index] || ''; + }); + return termin; + }); + + // Sortiere nach Datum + termine.sort((a, b) => new Date(a.datum) - new Date(b.datum)); + + // Filtere nur zukünftige Termine + const heute = new Date(); + heute.setHours(0, 0, 0, 0); + const zukuenftigeTermine = termine.filter(t => new Date(t.datum) >= heute); + + res.status(200).json(zukuenftigeTermine); + } catch (error) { + console.error('Error reading termine.csv:', error); + res.status(500).json({ error: 'Could not load termine' }); + } + } +} + +export default new TermineController(); + diff --git a/backend/data/termine.csv b/backend/data/termine.csv new file mode 100644 index 0000000..963842b --- /dev/null +++ b/backend/data/termine.csv @@ -0,0 +1,7 @@ +datum,titel,beschreibung,ort,uhrzeit +2025-10-07,Vereinsmeisterschaften 2025 Doppel,Die Vereinsmeisterschaften 2025 im Doppel finden im Rahmen des Erwachsenentrainings statt.,,, +2026-01-17,Vereinsmeisterschaften 2025 Einzel,Die Vereinsmeisterschaften 2025 im Einzel finden in der Schulturnhalle statt. Bitte vormerken!,,10:00 +2025-12-18,Weihnachtsfeier 2025,Die Weihnachtsfeier 2025 findet im Gasthaus „Zum Einhorn" in FFM-Bonames statt. Beginn 19:00 Uhr (bitte vormerken),Gasthaus „Zum Einhorn" FFM-Bonames,19:00 +2025-09-14,VR-Cup,Zwei VR-Cups am 14.09.2025 (jeweils 12 und 16 Uhr),,12:00 und 16:00 +2025-10-19,VR-Cup,Zwei VR-Cups am 19.10.2025 (jeweils 12 und 16 Uhr),,12:00 und 16:00 + diff --git a/backend/routers/termineRouter.js b/backend/routers/termineRouter.js new file mode 100644 index 0000000..ec907a0 --- /dev/null +++ b/backend/routers/termineRouter.js @@ -0,0 +1,9 @@ +import express from 'express'; +import termineController from '../controllers/termineController.js'; + +const router = express.Router(); + +router.get('/', termineController.getTermine); + +export default router; + diff --git a/frontend/src/components/TermineWidget.vue b/frontend/src/components/TermineWidget.vue new file mode 100644 index 0000000..e218eff --- /dev/null +++ b/frontend/src/components/TermineWidget.vue @@ -0,0 +1,151 @@ + + + + + + diff --git a/frontend/src/views/home/LoggedInView.vue b/frontend/src/views/home/LoggedInView.vue index d4ea93d..c72236a 100644 --- a/frontend/src/views/home/LoggedInView.vue +++ b/frontend/src/views/home/LoggedInView.vue @@ -1,17 +1,25 @@ \ No newline at end of file