chore: integriere Turnier-Wizard und ZNS-Importer in Veranstaltungsscreen, implementiere Profil-Onboarding und aktualisiere Modulabhängigkeiten
Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -34,6 +34,8 @@ kotlin {
|
||||
implementation(projects.frontend.core.auth)
|
||||
implementation(projects.frontend.features.vereinFeature)
|
||||
implementation(projects.frontend.features.deviceInitialization)
|
||||
implementation(projects.frontend.features.znsImportFeature)
|
||||
implementation(projects.frontend.features.turnierFeature)
|
||||
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.runtime)
|
||||
|
||||
+66
-70
@@ -17,6 +17,10 @@ import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.designsystem.components.MsFilePicker
|
||||
import at.mocode.frontend.core.designsystem.components.MsTextField
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
import at.mocode.frontend.features.turnier.presentation.TurnierWizard
|
||||
import at.mocode.frontend.features.turnier.presentation.TurnierWizardViewModel
|
||||
import at.mocode.frontend.features.zns.import.presentation.StammdatenImportScreen
|
||||
import org.koin.compose.koinInject
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalUuidApi::class)
|
||||
@@ -174,41 +178,39 @@ private fun ZnsCheckStep(viewModel: VeranstaltungWizardViewModel) {
|
||||
}
|
||||
|
||||
if (!state.isZnsAvailable && !state.isCheckingStats) {
|
||||
Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.errorContainer)) {
|
||||
Row(Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(Icons.Default.Warning, null, tint = MaterialTheme.colorScheme.error)
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Column {
|
||||
Text("🚨 Stammdaten fehlen!", fontWeight = FontWeight.Bold, style = MaterialTheme.typography.titleMedium)
|
||||
Text("Bitte importieren Sie die aktuelle ZNS.zip über den ZNS-Importer.")
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.errorContainer)) {
|
||||
Row(Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(Icons.Default.Warning, null, tint = MaterialTheme.colorScheme.error)
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Column {
|
||||
Text(
|
||||
"🚨 Stammdaten fehlen!",
|
||||
fontWeight = FontWeight.Bold,
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
Text("Bitte importieren Sie die aktuelle ZNS.zip, um fortzufahren.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Button(
|
||||
onClick = { viewModel.checkStammdatenStatus() },
|
||||
enabled = !state.isCheckingStats,
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
if (state.isCheckingStats) {
|
||||
CircularProgressIndicator(modifier = Modifier.size(18.dp), strokeWidth = 2.dp, color = MaterialTheme.colorScheme.onPrimary)
|
||||
} else {
|
||||
Icon(Icons.Default.Refresh, null)
|
||||
}
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Status prüfen")
|
||||
}
|
||||
|
||||
if (!state.isZnsAvailable) {
|
||||
OutlinedButton(
|
||||
onClick = { /* Navigiere zum ZNS Importer */ },
|
||||
modifier = Modifier.weight(1f)
|
||||
// Plug-and-Play Integration des Importers
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(max = 500.dp)
|
||||
.padding(vertical = 8.dp)
|
||||
) {
|
||||
Icon(Icons.Default.CloudDownload, null)
|
||||
StammdatenImportScreen(onBack = {})
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = { viewModel.checkStammdatenStatus() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Icon(Icons.Default.Refresh, null)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Zum ZNS-Importer")
|
||||
Text("Import-Status aktualisieren")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,52 +396,46 @@ private fun MetaDataStep(viewModel: VeranstaltungWizardViewModel) {
|
||||
@Composable
|
||||
private fun TurnierAnlageStep(viewModel: VeranstaltungWizardViewModel) {
|
||||
val state = viewModel.state
|
||||
var showWizard by remember { mutableStateOf(false) }
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Text("Schritt 5: Turniere & Ausschreibung", style = MaterialTheme.typography.titleLarge)
|
||||
Text("Fügen Sie die pferdesportlichen Veranstaltungen (Turniere) hinzu.")
|
||||
|
||||
state.turniere.forEachIndexed { index, turnier ->
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text("Turnier #${index + 1}", fontWeight = FontWeight.Bold)
|
||||
if (state.turniere.size > 1) {
|
||||
IconButton(onClick = { viewModel.removeTurnier(index) }) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Entfernen", tint = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
if (showWizard) {
|
||||
val turnierViewModel = koinInject<TurnierWizardViewModel>()
|
||||
Card(modifier = Modifier.fillMaxWidth().height(500.dp)) {
|
||||
TurnierWizard(
|
||||
viewModel = turnierViewModel,
|
||||
veranstaltungId = 0, // In Echt wird hier die ID aus dem State genutzt
|
||||
onBack = { showWizard = false },
|
||||
onFinish = {
|
||||
showWizard = false
|
||||
viewModel.addTurnier() // Dummy zum Hinzufügen im Haupt-Wizard
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Text("Fügen Sie die pferdesportlichen Veranstaltungen (Turniere) hinzu.")
|
||||
|
||||
state.turniere.forEachIndexed { index, turnier ->
|
||||
ListItem(
|
||||
headlineContent = { Text("Turnier #${index + 1}: ${turnier.nummer}") },
|
||||
trailingContent = {
|
||||
IconButton(onClick = { viewModel.removeTurnier(index) }) {
|
||||
Icon(Icons.Default.Delete, null, tint = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
}
|
||||
|
||||
MsTextField(
|
||||
value = turnier.nummer,
|
||||
onValueChange = { viewModel.updateTurnier(index, it, turnier.ausschreibungPath) },
|
||||
label = "Turnier-Nummer (ZNS)",
|
||||
placeholder = "z.B. 26123",
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
MsFilePicker(
|
||||
label = "Ausschreibung (PDF)",
|
||||
selectedPath = turnier.ausschreibungPath,
|
||||
onFileSelected = { viewModel.updateTurnier(index, turnier.nummer, it) },
|
||||
fileExtensions = listOf("pdf"),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
OutlinedButton(
|
||||
onClick = { viewModel.addTurnier() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Icon(Icons.Default.Add, contentDescription = null)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Weiteres Turnier hinzufügen")
|
||||
OutlinedButton(
|
||||
onClick = { showWizard = true },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Icon(Icons.Default.Add, null)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Neues Turnier mit Wizard anlegen")
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(16.dp))
|
||||
@@ -447,7 +443,7 @@ private fun TurnierAnlageStep(viewModel: VeranstaltungWizardViewModel) {
|
||||
Button(
|
||||
onClick = { viewModel.nextStep() },
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
enabled = state.turniere.all { it.nummer.isNotBlank() && it.ausschreibungPath != null }
|
||||
enabled = !showWizard && state.turniere.isNotEmpty()
|
||||
) {
|
||||
Text("Weiter zur Zusammenfassung")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user