- 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>
346 lines
12 KiB
Kotlin
346 lines
12 KiB
Kotlin
package screens
|
|
|
|
import androidx.compose.foundation.BorderStroke
|
|
import androidx.compose.foundation.layout.*
|
|
import androidx.compose.foundation.rememberScrollState
|
|
import androidx.compose.foundation.verticalScroll
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|
import androidx.compose.material3.*
|
|
import androidx.compose.runtime.*
|
|
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.auth.data.AuthTokenManager
|
|
|
|
@OptIn(ExperimentalMaterial3Api::class)
|
|
@Composable
|
|
fun OrganizerProfileScreen(
|
|
authTokenManager: AuthTokenManager,
|
|
onLogout: () -> Unit,
|
|
onNavigateToDashboard: () -> Unit
|
|
) {
|
|
val authState by authTokenManager.authState.collectAsState()
|
|
val scrollState = rememberScrollState()
|
|
|
|
// Formular-Felder
|
|
var vereinsname by remember { mutableStateOf("URFV Neumarkt") }
|
|
var vereinskuerzel by remember { mutableStateOf("URFV") }
|
|
var adresse by remember { mutableStateOf("") }
|
|
var plz by remember { mutableStateOf("") }
|
|
var ort by remember { mutableStateOf("") }
|
|
var land by remember { mutableStateOf("Österreich") }
|
|
var mapsLink by remember { mutableStateOf("") }
|
|
|
|
// Ansprechpersonen
|
|
var kontakt1Name by remember { mutableStateOf("") }
|
|
var kontakt1Email by remember { mutableStateOf("") }
|
|
var kontakt1Telefon by remember { mutableStateOf("") }
|
|
var kontakt2Name by remember { mutableStateOf("") }
|
|
var kontakt2Email by remember { mutableStateOf("") }
|
|
var kontakt2Telefon by remember { mutableStateOf("") }
|
|
|
|
// Social / Links
|
|
var webseite by remember { mutableStateOf("") }
|
|
var facebook by remember { mutableStateOf("") }
|
|
var instagram by remember { mutableStateOf("") }
|
|
var youtube by remember { mutableStateOf("") }
|
|
|
|
// Weitere Infos
|
|
var vereinsbeschreibung by remember { mutableStateOf("") }
|
|
var bankverbindung by remember { mutableStateOf("") }
|
|
var uid by remember { mutableStateOf("") }
|
|
|
|
var saveSuccess by remember { mutableStateOf(false) }
|
|
|
|
Scaffold(
|
|
topBar = {
|
|
TopAppBar(
|
|
title = { Text("Veranstalter Profil") },
|
|
navigationIcon = {
|
|
IconButton(onClick = onNavigateToDashboard) {
|
|
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Zurück")
|
|
}
|
|
},
|
|
actions = {
|
|
Text(
|
|
text = authState.username ?: "",
|
|
style = MaterialTheme.typography.bodyMedium,
|
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
modifier = Modifier.padding(end = 8.dp)
|
|
)
|
|
TextButton(onClick = onLogout) { Text("Abmelden") }
|
|
}
|
|
)
|
|
}
|
|
) { paddingValues ->
|
|
Column(
|
|
modifier = Modifier
|
|
.fillMaxSize()
|
|
.padding(paddingValues)
|
|
.verticalScroll(scrollState)
|
|
.padding(24.dp),
|
|
verticalArrangement = Arrangement.spacedBy(24.dp)
|
|
) {
|
|
|
|
// --- Logo & Vereinsname ---
|
|
Card(modifier = Modifier.fillMaxWidth()) {
|
|
Column(modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
|
Text("Verein / Veranstalter", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
|
|
|
|
// Logo Placeholder
|
|
Surface(
|
|
modifier = Modifier.fillMaxWidth(),
|
|
shape = MaterialTheme.shapes.medium,
|
|
color = MaterialTheme.colorScheme.surfaceVariant,
|
|
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant)
|
|
) {
|
|
Column(
|
|
modifier = Modifier.padding(24.dp).fillMaxWidth(),
|
|
horizontalAlignment = Alignment.CenterHorizontally,
|
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
) {
|
|
Text("🏆", style = MaterialTheme.typography.displayMedium)
|
|
Text(
|
|
"Vereins-/Veranstaltungslogo",
|
|
style = MaterialTheme.typography.bodyMedium,
|
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
|
)
|
|
OutlinedButton(onClick = { /* TODO: File Picker */ }) {
|
|
Text("Logo hochladen")
|
|
}
|
|
}
|
|
}
|
|
|
|
OutlinedTextField(
|
|
value = vereinsname,
|
|
onValueChange = { vereinsname = it },
|
|
label = { Text("Vereinsname / Veranstalter") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = vereinskuerzel,
|
|
onValueChange = { vereinskuerzel = it },
|
|
label = { Text("Kürzel") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = vereinsbeschreibung,
|
|
onValueChange = { vereinsbeschreibung = it },
|
|
label = { Text("Kurzbeschreibung / Über uns") },
|
|
minLines = 3,
|
|
maxLines = 6,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
}
|
|
}
|
|
|
|
// --- Adresse ---
|
|
Card(modifier = Modifier.fillMaxWidth()) {
|
|
Column(modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
|
Text("Adresse", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
|
|
|
|
OutlinedTextField(
|
|
value = adresse,
|
|
onValueChange = { adresse = it },
|
|
label = { Text("Straße & Hausnummer") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
|
OutlinedTextField(
|
|
value = plz,
|
|
onValueChange = { plz = it },
|
|
label = { Text("PLZ") },
|
|
singleLine = true,
|
|
modifier = Modifier.width(100.dp)
|
|
)
|
|
OutlinedTextField(
|
|
value = ort,
|
|
onValueChange = { ort = it },
|
|
label = { Text("Ort") },
|
|
singleLine = true,
|
|
modifier = Modifier.weight(1f)
|
|
)
|
|
}
|
|
OutlinedTextField(
|
|
value = land,
|
|
onValueChange = { land = it },
|
|
label = { Text("Land") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = mapsLink,
|
|
onValueChange = { mapsLink = it },
|
|
label = { Text("Google Maps / OpenStreetMap Link") },
|
|
placeholder = { Text("https://maps.google.com/...") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
}
|
|
}
|
|
|
|
// --- Ansprechpersonen ---
|
|
Card(modifier = Modifier.fillMaxWidth()) {
|
|
Column(modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
|
Text("Ansprechpersonen", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
|
|
|
|
Text("Hauptkontakt", style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.primary)
|
|
OutlinedTextField(
|
|
value = kontakt1Name,
|
|
onValueChange = { kontakt1Name = it },
|
|
label = { Text("Name") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = kontakt1Email,
|
|
onValueChange = { kontakt1Email = it },
|
|
label = { Text("E-Mail") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = kontakt1Telefon,
|
|
onValueChange = { kontakt1Telefon = it },
|
|
label = { Text("Telefon / Mobil") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
|
|
HorizontalDivider()
|
|
|
|
Text(
|
|
"Weiterer Kontakt (optional)",
|
|
style = MaterialTheme.typography.titleMedium,
|
|
color = MaterialTheme.colorScheme.secondary
|
|
)
|
|
OutlinedTextField(
|
|
value = kontakt2Name,
|
|
onValueChange = { kontakt2Name = it },
|
|
label = { Text("Name") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = kontakt2Email,
|
|
onValueChange = { kontakt2Email = it },
|
|
label = { Text("E-Mail") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = kontakt2Telefon,
|
|
onValueChange = { kontakt2Telefon = it },
|
|
label = { Text("Telefon / Mobil") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
}
|
|
}
|
|
|
|
// --- Social Media & Links ---
|
|
Card(modifier = Modifier.fillMaxWidth()) {
|
|
Column(modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
|
Text("Links & Social Media", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
|
|
|
|
OutlinedTextField(
|
|
value = webseite,
|
|
onValueChange = { webseite = it },
|
|
label = { Text("Webseite") },
|
|
placeholder = { Text("https://www.meinverein.at") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = facebook,
|
|
onValueChange = { facebook = it },
|
|
label = { Text("Facebook") },
|
|
placeholder = { Text("https://facebook.com/...") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = instagram,
|
|
onValueChange = { instagram = it },
|
|
label = { Text("Instagram") },
|
|
placeholder = { Text("https://instagram.com/...") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = youtube,
|
|
onValueChange = { youtube = it },
|
|
label = { Text("YouTube") },
|
|
placeholder = { Text("https://youtube.com/...") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
}
|
|
}
|
|
|
|
// --- Weitere Vereinsdaten ---
|
|
Card(modifier = Modifier.fillMaxWidth()) {
|
|
Column(modifier = Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
|
Text("Weitere Informationen", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold)
|
|
|
|
OutlinedTextField(
|
|
value = bankverbindung,
|
|
onValueChange = { bankverbindung = it },
|
|
label = { Text("IBAN / Bankverbindung") },
|
|
placeholder = { Text("AT12 3456 7890 1234 5678") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
OutlinedTextField(
|
|
value = uid,
|
|
onValueChange = { uid = it },
|
|
label = { Text("UID-Nummer / ZVR-Zahl") },
|
|
singleLine = true,
|
|
modifier = Modifier.fillMaxWidth()
|
|
)
|
|
}
|
|
}
|
|
|
|
// --- Speichern ---
|
|
if (saveSuccess) {
|
|
Card(
|
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer),
|
|
modifier = Modifier.fillMaxWidth()
|
|
) {
|
|
Text(
|
|
"✓ Profil erfolgreich gespeichert!",
|
|
modifier = Modifier.padding(16.dp),
|
|
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
|
style = MaterialTheme.typography.bodyLarge
|
|
)
|
|
}
|
|
}
|
|
|
|
Button(
|
|
onClick = {
|
|
// TODO: Backend-Anbindung (PUT /api/organizer/profile)
|
|
saveSuccess = true
|
|
},
|
|
modifier = Modifier.fillMaxWidth().height(52.dp)
|
|
) {
|
|
Text("Profil speichern", style = MaterialTheme.typography.titleMedium)
|
|
}
|
|
|
|
OutlinedButton(
|
|
onClick = onNavigateToDashboard,
|
|
modifier = Modifier.fillMaxWidth()
|
|
) {
|
|
Text("Zum Dashboard")
|
|
}
|
|
|
|
Spacer(modifier = Modifier.height(24.dp))
|
|
}
|
|
}
|
|
}
|
|
|