Point 47 - GymNet Import Localization¶
Problem¶
Das Import Log Fenster beim Import von GymNet war noch nicht lokalisiert. Die "Import Information" Sektion und die Progress-Meldungen hatten hardcodierte englische und deutsche Texte.
Lösung¶
1. Import Information Box (Yellow Info Box)¶
Vorher (hardcodiert):
<h4>Import Information</h4>
<li>• Event information will be extracted and created</li>
<li>• Competitions and disciplines will be imported</li>
<li>• Participants will be added to the database</li>
<li>• Existing clubs will be updated if found</li>
<li>• Existing participants will be updated if found</li>
Nachher (lokalisiert):
<h4>{t('events.import.information.title')}</h4>
<li>• {t('events.import.information.eventInfo')}</li>
<li>• {t('events.import.information.competitions')}</li>
<li>• {t('events.import.information.participants')}</li>
<li>• {t('events.import.information.clubsUpdate')}</li>
<li>• {t('events.import.information.participantsUpdate')}</li>
2. Import Progress Messages¶
Vorher (hardcodiert):
setImportProgress({ step: 'Import completed successfully!', progress: 100 })
setImportProgress({ step: `Import failed: ${errorMessage}`, progress: 0 })
summary = `\n🎪 Event Created: "${result.createdEvent.name}" (ID: ${result.createdEvent.id})${summary}`
summary += '\n\n💾 Database Import Results:\n'
summary += ` 🏛️ Clubs: ${clubResults.inserted} new, ${clubResults.updated} updated, ${clubResults.errors} errors\n`
Nachher (lokalisiert):
setImportProgress({ step: t('events.import.progress.completed'), progress: 100 })
setImportProgress({ step: `${t('events.import.progress.failed')} ${errorMessage}`, progress: 0 })
summary = `\n🎪 ${t('events.import.progress.eventCreated', { name: result.createdEvent.name, id: result.createdEvent.id })}${summary}`
summary += `\n\n💾 ${t('events.import.progress.databaseResults')}\n`
summary += ` 🏛️ ${t('events.import.progress.clubs', { inserted: clubResults.inserted, updated: clubResults.updated, errors: clubResults.errors })}\n`
Translation Keys¶
Deutsche Übersetzungen (de.json)¶
"import": {
// ... existing keys ...
"information": {
"title": "Import-Informationen",
"eventInfo": "Veranstaltungsinformationen werden extrahiert und erstellt",
"competitions": "Wettkämpfe und Disziplinen werden importiert",
"participants": "Teilnehmer werden zur Datenbank hinzugefügt",
"clubsUpdate": "Bestehende Vereine werden aktualisiert, falls vorhanden",
"participantsUpdate": "Bestehende Teilnehmer werden aktualisiert, falls vorhanden"
},
"progress": {
"completed": "Import erfolgreich abgeschlossen!",
"failed": "Import fehlgeschlagen:",
"eventCreated": "Veranstaltung erstellt: \"{name}\" (ID: {id})",
"databaseResults": "Datenbank-Import-Ergebnisse:",
"clubs": "Vereine: {inserted} neu, {updated} aktualisiert, {errors} Fehler",
"participants": "Teilnehmer: {inserted} neu, {updated} aktualisiert, {errors} Fehler",
"competitions": "Wettkämpfe: {inserted} neu, {updated} aktualisiert, {errors} Fehler",
"disciplines": "Disziplinen: {inserted} neu, {updated} aktualisiert, {errors} Fehler"
}
}
Englische Übersetzungen (en.json)¶
"import": {
// ... existing keys ...
"information": {
"title": "Import Information",
"eventInfo": "Event information will be extracted and created",
"competitions": "Competitions and disciplines will be imported",
"participants": "Participants will be added to the database",
"clubsUpdate": "Existing clubs will be updated if found",
"participantsUpdate": "Existing participants will be updated if found"
},
"progress": {
"completed": "Import completed successfully!",
"failed": "Import failed:",
"eventCreated": "Event Created: \"{name}\" (ID: {id})",
"databaseResults": "Database Import Results:",
"clubs": "Clubs: {inserted} new, {updated} updated, {errors} errors",
"participants": "Participants: {inserted} new, {updated} updated, {errors} errors",
"competitions": "Competitions: {inserted} new, {updated} updated, {errors} errors",
"disciplines": "Disciplines: {inserted} new, {updated} updated, {errors} errors"
}
}
String Interpolation¶
Die Progress-Messages verwenden i18next String-Interpolation für dynamische Werte:
// Beispiel: Event Creation
t('events.import.progress.eventCreated', {
name: result.createdEvent.name,
id: result.createdEvent.id
})
// Output (DE): Veranstaltung erstellt: "TestEvent" (ID: 123)
// Output (EN): Event Created: "TestEvent" (ID: 123)
// Beispiel: Database Results
t('events.import.progress.clubs', {
inserted: 5,
updated: 3,
errors: 0
})
// Output (DE): Vereine: 5 neu, 3 aktualisiert, 0 Fehler
// Output (EN): Clubs: 5 new, 3 updated, 0 errors
Betroffene Komponenten¶
client/src/pages/Events.tsx¶
- Import Information Box: Zeilen 854-862
- handleImportFile Success: Zeilen 371-393
- handleImportFile Error: Zeilen 410-414
client/src/i18n/locales/de.json¶
- events.import.information: 6 neue Keys
- events.import.progress: 8 neue Keys
client/src/i18n/locales/en.json¶
- events.import.information: 6 neue Keys
- events.import.progress: 8 neue Keys
Testing¶
Manuelles Testing¶
- Open Events page: http://localhost:5173/events
- Click "Veranstaltung importieren" / "Import Event"
- Verify Import Information Box ist lokalisiert:
- Header zeigt "Import-Informationen" (DE) oder "Import Information" (EN)
- Alle 5 Bullet Points sind übersetzt
- Select a Gymnet XML file
- Fill in event name and click "Importieren" / "Import"
- Verify Progress Messages sind lokalisiert:
- Success message: "Import erfolgreich abgeschlossen!" (DE) / "Import completed successfully!" (EN)
- Event creation: "Veranstaltung erstellt: ..." (DE) / "Event Created: ..." (EN)
- Database results header: "Datenbank-Import-Ergebnisse:" (DE) / "Database Import Results:" (EN)
- Result lines: "Vereine: X neu, Y aktualisiert, Z Fehler" (DE) / "Clubs: X new, Y updated, Z errors" (EN)
- Test Error Case: Use invalid XML file
- Verify error message: "Import fehlgeschlagen: ..." (DE) / "Import failed: ..." (EN)
Language Switching¶
- Start with German (default)
- Verify all texts in German
- Switch to English via language selector
- Verify all texts in English
- Import another file
- Verify progress messages in English
Ergebnis¶
✅ Vollständig lokalisiert: - Import Information Box (5 Texte) - Progress Messages (Success) - Progress Messages (Error) - Event Creation Message - Database Import Results (4 Kategorien mit Zählern)
✅ Build Status: - Client kompiliert ohne Fehler - Keine TypeScript-Fehler - Build-Zeit: 6.69s
✅ Translation Coverage: - 14 neue Translation Keys hinzugefügt - Alle Keys in DE und EN vorhanden - String-Interpolation funktioniert korrekt
Vorteile¶
- Konsistenz: Alle Texte verwenden das zentrale Translation-System
- Wartbarkeit: Änderungen an Texten nur in JSON-Dateien nötig
- Erweiterbarkeit: Weitere Sprachen können einfach hinzugefügt werden
- Benutzererfahrung: Import-Prozess vollständig in Benutzersprache
- Professionalität: Keine gemischten Sprachen mehr im UI
Hinweis¶
Die Server-seitigen Import-Log-Nachrichten (in server/src/routes/events.ts) bleiben auf Deutsch, da sie:
- Nur im Server-Log erscheinen (nicht im UI)
- Für Debugging-Zwecke gedacht sind
- Nicht vom Endbenutzer gesehen werden
Falls gewünscht, können diese später ebenfalls lokalisiert werden, aber das ist nicht Teil von Point 47.