Skip to content

Conversation

@Aryan-Baglane
Copy link
Contributor

@Aryan-Baglane Aryan-Baglane commented Dec 9, 2025

Fixes - MM-452

After
image

Please make sure these boxes are checked before submitting your pull request - thanks!

  • Run the static analysis check ./gradlew check or ci-prepush.sh to make sure you didn't break anything

  • [] If you have multiple commits please combine them into one commit by squashing them.

Summary by CodeRabbit

  • New Features

    • Full Recent Transactions screen with improved list UI, date/amount formatting, modal filter sheet, filter chips (All/Debit/Credit), account filter, and retry error UI.
    • Transaction history navigation updated to open the new recent transactions view.
  • Refactor

    • State and navigation redesigned for action-driven flows and clearer UI states (loading, empty, error, content).

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Walkthrough

Renamed Home navigation destination from Transaction to TransactionHistory, replaced navigation call to navigateToRecentTransactionScreen(), redesigned RecentTransactionScreen as a composable-driven UI with filter sheet and new UI components, and refactored the RecentTransactionViewModel to an action-driven state machine using AccountsRepository and SavingsAccountRepository with an exposed uiState.

Changes

Cohort / File(s) Summary
Navigation updates
cmp-navigation/src/commonMain/kotlin/.../AuthenticatedNavigation.kt, feature/home/src/commonMain/kotlin/.../HomeScreen.kt, feature/home/src/commonMain/kotlin/.../HomeNavigation.kt
Renamed HomeNavigationDestination.TransactionHomeNavigationDestination.TransactionHistory, added AccountsWithType data class, and changed navigation call from navigateToAccountTransactionsScreen(...) to navigateToRecentTransactionScreen().
RecentTransaction UI
feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/screen/RecentTransactionScreen.kt
Full rewrite to a composable-driven screen (Scaffold, TopAppBar, modal bottom sheet). Added public composables: RecentTransactionScreen, TransactionItem, TransactionList, ErrorScreen, TransactionFilterSheetContent, FilterOptionChip. Integrated viewModel-backed state rendering and filter UI.
UI state model
feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/utils/RecentTransactionState.kt
Replaced simple state with RecentTransactionUiState, nested ViewState (Loading/Empty/Error/Content), TransactionFilterType enum, and RecentTransactionAction sealed interface (user actions and internal events). Switched types to SavingAccount and Transactions.
ViewModel refactor
feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/viewmodel/RecentTransactionViewModel.kt
Constructor now depends on AccountsRepository and SavingsAccountRepository. Added public val uiState: StateFlow<RecentTransactionUiState> and fun handleAction(action: RecentTransactionAction). Implemented action-driven loading, local caching, client-side filtering, network status propagation, and segmented load/error handlers.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Screen as RecentTransactionScreen
    participant VM as RecentTransactionViewModel
    participant AccountsRepo as AccountsRepository
    participant SavingsRepo as SavingsAccountRepository
    participant Network as NetworkMonitor

    User->>Screen: open RecentTransactionScreen
    Screen->>VM: handleAction(LoadInitial)

    par Parallel loads
        VM->>AccountsRepo: fetchAccounts()
        AccountsRepo-->>VM: AccountsLoaded(accounts)
    and
        VM->>SavingsRepo: loadTransactions(account?, offset?)
        SavingsRepo-->>VM: TransactionsLoaded(items)
    and
        Network->>VM: network status updates
    end

    VM->>VM: compose RecentTransactionUiState (applyLocalFilters)
    VM-->>Screen: emit uiState (Content / Loading / Error)
    Screen->>Screen: render UI (list / sheet / error)

    User->>Screen: open filter sheet
    Screen->>VM: handleAction(ToggleFilter) / handleAction(ApplyFilter(...))
    VM->>VM: applyLocalFilters -> update uiState
    VM-->>Screen: emit updated uiState
    Screen->>Screen: re-render filtered list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus review on ViewModel refactor (action routing, state transitions, error handling).
  • Verify RecentTransactionScreen composition and modal bottom sheet lifecycle.
  • Validate local filtering logic, debit/credit classification, and use of Transactions/SavingAccount models.
  • Confirm navigation rename consistency across modules.

Suggested reviewers

  • WizCoderr
  • revanthkumarJ
  • Nagarjuna0033

Poem

🐰 I hopped through code, a curious sight,

