feat(auth, ui): add Keycloak login flow and enhance LoginScreen UI

- Introduced `onKeycloakLogin` callback in LoginScreen for Keycloak-based authentication.
- Updated Login UI with "Login with Keycloak" button and loading indicator for OIDC flow.
- Implemented dividers and spacing for improved visual structure.

- Refactored LandingScreen into a separate file for better modularity and maintenance.
- Reintroduced LandingScreen features, hero section, and footer with enhanced composables.

- Added `composeHotReload` plugin and `uiTooling` dependency for development improvements.

Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
2026-03-21 17:49:15 +01:00
parent faa2c344d1
commit 0e32999df4
4 changed files with 197 additions and 156 deletions
@@ -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")
}
}
}
}