Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Create donation flow (kids-1421) #1085

Merged
merged 9 commits into from
Sep 23, 2024

Conversation

Daniela510
Copy link
Contributor

@Daniela510 Daniela510 commented Sep 23, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Added a new event type parentReflectionFlowOrganisationClicked for enhanced analytics tracking.
    • Introduced streamlined access to GiveBloc and MediumCubit through dependency injection, improving code maintainability.
    • Enhanced GratefulScreen functionality with improved state handling and navigation for donation flows.
  • Bug Fixes

    • Simplified profile filtering in GratefulCubit to retain all children regardless of gratitude status.
  • Refactor

    • Refactored state management in various pages to use dependency injection for better clarity and maintainability.

@Daniela510 Daniela510 requested a review from a team as a code owner September 23, 2024 11:35
Copy link
Contributor

coderabbitai bot commented Sep 23, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The pull request introduces several changes across multiple files, primarily enhancing the AmplitudeEvents enum by adding a new event value. It also refines the dependency injection setup by registering new instances of MediumCubit and GiveBloc, transitioning from context-based retrieval to a more streamlined approach. Additionally, the state management for these blocs is improved, and new methods are introduced to facilitate donation handling and navigation within the application.

Changes

File Change Summary
lib/core/enums/amplitude_events.dart Added new enum value parentReflectionFlowOrganisationClicked with identifier 'parent_reflection_flow_organisation_clicked'.
lib/features/family/app/injection.dart Added imports and registered new singletons for MediumCubit and GiveBloc in the dependency injection setup.
lib/features/family/features/reflect/bloc/grateful_cubit.dart Simplified profile filtering logic and added new method onParentDonated for handling parent donations.
lib/features/family/features/reflect/presentation/pages/grateful_screen.dart Introduced BlocListener for GiveBloc to manage giving state changes and added new navigation methods for child and parent donation flows.

Possibly related PRs

Suggested reviewers

  • TammiLion
  • MaikelStuivenberg

