Merge remote-tracking branch 'origin/Xaver' into Florian

# Conflicts:
#	Ledger/app/src/main/java/at/xaxa/ledger/LedgerApplication.kt
#	Ledger/app/src/main/java/at/xaxa/ledger/data/EntryRepository.kt
#	Ledger/app/src/main/java/at/xaxa/ledger/data/db/LedgerDatabase.kt
This commit is contained in:
Florian 2025-01-14 09:24:52 +01:00
commit 6d8bd7224d
6 changed files with 381 additions and 2 deletions

View File

@ -61,6 +61,7 @@ dependencies {
implementation(libs.androidx.material3)
implementation(libs.androidx.room.common)
implementation(libs.androidx.room.ktx)
implementation(libs.androidx.navigation.compose)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

View File

@ -11,6 +11,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import at.xaxa.ledger.ui.LedgerApp
import at.xaxa.ledger.ui.theme.LedgerTheme
class MainActivity : ComponentActivity() {
@ -20,8 +21,7 @@ class MainActivity : ComponentActivity() {
setContent {
LedgerTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
LedgerApp(
modifier = Modifier.padding(innerPadding)
)
}

View File

@ -0,0 +1,56 @@
package at.xaxa.ledger.ui
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import at.xaxa.ledger.ui.home.Home
enum class AppRoutes(val route: String) {
Home("home"),
Add("add"),
Edit("edit/{gameId}")
}
@Composable
fun LedgerApp(modifier: Modifier = Modifier){
val navController = rememberNavController()
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
Scaffold() { innerPadding ->
NavHost(
navController = navController,
startDestination = AppRoutes.Home.route,
modifier = Modifier.padding(innerPadding),
contentAlignment = Alignment.Center
) {
composable(AppRoutes.Home.route){
Home(onCardClick = {
navController.navigate("home")
})
}
/*
composable(AppRoutes.Add.route) {
SearchList(onCardClick = {
navController.navigate("add/$it")
})
}
composable(
route = AppRoutes.Edit.route,
arguments = listOf(navArgument("gameId") {
type = NavType.IntType
})
) {
backStackEntry ->
DetailView(
modifier = Modifier
)
}*/
}
}
}

View File

@ -0,0 +1,275 @@
package at.xaxa.ledger.ui
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
// region Header Card
@Composable
fun HeaderCard(modifier: Modifier = Modifier, balance: String) {
Surface(
shape = RoundedCornerShape(12.dp),
color = Color(0xfff9f9f9),
border = BorderStroke(1.dp, Color(0xffc6c6c6)),
modifier = modifier
.requiredWidth(width = 360.dp)
.clip(shape = RoundedCornerShape(12.dp))
.shadow(
elevation = 8.dp,
shape = RoundedCornerShape(16.dp),
clip = true
)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
LayoutMediaTextHeader(modifier, balance)
}
}
}
@Composable
fun LayoutMediaTextHeader(modifier: Modifier = Modifier, balance: String) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.fillMaxWidth()
) {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.Top),
horizontalAlignment = Alignment.End, // Align content to the right
modifier = Modifier
.weight(1f)
) {
Text(
text = "your balance",
color = Color(0xff1b1b1b),
lineHeight = 1.5.em,
style = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.15.sp
)
)
Text(
text = balance,
color = Color(0xff1b1b1b),
lineHeight = 1.43.em,
style = TextStyle(
fontSize = 40.sp,
letterSpacing = 0.25.sp
)
)
}
}
}
@Preview()
@Composable
private fun HeaderCardPreview() {
HeaderCard(Modifier, "-4500627.98€")
}
// endregion
// region Horizontal Card
@Composable
fun HorizontalCard(modifier: Modifier = Modifier, name: String, date: String, amount:String, onClick: () -> Unit ) {
Surface(
onClick = onClick,
shape = RoundedCornerShape(12.dp),
color = Color(0xfff9f9f9),
border = BorderStroke(1.dp, Color(0xffc6c6c6)),
modifier = modifier
.requiredWidth(width = 360.dp)
.requiredHeight(height = 80.dp)
.clip(shape = RoundedCornerShape(12.dp))
) {
Row(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
LayoutMediaText(modifier, name, date, amount)
}
}
}
@Composable
fun LayoutMediaText(modifier: Modifier = Modifier, name: String, date: String, amount:String) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.fillMaxWidth()
) {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.Top),
modifier = Modifier
.weight(1f)
) {
Text(
text = name,
color = Color(0xff1b1b1b),
lineHeight = 1.5.em,
style = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.15.sp
)
)
Text(
text = date,
color = Color(0xff1b1b1b),
lineHeight = 1.43.em,
style = TextStyle(
fontSize = 14.sp,
letterSpacing = 0.25.sp
)
)
}
Box(
modifier = Modifier
.fillMaxHeight()
.wrapContentWidth() // Allow the Box to wrap its content width
.padding(start = 16.dp), // Add some padding to separate from the Column
contentAlignment = Alignment.Center
) {
Text(
text = amount,
fontSize = 30.sp, // Set the desired font size
modifier = Modifier.wrapContentSize() // Ensure the text wraps its content
)
}
}
}
@Preview(widthDp = 360, heightDp = 80)
@Composable
private fun HorizontalCardPreview() {
HorizontalCard(Modifier, "McDonald's", "12th Feb, 23:32", "-124234.00€", onClick = { println("success") })
}
// endregion
// region Button Success
@Composable
fun ButtonSuccess(modifier: Modifier = Modifier, text: String, onClick: () -> Unit) {
Button(
onClick = onClick,
shape = RoundedCornerShape(10.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xff61a483)),
contentPadding = PaddingValues(horizontal = 24.dp, vertical = 10.dp),
modifier = modifier
.requiredHeight(height = 40.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.requiredHeight(height = 40.dp)
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxSize()
) {
Text(
text = text,
color = Color.White,
textAlign = TextAlign.Center,
lineHeight = 1.43.em,
style = MaterialTheme.typography.labelLarge,
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
}
}
}
}
@Preview()
@Composable
private fun ButtonSuccessPreview() {
ButtonSuccess(Modifier, "Success", onClick = { println("success") })
}
// endregion
// region Button Danger
@Composable
fun ButtonDanger(modifier: Modifier = Modifier, text: String, onClick: () -> Unit) {
Button(
onClick = onClick,
shape = RoundedCornerShape(10.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xffc14d4d)),
contentPadding = PaddingValues(horizontal = 24.dp, vertical = 10.dp),
modifier = modifier
.requiredHeight(height = 40.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.requiredHeight(height = 40.dp)
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxSize()
) {
Text(
text = text,
color = Color.White,
textAlign = TextAlign.Center,
lineHeight = 1.43.em,
style = MaterialTheme.typography.labelLarge,
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
}
}
}
}
@Preview()
@Composable
private fun ButtonDangerPreview() {
ButtonDanger(Modifier, "Danger", onClick = { println("success") })
}
// endregion

View File

@ -1,2 +1,47 @@
package at.xaxa.ledger.ui.home
import androidx.compose.foundation.ExperimentalFoundationApi
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.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import at.xaxa.ledger.ui.HeaderCard
import at.xaxa.ledger.ui.HorizontalCard
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Home(modifier: Modifier = Modifier, onCardClick: (Int) -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally) {
val items = (1..20).toList()
LazyColumn() {
stickyHeader {
HeaderCard(modifier = modifier, "-13563.00€")
}
items(items) { index ->
Column(
modifier = Modifier.padding(vertical = 4.dp) // Add vertical padding
) {
HorizontalCard(
modifier = modifier,
name = "McDonald's $index",
date = "12th Feb, 23:32",
amount = "-12.99",
onClick = { onCardClick(index) }
)
}
}
}
}
}

View File

@ -10,6 +10,7 @@ activityCompose = "1.9.3"
composeBom = "2024.04.01"
roomCommon = "2.6.1"
roomKtx = "2.6.1"
navigationCompose = "2.8.5"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -28,6 +29,7 @@ androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }