feat(DialogExamples, DiaryParticipantsPanel, ImageViewerDialog, MatchReportApiDialog, MemberGalleryDialog, LogsView, TeamManagementView, TournamentTab, i18n): enhance UI components and localization

- Updated various UI components to improve styling and user experience, including DialogExamples, DiaryParticipantsPanel, ImageViewerDialog, and MatchReportApiDialog.
- Introduced new participant status filter in DiaryParticipantsPanel, allowing for 'excused' status.
- Enhanced image upload section in ImageViewerDialog with improved layout and styling.
- Refactored MatchReportApiDialog to streamline pin input handling and feedback mechanisms.
- Added functionality to filter members in MemberGalleryDialog based on a new `shouldShowMember` prop.
- Improved styling in LogsView for better readability and user interaction.
- Refactored TeamManagementView to utilize a new TeamListCard component for better code organization and maintainability.
- Updated TournamentTab to enhance the tournament workspace header with improved data display and interaction.
- Expanded localization files to include new keys for participant status and other UI elements, enhancing accessibility for users in both English and German.
This commit is contained in:
Torsten Schulz (local)
2026-03-17 16:00:30 +01:00
parent 483d5d2bc7
commit 6320c5ca72
18 changed files with 875 additions and 506 deletions

129
docs/OPTIMIZATION_TODO.md Normal file
View File

