Benefit Calculator BLoC
Component Detail
Description
BLoC state management layer for the calculator screen. Handles input change events, triggers recalculation via the calculation service, and emits updated states containing the current inputs and computed result. Keeps UI reactive without manual setState calls.
benefit-calculator-bloc
Summaries
The Benefit Calculator BLoC provides the responsive, real-time calculation experience that makes the benefit quantification tool feel immediate and trustworthy to peer mentors. By recomputing impact figures instantly as volunteers adjust their inputs, the interface reinforces engagement and encourages volunteers to explore how additional sessions multiply their contribution — a motivational mechanic that supports programme retention. The BLoC's structured state management also ensures that error and loading conditions are communicated clearly to users, preventing confusion when configuration data is slow to load in field conditions, and thereby maintaining volunteer confidence in the platform's reliability.
The Benefit Calculator BLoC depends on both the BenefitCalculationService and BenefitMultiplierConfigRepository being available and tested, making it a mid-to-late sprint deliverable. Its complexity is rated low because the event-state cycle is straightforward, but the async config fetch on initialisation introduces a loading state that must be covered in UI integration tests to ensure the calculator screen handles slow or failed config loads gracefully. Plan for widget tests that simulate InputChanged event sequences and verify emitted states contain correct BenefitCalculationResult values. The BLoC is not shared, so its interface can evolve alongside the calculator screen without cross-feature coordination overhead.
BenefitCalculatorBloc extends flutter_bloc's Bloc class with BenefitCalculatorEvent and BenefitCalculatorState as the event and state types respectively. On initialisation it dispatches a config load via BenefitMultiplierConfigRepository and emits a loading state; on success it transitions to a ready state. InputChanged events call BenefitCalculationService.calculate() synchronously (given the low-complexity arithmetic) and emit a new state containing the updated BenefitCalculationResult. ShareRequested delegates to BenefitShareService outside the BLoC to keep side-effect orchestration clean.
Use equatable on all state classes to enable flutter_bloc's internal state comparison and prevent redundant UI rebuilds. The BLoC should be provided at the calculator route level, not globally, to ensure clean disposal on navigation pop.
Responsibilities
- Handle InputChanged, ResetRequested, and ShareRequested events
- Call BenefitCalculationService on each input change and emit updated BenefitCalculationResult
- Expose loading and error states for async config fetch
Interfaces
BenefitCalculatorBloc(BenefitCalculationService, BenefitMultiplierConfigRepository)
add(BenefitCalculatorEvent)
Stream<BenefitCalculatorState> get stream
Relationships
Dependencies (2)
Components this component depends on