chore: consolidate redundant controllers in mail-service, improve backend stability, refine desktop UX, and enhance Vereinsverwaltung functionality
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
{
|
||||
"deviceName": "Meldestelle",
|
||||
"deviceName": "Meldestelle\n",
|
||||
"sharedKey": "Password",
|
||||
"backupPath": "/mocode/meldestelle/docs/temp",
|
||||
"networkRole": "MASTER"
|
||||
"networkRole": "MASTER",
|
||||
"expectedClients": [
|
||||
{
|
||||
"name": "Richter-Turm",
|
||||
"role": "RICHTER"
|
||||
}
|
||||
]
|
||||
}
|
||||
+36
-24
@@ -16,20 +16,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import at.mocode.frontend.shell.desktop.data.Store
|
||||
import at.mocode.frontend.shell.desktop.data.Turnier
|
||||
import at.mocode.frontend.shell.desktop.data.TurnierStore
|
||||
import at.mocode.frontend.shell.desktop.screens.management.FunktionaerVerwaltungScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.management.VeranstalterAuswahl
|
||||
import at.mocode.frontend.shell.desktop.screens.management.VeranstalterDetail
|
||||
import at.mocode.frontend.shell.desktop.screens.management.VeranstalterVerwaltungScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.nennung.NennungsEingangScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.profile.FunktionaerProfil
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.VeranstaltungVerwaltung
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.details.VeranstaltungKonfig
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.details.VeranstaltungProfilScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.wizards.TurnierWizard
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.wizards.VeranstalterAnlegenWizard
|
||||
import at.mocode.frontend.core.auth.data.local.AuthTokenManager
|
||||
import at.mocode.frontend.core.designsystem.theme.AppColors
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
@@ -47,20 +33,34 @@ import at.mocode.frontend.features.nennung.presentation.NennungManagementScreen
|
||||
import at.mocode.frontend.features.nennung.presentation.NennungViewModel
|
||||
import at.mocode.frontend.features.pferde.presentation.PferdeScreen
|
||||
import at.mocode.frontend.features.pferde.presentation.PferdeViewModel
|
||||
import at.mocode.frontend.features.ping.presentation.PingScreen
|
||||
import at.mocode.frontend.features.ping.presentation.PingViewModel
|
||||
import at.mocode.frontend.features.profile.presentation.ProfileScreen
|
||||
import at.mocode.frontend.features.profile.presentation.ProfileViewModel
|
||||
import at.mocode.frontend.features.reiter.presentation.ReiterScreen
|
||||
import at.mocode.frontend.features.reiter.presentation.ReiterViewModel
|
||||
import at.mocode.frontend.features.verein.presentation.VereinScreen
|
||||
import at.mocode.frontend.features.verein.presentation.VereinViewModel
|
||||
import at.mocode.frontend.features.ping.presentation.PingScreen
|
||||
import at.mocode.frontend.features.ping.presentation.PingViewModel
|
||||
import at.mocode.frontend.features.turnier.presentation.SeriesScreen
|
||||
import at.mocode.frontend.features.turnier.presentation.TurnierDetailScreen
|
||||
import at.mocode.frontend.features.veranstalter.presentation.VeranstaltungKonfigScreen
|
||||
import at.mocode.frontend.features.verein.presentation.VereinScreen
|
||||
import at.mocode.frontend.features.verein.presentation.VereinViewModel
|
||||
import at.mocode.frontend.features.zns.import.presentation.StammdatenImportScreen
|
||||
import at.mocode.frontend.shell.desktop.data.Store
|
||||
import at.mocode.frontend.shell.desktop.data.Turnier
|
||||
import at.mocode.frontend.shell.desktop.data.TurnierStore
|
||||
import at.mocode.frontend.shell.desktop.screens.management.FunktionaerVerwaltungScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.management.VeranstalterAuswahl
|
||||
import at.mocode.frontend.shell.desktop.screens.management.VeranstalterDetail
|
||||
import at.mocode.frontend.shell.desktop.screens.management.VeranstalterVerwaltungScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.nennung.NennungsEingangScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.profile.FunktionaerProfil
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.VeranstaltungVerwaltung
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.details.VeranstaltungProfilScreen
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.wizards.TurnierWizard
|
||||
import at.mocode.frontend.shell.desktop.screens.veranstaltung.wizards.VeranstalterAnlegenWizard
|
||||
import at.mocode.veranstaltung.feature.presentation.AdminUebersichtScreen
|
||||
import at.mocode.veranstaltung.feature.presentation.VeranstaltungDetailScreen
|
||||
import at.mocode.veranstaltung.feature.presentation.VeranstaltungNeuScreen
|
||||
import at.mocode.frontend.features.zns.import.presentation.StammdatenImportScreen
|
||||
import kotlinx.coroutines.delay
|
||||
import org.koin.compose.koinInject
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
@@ -671,12 +671,24 @@ private fun DesktopContentArea(
|
||||
|
||||
is AppScreen.VeranstaltungKonfig -> {
|
||||
val vId = currentScreen.veranstalterId
|
||||
// Falls vId == 0, kommen wir aus der Gesamtübersicht und wählen erst im Wizard
|
||||
VeranstaltungKonfig(
|
||||
VeranstaltungKonfigScreen(
|
||||
veranstalterId = vId,
|
||||
onBack = onBack,
|
||||
onSaved = { evtId: Long, finalVId: Long -> onNavigate(AppScreen.VeranstaltungProfil(finalVId, evtId)) },
|
||||
onVeranstalterCreated = { newVId: Long -> onNavigate(AppScreen.VeranstalterDetail(newVId)) }
|
||||
onAbbrechen = onBack,
|
||||
onSpeichern = { titel, datumVon, datumBis ->
|
||||
// In-Memory Store Simulation
|
||||
val allEvents = Store.allEvents()
|
||||
val newId = (allEvents.maxOfOrNull { it.id } ?: 0L) + 1L
|
||||
val newEvent = at.mocode.frontend.shell.desktop.data.Veranstaltung(
|
||||
id = newId,
|
||||
veranstalterId = vId,
|
||||
titel = titel,
|
||||
datumVon = datumVon,
|
||||
datumBis = datumBis,
|
||||
status = "NEU"
|
||||
)
|
||||
Store.addEventFirst(vId, newEvent)
|
||||
onNavigate(AppScreen.VeranstaltungProfil(vId, newId))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+37
-3
@@ -83,13 +83,15 @@ fun NennungsEingangScreen(onBack: () -> Unit) {
|
||||
}
|
||||
|
||||
val filteredMails = remember(mails, searchQuery) {
|
||||
if (searchQuery.isBlank()) mails
|
||||
val base = if (searchQuery.isBlank()) mails
|
||||
else mails.filter {
|
||||
it.vorname.contains(searchQuery, ignoreCase = true) ||
|
||||
it.nachname.contains(searchQuery, ignoreCase = true) ||
|
||||
it.pferd.contains(searchQuery, ignoreCase = true) ||
|
||||
it.turnierNr.contains(searchQuery, ignoreCase = true)
|
||||
}
|
||||
// Standard-Sortierung: Neueste zuerst (Status NEU oben, dann nach TurnierNr)
|
||||
base.sortedWith(compareBy({ it.status != "NEU" }, { it.turnierNr }, { it.datum }))
|
||||
}
|
||||
|
||||
// Initiales Laden
|
||||
@@ -108,6 +110,21 @@ fun NennungsEingangScreen(onBack: () -> Unit) {
|
||||
mails = updated
|
||||
selectedMail = null
|
||||
}
|
||||
},
|
||||
onSendReply = {
|
||||
scope.launch {
|
||||
repository.sendeAntwort(
|
||||
email = selectedMail!!.sender,
|
||||
turnierNr = selectedMail!!.turnierNr,
|
||||
vorname = selectedMail!!.vorname,
|
||||
nachname = selectedMail!!.nachname
|
||||
)
|
||||
// Nach Antwort automatisch als gelesen markieren
|
||||
repository.markiereAlsGelesen(selectedMail!!.id)
|
||||
val updated = mails.map { if (it.id == selectedMail!!.id) it.copy(status = "GELESEN") else it }
|
||||
mails = updated
|
||||
selectedMail = null
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -212,7 +229,12 @@ fun NennungsEingangScreen(onBack: () -> Unit) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NennungDetailDialog(mail: OnlineNennungMail, onDismiss: () -> Unit, onMarkProcessed: () -> Unit) {
|
||||
fun NennungDetailDialog(
|
||||
mail: OnlineNennungMail,
|
||||
onDismiss: () -> Unit,
|
||||
onMarkProcessed: () -> Unit,
|
||||
onSendReply: () -> Unit
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text("Details zur Online-EntryManagement") },
|
||||
@@ -235,7 +257,19 @@ fun NennungDetailDialog(mail: OnlineNennungMail, onDismiss: () -> Unit, onMarkPr
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
Button(onClick = onMarkProcessed) { Text("Als gelesen markieren") }
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (mail.status == "NEU") {
|
||||
Button(
|
||||
onClick = onSendReply,
|
||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2E7D32))
|
||||
) {
|
||||
Icon(Icons.Default.Email, null, modifier = Modifier.size(18.dp))
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text("Antwort & Übernahme")
|
||||
}
|
||||
}
|
||||
Button(onClick = onMarkProcessed) { Text("Als gelesen markieren") }
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) { Text("Schließen") }
|
||||
|
||||
Reference in New Issue
Block a user