🐇 In the code we hop and play,
New events come out to stay.
With blocs and cubits, we refine,
A smoother path, oh how divine!
So let us cheer, with joy we sing,
For every change, new joy it brings! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@@ -53,6 +55,15 @@ void initCubits() {
..registerLazySingleton<CameraCubit>(
CameraCubit.new,
)
..registerLazySingleton<MediumCubit>(MediumCubit.new)
..registerLazySingleton<GiveBloc>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice work!

Copy link
Contributor

@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

Outside diff range and nitpick comments (11)
lib/features/family/features/parent_giving_flow/presentation/pages/parent_amount_page.dart (2)

81-91: Improved floating action button layout and positioning

The changes to the floatingActionButton and floatingActionButtonLocation enhance the user interface:

  1. Centering the button at the bottom of the screen improves accessibility and follows material design guidelines.
  2. Adding horizontal padding ensures the button doesn't stretch edge-to-edge on larger screens, improving aesthetics.
  3. The functionality of the button (navigation and analytics) remains intact.

These improvements align well with creating an effective donation flow.

Consider adding some bottom padding to the Padding widget to ensure the button isn't too close to the edge of the screen on devices with rounded corners or gesture areas. For example:

 floatingActionButton: Padding(
-  padding: const EdgeInsets.symmetric(horizontal: 24),
+  padding: const EdgeInsets.fromLTRB(24, 0, 24, 16),
   child: FunButton(
     // ... existing code
   ),
 ),

Line range hint 31-35: Minor improvements for consistency and clarity

  1. The initialamount variable doesn't follow Dart naming conventions. Consider renaming it to initialAmount.
  2. For clarity, you might want to add a comment explaining why the initial amount is set to 5.

Apply this diff to address these points:

- final initialamount = 5;
+ // Default initial donation amount set to 5 (currency units)
+ final initialAmount = 5;
  late int _amount;
  @override
  void initState() {
    super.initState();
-   _amount = initialamount;
+   _amount = initialAmount;
  }

Also, update the FunCounter widget to use initialAmount:

 FunCounter(
   currency: widget.currency,
-  initialAmount: initialamount,
+  initialAmount: initialAmount,
   onAmountChanged: (amount) => setState(() {
     _amount = amount;
   }),
 ),
lib/features/family/features/parent_giving_flow/presentation/pages/give_from_list_page.dart (3)

33-38: Good refactoring: Consistent use of dependency injection.

The changes in the listener callback are good:

  1. Using the give variable instead of context.read<GiveBloc>() improves consistency and readability.
  2. Switching to getIt<MediumCubit>() aligns with the dependency injection approach.

These changes maintain the existing logic while improving the code structure.

For consistency, consider extracting getIt<MediumCubit>() to a local variable at the beginning of the build method, similar to how give is handled:

final give = getIt<GiveBloc>();
final mediumCubit = getIt<MediumCubit>();

This would make the code even more consistent and easier to maintain.


77-77: Good refactoring: Consistent use of dependency injection in navigation method.

The changes in the _navigateToGivingScreen method are appropriate:

  1. Using getIt<MediumCubit>() and getIt<GiveBloc>() is consistent with the dependency injection approach.
  2. The logic for setting the medium ID and adding the GiveAmountChanged event is preserved.
  3. Removing the dependency on BuildContext for accessing these instances improves the method's flexibility.

For consistency and to potentially improve performance, consider extracting the getIt calls to local variables at the beginning of the method:

Future<void> _navigateToGivingScreen(
  BuildContext context,
  CollectGroup collectGroup,
) async {
  final mediumCubit = getIt<MediumCubit>();
  final giveBloc = getIt<GiveBloc>();
  
  // ... rest of the method ...
  
  mediumCubit.setMediumId(collectGroup.nameSpace);
  
  // ... rest of the method ...
  
  giveBloc.add(
    GiveAmountChanged(
      // ... event parameters ...
    ),
  );
}

This would make the code more consistent with the changes in the build method and potentially reduce repeated calls to getIt.

Also applies to: 98-104


Line range hint 1-107: Overall: Excellent refactoring towards dependency injection.

The changes in this file represent a significant improvement in code structure and maintainability:

  1. Consistent use of getIt for dependency injection throughout the file.
  2. Reduced reliance on BuildContext for accessing bloc and cubit instances.
  3. Improved readability with the introduction of local variables for frequently used instances.

These changes make the code more modular, easier to test, and align with best practices for state management in Flutter.

To further improve the architecture:

  1. Consider creating a ServiceLocator class to encapsulate all getIt calls. This would make it easier to mock dependencies in tests and provide a single point of control for dependency injection.
  2. If not already done, ensure that the GiveBloc and MediumCubit are registered as singletons in the dependency injection setup to maintain consistent state across the app.
lib/features/family/app/injection.dart (2)

59-66: LGTM: GiveBloc registered as a lazy singleton, but consider clarifying dependencies

The GiveBloc is correctly registered as a lazy singleton with its dependencies. However, it would be helpful to add comments explaining what each of the four getIt() calls is retrieving. This would improve code readability and maintainability.

Example:

..registerLazySingleton<GiveBloc>(
  () => GiveBloc(
    getIt(), // SomeRepository
    getIt(), // AnotherService
    getIt(), // SomeConfig
    getIt(), // Logger
  ),
)

11-11: Summary: New components added for donation flow

These changes add the necessary dependency injection setup for MediumCubit and GiveBloc, which are likely key components in the new donation flow mentioned in the PR objectives. The additions are well-structured and consistent with the existing codebase style.

To further improve this PR:

  1. Consider adding comments to clarify the dependencies injected into GiveBloc.
  2. Ensure that unit tests are updated or added to cover these new injections.
  3. Verify that the GiveBloc and MediumCubit are properly disposed of when no longer needed to prevent memory leaks.

Also applies to: 26-26, 58-66

lib/features/family/features/parent_giving_flow/presentation/pages/parent_giving_page.dart (2)

87-91: LGTM: Consistent use of give variable

The changes in the _buildGivt method consistently use the give variable to access the state, which is a good improvement. It simplifies the code and makes it more readable.

For consistency, consider using give.state.organisation.organisationName on line 89 as well:

var orgName = give.state.organisation.organisationName!;

This makes the code more uniform and easier to maintain.

Also applies to: 99-99, 105-105


Line range hint 171-185: Consider moving CustomInAppBrowser to a separate file

The CustomInAppBrowser class at the end of this file seems unrelated to the main ParentGivingPage widget. To improve code organization and maintainability, consider moving this class to a separate file, perhaps named custom_in_app_browser.dart in an appropriate directory.

This separation of concerns will make the codebase more modular and easier to navigate.

lib/features/children/generosity_challenge/assignments/create_challenge_donation/pages/choose_amount_slider_page.dart (1)

43-43: LGTM! Consider making give private.

The introduction of the give instance using dependency injection is a good practice. It improves testability and flexibility of the code.

Consider making the give instance private by prefixing it with an underscore:

- final give = getIt<GiveBloc>();
+ final _give = getIt<GiveBloc>();

This encapsulation prevents accidental access from outside the class.

lib/core/enums/amplitude_events.dart (1)

336-337: LGTM! Consider adding documentation for the new event.

The new enum value parentReflectionFlowOrganisationClicked is correctly implemented and follows the established conventions in the file. It's appropriately placed at the end of the enum list, which helps maintain backwards compatibility.

Consider adding a brief comment above this new enum value to describe its purpose or the specific user action it represents. This would be helpful for other developers who might work with this code in the future.

Example:

  /// Tracks when a parent clicks on an organisation during the reflection flow
  parentReflectionFlowOrganisationClicked(
      'parent_reflection_flow_organisation_clicked'),
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9afdc9a and 386e0f0.

Files selected for processing (9)
  • lib/core/enums/amplitude_events.dart (1 hunks)
  • lib/features/children/generosity_challenge/assignments/create_challenge_donation/pages/choose_amount_slider_page.dart (4 hunks)
  • lib/features/family/app/family_routes.dart (1 hunks)
  • lib/features/family/app/injection.dart (3 hunks)
  • lib/features/family/features/parent_giving_flow/presentation/pages/give_from_list_page.dart (4 hunks)
  • lib/features/family/features/parent_giving_flow/presentation/pages/parent_amount_page.dart (1 hunks)
  • lib/features/family/features/parent_giving_flow/presentation/pages/parent_giving_page.dart (3 hunks)
  • lib/features/family/features/reflect/bloc/grateful_cubit.dart (2 hunks)
  • lib/features/family/features/reflect/presentation/pages/grateful_screen.dart (4 hunks)
Additional comments not posted (15)
lib/features/family/features/parent_giving_flow/presentation/pages/give_from_list_page.dart (2)

5-5: LGTM: Import for dependency injection added.

The addition of import 'package:givt_app/app/injection/injection.dart'; is appropriate for using the getIt dependency injection container in this file.


27-29: Good refactoring: Improved dependency management.

The introduction of the give variable and its use in the BlocConsumer is a good refactoring:

  1. It centralizes the retrieval of the GiveBloc instance.
  2. It improves code readability by reducing repetitive calls to getIt.
  3. It's consistent with the move towards dependency injection.

This change enhances maintainability and follows good coding practices.

lib/features/family/features/reflect/bloc/grateful_cubit.dart (1)

46-47: Verify the intended behavior of profile filtering

The condition for removing profiles has been simplified to only remove those with a null gratitude value. This change now includes all profiles (both child and non-child) in the _profiles list, as long as they have a non-null gratitude value.

Please confirm if this is the intended behavior, as it may affect downstream logic that previously assumed only child profiles were present in the list.

To verify the impact, you can run the following script:

Review the results to ensure that the logic in these locations can handle both child and non-child profiles correctly.

Verification successful

Profile filtering change verified successfully

The modification to remove profiles with a null gratitude value does not interfere with the existing usage of the isChild property. Profiles are now correctly filtered to include all with non-null gratitude, and sorting logic based on isChild remains unaffected.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of _profiles that might assume only child profiles

# Test 1: Search for direct usage of _profiles
echo "Searching for direct usage of _profiles:"
rg --type dart '_profiles' lib/features/family/features/reflect/

# Test 2: Search for methods that use _profiles indirectly
echo "Searching for methods that might use _profiles indirectly:"
rg --type dart 'getCurrentProfile|_getCurrentProfile|onAvatarTapped|onDonated' lib/features/family/features/reflect/

Length of output: 4162


Script:

#!/bin/bash
# Description: Check for usage of `isChild` in relation to _profiles

# Test 1: Search for direct usage of isChild within _profiles
echo "Searching for direct usage of isChild with _profiles:"
rg --type dart '_profiles.*isChild' lib/features/family/features/reflect/

# Test 2: Identify methods that rely on isChild for profile filtering
echo "Searching for methods or conditions that filter _profiles based on isChild:"
rg --type dart '_profiles.*isChild' lib/features/family/features/reflect/

Length of output: 429


Script:

#!/bin/bash
# Description: Search for all usages of the `isChild` property in the codebase

# Test 1: Search for any usage of `isChild`
echo "Searching for all usages of 'isChild':"
rg --type dart 'isChild' lib/features/family/features/reflect/

# Test 2: Search for conditional statements involving `isChild`
echo "Searching for conditional statements involving 'isChild':"
rg --type dart 'if\s*\(.*isChild.*\)' lib/features/family/features/reflect/

# Test 3: Search for functions or methods that return `isChild`
echo "Searching for functions or methods that return 'isChild':"
rg --type dart '=>\s*.*isChild' lib/features/family/features/reflect/

Length of output: 1446


Script:

#!/bin/bash
# Description: Search for all indirect usages of the `isChild` property related to _profiles

# Test 1: Search for methods that return `isChild` and are used within GratefulCubit
echo "Searching for methods returning 'isChild' used in GratefulCubit:"
rg --type dart 'bool\s+\w+\s*\(.*\)\s*=>\s*.*isChild' lib/features/family/features/reflect/bloc/grateful_cubit.dart

# Test 2: Search for conditional statements in GratefulCubit that use `isChild`
echo "Searching for conditional statements involving 'isChild' in GratefulCubit:"
rg --type dart 'if\s*\(.*isChild.*\)' lib/features/family/features/reflect/bloc/grateful_cubit.dart

# Test 3: Search for any usage of `isChild` in function parameters or return types within GratefulCubit
echo "Searching for any usage of 'isChild' in function parameters or return types in GratefulCubit:"
rg --type dart '\bisChild\b' lib/features/family/features/reflect/bloc/grateful_cubit.dart

Length of output: 996

lib/features/family/app/injection.dart (2)

11-11: LGTM: New imports added for MediumCubit and GiveBloc

The new import statements are correctly added to support the changes in the initCubits function.

Also applies to: 26-26


58-58: LGTM: MediumCubit registered as a lazy singleton

The MediumCubit is correctly registered as a lazy singleton, which is appropriate for its usage pattern.

lib/features/family/features/parent_giving_flow/presentation/pages/parent_giving_page.dart (3)

67-68: LGTM: Improved state access

The change to use give.state.afterGivingRedirection instead of the context-based access is a good improvement. It's consistent with the new approach and makes the code more readable.


103-103: Status of TODO comment

There's a TODO comment regarding Safari Givt transactions:

message: context.l10n.safariGivtTransaction,

What's the status of this TODO? Is there any ongoing work or plans to address this Safari-specific functionality?

If this TODO is still relevant, consider creating a GitHub issue to track this task. If it's no longer relevant, please remove the TODO comment to keep the codebase clean.


31-31: Overall improvement in state management

The consistent use of the give variable for accessing GiveBloc state is a good refactoring that improves code readability and maintainability. It's a positive step towards better dependency injection and state management.

To ensure these changes don't have unintended consequences, please verify:

  1. That all usages of GiveBloc in this file have been updated.
  2. That similar refactoring has been applied consistently across other files using GiveBloc.

You can use the following script to check for any remaining context-based GiveBloc accesses in this file and others:

This will help ensure the refactoring is complete and consistent across the codebase.

Also applies to: 67-68, 87-91, 99-99, 105-105

lib/features/children/generosity_challenge/assignments/create_challenge_donation/pages/choose_amount_slider_page.dart (4)

55-55: LGTM! Consistent use of the injected bloc.

The change to use the give instance in the BlocListener is consistent with the earlier introduction of the instance. This removes the need for context-based bloc access, which is a good practice.


Line range hint 190-203: LGTM! Consistent use of the injected bloc.

The change to use the give instance for adding events in the _handleStripeRegistrationSuccess method is consistent with the earlier introduction of the instance. This improves code consistency and removes the need for context-based bloc access.


215-215: LGTM! Consistent use of the injected bloc.

The change to use the give instance for adding the error event in the _handleStripeOrDonationError method is consistent with the earlier introduction of the instance. This improves code consistency and removes the need for context-based bloc access.


Line range hint 1-224: Overall, great improvements to the code structure!

The changes in this file consistently introduce dependency injection for the GiveBloc, replacing context-based bloc access. This improves testability, flexibility, and overall code quality. The logic remains unchanged, ensuring that the functionality is preserved while the code structure is enhanced.

lib/features/family/app/family_routes.dart (2)

298-298: LGTM! Verify state management in ParentGivingPage

The simplification of the ParentGivingPage route by removing the BlocProvider.value wrapper improves code readability and aligns with the transition to dependency injection. This change is approved.

To ensure that the ParentGivingPage still has access to the necessary state management logic, please run the following verification script:

#!/bin/bash
# Description: Verify that ParentGivingPage can access required state management logic

# Test: Check if ParentGivingPage uses getIt for dependency injection
ast-grep --lang dart --pattern 'class ParentGivingPage {
  $$$
  getIt<$_>($_)
  $$$
}'

