Implement MVVM for all V3 screens: add ViewModels for Turniere, Bewerbe, Abteilungen, Pferde, Reiter, Vereins, and Funktionaer workflows. Update roadmap to mark B-1 tasks as complete.
This commit is contained in:
+99
@@ -0,0 +1,99 @@
|
||||
package at.mocode.frontend.features.reiter.presentation
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
data class ReiterProfilState(
|
||||
val isLoading: Boolean = false,
|
||||
val errorMessage: String? = null,
|
||||
val vorname: String = "",
|
||||
val nachname: String = "",
|
||||
val oepsNummer: String = "",
|
||||
val feiId: String = "",
|
||||
val lizenzKlasse: String = "",
|
||||
val verein: String = "",
|
||||
val validHints: List<String> = emptyList(),
|
||||
val dirty: Boolean = false,
|
||||
)
|
||||
|
||||
sealed interface ReiterProfilIntent {
|
||||
data class Load(val id: String) : ReiterProfilIntent
|
||||
data object Refresh : ReiterProfilIntent
|
||||
data class EditVorname(val v: String) : ReiterProfilIntent
|
||||
data class EditNachname(val v: String) : ReiterProfilIntent
|
||||
data class EditOeps(val v: String) : ReiterProfilIntent
|
||||
data class EditFeiId(val v: String) : ReiterProfilIntent
|
||||
data class EditLizenz(val v: String) : ReiterProfilIntent
|
||||
data class EditVerein(val v: String) : ReiterProfilIntent
|
||||
data object Save : ReiterProfilIntent
|
||||
data object ClearError : ReiterProfilIntent
|
||||
}
|
||||
|
||||
interface ReiterProfilRepository {
|
||||
suspend fun load(id: String): ReiterProfilState
|
||||
suspend fun save(id: String, state: ReiterProfilState)
|
||||
}
|
||||
|
||||
class ReiterProfilViewModel(
|
||||
private val repo: ReiterProfilRepository,
|
||||
private var id: String,
|
||||
) {
|
||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
|
||||
private val _state = MutableStateFlow(ReiterProfilState(isLoading = true))
|
||||
val state: StateFlow<ReiterProfilState> = _state
|
||||
|
||||
init { send(ReiterProfilIntent.Load(id)) }
|
||||
|
||||
fun send(intent: ReiterProfilIntent) {
|
||||
when (intent) {
|
||||
is ReiterProfilIntent.Load -> { id = intent.id; load() }
|
||||
is ReiterProfilIntent.Refresh -> load()
|
||||
is ReiterProfilIntent.EditVorname -> edit { it.copy(vorname = intent.v) }
|
||||
is ReiterProfilIntent.EditNachname -> edit { it.copy(nachname = intent.v) }
|
||||
is ReiterProfilIntent.EditOeps -> edit { it.copy(oepsNummer = intent.v) }
|
||||
is ReiterProfilIntent.EditFeiId -> edit { it.copy(feiId = intent.v) }
|
||||
is ReiterProfilIntent.EditLizenz -> edit { it.copy(lizenzKlasse = intent.v) }
|
||||
is ReiterProfilIntent.EditVerein -> edit { it.copy(verein = intent.v) }
|
||||
is ReiterProfilIntent.Save -> save()
|
||||
is ReiterProfilIntent.ClearError -> reduce { it.copy(errorMessage = null) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun load() {
|
||||
reduce { it.copy(isLoading = true, errorMessage = null) }
|
||||
scope.launch {
|
||||
try {
|
||||
val loaded = repo.load(id)
|
||||
reduce { loaded.copy(isLoading = false, dirty = false) }
|
||||
} catch (t: Throwable) {
|
||||
reduce { it.copy(isLoading = false, errorMessage = t.message ?: "Fehler beim Laden") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun save() {
|
||||
val cur = _state.value
|
||||
reduce { it.copy(isLoading = true, errorMessage = null) }
|
||||
scope.launch {
|
||||
try {
|
||||
repo.save(id, cur)
|
||||
reduce { it.copy(isLoading = false, dirty = false) }
|
||||
} catch (t: Throwable) {
|
||||
reduce { it.copy(isLoading = false, errorMessage = t.message ?: "Fehler beim Speichern") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun edit(block: (ReiterProfilState) -> ReiterProfilState) {
|
||||
reduce { block(it).copy(dirty = true) }
|
||||
}
|
||||
|
||||
private inline fun reduce(block: (ReiterProfilState) -> ReiterProfilState) {
|
||||
_state.value = block(_state.value)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user