feat: add number of tables to tournament updates and enhance related UI components
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 47s
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 47s
This commit is contained in:
Binary file not shown.
@@ -22,12 +22,17 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.AlertDialog
|
||||
@@ -235,19 +240,37 @@ fun AppRoot(dependencies: AppDependencies) {
|
||||
}
|
||||
|
||||
CompositionLocalProvider(LocalLanguageCode provides languageState.currentLanguageCode) {
|
||||
var openMemberPortraitCropRequested by remember { mutableStateOf(false) }
|
||||
var openMemberGalleryRequested by remember { mutableStateOf(false) }
|
||||
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
|
||||
when {
|
||||
authState.isHydrating -> LoadingScreen(tr("mobile.appLoading", "App wird geladen"))
|
||||
!authState.isLoggedIn -> AuthFlowHost(dependencies = dependencies)
|
||||
clubState.currentClubId == null -> ClubSelectScreen(dependencies)
|
||||
else -> MainTabs(dependencies)
|
||||
else -> MainTabs(
|
||||
dependencies,
|
||||
openMemberPortraitCropRequested = openMemberPortraitCropRequested,
|
||||
onConsumeOpenMemberPortraitCrop = { openMemberPortraitCropRequested = false },
|
||||
onRequestOpenMemberPortraitCrop = { openMemberPortraitCropRequested = true },
|
||||
openMemberGalleryRequested = openMemberGalleryRequested,
|
||||
onConsumeOpenMemberGallery = { openMemberGalleryRequested = false },
|
||||
onRequestOpenMemberGallery = { openMemberGalleryRequested = true },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainTabs(dependencies: AppDependencies) {
|
||||
private fun MainTabs(
|
||||
dependencies: AppDependencies,
|
||||
openMemberPortraitCropRequested: Boolean,
|
||||
onConsumeOpenMemberPortraitCrop: () -> Unit,
|
||||
onRequestOpenMemberPortraitCrop: () -> Unit,
|
||||
openMemberGalleryRequested: Boolean,
|
||||
onConsumeOpenMemberGallery: () -> Unit,
|
||||
onRequestOpenMemberGallery: () -> Unit,
|
||||
) {
|
||||
var selectedTab by rememberSaveable { mutableStateOf(MainTab.Home) }
|
||||
var diarySelectedEntryId by remember { mutableStateOf<Int?>(null) }
|
||||
var membersNestedOpen by remember { mutableStateOf(false) }
|
||||
@@ -321,6 +344,15 @@ private fun MainTabs(dependencies: AppDependencies) {
|
||||
selectedTab = tab
|
||||
}
|
||||
|
||||
/** Wenn jemand die Mitglieder‑Galerie anfordert, wechsle zu Members und öffne die Nested‑Ansicht. */
|
||||
LaunchedEffect(openMemberGalleryRequested) {
|
||||
if (openMemberGalleryRequested) {
|
||||
selectMainTab(MainTab.Members)
|
||||
membersNestedOpen = true
|
||||
onConsumeOpenMemberGallery()
|
||||
}
|
||||
}
|
||||
|
||||
if (useWideMainNav) {
|
||||
Row(modifier = Modifier.fillMaxSize()) {
|
||||
MainNavigationRail(
|
||||
@@ -358,13 +390,19 @@ private fun MainTabs(dependencies: AppDependencies) {
|
||||
modifier = Modifier.fillMaxHeight().width(1.dp),
|
||||
)
|
||||
Box(modifier = Modifier.weight(1f).fillMaxHeight()) {
|
||||
MainTabContent(
|
||||
MainTabContent(
|
||||
selectedTab = selectedTab,
|
||||
dependencies = dependencies,
|
||||
onNavigateTab = { selectMainTab(it) },
|
||||
diarySelectedEntryId = diarySelectedEntryId,
|
||||
onDiarySelectedEntryId = { diarySelectedEntryId = it },
|
||||
onMembersNestedOpenChange = { membersNestedOpen = it },
|
||||
onMembersNestedOpenChange = { membersNestedOpen = it },
|
||||
onOpenMemberPortraitCrop = onRequestOpenMemberPortraitCrop,
|
||||
onOpenMembersGallery = onRequestOpenMemberGallery,
|
||||
openMemberPortraitCropRequested = openMemberPortraitCropRequested,
|
||||
onConsumeOpenMemberPortraitCrop = onConsumeOpenMemberPortraitCrop,
|
||||
openMemberGalleryRequested = openMemberGalleryRequested,
|
||||
onConsumeOpenMemberGallery = onConsumeOpenMemberGallery,
|
||||
billingOrdersSection = billingOrdersSection,
|
||||
onBillingOrdersSectionChange = { billingOrdersSection = it },
|
||||
settingsClubAdminRequest = settingsClubAdminRequest,
|
||||
@@ -384,6 +422,12 @@ private fun MainTabs(dependencies: AppDependencies) {
|
||||
diarySelectedEntryId = diarySelectedEntryId,
|
||||
onDiarySelectedEntryId = { diarySelectedEntryId = it },
|
||||
onMembersNestedOpenChange = { membersNestedOpen = it },
|
||||
onOpenMemberPortraitCrop = onRequestOpenMemberPortraitCrop,
|
||||
onOpenMembersGallery = onRequestOpenMemberGallery,
|
||||
openMemberPortraitCropRequested = openMemberPortraitCropRequested,
|
||||
onConsumeOpenMemberPortraitCrop = onConsumeOpenMemberPortraitCrop,
|
||||
openMemberGalleryRequested = openMemberGalleryRequested,
|
||||
onConsumeOpenMemberGallery = onConsumeOpenMemberGallery,
|
||||
billingOrdersSection = billingOrdersSection,
|
||||
onBillingOrdersSectionChange = { billingOrdersSection = it },
|
||||
settingsClubAdminRequest = settingsClubAdminRequest,
|
||||
@@ -421,6 +465,12 @@ private fun MainTabContent(
|
||||
diarySelectedEntryId: Int?,
|
||||
onDiarySelectedEntryId: (Int?) -> Unit,
|
||||
onMembersNestedOpenChange: (Boolean) -> Unit,
|
||||
onOpenMemberPortraitCrop: () -> Unit,
|
||||
onOpenMembersGallery: () -> Unit,
|
||||
openMemberPortraitCropRequested: Boolean,
|
||||
onConsumeOpenMemberPortraitCrop: () -> Unit,
|
||||
openMemberGalleryRequested: Boolean,
|
||||
onConsumeOpenMemberGallery: () -> Unit,
|
||||
billingOrdersSection: BillingOrdersSection?,
|
||||
onBillingOrdersSectionChange: (BillingOrdersSection?) -> Unit,
|
||||
settingsClubAdminRequest: ClubAdminSettingsSection?,
|
||||
@@ -434,10 +484,16 @@ private fun MainTabContent(
|
||||
dependencies = dependencies,
|
||||
selectedEntryId = diarySelectedEntryId,
|
||||
onSelectedEntryId = onDiarySelectedEntryId,
|
||||
onOpenMemberPortraitCrop = onOpenMemberPortraitCrop,
|
||||
onOpenMembersGallery = onOpenMembersGallery,
|
||||
)
|
||||
MainTab.Members -> MembersScreen(
|
||||
dependencies = dependencies,
|
||||
onNestedOpenChange = onMembersNestedOpenChange,
|
||||
openMemberPortraitCropRequested = openMemberPortraitCropRequested,
|
||||
onConsumeOpenMemberPortraitCrop = onConsumeOpenMemberPortraitCrop,
|
||||
openMemberGalleryRequested = openMemberGalleryRequested,
|
||||
onConsumeOpenMemberGallery = onConsumeOpenMemberGallery,
|
||||
)
|
||||
MainTab.Schedule -> ScheduleScreen(dependencies)
|
||||
MainTab.Calendar -> CalendarScreen(
|
||||
@@ -1415,6 +1471,8 @@ private fun DiaryListScreen(
|
||||
dependencies: AppDependencies,
|
||||
selectedEntryId: Int?,
|
||||
onSelectedEntryId: (Int?) -> Unit,
|
||||
onOpenMemberPortraitCrop: () -> Unit,
|
||||
onOpenMembersGallery: () -> Unit,
|
||||
) {
|
||||
val clubState by dependencies.clubManager.state.collectAsState()
|
||||
val diaryState by dependencies.diaryManager.state.collectAsState()
|
||||
@@ -1484,6 +1542,8 @@ private fun DiaryListScreen(
|
||||
entry = selectedEntry,
|
||||
dependencies = dependencies,
|
||||
onBack = { onSelectedEntryId(null) },
|
||||
onOpenMemberPortraitCrop = onOpenMemberPortraitCrop,
|
||||
onOpenMembersGallery = onOpenMembersGallery,
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -1783,6 +1843,8 @@ private fun DiaryDetailScreen(
|
||||
entry: DiaryDate,
|
||||
dependencies: AppDependencies,
|
||||
onBack: () -> Unit,
|
||||
onOpenMemberPortraitCrop: () -> Unit,
|
||||
onOpenMembersGallery: () -> Unit,
|
||||
) {
|
||||
BackHandler(onBack = onBack)
|
||||
|
||||
@@ -2106,7 +2168,7 @@ private fun DiaryDetailScreen(
|
||||
|
||||
val activeMembers = remember(membersState.members) {
|
||||
membersState.members.filter { it.active }.sortedWith(
|
||||
compareBy({ it.lastName.lowercase() }, { it.firstName.lowercase() }),
|
||||
compareBy({ it.firstName.lowercase() }, { it.lastName.lowercase() }),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2232,6 +2294,101 @@ private fun DiaryDetailScreen(
|
||||
) {
|
||||
Text(tr("common.delete", "Löschen"))
|
||||
}
|
||||
if (canReadMembers) {
|
||||
var showMembersGalleryDialog by remember { mutableStateOf(false) }
|
||||
OutlinedButton(
|
||||
onClick = { showMembersGalleryDialog = true },
|
||||
modifier = Modifier.heightIn(min = TouchMinHeight),
|
||||
) { Text(tr("members.gallery", "Mitglieder‑Galerie")) }
|
||||
|
||||
if (showMembersGalleryDialog) {
|
||||
val dialogMembers = activeMembers.filter { m ->
|
||||
(m.hasImage == true) || (m.imageUrl != null) || (m.primaryImageId != null) || (m.images.isNotEmpty())
|
||||
}
|
||||
AlertDialog(
|
||||
onDismissRequest = { showMembersGalleryDialog = false },
|
||||
title = { Text(tr("members.gallery", "Mitglieder‑Galerie")) },
|
||||
text = {
|
||||
Column(modifier = Modifier.fillMaxWidth().heightIn(max = 420.dp)) {
|
||||
val gridState = rememberLazyGridState()
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(minSize = 120.dp),
|
||||
state = gridState,
|
||||
modifier = Modifier.fillMaxWidth().padding(4.dp),
|
||||
) {
|
||||
items(dialogMembers) { m ->
|
||||
val pRow = participants.find { it.memberId == m.id }
|
||||
val checked = pRow?.isPresentParticipant() == true
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.aspectRatio(1f)
|
||||
.clickable {
|
||||
if (!canWriteDiary) return@clickable
|
||||
dependencies.applicationScope.launch {
|
||||
try {
|
||||
if (!checked) dependencies.diaryManager.addTrainingParticipant(entry.id, m.id)
|
||||
else dependencies.diaryManager.removeTrainingParticipant(entry.id, m.id)
|
||||
participants = dependencies.diaryManager.listTrainingParticipants(entry.id)
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
AuthenticatedAsyncImage(
|
||||
imageUrl = dependencies.apiConfig.toAbsoluteUrl(memberProfileImagePath(clubId, m.id)),
|
||||
authHeaders = dependencies.diaryAuthHeaders(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = m.fullName(),
|
||||
contentScale = androidx.compose.ui.layout.ContentScale.Crop,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.fillMaxWidth()
|
||||
.background(Color.Black.copy(alpha = 0.45f))
|
||||
.padding(6.dp)
|
||||
) {
|
||||
Text(
|
||||
text = m.fullName(),
|
||||
color = Color.White,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
fontSize = 12.sp,
|
||||
)
|
||||
}
|
||||
Checkbox(
|
||||
checked = checked,
|
||||
onCheckedChange = {
|
||||
dependencies.applicationScope.launch {
|
||||
try {
|
||||
if (it) dependencies.diaryManager.addTrainingParticipant(entry.id, m.id)
|
||||
else dependencies.diaryManager.removeTrainingParticipant(entry.id, m.id)
|
||||
participants = dependencies.diaryManager.listTrainingParticipants(entry.id)
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
},
|
||||
enabled = canWriteDiary,
|
||||
modifier = Modifier.align(Alignment.TopEnd).padding(6.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = { showMembersGalleryDialog = false }) { Text(tr("mobile.close", "Schließen")) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
if (canWriteMembers) {
|
||||
OutlinedButton(
|
||||
onClick = { onOpenMemberPortraitCrop() },
|
||||
modifier = Modifier.heightIn(min = TouchMinHeight),
|
||||
) { Text(tr("members.groupPortraitCropTitle", "Portrait aus Gruppenfoto")) }
|
||||
}
|
||||
}
|
||||
if (showEdit) {
|
||||
DiaryEditForm(
|
||||
@@ -4130,6 +4287,10 @@ private fun displayActivityDate(raw: String?): String {
|
||||
private fun MembersScreen(
|
||||
dependencies: AppDependencies,
|
||||
onNestedOpenChange: (Boolean) -> Unit,
|
||||
openMemberPortraitCropRequested: Boolean,
|
||||
onConsumeOpenMemberPortraitCrop: () -> Unit,
|
||||
openMemberGalleryRequested: Boolean,
|
||||
onConsumeOpenMemberGallery: () -> Unit,
|
||||
) {
|
||||
val clubState by dependencies.clubManager.state.collectAsState()
|
||||
val membersState by dependencies.membersManager.state.collectAsState()
|
||||
@@ -4137,6 +4298,18 @@ private fun MembersScreen(
|
||||
val canReadMembers = clubState.currentPermissions?.canReadMembers() == true
|
||||
val canWriteMembers = clubState.currentPermissions?.canWriteMembers() == true
|
||||
var stack by remember { mutableStateOf<MembersStackRoute>(MembersStackRoute.Browse) }
|
||||
LaunchedEffect(openMemberPortraitCropRequested) {
|
||||
if (openMemberPortraitCropRequested) {
|
||||
stack = MembersStackRoute.GroupPhotoPortraitCrop(returnToGroupPhotoManage = false)
|
||||
onConsumeOpenMemberPortraitCrop()
|
||||
}
|
||||
}
|
||||
LaunchedEffect(openMemberGalleryRequested) {
|
||||
if (openMemberGalleryRequested) {
|
||||
stack = MembersStackRoute.GroupPhoto
|
||||
onConsumeOpenMemberGallery()
|
||||
}
|
||||
}
|
||||
var query by rememberSaveable { mutableStateOf("") }
|
||||
|
||||
LaunchedEffect(stack, clubId) {
|
||||
|
||||
@@ -15,6 +15,7 @@ fun AuthenticatedAsyncImage(
|
||||
authHeaders: Map<String, String>,
|
||||
modifier: Modifier = Modifier,
|
||||
contentDescription: String? = null,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val request = remember(imageUrl, authHeaders) {
|
||||
@@ -30,6 +31,6 @@ fun AuthenticatedAsyncImage(
|
||||
model = request,
|
||||
contentDescription = contentDescription,
|
||||
modifier = modifier,
|
||||
contentScale = ContentScale.Fit,
|
||||
contentScale = contentScale,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.focus.FocusState
|
||||
|
||||
/**
|
||||
* Vollständiger Turnier-Workspace (analog Web [TournamentTab]): Stammdaten, Ablauf/Gruppen,
|
||||
@@ -284,6 +287,18 @@ private fun TournamentEditorMetaTab(
|
||||
var winningSets by remember(detail.id) { mutableStateOf((detail.winningSets ?: 3).toString()) }
|
||||
var tables by remember(detail.id) { mutableStateOf(detail.numberOfTables?.toString().orEmpty()) }
|
||||
var doubles by remember(detail.id) { mutableStateOf(detail.isDoublesTournament == true) }
|
||||
// Snapshot of last saved values to avoid repeated identical saves
|
||||
val lastSaved = remember(detail.id) {
|
||||
mutableStateOf(
|
||||
UpdateTournamentMetaBody(
|
||||
name = detail.name,
|
||||
date = detail.date,
|
||||
winningSets = detail.winningSets,
|
||||
numberOfTables = detail.numberOfTables,
|
||||
isDoublesTournament = detail.isDoublesTournament,
|
||||
),
|
||||
)
|
||||
}
|
||||
val scroll = rememberScrollState()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -293,45 +308,43 @@ private fun TournamentEditorMetaTab(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(tr("tournaments.tournamentName", "Turniername"), fontWeight = FontWeight.SemiBold)
|
||||
OutlinedTextField(value = name, onValueChange = { name = it }, modifier = Modifier.fillMaxWidth(), singleLine = true)
|
||||
OutlinedTextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
modifier = Modifier.fillMaxWidth().onFocusChanged { fs: FocusState -> if (!fs.isFocused) saveIfChanged(name, date, winningSets, tables, doubles, lastSaved, onSave) },
|
||||
singleLine = true,
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = date,
|
||||
onValueChange = { date = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth().onFocusChanged { fs: FocusState -> if (!fs.isFocused) saveIfChanged(name, date, winningSets, tables, doubles, lastSaved, onSave) },
|
||||
label = { Text(tr("tournaments.date", "Datum")) },
|
||||
singleLine = true,
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = winningSets,
|
||||
onValueChange = { winningSets = it.filter { ch -> ch.isDigit() }.take(2) },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth().onFocusChanged { fs: FocusState -> if (!fs.isFocused) saveIfChanged(name, date, winningSets, tables, doubles, lastSaved, onSave) },
|
||||
label = { Text(tr("tournaments.winningSets", "Gewinnsätze")) },
|
||||
singleLine = true,
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = tables,
|
||||
onValueChange = { tables = it.filter { ch -> ch.isDigit() } },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth().onFocusChanged { fs: FocusState -> if (!fs.isFocused) saveIfChanged(name, date, winningSets, tables, doubles, lastSaved, onSave) },
|
||||
label = { Text(tr("mobile.tables", "Tische")) },
|
||||
singleLine = true,
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(tr("mobile.doublesTournament", "Doppel-Turnier"))
|
||||
Switch(checked = doubles, onCheckedChange = { doubles = it })
|
||||
Switch(checked = doubles, onCheckedChange = {
|
||||
doubles = it
|
||||
saveIfChanged(name, date, winningSets, tables, doubles, lastSaved, onSave)
|
||||
})
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
val ws = winningSets.toIntOrNull()?.coerceAtLeast(1) ?: 3
|
||||
val nt = tables.toIntOrNull()
|
||||
onSave(
|
||||
UpdateTournamentMetaBody(
|
||||
name = name.ifBlank { null },
|
||||
date = date.ifBlank { null },
|
||||
winningSets = ws,
|
||||
numberOfTables = nt,
|
||||
isDoublesTournament = doubles,
|
||||
),
|
||||
)
|
||||
saveIfChanged(name, date, winningSets, tables, doubles, lastSaved, onSave, force = true)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
@@ -340,6 +353,35 @@ private fun TournamentEditorMetaTab(
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveIfChanged(
|
||||
name: String,
|
||||
date: String,
|
||||
winningSets: String,
|
||||
tables: String,
|
||||
doubles: Boolean,
|
||||
lastSaved: androidx.compose.runtime.MutableState<UpdateTournamentMetaBody>,
|
||||
onSave: (UpdateTournamentMetaBody) -> Unit,
|
||||
force: Boolean = false,
|
||||
) {
|
||||
val ws = winningSets.toIntOrNull()?.coerceAtLeast(1) ?: 3
|
||||
val nt = tables.toIntOrNull()
|
||||
val newBody = UpdateTournamentMetaBody(
|
||||
name = name.ifBlank { null },
|
||||
date = date.ifBlank { null },
|
||||
winningSets = ws,
|
||||
numberOfTables = nt,
|
||||
isDoublesTournament = doubles,
|
||||
)
|
||||
if (!force && newBody == lastSaved.value) return
|
||||
try {
|
||||
Log.d("InternalTournamentEditor", "saveIfChanged -> saving body: $newBody")
|
||||
} catch (e: Exception) {
|
||||
// ignore
|
||||
}
|
||||
onSave(newBody)
|
||||
lastSaved.value = newBody
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TournamentEditorFlowTab(
|
||||
clubId: Int,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[versions]
|
||||
# composeApp (Play Store / „Über die App“-Build)
|
||||
appVersionCode = "8"
|
||||
appVersionName = "1.3.2"
|
||||
appVersionCode = "9"
|
||||
appVersionName = "1.3.3"
|
||||
agp = "9.2.1"
|
||||
android-compileSdk = "35"
|
||||
android-minSdk = "24"
|
||||
|
||||
@@ -91,6 +91,12 @@ class TournamentsApi(
|
||||
}
|
||||
|
||||
suspend fun updateTournament(clubId: Int, tournamentId: Int, body: UpdateTournamentMetaBody): InternalTournamentDetailDto {
|
||||
// Debug: print body so it appears in device logs (useful during development)
|
||||
try {
|
||||
println("[TournamentsApi] updateTournament body: $body")
|
||||
} catch (t: Throwable) {
|
||||
// ignore on platforms where println may not be available
|
||||
}
|
||||
return client.http.put("/api/tournament/$clubId/$tournamentId") {
|
||||
setBody(body)
|
||||
}.body()
|
||||
|
||||
Reference in New Issue
Block a user