Skip to content

Commit f7331f0

Browse files
feat: loan account summary (#2888)
Co-authored-by: revanthkumarJ <[email protected]>
1 parent a6d460c commit f7331f0

File tree

14 files changed

+832
-19
lines changed

14 files changed

+832
-19
lines changed

cmp-navigation/src/commonMain/kotlin/cmp/navigation/authenticated/AuthenticatedNavigation.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ import org.mifos.mobile.feature.charge.navigation.clientChargeNavGraph
3535
import org.mifos.mobile.feature.charge.navigation.navigateToChargeGraph
3636
import org.mifos.mobile.feature.help.navigation.helpNavGraph
3737
import org.mifos.mobile.feature.help.navigation.navigateToHelpScreen
38+
import org.mifos.mobile.feature.loanaccount.loanAccountDetails.navigateToLoanAccountDetailsScreen
3839
import org.mifos.mobile.feature.loanaccount.navigation.loanNavGraph
39-
import org.mifos.mobile.feature.loanaccount.savingsAccountDetails.navigateToLoanAccountDetailsScreen
4040
import org.mifos.mobile.feature.location.navigation.locationsNavGraph
4141
import org.mifos.mobile.feature.location.navigation.navigateToLocationsScreen
4242
import org.mifos.mobile.feature.notification.navigation.navigateToNotificationScreen
@@ -131,7 +131,6 @@ internal fun NavGraphBuilder.authenticatedGraph(
131131
navController = navController,
132132
navigateToMakePaymentScreen = {},
133133
navigateToRepaymentScheduleScreen = {},
134-
navigateToLoanSummaryScreen = {},
135134
navigateToQrCodeScreen = navController::navigateToQrDisplayScreen,
136135
navigateToClientChargeScreen = navController::navigateToClientChargeScreen,
137136
navigateToLoanAccountTransactionScreen = {

feature/loan-account/src/commonMain/composeResources/values/strings.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,51 @@
5252
<string name="feature_loan_next_installment_label">Next Installment</string>
5353
<string name="feature_loan_installment_amount_label">Installment Amount</string>
5454
<string name="feature_loan_due_date_label">Due Date</string>
55+
56+
<!-- Account Summary -->
57+
58+
<string name="feature_loan_account_details_title">Account Details</string>
59+
<string name="feature_loan_payoff_details_title">Pay-off Details</string>
60+
<string name="feature_loan_charges_title">Charges</string>
61+
<string name="feature_loan_waivers_title">Waivers</string>
62+
<string name="feature_loan_paid_off_details_title">Paid-off Details</string>
63+
<string name="feature_loan_outstanding_details_title">Outstanding Details</string>
64+
<string name="feature_loan_installment_details_title">Installment Details</string>
65+
66+
<!-- Account Details -->
67+
<string name="feature_loan_type_label">Loan Type</string>
68+
<string name="feature_loan_scheme_label">Loan Scheme</string>
69+
<string name="feature_loan_account_status_label">Account Status</string>
70+
71+
<!-- Pay-off Details -->
72+
<string name="feature_loan_expected_payoff_label">Expected Payoff</string>
73+
<string name="feature_loan_interest_payoff_label">Interest Payoff</string>
74+
<string name="feature_loan_principal_label">Debt Principal</string>
75+
<string name="feature_loan_interest_rate_label">Rate</string>
76+
77+
<!-- Charges -->
78+
<string name="feature_loan_fees_label">Fees</string>
79+
<string name="feature_loan_penalties_label">Penalties</string>
80+
81+
<!-- Waivers -->
82+
<string name="feature_loan_interest_waived_label">Interest Waived</string>
83+
<string name="feature_loan_penalty_waived_label">Penalties Waived</string>
84+
<string name="feature_loan_fees_waived_label">Fees Waived</string>
85+
86+
<!-- Paid-off Details -->
87+
<string name="feature_loan_interest_paid_off_label">Interest Paid-off</string>
88+
<string name="feature_loan_principal_paid_off_label">Principal Paid-off</string>
89+
90+
<!-- Outstanding Details -->
91+
<string name="feature_loan_interest_outstanding_label">Interest Outstanding</string>
92+
<string name="feature_loan_principal_outstanding_label">Principal Outstanding</string>
93+
<string name="feature_loan_total_outstanding_label">Total Outstanding</string>
94+
95+
<!-- Installment Details -->
96+
<string name="feature_loan_regular_payment_label">Regular Payment</string>
97+
<string name="feature_loan_next_payment_label">Next Payment</string>
98+
<string name="feature_loan_months_left_label">Months Left</string>
99+
<string name="feature_loan_auto_debit_label">Auto Debit</string>
100+
<string name="feature_loan_linked_account_label">Linked Account</string>
101+
55102
</resources>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
9+
*/
10+
package org.mifos.mobile.feature.loanaccount.component
11+
12+
import androidx.compose.animation.AnimatedVisibility
13+
import androidx.compose.animation.fadeIn
14+
import androidx.compose.animation.fadeOut
15+
import androidx.compose.animation.slideInHorizontally
16+
import androidx.compose.animation.slideOutHorizontally
17+
import androidx.compose.foundation.border
18+
import androidx.compose.foundation.clickable
19+
import androidx.compose.foundation.layout.Arrangement
20+
import androidx.compose.foundation.layout.Column
21+
import androidx.compose.foundation.layout.Row
22+
import androidx.compose.foundation.layout.fillMaxWidth
23+
import androidx.compose.foundation.layout.padding
24+
import androidx.compose.foundation.layout.size
25+
import androidx.compose.material3.Icon
26+
import androidx.compose.material3.MaterialTheme
27+
import androidx.compose.material3.Text
28+
import androidx.compose.runtime.Composable
29+
import androidx.compose.runtime.getValue
30+
import androidx.compose.runtime.mutableStateOf
31+
import androidx.compose.runtime.saveable.rememberSaveable
32+
import androidx.compose.runtime.setValue
33+
import androidx.compose.ui.Alignment
34+
import androidx.compose.ui.Modifier
35+
import androidx.compose.ui.text.style.TextAlign
36+
import androidx.compose.ui.unit.dp
37+
import mifos_mobile.feature.loan_account.generated.resources.Res
38+
import mifos_mobile.feature.loan_account.generated.resources.feature_loan_account_number_label
39+
import mifos_mobile.feature.loan_account.generated.resources.feature_loan_account_status_label
40+
import mifos_mobile.feature.loan_account.generated.resources.feature_loan_product_type_label
41+
import mifos_mobile.feature.loan_account.generated.resources.feature_loan_scheme_label
42+
import org.jetbrains.compose.resources.StringResource
43+
import org.jetbrains.compose.resources.stringResource
44+
import org.jetbrains.compose.ui.tooling.preview.Preview
45+
import org.mifos.mobile.core.designsystem.component.CardVariant
46+
import org.mifos.mobile.core.designsystem.component.MifosCustomCard
47+
import org.mifos.mobile.core.designsystem.icon.MifosIcons
48+
import org.mifos.mobile.core.designsystem.theme.AppColors
49+
import org.mifos.mobile.core.designsystem.theme.DesignToken
50+
import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme
51+
import org.mifos.mobile.core.designsystem.theme.MifosTypography
52+
import kotlin.collections.component1
53+
import kotlin.collections.component2
54+
55+
@Composable
56+
fun AccountSummaryCard(
57+
keyValuePairs: Map<StringResource, String?>,
58+
modifier: Modifier = Modifier,
59+
title: String = "",
60+
) {
61+
var isExpanded by rememberSaveable { mutableStateOf(false) }
62+
63+
MifosCustomCard(
64+
variant = CardVariant.OUTLINED,
65+
modifier = modifier
66+
.fillMaxWidth()
67+
.border(
68+
1.dp,
69+
MaterialTheme.colorScheme.secondaryContainer,
70+
DesignToken.shapes.medium,
71+
),
72+
shape = DesignToken.shapes.medium,
73+
) {
74+
Column(
75+
modifier = Modifier
76+
.fillMaxWidth()
77+
.clickable { isExpanded = !isExpanded }
78+
.padding(DesignToken.padding.large),
79+
) {
80+
Row(
81+
modifier = Modifier
82+
.fillMaxWidth(),
83+
verticalAlignment = Alignment.CenterVertically,
84+
horizontalArrangement = Arrangement.SpaceBetween,
85+
) {
86+
Text(
87+
text = title,
88+
style = MifosTypography.titleSmallEmphasized,
89+
color = AppColors.customBlack,
90+
)
91+
Icon(
92+
modifier = Modifier.size(DesignToken.sizes.iconSmall),
93+
imageVector = if (isExpanded) MifosIcons.CaretUp else MifosIcons.CaretDown,
94+
contentDescription = if (isExpanded) "Collapse" else "Expand",
95+
tint = MaterialTheme.colorScheme.onSurface,
96+
)
97+
}
98+
99+
AnimatedVisibility(
100+
visible = isExpanded,
101+
enter = slideInHorizontally(initialOffsetX = { fullWidth -> fullWidth }) + fadeIn(),
102+
exit = slideOutHorizontally(targetOffsetX = { fullWidth -> fullWidth }) + fadeOut(),
103+
) {
104+
Column(modifier = Modifier.padding(top = DesignToken.padding.medium)) {
105+
keyValuePairs.forEach { (key, value) ->
106+
Row(
107+
modifier = Modifier
108+
.fillMaxWidth()
109+
.padding(vertical = DesignToken.padding.small),
110+
horizontalArrangement = Arrangement.SpaceBetween,
111+
) {
112+
Text(
113+
text = "${stringResource(key)} :",
114+
style = MifosTypography.labelMediumEmphasized,
115+
color = MaterialTheme.colorScheme.secondary,
116+
)
117+
Text(
118+
text = value ?: "",
119+
style = MifosTypography.labelMedium,
120+
textAlign = TextAlign.Right,
121+
color = if (key == Res.string.feature_loan_account_status_label) {
122+
AppColors.customEnable
123+
} else {
124+
MaterialTheme.colorScheme.secondary
125+
},
126+
)
127+
}
128+
}
129+
}
130+
}
131+
}
132+
}
133+
}
134+
135+
@Preview
136+
@Composable
137+
private fun Account_Card_Preview() {
138+
MifosMobileTheme {
139+
Column(
140+
modifier = Modifier
141+
.fillMaxWidth()
142+
.padding(DesignToken.padding.large),
143+
) {
144+
AccountSummaryCard(
145+
keyValuePairs = mapOf(
146+
Res.string.feature_loan_account_number_label to "John Miller",
147+
Res.string.feature_loan_product_type_label to "2-05-2025",
148+
Res.string.feature_loan_scheme_label to "268978976666",
149+
Res.string.feature_loan_account_status_label to "Wallet",
150+
),
151+
)
152+
}
153+
}
154+
}

feature/loan-account/src/commonMain/kotlin/org/mifos/mobile/feature/loanaccount/di/LoanModule.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ package org.mifos.mobile.feature.loanaccount.di
1212
import org.koin.core.module.dsl.viewModelOf
1313
import org.koin.dsl.module
1414
import org.mifos.mobile.feature.loanaccount.loanAccount.LoanAccountsViewmodel
15-
import org.mifos.mobile.feature.loanaccount.savingsAccountDetails.LoanAccountDetailsViewModel
15+
import org.mifos.mobile.feature.loanaccount.loanAccountDetails.LoanAccountDetailsViewModel
16+
import org.mifos.mobile.feature.loanaccount.loanAccountSummary.LoanAccountSummaryViewModel
1617

1718
val loanAccountModule = module {
1819
viewModelOf(::LoanAccountsViewmodel)
1920
viewModelOf(::LoanAccountDetailsViewModel)
21+
viewModelOf(::LoanAccountSummaryViewModel)
2022
}

feature/loan-account/src/commonMain/kotlin/org/mifos/mobile/feature/loanaccount/loanAccount/LoanAccountScreen.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,15 @@ internal fun LoanAccountContent(
177177
Row(
178178
horizontalArrangement = Arrangement.spacedBy(DesignToken.spacing.largeIncreased),
179179
) {
180-
Icon(
181-
modifier = Modifier
182-
.clickable {}
183-
.size(20.dp),
184-
imageVector = MifosIcons.SearchNew,
185-
contentDescription = null,
186-
)
180+
// TODO : commenting because it has no
181+
// functionality now which is not best experience for user
182+
// Icon(
183+
// modifier = Modifier
184+
// .clickable {}
185+
// .size(20.dp),
186+
// imageVector = MifosIcons.SearchNew,
187+
// contentDescription = null,
188+
// )
187189
Icon(
188190
modifier = Modifier
189191
.clickable { filtersClicked() }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
@file:Suppress("MatchingDeclarationName")
1111

12-
package org.mifos.mobile.feature.loanaccount.savingsAccountDetails
12+
package org.mifos.mobile.feature.loanaccount.loanAccountDetails
1313

1414
import androidx.navigation.NavController
1515
import androidx.navigation.NavGraphBuilder
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
99
*/
10-
package org.mifos.mobile.feature.loanaccount.savingsAccountDetails
10+
package org.mifos.mobile.feature.loanaccount.loanAccountDetails
1111

1212
import androidx.compose.foundation.layout.Arrangement
1313
import androidx.compose.foundation.layout.Column
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
99
*/
10-
package org.mifos.mobile.feature.loanaccount.savingsAccountDetails
10+
package org.mifos.mobile.feature.loanaccount.loanAccountDetails
1111

1212
import androidx.compose.runtime.Immutable
1313
import androidx.lifecycle.SavedStateHandle
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md
9+
*/
10+
package org.mifos.mobile.feature.loanaccount.loanAccountSummary
11+
12+
import androidx.navigation.NavController
13+
import androidx.navigation.NavGraphBuilder
14+
import androidx.navigation.NavOptions
15+
import kotlinx.serialization.Serializable
16+
import org.mifos.mobile.core.ui.composableWithSlideTransitions
17+
18+
@Serializable
19+
data class AccountSummaryRoute(
20+
val accountId: Long,
21+
)
22+
23+
fun NavController.navigateToLoanAccountSummaryScreen(
24+
accountId: Long,
25+
navOptions: NavOptions? = null,
26+
) {
27+
navigate(AccountSummaryRoute(accountId), navOptions)
28+
}
29+
30+
fun NavGraphBuilder.loanAccountSummaryDestination(
31+
navigateBack: () -> Unit,
32+
) {
33+
composableWithSlideTransitions<AccountSummaryRoute> {
34+
LoanAccountSummaryScreen(
35+
navigateBack = navigateBack,
36+
)
37+
}
38+
}

0 commit comments

Comments
 (0)