dev #46

Merged
admin merged 13 commits from dev into main 2026-07-17 14:00:13 +02:00
2 changed files with 41 additions and 19 deletions
Showing only changes of commit 1beb5c2eee - Show all commits

View File

@@ -204,20 +204,27 @@
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Spielplan-Team-IDs</label>
<select
:value="selectedSpielplanTeamIds"
multiple
size="4"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
:disabled="isSaving"
@change="updateSpielplanTeamIds"
>
<option v-for="team in spielplanTeams" :key="team.id" :value="team.id">
{{ team.label }}
</option>
</select>
<div class="max-h-48 overflow-y-auto rounded-lg border border-gray-300 divide-y divide-gray-100">
<label
v-for="team in spielplanTeams"
:key="team.id"
class="flex items-start gap-3 px-4 py-3 cursor-pointer hover:bg-gray-50"
>
<input
:checked="selectedSpielplanTeamIds.includes(team.id)"
type="checkbox"
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
:disabled="isSaving"
@change="toggleSpielplanTeamId(team.id, $event.target.checked)"
>
<span class="text-sm text-gray-800">{{ team.label }}</span>
</label>
<p v-if="!spielplanTeams.length" class="px-4 py-3 text-sm text-gray-500">
Noch keine importierten Spielplan-Teams verfügbar.
</p>
</div>
<p class="mt-1 text-xs text-gray-500">
Nach dem myTischtennis-Import alle passenden Einträge auswählen (z. B. Liga und Pokal). Mit Strg bzw. Cmd lassen sich mehrere Einträge markieren.
Alle passenden Einträge auswählen (z. B. Liga und Pokal). Die Auswahl wird beim Speichern beibehalten.
</p>
</div>
<div>
@@ -447,8 +454,11 @@ function parseSpielerString(s) { if (!s) return []; return String(s).split(';').
function serializeSpielerList(list) { return (list || []).map(s => (s?.name || '').trim()).filter(Boolean).join('; ') }
function serializeSpielerNames(names) { return (names || []).map(s => String(s || '').trim()).filter(Boolean).join('; ') }
const selectedSpielplanTeamIds = computed(() => String(formData.value.spielplan_mannschaft_id || '').split(',').map(id => id.trim()).filter(Boolean))
const updateSpielplanTeamIds = (event) => {
formData.value.spielplan_mannschaft_id = Array.from(event.target.selectedOptions, option => option.value).join(',')
const toggleSpielplanTeamId = (id, checked) => {
const ids = new Set(selectedSpielplanTeamIds.value)
if (checked) ids.add(id)
else ids.delete(id)
formData.value.spielplan_mannschaft_id = [...ids].join(',')
}
async function fetchCsvText(url) {

View File

@@ -54,8 +54,9 @@ function romanToNumber(value) {
return result || null
}
function getCmsTeamCriteria(name) {
const youth = String(name || '').trim().match(/^jugend\s+j(\d{1,2})(?:\s+([ivx]+|\d+))?\b/i)
function getCmsTeamCriteria(name, league) {
const teamName = String(name || '').trim()
const youth = teamName.match(/^jugend\s+j(\d{1,2})(?:\s+([ivx]+|\d+))?\b/i)
if (youth) {
const rawNumber = youth[2]
return {
@@ -64,7 +65,18 @@ function getCmsTeamCriteria(name) {
}
}
const adult = String(name || '').trim().match(/^erwachsene\s+(\d+)\b/i)
// In bestehenden CMS-Daten steht die Altersklasse häufig nur in der Liga,
// z. B. Mannschaft "Jugend I" mit Liga "Jugend 13 (J13)".
const ageMatch = `${teamName} ${String(league || '')}`.match(/\b(?:jugend\s*|j\s*\(?)(\d{1,2})\b/i)
if (ageMatch) {
const ordinal = teamName.match(/^jugend\s+([ivx]+|\d+)\b/i)?.[1]
return {
ageClass: `Jugend ${ageMatch[1]}`,
teamNumber: ordinal ? (Number(ordinal) || romanToNumber(ordinal)) : null
}
}
const adult = teamName.match(/^erwachsene\s+(\d+)\b/i)
if (adult) return { ageClass: 'Erwachsene', teamNumber: Number(adult[1]) }
return null
}
@@ -114,7 +126,7 @@ export async function synchronizeMannschaftenSpielplanIds(seasonSlug) {
let updatedTeams = 0
for (const row of parsed.slice(1)) {
const criteria = getCmsTeamCriteria(row[0])
const criteria = getCmsTeamCriteria(row[0], row[1])
if (!criteria) continue
const ids = importedTeams
.filter(team => team.ageClass === criteria.ageClass && (!criteria.teamNumber || team.teamNumber === criteria.teamNumber))