chore(docs, design-system, ping-service): integrate SQLDelight with KMP, refine design-system components, and enhance logging
- Added a comprehensive guide for SQLDelight integration in Kotlin Multiplatform, covering setup for Android, iOS, desktop, and web platforms. - Introduced `DashboardCard` and `DenseButton` to the design system, focusing on enterprise-grade usability and visual consistency. - Enhanced `PingViewModel` with structured logging (`LogEntry`) functionality for better debugging and traceability across API calls. - Updated `AppTheme` with a refined color palette, typography, and shapes to align with enterprise UI standards. - Extended Koin integration and modularized database setup for smoother dependency injection and code reuse.
This commit is contained in:
+44
@@ -0,0 +1,44 @@
|
||||
package at.mocode.frontend.core.designsystem.components
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
|
||||
/**
|
||||
* Ein kompakter Button für unsere High-Density UI.
|
||||
*
|
||||
* Warum ein eigener Button?
|
||||
* Der Standard Material3 Button ist sehr hoch (40dp+) und hat viel Padding.
|
||||
* Das verschwendet Platz in Tabellen oder Toolbars.
|
||||
* Unser 'DenseButton' ist fix 32dp hoch- und hat weniger Innenabstand.
|
||||
*/
|
||||
@Composable
|
||||
fun DenseButton(
|
||||
text: String,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
containerColor: Color = MaterialTheme.colorScheme.primary
|
||||
) {
|
||||
Button(
|
||||
onClick = onClick,
|
||||
enabled = enabled,
|
||||
modifier = modifier.height(32.dp), // Fixe, kompakte Höhe
|
||||
shape = MaterialTheme.shapes.small, // Nutzt unsere 4dp Rundung
|
||||
colors = ButtonDefaults.buttonColors(containerColor = containerColor),
|
||||
contentPadding = PaddingValues(horizontal = Dimens.SpacingM, vertical = 0.dp) // Wenig Padding
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.labelMedium // Kleinere Schrift
|
||||
)
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package at.mocode.frontend.core.designsystem.components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import at.mocode.frontend.core.designsystem.theme.Dimens
|
||||
|
||||
/**
|
||||
* Eine flache, umrandete Card für Dashboards.
|
||||
*
|
||||
* Warum?
|
||||
* Standard Cards haben oft Schatten (Elevation), was bei vielen Cards unruhig wirkt.
|
||||
* Im Enterprise-Kontext sind flache Cards mit dünnem Border (1px) oft sauberer.
|
||||
*/
|
||||
@Composable
|
||||
fun DashboardCard(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier,
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface
|
||||
),
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant), // Dünner Rahmen
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp) // Kein Schatten
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(Dimens.SpacingS) // Kompaktes Padding innen
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
-31
@@ -3,48 +3,104 @@ 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.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.
|
||||
|
||||
// Define custom colors for the app
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Color(0xFF1976D2),
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFFBBDEFB),
|
||||
onPrimaryContainer = Color(0xFF0D47A1),
|
||||
secondary = Color(0xFF03DAC6),
|
||||
onSecondary = Color.Black,
|
||||
tertiary = Color(0xFF03A9F4),
|
||||
background = Color(0xFFFAFAFA),
|
||||
surface = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onSurface = Color(0xFF1C1B1F)
|
||||
primary = Color(0xFF0052CC), // Enterprise Blue (stark)
|
||||
onPrimary = Color.White,
|
||||
primaryContainer = Color(0xFFDEEBFF),
|
||||
onPrimaryContainer = Color(0xFF0052CC),
|
||||
|
||||
secondary = Color(0xFF2684FF), // Helleres Blau für Akzente
|
||||
onSecondary = Color.White,
|
||||
|
||||
background = Color(0xFFF4F5F7), // Helles Grau (nicht hartes Weiß)
|
||||
surface = Color.White,
|
||||
onBackground = Color(0xFF172B4D), // Fast Schwarz (besser lesbar als #000)
|
||||
onSurface = Color(0xFF172B4D),
|
||||
|
||||
error = Color(0xFFDE350B),
|
||||
onError = Color.White
|
||||
)
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Color(0xFF90CAF9),
|
||||
onPrimary = Color(0xFF0D47A1),
|
||||
primaryContainer = Color(0xFF1565C0),
|
||||
onPrimaryContainer = Color(0xFFBBDEFB),
|
||||
secondary = Color(0xFF03DAC6),
|
||||
onSecondary = Color.Black,
|
||||
tertiary = Color(0xFF03A9F4),
|
||||
background = Color(0xFF121212),
|
||||
surface = Color(0xFF1E1E1E),
|
||||
onBackground = Color(0xFFE0E0E0),
|
||||
onSurface = Color(0xFFE0E0E0)
|
||||
primary = Color(0xFF4C9AFF), // Helleres Blau auf Dunkel
|
||||
onPrimary = Color(0xFF091E42),
|
||||
primaryContainer = Color(0xFF0052CC),
|
||||
onPrimaryContainer = Color.White,
|
||||
|
||||
secondary = Color(0xFF2684FF),
|
||||
onSecondary = Color.White,
|
||||
|
||||
background = Color(0xFF1E1E1E), // Dunkles Grau (angenehmer als #000)
|
||||
surface = Color(0xFF2C2C2C), // Panels heben sich leicht ab
|
||||
onBackground = Color(0xFFEBECF0),
|
||||
onSurface = Color(0xFFEBECF0),
|
||||
|
||||
error = Color(0xFFFF5630),
|
||||
onError = Color.Black
|
||||
)
|
||||
|
||||
// --- 2. Formen (Shapes) ---
|
||||
// Enterprise Apps nutzen oft weniger Rundung als Consumer Apps (seriöser).
|
||||
private val AppShapes = Shapes(
|
||||
small = RoundedCornerShape(Dimens.CornerRadiusS), // Buttons, Inputs
|
||||
medium = RoundedCornerShape(Dimens.CornerRadiusM), // Cards, Dialogs
|
||||
large = RoundedCornerShape(Dimens.CornerRadiusM)
|
||||
)
|
||||
|
||||
// --- 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
|
||||
)
|
||||
)
|
||||
|
||||
@Suppress("unused")
|
||||
@Composable
|
||||
fun AppTheme(
|
||||
darkTheme: Boolean = false, // For now, we'll default to light theme
|
||||
content: @Composable () -> Unit
|
||||
darkTheme: Boolean = false, // Kann später via Settings gesteuert werden
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
|
||||
val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
content = content
|
||||
)
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
shapes = AppShapes,
|
||||
typography = AppTypography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package at.mocode.frontend.core.designsystem.theme
|
||||
|
||||
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.
|
||||
* Wenn wir den Abstand global ändern wollen, machen wir das nur hier.
|
||||
*/
|
||||
object Dimens {
|
||||
// Spacing (Abstände)
|
||||
val SpacingXS = 4.dp // Sehr eng (für Tabellen, dichte Listen)
|
||||
val SpacingS = 8.dp // Standard Abstand zwischen Elementen
|
||||
val SpacingM = 16.dp // Abstand für Sektionen
|
||||
val SpacingL = 24.dp // Außenabstand für Screens
|
||||
|
||||
// Sizes (Größen)
|
||||
val IconSizeS = 16.dp
|
||||
val IconSizeM = 24.dp
|
||||
|
||||
// Borders
|
||||
val BorderThin = 1.dp
|
||||
|
||||
// Corner Radius (Ecken)
|
||||
val CornerRadiusS = 4.dp // Leicht abgerundet (Enterprise Look)
|
||||
val CornerRadiusM = 8.dp
|
||||
}
|
||||
Reference in New Issue
Block a user