Filters and states all glowing bright.
Actions now lead the transaction parade,
History found where old names played.
A joyful leap — the rabbit's delight!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Features/recent transaction screen' is vague and overly broad, using generic phrasing that doesn't clearly convey the specific changes made in the PR. Use a more specific and descriptive title that highlights the main objective, such as 'Refactor RecentTransactionScreen with new UI state management' or 'Replace Transaction with TransactionHistory navigation destination'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f84d307 and 5c75fb5.

📒 Files selected for processing (1)
  • cmp-navigation/src/commonMain/kotlin/cmp/navigation/authenticated/AuthenticatedNavigation.kt (2 hunks)
🔇 Additional comments (2)
cmp-navigation/src/commonMain/kotlin/cmp/navigation/authenticated/AuthenticatedNavigation.kt (2)

56-56: LGTM!

The import correctly references the navigation function used on line 118.


117-118: Verify no duplicate branches exist for the TransactionHistory destination.

The navigation refactoring from HomeNavigationDestination.Transaction to HomeNavigationDestination.TransactionHistory and the corresponding call to navigateToRecentTransactionScreen() requires verification:

  1. Confirm no duplicate when branches for TransactionHistory exist in the full when expression
  2. Verify that HomeNavigationDestination.TransactionHistory is properly defined in the destination sealed class
  3. Verify that the navigateToRecentTransactionScreen() function is implemented and accessible

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/utils/RecentTransactionState.kt (1)

39-61: Consider removing redundant list property in ViewState.Content.

RecentTransactionUiState already has a transactions field at lines 42, and ViewState.Content duplicates this with its own list property. This creates potential for state inconsistency if they diverge. Consider making Content a data object like Empty, since the transactions are already available from the parent state.

 sealed interface ViewState {
     data object Loading : ViewState
     data object Empty : ViewState
     data class Error(val message: String?) : ViewState
-    data class Content(val list: List<Transactions>) : ViewState
+    data object Content : ViewState
 }
feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/screen/RecentTransactionScreen.kt (4)

80-128: Move back button to navigationIcon slot.

The back IconButton is placed inside the title composable, which is unconventional for Material Design. Use the navigationIcon slot of TopAppBar for proper layout and accessibility.

 TopAppBar(
     title = {
         Column {
-            Row(verticalAlignment = Alignment.CenterVertically) {
-                IconButton(onClick = navigateBack) {
-                    Icon(
-                        imageVector = MifosIcons.ArrowBack,
-                        contentDescription = "Back",
-                    )
-                }
-
-                Text(
-                    text = "Transaction History",
-                    style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
-                    modifier = Modifier.padding(end = 8.dp),
-                )
-            }
+            Text(
+                text = "Transaction History",
+                style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
+            )
             state.selectedAccount?.let { account ->
                 Text(
                     text = account.accountNo ?: "Selected Account",
                     ...
                 )
             }
         }
     },
+    navigationIcon = {
+        IconButton(onClick = navigateBack) {
+            Icon(
+                imageVector = MifosIcons.ArrowBack,
+                contentDescription = "Back",
+            )
+        }
+    },
     actions = { ... },
 )

190-191: Use theme colors instead of hardcoded values.

Hardcoded Color(0xFF0A7E48) and Color.Red won't adapt to dark mode and may conflict with the app's color scheme. Consider defining semantic colors in the theme (e.g., MaterialTheme.colorScheme.tertiary for credit, MaterialTheme.colorScheme.error for debit) or using a custom color palette.


256-282: Add key parameter and pagination trigger.

  1. itemsIndexed should use a key parameter for stable item identity, improving performance and preventing UI glitches during list updates.
  2. The LoadMore action is defined but never triggered. Consider adding pagination detection.
 LazyColumn(
     modifier = modifier.fillMaxSize(),
 ) {
     itemsIndexed(
         items = transactions,
+        key = { _, transaction -> transaction.id ?: it }
     ) { index, transaction ->
         TransactionItem(
             transaction = transaction,
         )
         if (index != transactions.size - 1) {
             HorizontalDivider(...)
         }
+        // Trigger pagination when reaching near the end
+        if (index == transactions.size - 5) {
+            // Consider calling viewModel.handleAction(RecentTransactionAction.LoadMore(...))
+        }
     }
 }

354-414: Hardcoded colors break dark mode support.

Color.White, Color.Gray, and Color.Black (lines 361, 381, 387, 397) won't adapt to dark theme. Use semantic theme colors like MaterialTheme.colorScheme.surface, MaterialTheme.colorScheme.onSurfaceVariant, and MaterialTheme.colorScheme.onSurface.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c69ebf and f84d307.

