Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd5e37c4d5 | |||
| e89c58bd28 | |||
| 9882109d16 | |||
| 3a53dd95da | |||
| 0e32999df4 | |||
| faa2c344d1 | |||
| c0389558bb | |||
| a0b7d5aa34 | |||
| ac3bfcad3c |
@@ -61,6 +61,7 @@ RUN mkdir -p \
|
||||
frontend/core/local-db \
|
||||
frontend/core/sync \
|
||||
frontend/features/ping-feature \
|
||||
frontend/features/nennung-feature \
|
||||
frontend/shared \
|
||||
frontend/shells/meldestelle-portal \
|
||||
docs
|
||||
|
||||
@@ -59,6 +59,7 @@ RUN mkdir -p \
|
||||
frontend/core/local-db \
|
||||
frontend/core/sync \
|
||||
frontend/features/ping-feature \
|
||||
frontend/features/nennung-feature \
|
||||
frontend/shared \
|
||||
frontend/shells/meldestelle-portal \
|
||||
docs
|
||||
|
||||
@@ -71,6 +71,10 @@ subprojects {
|
||||
}
|
||||
// Configure CDS in auto-mode to prevent bootstrap classpath warnings
|
||||
jvmArgs("-Xshare:auto", "-Djdk.instrument.traceUsage=false")
|
||||
// Suppress Netty sun.misc.Unsafe warnings (transitiv via Spring Boot / Kafka)
|
||||
jvmArgs("--add-opens=java.base/java.nio=ALL-UNNAMED")
|
||||
// Suppress ByteBuddy/Mockito dynamic agent loading warnings (Java 21+)
|
||||
jvmArgs("-XX:+EnableDynamicAgentLoading")
|
||||
// Increase test JVM memory with a stable configuration
|
||||
minHeapSize = "512m"
|
||||
maxHeapSize = "2g"
|
||||
@@ -124,6 +128,8 @@ subprojects {
|
||||
shouldRunAfter("test")
|
||||
// Keep the same JVM settings for consistency
|
||||
jvmArgs("-Xshare:auto", "-Djdk.instrument.traceUsage=false")
|
||||
jvmArgs("--add-opens=java.base/java.nio=ALL-UNNAMED")
|
||||
jvmArgs("-XX:+EnableDynamicAgentLoading")
|
||||
maxHeapSize = "2g"
|
||||
dependsOn("testClasses")
|
||||
}
|
||||
|
||||
+32
-2
@@ -70,7 +70,8 @@ fun LoginScreen(
|
||||
focusManager = focusManager,
|
||||
onUsernameChange = viewModel::updateUsername,
|
||||
onPasswordChange = viewModel::updatePassword,
|
||||
onLogin = { focusManager.clearFocus(); viewModel.login() }
|
||||
onLogin = { focusManager.clearFocus(); viewModel.login() },
|
||||
onKeycloakLogin = viewModel::startOidcFlow
|
||||
)
|
||||
} else {
|
||||
RegisterTabContent()
|
||||
@@ -91,7 +92,8 @@ private fun LoginTabContent(
|
||||
focusManager: androidx.compose.ui.focus.FocusManager,
|
||||
onUsernameChange: (String) -> Unit,
|
||||
onPasswordChange: (String) -> Unit,
|
||||
onLogin: () -> Unit
|
||||
onLogin: () -> Unit,
|
||||
onKeycloakLogin: () -> Unit = {},
|
||||
) {
|
||||
var passwordVisible by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -169,6 +171,34 @@ private fun LoginTabContent(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
HorizontalDivider(modifier = Modifier.weight(1f))
|
||||
Text(
|
||||
text = " oder ",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.weight(1f))
|
||||
}
|
||||
|
||||
OutlinedButton(
|
||||
onClick = onKeycloakLogin,
|
||||
enabled = !uiState.isLoading && !uiState.isOidcLoading,
|
||||
modifier = Modifier.fillMaxWidth().height(48.dp)
|
||||
) {
|
||||
if (uiState.isOidcLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text("Mit Keycloak anmelden")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-60
@@ -1,56 +1,47 @@
|
||||
package at.mocode.frontend.core.designsystem.theme
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// --- 1. Farben (Palette) ---
|
||||
// wir definieren eine professionelle, kontrastreiche Palette.
|
||||
// Blau steht für Aktion/Information, Grau für Struktur.
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Color(0xFF0052CC), // Enterprise Blue (stark)
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFFDEEBFF),
|
||||
onPrimaryContainer = Color(0xFF0052CC),
|
||||
primary = AppColors.Primary,
|
||||
onPrimary = AppColors.OnPrimary,
|
||||
primaryContainer = AppColors.PrimaryContainer,
|
||||
onPrimaryContainer = AppColors.OnPrimaryContainer,
|
||||
|
||||
secondary = Color(0xFF2684FF), // Helleres Blau für Akzente
|
||||
onSecondary = Color.White,
|
||||
secondary = AppColors.Secondary,
|
||||
onSecondary = AppColors.OnSecondary,
|
||||
|
||||
background = Color(0xFFF4F5F7), // Helles Grau (nicht hartes Weiß)
|
||||
surface = Color.White,
|
||||
onBackground = Color(0xFF172B4D), // Fast Schwarz (besser lesbar als #000)
|
||||
onSurface = Color(0xFF172B4D),
|
||||
background = AppColors.BackgroundLight,
|
||||
surface = AppColors.SurfaceLight,
|
||||
onBackground = AppColors.OnBackgroundLight,
|
||||
onSurface = AppColors.OnBackgroundLight,
|
||||
|
||||
error = Color(0xFFDE350B),
|
||||
onError = Color.White
|
||||
error = AppColors.Error,
|
||||
onError = AppColors.OnError
|
||||
)
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Color(0xFF4C9AFF), // Helleres Blau auf Dunkel
|
||||
onPrimary = Color(0xFF091E42),
|
||||
primaryContainer = Color(0xFF0052CC),
|
||||
onPrimaryContainer = Color.White,
|
||||
primary = AppColors.Secondary, // Helleres Blau auf Dunkel
|
||||
onPrimary = AppColors.BackgroundDark,
|
||||
primaryContainer = AppColors.Primary,
|
||||
onPrimaryContainer = AppColors.OnPrimary,
|
||||
|
||||
secondary = Color(0xFF2684FF),
|
||||
onSecondary = Color.White,
|
||||
secondary = AppColors.Secondary,
|
||||
onSecondary = AppColors.OnSecondary,
|
||||
|
||||
background = Color(0xFF1E1E1E), // Dunkles Grau (angenehmer als #000)
|
||||
surface = Color(0xFF2C2C2C), // Panels heben sich leicht ab
|
||||
onBackground = Color(0xFFEBECF0),
|
||||
onSurface = Color(0xFFEBECF0),
|
||||
background = AppColors.BackgroundDark,
|
||||
surface = AppColors.SurfaceDark,
|
||||
onBackground = AppColors.OnBackgroundDark,
|
||||
onSurface = AppColors.OnBackgroundDark,
|
||||
|
||||
error = Color(0xFFFF5630),
|
||||
onError = Color.Black
|
||||
error = AppColors.Error,
|
||||
onError = AppColors.OnError
|
||||
)
|
||||
|
||||
// --- 2. Formen (Shapes) ---
|
||||
@@ -63,31 +54,11 @@ private val AppShapes = Shapes(
|
||||
|
||||
// --- 3. Typografie ---
|
||||
// wir setzen auf klare Hierarchie.
|
||||
private val AppTypography = Typography(
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp
|
||||
),
|
||||
titleMedium = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp
|
||||
),
|
||||
bodyMedium = TextStyle( // Standard Text
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp
|
||||
),
|
||||
labelSmall = TextStyle( // Für dichte Tabellen/Labels
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp
|
||||
)
|
||||
private val AppMaterialTypography = Typography(
|
||||
titleLarge = AppTypography.TitleLarge,
|
||||
titleMedium = AppTypography.TitleMedium,
|
||||
bodyMedium = AppTypography.BodyMedium,
|
||||
labelSmall = AppTypography.LabelSmall
|
||||
)
|
||||
|
||||
@Composable
|
||||
@@ -100,7 +71,7 @@ fun AppTheme(
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
shapes = AppShapes,
|
||||
typography = AppTypography,
|
||||
typography = AppMaterialTypography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package at.mocode.frontend.core.designsystem.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
/**
|
||||
* Zentrale Farbdefinitionen (Palette) für das Projekt.
|
||||
* Keine "Magic Colors" (wie Color.Red) in den UIs!
|
||||
* Stattdessen immer AppColors.Primary oder MaterialTheme.colorScheme.primary nutzen.
|
||||
*/
|
||||
object AppColors {
|
||||
// Enterprise Blue (Hauptaktion, starke Akzente)
|
||||
val Primary = Color(0xFF0052CC)
|
||||
val OnPrimary = Color.White
|
||||
val PrimaryContainer = Color(0xFFDEEBFF)
|
||||
val OnPrimaryContainer = Color(0xFF0052CC)
|
||||
|
||||
// Helleres Blau für sekundäre Akzente
|
||||
val Secondary = Color(0xFF2684FF)
|
||||
val OnSecondary = Color.White
|
||||
|
||||
// Neutral- & Hintergrund (Light Mode)
|
||||
val BackgroundLight = Color(0xFFF4F5F7) // Helles Grau (nicht hartes Weiß)
|
||||
val SurfaceLight = Color.White
|
||||
val OnBackgroundLight = Color(0xFF172B4D) // Fast Schwarz (besser lesbar)
|
||||
|
||||
// Neutral & Hintergrund (Dark Mode)
|
||||
val BackgroundDark = Color(0xFF1E1E1E) // Angenehmes, dunkles Grau
|
||||
val SurfaceDark = Color(0xFF2C2C2C)
|
||||
val OnBackgroundDark = Color(0xFFEBECF0)
|
||||
|
||||
// System Status
|
||||
val Error = Color(0xFFDE350B)
|
||||
val OnError = Color.White
|
||||
val Success = Color(0xFF4CAF50)
|
||||
val Warning = Color(0xFFE67E22)
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Zentrale Definition für Abstände und Größen.
|
||||
* Warum? Damit wir nicht überall "Magic Numbers" (z.B. 13.dp) haben.
|
||||
* Warum? Damit wir nicht überall "Magic Numbers" (z. B. 13.dp) haben.
|
||||
* Wenn wir den Abstand global ändern wollen, machen wir das nur hier.
|
||||
*/
|
||||
object Dimens {
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package at.mocode.frontend.core.designsystem.theme
|
||||
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
/**
|
||||
* Zentrale Typografie (Schriftgrößen und Stile) für das gesamte Projekt.
|
||||
* Die Idee: Im UI-Code schreiben wir nie "fontSize = 16.sp",
|
||||
* sondern nutzen die festgelegten Stile des AppTypography Objekts oder MaterialTheme.typography.
|
||||
*/
|
||||
object AppTypography {
|
||||
|
||||
// Große Überschriften (z. B. Screen-Titel)
|
||||
val TitleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp
|
||||
)
|
||||
|
||||
// Mittlere Überschriften (z.B. Card-Titel, Sektionen)
|
||||
val TitleMedium = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp
|
||||
)
|
||||
|
||||
// Standard Fließtext (z.B. Beschreibungen, Dialog-Texte)
|
||||
val BodyMedium = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 20.sp
|
||||
)
|
||||
|
||||
// Kleiner Text / Labels (z. B. Tabellenköpfe, dichte Informationen)
|
||||
val LabelSmall = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp
|
||||
)
|
||||
}
|
||||
@@ -83,6 +83,7 @@ kotlin {
|
||||
implementation(compose.ui)
|
||||
implementation(compose.components.resources)
|
||||
implementation(compose.materialIconsExtended)
|
||||
implementation(compose.components.uiToolingPreview)
|
||||
|
||||
// Bundles
|
||||
implementation(libs.bundles.kmp.common) // Coroutines, Serialization, DateTime
|
||||
@@ -92,6 +93,7 @@ kotlin {
|
||||
jvmMain.dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(libs.kotlinx.coroutines.swing)
|
||||
implementation(compose.uiTooling)
|
||||
implementation(libs.koin.core)
|
||||
implementation(project(":frontend:features:nennung-feature"))
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+145
@@ -0,0 +1,145 @@
|
||||
package components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
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
|
||||
|
||||
// Dummy-Datenklasse für Turnier-Einträge (wird später durch echtes Domain-Model ersetzt)
|
||||
data class TournamentData(
|
||||
val id: String,
|
||||
val date: String,
|
||||
val title: String,
|
||||
val location: String
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun TournamentCard(data: TournamentData) {
|
||||
OutlinedCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Left: Logo Placeholder
|
||||
Surface(
|
||||
modifier = Modifier.size(100.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
shape = MaterialTheme.shapes.medium
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text(
|
||||
"URFV\nLogo",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(24.dp))
|
||||
|
||||
// Middle: Info
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = data.title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "${data.location} ${data.date}",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "Turnier-Nr.:${data.id}",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(24.dp))
|
||||
|
||||
// Right: Actions
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = Modifier.width(200.dp)
|
||||
) {
|
||||
OutlinedButton(
|
||||
onClick = { /* TODO */ },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Ausschreibung")
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = { /* TODO */ },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Nennen")
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = { /* TODO */ },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Start- Ergebnislisten")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ToggleRow(label: String, isOnline: Boolean, isInteractive: Boolean = false) {
|
||||
Surface(
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
shape = MaterialTheme.shapes.small,
|
||||
modifier = Modifier.fillMaxWidth().height(40.dp),
|
||||
color = if (isInteractive) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceVariant
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxSize().padding(horizontal = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(label, style = MaterialTheme.typography.bodyMedium)
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
val statusColor = if (isOnline) Color(0xFF4CAF50) else Color(0xFF9E9E9E)
|
||||
Surface(
|
||||
modifier = Modifier.size(16.dp),
|
||||
shape = CircleShape,
|
||||
color = statusColor
|
||||
) {}
|
||||
|
||||
if (isInteractive) {
|
||||
Surface(
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline),
|
||||
modifier = Modifier.width(40.dp).height(24.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text(if (isOnline) "on" else "off", style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Text(
|
||||
if (isOnline) "Online" else "Offline",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
modifier = Modifier.width(40.dp),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.auth.data.AuthTokenManager
|
||||
|
||||
@Composable
|
||||
fun AuthStatusScreen(
|
||||
authTokenManager: AuthTokenManager,
|
||||
onNavigateToLogin: () -> Unit,
|
||||
onNavigateToPing: () -> Unit,
|
||||
onBackToHome: () -> Unit
|
||||
) {
|
||||
val authState by authTokenManager.authState.collectAsState()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(24.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text("Ping-Service / System Status", style = MaterialTheme.typography.headlineMedium)
|
||||
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(24.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
if (authState.isAuthenticated) {
|
||||
Text(
|
||||
"Du bist angemeldet als: ${authState.username ?: authState.userId ?: "unbekannt"}",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Button(onClick = onNavigateToPing) {
|
||||
Text("Ping-Service Tests durchführen")
|
||||
}
|
||||
OutlinedButton(onClick = {
|
||||
authTokenManager.clearToken()
|
||||
}) { Text("Abmelden") }
|
||||
}
|
||||
|
||||
} else {
|
||||
Text(
|
||||
"Du bist abgemeldet.",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.error
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Button(onClick = onNavigateToLogin) {
|
||||
Text("Login")
|
||||
}
|
||||
OutlinedButton(onClick = onNavigateToPing) {
|
||||
Text("Ping-Service (eingeschränkt testen)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
||||
OutlinedButton(onClick = onBackToHome) { Text("Zurück zur Startseite") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
package screens
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
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
|
||||
|
||||
@Composable
|
||||
fun CreateTournamentScreen(
|
||||
onBack: () -> Unit,
|
||||
onSave: () -> Unit
|
||||
) {
|
||||
var currentStep by remember { mutableStateOf(1) }
|
||||
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
// App Header
|
||||
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
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
TextButton(onClick = onBack) {
|
||||
Text("← Zurück")
|
||||
}
|
||||
Text(
|
||||
text = "Neues Turnier anlegen (Desktop Client)",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stepper / Progress Bar
|
||||
Surface(color = MaterialTheme.colorScheme.surfaceVariant, modifier = Modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp).fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceEvenly
|
||||
) {
|
||||
StepIndicator(step = 1, title = "Transfer", isActive = currentStep == 1, isCompleted = currentStep > 1)
|
||||
StepIndicator(step = 2, title = "Stammdaten", isActive = currentStep == 2, isCompleted = currentStep > 2)
|
||||
StepIndicator(step = 3, title = "Konfiguration", isActive = currentStep == 3, isCompleted = currentStep > 3)
|
||||
StepIndicator(step = 4, title = "Funktionäre", isActive = currentStep == 4, isCompleted = currentStep > 4)
|
||||
StepIndicator(step = 5, title = "Bewerbe", isActive = currentStep == 5, isCompleted = currentStep > 5)
|
||||
}
|
||||
}
|
||||
|
||||
// Wizard Content Area
|
||||
Box(modifier = Modifier.weight(1f).padding(24.dp)) {
|
||||
when (currentStep) {
|
||||
1 -> TournamentStepTransfer()
|
||||
2 -> TournamentStepStammdaten()
|
||||
3 -> TournamentStepKonfiguration()
|
||||
4 -> TournamentStepFunktionaere()
|
||||
5 -> TournamentStepBewerbe()
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom Navigation Bar
|
||||
Surface(shadowElevation = 8.dp, modifier = Modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
modifier = Modifier.padding(24.dp).fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
if (currentStep > 1) {
|
||||
OutlinedButton(onClick = { currentStep-- }) { Text("Zurück") }
|
||||
} else {
|
||||
Spacer(modifier = Modifier.width(1.dp))
|
||||
}
|
||||
|
||||
if (currentStep < 5) {
|
||||
Button(onClick = { currentStep++ }) { Text("Weiter") }
|
||||
} else {
|
||||
Button(onClick = onSave) { Text("Turnier speichern") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun StepIndicator(step: Int, title: String, isActive: Boolean, isCompleted: Boolean) {
|
||||
val color = when {
|
||||
isActive -> MaterialTheme.colorScheme.primary
|
||||
isCompleted -> MaterialTheme.colorScheme.primary.copy(alpha = 0.5f)
|
||||
else -> MaterialTheme.colorScheme.onSurface.copy(alpha = 0.3f)
|
||||
}
|
||||
val fontWeight = if (isActive) FontWeight.Bold else FontWeight.Normal
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = color,
|
||||
modifier = Modifier.size(24.dp)
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text(step.toString(), color = MaterialTheme.colorScheme.onPrimary, style = MaterialTheme.typography.labelSmall)
|
||||
}
|
||||
}
|
||||
Text(title, color = color, fontWeight = fontWeight)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TournamentStepTransfer() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(24.dp), modifier = Modifier.fillMaxWidth(0.8f)) {
|
||||
Text("Schritt 1: Transfer & Initialisierung", style = MaterialTheme.typography.headlineSmall)
|
||||
Text(
|
||||
"In diesem Schritt erschaffen wir eine separate Datenbank für dieses spezifische Turnier. " +
|
||||
"Diese Datenbank kann für den komplett isolierten Offline-Betrieb (z.B. am USB-Stick) auf andere Laptops übertragen werden.",
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth()) {
|
||||
OutlinedTextField(
|
||||
value = "",
|
||||
onValueChange = {},
|
||||
label = { Text("Turniernummer OEPS (z.B. 26128)") },
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Button(onClick = { /*TODO*/ }, modifier = Modifier.align(Alignment.CenterVertically)) {
|
||||
Text("Turnierdatenbank Initialisieren")
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
||||
|
||||
Text("Datenaustausch (OEPS / Externe Systeme)", style = MaterialTheme.typography.titleMedium)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Card(modifier = Modifier.weight(1f)) {
|
||||
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Text("ZNS / Stammdaten Import", fontWeight = FontWeight.Bold)
|
||||
Text(
|
||||
"Aktualisieren Sie die Reiter, Pferde und Funktionäre aus dem zentralen System.",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
OutlinedTextField(
|
||||
value = "",
|
||||
onValueChange = {},
|
||||
label = { Text("Pfad zur ZNS.zip") },
|
||||
modifier = Modifier.weight(1f),
|
||||
readOnly = true
|
||||
)
|
||||
Button(onClick = { /* Öffnet File Picker */ }) { Text("...") }
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
OutlinedTextField(
|
||||
value = "",
|
||||
onValueChange = {},
|
||||
label = { Text("Pfad zur AWÖ/Zucht-Datei") },
|
||||
modifier = Modifier.weight(1f),
|
||||
readOnly = true
|
||||
)
|
||||
Button(onClick = { /* Öffnet File Picker */ }) { Text("...") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Card(modifier = Modifier.weight(1f)) {
|
||||
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Text("OEPS Export", fontWeight = FontWeight.Bold)
|
||||
Text(
|
||||
"Erzeugt die xxxxx.erg Datei für die offizielle Ergebnismeldung nach dem Turnier.",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
OutlinedTextField(
|
||||
value = "",
|
||||
onValueChange = {},
|
||||
label = { Text("Ziel-Ordner für .erg Export") },
|
||||
modifier = Modifier.weight(1f),
|
||||
readOnly = true
|
||||
)
|
||||
Button(onClick = { /* Öffnet Directory Picker */ }) { Text("...") }
|
||||
}
|
||||
Button(
|
||||
onClick = { /*TODO*/ },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = false
|
||||
) { Text("Ergebnis-Export (.erg)") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
||||
|
||||
Text("Offline-Sync (USB-Stick / Lokales Netzwerk)", style = MaterialTheme.typography.titleMedium)
|
||||
Text(
|
||||
"Übertragen Sie den kompletten Turnierstand zwischen Master-Meldestelle und Richterturm-Laptops ohne Internet.",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
OutlinedTextField(
|
||||
value = "",
|
||||
onValueChange = {},
|
||||
label = { Text("Ziel-Pfad (z.B. D:/Export)") },
|
||||
modifier = Modifier.weight(1f),
|
||||
readOnly = true
|
||||
)
|
||||
Button(onClick = { /* Öffnet Directory Picker */ }) { Text("...") }
|
||||
}
|
||||
OutlinedButton(onClick = { /*TODO*/ }, modifier = Modifier.fillMaxWidth()) { Text("↑ Turnier Exportieren") }
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
OutlinedTextField(
|
||||
value = "",
|
||||
onValueChange = {},
|
||||
label = { Text("Quell-Datei (z.B. D:/turnier.db)") },
|
||||
modifier = Modifier.weight(1f),
|
||||
readOnly = true
|
||||
)
|
||||
Button(onClick = { /* Öffnet File Picker */ }) { Text("...") }
|
||||
}
|
||||
OutlinedButton(onClick = { /*TODO*/ }, modifier = Modifier.fillMaxWidth()) { Text("↓ Turnier Importieren") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TournamentStepStammdaten() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth(0.6f)) {
|
||||
Text("Schritt 2: Turnier-Stammdaten", style = MaterialTheme.typography.headlineSmall)
|
||||
|
||||
OutlinedTextField(
|
||||
value = "CSN-C NEU Neumarkt",
|
||||
onValueChange = {},
|
||||
label = { Text("Turniername") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth()) {
|
||||
OutlinedTextField(
|
||||
value = "25.04.2026",
|
||||
onValueChange = {},
|
||||
label = { Text("Datum von") },
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "25.04.2026",
|
||||
onValueChange = {},
|
||||
label = { Text("Datum bis") },
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TournamentStepKonfiguration() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth(0.6f)) {
|
||||
Text("Schritt 3: Konfiguration", style = MaterialTheme.typography.headlineSmall)
|
||||
Text("Austragungsplätze und Preisliste")
|
||||
|
||||
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text("Austragungsplätze", fontWeight = FontWeight.Bold)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(top = 8.dp)) {
|
||||
FilterChip(selected = true, onClick = {}, label = { Text("Platz 1 (Sand/Vlies 45x65m)") })
|
||||
FilterChip(selected = false, onClick = {}, label = { Text("Halle (Sand/Vlies 20x40m)") })
|
||||
FilterChip(selected = false, onClick = {}, label = { Text("+ Hinzufügen") })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TournamentStepFunktionaere() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth(0.6f)) {
|
||||
Text("Schritt 4: Team & Funktionäre", style = MaterialTheme.typography.headlineSmall)
|
||||
Text("Zuweisung von Richtern und Parcoursbauern (aus ZNS)")
|
||||
|
||||
OutlinedTextField(
|
||||
value = "Rudi Kreupl",
|
||||
onValueChange = {},
|
||||
label = { Text("Turnierbeauftragter (Suche nach Name oder ID)") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
value = "Helmut Riedler",
|
||||
onValueChange = {},
|
||||
label = { Text("Richter (Suche nach Name oder ID)") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
OutlinedTextField(
|
||||
value = "Kurt Reitetschlägerr",
|
||||
onValueChange = {},
|
||||
label = { Text("Parcoursbauchef") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TournamentStepBewerbe() {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxSize()) {
|
||||
Text("Schritt 5: Bewerbe anlegen", style = MaterialTheme.typography.headlineSmall)
|
||||
|
||||
Row(modifier = Modifier.fillMaxSize(), horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
// Left: List of Bewerbe
|
||||
Card(modifier = Modifier.weight(1f).fillMaxHeight()) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
Text("Bewerbe", fontWeight = FontWeight.Bold)
|
||||
TextButton(onClick = {}) { Text("+ Neu") }
|
||||
}
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
||||
Text("1: Pony Stilspringprüfung (60cm)", modifier = Modifier.padding(vertical = 4.dp))
|
||||
Text("2: Einlaufspringprüfung (60cm)", modifier = Modifier.padding(vertical = 4.dp))
|
||||
Text("3: Pony Stilspringprüfung (70cm)", modifier = Modifier.padding(vertical = 4.dp))
|
||||
Text("4: Einlaufspringprüfung (70cm)", modifier = Modifier.padding(vertical = 4.dp))
|
||||
Text("...", modifier = Modifier.padding(vertical = 4.dp), color = MaterialTheme.colorScheme.onSurfaceVariant)
|
||||
}
|
||||
}
|
||||
|
||||
// Right: Detail Tabs for selected Bewerb
|
||||
Card(modifier = Modifier.weight(2f).fillMaxHeight()) {
|
||||
Column {
|
||||
PrimaryTabRow(selectedTabIndex = 0) {
|
||||
Tab(selected = true, onClick = {}, text = { Text("Bewertung") })
|
||||
Tab(selected = false, onClick = {}, text = { Text("Geldpreis") })
|
||||
Tab(selected = false, onClick = {}, text = { Text("Ort/Zeit") })
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
OutlinedTextField(
|
||||
value = "2",
|
||||
onValueChange = {},
|
||||
label = { Text("Bewerb Nr.") },
|
||||
modifier = Modifier.width(100.dp)
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "Einlaufspringprüfung",
|
||||
onValueChange = {},
|
||||
label = { Text("Bezeichnung") },
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
OutlinedTextField(
|
||||
value = "60cm",
|
||||
onValueChange = {},
|
||||
label = { Text("Klasse / Höhe") },
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "§ 218",
|
||||
onValueChange = {},
|
||||
label = { Text("Richtverfahren") },
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
|
||||
Text("Abteilungen", fontWeight = FontWeight.Bold, modifier = Modifier.padding(top = 8.dp))
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Checkbox(checked = true, onCheckedChange = {})
|
||||
Text("1. Abt: lizenzfrei")
|
||||
}
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Checkbox(checked = true, onCheckedChange = {})
|
||||
Text("2. Abt: mit Lizenz")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
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.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.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.auth.data.AuthTokenManager
|
||||
import at.mocode.frontend.core.domain.PlatformType
|
||||
import at.mocode.frontend.core.domain.currentPlatform
|
||||
import components.ToggleRow
|
||||
import components.TournamentData
|
||||
|
||||
@Composable
|
||||
fun DashboardScreen(
|
||||
authTokenManager: AuthTokenManager,
|
||||
onLogout: () -> Unit,
|
||||
onCreateTournament: () -> Unit,
|
||||
onNennungOeffnen: () -> Unit = {},
|
||||
) {
|
||||
val authState by authTokenManager.authState.collectAsState()
|
||||
val scrollState = rememberScrollState()
|
||||
val isDesktop = currentPlatform() == PlatformType.DESKTOP
|
||||
|
||||
// Security Check für das Dashboard
|
||||
if (!authState.isAuthenticated) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val isAdmin = authTokenManager.isAdmin()
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
// App Header (Meldestelle Toolbar)
|
||||
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 = if (isDesktop) "Master-Meldestelle Steuerungszentrale" else if (isAdmin) "Admin-Dashboard (Web)" else "Veranstalter-Dashboard",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Angemeldet als: ${authState.username ?: "Admin"}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
TextButton(onClick = onLogout) {
|
||||
Text("Abmelden")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main Content Area
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(24.dp).verticalScroll(scrollState),
|
||||
verticalArrangement = Arrangement.spacedBy(24.dp)
|
||||
) {
|
||||
|
||||
if (isDesktop && isAdmin) {
|
||||
// DESKTOP VIEW - STEUERUNGSZENTRALE FÜR DEN ADMIN
|
||||
Button(
|
||||
onClick = onNennungOeffnen,
|
||||
modifier = Modifier.fillMaxWidth().height(64.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "📋 Nennungs-Maske öffnen",
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = onCreateTournament,
|
||||
modifier = Modifier.fillMaxWidth().height(64.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "+ neues Turnier anlegen",
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "Alle verwalteten Turniere",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
// Filters (Mockup)
|
||||
Surface(
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
shape = MaterialTheme.shapes.small,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Text("Zeitraum:", style = MaterialTheme.typography.bodyMedium)
|
||||
OutlinedTextField(
|
||||
value = "März",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(100.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
Text("bis", style = MaterialTheme.typography.bodyMedium)
|
||||
OutlinedTextField(
|
||||
value = "Dezember",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(120.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "2026",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(80.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "Bundesland",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(150.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
Button(
|
||||
onClick = {},
|
||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFFE67E22))
|
||||
) {
|
||||
Text("Anzeigen")
|
||||
}
|
||||
}
|
||||
Text("Zusätzliche Filter auf Suchergebnisse:", style = MaterialTheme.typography.bodyMedium)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
OutlinedTextField(
|
||||
value = "Veranstalter (Verein)",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(180.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "Ort",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(120.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "Sparte",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(120.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
OutlinedTextField(
|
||||
value = "Turnierart",
|
||||
onValueChange = {},
|
||||
modifier = Modifier.width(120.dp).height(48.dp),
|
||||
singleLine = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Desktop Tournament Card (Steuerungszentrale Ansicht)
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
border = BorderStroke(2.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp).fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier.size(120.dp),
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
shape = MaterialTheme.shapes.small
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center) {
|
||||
Text("NEUMARKT\nLOGO", textAlign = TextAlign.Center, style = MaterialTheme.typography.bodySmall)
|
||||
}
|
||||
}
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text("CDN-C NEU CDNP-C", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
|
||||
Text(
|
||||
"Veranstalter: URFV Neumarkt",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Text("NEUMARKT/M., OÖ 26. APRIL 2026", style = MaterialTheme.typography.bodyMedium)
|
||||
Text("Turnier-Nr.: 26129", style = MaterialTheme.typography.bodyMedium)
|
||||
}
|
||||
}
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.width(300.dp)) {
|
||||
var meldestelleOnline by remember { mutableStateOf(true) }
|
||||
var nennsystemOnline by remember { mutableStateOf(true) }
|
||||
var startlisteOnline by remember { mutableStateOf(true) }
|
||||
ToggleRow("Meldestelle-Desktop online", isOnline = meldestelleOnline, isInteractive = false)
|
||||
ToggleRow("Nennsystem online", isOnline = nennsystemOnline, isInteractive = true)
|
||||
ToggleRow("Start- Ergebnislisten online", isOnline = startlisteOnline, isInteractive = true)
|
||||
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
OutlinedButton(
|
||||
onClick = { /* Link kopieren oder Email Dialog öffnen */ },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Veranstalter-Link senden")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (isDesktop && !isAdmin) {
|
||||
// DESKTOP VIEW - VERANSTALTER (Meldestelle am Platz)
|
||||
Text(
|
||||
"Willkommen in der Meldestellen-Software für Turnier 26129",
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
Text("Bitte initialisieren Sie die lokale Datenbank oder importieren Sie einen Stand vom USB-Stick.")
|
||||
Spacer(Modifier.height(16.dp))
|
||||
Button(onClick = onCreateTournament) {
|
||||
Text("Turnier initialisieren / Importieren")
|
||||
}
|
||||
} else if (!isDesktop && isAdmin) {
|
||||
// WEB VIEW - ADMIN PORTAL
|
||||
Text(
|
||||
text = "Alle verwalteten Turniere",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp).fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
"CDN-C NEU CDNP-C Neumarkt",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text("Veranstalter: URFV Neumarkt", style = MaterialTheme.typography.bodyMedium)
|
||||
Text("Nr: 26129 | 26. APRIL 2026", style = MaterialTheme.typography.bodyMedium)
|
||||
}
|
||||
Button(onClick = { /* TODO: Download Trigger for Master App */ }) {
|
||||
Text("Master-Desktop-App herunterladen")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// WEB VIEW - VERANSTALTER PORTAL
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.secondaryContainer)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(24.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Text(
|
||||
"Aktuelles Turnier: CDN-C NEU CDNP-C Neumarkt",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
)
|
||||
Text(
|
||||
"Turnier-Nr.: 26129 | 26. APRIL 2026",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
Text(
|
||||
"Bitte laden Sie die Desktop-Anwendung herunter, um die Meldestelle lokal an Ihrem Turnierplatz zu betreiben.",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
)
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
) {
|
||||
Button(onClick = { /* TODO: Download Trigger for generic app */ }) {
|
||||
Text("Meldestelle-App herunterladen (.exe)")
|
||||
}
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline)
|
||||
) {
|
||||
Text(
|
||||
"Ihr Aktivierungs-Code: X7F9-K2M4",
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Turnier-Historie
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Turnier-Historie (Archiv)", style = MaterialTheme.typography.headlineSmall)
|
||||
|
||||
val turniere = listOf(
|
||||
TournamentData(
|
||||
id = "25044",
|
||||
date = "24. APRIL 2025",
|
||||
title = "CSN-C CSNP-C Neumarkt",
|
||||
location = "NEUMARKT/M., OÖ"
|
||||
),
|
||||
TournamentData(
|
||||
id = "24012",
|
||||
date = "28. APRIL 2024",
|
||||
title = "CDN-C CDNP-C Neumarkt",
|
||||
location = "NEUMARKT/M., OÖ"
|
||||
)
|
||||
)
|
||||
|
||||
turniere.forEach { turnier ->
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp).fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column {
|
||||
Text(turnier.title, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
|
||||
Text("Nr: ${turnier.id} | ${turnier.date}", style = MaterialTheme.typography.bodyMedium)
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
OutlinedButton(onClick = { /* TODO: Open PDF Archive */ }) {
|
||||
Text("Ergebnislisten (PDF)")
|
||||
}
|
||||
OutlinedButton(onClick = { /* TODO: Open Stats */ }) {
|
||||
Text("Statistiken")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import kotlinx.browser.window
|
||||
import kotlinx.coroutines.await
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.w3c.fetch.RequestInit
|
||||
|
||||
private val AppJson = Json { ignoreUnknownKeys = true }
|
||||
|
||||
@@ -14,7 +15,7 @@ data class AppConfig(
|
||||
suspend fun loadAppConfig(): AppConfig {
|
||||
return try {
|
||||
// ?_nocache erzwingt einen SW-bypassing Request (SW sieht andere URL → Cache-Miss → Netzwerk)
|
||||
val response = window.fetch("/config.json?_nocache=1").await()
|
||||
val response = window.fetch("/config.json?_nocache=1", RequestInit()).await()
|
||||
if (!response.ok) {
|
||||
console.warn("[Config] Failed to load config.json, falling back to globalThis")
|
||||
return fallbackFromGlobal()
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import at.mocode.frontend.core.designsystem.theme.AppTheme
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun LandingPagePreview() {
|
||||
AppTheme {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(Dimens.SpacingM),
|
||||
verticalArrangement = Arrangement.spacedBy(Dimens.SpacingM)
|
||||
) {
|
||||
Text(
|
||||
text = "Landing Page Preview",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Text(
|
||||
text = "Dies ist eine Live-Vorschau. Du kannst hier deine UI-Komponenten isoliert bauen und sofort sehen, wie sie aussehen. Ändere Text, Farben oder Layouts im Code – die Preview aktualisiert sich automatisch in IntelliJ (Hot-Reload).",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground
|
||||
)
|
||||
Button(onClick = {}) {
|
||||
Text("Ein Button im Primary-Design")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback für IntelliJ, falls das Compose Plugin die Preview nicht erkennt
|
||||
fun main() = application {
|
||||
Window(onCloseRequest = ::exitApplication, title = "Design Preview Sandbox") {
|
||||
LandingPagePreview()
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
# === FRONTEND & KMP CORE ===
|
||||
# ==============================================================================
|
||||
# Kotlin & Tooling
|
||||
kotlin = "2.3.0"
|
||||
kotlin = "2.3.20"
|
||||
ksp = "2.3.4"
|
||||
|
||||
# KotlinX (Core Libraries)
|
||||
@@ -17,14 +17,14 @@ kotlinx-datetime = "0.7.1"
|
||||
|
||||
# UI: Compose Multiplatform
|
||||
# Aligned with Kotlin 2.3.0
|
||||
composeMultiplatform = "1.10.0"
|
||||
composeMultiplatform = "1.11.0-alpha04"
|
||||
composeHotReload = "1.0.0"
|
||||
androidx-lifecycle = "2.9.6"
|
||||
uiDesktop = "1.7.0"
|
||||
|
||||
# Network: Ktor (Client & Server)
|
||||
# Align with Kotlin 2.3.0 – upgrade to 3.4.0 (runtime OpenAPI + lifecycle improvements)
|
||||
ktor = "3.4.0"
|
||||
ktor = "3.4.1"
|
||||
|
||||
# Dependency Injection
|
||||
koin = "4.1.1"
|
||||
|
||||
+326
-143
@@ -95,6 +95,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1"
|
||||
integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==
|
||||
|
||||
"@noble/hashes@1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426"
|
||||
integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
@@ -116,6 +121,129 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@peculiar/asn1-cms@^2.6.0", "@peculiar/asn1-cms@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz#cb5445c1bad9197d176073bf142a5c035b460640"
|
||||
integrity sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
"@peculiar/asn1-x509-attr" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-csr@^2.6.0":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz#9629d403bc5a61254f28ed0b90e99cee61c0e8be"
|
||||
integrity sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-ecc@^2.6.0":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz#d29c4af671508a9934edc78e7c9419fbf7bc9870"
|
||||
integrity sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-pfx@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz#75cddd14d43ef875109e91ea150377d679c8fbc1"
|
||||
integrity sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==
|
||||
dependencies:
|
||||
"@peculiar/asn1-cms" "^2.6.1"
|
||||
"@peculiar/asn1-pkcs8" "^2.6.1"
|
||||
"@peculiar/asn1-rsa" "^2.6.1"
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-pkcs8@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz#bd56b4bb9e8a3702369049713a89134c87c6931a"
|
||||
integrity sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-pkcs9@^2.6.0":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz#ddc5222952f25b59a0562a6f8cabdb72f586a496"
|
||||
integrity sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==
|
||||
dependencies:
|
||||
"@peculiar/asn1-cms" "^2.6.1"
|
||||
"@peculiar/asn1-pfx" "^2.6.1"
|
||||
"@peculiar/asn1-pkcs8" "^2.6.1"
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
"@peculiar/asn1-x509-attr" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-rsa@^2.6.0", "@peculiar/asn1-rsa@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz#2cdf9f9ea6d6fdbaae214b9fed6de0534b654437"
|
||||
integrity sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-schema@^2.6.0":
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz#0dca1601d5b0fed2a72fed7a5f1d0d7dbe3a6f82"
|
||||
integrity sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==
|
||||
dependencies:
|
||||
asn1js "^3.0.6"
|
||||
pvtsutils "^1.3.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-x509-attr@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz#6425008b8099476010aace5b8ae9f9cbc41db0ab"
|
||||
integrity sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.1"
|
||||
asn1js "^3.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/asn1-x509@^2.6.0", "@peculiar/asn1-x509@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz#4e8995659e16178e0e90fe90519aa269045af262"
|
||||
integrity sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==
|
||||
dependencies:
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
asn1js "^3.0.6"
|
||||
pvtsutils "^1.3.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
"@peculiar/x509@^1.14.2":
|
||||
version "1.14.3"
|
||||
resolved "https://registry.yarnpkg.com/@peculiar/x509/-/x509-1.14.3.tgz#2c44c2b89474346afec38a0c2803ec4fb8ce959e"
|
||||
integrity sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==
|
||||
dependencies:
|
||||
"@peculiar/asn1-cms" "^2.6.0"
|
||||
"@peculiar/asn1-csr" "^2.6.0"
|
||||
"@peculiar/asn1-ecc" "^2.6.0"
|
||||
"@peculiar/asn1-pkcs9" "^2.6.0"
|
||||
"@peculiar/asn1-rsa" "^2.6.0"
|
||||
"@peculiar/asn1-schema" "^2.6.0"
|
||||
"@peculiar/asn1-x509" "^2.6.0"
|
||||
pvtsutils "^1.3.6"
|
||||
reflect-metadata "^0.2.2"
|
||||
tslib "^2.8.1"
|
||||
tsyringe "^4.10.0"
|
||||
|
||||
"@sqlite.org/sqlite-wasm@3.51.1-build2":
|
||||
version "3.51.1-build2"
|
||||
resolved "https://registry.yarnpkg.com/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.51.1-build2.tgz#822497fdd05cbee3b1e8209aa46ffe1bafc70dbb"
|
||||
@@ -201,15 +329,15 @@
|
||||
"@types/express-serve-static-core" "^5.0.0"
|
||||
"@types/serve-static" "*"
|
||||
|
||||
"@types/express@^4.17.21":
|
||||
version "4.17.23"
|
||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.23.tgz#35af3193c640bfd4d7fe77191cd0ed411a433bef"
|
||||
integrity sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==
|
||||
"@types/express@^4.17.25":
|
||||
version "4.17.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b"
|
||||
integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==
|
||||
dependencies:
|
||||
"@types/body-parser" "*"
|
||||
"@types/express-serve-static-core" "^4.17.33"
|
||||
"@types/qs" "*"
|
||||
"@types/serve-static" "*"
|
||||
"@types/serve-static" "^1"
|
||||
|
||||
"@types/http-errors@*":
|
||||
version "2.0.5"
|
||||
@@ -233,13 +361,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
|
||||
integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
|
||||
|
||||
"@types/node-forge@^1.3.0":
|
||||
version "1.3.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.14.tgz#006c2616ccd65550560c2757d8472eb6d3ecea0b"
|
||||
integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "24.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.3.1.tgz#b0a3fb2afed0ef98e8d7f06d46ef6349047709f3"
|
||||
@@ -270,6 +391,14 @@
|
||||
"@types/mime" "^1"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/send@<1":
|
||||
version "0.17.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25"
|
||||
integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==
|
||||
dependencies:
|
||||
"@types/mime" "^1"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/serve-index@^1.9.4":
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898"
|
||||
@@ -286,6 +415,15 @@
|
||||
"@types/node" "*"
|
||||
"@types/send" "*"
|
||||
|
||||
"@types/serve-static@^1":
|
||||
version "1.15.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee"
|
||||
integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==
|
||||
dependencies:
|
||||
"@types/http-errors" "*"
|
||||
"@types/node" "*"
|
||||
"@types/send" "<1"
|
||||
|
||||
"@types/sockjs@^0.3.36":
|
||||
version "0.3.36"
|
||||
resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535"
|
||||
@@ -506,6 +644,15 @@ array-flatten@1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
|
||||
|
||||
asn1js@^3.0.6:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.7.tgz#15f1f2f59e60f80d5b43ef14047a294a969f824f"
|
||||
integrity sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==
|
||||
dependencies:
|
||||
pvtsutils "^1.3.6"
|
||||
pvutils "^1.1.3"
|
||||
tslib "^2.8.1"
|
||||
|
||||
batch@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
|
||||
@@ -516,23 +663,23 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
||||
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
||||
|
||||
body-parser@1.20.3:
|
||||
version "1.20.3"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6"
|
||||
integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==
|
||||
body-parser@~1.20.3:
|
||||
version "1.20.4"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f"
|
||||
integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==
|
||||
dependencies:
|
||||
bytes "3.1.2"
|
||||
bytes "~3.1.2"
|
||||
content-type "~1.0.5"
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
destroy "1.2.0"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
on-finished "2.4.1"
|
||||
qs "6.13.0"
|
||||
raw-body "2.5.2"
|
||||
destroy "~1.2.0"
|
||||
http-errors "~2.0.1"
|
||||
iconv-lite "~0.4.24"
|
||||
on-finished "~2.4.1"
|
||||
qs "~6.14.0"
|
||||
raw-body "~2.5.3"
|
||||
type-is "~1.6.18"
|
||||
unpipe "1.0.0"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
bonjour-service@^1.2.1:
|
||||
version "1.3.0"
|
||||
@@ -571,11 +718,16 @@ bundle-name@^4.1.0:
|
||||
dependencies:
|
||||
run-applescript "^7.0.0"
|
||||
|
||||
bytes@3.1.2:
|
||||
bytes@3.1.2, bytes@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
|
||||
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
|
||||
|
||||
bytestreamjs@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bytestreamjs/-/bytestreamjs-2.0.1.tgz#a32947c7ce389a6fa11a09a9a563d0a45889535e"
|
||||
integrity sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==
|
||||
|
||||
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
|
||||
@@ -648,7 +800,7 @@ compressible@~2.0.18:
|
||||
dependencies:
|
||||
mime-db ">= 1.43.0 < 2"
|
||||
|
||||
compression@^1.7.4:
|
||||
compression@^1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79"
|
||||
integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==
|
||||
@@ -666,7 +818,7 @@ connect-history-api-fallback@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
|
||||
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
|
||||
|
||||
content-disposition@0.5.4:
|
||||
content-disposition@~0.5.4:
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
||||
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
|
||||
@@ -678,15 +830,15 @@ content-type@~1.0.4, content-type@~1.0.5:
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
||||
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
|
||||
|
||||
cookie-signature@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
|
||||
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
|
||||
cookie-signature@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454"
|
||||
integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==
|
||||
|
||||
cookie@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9"
|
||||
integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
|
||||
cookie@~0.7.1:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7"
|
||||
integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
|
||||
|
||||
copy-webpack-plugin@11.0.0:
|
||||
version "11.0.0"
|
||||
@@ -746,7 +898,7 @@ define-lazy-prop@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f"
|
||||
integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==
|
||||
|
||||
depd@2.0.0:
|
||||
depd@2.0.0, depd@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
@@ -756,7 +908,7 @@ depd@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
|
||||
|
||||
destroy@1.2.0:
|
||||
destroy@1.2.0, destroy@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
||||
@@ -799,11 +951,6 @@ electron-to-chromium@^1.5.211:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.215.tgz#200c8d69b1270af6126837b6b1f95077c3a347b1"
|
||||
integrity sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==
|
||||
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
|
||||
|
||||
encodeurl@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
|
||||
@@ -894,39 +1041,39 @@ events@^3.2.0:
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
|
||||
express@^4.21.2:
|
||||
version "4.21.2"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32"
|
||||
integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==
|
||||
express@^4.22.1:
|
||||
version "4.22.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069"
|
||||
integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==
|
||||
dependencies:
|
||||
accepts "~1.3.8"
|
||||
array-flatten "1.1.1"
|
||||
body-parser "1.20.3"
|
||||
content-disposition "0.5.4"
|
||||
body-parser "~1.20.3"
|
||||
content-disposition "~0.5.4"
|
||||
content-type "~1.0.4"
|
||||
cookie "0.7.1"
|
||||
cookie-signature "1.0.6"
|
||||
cookie "~0.7.1"
|
||||
cookie-signature "~1.0.6"
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
finalhandler "1.3.1"
|
||||
fresh "0.5.2"
|
||||
http-errors "2.0.0"
|
||||
finalhandler "~1.3.1"
|
||||
fresh "~0.5.2"
|
||||
http-errors "~2.0.0"
|
||||
merge-descriptors "1.0.3"
|
||||
methods "~1.1.2"
|
||||
on-finished "2.4.1"
|
||||
on-finished "~2.4.1"
|
||||
parseurl "~1.3.3"
|
||||
path-to-regexp "0.1.12"
|
||||
path-to-regexp "~0.1.12"
|
||||
proxy-addr "~2.0.7"
|
||||
qs "6.13.0"
|
||||
qs "~6.14.0"
|
||||
range-parser "~1.2.1"
|
||||
safe-buffer "5.2.1"
|
||||
send "0.19.0"
|
||||
serve-static "1.16.2"
|
||||
send "~0.19.0"
|
||||
serve-static "~1.16.2"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "2.0.1"
|
||||
statuses "~2.0.1"
|
||||
type-is "~1.6.18"
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
@@ -978,17 +1125,17 @@ fill-range@^7.1.1:
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
finalhandler@1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019"
|
||||
integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==
|
||||
finalhandler@~1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88"
|
||||
integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
on-finished "2.4.1"
|
||||
on-finished "~2.4.1"
|
||||
parseurl "~1.3.3"
|
||||
statuses "2.0.1"
|
||||
statuses "~2.0.2"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
find-up@^4.0.0:
|
||||
@@ -1019,7 +1166,7 @@ forwarded@0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
||||
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||
|
||||
fresh@0.5.2:
|
||||
fresh@~0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
|
||||
@@ -1140,17 +1287,6 @@ http-deceiver@^1.2.7:
|
||||
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
|
||||
integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==
|
||||
|
||||
http-errors@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
|
||||
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
|
||||
dependencies:
|
||||
depd "2.0.0"
|
||||
inherits "2.0.4"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "2.0.1"
|
||||
toidentifier "1.0.1"
|
||||
|
||||
http-errors@~1.6.2:
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
|
||||
@@ -1161,6 +1297,17 @@ http-errors@~1.6.2:
|
||||
setprototypeof "1.1.0"
|
||||
statuses ">= 1.4.0 < 2"
|
||||
|
||||
http-errors@~2.0.0, http-errors@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b"
|
||||
integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==
|
||||
dependencies:
|
||||
depd "~2.0.0"
|
||||
inherits "~2.0.4"
|
||||
setprototypeof "~1.2.0"
|
||||
statuses "~2.0.2"
|
||||
toidentifier "~1.0.1"
|
||||
|
||||
http-parser-js@>=0.5.1:
|
||||
version "0.5.10"
|
||||
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.10.tgz#b3277bd6d7ed5588e20ea73bf724fcbe44609075"
|
||||
@@ -1191,13 +1338,6 @@ hyperdyperid@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b"
|
||||
integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@^0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
||||
@@ -1205,6 +1345,13 @@ iconv-lite@^0.6.3:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
iconv-lite@~0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
ignore@^5.2.4:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
|
||||
@@ -1223,7 +1370,7 @@ inherits@2.0.3:
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
|
||||
|
||||
inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
|
||||
inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@@ -1493,11 +1640,6 @@ neo-async@^2.6.2:
|
||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||
|
||||
node-forge@^1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
|
||||
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
|
||||
|
||||
node-releases@^2.0.19:
|
||||
version "2.0.20"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.20.tgz#e26bb79dbdd1e64a146df389c699014c611cbc27"
|
||||
@@ -1518,7 +1660,7 @@ obuf@^1.0.0, obuf@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
|
||||
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
|
||||
|
||||
on-finished@2.4.1, on-finished@^2.4.1:
|
||||
on-finished@^2.4.1, on-finished@~2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
||||
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
|
||||
@@ -1588,7 +1730,7 @@ path-parse@^1.0.7:
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
path-to-regexp@0.1.12:
|
||||
path-to-regexp@~0.1.12:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7"
|
||||
integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==
|
||||
@@ -1615,6 +1757,18 @@ pkg-dir@^4.2.0:
|
||||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
pkijs@^3.3.3:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-3.4.0.tgz#d9164def30ff6d97be2d88966d5e36192499ca9c"
|
||||
integrity sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==
|
||||
dependencies:
|
||||
"@noble/hashes" "1.4.0"
|
||||
asn1js "^3.0.6"
|
||||
bytestreamjs "^2.0.1"
|
||||
pvtsutils "^1.3.6"
|
||||
pvutils "^1.1.3"
|
||||
tslib "^2.8.1"
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
@@ -1628,12 +1782,24 @@ proxy-addr@~2.0.7:
|
||||
forwarded "0.2.0"
|
||||
ipaddr.js "1.9.1"
|
||||
|
||||
qs@6.13.0:
|
||||
version "6.13.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
|
||||
integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
|
||||
pvtsutils@^1.3.6:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.6.tgz#ec46e34db7422b9e4fdc5490578c1883657d6001"
|
||||
integrity sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==
|
||||
dependencies:
|
||||
side-channel "^1.0.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
pvutils@^1.1.3:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.5.tgz#84b0dea4a5d670249aa9800511804ee0b7c2809c"
|
||||
integrity sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==
|
||||
|
||||
qs@~6.14.0:
|
||||
version "6.14.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.2.tgz#b5634cf9d9ad9898e31fba3504e866e8efb6798c"
|
||||
integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==
|
||||
dependencies:
|
||||
side-channel "^1.1.0"
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
@@ -1652,15 +1818,15 @@ range-parser@^1.2.1, range-parser@~1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||
|
||||
raw-body@2.5.2:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
|
||||
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
|
||||
raw-body@~2.5.3:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2"
|
||||
integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==
|
||||
dependencies:
|
||||
bytes "3.1.2"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
bytes "~3.1.2"
|
||||
http-errors "~2.0.1"
|
||||
iconv-lite "~0.4.24"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
readable-stream@^2.0.1:
|
||||
version "2.3.8"
|
||||
@@ -1698,6 +1864,11 @@ rechoir@^0.8.0:
|
||||
dependencies:
|
||||
resolve "^1.20.0"
|
||||
|
||||
reflect-metadata@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b"
|
||||
integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
@@ -1781,32 +1952,32 @@ select-hose@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==
|
||||
|
||||
selfsigned@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0"
|
||||
integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==
|
||||
selfsigned@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-5.5.0.tgz#4c9ab7c7c9f35f18fb6a9882c253eb0e6bd6557b"
|
||||
integrity sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==
|
||||
dependencies:
|
||||
"@types/node-forge" "^1.3.0"
|
||||
node-forge "^1"
|
||||
"@peculiar/x509" "^1.14.2"
|
||||
pkijs "^3.3.3"
|
||||
|
||||
send@0.19.0:
|
||||
version "0.19.0"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8"
|
||||
integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==
|
||||
send@~0.19.0, send@~0.19.1:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29"
|
||||
integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==
|
||||
dependencies:
|
||||
debug "2.6.9"
|
||||
depd "2.0.0"
|
||||
destroy "1.2.0"
|
||||
encodeurl "~1.0.2"
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
etag "~1.8.1"
|
||||
fresh "0.5.2"
|
||||
http-errors "2.0.0"
|
||||
fresh "~0.5.2"
|
||||
http-errors "~2.0.1"
|
||||
mime "1.6.0"
|
||||
ms "2.1.3"
|
||||
on-finished "2.4.1"
|
||||
on-finished "~2.4.1"
|
||||
range-parser "~1.2.1"
|
||||
statuses "2.0.1"
|
||||
statuses "~2.0.2"
|
||||
|
||||
serialize-javascript@^6.0.0, serialize-javascript@^6.0.2:
|
||||
version "6.0.2"
|
||||
@@ -1828,22 +1999,22 @@ serve-index@^1.9.1:
|
||||
mime-types "~2.1.17"
|
||||
parseurl "~1.3.2"
|
||||
|
||||
serve-static@1.16.2:
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296"
|
||||
integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==
|
||||
serve-static@~1.16.2:
|
||||
version "1.16.3"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9"
|
||||
integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==
|
||||
dependencies:
|
||||
encodeurl "~2.0.0"
|
||||
escape-html "~1.0.3"
|
||||
parseurl "~1.3.3"
|
||||
send "0.19.0"
|
||||
send "~0.19.1"
|
||||
|
||||
setprototypeof@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
|
||||
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
setprototypeof@1.2.0, setprototypeof@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
|
||||
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
|
||||
@@ -1901,7 +2072,7 @@ side-channel-weakmap@^1.0.2:
|
||||
object-inspect "^1.13.3"
|
||||
side-channel-map "^1.0.1"
|
||||
|
||||
side-channel@^1.0.6:
|
||||
side-channel@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
|
||||
integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
|
||||
@@ -1975,16 +2146,16 @@ spdy@^4.0.2:
|
||||
select-hose "^2.0.0"
|
||||
spdy-transport "^3.0.0"
|
||||
|
||||
statuses@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
"statuses@>= 1.4.0 < 2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
|
||||
|
||||
statuses@~2.0.1, statuses@~2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382"
|
||||
integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
@@ -2054,7 +2225,7 @@ to-regex-range@^5.0.1:
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
toidentifier@1.0.1:
|
||||
toidentifier@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||
@@ -2064,11 +2235,23 @@ tree-dump@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.1.0.tgz#ab29129169dc46004414f5a9d4a3c6e89f13e8a4"
|
||||
integrity sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==
|
||||
|
||||
tslib@^2.0.0:
|
||||
tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.8.1:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
|
||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
|
||||
tsyringe@^4.10.0:
|
||||
version "4.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tsyringe/-/tsyringe-4.10.0.tgz#d0c95815d584464214060285eaaadd94aa03299c"
|
||||
integrity sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==
|
||||
dependencies:
|
||||
tslib "^1.9.3"
|
||||
|
||||
type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
@@ -2082,7 +2265,7 @@ undici-types@~7.10.0:
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350"
|
||||
integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==
|
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
|
||||
@@ -2161,14 +2344,14 @@ webpack-dev-middleware@^7.4.2:
|
||||
range-parser "^1.2.1"
|
||||
schema-utils "^4.0.0"
|
||||
|
||||
webpack-dev-server@5.2.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz#96a143d50c58fef0c79107e61df911728d7ceb39"
|
||||
integrity sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==
|
||||
webpack-dev-server@5.2.3:
|
||||
version "5.2.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz#7f36a78be7ac88833fd87757edee31469a9e47d3"
|
||||
integrity sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==
|
||||
dependencies:
|
||||
"@types/bonjour" "^3.5.13"
|
||||
"@types/connect-history-api-fallback" "^1.5.4"
|
||||
"@types/express" "^4.17.21"
|
||||
"@types/express" "^4.17.25"
|
||||
"@types/express-serve-static-core" "^4.17.21"
|
||||
"@types/serve-index" "^1.9.4"
|
||||
"@types/serve-static" "^1.15.5"
|
||||
@@ -2178,9 +2361,9 @@ webpack-dev-server@5.2.2:
|
||||
bonjour-service "^1.2.1"
|
||||
chokidar "^3.6.0"
|
||||
colorette "^2.0.10"
|
||||
compression "^1.7.4"
|
||||
compression "^1.8.1"
|
||||
connect-history-api-fallback "^2.0.0"
|
||||
express "^4.21.2"
|
||||
express "^4.22.1"
|
||||
graceful-fs "^4.2.6"
|
||||
http-proxy-middleware "^2.0.9"
|
||||
ipaddr.js "^2.1.0"
|
||||
@@ -2188,7 +2371,7 @@ webpack-dev-server@5.2.2:
|
||||
open "^10.0.3"
|
||||
p-retry "^6.2.0"
|
||||
schema-utils "^4.2.0"
|
||||
selfsigned "^2.4.1"
|
||||
selfsigned "^5.5.0"
|
||||
serve-index "^1.9.1"
|
||||
sockjs "^0.3.24"
|
||||
spdy "^4.0.2"
|
||||
|
||||
Reference in New Issue
Block a user