Skip to content

Commit 3b4bef2

Browse files
feat: savings application & enhance home navigation (#2938)
1 parent 6e6e0b7 commit 3b4bef2

File tree

31 files changed

+1332
-117
lines changed

31 files changed

+1332
-117
lines changed

cmp-navigation/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ kotlin {
3838
implementation(projects.feature.passcode)
3939
implementation(projects.feature.status)
4040
implementation(projects.feature.loanApplication)
41+
implementation(projects.feature.savingsApplication)
4142
// Core Modules
4243
implementation(projects.core.data)
4344
implementation(projects.core.common)

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

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import org.mifos.mobile.feature.beneficiary.navigation.navigateToBeneficiaryNavG
3434
import org.mifos.mobile.feature.charge.charges.navigateToClientChargeScreen
3535
import org.mifos.mobile.feature.charge.navigation.clientChargeNavGraph
3636
import org.mifos.mobile.feature.charge.navigation.navigateToChargeGraph
37+
import org.mifos.mobile.feature.home.navigation.HomeNavigationDestination
3738
import org.mifos.mobile.feature.loan.application.navigation.loanApplicationNavGraph
3839
import org.mifos.mobile.feature.loan.application.navigation.navigateToLoanApplicationGraph
3940
import org.mifos.mobile.feature.loanaccount.loanAccountDetails.navigateToLoanAccountDetailsScreen
@@ -48,8 +49,12 @@ import org.mifos.mobile.feature.qr.navigation.qrNavGraph
4849
import org.mifos.mobile.feature.qr.qr.navigateToQrReaderScreen
4950
import org.mifos.mobile.feature.qr.qrCodeDisplay.navigateToQrDisplayScreen
5051
import org.mifos.mobile.feature.recent.transaction.navigation.recentTransactionNavGraph
52+
import org.mifos.mobile.feature.savings.application.navigation.navigateToSavingsApplicationGraph
53+
import org.mifos.mobile.feature.savings.application.navigation.savingsApplicationNavGraph
5154
import org.mifos.mobile.feature.savingsaccount.navigation.savingsNavGraph
5255
import org.mifos.mobile.feature.savingsaccount.savingsAccountDetails.navigateToSavingsAccountDetailsScreen
56+
import org.mifos.mobile.feature.settings.faq.faqDestination
57+
import org.mifos.mobile.feature.settings.faq.navigateToFaq
5358
import org.mifos.mobile.feature.status.navigation.StatusNavigationRoute
5459
import org.mifos.mobile.feature.status.navigation.statusDestination
5560
import org.mifos.mobile.feature.third.party.transfer.navigation.thirdPartyTransferNavGraph
@@ -72,22 +77,44 @@ internal fun NavGraphBuilder.authenticatedGraph(
7277
navigation<AuthenticatedGraphRoute>(
7378
startDestination = AuthenticatedNavbarRoute,
7479
) {
75-
authenticatedNavbarGraph(
76-
navigateToNotificationScreen = navController::navigateToNotificationScreen,
77-
navigateToAccountsScreen = {
78-
when (it) {
79-
Constants.SAVINGS_ACCOUNT, Constants.LOAN_ACCOUNT, Constants.SHARE_ACCOUNTS ->
80-
navController.navigateToAccountsScreen(it)
81-
else -> Unit
80+
authenticatedNavbarGraph { destination ->
81+
when (destination) {
82+
is HomeNavigationDestination.AccountsWithType -> {
83+
if (destination.type in listOf(
84+
Constants.SAVINGS_ACCOUNT,
85+
Constants.LOAN_ACCOUNT,
86+
Constants.SHARE_ACCOUNTS,
87+
)
88+
) {
89+
navController.navigateToAccountsScreen(destination.type)
90+
}
8291
}
83-
},
84-
navigateToChargeScreen = navController::navigateToChargeGraph,
85-
navigateToBeneficiaryScreen = navController::navigateToBeneficiaryNavGraph,
86-
navigateToTransactionScreen = {
87-
navController.navigateToAccountTransactionsScreen(Constants.RECENT_TRANSACTIONS, -1L)
88-
},
89-
navigateToApplyLoanScreen = navController::navigateToLoanApplicationGraph,
90-
)
92+
93+
is HomeNavigationDestination.Notification ->
94+
navController.navigateToNotificationScreen()
95+
96+
is HomeNavigationDestination.Charge ->
97+
navController.navigateToChargeGraph()
98+
99+
is HomeNavigationDestination.Faq ->
100+
navController.navigateToFaq()
101+
102+
is HomeNavigationDestination.Beneficiary ->
103+
navController.navigateToBeneficiaryNavGraph()
104+
105+
is HomeNavigationDestination.Transaction ->
106+
navController.navigateToAccountTransactionsScreen(
107+
Constants.RECENT_TRANSACTIONS,
108+
-1L,
109+
)
110+
111+
is HomeNavigationDestination.ApplyLoan ->
112+
navController.navigateToLoanApplicationGraph()
113+
114+
is HomeNavigationDestination.ApplySavings ->
115+
navController.navigateToSavingsApplicationGraph()
116+
}
117+
}
91118

92119
notificationDestination(
93120
navigateBack = navController::popBackStack,
@@ -157,6 +184,10 @@ internal fun NavGraphBuilder.authenticatedGraph(
157184
navigateToStatusScreen = navController::navigateToStatusAfterUpdate,
158185
)
159186

187+
savingsApplicationNavGraph(
188+
navController = navController,
189+
)
190+
160191
passcodeDestination(
161192
onPasscodeConfirm = navController::popBackStack,
162193
)
@@ -220,6 +251,8 @@ internal fun NavGraphBuilder.authenticatedGraph(
220251
navigateToAuthenticateScreen = navController::navigateToVerifyPasscodeScreen,
221252
navigateToStatusScreen = navController::navigateToStatusAfterUpdate,
222253
)
254+
255+
faqDestination(onBackClick = navController::popBackStack, contact = {})
223256
}
224257
}
225258

cmp-navigation/src/commonMain/kotlin/cmp/navigation/authenticatednavbar/AuthenticatedNavbarNavigation.kt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.navigation.NavGraphBuilder
1616
import androidx.navigation.NavOptions
1717
import kotlinx.serialization.Serializable
1818
import org.mifos.mobile.core.ui.composableWithStayTransitions
19+
import org.mifos.mobile.feature.home.navigation.HomeNavigator
1920

2021
@Serializable
2122
data object AuthenticatedNavbarRoute
@@ -25,21 +26,11 @@ internal fun NavController.navigateToAuthenticatedNavBar(navOptions: NavOptions?
2526
}
2627

2728
internal fun NavGraphBuilder.authenticatedNavbarGraph(
28-
navigateToNotificationScreen: () -> Unit,
29-
navigateToAccountsScreen: (String) -> Unit,
30-
navigateToChargeScreen: () -> Unit,
31-
navigateToBeneficiaryScreen: () -> Unit,
32-
navigateToTransactionScreen: () -> Unit,
33-
navigateToApplyLoanScreen: () -> Unit,
29+
homeNavigator: HomeNavigator,
3430
) {
3531
composableWithStayTransitions<AuthenticatedNavbarRoute> {
3632
AuthenticatedNavbarNavigationScreen(
37-
navigateToNotificationScreen = navigateToNotificationScreen,
38-
navigateToAccountsScreen = { navigateToAccountsScreen(it) },
39-
navigateToChargeScreen = navigateToChargeScreen,
40-
navigateToBeneficiaryScreen = navigateToBeneficiaryScreen,
41-
navigateToTransactionScreen = navigateToTransactionScreen,
42-
navigateToApplyLoanScreen = navigateToApplyLoanScreen,
33+
homeNavigator = homeNavigator,
4334
)
4435
}
4536
}

cmp-navigation/src/commonMain/kotlin/cmp/navigation/authenticatednavbar/AuthenticatedNavbarNavigationScreen.kt

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,18 @@ import org.koin.compose.viewmodel.koinViewModel
4040
import org.mifos.mobile.core.ui.RootTransitionProviders
4141
import org.mifos.mobile.core.ui.navigation.NavigationItem
4242
import org.mifos.mobile.core.ui.utils.EventsEffect
43+
import org.mifos.mobile.feature.home.navigation.HomeNavigator
4344
import org.mifos.mobile.feature.home.navigation.HomeRoute
4445
import org.mifos.mobile.feature.home.navigation.homeDestination
4546
import org.mifos.mobile.feature.home.navigation.navigateToHomeScreen
46-
import org.mifos.mobile.feature.settings.faq.navigateToFaq
4747
import org.mifos.mobile.feature.settings.navigation.navigateToSettingsGraph
4848
import org.mifos.mobile.feature.settings.navigation.settingsGraph
4949
import org.mifos.mobile.navigation.generated.resources.Res
5050
import org.mifos.mobile.navigation.generated.resources.not_connected
5151

5252
@Composable
5353
internal fun AuthenticatedNavbarNavigationScreen(
54-
navigateToNotificationScreen: () -> Unit,
55-
navigateToAccountsScreen: (String) -> Unit,
56-
navigateToChargeScreen: () -> Unit,
57-
navigateToBeneficiaryScreen: () -> Unit,
58-
navigateToTransactionScreen: () -> Unit,
59-
navigateToApplyLoanScreen: () -> Unit,
54+
homeNavigator: HomeNavigator,
6055
modifier: Modifier = Modifier,
6156
navController: NavHostController = rememberMifosNavController(
6257
name = "AuthenticatedNavbarScreen",
@@ -107,24 +102,14 @@ internal fun AuthenticatedNavbarNavigationScreen(
107102
onAction = remember(viewModel) {
108103
{ viewModel.trySendAction(it) }
109104
},
110-
navigateToNotificationScreen = navigateToNotificationScreen,
111-
navigateToAccountsScreen = { navigateToAccountsScreen(it) },
112-
navigateToChargeScreen = navigateToChargeScreen,
113-
navigateToBeneficiaryScreen = navigateToBeneficiaryScreen,
114-
navigateToTransactionScreen = navigateToTransactionScreen,
115-
navigateToApplyLoanScreen = navigateToApplyLoanScreen,
105+
homeNavigator = homeNavigator,
116106
)
117107
}
118108

119109
@Composable
120110
internal fun AuthenticatedNavbarNavigationScreenContent(
121111
navController: NavHostController,
122-
navigateToNotificationScreen: () -> Unit,
123-
navigateToAccountsScreen: (String) -> Unit,
124-
navigateToChargeScreen: () -> Unit,
125-
navigateToBeneficiaryScreen: () -> Unit,
126-
navigateToTransactionScreen: () -> Unit,
127-
navigateToApplyLoanScreen: () -> Unit,
112+
homeNavigator: HomeNavigator,
128113
modifier: Modifier = Modifier,
129114
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
130115
onAction: (AuthenticatedNavBarAction) -> Unit,
@@ -175,21 +160,7 @@ internal fun AuthenticatedNavbarNavigationScreenContent(
175160
popExitTransition = RootTransitionProviders.Exit.fadeOut,
176161
) {
177162
// TODO Add top level destination screens
178-
179-
homeDestination(
180-
// navigateToDestinationScreen = {
181-
// navController.navigate(
182-
// it
183-
// )
184-
// },
185-
navigateToAccountsScreen = { navigateToAccountsScreen(it) },
186-
navigateToChargeScreen = navigateToChargeScreen,
187-
navigateToNotificationScreen = navigateToNotificationScreen,
188-
navigateToFaqScreen = navController::navigateToFaq,
189-
navigateToBeneficiaryScreen = navigateToBeneficiaryScreen,
190-
navigateToTransactionScreen = navigateToTransactionScreen,
191-
navigateToApplyLoanScreen = navigateToApplyLoanScreen,
192-
)
163+
homeDestination(onNavigate = homeNavigator)
193164

194165
settingsGraph(
195166
navController = navController,

cmp-navigation/src/commonMain/kotlin/cmp/navigation/di/KoinModules.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import org.mifos.mobile.feature.onboarding.language.di.SetOnboardingLanguageModu
3232
import org.mifos.mobile.feature.passcode.di.PasscodeModule
3333
import org.mifos.mobile.feature.qr.di.QrModule
3434
import org.mifos.mobile.feature.recent.transaction.di.recentTransactionModule
35+
import org.mifos.mobile.feature.savings.application.di.savingsApplicationModule
3536
import org.mifos.mobile.feature.savingsaccount.di.savingsAccountModule
3637
import org.mifos.mobile.feature.settings.di.SettingsModule
3738
import org.mifos.mobile.feature.shareaccount.di.shareAccountModule
@@ -79,6 +80,7 @@ object KoinModules {
7980
PasscodeModule,
8081
StatusModule,
8182
loanApplicationModule,
83+
savingsApplicationModule,
8284
)
8385
}
8486

core/common/src/commonMain/kotlin/org/mifos/mobile/core/common/Constants.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,6 @@ object Constants {
111111
const val APPLY_LOAN = "apply_loan"
112112
const val NAVIGATE_BACK_TO_SAVINGS = "navigate_back_to_savings"
113113
const val NAVIGATE_BACK_TO_LOAN = "navigate_back_to_loan"
114+
115+
const val APPLY_SAVINGS = "apply_savings"
114116
}

core/data/src/commonMain/kotlin/org/mifos/mobile/core/data/repository/SavingsAccountRepository.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ interface SavingsAccountRepository {
2727

2828
fun getSavingAccountApplicationTemplate(clientId: Long?): Flow<DataState<SavingsAccountTemplate>>
2929

30+
fun getSavingAccountApplicationTemplateByProduct(
31+
clientId: Long?,
32+
productId: Long?,
33+
): Flow<DataState<SavingsAccountTemplate>>
34+
3035
suspend fun submitSavingAccountApplication(payload: SavingsAccountApplicationPayload?): DataState<String>
3136

3237
suspend fun updateSavingsAccount(

core/data/src/commonMain/kotlin/org/mifos/mobile/core/data/repositoryImpl/SavingsAccountRepositoryImp.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ class SavingsAccountRepositoryImp(
4949
.asDataStateFlow().flowOn(ioDispatcher)
5050
}
5151

52+
override fun getSavingAccountApplicationTemplateByProduct(
53+
clientId: Long?,
54+
productId: Long?,
55+
): Flow<DataState<SavingsAccountTemplate>> {
56+
return dataManager.savingAccountsListApi.getSavingsAccountApplicationTemplateByProduct(
57+
clientId,
58+
productId,
59+
).asDataStateFlow().flowOn(ioDispatcher)
60+
}
61+
5262
override suspend fun submitSavingAccountApplication(
5363
payload: SavingsAccountApplicationPayload?,
5464
): DataState<String> {

core/designsystem/src/commonMain/kotlin/org/mifos/mobile/core/designsystem/icon/MifosIcons.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ import fluent.ui.system.icons.filled.QrCode
8989
import fluent.ui.system.icons.filled.QuestionCircle
9090
import fluent.ui.system.icons.filled.Receipt
9191
import fluent.ui.system.icons.filled.ReceiptMoney
92+
import fluent.ui.system.icons.filled.Savings
9293
import fluent.ui.system.icons.filled.SignOut
9394
import fluent.ui.system.icons.filled.TableCellEdit
9495
import fluent.ui.system.icons.filled.Wallet
@@ -191,6 +192,7 @@ object MifosIcons {
191192
val LoanAccount = FluentIcons.Filled.CoinMultiple
192193
val ShareAccount = FluentIcons.Filled.DataWhisker
193194
val ApplyForLoan = FluentIcons.Filled.Receipt
195+
val ApplyForSavings = FluentIcons.Filled.Savings
194196
val TransactionHistory = FluentIcons.Filled.ChatHistory
195197
val Charges = FluentIcons.Filled.Feed
196198
val Beneficiary = FluentIcons.Filled.ContactCardRibbon
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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.core.model.entity.templates.savings
11+
12+
import kotlinx.serialization.Serializable
13+
import org.mifos.mobile.core.model.Parcelable
14+
import org.mifos.mobile.core.model.Parcelize
15+
16+
@Serializable
17+
@Parcelize
18+
data class FieldOfficerOptions(
19+
val id: Int,
20+
val firstname: String? = null,
21+
val lastname: String? = null,
22+
val displayName: String? = null,
23+
val officeId: Int? = null,
24+
val officeName: String? = null,
25+
val isLoanOfficer: Boolean? = null,
26+
val isActive: Boolean? = null,
27+
) : Parcelable

0 commit comments

Comments
 (0)