fix: update application namespace and clean up deprecated files
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 45s
- Changed application namespace from `de.tt_tagebuch.app` to `de.tsschulz.tt_tagebuch` in build.gradle.kts and AndroidManifest.xml for consistency. - Updated DEVELOPMENT.md to reflect the correct package name for the app. - Removed deprecated files related to AppDependencies, MainActivity, MainApplication, and PDF generation, streamlining the codebase. - Enhanced TODO.md to reflect the current status of the Android team planning phase implementation.
@@ -63,7 +63,7 @@ Testest du mit der **LAN-IP deines PCs** (echtes Gerät), musst du diese IP dort
|
||||
2. **Alte Installation / Build-Cache:** Emulator-App deinstallieren, Clean, neu installieren:
|
||||
```bash
|
||||
cd mobile-app
|
||||
adb uninstall de.tt_tagebuch.app
|
||||
adb uninstall de.tsschulz.tt_tagebuch
|
||||
./gradlew :composeApp:clean :composeApp:installDebug --no-configuration-cache
|
||||
```
|
||||
Oder das Skript: `./scripts/install-debug-emulator.sh`
|
||||
|
||||
@@ -165,49 +165,19 @@ Web: `DiaryView.vue` (sehr groß). API-Cluster (Auszug – in Web nach `apiClien
|
||||
|
||||
- [x] **Ausstehende Freigaben** – `ClubApprovalsApi`, `PendingApprovalsManager`, Screen unter „Mehr“ → Club-Verwaltung (`ClubAdminScreens.kt`)
|
||||
- [x] **Team-Management (Mannschaften + Editor)** – `TeamManagementScreen` + `TeamEditorScreen`: Saison, Suche, CRUD Mannschaften; Tabs Stammdaten, Spielerstatistik (Liga), **Aufstellung/Meldung**, Dokumente, Scheduler-Jobs, MyTT (`ClubTeamsApi`, `MatchesApi`, `TeamDocumentsApi`, `ApiLogsApi`, `MyTischtennisApi`, Rechte `canReadTeams`/`canWriteTeams`)
|
||||
- [ ] **Mannschafts-Planung (Android)** – siehe Unterabschnitt **Phase 8a** (Web hat das Planungsboard bereits; mobil bewusst **offen**)
|
||||
- [x] **Mannschafts-Planung (Android)** – `TeamManagementScreen` **Mannschaften | Planung**; `TeamPlanningScreen` / `TeamPlanningLogic`; `MembersApi` Play-Interest (`TeamEditorModels`) – Details **Phase 8a**
|
||||
- [x] **Berechtigungen** – erweiterte `PermissionsApi`, `PermissionsAdminManager`, UI Rolle/Status/Anpassen mit `RolePermissionMatrix` (`ClubAdminScreens.kt`)
|
||||
- [x] **Logs** – `ApiLogsApi`, `ApiLogsManager`, Liste + Pagination + Detail (`ClubAdminScreens.kt`); `AppDependencies` / Logout / 401 räumen Manager auf
|
||||
|
||||
### Phase 8a – Mannschafts-Planung auf Android (Backlog / Plan)
|
||||
### Phase 8a – Mannschafts-Planung auf Android (umgesetzt, Stand 2026-05)
|
||||
|
||||
**Ziel:** Gleiche **fachliche** Funktion wie Web **Team-Verwaltung → Planung**: Pool „möchte spielen“, mehrere Mannschaften der Saison parallel, Spieler nur **eligibility-konform** zuordnen, lokale Stammdaten (Name, geplante Liga, AK/GK) pro Team, **Meldung (Lineup)** je Team und gewählter **Halbserie** lesen/schreiben, optional **Debounced Autosave** wie Web.
|
||||
- [x] `GET/POST` **`/api/clubmembers/play-interest/:clubId`** – `MembersApi` + DTOs `MemberPlayInterestRowDto` / `MemberPlayInterestSetBody`
|
||||
- [x] **UI:** `TeamPlanningScreen.kt` – Halbserie, Pool, Interesse markieren, Mannschaft hinzufügen, pro Team Stammdaten + Meldung, QTTR-Abstand, „Im Editor öffnen“
|
||||
- [x] **Einstieg:** `TeamManagementScreen` – Segment **Mannschaften | Planung**
|
||||
- [x] **Logik:** `TeamPlanningLogic.kt` – Normalisierung Zuordnungen, Eligibility über `TeamEditorLineupLogic`, Default-Halbserie
|
||||
- [ ] **Optional später:** Drag-and-Drop statt Menüs; Debounced Autosave wie Web; dedizierte Tests Serialisierung
|
||||
|
||||
**Web-Referenz (1:1 zum Durchlesen der Logik):**
|
||||
|
||||
| Bereich | Datei / Abschnitt |
|
||||
|--------|-------------------|
|
||||
| Umschalter „Mannschaften“ / „Planung“, Board einbinden | `frontend/src/views/TeamManagementView.vue` (`activeMainSection`, `TeamPlanningBoard`) |
|
||||
| UI Pool, Teams, Suche, Interesse markieren | `frontend/src/components/team/TeamPlanningBoard.vue` |
|
||||
| Lanes / Drag-Drop | `frontend/src/components/team/TeamPlanningLane.vue` |
|
||||
|
||||
**Backend-APIs (aus Web `apiClient`; im `shared` ergänzen, falls noch fehlend):**
|
||||
|
||||
- [ ] `GET /api/clubmembers/play-interest/:clubId` mit Query `seasonId`, `lineupHalf` – geladene **Interessen** für Pool (`loadPlanningInterestedMemberIds`)
|
||||
- [ ] `POST /api/clubmembers/play-interest/:clubId` – Body `memberId`, `seasonId`, `lineupHalf`, `interested` – Mitglied als „interessiert“ markieren (`onPlanningMarkMemberInterested`)
|
||||
- [x] `GET /api/clubmembers/get/:clubId/:showAll` – bereits `MembersApi.listMembers`
|
||||
- [x] `GET /api/club-teams/...` Mannschaften Saison, `GET …/lineup?half=`, `PUT …/lineup` – `ClubTeamsApi` (Planung lädt Lineups **aller** Teams der Saison parallel wie Web `loadPlanningAssignments`)
|
||||
- [x] `PUT /api/club-teams/:id` – Stammdaten Planungsteam (`updateClubTeam`)
|
||||
- [x] `POST /api/club-teams/club/:clubId` – neue Planungs-Mannschaft (`createClubTeam` o. ä.)
|
||||
- [x] `DELETE /api/club-teams/:id` – Planungs-Mannschaft löschen
|
||||
|
||||
**Shared / Domäne:**
|
||||
|
||||
- [ ] DTOs für Play-Interest (Response-Zeilen: `memberId`, `interested`, …) + `MembersApi` Erweiterung
|
||||
- [ ] Optional: **PlanningState**-Use-Case (normalisierte Zuordnungen `teamId`/`memberId`/`position`, Halbserie, Recompute bei AK/GK-Wechsel) – Web: `normalizePlanningAssignments`, `removeAllIneligiblePlanningAssignments`, `isEligibleForPlanningTeam` (analog `TeamEditorLineupLogic.isEligibleForTeam` + Team-spezifische AK/GK aus `planningLocalTeams`)
|
||||
|
||||
**Android UI (Vorschlag für Umsetzungsschritte):**
|
||||
|
||||
1. [ ] **Einstieg:** In `TeamManagementScreen` (oder `AppRoot`) zweiter Modus **„Planung“** neben **„Mannschaften“** (wie Web-Workspace-Buttons), gleiche Saison-Auswahl wie Liste
|
||||
2. [ ] **Screen** `TeamPlanningScreen.kt` (oder modular `TeamPlanningPool.kt` / `TeamPlanningTeamCard.kt`): Pool + Liste der Teams; kein 1:1-Spiegel der Web-Grid-Optik nötig, aber **alle Aktionen** abdeckbar
|
||||
3. [ ] **Drag-and-Drop:** Entweder Compose **Drag-and-Drop** (Plattform-API) oder **Fallback** ohne DnD: „Mitglied auswählen → Ziel-Mannschaft“ / „Aus Mannschaft entfernen“ / Reihenfolge **↑↓** in der Lane (wie Aufstellungs-Tab)
|
||||
4. [ ] **Halbserie** (VR/RR) gemeinsam mit Web-Parameter `lineupHalf` an Play-Interest und Lineup-Requests
|
||||
5. [ ] **„In Workspace öffnen“** / Team-Editor: Web `convertPlanningTeamToRegular` prüfen – ggf. nur Navigation zum bestehenden `TeamEditorScreen` statt Konvertierungs-API
|
||||
6. [ ] **Autosave:** Web nutzt Debounce (`schedulePlanningTeamAutosave`) – mobil entweder gleichziehen oder explizit **„Speichern“** pro Team + Konflikt-Hinweis (Produktentscheidung)
|
||||
7. [ ] **i18n:** Keys aus `teamManagement.planning*` / `markAsInterested` usw. in `MobileStrings` oder Fallback-Kette wie andere Admin-Screens
|
||||
8. [ ] **Tests:** Serialisierung Play-Interest; optional Snapshot der Normalisierung `planningAssignments`
|
||||
|
||||
**Hinweis im Code:** Solange 8a offen ist, kann im Tab Aufstellung ein kurzer Verweis auf die **zukünftige** in-App-Planung stehen (nach Umsetzung Text anpassen oder entfernen).
|
||||
**Hinweis im Code:** Tab Aufstellung (`TeamEditorScreen`) verweist auf den Reiter **Planung** in derselben Team-Verwaltung.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -51,11 +51,11 @@ kotlin {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "de.tt_tagebuch.app"
|
||||
namespace = "de.tsschulz.tt_tagebuch"
|
||||
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "de.tt_tagebuch.app"
|
||||
applicationId = "de.tsschulz.tt_tagebuch"
|
||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
||||
targetSdk = libs.versions.android.targetSdk.get().toInt()
|
||||
versionCode = 1
|
||||
|
||||
BIN
mobile-app/composeApp/release/composeApp-release.aab
Normal file
@@ -4,16 +4,16 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:name=".app.MainApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@android:mipmap/sym_def_app_icon"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Trainingstagebuch"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@android:mipmap/sym_def_app_icon"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@android:style/Theme.Material.Light.NoActionBar">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".app.MainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.Material.Light.NoActionBar"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
|
||||
@@ -1,59 +1,60 @@
|
||||
package de.tt_tagebuch.app
|
||||
package de.tsschulz.tt_tagebuch.app
|
||||
|
||||
import android.content.Context
|
||||
import de.tt_tagebuch.shared.api.BillingApi
|
||||
import de.tt_tagebuch.shared.api.CalendarHolidayApi
|
||||
import de.tt_tagebuch.shared.api.AccidentApi
|
||||
import de.tt_tagebuch.shared.api.ApiLogsApi
|
||||
import de.tt_tagebuch.shared.api.ClubApprovalsApi
|
||||
import de.tt_tagebuch.shared.api.ClickTtAccountApi
|
||||
import de.tt_tagebuch.shared.api.ApiConfig
|
||||
import de.tt_tagebuch.shared.api.AuthApi
|
||||
import de.tt_tagebuch.shared.api.PublicAuthApi
|
||||
import de.tt_tagebuch.shared.api.ClubTeamsApi
|
||||
import de.tt_tagebuch.shared.api.ClubsApi
|
||||
import de.tt_tagebuch.shared.api.DiaryApi
|
||||
import de.tt_tagebuch.shared.api.DiaryMemberActivitiesApi
|
||||
import de.tt_tagebuch.shared.api.DiaryMemberApi
|
||||
import de.tt_tagebuch.shared.api.GroupApi
|
||||
import de.tt_tagebuch.shared.api.ParticipantsApi
|
||||
import de.tt_tagebuch.shared.api.PredefinedActivitiesApi
|
||||
import de.tt_tagebuch.shared.api.MatchesApi
|
||||
import de.tt_tagebuch.shared.api.MemberActivitiesApi
|
||||
import de.tt_tagebuch.shared.api.MemberGroupPhotosApi
|
||||
import de.tt_tagebuch.shared.api.MemberTransferConfigApi
|
||||
import de.tt_tagebuch.shared.api.MemberOrdersApi
|
||||
import de.tt_tagebuch.shared.api.TrainingCancellationApi
|
||||
import de.tt_tagebuch.shared.api.MembersApi
|
||||
import de.tt_tagebuch.shared.api.MyTischtennisApi
|
||||
import de.tt_tagebuch.shared.api.OfficialTournamentsApi
|
||||
import de.tt_tagebuch.shared.api.PermissionsApi
|
||||
import de.tt_tagebuch.shared.api.SeasonsApi
|
||||
import de.tt_tagebuch.shared.api.SessionApi
|
||||
import de.tt_tagebuch.shared.api.TeamDocumentsApi
|
||||
import de.tt_tagebuch.shared.api.TrainingGroupsApi
|
||||
import de.tt_tagebuch.shared.api.TrainingStatsApi
|
||||
import de.tt_tagebuch.shared.api.TrainingTimesApi
|
||||
import de.tt_tagebuch.shared.api.TournamentsApi
|
||||
import de.tt_tagebuch.shared.api.http.AndroidHttpClientEngineFactory
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.http.PublicHttpClient
|
||||
import de.tt_tagebuch.shared.state.AndroidClubStorage
|
||||
import de.tt_tagebuch.shared.state.AndroidLanguageStorage
|
||||
import de.tt_tagebuch.shared.state.AndroidTokenStorage
|
||||
import de.tt_tagebuch.shared.state.ApiLogsManager
|
||||
import de.tt_tagebuch.shared.state.AuthManager
|
||||
import de.tt_tagebuch.shared.state.ClubInternalTournamentsManager
|
||||
import de.tt_tagebuch.shared.state.ClubManager
|
||||
import de.tt_tagebuch.shared.state.DiaryManager
|
||||
import de.tt_tagebuch.shared.state.LanguageManager
|
||||
import de.tt_tagebuch.shared.state.MembersManager
|
||||
import de.tt_tagebuch.shared.state.MutableTokenProvider
|
||||
import de.tt_tagebuch.shared.state.OfficialTournamentsReadManager
|
||||
import de.tt_tagebuch.shared.state.PendingApprovalsManager
|
||||
import de.tt_tagebuch.shared.state.PermissionsAdminManager
|
||||
import de.tt_tagebuch.shared.state.ScheduleManager
|
||||
import de.tt_tagebuch.shared.state.TrainingStatsManager
|
||||
import de.tsschulz.tt_tagebuch.BuildConfig
|
||||
import de.tsschulz.tt_tagebuch.shared.api.BillingApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.CalendarHolidayApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.AccidentApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ApiLogsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ClubApprovalsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ClickTtAccountApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ApiConfig
|
||||
import de.tsschulz.tt_tagebuch.shared.api.AuthApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.PublicAuthApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ClubTeamsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ClubsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.DiaryApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.DiaryMemberActivitiesApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.DiaryMemberApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.GroupApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ParticipantsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.PredefinedActivitiesApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MatchesApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MemberActivitiesApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MemberGroupPhotosApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MemberTransferConfigApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MemberOrdersApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TrainingCancellationApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MembersApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.MyTischtennisApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.OfficialTournamentsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.PermissionsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.SeasonsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.SessionApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TeamDocumentsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TrainingGroupsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TrainingStatsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TrainingTimesApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TournamentsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AndroidHttpClientEngineFactory
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.PublicHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.state.AndroidClubStorage
|
||||
import de.tsschulz.tt_tagebuch.shared.state.AndroidLanguageStorage
|
||||
import de.tsschulz.tt_tagebuch.shared.state.AndroidTokenStorage
|
||||
import de.tsschulz.tt_tagebuch.shared.state.ApiLogsManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.AuthManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.ClubInternalTournamentsManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.ClubManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.DiaryManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.LanguageManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.MembersManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.MutableTokenProvider
|
||||
import de.tsschulz.tt_tagebuch.shared.state.OfficialTournamentsReadManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.PendingApprovalsManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.PermissionsAdminManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.ScheduleManager
|
||||
import de.tsschulz.tt_tagebuch.shared.state.TrainingStatsManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app
|
||||
package de.tsschulz.tt_tagebuch.app
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
@@ -9,8 +9,8 @@ import androidx.compose.material.Surface
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import de.tt_tagebuch.app.ui.AppRoot
|
||||
import de.tt_tagebuch.app.ui.TtTagebuchTheme
|
||||
import de.tsschulz.tt_tagebuch.app.ui.AppRoot
|
||||
import de.tsschulz.tt_tagebuch.app.ui.TtTagebuchTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app
|
||||
package de.tsschulz.tt_tagebuch.app
|
||||
|
||||
import android.app.Application
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package de.tt_tagebuch.app.calendar
|
||||
package de.tsschulz.tt_tagebuch.app.calendar
|
||||
|
||||
import de.tt_tagebuch.shared.api.models.CalendarHolidayRowDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.DiaryDate
|
||||
import de.tt_tagebuch.shared.api.models.InternalTournamentSummaryDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParticipationBucketDto
|
||||
import de.tt_tagebuch.shared.api.models.ScheduleMatchDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingCancellationDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CalendarHolidayRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryDate
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentSummaryDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipationBucketDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleMatchDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingCancellationDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalTime
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.pdf
|
||||
package de.tsschulz.tt_tagebuch.app.pdf
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
@@ -8,12 +8,12 @@ import android.graphics.pdf.PdfDocument
|
||||
import android.text.Layout
|
||||
import android.text.StaticLayout
|
||||
import android.text.TextPaint
|
||||
import de.tt_tagebuch.shared.api.models.DiaryDateActivityItem
|
||||
import de.tt_tagebuch.shared.api.models.DiaryFreeformActivity
|
||||
import de.tt_tagebuch.shared.api.models.DiaryTrainingParticipant
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.displayTitle
|
||||
import de.tt_tagebuch.shared.api.models.isPresentParticipant
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryDateActivityItem
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryFreeformActivity
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryTrainingParticipant
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.displayTitle
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.isPresentParticipant
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.Locale
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.app.pdf
|
||||
package de.tsschulz.tt_tagebuch.app.pdf
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.content.FileProvider
|
||||
import de.tt_tagebuch.app.BuildConfig
|
||||
import de.tsschulz.tt_tagebuch.BuildConfig
|
||||
import java.io.File
|
||||
|
||||
fun shareFileWithMime(context: Context, file: File, mimeType: String, chooserTitle: String) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.pdf
|
||||
package de.tsschulz.tt_tagebuch.app.pdf
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
@@ -8,8 +8,8 @@ import android.graphics.pdf.PdfDocument
|
||||
import android.text.Layout
|
||||
import android.text.StaticLayout
|
||||
import android.text.TextPaint
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.MemberContactDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberContactDto
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.time.LocalDate
|
||||
@@ -1,10 +1,10 @@
|
||||
package de.tt_tagebuch.app.stats
|
||||
package de.tsschulz.tt_tagebuch.app.stats
|
||||
|
||||
import de.tt_tagebuch.shared.api.models.TrainingStatsDay
|
||||
import de.tt_tagebuch.shared.api.models.TrainingStatsMember
|
||||
import de.tt_tagebuch.shared.api.models.TrainingStatsMemberDistribution
|
||||
import de.tt_tagebuch.shared.api.models.TrainingStatsMonthlyTrend
|
||||
import de.tt_tagebuch.shared.api.models.TrainingStatsWeekdayBucket
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsDay
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsMember
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsMemberDistribution
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsMonthlyTrend
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsWeekdayBucket
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDate
|
||||
import java.util.Locale
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -89,61 +89,61 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlin.math.max
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.pdf.sharePdfFile
|
||||
import de.tt_tagebuch.app.pdf.writeMembersPhoneListPdf
|
||||
import de.tt_tagebuch.app.pdf.writeTrainingDaySummaryPdf
|
||||
import de.tt_tagebuch.app.pdf.writeTrainingPlanPdf
|
||||
import de.tt_tagebuch.shared.api.memberProfileImagePath
|
||||
import de.tt_tagebuch.shared.api.toAbsoluteUrl
|
||||
import de.tt_tagebuch.shared.api.models.MemberGroupPhotoDto
|
||||
import de.tt_tagebuch.shared.api.models.canReadApprovals
|
||||
import de.tt_tagebuch.shared.api.models.canReadClubPermissions
|
||||
import de.tt_tagebuch.shared.api.models.canReadClubSettings
|
||||
import de.tt_tagebuch.shared.api.models.canReadPredefinedActivities
|
||||
import de.tt_tagebuch.shared.api.models.canReadDiary
|
||||
import de.tt_tagebuch.shared.api.models.canReadTeams
|
||||
import de.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tt_tagebuch.shared.api.models.canReadSchedule
|
||||
import de.tt_tagebuch.shared.api.models.canReadStatistics
|
||||
import de.tt_tagebuch.shared.api.models.canReadTournaments
|
||||
import de.tt_tagebuch.shared.api.models.canWriteDiary
|
||||
import de.tt_tagebuch.shared.api.models.canWriteMembers
|
||||
import de.tt_tagebuch.shared.api.models.canWriteMyTischtennis
|
||||
import de.tt_tagebuch.shared.api.models.mainActivityImagePath
|
||||
import de.tt_tagebuch.shared.api.models.nestedActivityImagePath
|
||||
import de.tt_tagebuch.shared.api.models.AccidentReportDto
|
||||
import de.tt_tagebuch.shared.api.models.Club
|
||||
import de.tt_tagebuch.shared.api.models.DiaryDate
|
||||
import de.tt_tagebuch.shared.api.models.DiaryFreeformActivity
|
||||
import de.tt_tagebuch.shared.api.models.AddDiaryPlanGroupActivityRequest
|
||||
import de.tt_tagebuch.shared.api.models.CreateDiaryPlanActivityRequest
|
||||
import de.tt_tagebuch.shared.api.models.DiaryDateActivityItem
|
||||
import de.tt_tagebuch.shared.api.models.DiaryPlanGroup
|
||||
import de.tt_tagebuch.shared.api.models.UpdateDiaryPlanActivityRequest
|
||||
import de.tt_tagebuch.shared.api.models.DiaryMemberNoteDto
|
||||
import de.tt_tagebuch.shared.api.models.DiaryMemberTagLinkDto
|
||||
import de.tt_tagebuch.shared.api.models.DiaryTag
|
||||
import de.tt_tagebuch.shared.api.models.PredefinedActivityDto
|
||||
import de.tt_tagebuch.shared.api.models.displayLabel as predefinedDtoDisplayLabel
|
||||
import de.tt_tagebuch.shared.api.models.tagDefinitionId
|
||||
import de.tt_tagebuch.shared.api.models.tagDisplayName
|
||||
import de.tt_tagebuch.shared.api.models.DiaryTrainingParticipant
|
||||
import de.tt_tagebuch.shared.api.models.isPresentParticipant
|
||||
import de.tt_tagebuch.shared.api.models.displayLabel
|
||||
import de.tt_tagebuch.shared.api.models.displayTitle
|
||||
import de.tt_tagebuch.shared.api.models.memberLabel
|
||||
import de.tt_tagebuch.shared.api.models.MemberActivityStatDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberContactDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberContactSetBody
|
||||
import de.tt_tagebuch.shared.api.models.MemberDataQualityRequirements
|
||||
import de.tt_tagebuch.shared.api.models.MemberLastParticipationDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tt_tagebuch.shared.api.models.toSetBody
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.UserClubPermissions
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.sharePdfFile
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.writeMembersPhoneListPdf
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.writeTrainingDaySummaryPdf
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.writeTrainingPlanPdf
|
||||
import de.tsschulz.tt_tagebuch.shared.api.memberProfileImagePath
|
||||
import de.tsschulz.tt_tagebuch.shared.api.toAbsoluteUrl
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberGroupPhotoDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadApprovals
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadClubPermissions
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadClubSettings
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadPredefinedActivities
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadDiary
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadTeams
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadSchedule
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadStatistics
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadTournaments
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteDiary
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteMyTischtennis
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.mainActivityImagePath
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.nestedActivityImagePath
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AccidentReportDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Club
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryDate
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryFreeformActivity
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddDiaryPlanGroupActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateDiaryPlanActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryDateActivityItem
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryPlanGroup
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateDiaryPlanActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberNoteDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberTagLinkDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryTag
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.PredefinedActivityDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.displayLabel as predefinedDtoDisplayLabel
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.tagDefinitionId
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.tagDisplayName
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryTrainingParticipant
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.isPresentParticipant
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.displayLabel
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.displayTitle
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.memberLabel
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberActivityStatDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberContactDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberContactSetBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberDataQualityRequirements
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberLastParticipationDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.toSetBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UserClubPermissions
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
@@ -46,16 +46,16 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.pdf.sharePdfFile
|
||||
import de.tt_tagebuch.shared.api.models.BillingCreateRunBody
|
||||
import de.tt_tagebuch.shared.api.models.BillingRunDto
|
||||
import de.tt_tagebuch.shared.api.models.BillingTemplateDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberOrderDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberOrderPatchBody
|
||||
import de.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tt_tagebuch.shared.api.models.canWriteMembers
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.sharePdfFile
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingCreateRunBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingRunDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingTemplateDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberOrderDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberOrderPatchBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
@@ -37,16 +37,16 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.calendar.CalendarAggregator
|
||||
import de.tt_tagebuch.app.calendar.CalendarEventAction
|
||||
import de.tt_tagebuch.app.calendar.CalendarEventType
|
||||
import de.tt_tagebuch.app.calendar.CalendarUiEvent
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.calendar.CalendarAggregator
|
||||
import de.tsschulz.tt_tagebuch.app.calendar.CalendarEventAction
|
||||
import de.tsschulz.tt_tagebuch.app.calendar.CalendarEventType
|
||||
import de.tsschulz.tt_tagebuch.app.calendar.CalendarUiEvent
|
||||
import android.util.Log
|
||||
import de.tt_tagebuch.shared.api.http.ApiException
|
||||
import de.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.TrainingCancellationUpsertBody
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.ApiException
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingCancellationUpsertBody
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -45,16 +45,16 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.RolePermissionMatrix
|
||||
import de.tt_tagebuch.shared.api.models.ApiLogDetailDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubPermissionMemberDto
|
||||
import de.tt_tagebuch.shared.api.models.PermissionResourceDto
|
||||
import de.tt_tagebuch.shared.api.models.canReadApprovals
|
||||
import de.tt_tagebuch.shared.api.models.canReadClubPermissions
|
||||
import de.tt_tagebuch.shared.api.models.canWriteApprovals
|
||||
import de.tt_tagebuch.shared.api.models.canWriteClubPermissions
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.RolePermissionMatrix
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ApiLogDetailDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubPermissionMemberDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.PermissionResourceDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadApprovals
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadClubPermissions
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteApprovals
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteClubPermissions
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.JsonNull
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -45,20 +45,20 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.models.Club
|
||||
import de.tt_tagebuch.shared.api.models.CreateTrainingTimeBody
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.MemberDataQualityRequirements
|
||||
import de.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingGroupMemberBrief
|
||||
import de.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tt_tagebuch.shared.api.models.UpdateClubSettingsBody
|
||||
import de.tt_tagebuch.shared.api.models.UpdateTrainingTimeBody
|
||||
import de.tt_tagebuch.shared.api.models.canReadClubSettings
|
||||
import de.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tt_tagebuch.shared.api.models.canWriteClubSettings
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Club
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateTrainingTimeBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberDataQualityRequirements
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingGroupMemberBrief
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateClubSettingsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateTrainingTimeBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadClubSettings
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteClubSettings
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private val ClubSettingsPad = 20.dp
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -44,23 +44,23 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.PredefinedActivitiesApi
|
||||
import de.tt_tagebuch.shared.api.models.MemberTransferConfigEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.MemberTransferConfigSaveBody
|
||||
import de.tt_tagebuch.shared.api.models.PredefinedActivityDto
|
||||
import de.tt_tagebuch.shared.api.models.PredefinedActivityUpsertBody
|
||||
import de.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tt_tagebuch.shared.api.models.UpdateClubSettingsBody
|
||||
import de.tt_tagebuch.shared.api.models.UpdateTrainingTimeBody
|
||||
import de.tt_tagebuch.shared.api.models.canReadClubSettings
|
||||
import de.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tt_tagebuch.shared.api.models.canReadPredefinedActivities
|
||||
import de.tt_tagebuch.shared.api.models.canWriteMembers
|
||||
import de.tt_tagebuch.shared.api.models.canWritePredefinedActivities
|
||||
import de.tt_tagebuch.shared.api.models.displayLabel
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.PredefinedActivitiesApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferConfigEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferConfigSaveBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.PredefinedActivityDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.PredefinedActivityUpsertBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingGroupDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingTimeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateClubSettingsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateTrainingTimeBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadClubSettings
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadPredefinedActivities
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteMembers
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWritePredefinedActivities
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.displayLabel
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.buildJsonObject
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -31,23 +31,23 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.TournamentsApi
|
||||
import de.tt_tagebuch.shared.api.models.AddTournamentClassBody
|
||||
import de.tt_tagebuch.shared.api.models.CreateTournamentPairingBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentAddInternalParticipantBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentAddMatchResultBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentClassDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentDeleteKnockoutBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentExternalParticipantRowDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentFinishMatchBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentMatchDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentParticipantRowDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentRemoveInternalParticipantBody
|
||||
import de.tt_tagebuch.shared.api.models.UpdateParticipantClassBody
|
||||
import de.tt_tagebuch.shared.api.models.UpdateTournamentClassBody
|
||||
import de.tt_tagebuch.shared.api.models.AddExternalTournamentParticipantBody
|
||||
import de.tt_tagebuch.shared.api.models.RemoveExternalTournamentParticipantBody
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.TournamentsApi
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddTournamentClassBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateTournamentPairingBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentAddInternalParticipantBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentAddMatchResultBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentClassDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentDeleteKnockoutBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentExternalParticipantRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentFinishMatchBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentMatchDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentParticipantRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentRemoveInternalParticipantBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateParticipantClassBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateTournamentClassBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddExternalTournamentParticipantBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.RemoveExternalTournamentParticipantBody
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -38,20 +38,20 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.models.InternalTournamentDetailDto
|
||||
import de.tt_tagebuch.shared.api.models.SetTournamentModusBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentClassDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentClubTournamentBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentCreateGroupMatchesBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentCreateGroupsBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentExternalParticipantRowDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentGetExternalParticipantsBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentGetParticipantsBody
|
||||
import de.tt_tagebuch.shared.api.models.TournamentMatchDto
|
||||
import de.tt_tagebuch.shared.api.models.TournamentParticipantRowDto
|
||||
import de.tt_tagebuch.shared.api.models.UpdateTournamentMetaBody
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentDetailDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.SetTournamentModusBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentClassDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentClubTournamentBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentCreateGroupMatchesBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentCreateGroupsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentExternalParticipantRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentGetExternalParticipantsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentGetParticipantsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentMatchDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TournamentParticipantRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateTournamentMetaBody
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -59,7 +59,7 @@ import kotlinx.serialization.json.JsonElement
|
||||
|
||||
/**
|
||||
* Vollständiger Turnier-Workspace (analog Web [TournamentTab]): Stammdaten, Ablauf/Gruppen,
|
||||
* Klassen, Teilnehmer, Spiele, Doppel-Paarungen. Lädt und speichert über [de.tt_tagebuch.shared.api.TournamentsApi].
|
||||
* Klassen, Teilnehmer, Spiele, Doppel-Paarungen. Lädt und speichert über [de.tsschulz.tt_tagebuch.shared.api.TournamentsApi].
|
||||
*/
|
||||
@Composable
|
||||
internal fun InternalTournamentEditorScreen(
|
||||
@@ -347,7 +347,7 @@ private fun TournamentEditorFlowTab(
|
||||
detail: InternalTournamentDetailDto,
|
||||
groupsJson: JsonElement?,
|
||||
tr: (String, String) -> String,
|
||||
api: de.tt_tagebuch.shared.api.TournamentsApi,
|
||||
api: de.tsschulz.tt_tagebuch.shared.api.TournamentsApi,
|
||||
scope: kotlinx.coroutines.CoroutineScope,
|
||||
onReload: () -> Unit,
|
||||
onError: (String?) -> Unit,
|
||||
@@ -500,7 +500,7 @@ private fun TournamentEditorFlowTab(
|
||||
runCatching {
|
||||
kotlinx.coroutines.withContext(Dispatchers.IO) {
|
||||
api.startKnockout(
|
||||
de.tt_tagebuch.shared.api.models.TournamentStartKnockoutBody(clubId, tournamentId),
|
||||
de.tsschulz.tt_tagebuch.shared.api.models.TournamentStartKnockoutBody(clubId, tournamentId),
|
||||
)
|
||||
}
|
||||
}.onFailure { onError(it.message) }
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -28,10 +28,10 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.models.InternalTournamentStatsAgeOption
|
||||
import de.tt_tagebuch.shared.api.models.InternalTournamentStatsDto
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentStatsAgeOption
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentStatsDto
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
|
||||
private fun allBandKeysFromOptions(options: List<InternalTournamentStatsAgeOption>): Set<String> {
|
||||
val seen = mutableSetOf<String>()
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
|
||||
internal val LocalLanguageCode = compositionLocalOf { MobileStrings.DEFAULT_LANGUAGE }
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
@@ -60,9 +60,9 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
@@ -37,12 +37,12 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.models.MemberGroupPhotoDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberTransferConfigEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.MemberTransferRunBody
|
||||
import de.tt_tagebuch.shared.api.toAbsoluteUrl
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberGroupPhotoDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferConfigEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferRunBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.toAbsoluteUrl
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.booleanOrNull
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import java.time.LocalDate
|
||||
import java.time.Period
|
||||
import java.time.ZoneId
|
||||
@@ -1,14 +1,14 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import de.tt_tagebuch.app.util.OfficialTournamentEligibility
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.OfficialCompetitionMemberStateDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedCompetitionDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedDataDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParticipationBucketDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParticipationEntryDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialTournamentListRowDto
|
||||
import de.tsschulz.tt_tagebuch.app.util.OfficialTournamentEligibility
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialCompetitionMemberStateDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedCompetitionDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedDataDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipationBucketDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipationEntryDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialTournamentListRowDto
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonNull
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
@@ -55,18 +55,18 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.util.OfficialTournamentEligibility
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedCompetitionDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialPatchTournamentBody
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParticipantStatusBody
|
||||
import de.tt_tagebuch.shared.api.models.OfficialTournamentListRowDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialUpsertParticipationBody
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.canReadTournaments
|
||||
import de.tt_tagebuch.shared.api.models.canWriteTournaments
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.util.OfficialTournamentEligibility
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedCompetitionDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialPatchTournamentBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipantStatusBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialTournamentListRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialUpsertParticipationBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadTournaments
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteTournaments
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.ViewGroup
|
||||
@@ -49,15 +49,15 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.http.ApiException
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountDto
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountStatusDto
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountUpsertBody
|
||||
import de.tt_tagebuch.shared.api.models.MyTischtennisAccountDto
|
||||
import de.tt_tagebuch.shared.api.models.MyTischtennisAccountUpsertBody
|
||||
import de.tt_tagebuch.shared.api.models.MyTischtennisStatusDto
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.ApiException
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountStatusDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountUpsertBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MyTischtennisAccountDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MyTischtennisAccountUpsertBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MyTischtennisStatusDto
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.launch
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
@@ -349,7 +349,7 @@ private fun MyTischtennisEditorDialog(
|
||||
onSaved: () -> Unit,
|
||||
onLoggedIn: () -> Unit,
|
||||
scope: kotlinx.coroutines.CoroutineScope,
|
||||
api: de.tt_tagebuch.shared.api.MyTischtennisApi,
|
||||
api: de.tsschulz.tt_tagebuch.shared.api.MyTischtennisApi,
|
||||
) {
|
||||
var email by remember(account?.id, loginMode) { mutableStateOf(account?.email.orEmpty()) }
|
||||
var password by remember(account?.id, loginMode) { mutableStateOf("") }
|
||||
@@ -614,7 +614,7 @@ private fun ClickTtEditorDialog(
|
||||
onSaved: () -> Unit,
|
||||
onLoggedIn: () -> Unit,
|
||||
scope: kotlinx.coroutines.CoroutineScope,
|
||||
api: de.tt_tagebuch.shared.api.ClickTtAccountApi,
|
||||
api: de.tsschulz.tt_tagebuch.shared.api.ClickTtAccountApi,
|
||||
) {
|
||||
var username by remember(account?.id, loginMode) { mutableStateOf(account?.username.orEmpty()) }
|
||||
var password by remember(account?.id, loginMode) { mutableStateOf("") }
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -46,14 +46,14 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.stats.TrainingStatsDerived
|
||||
import de.tt_tagebuch.shared.api.models.ScheduleMatchDto
|
||||
import de.tt_tagebuch.shared.api.models.ScheduleMatchScope
|
||||
import de.tt_tagebuch.shared.api.models.ScheduleViewMode
|
||||
import de.tt_tagebuch.shared.api.models.canReadSchedule
|
||||
import de.tt_tagebuch.shared.api.models.canWriteSchedule
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.stats.TrainingStatsDerived
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleMatchDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleMatchScope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleViewMode
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadSchedule
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteSchedule
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private val SchedulePad = 20.dp
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import java.util.Calendar
|
||||
import java.util.GregorianCalendar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
@@ -49,19 +49,19 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.pdf.shareFileWithMime
|
||||
import de.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamCreateBody
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamLineupRowDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamUpdateBody
|
||||
import de.tt_tagebuch.shared.api.models.LeaguePlayerStatDto
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.TeamLineupAssignmentItem
|
||||
import de.tt_tagebuch.shared.api.models.TeamLineupUpdateBody
|
||||
import de.tt_tagebuch.shared.api.models.canWriteTeams
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.shareFileWithMime
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamCreateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamLineupRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamUpdateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.LeaguePlayerStatDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupAssignmentItem
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupUpdateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteTeams
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -196,13 +196,13 @@ internal fun TeamEditorScreen(
|
||||
var loadingLineup by remember { mutableStateOf(false) }
|
||||
var savingLineup by remember { mutableStateOf(false) }
|
||||
|
||||
var documents by remember { mutableStateOf<List<de.tt_tagebuch.shared.api.models.TeamDocumentDto>>(emptyList()) }
|
||||
var documents by remember { mutableStateOf<List<de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto>>(emptyList()) }
|
||||
var loadingDocs by remember { mutableStateOf(false) }
|
||||
var parsingDocId by remember { mutableStateOf<Int?>(null) }
|
||||
|
||||
var schedulerLoaded by remember { mutableStateOf(false) }
|
||||
var schedulerBlock by remember {
|
||||
mutableStateOf<de.tt_tagebuch.shared.api.models.SchedulerJobBlockDto?>(
|
||||
mutableStateOf<de.tsschulz.tt_tagebuch.shared.api.models.SchedulerJobBlockDto?>(
|
||||
null,
|
||||
)
|
||||
}
|
||||
@@ -617,7 +617,7 @@ internal fun TeamEditorScreen(
|
||||
runCatching {
|
||||
withContext(Dispatchers.IO) {
|
||||
dependencies.myTischtennisApi.configureTeam(
|
||||
de.tt_tagebuch.shared.api.models.MyTtConfigureTeamBody(
|
||||
de.tsschulz.tt_tagebuch.shared.api.models.MyTtConfigureTeamBody(
|
||||
url = myTtUrl.trim(),
|
||||
clubTeamId = team!!.id,
|
||||
createLeague = createLeague,
|
||||
@@ -640,7 +640,7 @@ internal fun TeamEditorScreen(
|
||||
runCatching {
|
||||
withContext(Dispatchers.IO) {
|
||||
dependencies.myTischtennisApi.configureLeague(
|
||||
de.tt_tagebuch.shared.api.models.MyTtConfigureLeagueBody(
|
||||
de.tsschulz.tt_tagebuch.shared.api.models.MyTtConfigureLeagueBody(
|
||||
url = myTtLeagueUrl.trim(),
|
||||
createSeason = createSeasonLeague,
|
||||
),
|
||||
@@ -1091,13 +1091,13 @@ private fun LineupTab(
|
||||
Card(elevation = 0.dp, modifier = Modifier.fillMaxWidth(), backgroundColor = MaterialTheme.colors.surface) {
|
||||
Column(Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
Text(
|
||||
t("mobile.teamPlanningTitle", "Mannschafts-Planung (Web)"),
|
||||
t("mobile.teamPlanningTitle", "Mannschafts-Planung"),
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
Text(
|
||||
t(
|
||||
"mobile.teamPlanningBody",
|
||||
"Die Planungs-Ansicht mit Pool, mehreren Mannschaften und Drag-and-Drop gibt es in der Web-App unter Team-Verwaltung → Planung. In dieser App bearbeitest du die Meldung je Mannschaft hier im Tab Aufstellung.",
|
||||
"Die übergreifende Planung (Pool „Möchte spielen“, mehrere Mannschaften) findest du in der Team-Verwaltung unter dem Reiter „Planung“. Hier pflegst du die Meldung nur für diese eine Mannschaft.",
|
||||
),
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.82f),
|
||||
@@ -1118,12 +1118,12 @@ private fun DocumentsTab(
|
||||
t: (String, String) -> String,
|
||||
canWrite: Boolean,
|
||||
team: ClubTeamDto,
|
||||
documents: List<de.tt_tagebuch.shared.api.models.TeamDocumentDto>,
|
||||
documents: List<de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto>,
|
||||
loading: Boolean,
|
||||
parsingId: Int?,
|
||||
onPickUpload: (String) -> Unit,
|
||||
onParse: (de.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
onOpen: (de.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
onParse: (de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
onOpen: (de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
) {
|
||||
fun latest(type: String) = documents.filter { it.documentType == type }.maxByOrNull { it.id }
|
||||
Column(Modifier.verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
@@ -1154,12 +1154,12 @@ private fun DocumentsTab(
|
||||
@Composable
|
||||
private fun DocCard(
|
||||
title: String,
|
||||
latest: de.tt_tagebuch.shared.api.models.TeamDocumentDto?,
|
||||
latest: de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto?,
|
||||
canWrite: Boolean,
|
||||
parsingId: Int?,
|
||||
onUpload: () -> Unit,
|
||||
onParse: (de.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
onOpen: (de.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
onParse: (de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
onOpen: (de.tsschulz.tt_tagebuch.shared.api.models.TeamDocumentDto) -> Unit,
|
||||
t: (String, String) -> String,
|
||||
) {
|
||||
Card(elevation = 1.dp, modifier = Modifier.fillMaxWidth()) {
|
||||
@@ -1192,7 +1192,7 @@ private fun DocCard(
|
||||
@Composable
|
||||
private fun JobsTab(
|
||||
t: (String, String) -> String,
|
||||
block: de.tt_tagebuch.shared.api.models.SchedulerJobBlockDto?,
|
||||
block: de.tsschulz.tt_tagebuch.shared.api.models.SchedulerJobBlockDto?,
|
||||
teamId: Int,
|
||||
) {
|
||||
val detail = block?.teamDetails?.find { it.clubTeamId == teamId }
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -38,14 +38,14 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.ScheduleLogic
|
||||
import de.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tt_tagebuch.shared.api.models.SeasonDto
|
||||
import de.tt_tagebuch.shared.api.models.canReadTeams
|
||||
import de.tt_tagebuch.shared.api.models.canWriteTeams
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.ScheduleLogic
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.SeasonDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadTeams
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteTeams
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -53,6 +53,11 @@ import kotlinx.coroutines.withContext
|
||||
|
||||
private val TeamPad = 20.dp
|
||||
|
||||
private enum class TeamWorkspaceSection {
|
||||
Teams,
|
||||
Planning,
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TeamManagementScreen(
|
||||
dependencies: AppDependencies,
|
||||
@@ -81,6 +86,8 @@ internal fun TeamManagementScreen(
|
||||
var editorOpen by remember { mutableStateOf(false) }
|
||||
var editorTeamId by remember { mutableStateOf<Int?>(null) }
|
||||
|
||||
var workspace by remember { mutableStateOf(TeamWorkspaceSection.Teams) }
|
||||
|
||||
var seasonMenu by remember { mutableStateOf(false) }
|
||||
|
||||
var deleteTarget by remember { mutableStateOf<ClubTeamDto?>(null) }
|
||||
@@ -172,7 +179,7 @@ internal fun TeamManagementScreen(
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
if (canWrite) {
|
||||
if (canWrite && workspace == TeamWorkspaceSection.Teams) {
|
||||
Button(
|
||||
onClick = { openNewTeamEditor() },
|
||||
enabled = !loading && selectedSeasonId != null,
|
||||
@@ -187,11 +194,19 @@ internal fun TeamManagementScreen(
|
||||
return@Column
|
||||
}
|
||||
|
||||
Text(
|
||||
getMobileString("mobile.teamsIntro", "Mannschaften pro Saison verwalten (Name, Liga, geplante Liga, Geschlechtsklasse, Altersklasse)."),
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.72f),
|
||||
)
|
||||
if (workspace == TeamWorkspaceSection.Teams) {
|
||||
Text(
|
||||
getMobileString("mobile.teamsIntro", "Mannschaften pro Saison verwalten (Name, Liga, geplante Liga, Geschlechtsklasse, Altersklasse)."),
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.72f),
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
getMobileString("teamManagement.planningSubtitle", "Spieler dem Pool „Möchte spielen“ zuordnen und auf Mannschaften verteilen."),
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.72f),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
@@ -217,78 +232,131 @@ internal fun TeamManagementScreen(
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
OutlinedTextField(
|
||||
value = search,
|
||||
onValueChange = { search = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
label = { Text(getMobileString("mobile.teamSearch", "Mannschaft suchen")) },
|
||||
)
|
||||
|
||||
error?.let {
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(it, color = MaterialTheme.colors.error)
|
||||
}
|
||||
|
||||
if (loading && teams.isEmpty()) {
|
||||
Box(Modifier.fillMaxWidth().padding(top = 24.dp), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (workspace == TeamWorkspaceSection.Teams) {
|
||||
Button(onClick = { }, enabled = false, modifier = Modifier.weight(1f)) {
|
||||
Text(getMobileString("mobile.teamWorkspaceTeams", "Mannschaften"))
|
||||
}
|
||||
} else {
|
||||
OutlinedButton(onClick = { workspace = TeamWorkspaceSection.Teams }, modifier = Modifier.weight(1f)) {
|
||||
Text(getMobileString("mobile.teamWorkspaceTeams", "Mannschaften"))
|
||||
}
|
||||
}
|
||||
if (workspace == TeamWorkspaceSection.Planning) {
|
||||
Button(onClick = { }, enabled = false, modifier = Modifier.weight(1f)) {
|
||||
Text(getMobileString("mobile.teamWorkspacePlanning", "Planung"))
|
||||
}
|
||||
} else {
|
||||
OutlinedButton(
|
||||
onClick = { workspace = TeamWorkspaceSection.Planning },
|
||||
enabled = selectedSeasonId != null,
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text(getMobileString("mobile.teamWorkspacePlanning", "Planung"))
|
||||
}
|
||||
}
|
||||
return@Column
|
||||
}
|
||||
|
||||
if (!loading && teams.isEmpty()) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(getMobileString("mobile.noTeams", "Keine Mannschaften für diese Saison."))
|
||||
return@Column
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
items(filtered, key = { it.id }) { team ->
|
||||
Card(elevation = 1.dp, modifier = Modifier.fillMaxWidth()) {
|
||||
Column(Modifier.padding(12.dp)) {
|
||||
Text(team.name.ifBlank { "#${team.id}" }, fontWeight = FontWeight.SemiBold)
|
||||
val lg = team.league?.name?.takeIf { it.isNotBlank() }
|
||||
?: getMobileString("mobile.noLeague", "Keine Liga")
|
||||
Text(lg, style = MaterialTheme.typography.caption)
|
||||
team.season?.season?.takeIf { it.isNotBlank() }?.let {
|
||||
Text(it, style = MaterialTheme.typography.caption)
|
||||
}
|
||||
team.plannedLeagueName?.takeIf { it.isNotBlank() }?.let { pl ->
|
||||
Text(
|
||||
getMobileString("mobile.plannedLeagueShort", "Geplant: ") + pl,
|
||||
style = MaterialTheme.typography.caption,
|
||||
)
|
||||
}
|
||||
val g = team.teamGender ?: "open"
|
||||
val a = team.teamAgeGroup ?: "adult"
|
||||
val genShort = getMobileString("mobile.teamGenderShort", "Geschlecht")
|
||||
val ageShort = getMobileString("mobile.teamAgeShort", "AK")
|
||||
Text(
|
||||
"$genShort: ${labelGender(getMobileString, g)} · $ageShort: ${labelAge(getMobileString, a)}",
|
||||
style = MaterialTheme.typography.caption,
|
||||
)
|
||||
team.myTischtennisTeamId?.takeIf { it.isNotBlank() }?.let { mid ->
|
||||
Text("myTischtennis: $mid", style = MaterialTheme.typography.caption)
|
||||
}
|
||||
if (canWrite) {
|
||||
Row(Modifier.padding(top = 8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
TextButton(onClick = { openEditor(team) }) {
|
||||
Text(getMobileString("common.edit", "Bearbeiten"))
|
||||
when (workspace) {
|
||||
TeamWorkspaceSection.Teams -> {
|
||||
OutlinedTextField(
|
||||
value = search,
|
||||
onValueChange = { search = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
label = { Text(getMobileString("mobile.teamSearch", "Mannschaft suchen")) },
|
||||
)
|
||||
|
||||
error?.let {
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(it, color = MaterialTheme.colors.error)
|
||||
}
|
||||
|
||||
if (loading && teams.isEmpty()) {
|
||||
Box(Modifier.fillMaxWidth().padding(top = 24.dp), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
return@Column
|
||||
}
|
||||
|
||||
if (!loading && teams.isEmpty()) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Text(getMobileString("mobile.noTeams", "Keine Mannschaften für diese Saison."))
|
||||
return@Column
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
items(filtered, key = { it.id }) { team ->
|
||||
Card(elevation = 1.dp, modifier = Modifier.fillMaxWidth()) {
|
||||
Column(Modifier.padding(12.dp)) {
|
||||
Text(team.name.ifBlank { "#${team.id}" }, fontWeight = FontWeight.SemiBold)
|
||||
val lg = team.league?.name?.takeIf { it.isNotBlank() }
|
||||
?: getMobileString("mobile.noLeague", "Keine Liga")
|
||||
Text(lg, style = MaterialTheme.typography.caption)
|
||||
team.season?.season?.takeIf { it.isNotBlank() }?.let {
|
||||
Text(it, style = MaterialTheme.typography.caption)
|
||||
}
|
||||
TextButton(onClick = { deleteTarget = team }) {
|
||||
Text(getMobileString("common.delete", "Löschen"), color = MaterialTheme.colors.error)
|
||||
team.plannedLeagueName?.takeIf { it.isNotBlank() }?.let { pl ->
|
||||
Text(
|
||||
getMobileString("mobile.plannedLeagueShort", "Geplant: ") + pl,
|
||||
style = MaterialTheme.typography.caption,
|
||||
)
|
||||
}
|
||||
val g = team.teamGender ?: "open"
|
||||
val a = team.teamAgeGroup ?: "adult"
|
||||
val genShort = getMobileString("mobile.teamGenderShort", "Geschlecht")
|
||||
val ageShort = getMobileString("mobile.teamAgeShort", "AK")
|
||||
Text(
|
||||
"$genShort: ${labelGender(getMobileString, g)} · $ageShort: ${labelAge(getMobileString, a)}",
|
||||
style = MaterialTheme.typography.caption,
|
||||
)
|
||||
team.myTischtennisTeamId?.takeIf { it.isNotBlank() }?.let { mid ->
|
||||
Text("myTischtennis: $mid", style = MaterialTheme.typography.caption)
|
||||
}
|
||||
if (canWrite) {
|
||||
Row(Modifier.padding(top = 8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
TextButton(onClick = { openEditor(team) }) {
|
||||
Text(getMobileString("common.edit", "Bearbeiten"))
|
||||
}
|
||||
TextButton(onClick = { deleteTarget = team }) {
|
||||
Text(getMobileString("common.delete", "Löschen"), color = MaterialTheme.colors.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TeamWorkspaceSection.Planning -> {
|
||||
val sid = selectedSeasonId
|
||||
if (sid == null) {
|
||||
Text(getMobileString("mobile.seasonPick", "Saison wählen"))
|
||||
} else {
|
||||
TeamPlanningScreen(
|
||||
dependencies = dependencies,
|
||||
clubId = clubId,
|
||||
seasonId = sid,
|
||||
seasonLabel = seasons.find { it.id == sid }?.season.orEmpty(),
|
||||
teams = teams,
|
||||
canWrite = canWrite,
|
||||
onTeamsChanged = { loadTick++ },
|
||||
onOpenTeamEditor = { tid ->
|
||||
editorTeamId = tid
|
||||
editorOpen = true
|
||||
},
|
||||
t = getMobileString,
|
||||
modifier = Modifier.weight(1f).fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import java.util.Calendar
|
||||
import java.util.GregorianCalendar
|
||||
|
||||
/**
|
||||
* Zuordnungen Spieler ↔ Mannschaft in der Saison-Planung (Halbserie),
|
||||
* analog `planningAssignments` / `normalizePlanningTeamAssignments` in `TeamManagementView.vue`.
|
||||
*/
|
||||
internal data class PlanningAssignment(
|
||||
val teamId: Int,
|
||||
val memberId: Int,
|
||||
val position: Int,
|
||||
)
|
||||
|
||||
internal object TeamPlanningLogic {
|
||||
|
||||
fun defaultLineupHalf(): String =
|
||||
if (isSecondHalfSeason()) "second_half" else "first_half"
|
||||
|
||||
private fun isSecondHalfSeason(): Boolean {
|
||||
val now = GregorianCalendar()
|
||||
val seasonStart = GregorianCalendar(now.get(Calendar.YEAR), Calendar.JULY, 1, 0, 0, 0)
|
||||
if (seasonStart.after(now)) {
|
||||
seasonStart.add(Calendar.YEAR, -1)
|
||||
}
|
||||
val secondHalfStart = GregorianCalendar(seasonStart.get(Calendar.YEAR) + 1, Calendar.JANUARY, 1, 0, 0, 0)
|
||||
return now.timeInMillis >= secondHalfStart.timeInMillis
|
||||
}
|
||||
|
||||
fun normalizeAssignments(raw: List<PlanningAssignment>): List<PlanningAssignment> {
|
||||
val filtered = raw.filter { it.teamId > 0 && it.memberId > 0 }
|
||||
val byTeam = filtered.groupBy { it.teamId }
|
||||
val out = ArrayList<PlanningAssignment>()
|
||||
byTeam.entries.sortedBy { it.key }.forEach { (_, entries) ->
|
||||
entries
|
||||
.sortedBy { it.position }
|
||||
.forEachIndexed { idx, e ->
|
||||
out.add(PlanningAssignment(teamId = e.teamId, memberId = e.memberId, position = idx + 1))
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
fun withoutMember(assignments: List<PlanningAssignment>, memberId: Int): List<PlanningAssignment> =
|
||||
assignments.filter { it.memberId != memberId }
|
||||
|
||||
fun assignToTeamEnd(
|
||||
assignments: List<PlanningAssignment>,
|
||||
teamId: Int,
|
||||
memberId: Int,
|
||||
): List<PlanningAssignment> {
|
||||
val without = withoutMember(assignments, memberId)
|
||||
val teamCount = without.count { it.teamId == teamId }
|
||||
return without + PlanningAssignment(teamId = teamId, memberId = memberId, position = teamCount + 1)
|
||||
}
|
||||
|
||||
fun removeFromTeam(assignments: List<PlanningAssignment>, teamId: Int, memberId: Int): List<PlanningAssignment> {
|
||||
val without = assignments.filterNot { it.teamId == teamId && it.memberId == memberId }
|
||||
return normalizeAssignments(without)
|
||||
}
|
||||
|
||||
fun moveWithinTeam(
|
||||
assignments: List<PlanningAssignment>,
|
||||
teamId: Int,
|
||||
memberId: Int,
|
||||
direction: Int,
|
||||
): List<PlanningAssignment>? {
|
||||
val teamEntries = assignments.filter { it.teamId == teamId }.sortedBy { it.position }
|
||||
val index = teamEntries.indexOfFirst { it.memberId == memberId }
|
||||
if (index < 0) return null
|
||||
val target = index + direction
|
||||
if (target < 0 || target >= teamEntries.size) return null
|
||||
val reordered = teamEntries.toMutableList()
|
||||
val tmp = reordered[index]
|
||||
reordered[index] = reordered[target]
|
||||
reordered[target] = tmp
|
||||
val others = assignments.filter { it.teamId != teamId }
|
||||
val updated = others + reordered.mapIndexed { idx, e ->
|
||||
PlanningAssignment(teamId = teamId, memberId = e.memberId, position = idx + 1)
|
||||
}
|
||||
return normalizeAssignments(updated)
|
||||
}
|
||||
|
||||
fun teamLineupMembers(assignments: List<PlanningAssignment>, teamId: Int, membersById: Map<Int, Member>): List<Member> =
|
||||
assignments
|
||||
.filter { it.teamId == teamId }
|
||||
.sortedBy { it.position }
|
||||
.mapNotNull { membersById[it.memberId] }
|
||||
|
||||
fun isEligible(member: Member, team: ClubTeamDto, seasonLabel: String): Boolean {
|
||||
val tAge = TeamEditorLineupLogic.configuredTeamAgeGroup(team.teamAgeGroup, team.league?.name)
|
||||
val tGender = TeamEditorLineupLogic.configuredTeamGender(team.teamGender, team.league?.name)
|
||||
return TeamEditorLineupLogic.isEligibleForTeam(member, tAge, tGender, seasonLabel)
|
||||
}
|
||||
|
||||
fun lineupGapOk(membersOrdered: List<Member>, template: (String, String) -> String): String? =
|
||||
TeamEditorLineupLogic.lineupGapViolationMessage(membersOrdered, template)
|
||||
}
|
||||
@@ -0,0 +1,645 @@
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.OutlinedButton
|
||||
import androidx.compose.material.OutlinedTextField
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateMapOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamCreateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamUpdateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberPlayInterestSetBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupAssignmentItem
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupUpdateBody
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
private data class TeamDraft(
|
||||
val name: String,
|
||||
val plannedLeagueName: String,
|
||||
val teamGender: String,
|
||||
val teamAgeGroup: String,
|
||||
)
|
||||
|
||||
private fun filterAssignmentsForTeamEligibility(
|
||||
teamId: Int,
|
||||
src: List<PlanningAssignment>,
|
||||
teams: List<ClubTeamDto>,
|
||||
drafts: Map<Int, TeamDraft>,
|
||||
membersById: Map<Int, Member>,
|
||||
seasonLabel: String,
|
||||
): List<PlanningAssignment> {
|
||||
val team = teams.find { it.id == teamId } ?: return src
|
||||
val d = drafts[teamId] ?: return src
|
||||
val pseudo = team.copy(
|
||||
name = d.name,
|
||||
plannedLeagueName = d.plannedLeagueName.ifBlank { null },
|
||||
teamGender = d.teamGender,
|
||||
teamAgeGroup = d.teamAgeGroup,
|
||||
)
|
||||
return TeamPlanningLogic.normalizeAssignments(
|
||||
src.filter { a ->
|
||||
if (a.teamId != teamId) return@filter true
|
||||
val m = membersById[a.memberId] ?: return@filter false
|
||||
TeamPlanningLogic.isEligible(m, pseudo, seasonLabel)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TeamPlanningScreen(
|
||||
dependencies: AppDependencies,
|
||||
clubId: Int,
|
||||
seasonId: Int,
|
||||
seasonLabel: String,
|
||||
teams: List<ClubTeamDto>,
|
||||
canWrite: Boolean,
|
||||
onTeamsChanged: () -> Unit,
|
||||
onOpenTeamEditor: (Int) -> Unit,
|
||||
t: (String, String) -> String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var lineupHalf by remember { mutableStateOf(TeamPlanningLogic.defaultLineupHalf()) }
|
||||
var members by remember { mutableStateOf<List<Member>>(emptyList()) }
|
||||
var interestedIds by remember { mutableStateOf<Set<Int>>(emptySet()) }
|
||||
var assignments by remember { mutableStateOf<List<PlanningAssignment>>(emptyList()) }
|
||||
val drafts = remember { mutableStateMapOf<Int, TeamDraft>() }
|
||||
|
||||
var loading by remember { mutableStateOf(true) }
|
||||
var poolSearch by remember { mutableStateOf("") }
|
||||
var addInterestMemberId by remember { mutableStateOf<Int?>(null) }
|
||||
var addInterestMenu by remember { mutableStateOf(false) }
|
||||
var markingInterest by remember { mutableStateOf(false) }
|
||||
var deleteTeamId by remember { mutableStateOf<Int?>(null) }
|
||||
var info by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
val membersById = remember(members) { members.associateBy { it.id } }
|
||||
|
||||
LaunchedEffect(teams.map { "${it.id}:${it.name}:${it.teamGender}:${it.teamAgeGroup}" }.joinToString("|")) {
|
||||
teams.forEach { team ->
|
||||
drafts[team.id] = TeamDraft(
|
||||
name = team.name,
|
||||
plannedLeagueName = team.plannedLeagueName.orEmpty(),
|
||||
teamGender = team.teamGender?.takeIf { it.isNotBlank() } ?: "open",
|
||||
teamAgeGroup = team.teamAgeGroup?.takeIf { it.isNotBlank() } ?: "adult",
|
||||
)
|
||||
}
|
||||
val keep = teams.map { it.id }.toSet()
|
||||
drafts.keys.filter { it !in keep }.forEach { drafts.remove(it) }
|
||||
}
|
||||
|
||||
suspend fun loadPlanningData() {
|
||||
loading = true
|
||||
runCatching {
|
||||
coroutineScope {
|
||||
val memJob = async(Dispatchers.IO) {
|
||||
dependencies.membersApi.listMembers(clubId, showAll = true)
|
||||
}
|
||||
val intJob = async(Dispatchers.IO) {
|
||||
dependencies.membersApi.listPlayInterests(clubId, seasonId, lineupHalf)
|
||||
}
|
||||
members = memJob.await()
|
||||
interestedIds = intJob.await().map { it.memberId }.toSet()
|
||||
|
||||
val lineupJobs = teams.map { team ->
|
||||
async(Dispatchers.IO) {
|
||||
runCatching {
|
||||
team.id to dependencies.clubTeamsApi.getLineup(team.id, lineupHalf)
|
||||
}.getOrElse { team.id to emptyList() }
|
||||
}
|
||||
}
|
||||
val lineups = lineupJobs.awaitAll()
|
||||
assignments = TeamPlanningLogic.normalizeAssignments(
|
||||
lineups.flatMap { (teamId, rows) ->
|
||||
rows.sortedBy { it.position }.mapIndexed { idx, row ->
|
||||
PlanningAssignment(teamId = teamId, memberId = row.memberId, position = idx + 1)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}.onFailure { ex ->
|
||||
if (ex !is CancellationException) {
|
||||
info = ex.message ?: t("mobile.teamLoadError", "Laden fehlgeschlagen")
|
||||
}
|
||||
}
|
||||
loading = false
|
||||
}
|
||||
|
||||
LaunchedEffect(clubId, seasonId, lineupHalf, teams.map { it.id }.sorted().joinToString(",")) {
|
||||
loadPlanningData()
|
||||
}
|
||||
|
||||
val poolMembers = remember(members, interestedIds, poolSearch) {
|
||||
val q = poolSearch.trim().lowercase()
|
||||
members.filter { it.id in interestedIds && it.active }
|
||||
.filter {
|
||||
if (q.isEmpty()) true
|
||||
else "${it.firstName} ${it.lastName}".lowercase().contains(q)
|
||||
}
|
||||
.sortedWith(compareBy({ it.lastName.lowercase() }, { it.firstName.lowercase() }))
|
||||
}
|
||||
|
||||
val assignedIds = remember(assignments) { assignments.map { it.memberId }.toSet() }
|
||||
val unassignedPool = remember(poolMembers, assignedIds) {
|
||||
poolMembers.filter { it.id !in assignedIds }
|
||||
}
|
||||
|
||||
val selectableForInterest = remember(members, interestedIds, poolSearch) {
|
||||
val q = poolSearch.trim().lowercase()
|
||||
members.filter { m ->
|
||||
m.active && m.testMembership != true && m.id !in interestedIds &&
|
||||
(q.isEmpty() || "${m.firstName} ${m.lastName}".lowercase().contains(q))
|
||||
}.sortedWith(compareBy({ it.lastName.lowercase() }, { it.firstName.lowercase() }))
|
||||
}
|
||||
|
||||
fun persistTeam(teamId: Int, nextAssignments: List<PlanningAssignment>, onDone: () -> Unit = {}) {
|
||||
val team = teams.find { it.id == teamId } ?: return
|
||||
val draft = drafts[teamId] ?: return
|
||||
scope.launch {
|
||||
val byId = members.associateBy { it.id }
|
||||
runCatching {
|
||||
val orderedMembers = TeamPlanningLogic.teamLineupMembers(nextAssignments, teamId, byId)
|
||||
val gap = TeamPlanningLogic.lineupGapOk(orderedMembers) { hi, lo ->
|
||||
t("mobile.lineupGapWarn", "QTTR-Abstand >30: $hi über $lo")
|
||||
}
|
||||
if (gap != null) {
|
||||
Toast.makeText(context, gap, Toast.LENGTH_LONG).show()
|
||||
return@launch
|
||||
}
|
||||
val items = orderedMembers.mapIndexed { i, m -> TeamLineupAssignmentItem(m.id, i + 1) }
|
||||
withContext(Dispatchers.IO) {
|
||||
dependencies.clubTeamsApi.updateClubTeam(
|
||||
teamId,
|
||||
ClubTeamUpdateBody(
|
||||
name = draft.name.trim(),
|
||||
leagueId = team.leagueId,
|
||||
seasonId = team.seasonId ?: seasonId,
|
||||
teamGender = draft.teamGender,
|
||||
teamAgeGroup = draft.teamAgeGroup,
|
||||
plannedLeagueName = draft.plannedLeagueName.trim().ifBlank { null },
|
||||
),
|
||||
)
|
||||
dependencies.clubTeamsApi.updateLineup(
|
||||
teamId,
|
||||
TeamLineupUpdateBody(assignments = items, lineupHalf = lineupHalf),
|
||||
)
|
||||
}
|
||||
assignments = TeamPlanningLogic.normalizeAssignments(nextAssignments)
|
||||
onTeamsChanged()
|
||||
onDone()
|
||||
}.onFailure { ex ->
|
||||
if (ex !is CancellationException) info = ex.message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(modifier.fillMaxSize()) {
|
||||
Text(
|
||||
t("teamManagement.planningSubtitle", "Spieler dem Pool „Möchte spielen“ zuordnen und auf Mannschaften verteilen."),
|
||||
style = MaterialTheme.typography.caption,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.78f),
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(t("common.period", "Halbserie"), style = MaterialTheme.typography.body2)
|
||||
listOf("first_half" to "VR", "second_half" to "RR").forEach { (v, label) ->
|
||||
OutlinedButton(
|
||||
onClick = { lineupHalf = v },
|
||||
enabled = !loading && lineupHalf != v,
|
||||
) { Text(label) }
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
OutlinedButton(onClick = { scope.launch { loadPlanningData() } }, enabled = !loading) {
|
||||
Text(t("teamManagement.refreshStats", "Aktualisieren"))
|
||||
}
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
CircularProgressIndicator(Modifier.padding(16.dp))
|
||||
} else {
|
||||
LazyColumn(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
item {
|
||||
Text(t("teamManagement.playersWantToPlay", "Möchte spielen (Pool)"), fontWeight = FontWeight.SemiBold)
|
||||
OutlinedTextField(
|
||||
value = poolSearch,
|
||||
onValueChange = { poolSearch = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
label = { Text(t("teamManagement.searchMembers", "Mitglieder suchen")) },
|
||||
)
|
||||
Text(
|
||||
t("mobile.teamPlanningUnassigned", "Noch keiner Mannschaft zugeordnet") + ": ${unassignedPool.size}",
|
||||
style = MaterialTheme.typography.caption,
|
||||
)
|
||||
}
|
||||
items(unassignedPool, key = { it.id }) { m ->
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text("${m.firstName} ${m.lastName}", fontWeight = FontWeight.Medium)
|
||||
}
|
||||
if (canWrite) {
|
||||
var addMenu by remember(key1 = m.id) { mutableStateOf(false) }
|
||||
Box {
|
||||
OutlinedButton(onClick = { addMenu = true }) {
|
||||
Text(t("mobile.teamPlanningAssign", "Zu Mannschaft …"))
|
||||
}
|
||||
DropdownMenu(expanded = addMenu, onDismissRequest = { addMenu = false }) {
|
||||
teams.forEach { team ->
|
||||
val draft = drafts[team.id] ?: return@forEach
|
||||
val pseudo = team.copy(
|
||||
name = draft.name,
|
||||
plannedLeagueName = draft.plannedLeagueName.ifBlank { null },
|
||||
teamGender = draft.teamGender,
|
||||
teamAgeGroup = draft.teamAgeGroup,
|
||||
)
|
||||
val ok = TeamPlanningLogic.isEligible(m, pseudo, seasonLabel)
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
addMenu = false
|
||||
if (!ok) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
t(
|
||||
"mobile.teamPlanningNotEligible",
|
||||
"Mitglied passt nicht zu Alters-/Geschlechtsklasse dieser Mannschaft.",
|
||||
),
|
||||
Toast.LENGTH_LONG,
|
||||
).show()
|
||||
return@DropdownMenuItem
|
||||
}
|
||||
val next = TeamPlanningLogic.assignToTeamEnd(assignments, team.id, m.id)
|
||||
val gapMembers = TeamPlanningLogic.teamLineupMembers(next, team.id, membersById)
|
||||
val gap = TeamPlanningLogic.lineupGapOk(gapMembers) { hi, lo ->
|
||||
t("mobile.lineupGapWarn", "QTTR-Abstand >30: $hi über $lo")
|
||||
}
|
||||
if (gap != null) {
|
||||
Toast.makeText(context, gap, Toast.LENGTH_LONG).show()
|
||||
return@DropdownMenuItem
|
||||
}
|
||||
persistTeam(team.id, next)
|
||||
},
|
||||
enabled = ok,
|
||||
) {
|
||||
Text(team.name.ifBlank { "#${team.id}" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
Divider()
|
||||
Text(t("teamManagement.markAsInterested", "Als interessiert markieren"), fontWeight = FontWeight.SemiBold)
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Box(Modifier.weight(1f)) {
|
||||
OutlinedButton(
|
||||
onClick = { addInterestMenu = true },
|
||||
enabled = canWrite && !markingInterest,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text(
|
||||
addInterestMemberId?.let { id ->
|
||||
membersById[id]?.let { "${it.firstName} ${it.lastName}" }
|
||||
} ?: t("teamManagement.selectMember", "Mitglied wählen"),
|
||||
)
|
||||
}
|
||||
DropdownMenu(expanded = addInterestMenu, onDismissRequest = { addInterestMenu = false }) {
|
||||
selectableForInterest.take(400).forEach { m ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
addInterestMemberId = m.id
|
||||
addInterestMenu = false
|
||||
},
|
||||
) { Text("${m.firstName} ${m.lastName}") }
|
||||
}
|
||||
}
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
val mid = addInterestMemberId ?: return@Button
|
||||
scope.launch {
|
||||
markingInterest = true
|
||||
runCatching {
|
||||
withContext(Dispatchers.IO) {
|
||||
dependencies.membersApi.setPlayInterest(
|
||||
clubId,
|
||||
MemberPlayInterestSetBody(
|
||||
memberId = mid,
|
||||
seasonId = seasonId,
|
||||
lineupHalf = lineupHalf,
|
||||
interested = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
interestedIds = interestedIds + mid
|
||||
addInterestMemberId = null
|
||||
}.onFailure { if (it !is CancellationException) info = it.message }
|
||||
markingInterest = false
|
||||
}
|
||||
},
|
||||
enabled = canWrite && addInterestMemberId != null && !markingInterest,
|
||||
) {
|
||||
Text(if (markingInterest) "…" else t("teamManagement.markAsInterested", "Interesse speichern"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
Divider()
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(t("teamManagement.planningTitle", "Planung"), fontWeight = FontWeight.SemiBold)
|
||||
if (canWrite) {
|
||||
Button(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
runCatching {
|
||||
val nextIndex = teams.size + 1
|
||||
withContext(Dispatchers.IO) {
|
||||
dependencies.clubTeamsApi.createClubTeam(
|
||||
clubId,
|
||||
ClubTeamCreateBody(
|
||||
name = t("teamManagement.teamName", "Mannschaft") + " $nextIndex",
|
||||
leagueId = null,
|
||||
seasonId = seasonId,
|
||||
teamGender = "open",
|
||||
teamAgeGroup = "adult",
|
||||
plannedLeagueName = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
onTeamsChanged()
|
||||
}.onFailure { if (it !is CancellationException) info = it.message }
|
||||
}
|
||||
},
|
||||
) {
|
||||
Text(t("teamManagement.addPlanningTeam", "Mannschaft hinzufügen"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items(teams, key = { it.id }) { team ->
|
||||
val teamId = team.id
|
||||
val draft = drafts[teamId] ?: return@items
|
||||
CardTeamPlanningBlock(
|
||||
team = team,
|
||||
draft = draft,
|
||||
onDraftChange = { nd -> drafts[teamId] = nd },
|
||||
assignments = assignments,
|
||||
membersById = membersById,
|
||||
canWrite = canWrite,
|
||||
t = t,
|
||||
onPersistLineup = { next -> persistTeam(teamId, next) },
|
||||
onSaveTeamMeta = {
|
||||
val fa = filterAssignmentsForTeamEligibility(
|
||||
teamId,
|
||||
assignments,
|
||||
teams,
|
||||
drafts,
|
||||
membersById,
|
||||
seasonLabel,
|
||||
)
|
||||
persistTeam(teamId, fa)
|
||||
},
|
||||
onMoveInTeam = { memberId, dir ->
|
||||
val next = TeamPlanningLogic.moveWithinTeam(assignments, teamId, memberId, dir)
|
||||
if (next != null) persistTeam(teamId, next)
|
||||
},
|
||||
onRemoveMember = { memberId ->
|
||||
val next = TeamPlanningLogic.removeFromTeam(assignments, teamId, memberId)
|
||||
persistTeam(teamId, next)
|
||||
},
|
||||
onOpenEditor = { onOpenTeamEditor(teamId) },
|
||||
onDeleteRequest = { deleteTeamId = teamId },
|
||||
poolAddCandidates = unassignedPool.filter { u ->
|
||||
val pseudo = team.copy(
|
||||
name = draft.name,
|
||||
plannedLeagueName = draft.plannedLeagueName.ifBlank { null },
|
||||
teamGender = draft.teamGender,
|
||||
teamAgeGroup = draft.teamAgeGroup,
|
||||
)
|
||||
TeamPlanningLogic.isEligible(u, pseudo, seasonLabel)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deleteTeamId?.let { tid ->
|
||||
AlertDialog(
|
||||
onDismissRequest = { deleteTeamId = null },
|
||||
title = { Text(t("mobile.teamDeleteTitle", "Mannschaft löschen?")) },
|
||||
text = { Text(teams.find { it.id == tid }?.name.orEmpty()) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
deleteTeamId = null
|
||||
scope.launch {
|
||||
runCatching {
|
||||
withContext(Dispatchers.IO) { dependencies.clubTeamsApi.deleteClubTeam(tid) }
|
||||
onTeamsChanged()
|
||||
}.onFailure { if (it !is CancellationException) info = it.message }
|
||||
}
|
||||
},
|
||||
) { Text(t("common.delete", "Löschen")) }
|
||||
},
|
||||
dismissButton = { TextButton(onClick = { deleteTeamId = null }) { Text(t("common.cancel", "Abbrechen")) } },
|
||||
)
|
||||
}
|
||||
|
||||
info?.let { msg ->
|
||||
AlertDialog(
|
||||
onDismissRequest = { info = null },
|
||||
title = { Text(t("common.error", "Fehler")) },
|
||||
text = { Text(msg) },
|
||||
confirmButton = { TextButton(onClick = { info = null }) { Text(t("common.ok", "OK")) } },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CardTeamPlanningBlock(
|
||||
team: ClubTeamDto,
|
||||
draft: TeamDraft,
|
||||
onDraftChange: (TeamDraft) -> Unit,
|
||||
assignments: List<PlanningAssignment>,
|
||||
membersById: Map<Int, Member>,
|
||||
canWrite: Boolean,
|
||||
t: (String, String) -> String,
|
||||
onPersistLineup: (List<PlanningAssignment>) -> Unit,
|
||||
onSaveTeamMeta: () -> Unit,
|
||||
onMoveInTeam: (Int, Int) -> Unit,
|
||||
onRemoveMember: (Int) -> Unit,
|
||||
onOpenEditor: () -> Unit,
|
||||
onDeleteRequest: () -> Unit,
|
||||
poolAddCandidates: List<Member>,
|
||||
) {
|
||||
val teamId = team.id
|
||||
val ordered = TeamPlanningLogic.teamLineupMembers(assignments, teamId, membersById)
|
||||
var metaMenu by remember { mutableStateOf(false) }
|
||||
var addMemberMenu by remember { mutableStateOf(false) }
|
||||
val cardContext = LocalContext.current
|
||||
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
Text(team.name.ifBlank { "#$teamId" }, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.subtitle1)
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
OutlinedButton(onClick = onOpenEditor) {
|
||||
Text(t("teamManagement.openInWorkspace", "Im Editor öffnen"))
|
||||
}
|
||||
if (canWrite) {
|
||||
OutlinedButton(onClick = onDeleteRequest) {
|
||||
Text(t("common.delete", "Löschen"))
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(6.dp))
|
||||
OutlinedTextField(
|
||||
value = draft.name,
|
||||
onValueChange = { onDraftChange(draft.copy(name = it)) },
|
||||
label = { Text(t("teamManagement.teamName", "Mannschaft")) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = canWrite,
|
||||
singleLine = true,
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = draft.plannedLeagueName,
|
||||
onValueChange = { onDraftChange(draft.copy(plannedLeagueName = it)) },
|
||||
label = { Text(t("teamManagement.plannedLeague", "Geplante Liga")) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = canWrite,
|
||||
singleLine = true,
|
||||
)
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Box {
|
||||
OutlinedButton(onClick = { metaMenu = true }, enabled = canWrite) {
|
||||
Text(t("mobile.teamAgeShort", "AK") + ": ${draft.teamAgeGroup}")
|
||||
}
|
||||
DropdownMenu(expanded = metaMenu, onDismissRequest = { metaMenu = false }) {
|
||||
listOf("adult", "J19", "J17", "J15", "J13", "J11").forEach { a ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
metaMenu = false
|
||||
onDraftChange(draft.copy(teamAgeGroup = a))
|
||||
onSaveTeamMeta()
|
||||
},
|
||||
) { Text(a) }
|
||||
}
|
||||
}
|
||||
}
|
||||
Box {
|
||||
var gMenu by remember { mutableStateOf(false) }
|
||||
OutlinedButton(onClick = { gMenu = true }, enabled = canWrite) {
|
||||
Text(t("mobile.teamGenderShort", "GK") + ": ${draft.teamGender}")
|
||||
}
|
||||
DropdownMenu(expanded = gMenu, onDismissRequest = { gMenu = false }) {
|
||||
listOf("open", "female").forEach { g ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
gMenu = false
|
||||
onDraftChange(draft.copy(teamGender = g))
|
||||
onSaveTeamMeta()
|
||||
},
|
||||
) { Text(g) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canWrite) {
|
||||
Button(
|
||||
onClick = { onSaveTeamMeta() },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Text(t("mobile.teamPlanningSaveTeam", "Mannschaft speichern"))
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Text(t("teamManagement.selectedLineup", "Meldung"), fontWeight = FontWeight.Medium)
|
||||
ordered.forEachIndexed { index, m ->
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("${index + 1}. ${m.firstName} ${m.lastName}")
|
||||
if (canWrite) {
|
||||
Row {
|
||||
TextButton(onClick = { onMoveInTeam(m.id, -1) }, enabled = index > 0) { Text("↑") }
|
||||
TextButton(onClick = { onMoveInTeam(m.id, 1) }, enabled = index < ordered.lastIndex) { Text("↓") }
|
||||
TextButton(onClick = { onRemoveMember(m.id) }) { Text("−") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canWrite && poolAddCandidates.isNotEmpty()) {
|
||||
Box {
|
||||
OutlinedButton(onClick = { addMemberMenu = true }) {
|
||||
Text(t("mobile.teamLineupAddToLineup", "Hinzufügen"))
|
||||
}
|
||||
DropdownMenu(expanded = addMemberMenu, onDismissRequest = { addMemberMenu = false }) {
|
||||
poolAddCandidates.forEach { m ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
addMemberMenu = false
|
||||
val next = TeamPlanningLogic.assignToTeamEnd(assignments, teamId, m.id)
|
||||
val gapMembers = TeamPlanningLogic.teamLineupMembers(next, teamId, membersById)
|
||||
val gap = TeamPlanningLogic.lineupGapOk(gapMembers) { hi, lo ->
|
||||
t("mobile.lineupGapWarn", "QTTR-Abstand >30: $hi über $lo")
|
||||
}
|
||||
if (gap != null) {
|
||||
Toast.makeText(cardContext, gap, Toast.LENGTH_LONG).show()
|
||||
} else {
|
||||
onPersistLineup(next)
|
||||
}
|
||||
},
|
||||
) { Text("${m.firstName} ${m.lastName}") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
@@ -40,15 +40,15 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.shared.api.models.AddMiniChampionshipBody
|
||||
import de.tt_tagebuch.shared.api.models.AddStandardTournamentBody
|
||||
import de.tt_tagebuch.shared.api.models.InternalTournamentSummaryDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParticipationEntryDto
|
||||
import de.tt_tagebuch.shared.api.models.canReadTournaments
|
||||
import de.tt_tagebuch.shared.api.models.canWriteTournaments
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tt_tagebuch.shared.state.ClubTournamentDisplayFilter
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddMiniChampionshipBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddStandardTournamentBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentSummaryDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipationEntryDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canReadTournaments
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteTournaments
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.shared.state.ClubTournamentDisplayFilter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -42,11 +42,11 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import de.tt_tagebuch.app.AppDependencies
|
||||
import de.tt_tagebuch.app.pdf.shareFileWithMime
|
||||
import de.tt_tagebuch.app.stats.TrainingStatsDerived
|
||||
import de.tt_tagebuch.shared.api.models.TrainingStatsMember
|
||||
import de.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import de.tsschulz.tt_tagebuch.app.AppDependencies
|
||||
import de.tsschulz.tt_tagebuch.app.pdf.shareFileWithMime
|
||||
import de.tsschulz.tt_tagebuch.app.stats.TrainingStatsDerived
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsMember
|
||||
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.lightColors
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.app.util
|
||||
package de.tsschulz.tt_tagebuch.app.util
|
||||
|
||||
import de.tt_tagebuch.shared.api.models.Member
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedCompetitionDto
|
||||
import de.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedCompetitionDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
|
||||
import java.text.Collator
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Entspricht legacy Expo android.adaptiveIcon.backgroundColor -->
|
||||
<color name="ic_launcher_background">#FFFFFF</color>
|
||||
</resources>
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.app
|
||||
package de.tsschulz.tt_tagebuch.app
|
||||
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import de.tt_tagebuch.app.ui.LoginScreen
|
||||
import de.tsschulz.tt_tagebuch.app.ui.LoginScreen
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.tsschulz.tt_tagebuch.app.di
|
||||
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.DiaryScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.LoginScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.MemberScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.ParticipantScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.MemberEditScreenModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val appModule = module {
|
||||
factory { LoginScreenModel(get()) }
|
||||
factory { DiaryScreenModel(get()) }
|
||||
factory { MemberScreenModel(get()) } // Updated
|
||||
factory { ParticipantScreenModel(get()) }
|
||||
factory { MemberEditScreenModel(get()) }
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
@@ -13,8 +13,8 @@ import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.DiaryScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.DiaryState
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.DiaryScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.DiaryState
|
||||
|
||||
class DiaryScreen(private val clubId: Int) : Screen {
|
||||
@Composable
|
||||
@@ -65,7 +65,7 @@ class DiaryScreen(private val clubId: Int) : Screen {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DiaryDateItem(date: de.tt_tagebuch.shared.models.DiaryDate, onClick: () -> Unit) {
|
||||
fun DiaryDateItem(date: de.tsschulz.tt_tagebuch.shared.models.DiaryDate, onClick: () -> Unit) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth().padding(8.dp).clickable { onClick() },
|
||||
elevation = 4.dp
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
@@ -10,9 +10,9 @@ import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import de.tt_tagebuch.app.viewmodel.LoginScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.LoginState
|
||||
import de.tt_tagebuch.app.ui.HomeScreen
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.LoginScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.LoginState
|
||||
import de.tsschulz.tt_tagebuch.app.ui.HomeScreen
|
||||
|
||||
class LoginScreen : Screen {
|
||||
@Composable
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@@ -16,7 +16,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import de.tt_tagebuch.shared.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.models.Member
|
||||
|
||||
class MemberDetailScreen(private val member: Member) : Screen {
|
||||
@Composable
|
||||
@@ -121,7 +121,7 @@ class MemberDetailScreen(private val member: Member) : Screen {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContactRow(contact: de.tt_tagebuch.shared.models.MemberContact) {
|
||||
fun ContactRow(contact: de.tsschulz.tt_tagebuch.shared.models.MemberContact) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@@ -16,10 +16,10 @@ import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import de.tt_tagebuch.app.viewmodel.MemberEditScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.MemberEditState
|
||||
import de.tt_tagebuch.shared.models.Member
|
||||
import de.tt_tagebuch.shared.models.MemberContact
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.MemberEditScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.MemberEditState
|
||||
import de.tsschulz.tt_tagebuch.shared.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.models.MemberContact
|
||||
|
||||
class MemberEditScreen(private val clubId: Int, private val member: Member? = null) : Screen {
|
||||
@Composable
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
@@ -13,8 +13,8 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.MemberScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.MemberState
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.MemberScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.MemberState
|
||||
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
|
||||
@@ -70,7 +70,7 @@ class MemberScreen(private val clubId: Int) : Screen {
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun MemberItem(member: de.tt_tagebuch.shared.models.Member, onClick: () -> Unit) {
|
||||
fun MemberItem(member: de.tsschulz.tt_tagebuch.shared.models.Member, onClick: () -> Unit) {
|
||||
ListItem(
|
||||
modifier = Modifier.clickable { onClick() },
|
||||
text = { Text("${member.firstName} ${member.lastName}") },
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.app.ui
|
||||
package de.tsschulz.tt_tagebuch.app.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@@ -14,8 +14,8 @@ import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import de.tt_tagebuch.app.viewmodel.ParticipantScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.ParticipantState
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.ParticipantScreenModel
|
||||
import de.tsschulz.tt_tagebuch.app.viewmodel.ParticipantState
|
||||
|
||||
class ParticipantScreen(private val dateId: Int, private val dateStr: String) : Screen {
|
||||
@Composable
|
||||
@@ -69,7 +69,7 @@ class ParticipantScreen(private val dateId: Int, private val dateStr: String) :
|
||||
|
||||
@Composable
|
||||
fun ParticipantItem(
|
||||
participant: de.tt_tagebuch.shared.models.Participant,
|
||||
participant: de.tsschulz.tt_tagebuch.shared.models.Participant,
|
||||
onStatusChange: (String) -> Unit
|
||||
) {
|
||||
val member = participant.member
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.app.viewmodel
|
||||
package de.tsschulz.tt_tagebuch.app.viewmodel
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import de.tt_tagebuch.shared.models.DiaryDate
|
||||
import de.tt_tagebuch.shared.repository.DiaryRepository
|
||||
import de.tsschulz.tt_tagebuch.shared.models.DiaryDate
|
||||
import de.tsschulz.tt_tagebuch.shared.repository.DiaryRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.app.viewmodel
|
||||
package de.tsschulz.tt_tagebuch.app.viewmodel
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import de.tt_tagebuch.shared.repository.AuthRepository
|
||||
import de.tsschulz.tt_tagebuch.shared.repository.AuthRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.app.viewmodel
|
||||
package de.tsschulz.tt_tagebuch.app.viewmodel
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import de.tt_tagebuch.shared.models.Member
|
||||
import de.tt_tagebuch.shared.repository.MemberRepository
|
||||
import de.tsschulz.tt_tagebuch.shared.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.repository.MemberRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.app.viewmodel
|
||||
package de.tsschulz.tt_tagebuch.app.viewmodel
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import de.tt_tagebuch.shared.models.Member
|
||||
import de.tt_tagebuch.shared.repository.DiaryRepository
|
||||
import de.tsschulz.tt_tagebuch.shared.models.Member
|
||||
import de.tsschulz.tt_tagebuch.shared.repository.DiaryRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.app.viewmodel
|
||||
package de.tsschulz.tt_tagebuch.app.viewmodel
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import de.tt_tagebuch.shared.models.Participant
|
||||
import de.tt_tagebuch.shared.repository.DiaryRepository
|
||||
import de.tsschulz.tt_tagebuch.shared.models.Participant
|
||||
import de.tsschulz.tt_tagebuch.shared.repository.DiaryRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,16 +0,0 @@
|
||||
package de.tt_tagebuch.app.di
|
||||
|
||||
import de.tt_tagebuch.app.viewmodel.DiaryScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.LoginScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.MemberScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.ParticipantScreenModel
|
||||
import de.tt_tagebuch.app.viewmodel.MemberEditScreenModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val appModule = module {
|
||||
factory { LoginScreenModel(get()) }
|
||||
factory { DiaryScreenModel(get()) }
|
||||
factory { MemberScreenModel(get()) } // Updated
|
||||
factory { ParticipantScreenModel(get()) }
|
||||
factory { MemberEditScreenModel(get()) }
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
# Nutzung: von mobile-app/ aus: ./scripts/install-debug-emulator.sh
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
adb uninstall de.tt_tagebuch.app 2>/dev/null || true
|
||||
adb uninstall de.tsschulz.tt_tagebuch 2>/dev/null || true
|
||||
./gradlew :composeApp:clean :composeApp:installDebug \
|
||||
-PbackendBaseUrl=http://10.0.2.2:3005 \
|
||||
--no-configuration-cache
|
||||
|
||||
@@ -47,7 +47,7 @@ kotlin {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "de.tt_tagebuch.shared"
|
||||
namespace = "de.tsschulz.tt_tagebuch.shared"
|
||||
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
||||
defaultConfig {
|
||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.shared.api.http
|
||||
package de.tsschulz.tt_tagebuch.shared.api.http
|
||||
|
||||
import io.ktor.client.engine.HttpClientEngine
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.shared.state
|
||||
package de.tsschulz.tt_tagebuch.shared.state
|
||||
|
||||
import android.content.Context
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.shared.state
|
||||
package de.tsschulz.tt_tagebuch.shared.state
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.shared.state
|
||||
package de.tsschulz.tt_tagebuch.shared.state
|
||||
|
||||
import android.content.Context
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.AccidentReportDto
|
||||
import de.tt_tagebuch.shared.api.models.CreateAccidentBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AccidentReportDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateAccidentBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.post
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.models.*
|
||||
import de.tsschulz.tt_tagebuch.shared.models.*
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
data class ApiConfig(
|
||||
val baseUrl: String,
|
||||
@@ -1,11 +1,11 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.ApiLogDetailDto
|
||||
import de.tt_tagebuch.shared.api.models.ApiLogDetailEnvelopeDto
|
||||
import de.tt_tagebuch.shared.api.models.ApiLogsListEnvelopeDto
|
||||
import de.tt_tagebuch.shared.api.models.ApiLogsListPageDto
|
||||
import de.tt_tagebuch.shared.api.models.SchedulerLastExecutionsEnvelopeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ApiLogDetailDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ApiLogDetailEnvelopeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ApiLogsListEnvelopeDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ApiLogsListPageDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.SchedulerLastExecutionsEnvelopeDto
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.LoginRequest
|
||||
import de.tt_tagebuch.shared.api.models.LoginResponse
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.LoginRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.LoginResponse
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.client.request.setBody
|
||||
@@ -1,14 +1,14 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.BillingCreateRunBody
|
||||
import de.tt_tagebuch.shared.api.models.BillingCreateRunEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.BillingGenerateBody
|
||||
import de.tt_tagebuch.shared.api.models.BillingGenerateEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.BillingHoursPreviewEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.BillingRunsEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.BillingSettingsEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.BillingTemplatesEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingCreateRunBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingCreateRunEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingGenerateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingGenerateEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingHoursPreviewEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingRunsEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingSettingsEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.BillingTemplatesEnvelope
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.forms.MultiPartFormDataContent
|
||||
@@ -1,7 +1,7 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubCalendarHolidaysEnvelope
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
@@ -1,12 +1,12 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountSaveResponse
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountStatusDto
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtAccountUpsertBody
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtVerifyBody
|
||||
import de.tt_tagebuch.shared.api.models.ClickTtVerifyResponseDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountSaveResponse
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountStatusDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtAccountUpsertBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtVerifyBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClickTtVerifyResponseDto
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.ClubAccessDecisionBody
|
||||
import de.tt_tagebuch.shared.api.models.PendingUserClubJoinDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubAccessDecisionBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.PendingUserClubJoinDto
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.post
|
||||
@@ -1,12 +1,12 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamCreateBody
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamLineupRowDto
|
||||
import de.tt_tagebuch.shared.api.models.ClubTeamUpdateBody
|
||||
import de.tt_tagebuch.shared.api.models.TeamLineupUpdateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamCreateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamLineupRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamUpdateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupUpdateBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.Club
|
||||
import de.tt_tagebuch.shared.api.models.UpdateClubSettingsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.Club
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateClubSettingsBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.post
|
||||
@@ -1,21 +1,21 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.AddDiaryNoteRequest
|
||||
import de.tt_tagebuch.shared.api.models.AddFreeformActivityBody
|
||||
import de.tt_tagebuch.shared.api.models.AddDiaryPlanGroupActivityRequest
|
||||
import de.tt_tagebuch.shared.api.models.CreateDiaryDateRequest
|
||||
import de.tt_tagebuch.shared.api.models.CreateDiaryPlanActivityRequest
|
||||
import de.tt_tagebuch.shared.api.models.DiaryDate
|
||||
import de.tt_tagebuch.shared.api.models.DiaryDateActivityItem
|
||||
import de.tt_tagebuch.shared.api.models.DiaryFreeformActivity
|
||||
import de.tt_tagebuch.shared.api.models.DiaryNote
|
||||
import de.tt_tagebuch.shared.api.models.DiaryTag
|
||||
import de.tt_tagebuch.shared.api.models.LinkDiaryTagRequest
|
||||
import de.tt_tagebuch.shared.api.models.UpdateDiaryPlanActivityOrderRequest
|
||||
import de.tt_tagebuch.shared.api.models.UpdateDiaryPlanActivityRequest
|
||||
import de.tt_tagebuch.shared.api.models.UpdateDiaryTimesRequest
|
||||
import de.tt_tagebuch.shared.api.models.UpdateNestedPlanGroupActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddDiaryNoteRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddFreeformActivityBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddDiaryPlanGroupActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateDiaryDateRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateDiaryPlanActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryDate
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryDateActivityItem
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryFreeformActivity
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryNote
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryTag
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.LinkDiaryTagRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateDiaryPlanActivityOrderRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateDiaryPlanActivityRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateDiaryTimesRequest
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateNestedPlanGroupActivityRequest
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.AddMemberActivityParticipantsBody
|
||||
import de.tt_tagebuch.shared.api.models.DiaryMemberActivityLink
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddMemberActivityParticipantsBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberActivityLink
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
@@ -1,10 +1,10 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.AddDiaryMemberNoteBody
|
||||
import de.tt_tagebuch.shared.api.models.DiaryMemberNoteDto
|
||||
import de.tt_tagebuch.shared.api.models.DiaryMemberTagLinkDto
|
||||
import de.tt_tagebuch.shared.api.models.DiaryMemberTagMutationBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.AddDiaryMemberNoteBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberNoteDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberTagLinkDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberTagMutationBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
@@ -1,10 +1,10 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.CreateTrainingGroupBody
|
||||
import de.tt_tagebuch.shared.api.models.DeleteTrainingGroupBody
|
||||
import de.tt_tagebuch.shared.api.models.DiaryPlanGroup
|
||||
import de.tt_tagebuch.shared.api.models.UpdateTrainingGroupBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.CreateTrainingGroupBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DeleteTrainingGroupBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.DiaryPlanGroup
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateTrainingGroupBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||
@@ -1,10 +1,10 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.LeaguePlayerStatDto
|
||||
import de.tt_tagebuch.shared.api.models.LeagueTableRowDto
|
||||
import de.tt_tagebuch.shared.api.models.ScheduleMatchDto
|
||||
import de.tt_tagebuch.shared.api.models.UpdateMatchPlayersBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.LeaguePlayerStatDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.LeagueTableRowDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.ScheduleMatchDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.UpdateMatchPlayersBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.MemberActivityStatDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberLastParticipationDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberActivityStatDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberLastParticipationDto
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.MemberGroupPhotoDto
|
||||
import de.tt_tagebuch.shared.api.models.MemberGroupPhotoListResponse
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberGroupPhotoDto
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberGroupPhotoListResponse
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.forms.MultiPartFormDataContent
|
||||
@@ -1,10 +1,10 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.MemberOrderCreateBody
|
||||
import de.tt_tagebuch.shared.api.models.MemberOrderEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.MemberOrderPatchBody
|
||||
import de.tt_tagebuch.shared.api.models.MemberOrdersListEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberOrderCreateBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberOrderEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberOrderPatchBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberOrdersListEnvelope
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.patch
|
||||
@@ -1,9 +1,9 @@
|
||||
package de.tt_tagebuch.shared.api
|
||||
package de.tsschulz.tt_tagebuch.shared.api
|
||||
|
||||
import de.tt_tagebuch.shared.api.http.ApiException
|
||||
import de.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tt_tagebuch.shared.api.models.MemberTransferConfigEnvelope
|
||||
import de.tt_tagebuch.shared.api.models.MemberTransferConfigSaveBody
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.ApiException
|
||||
import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferConfigEnvelope
|
||||
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferConfigSaveBody
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.delete
|
||||
import io.ktor.client.request.get
|
||||