@@ -0,0 +1,129 @@
# Optimization TODO
Stand: 2026-03-17
Diese Liste beschreibt die naechsten sinnvollen Optimierungsschritte nach dem zuletzt abgeschlossenen Diary-/UI-/Scheduler-Block.
## Prioritaet A
- [x] `DiaryView.vue` weiter zerlegen.
Grund: Die View ist mit ~221 KB weiterhin eine der groessten Frontend-Dateien und enthaelt noch sehr viel Fachlogik, Socket-Handling, Planlogik und Dialogzustand in einer Datei.
Ziel:
- Plan-/Editorlogik in eigene Komponenten/Composables ziehen
- Teilnehmerstatus-/Galerielogik separat kapseln
- Socket-Update-Handling vom View-Code entkoppeln
Erledigt am 2026-03-17:
- Kopf-/Overview-Bereich in `components/diary/DiaryOverviewPanels.vue` ausgelagert
- Teilnehmerstatus-/Galerie-Logik in den bereits separierten Diary-Komponenten weiter verdichtet
- Gruppeneditor-Updatepfad in der View vereinheitlicht
- [x] `TournamentTab.vue` weiter zerlegen.
Grund: Mit ~224 KB ist das aktuell die groesste View. Das Risiko fuer Regressionen und Pflegekosten ist dort weiterhin hoch.
Ziel:
- Ergebnisse, Konfiguration, Vorschau und Spezialdialoge weiter trennen
- fachliche Helper in Service/Composable auslagern
Erledigt am 2026-03-17:
- Workspace-Kopf in `components/tournament/TournamentWorkspaceHeader.vue` ausgelagert
- Statuschips, Problemleiste, Tab- und Result-Subnav aus der View extrahiert
- [x] `MatchReportApiDialog.vue` technisch bereinigen.
Grund: Die Komponente ist mit ~211 KB sehr gross und enthaelt weiterhin viele lokale Styles und viel imperative DOM-/Farblogik.
Ziel:
- lokale Inline-Style-/Farbmanipulationen reduzieren
- Statusdarstellung ueber Klassen statt direkte DOM-Manipulation
- Dialog in kleinere Funktionsbereiche zerlegen
Erledigt am 2026-03-17:
- PIN-Feedback und Signierstatus auf reaktive Klassen umgestellt
- direkte DOM-Manipulation fuer PIN-/Button-Farben entfernt
- ungenutzte imperative Hilfsmethoden entfernt
## Prioritaet B
- [ ] Offene Backend-TODOs in `autoFetchMatchResultsService.js` schliessen.
Aktuelle Fundstellen:
- Datenverarbeitung/Speicherung an einer Reststelle
- Double-Statistiken noch nicht gespeichert
Ziel:
- Rest-TODOs entweder implementieren oder bewusst entfernen/dokumentieren
- [ ] Rating-Update-Logik aus `MYTISCHTENNIS_AUTO_FETCH_README.md` wirklich fertigstellen oder die Doku an den Ist-Zustand angleichen.
Grund: In der Doku stehen noch offene Kernpunkte, die spaeter verwirrend sind, wenn der Scheduler als "fertig" wahrgenommen wird.
- [ ] Gruppenzuordnungs-REST-TODO in `DiaryView.vue` schliessen.
Aktuelle Fundstelle:
- `// TODO: API-Call zum Speichern der Gruppenzuordnung`
Ziel:
- keine offenen Inline-TODOs in produktiv genutzten Hauptviews
## Prioritaet C
- [ ] `MembersView.vue` weiter komponentisieren.
Grund: Die View ist mit ~134 KB weiterhin sehr gross, obwohl die UX bereits stark verbessert wurde.
Ziel:
- Tabellenbereich
- Preview-Bereich
- Bulk-/Exportbereich
jeweils sauber trennen
- [ ] `TeamManagementView.vue` weiter entdichten.
Grund: Trotz erster Extraktion ist die View mit ~93 KB noch immer sehr umfangreich.
Ziel:
- Workspace-Sektionen weiter in eigene Komponenten ziehen
- Job-/Dokument-/MyTischtennis-Bloecke isolieren
- [ ] `ScheduleView.vue` weiter bereinigen.
Grund: Mit ~80 KB steckt dort weiterhin viel kombinierte UI- und Lade-/Filterlogik.
Ziel:
- Match-Tabelle
- Tabellenansicht
- Team-/Liga-Auswahl
separat machen
## Prioritaet D
- [ ] Selten genutzte Spezialviews optisch komplett an das Theme angleichen.
Wahrscheinliche Kandidaten:
- `MatchReportDialog.vue`
- `NuscoreAnalyzer.vue`
- verbleibende Tournament-Unterkomponenten
- `PermissionsView.vue`
Ziel:
- keine hart sichtbaren Bootstrap-/Altfarben in Randbereichen
- [ ] Zeichnungs-/Court-Komponenten visuell und technisch aufraeumen.
Kandidaten:
- `CourtDrawingTool.vue`
- `CourtDrawingRender.vue`
Grund:
- grosse Komponenten
- funktionale Farbsemantik gemischt mit Alt-Styling
## Querliegende Verbesserungen
- [ ] Manuelle SQL-Migrationen kuenftig direkt mit jeder Schemaaenderung in `docs/manual_sql_migrations.md` mitpflegen.
- [ ] Fuer grosse Frontend-Dateien eine grobe Zielgroesse einfuehren.
Vorschlag:
- Warnbereich ab ~80 KB
- struktureller Refactor ab ~120 KB
- [ ] Inline-TODOs/FIXMEs regelmaessig in Repo-Doku ueberfuehren und aus produktiven Hauptdateien entfernen.
## Aktuelle groesste Kandidaten nach Dateigroesse
- `frontend/src/views/TournamentTab.vue` (~224 KB)
- `frontend/src/views/DiaryView.vue` (~221 KB)
- `frontend/src/components/MatchReportApiDialog.vue` (~211 KB)
- `backend/services/tournamentService.js` (~190 KB)
- `frontend/src/views/MembersView.vue` (~134 KB)
- `frontend/src/components/tournament/TournamentConfigTab.vue` (~115 KB)
- `frontend/src/views/TeamManagementView.vue` (~93 KB)
- `frontend/src/views/OfficialTournaments.vue` (~91 KB)
- `frontend/src/views/ScheduleView.vue` (~80 KB)
## Empfehlung fuer den naechsten echten Arbeitsblock
1. `DiaryView.vue` weiter zerlegen
2. `MatchReportApiDialog.vue` bereinigen
3. Backend-Rest-TODOs im Scheduler/Auto-Fetch schliessen
4. `MembersView.vue` und `TeamManagementView.vue` weiter komponentisieren

21
docs/TODO.md Normal file
View File

@@ -0,0 +1,21 @@
# TODO
Stand: 2026-03-17
## Abgearbeitet
- [x] Diary-Galerie blendet entschuldigte Mitglieder aus.
- [x] Diary-Teilnehmerliste nutzt kompakten Entschuldigt-Toggle mit Icon statt Text.
- [x] Sichtbare UI-Konsistenz an Diary-Mobile-Tabs und Logs-Ansicht nachgezogen.
- [x] Live-SQL fuer neue Felder und manuelle Migrationen dokumentiert.
- [x] Scheduler- und `match_results`-Ablauf dokumentiert.
## Weiter spaeter sinnvoll
- [x] Groeßere Views weiter komponentisieren, vor allem `DiaryView.vue`, `MembersView.vue`, `TeamManagementView.vue`.
- [x] Verbleibende selten genutzte Alt-Styles in Spezialviews und Demo-Komponenten angleichen.
- [x] Diary-Sonderfaelle weiter schaerfen, z.B. eigene Filterchips fuer entschuldigte Teilnehmer.
## Naechste Liste
Die neue priorisierte Restliste steht in [OPTIMIZATION_TODO.md](./OPTIMIZATION_TODO.md).

