Skip to content

Commit

Permalink
- Added Details Screen
Browse files Browse the repository at this point in the history
- Used Mapper DTO to get income expense details.
  • Loading branch information
EvolvingLearner committed Sep 25, 2024
1 parent aa2ce65 commit 52ddddb
Show file tree
Hide file tree
Showing 30 changed files with 773 additions and 428 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,6 @@ dependencies {
// Coroutine
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0'

implementation "org.jetbrains.kotlin:kotlin-reflect:2.0.20"
}
1 change: 0 additions & 1 deletion app/src/main/java/com/money/expenz/BaseActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ open class BaseActivity : ComponentActivity() {

setContent {
ExpenzTheme {

val owner = LocalViewModelStoreOwner.current

owner?.let {
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/com/money/expenz/data/DataSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.money.expenz.data
import com.money.expenz.R

class DataSource {

fun loadSubscriptions(): List<Subscription> {
return listOf(
Subscription(R.string.netflix, R.drawable.ic_category_media),
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/money/expenz/data/IEDetails.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.money.expenz.data
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlin.reflect.full.memberProperties

@Entity(tableName = "IEDetails")
data class IEDetails(
Expand All @@ -22,3 +23,20 @@ data class IEDetails(
@ColumnInfo(name = "userId")
var userId: Int = 0
)

data class IEDetailsDTO(
val ie: String = "",
val category: String = "",
val amount: Int = 0,
val date: String = "",
val notes: String = ""
)

fun IEDetails.toIEDetailsDTO(): IEDetailsDTO {
return IEDetailsDTO(ie, category, amount, date, notes)
}

inline fun <reified T : Any> T.asMap(): Map<String, Any?> {
val props = T::class.memberProperties.associateBy { it.name }
return props.keys.associateWith { props[it]?.get(this) }
}
2 changes: 1 addition & 1 deletion app/src/main/java/com/money/expenz/data/Subscription.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import androidx.annotation.StringRes

data class Subscription(
@StringRes val stringResourceId: Int,
@DrawableRes val imageResourceId: Int
@DrawableRes val imageResourceId: Int,
)
2 changes: 1 addition & 1 deletion app/src/main/java/com/money/expenz/data/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ data class User(
@ColumnInfo(name = "TotalIncome")
var totalIncome: Long = 0,
@ColumnInfo(name = "TotalExpense")
var totalExpense: Long = 0
var totalExpense: Long = 0,
)
4 changes: 2 additions & 2 deletions app/src/main/java/com/money/expenz/data/UserWithIEDetails.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ data class UserWithIEDetails(
@Embedded val user: User,
@Relation(
parentColumn = "Id",
entityColumn = "userId"
entityColumn = "userId",
)
val ieDetails: List<IEDetails>
val ieDetails: List<IEDetails>,
)
41 changes: 11 additions & 30 deletions app/src/main/java/com/money/expenz/database/UserDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,34 @@ import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import com.money.expenz.data.IEDetails
import com.money.expenz.data.User
import com.money.expenz.model.UserDAO
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

@Database(entities = [User::class, IEDetails::class], version = 2, exportSchema = true)
@Database(entities = [User::class, IEDetails::class], version = 1, exportSchema = true)
abstract class UserDatabase : RoomDatabase() {

abstract fun userDAO(): UserDAO

private class UserDatabaseCallBack(private val coroutineScope: CoroutineScope) : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
INSTANCE?.let { database ->
coroutineScope.launch {
populateDatabase(database.userDAO())
}
}
}

suspend fun populateDatabase(userDao: UserDAO) {

val user = User(userName = "Sam", password = "abc@38", email = "vasu@gmail.com", country = "china")
userDao.insertUser(user)

val ieDetails = IEDetails(ie = "Income", category = "other", amount = 0, userId = 1)
userDao.insertIEDetails(ieDetails)
}
}

companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
@Volatile
private var INSTANCE: UserDatabase? = null

fun getInstance(context: Context, coroutineScope: CoroutineScope): UserDatabase {
fun getInstance(
context: Context,
coroutineScope: CoroutineScope,
): UserDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
UserDatabase::class.java,
"user_database"
).addCallback(UserDatabaseCallBack(coroutineScope)).build()
val instance =
Room.databaseBuilder(
context.applicationContext,
UserDatabase::class.java,
"user_database",
).build()
INSTANCE = instance
instance
}
Expand Down
57 changes: 29 additions & 28 deletions app/src/main/java/com/money/expenz/model/ExpenzAppBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import com.money.expenz.ui.Screen
import com.money.expenz.ui.home.ExpenzViewModel

class ExpenzAppBar {

object ExpenzTheme {
val colorScheme: ColorScheme
@Composable
Expand All @@ -45,7 +44,7 @@ class ExpenzAppBar {
@Composable
fun AppBar(
viewModel: ExpenzViewModel,
navController: NavHostController = rememberNavController()
navController: NavHostController = rememberNavController(),
) {
// Get current back stack entry
val backStackEntry by navController.currentBackStackEntryAsState()
Expand All @@ -54,17 +53,19 @@ class ExpenzAppBar {
topBar = {
TopAppBar(
currentScreen = Screen.valueOf(currentRoute ?: Screen.Home.route),
canNavigateBack = navController.previousBackStackEntry != null && !currentRoute.equals(
Screen.Home.route
),
navigateUp = { navController.navigateUp() }
canNavigateBack =
navController.previousBackStackEntry != null &&
!currentRoute.equals(
Screen.Home.route,
),
navigateUp = { navController.navigateUp() },
)
},
bottomBar = {
BottomNavigationBar(navController = navController)
},
backgroundColor = ExpenzTheme.colorScheme.background,
contentColor = ExpenzTheme.colorScheme.onBackground
contentColor = ExpenzTheme.colorScheme.onBackground,
) { innerPadding ->
BaseContent(viewModel, innerPadding, navController)
}
Expand All @@ -75,7 +76,7 @@ class ExpenzAppBar {
currentScreen: Screen,
canNavigateBack: Boolean,
navigateUp: () -> Unit,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
val localContext = LocalContext.current as Activity
TopAppBar(
Expand All @@ -88,7 +89,7 @@ class ExpenzAppBar {
description = "Logout",
onClick = {
localContext.finishAffinity()
}
},
)
},
modifier = modifier,
Expand All @@ -97,39 +98,38 @@ class ExpenzAppBar {
AppBarActionButton(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
description = "Back",
onClick = navigateUp
onClick = navigateUp,
)
}
}
},
)
}

@Composable
fun AppBarActionButton(
imageVector: ImageVector,
description: String,
onClick: () -> Unit
onClick: () -> Unit,
) {
IconButton(onClick = {
onClick()
}) {
Icon(
imageVector = imageVector,
contentDescription = description,
tint = ExpenzTheme.colorScheme.onPrimary
tint = ExpenzTheme.colorScheme.onPrimary,
)
}
}

@Composable
fun BottomNavigationBar(
navController: NavController
) {
val items = listOf(
BottomNavItem.Home,
BottomNavItem.Add,
BottomNavItem.Subscriptions
)
fun BottomNavigationBar(navController: NavController) {
val items =
listOf(
BottomNavItem.Home,
BottomNavItem.Add,
BottomNavItem.Subscriptions,
)

BottomNavigation(
modifier = Modifier.fillMaxWidth(),
Expand All @@ -144,7 +144,7 @@ class ExpenzAppBar {
Icon(
imageVector = item.icon,
contentDescription = stringResource(id = item.titleResId),
tint = ExpenzTheme.colorScheme.onPrimary
tint = ExpenzTheme.colorScheme.onPrimary,
)
},
label = { Text(text = stringResource(id = item.titleResId)) },
Expand All @@ -164,7 +164,7 @@ class ExpenzAppBar {
// Restore state when re-selecting a previously selected item
restoreState = true
}
}
},
)
}
}
Expand All @@ -174,19 +174,20 @@ class ExpenzAppBar {
fun BaseContent(
viewModel: ExpenzViewModel,
innerPaddingValues: PaddingValues,
navController: NavHostController
navController: NavHostController,
) {
Column(
Modifier.padding(
paddingValues = PaddingValues(
paddingValues =
PaddingValues(
10.dp,
innerPaddingValues.calculateTopPadding(),
10.dp,
innerPaddingValues.calculateBottomPadding()
)
innerPaddingValues.calculateBottomPadding(),
),
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
verticalArrangement = Arrangement.Center,
) {
NavigationSetup(viewModel, navController = navController, Screen.Home.route)
// HomeScreen(viewModel, navController)
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/com/money/expenz/model/UserDAO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ import kotlinx.coroutines.flow.Flow

@Dao
interface UserDAO {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: User)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertIEDetails(ieDetails: IEDetails)

@Query("SELECT * FROM User")
fun getAllUsers(): Flow<List<User>>
fun getAllUsers(): Flow<List<User>>?

@Query("SELECT * FROM User WHERE id LIKE :userId")
suspend fun getLoggedInUserDetails(userId: Int): User
Expand All @@ -31,6 +30,9 @@ interface UserDAO {
@Query("SELECT * FROM User")
fun getUserWithIEDetails(): Flow<List<UserWithIEDetails>>

@Query("SELECT * FROM IEDetails WHERE category LIKE :category")
suspend fun searchIECategory(category: String): List<IEDetails>

@Update
suspend fun updateUserDetails(user: User)

Expand Down
11 changes: 9 additions & 2 deletions app/src/main/java/com/money/expenz/repository/UserRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import kotlinx.coroutines.flow.Flow
* Coroutine used to avoid database operations on main thread
*/
class UserRepository(private val userDAO: UserDAO) {

val allUsersList: Flow<List<User>> = userDAO.getAllUsers()
@WorkerThread
fun getUsers(): Flow<List<User>>? {
return userDAO.getAllUsers()
}

@WorkerThread
fun getUserWithIEDetails(): Flow<List<UserWithIEDetails>> {
Expand All @@ -37,4 +39,9 @@ class UserRepository(private val userDAO: UserDAO) {
suspend fun updateUserDetails(user: User) {
userDAO.updateUserDetails(user)
}

@WorkerThread
suspend fun searchIECategory(category: String): List<IEDetails> {
return userDAO.searchIECategory(category)
}
}
Loading

0 comments on commit 52ddddb

Please sign in to comment.