Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,14 @@
<string name="client_apply_new_applications_apply_recurring_account">Apply for new recurring deposit account</string>
<string name="client_apply_new_applications_apply_fixed_account">Apply for new fixed deposit account</string>

<string name="step_details">Details</string>
<string name="step_terms">Terms</string>
<string name="step_settings">Settings</string>
<string name="step_interest">Interest</string>
<string name="step_charges">Charges</string>
<string name="create_recurring_deposit_account">Create Recurring Deposit Account</string>


<!-- Client Signature -->
<string name="client_signature_delete">Delete Signature</string>
<string name="client_signature_upload">Upload New Signature</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import kotlinx.serialization.Serializable

@Serializable
data object RecurringAccountRoute

fun NavGraphBuilder.recurringAccountDestination() {
composable<RecurringAccountRoute> {
RecurringAccountScreen(
onNavigateBack = {},
onFinish = {},
)
}
}

fun NavController.navigateToRecurringAccountRoute() {
this.navigate(
RecurringAccountRoute,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount

import androidclient.feature.client.generated.resources.Res
import androidclient.feature.client.generated.resources.create_recurring_deposit_account
import androidclient.feature.client.generated.resources.step_charges
import androidclient.feature.client.generated.resources.step_details
import androidclient.feature.client.generated.resources.step_interest
import androidclient.feature.client.generated.resources.step_settings
import androidclient.feature.client.generated.resources.step_terms
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mifos.core.designsystem.component.MifosScaffold
import com.mifos.core.ui.components.MifosStepper
import com.mifos.core.ui.components.Step
import com.mifos.core.ui.util.EventsEffect
import com.mifos.feature.client.createRecurringDepositAccount.pages.ChargesPage
import com.mifos.feature.client.createRecurringDepositAccount.pages.DetailsPage
import com.mifos.feature.client.createRecurringDepositAccount.pages.InterestPage
import com.mifos.feature.client.createRecurringDepositAccount.pages.SettingPage
import com.mifos.feature.client.createRecurringDepositAccount.pages.TermsPage
import org.jetbrains.compose.resources.stringResource

@Composable
internal fun RecurringAccountScreen(
onNavigateBack: () -> Unit,
onFinish: () -> Unit,
modifier: Modifier = Modifier,
viewModel: RecurringAccountViewModel = viewModel(),
) {
val state by viewModel.stateFlow.collectAsStateWithLifecycle()

EventsEffect(viewModel.eventFlow) { event ->
when (event) {
RecurringAccountEvent.NavigateBack -> onNavigateBack()
RecurringAccountEvent.Finish -> onFinish()
}
}

RecurringAccountScaffold(
modifier = modifier,
state = state,
onAction = { viewModel.trySendAction(it) },
)
}

@Composable
private fun RecurringAccountScaffold(
state: RecurringAccountState,
modifier: Modifier = Modifier,
onAction: (RecurringAccountAction) -> Unit,
) {
val steps = listOf(
Step(name = stringResource(Res.string.step_details)) {
DetailsPage(
onNext = { onAction(RecurringAccountAction.NextStep) },
)
},
Step(name = stringResource(Res.string.step_terms)) {
TermsPage(
onNext = { onAction(RecurringAccountAction.NextStep) },
)
},
Step(name = stringResource(Res.string.step_settings)) {
SettingPage(
onNext = { onAction(RecurringAccountAction.NextStep) },
)
},
Step(name = stringResource(Res.string.step_interest)) {
InterestPage(
onNext = { onAction(RecurringAccountAction.NextStep) },
)
},
Step(name = stringResource(Res.string.step_charges)) {
ChargesPage(
onNext = { onAction(RecurringAccountAction.NextStep) },
)
},
)

MifosScaffold(
title = stringResource(Res.string.create_recurring_deposit_account),
onBackPressed = { onAction(RecurringAccountAction.NavigateBack) },
modifier = modifier,
) { paddingValues ->
if (state.dialogState == null) {
MifosStepper(
steps = steps,
currentIndex = state.currentStep,
onStepChange = { newIndex ->
onAction(RecurringAccountAction.OnStepChange(newIndex))
},
modifier = Modifier
.fillMaxWidth()
.padding(paddingValues),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount

import com.mifos.core.ui.util.BaseViewModel
import kotlinx.coroutines.flow.update

class RecurringAccountViewModel :
BaseViewModel<RecurringAccountState, RecurringAccountEvent, RecurringAccountAction>(RecurringAccountState()) {

override fun handleAction(action: RecurringAccountAction) {
when (action) {
RecurringAccountAction.NextStep -> {
mutableStateFlow.update { state ->
val maxIndex = 4
state.copy(currentStep = (state.currentStep + 1).coerceAtMost(maxIndex))
}
}
is RecurringAccountAction.OnStepChange -> {
mutableStateFlow.update { it.copy(currentStep = action.index) }
}
RecurringAccountAction.NavigateBack -> {
sendEvent(RecurringAccountEvent.NavigateBack)
}
RecurringAccountAction.Finish -> {
sendEvent(RecurringAccountEvent.Finish)
}
}
}
}

data class RecurringAccountState(
val currentStep: Int = 0,
val dialogState: Any? = null,
)

sealed class RecurringAccountAction {
object NextStep : RecurringAccountAction()
data class OnStepChange(val index: Int) : RecurringAccountAction()
object NavigateBack : RecurringAccountAction()
object Finish : RecurringAccountAction()
}

sealed class RecurringAccountEvent {
object NavigateBack : RecurringAccountEvent()
object Finish : RecurringAccountEvent()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount.pages

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
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

@Composable
fun ChargesPage(onNext: () -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Charges Page")
Spacer(Modifier.height(8.dp))
Button(onClick = onNext) {
Text("Next Button")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount.pages

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
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

@Composable
fun DetailsPage(onNext: () -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Details Page")
Spacer(Modifier.height(8.dp))
Button(onClick = onNext) {
Text("Next Button")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount.pages

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
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

@Composable
fun InterestPage(onNext: () -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Interest Page")
Spacer(Modifier.height(8.dp))
Button(onClick = onNext) {
Text("Next Button")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount.pages

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
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

@Composable
fun SettingPage(onNext: () -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Settings Page")
Spacer(Modifier.height(8.dp))
Button(onClick = onNext) {
Text("Next Button")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.client.createRecurringDepositAccount.pages

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
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

@Composable
fun TermsPage(onNext: () -> Unit) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Terms Page")
Spacer(Modifier.height(8.dp))
Button(onClick = onNext) {
Text("Next Button")
}
}
}
Loading