📒 Files selected for processing (6)
  • cmp-navigation/src/commonMain/kotlin/cmp/navigation/authenticated/AuthenticatedNavigation.kt (2 hunks)
  • feature/home/src/commonMain/kotlin/org/mifos/mobile/feature/home/HomeScreen.kt (1 hunks)
  • feature/home/src/commonMain/kotlin/org/mifos/mobile/feature/home/navigation/HomeNavigation.kt (1 hunks)
  • feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/screen/RecentTransactionScreen.kt (1 hunks)
  • feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/utils/RecentTransactionState.kt (1 hunks)
  • feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/viewmodel/RecentTransactionViewModel.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/viewmodel/RecentTransactionViewModel.kt (5)
feature/accounts/src/commonMain/kotlin/org/mifos/mobile/feature/accounts/accounts/AccountsViewModel.kt (1)
  • handleAction (45-89)
feature/share-account/src/commonMain/kotlin/org/mifos/mobile/feature/shareaccount/shareAccount/ShareAccountViewModel.kt (1)
  • handleAction (56-84)
feature/savings-account/src/commonMain/kotlin/org/mifos/mobile/feature/savingsaccount/savingsAccountDetails/SavingsAccountDetailsViewModel.kt (1)
  • handleAction (100-123)
feature/client-charge/src/commonMain/kotlin/org/mifos/mobile/feature/charge/chargeDetails/ChargeDetailsViewModel.kt (1)
  • handleAction (55-65)
feature/client-charge/src/commonMain/kotlin/org/mifos/mobile/feature/charge/charges/ClientChargeViewModel.kt (1)
  • handleAction (106-126)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: PR Checks KMP / Static Analysis Check
🔇 Additional comments (9)
feature/home/src/commonMain/kotlin/org/mifos/mobile/feature/home/navigation/HomeNavigation.kt (2)

36-36: LGTM!

The new AccountsWithType data class provides a clean, parameterized navigation destination for different account types.


32-32: Verify that all usages of the renamed destination have been updated.

The renaming from Transaction to TransactionHistory is a breaking change to the navigation API. Confirm all references throughout the codebase have been updated consistently by searching for any remaining references to the old Transaction destination name and verifying that all call sites now use TransactionHistory.

feature/home/src/commonMain/kotlin/org/mifos/mobile/feature/home/HomeScreen.kt (1)

93-93: LGTM!

The navigation update correctly uses the renamed TransactionHistory destination, consistent with the changes in HomeNavigation.kt.

feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/utils/RecentTransactionState.kt (1)

66-81: LGTM! Well-structured action hierarchy.

The separation of user-initiated actions from internal events using a nested Internal sealed interface is consistent with other ViewModels in the codebase (e.g., ClientChargeAction, ShareAccountsAction). This cleanly distinguishes public API from internal state machine events.

feature/recent-transaction/src/commonMain/kotlin/org/mifos/mobile/feature/recent/transaction/viewmodel/RecentTransactionViewModel.kt (5)

49-64: LGTM! Proper reactive initialization.

Network status monitoring with launchIn and clientId observation with collect are correctly set up in the init block. Each clientId change triggering LoadInitial handles re-login scenarios appropriately.


126-140: LGTM! Account fetching logic is sound.

The method correctly filters for active savings accounts and dispatches appropriate internal actions. The clientId being nullable is handled upstream by the init block flow that only triggers LoadInitial when clientId is non-null.


162-183: Potential double error handling between catch and DataState.Error.

Both the catch operator (line 167) and DataState.Error branch (line 177-179) call handleAction(Internal.LoadFailed(...)). If the repository emits DataState.Error, both paths could potentially execute, though typically catch handles upstream exceptions while collect handles downstream emissions.

Verify whether this is the intended behavior or if the catch should be removed since error states are already handled via DataState.Error.


216-228: LGTM! Robust transaction type detection.

The isTransactionCreditLogic method correctly prioritizes explicit boolean flags (deposit, withdrawal) before falling back to string matching on the transaction type value. This defensive approach handles various data representations well.


70-74: Pagination implementation requires manual verification.

The review claims that the offset parameter in LoadMore is unused and canPaginate is always false, but these assertions require direct codebase inspection to confirm. Verify:

  1. Whether LoadMore.offset is read anywhere in the action handler or related methods.
  2. Whether canPaginate is always set to false or if there are conditions that set it to true.
  3. If pagination is intentionally deferred, add a TODO comment; otherwise, remove unused code.

@therajanmaurya therajanmaurya merged commit 92ee759 into openMF:development Dec 12, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants