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 @@ -14,6 +14,11 @@ import org.koin.dsl.module
import org.mifos.mobile.feature.share.application.fillApplication.ShareFillApplicationViewModel
import org.mifos.mobile.feature.share.application.shareApplication.ShareApplyViewModel

/**
* Koin module for the Share Application feature.
*
* This module provides the ViewModels required for the share application screens.
*/
val shareApplicationModule = module {
viewModelOf(::ShareApplyViewModel)
viewModelOf(::ShareFillApplicationViewModel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,36 @@ import androidx.navigation.NavOptions
import kotlinx.serialization.Serializable
import org.mifos.mobile.core.ui.composableWithSlideTransitions

/**
* A serializable data class representing the route to the Share Fill Application screen.
*
* @property shareProductId The ID of the share product to apply for.
*/
@Serializable
data class ShareFillApplicationRoute(
val shareProductId: Long,
)

/**
* Navigates to the Share Fill Application screen.
*
* @param shareProductId The ID of the share product.
* @param navOptions Optional navigation options.
*/
fun NavController.navigateToShareFillApplicationScreen(
shareProductId: Long,
navOptions: NavOptions? = null,
) {
this.navigate(ShareFillApplicationRoute(shareProductId), navOptions)
}

/**
* Defines the destination for the Share Fill Application screen in the navigation graph.
*
* @param navigateToAuthenticateScreen A function to navigate to the authentication screen.
* @param navigateToStatusScreen A function to navigate to the status screen.
* @param navigateBack A function to navigate back to the previous screen.
*/
fun NavGraphBuilder.shareFillApplicationDestination(
navigateToAuthenticateScreen: () -> Unit,
navigateToStatusScreen: (String, String, String, String, String) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ import org.mifos.mobile.core.ui.component.MifosProgressIndicator
import org.mifos.mobile.core.ui.component.MifosProgressIndicatorOverlay
import org.mifos.mobile.core.ui.utils.EventsEffect

/**
* A Composable function that represents the Share Fill Application screen.
*
* @param navigateBack A function to navigate back to the previous screen.
* @param navigateToStatusScreen A function to navigate to the status screen.
* @param navigateToAuthenticateScreen A function to navigate to the authentication screen.
* @param viewModel An instance of [ShareFillApplicationViewModel].
*/
@Composable
internal fun ShareFillApplicationScreen(
navigateBack: () -> Unit,
Expand Down Expand Up @@ -104,6 +112,12 @@ internal fun ShareFillApplicationScreen(
)
}

/**
* A Composable function that displays a dialog based on the [ShareApplicationDialogState].
*
* @param dialogState The state of the dialog to be displayed.
* @param onAction A function to handle actions from the dialog.
*/
@Composable
internal fun ShareFillApplicationDialog(
dialogState: ShareApplicationDialogState?,
Expand All @@ -130,6 +144,13 @@ internal fun ShareFillApplicationDialog(
}
}

/**
* A Composable function that displays the content of the Share Fill Application screen.
*
* @param state The current state of the screen.
* @param onAction A function to handle actions from the screen.
* @param modifier A [Modifier] for the Composable.
*/
@Composable
internal fun ShareFillApplicationContent(
state: ShareApplicationState,
Expand Down Expand Up @@ -182,6 +203,13 @@ internal fun ShareFillApplicationContent(
}
}

/**
* A Composable function that displays the form for the Share Fill Application screen.
*
* @param state The current state of the screen.
* @param onAction A function to handle actions from the screen.
* @param modifier A [Modifier] for the Composable.
*/
@Composable
internal fun ShareFillApplicationForm(
state: ShareApplicationState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ internal class ShareFillApplicationViewModel(
accountsRepositoryImpl.loadAccounts(
clientId = state.clientId,
accountType = Constants.SAVINGS_ACCOUNTS,
).catch {
).catch { e ->
mutableStateFlow.update {
it.copy(
uiState = ShareApplicationUiState.Error(Res.string.feature_apply_share_error_server),
Expand Down Expand Up @@ -315,7 +315,6 @@ internal class ShareFillApplicationViewModel(
}
is DataState.Success -> {
val shareTemplate = response.data
println(shareTemplate)
updateState {
it.copy(
defaultAccounts = shareTemplate.savingsAccounts ?: emptyList(),
Expand Down Expand Up @@ -348,8 +347,6 @@ internal class ShareFillApplicationViewModel(
}
is DataState.Success -> {
val shareTemplate = template.data ?: return
println(shareTemplate)
println(shareTemplate.accountingMappings?.toAccountList())
updateState {
it.copy(
currency = shareTemplate.currency ?: Currency(),
Expand Down Expand Up @@ -380,10 +377,6 @@ internal class ShareFillApplicationViewModel(
updateState { it.copy(uiState = ShareApplicationUiState.Loading) }
}

/**
* Sets the UI state to `OverlayLoading`.
*/

/**
* Sets the dialog state to an `Error` dialog.
*
Expand Down Expand Up @@ -452,7 +445,7 @@ internal class ShareFillApplicationViewModel(
*/
private fun validateTotalShares(newValue: String): ValidationResult = when {
newValue.isBlank() -> ValidationResult.Error(Res.string.feature_apply_share_error_shares_required)
newValue.toIntOrNull() == null -> ValidationResult.Error(Res.string.feature_apply_share_shares_invalid)
newValue.toLongOrNull() == null -> ValidationResult.Error(Res.string.feature_apply_share_shares_invalid)
else -> ValidationResult.Success
}

Expand Down Expand Up @@ -783,6 +776,7 @@ internal class ShareFillApplicationViewModel(
* @property networkStatus The current network connectivity status.
* @property dialogState The state of the dialog to be displayed.
* @property uiState The overall UI state (e.g., loading, success, error).
* @property showOverlay A flag to show an overlay progress indicator.
*/
@OptIn(ExperimentalMaterial3Api::class)
internal data class ShareApplicationState(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,28 @@ import org.mifos.mobile.feature.share.application.fillApplication.shareFillAppli
import org.mifos.mobile.feature.share.application.shareApplication.ShareApplyRoute
import org.mifos.mobile.feature.share.application.shareApplication.shareApplyDestination

/**
* A serializable object representing the navigation graph for the Share Application feature.
*/
@Serializable
data object ShareApplicationNavGraph

/**
* Navigates to the Share Application navigation graph.
*
* @param navOptions Optional navigation options.
*/
fun NavController.navigateToShareApplicationGraph(navOptions: NavOptions? = null) {
this.navigate(ShareApplicationNavGraph, navOptions)
}

/**
* Defines the navigation graph for the Share Application feature.
*
* @param navController The [NavController] for the graph.
* @param navigateToAuthenticateScreen A function to navigate to the authentication screen.
* @param navigateToStatusScreen A function to navigate to the status screen.
*/
fun NavGraphBuilder.shareApplicationNavGraph(
navController: NavController,
navigateToAuthenticateScreen: () -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,28 @@ import androidx.navigation.NavOptions
import kotlinx.serialization.Serializable
import org.mifos.mobile.core.ui.composableWithSlideTransitions

/**
* A serializable object representing the route to the Share Apply screen.
*/
@Serializable
data object ShareApplyRoute

/**
* Navigates to the Share Apply screen.
*
* @param navOptions Optional navigation options.
*/
fun NavController.navigateToShareApplyScreen(
navOptions: NavOptions? = null,
) =
navigate(ShareApplyRoute, navOptions)

/**
* Defines the destination for the Share Apply screen in the navigation graph.
*
* @param navigateToFillDetailsScreen A function to navigate to the fill details screen.
* @param navigateBack A function to navigate back to the previous screen.
*/
fun NavGraphBuilder.shareApplyDestination(
navigateToFillDetailsScreen: (Long) -> Unit,
navigateBack: () -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ import org.mifos.mobile.core.ui.component.MifosPoweredCard
import org.mifos.mobile.core.ui.component.MifosProgressIndicator
import org.mifos.mobile.core.ui.utils.EventsEffect

/**
* A Composable function that represents the Share Apply screen.
*
* @param navigateBack A function to navigate back to the previous screen.
* @param navigateToFillDetailsScreen A function to navigate to the fill details screen.
* @param viewModel An instance of [ShareApplyViewModel].
*/
@Composable
internal fun ShareApplyScreen(
navigateBack: () -> Unit,
Expand Down Expand Up @@ -85,6 +92,12 @@ internal fun ShareApplyScreen(
)
}

/**
* A Composable function that displays a dialog based on the [ShareApplicationDialogState].
*
* @param dialogState The state of the dialog to be displayed.
* @param onAction A function to handle actions from the dialog.
*/
@Composable
internal fun ShareApplicationDialog(
dialogState: ShareApplicationDialogState?,
Expand All @@ -105,6 +118,13 @@ internal fun ShareApplicationDialog(
}
}

/**
* A Composable function that displays the content of the Share Application screen.
*
* @param state The current state of the screen.
* @param onAction A function to handle actions from the screen.
* @param modifier A [Modifier] for the Composable.
*/
@Composable
internal fun ShareApplicationContent(
state: ShareApplicationState,
Expand Down Expand Up @@ -163,6 +183,13 @@ internal fun ShareApplicationContent(
}
}

/**
* A Composable function that displays the form for the Share Application screen.
*
* @param state The current state of the screen.
* @param onAction A function to handle actions from the screen.
* @param modifier A [Modifier] for the Composable.
*/
@Composable
internal fun ShareApplicationForm(
state: ShareApplicationState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ internal class ShareApplyViewModel(
observeNetworkStatus()
}

/*
* Functions related to Data Observation and Fetching
*/

/**
* Observes the network connectivity status and updates the UI state accordingly.
* If the network is unavailable, it sets the `networkUnavailable` flag in the state
Expand Down Expand Up @@ -98,7 +94,7 @@ internal class ShareApplyViewModel(
* When the app is **online**:
* - It immediately updates the `networkStatus` in the state to `true`.
* - It then triggers essential functions to **refresh data** and ensure the UI is up-to-date,
* specifically by calling `unreadNotificationsCount()` and `loadClientAccountDetails()`.
* specifically by calling `getClientDataAndTemplate()`.
*
* @param isOnline A `Boolean` indicating the current network connectivity status.
*
Expand All @@ -125,8 +121,7 @@ internal class ShareApplyViewModel(
}

/**
* Fetches client data, a generic share template, and a product-specific loan purpose template
* from the repositories.
* Fetches client data and a generic share template from the repositories.
* The results are combined and handled in a single flow to manage loading and error states.
*/
private fun getClientDataAndTemplate() {
Expand Down Expand Up @@ -166,6 +161,7 @@ internal class ShareApplyViewModel(
* Updates the state with product options and currency on success,
* or displays an error and navigates back on failure.
*
* @param client The [DataState] containing the client data.
* @param template The [DataState] containing the savings template data.
*/
private fun handleClientAndSavingsTemplate(
Expand Down Expand Up @@ -202,7 +198,7 @@ internal class ShareApplyViewModel(

/**
* Retries the data fetching process. If the network is unavailable, it shows
* a network error dialog. Otherwise, it triggers the `fetchShareTemplate` `fetchClient`,
* a network error dialog. Otherwise, it triggers the `getClientDataAndTemplate` function.
*/
private fun retry() {
viewModelScope.launch {
Expand All @@ -214,10 +210,6 @@ internal class ShareApplyViewModel(
}
}

/*
* Functions related to UI State and Dialogs
*/

/**
* A helper function to update the mutable state flow.
*
Expand Down Expand Up @@ -252,10 +244,6 @@ internal class ShareApplyViewModel(
}
}

/*
* Functions related to User Input and Validation
*/

/**
* Handles incoming actions from the UI and dispatches them to the appropriate
* business logic functions.
Expand Down Expand Up @@ -287,8 +275,7 @@ internal class ShareApplyViewModel(

/**
* Handles changes to the selected savings product.
* It updates the state, fetches the corresponding field officer options,
* and debounces validation.
* It updates the state with the new product ID and name.
*
* @param id The ID of the selected savings product.
* @param name The name of the selected savings product.
Expand Down Expand Up @@ -331,10 +318,6 @@ internal class ShareApplyViewModel(
}
}

/*
* Functions related to Navigation and Lifecycle
*/

/**
* Handles the back navigation. If there are unsaved changes, it shows a
* confirmation dialog. Otherwise, it sends an event to navigate back.
Expand All @@ -360,11 +343,13 @@ internal class ShareApplyViewModel(
* @property clientId The ID of the current client.
* @property applicantName The name of the applicant.
* @property productOptions A list of available savings product options.
* @property selectedShareProduct The name of the selected share product.
* @property selectedShareProductId The ID of the selected share product.
* @property dialogState The state of any dialogs that overlay the main content.
* @property savingsProductTemplate The full savings template object for the selected product.
* @property hasChanges A boolean indicating if there are unsaved changes.
* @property networkStatus A boolean indicating if the network is unavailable.
* @property uiState The primary UI state of the screen (e.g., Loading, Empty, Success).
* @property dialogState The state of any dialogs that overlay the main content.
*/
@OptIn(ExperimentalMaterial3Api::class)
internal data class ShareApplicationState(
Expand Down Expand Up @@ -399,6 +384,9 @@ internal data class ShareApplicationState(
}
.toMap()

/**
* The current date formatted as a string.
*/
@OptIn(ExperimentalTime::class)
val submittedOnDate: String
get() {
Expand Down Expand Up @@ -496,8 +484,9 @@ internal sealed interface ShareApplicationAction {
data class ReceiveNetworkResult(val isOnline: Boolean) : ShareApplicationAction

/**
* An internal action to handle the result of fetching a savings template.
* @property template The [DataState] containing the savings template data.
* An internal action to handle the result of fetching client and template data.
* @property client The [DataState] containing the client data.
* @property template The [DataState] containing the share product data.
*/
data class ReceiveClientAndTemplateResult(
val client: DataState<Client>,
Expand Down
Loading