Showing AddAccountDialog on click on FloatingActionButton

This commit is contained in:
dankito 2024-08-25 04:27:04 +02:00
parent 23bd5833ea
commit 5f25b51487
9 changed files with 268 additions and 21 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,22 +1,22 @@
package net.codinux.banking.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Typography
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
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.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.launch
import net.codinux.banking.client.model.AccountTransaction
import net.codinux.banking.ui.composables.TransactionsList
import net.codinux.banking.ui.dialogs.AddAccountDialog
import net.codinux.banking.ui.service.BankingService
import net.codinux.banking.ui.service.Colors
import org.jetbrains.compose.ui.tooling.preview.Preview
@ -30,6 +30,10 @@ private val bankService = BankingService()
@Composable
@Preview
fun App() {
val colors = MaterialTheme.colors.copy(secondary = Colors.CodinuxSecondaryColor, onSecondary = Color.White)
var showAddAccountDialog by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val (transactions, setTransaction) = remember { mutableStateOf<List<AccountTransaction>>(emptyList()) }
@ -37,12 +41,28 @@ fun App() {
setTransaction(bankService.getTransactions())
}
MaterialTheme(typography = typography) {
Column(
Modifier.fillMaxWidth().fillMaxHeight().background(color = Colors.Zinc100),
horizontalAlignment = Alignment.CenterHorizontally
) {
TransactionsList(transactions)
MaterialTheme(colors = colors, typography = typography) {
Box {
Column(
Modifier.fillMaxWidth().fillMaxHeight().background(color = Colors.Zinc100),
horizontalAlignment = Alignment.CenterHorizontally
) {
TransactionsList(transactions)
}
Row(Modifier.align(Alignment.BottomEnd)) {
FloatingActionButton(
shape = CircleShape,
modifier = Modifier.offset((-12).dp, (-12).dp),
onClick = { showAddAccountDialog = true }
) {
Icon(Icons.Filled.Add, contentDescription = "Add a bank account")
}
}
if (showAddAccountDialog) {
AddAccountDialog { showAddAccountDialog = false }
}
}
}
}

View File

@ -4,8 +4,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.Divider
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
@ -23,6 +21,7 @@ import kotlinx.datetime.LocalDate
import net.codinux.banking.client.model.AccountTransaction
import net.codinux.banking.client.model.Amount
import net.codinux.banking.ui.extensions.toBigDecimal
import net.codinux.banking.ui.forms.RoundedCornersCard
import net.codinux.banking.ui.service.Colors
import net.codinux.banking.ui.service.DI
import org.jetbrains.compose.ui.tooling.preview.Preview
@ -51,10 +50,7 @@ fun TransactionsList(transactions: List<AccountTransaction>) {
val monthTransactions = groupedByMonth[month].orEmpty().sortedByDescending { it.valueDate }
Card(
shape = RoundedCornerShape(12.dp), // Rounded corners
elevation = 2.dp // Shadow elevation
) {
RoundedCornersCard {
Column(Modifier.background(Color.White)) { // LazyColumn inside LazyColumn is not allowed
monthTransactions.forEachIndexed { index, transaction ->
TransactionListItem(transaction, if (index % 2 == 1) Colors.Zinc100_50 else Color.Transparent)

View File

@ -0,0 +1,97 @@
package net.codinux.banking.ui.dialogs
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import net.codinux.banking.ui.forms.OutlinedTextField
import net.codinux.banking.ui.forms.PasswordTextField
import net.codinux.banking.ui.forms.RoundedCornersCard
import net.codinux.banking.ui.service.Colors
@Composable
fun AddAccountDialog(
onDismiss: () -> Unit,
) {
var bankCode by remember { mutableStateOf("") }
var loginName by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
val isRequiredDataEntered by remember(bankCode, loginName, password) {
derivedStateOf { bankCode.length == 8 && loginName.length > 3 && password.length > 3 }
}
val coroutineScope = rememberCoroutineScope()
Dialog(onDismissRequest = onDismiss) {
RoundedCornersCard {
Column(Modifier.background(Color.White).padding(8.dp)) {
Row(Modifier.fillMaxWidth()) {
Text(
"Bank Konto hinzufügen",
color = Color.Black,
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(top = 8.dp, bottom = 16.dp).weight(1f)
)
TextButton(onDismiss, colors = ButtonDefaults.buttonColors(contentColor = Colors.Zinc700, backgroundColor = Color.Transparent)) {
Icon(Icons.Filled.Close, contentDescription = "Close dialog", Modifier.size(32.dp))
}
}
OutlinedTextField(
value = bankCode,
onValueChange = { bankCode = it },
label = { Text("Bank (Suche mit Name, Bankleitzahl oder Ort)") },
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(24.dp))
Text("Online-Banking Zugangsdaten", color = Colors.CodinuxSecondaryColor)
Spacer(modifier = Modifier.height(12.dp))
OutlinedTextField(
value = loginName,
onValueChange = { loginName = it },
label = { Text("Login Name") },
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(12.dp))
PasswordTextField(password) { password = it }
Spacer(modifier = Modifier.height(16.dp))
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
TextButton(onClick = onDismiss) {
Text("Abbrechen")
}
Spacer(Modifier.width(8.dp))
TextButton(
onClick = onDismiss,
enabled = isRequiredDataEntered
) {
Text("Hinzufügen")
}
}
}
}
}
}

View File

@ -0,0 +1,67 @@
package net.codinux.banking.ui.forms
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme
import androidx.compose.material.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.VisualTransformation
import net.codinux.banking.ui.service.Colors
@Composable
fun OutlinedTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
readOnly: Boolean = false,
textStyle: TextStyle = LocalTextStyle.current,
label: @Composable (() -> Unit)? = null,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
isError: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
minLines: Int = 1,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = MaterialTheme.shapes.small,
// colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors() // TODO: merge
) {
val textFieldColors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Colors.CodinuxSecondaryColor,
focusedLabelColor = Colors.CodinuxSecondaryColor // does not work
)
androidx.compose.material.OutlinedTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier,
enabled = enabled,
readOnly = readOnly,
textStyle = textStyle,
label = label,
placeholder = placeholder,
leadingIcon = leadingIcon,
trailingIcon = trailingIcon,
isError = isError,
visualTransformation = visualTransformation,
keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions,
singleLine = singleLine,
maxLines = maxLines,
minLines = minLines,
interactionSource = interactionSource,
shape = shape,
colors = textFieldColors
)
}

View File

@ -0,0 +1,46 @@
package net.codinux.banking.ui.forms
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import bankmeister.composeapp.generated.resources.Res
import bankmeister.composeapp.generated.resources.visibility
import bankmeister.composeapp.generated.resources.visibility_off
import org.jetbrains.compose.resources.imageResource
@Composable
fun PasswordTextField(password: String = "", label: String = "Passwort", onChange: (String) -> Unit) {
var passwordVisible by remember { mutableStateOf(false) }
OutlinedTextField(
value = password,
onValueChange = { onChange(it) },
label = { Text(label) },
singleLine = true,
modifier = Modifier.fillMaxWidth(),
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
val visibilityIcon = if (passwordVisible) {
Res.drawable.visibility_off
} else {
Res.drawable.visibility
}
Icon(
bitmap = imageResource(visibilityIcon),
contentDescription = if (passwordVisible) "Hide password" else "Show password",
modifier = Modifier.size(24.dp).clickable { passwordVisible = !passwordVisible }
)
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
}

View File

@ -0,0 +1,16 @@
package net.codinux.banking.ui.forms
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Composable
fun RoundedCornersCard(cornerSize: Dp = 12.dp, shadowElevation: Dp = 2.dp, content: @Composable () -> Unit) {
Card(
shape = RoundedCornerShape(cornerSize), // Rounded corners
elevation = shadowElevation, // Shadow elevation
content = content
)
}

View File

@ -4,6 +4,11 @@ import androidx.compose.ui.graphics.Color
object Colors {
val CodinuxPrimaryColor = Color(30, 54, 78)
val CodinuxSecondaryColor = Color(251, 187, 33)
val Zinc100 = Color(244, 244, 245)
val Zinc100_50 = Zinc100.copy(alpha = 0.5f)