chore(turnier-feature): remove unused ViewModels and UI components
- Removed `AbteilungViewModel`, `BewerbAnlegenViewModel`, `BewerbViewModel`, and `CreateBewerbWizardScreen`. - Cleaned up related imports and unused domain models.
This commit is contained in:
@@ -21,7 +21,7 @@ plugins {
|
||||
alias(libs.plugins.composeCompiler)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
id("org.jetbrains.compose.hot-reload")
|
||||
// id("org.jetbrains.compose.hot-reload")
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
@@ -30,9 +30,9 @@ plugins {
|
||||
val versionProps = Properties().also { props ->
|
||||
rootProject.file("version.properties").inputStream().use { props.load(it) }
|
||||
}
|
||||
val vMajor = versionProps.getProperty("VERSION_MAJOR", "1")
|
||||
val vMinor = versionProps.getProperty("VERSION_MINOR", "0")
|
||||
val vPatch = versionProps.getProperty("VERSION_PATCH", "0")
|
||||
val vMajor: String? = versionProps.getProperty("VERSION_MAJOR", "1")
|
||||
val vMinor: String? = versionProps.getProperty("VERSION_MINOR", "0")
|
||||
val vPatch: String? = versionProps.getProperty("VERSION_PATCH", "0")
|
||||
// nativeDistributions erwartet reines "MAJOR.MINOR.PATCH" (kein Qualifier)
|
||||
val packageVer = "$vMajor.$vMinor.$vPatch"
|
||||
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ import at.mocode.zns.parser.ZnsBewerb
|
||||
import at.mocode.frontend.features.veranstalter.presentation.VeranstalterAuswahlScreen
|
||||
import at.mocode.frontend.features.veranstalter.presentation.VeranstalterDetailScreen
|
||||
import at.mocode.frontend.features.veranstalter.presentation.VeranstalterNeuScreen
|
||||
import at.mocode.turnier.feature.domain.model.StartlistenZeile
|
||||
import at.mocode.veranstaltung.feature.presentation.VeranstaltungUebersichtScreen
|
||||
import at.mocode.wui.preview.ComponentPreview
|
||||
|
||||
|
||||
+14
-11
@@ -274,32 +274,35 @@ object StoreV2 {
|
||||
// Falls bereits Daten da sind (außer den statischen Vereinen), nichts tun
|
||||
if (veranstaltungen.isNotEmpty()) return
|
||||
|
||||
// 1. Neumarkt 2026 (ID 100)
|
||||
// 1. Neumarkt April 2026 (ID 100)
|
||||
val neumarktId = 100L
|
||||
addEventFirst(
|
||||
1, VeranstaltungV2(
|
||||
id = neumarktId,
|
||||
veranstalterId = 1,
|
||||
titel = "Frühjahrsturnier Neumarkt/M. 2026",
|
||||
datumVon = "2026-04-10",
|
||||
datumBis = "2026-04-12",
|
||||
titel = "CSN-B* Neumarkt am Wallersee",
|
||||
datumVon = "2026-04-24",
|
||||
datumBis = "2026-04-26",
|
||||
status = "Nennungsphase",
|
||||
beschreibung = "Traditionelles Frühjahrsturnier mit Spring- und Dressurprüfungen bis Klasse LM."
|
||||
ort = "Neumarkt am Wallersee",
|
||||
beschreibung = "Großes Springturnier mit Teilnehmern aus ganz Österreich. Vorbereitungen für das Live-Event am 24. April laufen."
|
||||
)
|
||||
)
|
||||
|
||||
TurnierStoreV2.add(
|
||||
neumarktId,
|
||||
TurnierV2(101, neumarktId, 26128, datumVon = "2026-04-10", datumBis = "2026-04-12", znsDataLoaded = true).apply {
|
||||
kategorie.add("CSN-C-NEU")
|
||||
kategorie.add("CSNP-C-NEU")
|
||||
TurnierV2(101, neumarktId, 26128, datumVon = "2026-04-24", datumBis = "2026-04-26", znsDataLoaded = true).apply {
|
||||
titel = "Springturnier Neumarkt"
|
||||
kategorie.add("CSN-B*")
|
||||
kategorie.add("CSNP-B")
|
||||
}
|
||||
)
|
||||
TurnierStoreV2.add(
|
||||
neumarktId,
|
||||
TurnierV2(102, neumarktId, 26129, datumVon = "2026-04-10", datumBis = "2026-04-12", znsDataLoaded = true).apply {
|
||||
kategorie.add("CDN-C-NEU")
|
||||
kategorie.add("CDNP-C-NEU")
|
||||
TurnierV2(102, neumarktId, 26129, datumVon = "2026-04-24", datumBis = "2026-04-26", znsDataLoaded = true).apply {
|
||||
titel = "Dressurturnier Neumarkt"
|
||||
kategorie.add("CDN-B")
|
||||
kategorie.add("CDNP-B")
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+4
@@ -780,6 +780,10 @@ object TurnierStoreV2 {
|
||||
fun list(veranstaltungId: Long): MutableList<TurnierV2> = map.getOrPut(veranstaltungId) { mutableListOf() }
|
||||
fun add(veranstaltungId: Long, t: TurnierV2) { list(veranstaltungId).add(0, t) }
|
||||
fun remove(veranstaltungId: Long, tId: Long) { list(veranstaltungId).removeAll { it.id == tId } }
|
||||
|
||||
// Hilfsmethode für Reflection-Zugriff aus anderen Modulen (StammdatenTab)
|
||||
@JvmStatic
|
||||
fun allTurniere(): List<TurnierV2> = map.values.flatten()
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.kotlinSerialization)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@OptIn(ExperimentalWasmDsl::class)
|
||||
wasmJs {
|
||||
browser {
|
||||
commonWebpackConfig {
|
||||
outputFileName = "meldestelle-web.js"
|
||||
}
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
val wasmJsMain by getting {
|
||||
dependencies {
|
||||
// Core-Module
|
||||
implementation(projects.frontend.core.domain)
|
||||
implementation(projects.frontend.core.designSystem)
|
||||
implementation(projects.frontend.core.navigation)
|
||||
implementation(projects.frontend.core.network)
|
||||
implementation(projects.frontend.core.auth)
|
||||
|
||||
// Feature-Module (die öffentlich sein dürfen)
|
||||
implementation(projects.frontend.features.veranstaltungFeature)
|
||||
implementation(projects.frontend.features.turnierFeature)
|
||||
implementation(projects.frontend.features.nennungFeature)
|
||||
|
||||
// Compose Multiplatform
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material3)
|
||||
implementation(compose.ui)
|
||||
implementation(compose.components.resources)
|
||||
implementation(libs.compose.materialIconsExtended)
|
||||
|
||||
// DI (Koin)
|
||||
implementation(libs.koin.core)
|
||||
implementation(libs.koin.compose)
|
||||
implementation(libs.koin.compose.viewmodel)
|
||||
|
||||
// Bundles
|
||||
implementation(libs.bundles.kmp.common)
|
||||
implementation(libs.bundles.compose.common)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
package at.mocode.web
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Description
|
||||
import androidx.compose.material.icons.filled.OpenInNew
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.designsystem.theme.AppColors
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun WebMainScreen() {
|
||||
var currentScreen by remember { mutableStateOf<WebScreen>(WebScreen.Landing) }
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Meldestelle Online", fontWeight = FontWeight.Bold) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = AppColors.Primary,
|
||||
titleContentColor = Color.White
|
||||
)
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
Box(modifier = Modifier.fillMaxSize().padding(padding)) {
|
||||
when (val screen = currentScreen) {
|
||||
is WebScreen.Landing -> LandingPage(
|
||||
onVeranstaltungClick = { vId ->
|
||||
// Für den Prototyp zeigen wir einfach die Turniere dieser Veranstaltung
|
||||
},
|
||||
onNennenClick = { vId, tId ->
|
||||
currentScreen = WebScreen.Nennung(vId, tId)
|
||||
}
|
||||
)
|
||||
is WebScreen.Nennung -> NennungWebFormular(
|
||||
veranstaltungId = screen.veranstaltungId,
|
||||
turnierId = screen.turnierId,
|
||||
onBack = { currentScreen = WebScreen.Landing }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WebScreen {
|
||||
data object Landing : WebScreen()
|
||||
data class Nennung(val veranstaltungId: Long, val turnierId: Long) : WebScreen()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LandingPage(
|
||||
onVeranstaltungClick: (Long) -> Unit,
|
||||
onNennenClick: (Long, Long) -> Unit
|
||||
) {
|
||||
val veranstaltungen = remember {
|
||||
listOf(
|
||||
VeranstaltungWebModel(
|
||||
id = 1,
|
||||
name = "CSN-B* Neumarkt",
|
||||
ort = "Neumarkt am Wallersee",
|
||||
datum = "24. - 26. April 2026",
|
||||
turniere = listOf(
|
||||
TurnierWebModel(101, "Springturnier Neumarkt", "Ausschreibung_Neumarkt.pdf"),
|
||||
TurnierWebModel(102, "Dressurturnier Neumarkt", "Ausschreibung_Dressur.pdf")
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize().padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(24.dp)
|
||||
) {
|
||||
item {
|
||||
Text(
|
||||
"Willkommen bei der Meldestelle Online",
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
color = AppColors.OnBackgroundLight
|
||||
)
|
||||
Text(
|
||||
"Hier finden Sie aktuelle Reitturniere und können Ihre Nennungen online abgeben.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Text(
|
||||
"Aktuelle Veranstaltungen",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier.padding(vertical = 8.dp)
|
||||
)
|
||||
}
|
||||
|
||||
items(veranstaltungen) { veranstaltung ->
|
||||
VeranstaltungsCardWeb(
|
||||
veranstaltung = veranstaltung,
|
||||
onNennenClick = { tId -> onNennenClick(veranstaltung.id, tId) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun VeranstaltungsCardWeb(
|
||||
veranstaltung: VeranstaltungWebModel,
|
||||
onNennenClick: (Long) -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(containerColor = Color.White),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(veranstaltung.name, style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Bold)
|
||||
Text("${veranstaltung.datum} | ${veranstaltung.ort}", style = MaterialTheme.typography.bodyMedium, color = Color.Gray)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text("Turniere dieser Veranstaltung:", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
|
||||
|
||||
veranstaltung.turniere.forEach { turnier ->
|
||||
TurnierCardWeb(
|
||||
turnier = turnier,
|
||||
onNennenClick = { onNennenClick(turnier.id) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TurnierCardWeb(
|
||||
turnier: TurnierWebModel,
|
||||
onNennenClick: () -> Unit
|
||||
) {
|
||||
OutlinedCard(
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
|
||||
colors = CardDefaults.outlinedCardColors(containerColor = AppColors.BackgroundLight)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(turnier.name, fontWeight = FontWeight.Bold)
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
TextButton(onClick = { /* PDF öffnen Logik */ }) {
|
||||
Icon(Icons.Default.Description, contentDescription = null)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text("Ausschreibung")
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = onNennenClick,
|
||||
colors = ButtonDefaults.buttonColors(containerColor = AppColors.Success)
|
||||
) {
|
||||
Icon(Icons.Default.OpenInNew, contentDescription = null)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text("Online-Nennen")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NennungWebFormular(
|
||||
veranstaltungId: Long,
|
||||
turnierId: Long,
|
||||
onBack: () -> Unit
|
||||
) {
|
||||
var statusMessage by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
|
||||
Text("Online-Nennung", style = MaterialTheme.typography.headlineMedium)
|
||||
Text("Turnier ID: $turnierId", style = MaterialTheme.typography.bodyMedium)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
if (statusMessage == null) {
|
||||
// Vereinfachtes Formular für den Prototyp
|
||||
var reiter by remember { mutableStateOf("") }
|
||||
var pferd by remember { mutableStateOf("") }
|
||||
var bewerbe by remember { mutableStateOf("") }
|
||||
|
||||
OutlinedTextField(
|
||||
value = reiter,
|
||||
onValueChange = { reiter = it },
|
||||
label = { Text("Reiter Name / ZNS-Nummer") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = pferd,
|
||||
onValueChange = { pferd = it },
|
||||
label = { Text("Pferd Name / Kopfnummer") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = bewerbe,
|
||||
onValueChange = { bewerbe = it },
|
||||
label = { Text("Bewerbe (z.B. 1, 2, 5)") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
OutlinedButton(onClick = onBack) { Text("Abbrechen") }
|
||||
Button(
|
||||
onClick = {
|
||||
statusMessage = "Nennung erfolgreich abgeschickt! Sie erhalten in Kürze eine Bestätigung per E-Mail."
|
||||
},
|
||||
enabled = reiter.isNotBlank() && pferd.isNotBlank() && bewerbe.isNotBlank()
|
||||
) {
|
||||
Text("Jetzt Nennen")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Card(
|
||||
colors = CardDefaults.cardColors(containerColor = AppColors.PrimaryContainer),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(statusMessage!!, color = AppColors.OnPrimaryContainer)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(onClick = onBack) { Text("Zurück zur Übersicht") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class VeranstaltungWebModel(
|
||||
val id: Long,
|
||||
val name: String,
|
||||
val ort: String,
|
||||
val datum: String,
|
||||
val turniere: List<TurnierWebModel>
|
||||
)
|
||||
|
||||
data class TurnierWebModel(
|
||||
val id: Long,
|
||||
val name: String,
|
||||
val pdfUrl: String
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
package at.mocode.web
|
||||
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.window.ComposeViewport
|
||||
import at.mocode.frontend.core.designsystem.theme.AppTheme
|
||||
import at.mocode.frontend.core.network.networkModule
|
||||
import at.mocode.frontend.features.nennung.di.nennungFeatureModule
|
||||
import at.mocode.turnier.feature.di.turnierFeatureModule
|
||||
import org.koin.core.context.startKoin
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun main() {
|
||||
startKoin {
|
||||
modules(
|
||||
networkModule,
|
||||
nennungFeatureModule,
|
||||
turnierFeatureModule,
|
||||
)
|
||||
}
|
||||
|
||||
ComposeViewport(content = {
|
||||
AppTheme {
|
||||
WebMainScreen()
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user