Add league configuration endpoint and frontend integration for myTischtennis
Implemented a new POST endpoint in MyTischtennisUrlController to configure leagues from table URLs, including season creation logic. Updated myTischtennisRoutes to include the new route for league configuration. Enhanced the myTischtennisUrlParserService to support parsing of table URLs and added a method for decoding group names. Updated TeamManagementView.vue to prompt users for league configuration when a table URL is detected, providing feedback upon successful configuration and reloading relevant data.
This commit is contained in:
@@ -15,14 +15,28 @@ class MyTischtennisUrlParserService {
|
||||
// Remove trailing slash if present
|
||||
url = url.trim().replace(/\/$/, '');
|
||||
|
||||
// Extract parts using regex
|
||||
// Pattern: /click-tt/{association}/{season}/{type}/{groupname}/gruppe/{groupId}/mannschaft/{teamId}/{teamname}/...
|
||||
const pattern = /\/click-tt\/([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)\/gruppe\/([^\/]+)\/mannschaft\/([^\/]+)\/([^\/]+)/;
|
||||
// Try different URL patterns
|
||||
|
||||
const match = url.match(pattern);
|
||||
// Pattern 1: Team URL with mannschaft/{teamId}/{teamname}
|
||||
// /click-tt/{association}/{season}/{type}/{groupname}/gruppe/{groupId}/mannschaft/{teamId}/{teamname}/...
|
||||
const teamPattern = /\/click-tt\/([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)\/gruppe\/([^\/]+)\/mannschaft\/([^\/]+)\/([^\/]+)/;
|
||||
|
||||
// Pattern 2: Table/Group URL without team info
|
||||
// /click-tt/{association}/{season}/{type}/{groupname}/gruppe/{groupId}/tabelle/gesamt
|
||||
const tablePattern = /\/click-tt\/([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)\/gruppe\/([^\/]+)\/tabelle\/([^\/]+)/;
|
||||
|
||||
let match = url.match(teamPattern);
|
||||
let isTeamUrl = true;
|
||||
|
||||
if (!match) {
|
||||
throw new Error('URL format not recognized. Expected format: /click-tt/{association}/{season}/{type}/{groupname}/gruppe/{groupId}/mannschaft/{teamId}/{teamname}/...');
|
||||
match = url.match(tablePattern);
|
||||
isTeamUrl = false;
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
throw new Error('URL format not recognized. Expected formats:\n' +
|
||||
'- Team URL: /click-tt/{association}/{season}/{type}/{groupname}/gruppe/{groupId}/mannschaft/{teamId}/{teamname}/...\n' +
|
||||
'- Table URL: /click-tt/{association}/{season}/{type}/{groupname}/gruppe/{groupId}/tabelle/gesamt');
|
||||
}
|
||||
|
||||
const [
|
||||
@@ -32,28 +46,38 @@ class MyTischtennisUrlParserService {
|
||||
type,
|
||||
groupnameEncoded,
|
||||
groupId,
|
||||
teamId,
|
||||
teamnameEncoded
|
||||
...rest
|
||||
] = match;
|
||||
|
||||
// Decode and process values
|
||||
const seasonShort = seasonRaw.replace('--', '/'); // "25--26" -> "25/26"
|
||||
const season = this.convertToFullSeason(seasonShort); // "25/26" -> "2025/2026"
|
||||
const groupname = decodeURIComponent(groupnameEncoded);
|
||||
const teamname = decodeURIComponent(teamnameEncoded).replace(/_/g, ' '); // "Harheimer_TC_(J11)" -> "Harheimer TC (J11)"
|
||||
const groupnameDecoded = this.decodeGroupName(groupnameEncoded);
|
||||
|
||||
const result = {
|
||||
association,
|
||||
season,
|
||||
seasonShort, // Für API-Calls
|
||||
type,
|
||||
groupname,
|
||||
groupname: groupnameDecoded, // Dekodierte Version für Anzeige
|
||||
groupnameOriginal: groupnameEncoded, // Originale URL-kodierte Version
|
||||
groupId,
|
||||
teamId,
|
||||
teamname,
|
||||
originalUrl: url
|
||||
originalUrl: url,
|
||||
urlType: isTeamUrl ? 'team' : 'table'
|
||||
};
|
||||
|
||||
if (isTeamUrl) {
|
||||
// Team URL: extract team info
|
||||
const [teamId, teamnameEncoded] = rest;
|
||||
const teamname = decodeURIComponent(teamnameEncoded).replace(/_/g, ' '); // "Harheimer_TC_(J11)" -> "Harheimer TC (J11)"
|
||||
result.teamId = teamId;
|
||||
result.teamname = teamname;
|
||||
} else {
|
||||
// Table URL: no team info
|
||||
result.teamId = null;
|
||||
result.teamname = null;
|
||||
}
|
||||
|
||||
devLog('Parsed myTischtennis URL:', result);
|
||||
|
||||
return result;
|
||||
@@ -63,6 +87,23 @@ class MyTischtennisUrlParserService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode group name from URL-encoded format
|
||||
* "2._Kreisklasse_Gr._2" -> "2. Kreisklasse Gr. 2"
|
||||
*/
|
||||
decodeGroupName(encodedName) {
|
||||
// First decode URI components
|
||||
let decoded = decodeURIComponent(encodedName);
|
||||
|
||||
// Replace underscores with spaces
|
||||
decoded = decoded.replace(/_/g, ' ');
|
||||
|
||||
// Clean up multiple spaces
|
||||
decoded = decoded.replace(/\s+/g, ' ');
|
||||
|
||||
return decoded.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert short season format to full format
|
||||
* "25/26" -> "2025/2026"
|
||||
@@ -214,6 +255,10 @@ class MyTischtennisUrlParserService {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
isValidUrl(url) {
|
||||
return this.isValidTeamUrl(url); // Alias for backward compatibility
|
||||
}
|
||||
|
||||
/**
|
||||
* Build myTischtennis URL from components
|
||||
@@ -229,16 +274,23 @@ class MyTischtennisUrlParserService {
|
||||
groupname,
|
||||
groupId,
|
||||
teamId,
|
||||
teamname
|
||||
teamname,
|
||||
urlType = 'team'
|
||||
} = config;
|
||||
|
||||
// Convert full season to short format for URL
|
||||
const seasonShort = this.convertToShortSeason(season);
|
||||
const seasonStr = seasonShort.replace('/', '--');
|
||||
const teamnameEncoded = encodeURIComponent(teamname.replace(/\s/g, '_'));
|
||||
const groupnameEncoded = encodeURIComponent(groupname);
|
||||
|
||||
return `https://www.mytischtennis.de/click-tt/${association}/${seasonStr}/${type}/${groupnameEncoded}/gruppe/${groupId}/mannschaft/${teamId}/${teamnameEncoded}/spielerbilanzen/gesamt`;
|
||||
if (urlType === 'table' || !teamId || !teamname) {
|
||||
// Build table URL
|
||||
return `https://www.mytischtennis.de/click-tt/${association}/${seasonStr}/${type}/${groupnameEncoded}/gruppe/${groupId}/tabelle/gesamt`;
|
||||
} else {
|
||||
// Build team URL
|
||||
const teamnameEncoded = encodeURIComponent(teamname.replace(/\s/g, '_'));
|
||||
return `https://www.mytischtennis.de/click-tt/${association}/${seasonStr}/${type}/${groupnameEncoded}/gruppe/${groupId}/mannschaft/${teamId}/${teamnameEncoded}/spielerbilanzen/gesamt`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user