Skip to content

Commit

Permalink
feat(feature:loan-account): Migrate loan-account module to CMP
Browse files Browse the repository at this point in the history
  • Loading branch information
HekmatullahAmin committed Feb 19, 2025
1 parent 3631233 commit df2e753
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 277 deletions.
3 changes: 1 addition & 2 deletions feature/loan-account/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ plugins {
}

android {
namespace = "com.hekmatullahamin.loan_account"
namespace = "org.mifos.mobile.feature.loanaccount"
}

kotlin {
Expand All @@ -24,7 +24,6 @@ kotlin {

api(projects.core.ui)
api(projects.core.model)
api(projects.core.common)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,13 @@
See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
-->
<resources>
<string name="feature_account_disbursement">Disbursement</string>
<string name="feature_account_approved">Approved</string>
<string name="feature_account_submitted">Submitted</string>
<string name="feature_account_active">Active</string>
<string name="feature_account_approval_pending">Approval Pending</string>
<string name="feature_account_closed">Closed</string>
<string name="feature_account_withdrawn">Withdrawn</string>
<string name="feature_account_disburse">Waiting for Disburse</string>
<string name="feature_account_approval_pending">Approval Pending</string>
<string name="feature_account_overpaid">Overpaid</string>
<string name="feature_account_matured">Matured</string>

<string name="feature_account_active">Active</string>
<string name="feature_account_in_arrears">In Arrears</string>
<string name="feature_account_empty_loan_accounts">There is no LoanAccount associated with you</string>
<string name="feature_account_withdrawn">Withdrawn</string>

<string name="feature_account_empty_loan_accounts">There is no LoanAccount associated with you</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import org.mifos.mobile.core.model.entity.accounts.loan.LoanAccount

@Composable
fun AccountCard(
accountNo: String?,
productName: String?,
statusString: String?,
loanAccount: LoanAccount,
accountStatus: String?,
balance: String,
indicatorColor: Color,
textColor: Color?,
Expand All @@ -37,6 +38,8 @@ fun AccountCard(
Card(
onClick = onClick,
modifier = modifier,
shape = MaterialTheme.shapes.medium,
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
) {
Box {
AccountTypeItemIndicator(
Expand All @@ -48,22 +51,22 @@ fun AccountCard(
verticalAlignment = Alignment.CenterVertically,
) {
Column(modifier = Modifier.padding(start = 12.dp)) {
accountNo?.let {
loanAccount.accountNo?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyLarge,
)
}
productName?.let {
loanAccount.productName?.let {
Text(
text = it,
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
if (statusString != null) {
if (accountStatus != null) {
Text(
text = statusString,
text = accountStatus,
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
*
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
*/
package org.mifos.mobile.feature.loanaccount.model
package org.mifos.mobile.feature.loanaccount.di

import org.jetbrains.compose.resources.StringResource
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module
import org.mifos.mobile.feature.loanaccount.viewmodel.LoanAccountViewmodel

internal data class CheckboxStatus(
val status: StringResource?,
val isChecked: Boolean = false,
)
val loanAccountModule = module {
viewModelOf(::LoanAccountViewmodel)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,75 +10,99 @@
package org.mifos.mobile.feature.loanaccount.screen

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mifos_mobile.feature.loan_account.generated.resources.Res
import mifos_mobile.feature.loan_account.generated.resources.feature_account_empty_loan_accounts
import mifos_mobile.feature.loan_account.generated.resources.feature_account_error_black
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.vectorResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifos.mobile.core.model.enums.AccountType
import org.mifos.mobile.core.ui.component.EmptyDataView
import org.mifos.mobile.core.ui.component.MifosErrorComponent
import org.mifos.mobile.core.ui.component.MifosProgressIndicatorOverlay
import org.mifos.mobile.feature.loanaccount.utils.AccountState
import org.mifos.mobile.feature.loanaccount.viewmodel.LoanAccountViewmodel

@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun LoanAccountScreen(
fun LoanAccountScreen(
checkboxOptionsLabels: List<StringResource?>,
searchQuery: String,
isSearchActive: Boolean,
isFiltered: Boolean,
onAccountSelected: (accountType: String, accountId: Long) -> Unit,
onAccountSelected: (accountType: AccountType, accountId: Long) -> Unit,
modifier: Modifier = Modifier,
viewModel: LoanAccountViewmodel = koinViewModel(),
) {
val uiState = viewModel.accountUiState.collectAsStateWithLifecycle()
val isNetworkAvailable = viewModel.isNetworkAvailable.collectAsStateWithLifecycle()
val isRefreshing by viewModel.isRefreshing.collectAsStateWithLifecycle()
val isNetworkAvailable by viewModel.isNetworkAvailable.collectAsStateWithLifecycle()

val pullRefreshState = rememberPullToRefreshState()

LaunchedEffect(Unit) {
viewModel.loadSavingsAccounts()
}

when (val state = uiState.value) {
is AccountState.Error -> {
MifosErrorComponent(
isNetworkConnected = isNetworkAvailable.value,
isRetryEnabled = true,
onRetry = viewModel::loadSavingsAccounts,
)
}
PullToRefreshBox(
isRefreshing = isRefreshing,
state = pullRefreshState,
onRefresh = viewModel::refresh,
modifier = modifier,
) {
when (val state = uiState.value) {
is AccountState.Error -> {
MifosErrorComponent(
isNetworkConnected = isNetworkAvailable,
isRetryEnabled = true,
onRetry = viewModel::loadSavingsAccounts,
)
}

is AccountState.Loading -> {
MifosProgressIndicatorOverlay()
}
is AccountState.Loading -> {
MifosProgressIndicatorOverlay()
}

is AccountState.Success -> {
val loanAccounts = state.accounts
if (loanAccounts.isNullOrEmpty()) {
EmptyDataView(
icon = vectorResource(resource = Res.drawable.feature_account_error_black),
error = Res.string.feature_account_empty_loan_accounts,
modifier = Modifier.fillMaxSize(),
)
} else {
val updatedFilteredAccounts =
remember(searchQuery, isFiltered, isSearchActive, loanAccounts) {
viewModel.getUpdatedFilteredAccountList(
searchQuery = searchQuery,
isFiltered = isFiltered,
isSearchActive = isSearchActive,
accountList = loanAccounts,
)
}
is AccountState.Success -> {
val loanAccounts = state.accounts
if (loanAccounts.isNullOrEmpty()) {
EmptyDataView(
icon = vectorResource(resource = Res.drawable.feature_account_error_black),
error = Res.string.feature_account_empty_loan_accounts,
modifier = Modifier.fillMaxSize(),
)
} else {
val updatedFilteredAccounts =
remember(
searchQuery,
isFiltered,
isSearchActive,
loanAccounts,
checkboxOptionsLabels,
) {
viewModel.getFilteredAccounts(
searchQuery = searchQuery,
isFiltered = isFiltered,
isSearchActive = isSearchActive,
selectedCheckboxLabels = checkboxOptionsLabels,
accounts = loanAccounts,
)
}

LoanAccountScreenContent(
accountList = updatedFilteredAccounts,
onAccountSelected = onAccountSelected,
modifier = modifier,
)
LoanAccountScreenContent(
accountList = updatedFilteredAccounts,
onAccountSelected = onAccountSelected,
)
}
}
}
}
Expand Down
Loading

0 comments on commit df2e753

Please sign in to comment.