- S/U/N
+ S
+ |
+
+ U
+ |
+
+ N
|
Sätze
|
-
- Bälle
- |
Punkte
|
@@ -262,13 +265,16 @@
{{ row.meetings_count ?? '-' }}
- {{ formatSun(row) }}
+ {{ row.meetings_won ?? 0 }}
|
- {{ row.sets_relation || '-' }}
+ {{ row.meetings_tie ?? 0 }}
|
- {{ row.games_relation || '-' }}
+ {{ row.meetings_lost ?? 0 }}
+ |
+
+ {{ formatSaetze(row) }}
|
{{ formatPunkte(row) }}
@@ -364,6 +370,15 @@ const spielplanSeasonLabel = computed(() => {
return match ? `20${match[1]}/${match[2]}` : ''
})
+const mannschaftSeasonLabel = computed(() => {
+ if (spielplanSeasonLabel.value) return spielplanSeasonLabel.value
+
+ const now = new Date()
+ const year = now.getFullYear()
+ const start = now.getMonth() >= 6 ? year : year - 1
+ return `${start}/${String(start + 1).slice(-2)}`
+})
+
async function fetchCsvText(url) {
const attempt = async () => {
const withBuster = `${url}${url.includes('?') ? '&' : '?'}_t=${Date.now()}`
@@ -650,12 +665,11 @@ const getRowClass = (row) => {
return 'bg-white'
}
-const formatSun = (row) => {
- const s = row?.meetings_won
- const u = row?.meetings_tie
- const n = row?.meetings_lost
- if (s == null && u == null && n == null) return '-'
- return `${s ?? 0}/${u ?? 0}/${n ?? 0}`
+const formatSaetze = (row) => {
+ const won = row?.sets_won
+ const lost = row?.sets_lost
+ if (won == null && lost == null) return row?.sets_relation || '-'
+ return `${won ?? 0}:${lost ?? 0}`
}
const formatPunkte = (row) => {
diff --git a/server/api/cms/save-csv.post.js b/server/api/cms/save-csv.post.js
index b54d7cc..cb04f52 100644
--- a/server/api/cms/save-csv.post.js
+++ b/server/api/cms/save-csv.post.js
@@ -51,8 +51,9 @@ export default defineEventHandler(async (event) => {
'termine.csv',
'spielplan.csv'
]
+ const isSeasonalMannschaftenFile = /^mannschaften_\d{2}--\d{2}\.csv$/.test(String(filename))
- if (!allowedFiles.includes(filename)) {
+ if (!allowedFiles.includes(filename) && !isSeasonalMannschaftenFile) {
throw createError({
statusCode: 403,
statusMessage: 'Datei nicht erlaubt'
@@ -105,7 +106,9 @@ export default defineEventHandler(async (event) => {
'termine.csv': [`${cwd}/server/data/public-data/termine.csv`, `${cwd}/../server/data/public-data/termine.csv`],
'spielplan.csv': [`${cwd}/server/data/public-data/spielplan.csv`, `${cwd}/../server/data/public-data/spielplan.csv`]
}
- const internalPaths = dataTargetsByFile[filename] || []
+ const internalPaths = isSeasonalMannschaftenFile
+ ? [`${cwd}/server/data/public-data/${filename}`, `${cwd}/../server/data/public-data/${filename}`]
+ : (dataTargetsByFile[filename] || [])
const uniquePaths = [...new Set([...internalPaths])]
const writeResults = []
diff --git a/server/api/mannschaften.get.js b/server/api/mannschaften.get.js
index 22f73d8..374528b 100644
--- a/server/api/mannschaften.get.js
+++ b/server/api/mannschaften.get.js
@@ -1,5 +1,10 @@
import { promises as fs } from 'fs'
import path from 'path'
+import { getCurrentSeasonSlug, validateSeasonSlug } from '../utils/spielplan-data.js'
+
+function normalizeSeasonFilename(season) {
+ return `mannschaften_${season}.csv`
+}
async function exists(p) {
try {
@@ -13,20 +18,36 @@ async function exists(p) {
export default defineEventHandler(async (event) => {
try {
const cwd = process.cwd()
- const filename = 'mannschaften.csv'
+ const query = getQuery(event)
+ const requestedSeason = query.season ? String(query.season).trim() : ''
+
+ if (requestedSeason && !validateSeasonSlug(requestedSeason)) {
+ throw createError({
+ statusCode: 400,
+ statusMessage: 'Ungueltiger Saison-Slug'
+ })
+ }
+
+ const defaultSeason = getCurrentSeasonSlug()
+ const candidateFileNames = requestedSeason
+ ? [normalizeSeasonFilename(requestedSeason), 'mannschaften.csv']
+ : [normalizeSeasonFilename(defaultSeason), 'mannschaften.csv']
// Prefer CMS write target first (server/data/public-data),
// then legacy locations.
- const candidates = [
- path.join(cwd, 'server/data/public-data', filename),
- path.join(cwd, '../server/data/public-data', filename),
- path.join(cwd, '.output/server/data', filename),
- path.join(cwd, 'server/data', filename),
- path.join(cwd, '.output/public/data', filename),
- path.join(cwd, 'public/data', filename),
- path.join(cwd, '../.output/public/data', filename),
- path.join(cwd, '../public/data', filename)
- ]
+ const candidates = []
+ for (const filename of candidateFileNames) {
+ candidates.push(
+ path.join(cwd, 'server/data/public-data', filename),
+ path.join(cwd, '../server/data/public-data', filename),
+ path.join(cwd, '.output/server/data', filename),
+ path.join(cwd, 'server/data', filename),
+ path.join(cwd, '.output/public/data', filename),
+ path.join(cwd, 'public/data', filename),
+ path.join(cwd, '../.output/public/data', filename),
+ path.join(cwd, '../public/data', filename)
+ )
+ }
let csvPath = null
for (const p of candidates) {
|