Files
meldestelle/frontend/shells/meldestelle-portal/src/commonMain/kotlin/screens/LandingScreen.kt
T
stefan e89c58bd28 feat(ui): add new screens for AuthStatus, OrganizerProfile, and Dashboard
- Introduced `AuthStatusScreen` to display user authentication status and navigation options.
- Added `OrganizerProfileScreen` with detailed profile editing features (contacts, address, and social links).
- Created `DashboardScreen` for admins and organizers with responsive layouts.
- Developed reusable `TournamentCard` component for displaying tournament details.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
2026-03-21 18:37:23 +01:00

166 lines
5.9 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package screens
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import at.mocode.frontend.core.designsystem.components.AppFooter
@Composable
fun LandingScreen(
onPrimaryCta: () -> Unit,
onOpenPing: () -> Unit
) {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(scrollState)
) {
// Top Bar
Surface(
color = MaterialTheme.colorScheme.surface,
shadowElevation = 2.dp,
modifier = Modifier.fillMaxWidth()
) {
Row(
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "mo-code.at",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)
Button(onClick = onPrimaryCta) {
Text("Login Meldestelle")
}
}
}
// Hero
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 60.dp),
verticalArrangement = Arrangement.spacedBy(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Die moderne Meldestelle",
style = MaterialTheme.typography.displayMedium,
fontWeight = FontWeight.Bold
)
Text(
text = "Von Praktikern für Praktiker. Schneller Nennen, fehlerfrei Richten und stressfrei Auswerten konform nach ÖTO & FEI.",
style = MaterialTheme.typography.headlineSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
// Manifest / Intro
Surface(color = MaterialTheme.colorScheme.surfaceVariant) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 60.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text("Unser Anspruch: Ein durchdachtes System.", style = MaterialTheme.typography.headlineMedium)
Text(
"Die Meldestelle ist das Herzstück jedes Turniers. Wenn sie stolpert, stockt der Sport. Wir verstehen den Balanceakt zwischen Veranstaltern, Reitern und den Verbänden.",
style = MaterialTheme.typography.bodyLarge
)
Text(
"Deshalb entwickeln wir diese Plattform nicht am Reißbrett, sondern direkt am Turnierplatz aus der Sicht der Meldestelle, der Richter, der Zeitnehmer und aller Funktionäre.",
style = MaterialTheme.typography.bodyLarge
)
Text(
"Mit Fokus auf die Praxis: Tastaturbedienung für höchste Geschwindigkeit, Offline-Fähigkeit für das 'Plumpsklo' am Rand des Abreiteplatzes und eine integrierte Kassenführung.",
style = MaterialTheme.typography.bodyLarge
)
}
}
// Kern-Säulen
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 60.dp),
verticalArrangement = Arrangement.spacedBy(32.dp)
) {
Text("Die Kern-Säulen", style = MaterialTheme.typography.headlineMedium)
Column(verticalArrangement = Arrangement.spacedBy(24.dp)) {
LandingFeatureCard(
number = "01",
title = "Regelwerks-Intelligenz (ÖTO)",
body = "Wir nehmen Ihnen die Validierungs-Komplexität ab. Von der Lizenzprüfung der Reiter bis zur Kontrolle der Richterqualifikationen beim Anlegen der Bewerbe."
)
LandingFeatureCard(
number = "02",
title = "Offline-First & Resilient",
body = "Stabil auf dem Laptop. Dank Offline-Unterstützung und lokaler Datenbank arbeiten Sie nahtlos weiter, selbst wenn die Internetverbindung am Platz wieder einmal abreißt."
)
LandingFeatureCard(
number = "03",
title = "Speed-Workflow",
body = "Die Nennungsmaske und die Ergebniserfassung sind kompromisslos auf Geschwindigkeit und Tastaturbedienung (Enter & Tab) optimiert. Weil am Turniertag jede Sekunde zählt."
)
LandingFeatureCard(
number = "04",
title = "Smarte Kassenführung",
body = "Kontobasierte Abrechnung für Reiter und Besitzer. Nenngelder, Startgelder und Nachnenngebühren sauber getrennt selbst ein Nennungstausch wird als einfacher Transfer verbucht."
)
}
}
// System Status Link
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedButton(onClick = onOpenPing) {
Text("System Status (Ping-Service)")
}
}
AppFooter()
}
}
@Composable
private fun LandingFeatureCard(number: String, title: String, body: String) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
Row(
modifier = Modifier.fillMaxWidth().padding(16.dp),
verticalAlignment = Alignment.Top
) {
Text(
text = number,
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Black,
modifier = Modifier.width(64.dp)
)
Column(modifier = Modifier.weight(1f)) {
Text(title, style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
Spacer(Modifier.height(8.dp))
Text(body, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
}
}
}