Umbau zu SCS

This commit is contained in:
stefan
2025-07-17 15:17:31 +02:00
parent 67c52f7381
commit 029b0c86bc
255 changed files with 6458 additions and 26663 deletions
@@ -1,36 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="600dp"
android:height="600dp"
android:viewportWidth="600"
android:viewportHeight="600">
<path
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z"
android:fillColor="#041619"
android:fillType="nonZero"/>
<path
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z"
android:fillColor="#37BF6E"
android:fillType="nonZero"/>
<path
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z"
android:fillColor="#3870B2"
android:fillType="nonZero"/>
<path
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#083042"
android:fillType="nonZero"/>
<path
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#083042"
android:fillType="nonZero"/>
<path
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#083042"
android:fillType="nonZero"/>
</vector>
@@ -1,335 +0,0 @@
package at.mocode
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.*
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.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import at.mocode.config.AppServiceConfiguration
import at.mocode.config.ThemeService
import at.mocode.di.ServiceRegistry
import at.mocode.di.resolve
import org.jetbrains.compose.ui.tooling.preview.Preview
@Composable
@Preview
fun App() {
// State to track if services are initialized
var servicesInitialized by remember { mutableStateOf(false) }
// Initialize services when the app starts
LaunchedEffect(Unit) {
AppServiceConfiguration.configureAppServices()
servicesInitialized = true
}
// Only show the app content after services are initialized
if (servicesInitialized) {
// Get theme service to demonstrate ServiceLocator usage
val themeService: ThemeService = ServiceRegistry.serviceLocator.resolve()
val currentTheme by remember { mutableStateOf(themeService.getCurrentTheme()) }
MaterialTheme(
colors = lightColors(
primary = Color(0xFF2E7D32),
primaryVariant = Color(0xFF1B5E20),
secondary = Color(0xFF8BC34A),
background = Color(0xFFF1F8E9)
)
) {
HomePage()
}
} else {
// Show loading state while services are being initialized
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
}
@Composable
fun HomePage() {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
item {
// Header Section
HeaderSection()
}
item {
// Welcome, Card
WelcomeCard()
}
item {
// Quick Actions
QuickActionsSection()
}
item {
// Features Overview
FeaturesSection()
}
item {
// Footer
FooterSection()
}
}
}
@Composable
fun HeaderSection() {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 4.dp,
backgroundColor = MaterialTheme.colors.primary
) {
Column(
modifier = Modifier.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "🏆",
style = MaterialTheme.typography.h2,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Meldestelle",
style = MaterialTheme.typography.h3.copy(
color = Color.White,
fontWeight = FontWeight.Bold
),
textAlign = TextAlign.Center
)
Text(
text = "Turnierverwaltungssystem",
style = MaterialTheme.typography.subtitle1.copy(
color = Color.White.copy(alpha = 0.9f)
),
textAlign = TextAlign.Center
)
}
}
}
@Composable
fun WelcomeCard() {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 2.dp
) {
Column(
modifier = Modifier.padding(20.dp)
) {
Text(
text = "Willkommen bei der Meldestelle",
style = MaterialTheme.typography.h5.copy(
fontWeight = FontWeight.Bold,
color = MaterialTheme.colors.primary
)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Ihr zentrales System für die Verwaltung von Reitturnieren. " +
"Verwalten Sie Turniere, Anmeldungen, Teilnehmer und alle " +
"wichtigen Informationen rund um Ihre Veranstaltungen.",
style = MaterialTheme.typography.body1,
lineHeight = 24.sp
)
}
}
}
@Composable
fun QuickActionsSection() {
Column {
Text(
text = "Schnellzugriff",
style = MaterialTheme.typography.h6.copy(
fontWeight = FontWeight.Bold,
color = MaterialTheme.colors.primary
),
modifier = Modifier.padding(bottom = 12.dp)
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
QuickActionCard(
title = "Neues Turnier",
emoji = "",
modifier = Modifier.weight(1f)
)
QuickActionCard(
title = "Turniere anzeigen",
emoji = "📋",
modifier = Modifier.weight(1f)
)
}
Spacer(modifier = Modifier.height(12.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
QuickActionCard(
title = "Anmeldungen",
emoji = "👥",
modifier = Modifier.weight(1f)
)
QuickActionCard(
title = "Berichte",
emoji = "📊",
modifier = Modifier.weight(1f)
)
}
}
}
@Composable
fun QuickActionCard(
title: String,
emoji: String,
modifier: Modifier = Modifier
) {
Card(
modifier = modifier,
elevation = 2.dp,
backgroundColor = MaterialTheme.colors.secondary.copy(alpha = 0.1f)
) {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = emoji,
style = MaterialTheme.typography.h4,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = title,
style = MaterialTheme.typography.body2.copy(
fontWeight = FontWeight.Medium
),
textAlign = TextAlign.Center
)
}
}
}
@Composable
fun FeaturesSection() {
Column {
Text(
text = "Funktionen",
style = MaterialTheme.typography.h6.copy(
fontWeight = FontWeight.Bold,
color = MaterialTheme.colors.primary
),
modifier = Modifier.padding(bottom = 12.dp)
)
val features = listOf(
FeatureItem("Turnierverwaltung", "Erstellen und verwalten Sie Reitturniere mit allen Details", "🏇"),
FeatureItem("Teilnehmerverwaltung", "Verwalten Sie Reiter, Pferde und Vereine", "👥"),
FeatureItem("Anmeldungen", "Bearbeiten Sie Turnieranmeldungen und Nennungen", "📝"),
FeatureItem("Plätze & Richter", "Verwalten Sie Austragungsorte und Richter", "📍"),
FeatureItem("Ergebnisse", "Erfassen und verwalten Sie Turnierergebnisse", "🏆"),
FeatureItem("Berichte", "Erstellen Sie detaillierte Berichte und Statistiken", "📊")
)
features.forEach { feature ->
FeatureCard(feature)
Spacer(modifier = Modifier.height(8.dp))
}
}
}
@Composable
fun FeatureCard(feature: FeatureItem) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 1.dp
) {
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = feature.emoji,
style = MaterialTheme.typography.h5,
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(16.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = feature.title,
style = MaterialTheme.typography.subtitle2.copy(
fontWeight = FontWeight.Medium
)
)
Text(
text = feature.description,
style = MaterialTheme.typography.body2.copy(
color = MaterialTheme.colors.onSurface.copy(alpha = 0.7f)
)
)
}
}
}
}
@Composable
fun FooterSection() {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = 1.dp,
backgroundColor = MaterialTheme.colors.primary.copy(alpha = 0.05f)
) {
Column(
modifier = Modifier.padding(20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Meldestelle v1.0.0",
style = MaterialTheme.typography.body2.copy(
fontWeight = FontWeight.Medium,
color = MaterialTheme.colors.primary
)
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "Turnierverwaltungssystem für Reitsport",
style = MaterialTheme.typography.caption.copy(
color = MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
)
)
}
}
}
data class FeatureItem(
val title: String,
val description: String,
val emoji: String
)
@@ -1,88 +0,0 @@
package at.mocode.config
import at.mocode.di.ServiceRegistry
import at.mocode.di.register
/**
* Service configuration for the Compose application.
* Demonstrates how to use the ServiceLocator pattern in the frontend.
*/
object AppServiceConfiguration {
/**
* Initialize services for the compose application
*/
fun configureAppServices() {
val serviceLocator = ServiceRegistry.serviceLocator
// Register frontend-specific services
registerUIServices(serviceLocator)
// Register API clients or other services as needed
// registerApiServices(serviceLocator)
}
/**
* Register UI-related services
*/
private fun registerUIServices(serviceLocator: at.mocode.di.ServiceLocator) {
// Example: Register a theme service
serviceLocator.register<ThemeService> { DefaultThemeService() }
// Example: Register a navigation service
serviceLocator.register<NavigationService> { DefaultNavigationService() }
// Add more UI services as needed
}
/**
* Clear all registered services (useful for testing)
*/
fun clearAppServices() {
ServiceRegistry.serviceLocator.clear()
}
}
/**
* Example theme service interface
*/
interface ThemeService {
fun getCurrentTheme(): String
fun setTheme(theme: String)
}
/**
* Default implementation of ThemeService
*/
class DefaultThemeService : ThemeService {
private var currentTheme = "light"
override fun getCurrentTheme(): String = currentTheme
override fun setTheme(theme: String) {
currentTheme = theme
}
}
/**
* Example navigation service interface
*/
interface NavigationService {
fun navigateTo(route: String)
fun goBack()
}
/**
* Default implementation of NavigationService
*/
class DefaultNavigationService : NavigationService {
override fun navigateTo(route: String) {
// Implementation for navigation
println("Navigating to: $route")
}
override fun goBack() {
// Implementation for going back
println("Going back")
}
}
@@ -1,13 +0,0 @@
package at.mocode
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
fun main() = application {
Window(
onCloseRequest = ::exitApplication,
title = "Meldestelle",
) {
App()
}
}
@@ -1,12 +0,0 @@
package at.mocode
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.window.ComposeViewport
import kotlinx.browser.document
@OptIn(ExperimentalComposeUiApi::class)
fun main() {
ComposeViewport(document.body!!) {
App()
}
}
@@ -1,12 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Meldestelle</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script type="application/javascript" src="composeApp.js"></script>
</head>
<body>
</body>
</html>
@@ -1,7 +0,0 @@
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}