chore: implementiere Logo-Upload-Zone mit Base64-Unterstützung, verbessere Vereinsverwaltung mit kompakten Feldern und nutzerspezifischen Uploadoptionen, optimiere Desktop-UX und Navigation

This commit is contained in:
2026-04-20 01:20:16 +02:00
parent dfaa2e8545
commit 85ac1cae9c
12 changed files with 485 additions and 70 deletions
@@ -2,15 +2,21 @@ package at.mocode.frontend.features.veranstalter.presentation
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import at.mocode.frontend.core.designsystem.components.MsDatePickerField
import at.mocode.frontend.core.designsystem.components.MsTextField
/**
* Formular zum Anlegen einer neuen Veranstaltung (Titel + Datumspfad). Pflichtfelder: Titel, Datum von/bis.
@@ -26,8 +32,9 @@ fun VeranstaltungKonfigScreen(
var datumVon by remember { mutableStateOf("") }
var datumBis by remember { mutableStateOf("") }
val focusManager = LocalFocusManager.current
val datesPresent = datumVon.isNotBlank() && datumBis.isNotBlank()
// Einfache Validierung: YYYY-MM-DD Format erzwingen wir hier nicht strikt; wenn beide gesetzt, prüfen wir lexikografisch
// Einfache Validierung: YYYY-MM-DD Format erzwingen wir hier nicht strikt; wenn beide gesetzt sind, prüfen wir lexikografisch
val dateOrderOk = !datesPresent || datumBis >= datumVon
val valid = titel.isNotBlank() && datesPresent && dateOrderOk
@@ -61,37 +68,36 @@ fun VeranstaltungKonfigScreen(
Column(modifier = Modifier.padding(24.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
Text("Stammdaten", fontWeight = FontWeight.SemiBold, fontSize = 14.sp)
OutlinedTextField(
MsTextField(
value = titel,
onValueChange = { titel = it },
label = { Text("Titel *") },
label = "Titel *",
placeholder = "z.B. Frühjahrsturnier 2026",
singleLine = true,
modifier = Modifier.fillMaxWidth(),
isError = titel.isBlank(),
imeAction = ImeAction.Next,
keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Down) })
)
Text("Zeitraum", fontWeight = FontWeight.SemiBold, fontSize = 14.sp)
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
OutlinedTextField(
MsDatePickerField(
label = "von *",
value = datumVon,
onValueChange = { datumVon = it },
label = { Text("von (YYYY-MM-DD) *") },
singleLine = true,
modifier = Modifier.weight(1f),
isError = datumVon.isBlank(),
)
OutlinedTextField(
MsDatePickerField(
label = "bis *",
value = datumBis,
onValueChange = { datumBis = it },
label = { Text("bis (YYYY-MM-DD) *") },
singleLine = true,
modifier = Modifier.weight(1f),
isError = datumBis.isBlank() || (datesPresent && !dateOrderOk),
errorMessage = if (datesPresent && !dateOrderOk) "Ungültiger Zeitraum" else null
)
}
if (datesPresent && !dateOrderOk) {
Text("Das bis-Datum darf nicht vor dem von-Datum liegen.", color = MaterialTheme.colorScheme.error, fontSize = 12.sp)
}
}
}