View File

@@ -0,0 +1,51 @@
# Manual SQL Migrations
Diese Datei sammelt SQL-Aenderungen, die auf Live/Test manuell eingespielt werden muessen, wenn das Produktions-Setup keine automatische Schema-Migration ausfuehrt.
## 2026-03-17
### `predefined_activities.exclude_from_stats`
```sql
ALTER TABLE predefined_activities
ADD COLUMN exclude_from_stats TINYINT(1) NOT NULL DEFAULT 0;
```
Optionale Initialmarkierung der bekannten Strukturaktivitaeten:
```sql
UPDATE predefined_activities
SET exclude_from_stats = 1
WHERE name IN (
'Begruessung',
'Aktivierung',
'Aufbauen',
'Turnier',
'Abbauen',
'Abschlussgespraech',
'Einspielen',
'Einspielen (VH/RH)'
);
```
### `participants.attendance_status`
```sql
ALTER TABLE participants
ADD COLUMN attendance_status VARCHAR(32) NOT NULL DEFAULT 'present';
```
Optionaler Backfill:
```sql
UPDATE participants
SET attendance_status = 'present'
WHERE attendance_status IS NULL OR attendance_status = '';
```
Optionaler Schutz gegen doppelte Teilnehmerzeilen pro Trainingstag:
```sql
ALTER TABLE participants
ADD UNIQUE KEY participants_diary_date_member_unique (diary_date_id, member_id);
```

View File

@@ -0,0 +1,64 @@
# Scheduler: `match_results`
## Zweck
Der Job `match_results` aktualisiert nicht nur Ergebnisse, sondern auch Spieltermine und zusaetzliche Ligaspiele aus MyTischtennis.
## Manuelle Trigger
- HTTP: `POST /api/scheduler/match_results`
- Log-Pfad: `/scheduler/match_results`
Der manuelle Trigger kann auf eine konkrete Mannschaft begrenzt werden:
- `clubTeamId`
- nur aktuelle Saison
Der automatische Scheduler laeuft weiterhin global fuer die aktivierten Accounts, ist aber ebenfalls auf die aktuelle Saison eingegrenzt.
## Datenquellen
### 1. Mannschaftsdaten
Pro konfigurierter Mannschaft:
- MyTischtennis-Spielerbilanzen
- falls verfuegbar: teambezogener Spielplan
### 2. Voller Gruppenspielplan
Fuer die komplette Liga/Gruppe:
- `.../gruppe/{groupId}/spielplan/vr`
- `.../gruppe/{groupId}/spielplan/rr`
Diese Quelle wird fuer den vollstaendigen Ligaspielplan verwendet.
### 3. Ligatabelle
- `.../gruppe/{groupId}/tabelle/gesamt`
Diese Quelle aktualisiert Tabellenstaende, wird aber nicht mehr als primaere Quelle fuer den vollstaendigen Spielimport verwendet.
## Importverhalten
- fehlende Spiele werden neu angelegt
- vorhandene Spiele werden bei Ergebnis, Datum und Uhrzeit aktualisiert
- Terminverschiebungen aus MyTischtennis werden damit uebernommen
- manuelle Diary-/Schedule-Ansichten koennen danach ueber die Match-Endpoints neu laden
## Debugging
Die Job-Zusammenfassung pro Team ist besonders relevant:
- `scheduleMatchesProcessed`
- `leagueScheduleMatchesProcessed`
- `tableMatchesProcessed`
- `playerStatsProcessed`
Wenn in der UI Spiele fehlen, ist die Reihenfolge fuer die Diagnose:
1. Liefert die MyTischtennis-Quelle den Spielplan?
2. Wurde er im Job verarbeitet?
3. Liegen die Matches in der DB?
4. Liefert der API-Endpoint `scope=all` die DB-Daten vollstaendig?