Initial commit: WrestleDesk full project
- Django backend with DRF (clubs, wrestlers, trainers, exercises, templates, trainings, homework, locations, leistungstest) - Next.js 16 frontend with React, Shadcn UI, Tailwind - JWT authentication - Full CRUD for all entities - Calendar view for trainings - Homework management system - Leistungstest tracking
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# Leistungstest Statistiken — Design
|
||||
|
||||
## Overview
|
||||
|
||||
Erweiterung des Leistungstest-Bereichs um Statistiken und Ranglisten auf zwei Ebenen: **Vorlagen** und **Übungen**. Filterbar nach Zeitraum (Monat / Alle Zeiten).
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Ranglisten pro Vorlage
|
||||
- Rangliste aller Wrestler nach `score_percent` (absteigend)
|
||||
- Optional: Sortierung nach `total_time_seconds` (aufsteigend = schnellste Zeit)
|
||||
- Zeitraum-Filter: "Alle Zeiten" | "Dieser Monat" | "Letzte 3 Monate" | "Dieses Jahr"
|
||||
- Anzeige: Rank, Wrestler-Name, Score %, Gesamtzeit, Datum
|
||||
|
||||
### 2. Ranglisten pro Übung
|
||||
- Für jede Übung: Rangliste nach `elapsed_seconds` (schnellste Zeit)
|
||||
- Berechnung: Beste Zeit (niedrigste elapsed_seconds) pro Wrestler pro Übung
|
||||
- Zeitraum-Filter wie oben
|
||||
- Anzeige: Rank, Wrestler-Name, Übungsname, Bestzeit, Datum
|
||||
|
||||
### 3. Ringer-Statistik (optional)
|
||||
- Pro Wrestler: Durchschnitts-Score, Anzahl Tests, Trend (besser/schlechter)
|
||||
|
||||
## Datenmodell
|
||||
|
||||
Keine neuen Modelle — Berechnung erfolgt on-the-fly aus `LeistungstestResult` und `LeistungstestResultItem`.
|
||||
|
||||
## API Endpoints (Backend)
|
||||
|
||||
### `GET /api/v1/leistungstest/stats/leaderboard/`
|
||||
Query-Parameter:
|
||||
- `type`: `"template"` | `"exercise"`
|
||||
- `template_id`: number (für template-Typ)
|
||||
- `period`: `"all"` | `"month"` | `"3months"` | `"year"`
|
||||
- `limit`: number (default: 10)
|
||||
|
||||
Response für `type=template`:
|
||||
```json
|
||||
{
|
||||
"template_id": 1,
|
||||
"template_name": "Krafttest Februar",
|
||||
"period": "all",
|
||||
"results": [
|
||||
{
|
||||
"rank": 1,
|
||||
"wrestler_id": 1,
|
||||
"wrestler_name": "Max Mustermann",
|
||||
"score_percent": 100.0,
|
||||
"total_time_seconds": 342,
|
||||
"completed_at": "2026-03-24"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Response für `type=exercise`:
|
||||
```json
|
||||
{
|
||||
"exercise_id": 1,
|
||||
"exercise_name": "Liegestütze",
|
||||
"period": "all",
|
||||
"results": [
|
||||
{
|
||||
"rank": 1,
|
||||
"wrestler_id": 1,
|
||||
"wrestler_name": "Max Mustermann",
|
||||
"best_time_seconds": 75,
|
||||
"completed_at": "2026-03-24"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/leistungstest/stats/exercises/`
|
||||
Liste aller Übungen die jemals in einem Leistungstest verwendet wurden (für Dropdown).
|
||||
|
||||
## Frontend
|
||||
|
||||
### Neuer Tab: "📊 Statistiken"
|
||||
|
||||
Tabs im Leistungstest:
|
||||
1. Vorlagen (existiert)
|
||||
2. Zuweisen (existiert)
|
||||
3. Ergebnisse (existiert, jetzt Karten-Ansicht)
|
||||
4. **📊 Statistiken** (NEU)
|
||||
|
||||
### Statistiken-Tab Layout:
|
||||
```
|
||||
[Tab: Vorlagen | Zuweisen | Ergebnisse | 📊 Statistiken]
|
||||
|
||||
📊 Statistiken
|
||||
|
||||
[Dropdowns: Vorlage auswählen | Zeitraum: Alle Zeiten ▾]
|
||||
|
||||
-tabs-
|
||||
[⊞ Nach Vorlage] [📋 Nach Übung]
|
||||
|
||||
--- Nach Vorlage ---
|
||||
Rangliste: Krafttest Februar
|
||||
1. 🥇 Max Mustermann — 100% (5:42)
|
||||
2. 🥈 Anna Schmidt — 87% (6:20)
|
||||
3. 🥉 Tom Klein — 65% (8:15)
|
||||
|
||||
--- Nach Übung ---
|
||||
Rangliste: Liegestütze
|
||||
1. 🥇 Max Mustermann — 1:15
|
||||
2. 🥈 Anna Schmidt — 1:30
|
||||
3. 🥉 Tom Klein — 2:00
|
||||
|
||||
Rangliste: Kniebeugen
|
||||
1. 🥇 Max Mustermann — 2:30
|
||||
...
|
||||
```
|
||||
|
||||
## Backend-Implementierung
|
||||
|
||||
### Neue Datei: `leistungstest/stats.py`
|
||||
```python
|
||||
def get_template_leaderboard(template_id, period="all", limit=10):
|
||||
# Filter results by template and period
|
||||
# Order by score_percent DESC, total_time_seconds ASC
|
||||
# Return top N with rank
|
||||
|
||||
def get_exercise_leaderboard(exercise_id, period="all", limit=10):
|
||||
# For each wrestler, find their BEST (lowest) elapsed_seconds
|
||||
# Filter by period
|
||||
# Order by best_time ASC
|
||||
# Return top N
|
||||
```
|
||||
|
||||
### Neue URL: `leistungstest/stats.py` ViewSet
|
||||
- `GET /leaderboard/` — Template oder Exercise Leaderboard
|
||||
- `GET /exercises/` — Liste verwendeter Übungen
|
||||
|
||||
## Zeitraum-Filter Logik
|
||||
```python
|
||||
def get_date_range(period):
|
||||
today = date.today()
|
||||
if period == "month":
|
||||
return today.replace(day=1)
|
||||
elif period == "3months":
|
||||
return today - timedelta(days=90)
|
||||
elif period == "year":
|
||||
return today.replace(month=1, day=1)
|
||||
return None # "all"
|
||||
```
|
||||
|
||||
## Implementierungs-Reihenfolge
|
||||
|
||||
1. Backend: `stats.py` mit ViewSet + URLs
|
||||
2. Frontend: Neuer "Statistiken" Tab
|
||||
3. Toggle zwischen Vorlagen/Übungs-Ansicht
|
||||
4. Zeitraum-Filter
|
||||
5. Ranglisten-Anzeige mit Medaillen-Icons
|
||||
Reference in New Issue
Block a user