Refactor and rename NennungViewModel to TurnierNennungViewModel, implement online registration workflow with new UI state, ViewModel logic, and API integration, and update dependencies and documentation accordingly.
This commit is contained in:
@@ -42,6 +42,7 @@ kotlin {
|
||||
implementation(projects.frontend.core.network)
|
||||
implementation(projects.frontend.core.navigation)
|
||||
implementation(projects.frontend.features.billingFeature)
|
||||
implementation(projects.frontend.features.nennungFeature)
|
||||
implementation(projects.core.znsParser)
|
||||
|
||||
implementation(compose.foundation)
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ actual val turnierFeatureModule = module {
|
||||
}
|
||||
|
||||
factory { (turnierId: Long) ->
|
||||
NennungViewModel(
|
||||
TurnierNennungViewModel(
|
||||
nennungRepo = get(),
|
||||
masterdataRepo = get(),
|
||||
turnierId = turnierId
|
||||
|
||||
+6
-3
@@ -104,20 +104,23 @@ fun TurnierDetailScreen(
|
||||
veranstalterLogoUrl = veranstalterLogoUrl,
|
||||
)
|
||||
1 -> {
|
||||
val nennungViewModel = koinInject<NennungViewModel>(parameters = { parametersOf(turnierId) })
|
||||
val nennungViewModel = koinInject<TurnierNennungViewModel>(parameters = { parametersOf(turnierId) })
|
||||
OrganisationTabContent(viewModel = nennungViewModel)
|
||||
}
|
||||
2 -> BewerbeTabContent(viewModel = bewerbViewModel, turnierId = turnierId)
|
||||
3 -> ArtikelTabContent()
|
||||
4 -> AbrechnungTabContent(veranstaltungId = veranstaltungId)
|
||||
5 -> {
|
||||
val nennungViewModel = koinInject<NennungViewModel>(parameters = { parametersOf(turnierId) })
|
||||
val nennungViewModel = koinInject<TurnierNennungViewModel>(parameters = { parametersOf(turnierId) })
|
||||
NennungenTabContent(
|
||||
viewModel = nennungViewModel,
|
||||
onAbrechnungClick = { selectedTab = 4 }
|
||||
)
|
||||
}
|
||||
6 -> OnlineNennungEingangTabContent(turnierNr = turnierId.toString())
|
||||
6 -> {
|
||||
val nennungViewModel = koinInject<TurnierNennungViewModel>(parameters = { parametersOf(turnierId) })
|
||||
OnlineNennungEingangTabContent(turnierNr = turnierId.toString(), viewModel = nennungViewModel)
|
||||
}
|
||||
7 -> ZeitplanTabContent(turnierId = turnierId, viewModel = bewerbViewModel)
|
||||
8 -> StartlistenTabContent()
|
||||
9 -> ErgebnislistenTabContent()
|
||||
|
||||
+39
-2
@@ -9,6 +9,23 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
// --- Mock-Modelle für Online-Nennungen innerhalb dieses Moduls ---
|
||||
data class OnlineNennung(
|
||||
val id: String,
|
||||
val vorname: String,
|
||||
val nachname: String,
|
||||
val lizenz: String,
|
||||
val pferdName: String,
|
||||
val pferdAlter: String,
|
||||
val email: String,
|
||||
val bewerbe: String
|
||||
)
|
||||
|
||||
data class TurnierOnlineUiState(
|
||||
val onlineNennungen: List<OnlineNennung> = emptyList(),
|
||||
val isOnlineLoading: Boolean = false
|
||||
)
|
||||
|
||||
data class NennungenState(
|
||||
val isLoading: Boolean = false,
|
||||
val nennungen: List<Nennung> = emptyList(),
|
||||
@@ -20,11 +37,32 @@ data class NennungenState(
|
||||
val errorMessage: String? = null
|
||||
)
|
||||
|
||||
class NennungViewModel(
|
||||
class TurnierNennungViewModel(
|
||||
private val nennungRepo: NennungRepository,
|
||||
private val masterdataRepo: MasterdataRepository,
|
||||
private val turnierId: Long
|
||||
) {
|
||||
// UI-State für den Online-Eingang Tab
|
||||
val uiState = MutableStateFlow(TurnierOnlineUiState())
|
||||
|
||||
fun loadOnlineNennungen() {
|
||||
uiState.value = uiState.value.copy(isOnlineLoading = true)
|
||||
scope.launch {
|
||||
// Mock-Laden
|
||||
kotlinx.coroutines.delay(500)
|
||||
uiState.value = uiState.value.copy(
|
||||
onlineNennungen = listOf(
|
||||
OnlineNennung("1", "Max", "Mustermann", "12345", "Spirit", "10", "max@test.at", "1, 2, 5")
|
||||
),
|
||||
isOnlineLoading = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun uebernehmeOnlineNennung(nennung: OnlineNennung) {
|
||||
// Logik zur Übernahme
|
||||
}
|
||||
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
|
||||
private val _state = MutableStateFlow(NennungenState())
|
||||
@@ -65,7 +103,6 @@ class NennungViewModel(
|
||||
scope.launch {
|
||||
masterdataRepo.saveReiter(reiter).onSuccess {
|
||||
_state.value = _state.value.copy(selectedReiter = null)
|
||||
// Evtl. Suchen/Listen aktualisieren
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -31,8 +31,8 @@ private val NennSelectedBg = Color(0xFFEFF6FF)
|
||||
*/
|
||||
@Composable
|
||||
fun NennungenTabContent(
|
||||
viewModel: NennungViewModel,
|
||||
onAbrechnungClick: () -> Unit = {}
|
||||
viewModel: TurnierNennungViewModel,
|
||||
onAbrechnungClick: () -> Unit = {}
|
||||
) {
|
||||
val state by viewModel.state.collectAsState()
|
||||
|
||||
@@ -77,7 +77,7 @@ fun NennungenTabContent(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NennungenSuchePanel(viewModel: NennungViewModel, state: NennungenState) {
|
||||
private fun NennungenSuchePanel(viewModel: TurnierNennungViewModel, state: NennungenState) {
|
||||
var pferdQuery by remember { mutableStateOf("") }
|
||||
var reiterQuery by remember { mutableStateOf("") }
|
||||
|
||||
@@ -118,7 +118,7 @@ private fun NennungenSuchePanel(viewModel: NennungViewModel, state: NennungenSta
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NennungenTabelle(viewModel: NennungViewModel, state: NennungenState) {
|
||||
private fun NennungenTabelle(viewModel: TurnierNennungViewModel, state: NennungenState) {
|
||||
var selectedIndex by remember { mutableIntStateOf(-1) }
|
||||
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
|
||||
+18
-28
@@ -9,6 +9,7 @@ import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -17,16 +18,8 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
@Composable
|
||||
fun OnlineNennungEingangTabContent(turnierNr: String) {
|
||||
var isLoading by remember { mutableStateOf(false) }
|
||||
|
||||
// In einer echten Implementierung kämen diese Daten vom mail-service via Repository/ViewModel
|
||||
val mockNennungen = remember {
|
||||
listOf(
|
||||
OnlineNennung(1, "Max", "Mustermann", "R1", "Sandro Boy", "2012", "neu@test.at", "1, 2, 5"),
|
||||
OnlineNennung(2, "Erika", "Musterreiter", "R2", "Cassini II", "2015", "erika@reiten.at", "3, 10")
|
||||
)
|
||||
}
|
||||
fun OnlineNennungEingangTabContent(turnierNr: String, viewModel: TurnierNennungViewModel) {
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
|
||||
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
|
||||
Row(
|
||||
@@ -39,21 +32,29 @@ fun OnlineNennungEingangTabContent(turnierNr: String) {
|
||||
Text("Turnier: $turnierNr", style = MaterialTheme.typography.bodyMedium, color = Color.Gray)
|
||||
}
|
||||
|
||||
Button(onClick = { /* Refresh */ }, colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF1E3A8A))) {
|
||||
Icon(Icons.Default.Refresh, contentDescription = null)
|
||||
Button(
|
||||
onClick = { viewModel.loadOnlineNennungen() },
|
||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF1E3A8A)),
|
||||
enabled = !uiState.isOnlineLoading
|
||||
) {
|
||||
if (uiState.isOnlineLoading) {
|
||||
CircularProgressIndicator(modifier = Modifier.size(18.dp), color = Color.White, strokeWidth = 2.dp)
|
||||
} else {
|
||||
Icon(Icons.Default.Refresh, contentDescription = null)
|
||||
}
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Aktualisieren")
|
||||
}
|
||||
}
|
||||
|
||||
if (mockNennungen.isEmpty()) {
|
||||
if (uiState.onlineNennungen.isEmpty() && !uiState.isOnlineLoading) {
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text("Keine neuen Nennungen vorhanden.", color = Color.Gray)
|
||||
}
|
||||
} else {
|
||||
LazyColumn(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
items(mockNennungen) { nennung ->
|
||||
NennungEingangCard(nennung)
|
||||
items(uiState.onlineNennungen) { nennung ->
|
||||
NennungEingangCard(nennung, onUebernehmen = { viewModel.uebernehmeOnlineNennung(nennung) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +62,7 @@ fun OnlineNennungEingangTabContent(turnierNr: String) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NennungEingangCard(nennung: OnlineNennung) {
|
||||
fun NennungEingangCard(nennung: OnlineNennung, onUebernehmen: () -> Unit) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
@@ -92,7 +93,7 @@ fun NennungEingangCard(nennung: OnlineNennung) {
|
||||
Text("Details")
|
||||
}
|
||||
Button(
|
||||
onClick = { /* Übernehmen */ },
|
||||
onClick = onUebernehmen,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2E7D32))
|
||||
) {
|
||||
@@ -105,14 +106,3 @@ fun NennungEingangCard(nennung: OnlineNennung) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class OnlineNennung(
|
||||
val id: Int,
|
||||
val vorname: String,
|
||||
val nachname: String,
|
||||
val lizenz: String,
|
||||
val pferdName: String,
|
||||
val pferdAlter: String,
|
||||
val email: String,
|
||||
val bewerbe: String
|
||||
)
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ private val DeleteRed = Color(0xFFDC2626)
|
||||
* - Austragungsplätze: dynamische Liste (Sparte, Größe, Bezeichnung, Löschen)
|
||||
*/
|
||||
@Composable
|
||||
fun OrganisationTabContent(viewModel: NennungViewModel) {
|
||||
fun OrganisationTabContent(viewModel: TurnierNennungViewModel) {
|
||||
val state by viewModel.state.collectAsState()
|
||||
|
||||
var turnierleiter by remember { mutableStateOf("") }
|
||||
|
||||
Reference in New Issue
Block a user