# Test: Check if ParentGivingPage uses any Bloc-related functionality
rg --type dart -e 'BlocBuilder|BlocListener|BlocConsumer|context\.read<|context\.watch<' lib/features/family/features/parent_giving_flow/presentation/pages/parent_giving_page.dart

Line range hint 1-1000: Approve refactoring to centralized dependency injection

The systematic removal of BlocProvider instances for GiveBloc and MediumCubit throughout the file indicates a shift towards a more centralized dependency injection approach using getIt. This refactoring can lead to improved performance and easier testing.

To ensure the consistency and correctness of this refactoring, please run the following verification script:

Please review the results to ensure that:

  1. No instances of BlocProvider for GiveBloc or MediumCubit remain in the routes file.
  2. Affected pages are using getIt for dependency injection.
  3. Bloc-related functionality is still accessible in the affected pages.
lib/features/family/features/reflect/presentation/pages/grateful_screen.dart (1)

66-72: Review potential event loop in BlocListener.

Adding an event to _give within a BlocListener on _give could potentially cause an unintended event loop.

Ensure that the event added does not trigger the same listener condition, leading to a loop.

BuildContext context,
Organisation org,
) async {
_medium.setMediumId(org.namespace);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need
await context.read<ProfilesCubit>().setActiveProfile(profile.userId);
here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, thats for kids

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the GiveBloc uses the userid from the AuthCubit, not ProfilesCubit

Copy link
Contributor

Choose a reason for hiding this comment

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

Clear, ty

Daniela510 and others added 4 commits September 23, 2024 13:49
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
# Conflicts:
#	lib/core/enums/amplitude_events.dart
#	lib/features/family/features/reflect/presentation/pages/grateful_screen.dart
…ivtnl/givt-app into feature/kids-1421-create-donation-flow
@github-actions github-actions bot added the enhancement New feature or request label Sep 23, 2024
Copy link
Contributor

@TammiLion TammiLion left a comment

Choose a reason for hiding this comment

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

just the google meet discussion thingie, but all else approved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants