feat: ZNS-Cloud-Sync und manuellen Veranstalter-Button im Wizard hinzugefügt
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 59s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m6s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m10s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 1m13s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m51s

Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
2026-04-17 00:31:35 +02:00
parent a1194adeac
commit 4b6a242372
7 changed files with 346 additions and 4 deletions
@@ -443,7 +443,56 @@ fun VeranstaltungKonfigV2(
HorizontalDivider(Modifier.padding(vertical = 8.dp))
// 2. Bestehende Veranstalter (Kompakt)
// 2. Cloud Sync (Neu gemäß User-Wunsch)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth().padding(horizontal = 4.dp)
) {
Button(
onClick = {
znsImporter.syncFromCloud { remoteList ->
remoteList.forEach { remote ->
StoreV2.vereine.find { it.oepsNummer == remote.oepsNummer }
?: StoreV2.addVerein(remote.name, remote.oepsNummer, remote.ort ?: "")
}
}
},
enabled = !znsState.isSyncing,
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.secondary)
) {
if (znsState.isSyncing) {
CircularProgressIndicator(
modifier = Modifier.size(18.dp),
color = MaterialTheme.colorScheme.onSecondary
)
Spacer(Modifier.width(8.dp))
Text("Synchronisiere...")
} else {
Icon(Icons.Default.CloudSync, contentDescription = null)
Spacer(Modifier.width(8.dp))
Text("ZNS-Daten-Sync")
}
}
Column {
Text(
"ZNS-Daten geladen",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
"[Version ${znsState.lastSyncVersion ?: "Kein Sync"}]",
style = MaterialTheme.typography.bodySmall,
fontWeight = FontWeight.Bold,
color = if (znsState.lastSyncVersion != null) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.error
)
}
}
HorizontalDivider(Modifier.padding(vertical = 8.dp))
// 3. Bestehende Veranstalter (Kompakt)
Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.weight(1f)) {
var search by remember { mutableStateOf("") }
val filteredVereine = remember(search) {
@@ -465,7 +514,7 @@ fun VeranstaltungKonfigV2(
)
LazyColumn(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier.fillMaxWidth().weight(1f),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
items(filteredVereine) { verein ->
@@ -499,6 +548,18 @@ fun VeranstaltungKonfigV2(
}
}
}
// 3. Manueller Button für neuen Veranstalter
OutlinedButton(
onClick = { showVereinNeu = true },
modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
contentPadding = PaddingValues(12.dp),
border = androidx.compose.foundation.BorderStroke(1.dp, MaterialTheme.colorScheme.primary)
) {
Icon(Icons.Default.Add, contentDescription = null)
Spacer(Modifier.width(8.dp))
Text("+ Neuen Veranstalter anlegen", fontWeight = FontWeight.Bold)
}
}
if (showVereinNeu) {
@@ -511,7 +572,8 @@ fun VeranstaltungKonfigV2(
onCancel = { showVereinNeu = false },
onVereinCreated = { newId ->
showVereinNeu = false
onVeranstalterCreated(newId)
selectedVereinId = newId
currentStep = 2 // Direkt zum nächsten Schritt
}
)
}