diff --git a/apps/mobile/packages/core/lib/src/routing/client/navigator.dart b/apps/mobile/packages/core/lib/src/routing/client/navigator.dart index a3650f69..a7ce7150 100644 --- a/apps/mobile/packages/core/lib/src/routing/client/navigator.dart +++ b/apps/mobile/packages/core/lib/src/routing/client/navigator.dart @@ -102,7 +102,7 @@ extension ClientNavigator on IModularNavigator { /// Navigates to the full list of invoices awaiting approval. void toAwaitingApproval({Object? arguments}) { - pushNamed(ClientPaths.awaitingApproval, arguments: arguments); + navigate(ClientPaths.awaitingApproval, arguments: arguments); } /// Navigates to the Invoice Ready page. diff --git a/apps/mobile/packages/design_system/lib/src/widgets/ui_button.dart b/apps/mobile/packages/design_system/lib/src/widgets/ui_button.dart index bfa6ceaf..44475be5 100644 --- a/apps/mobile/packages/design_system/lib/src/widgets/ui_button.dart +++ b/apps/mobile/packages/design_system/lib/src/widgets/ui_button.dart @@ -3,7 +3,6 @@ import '../ui_constants.dart'; /// A custom button widget with different variants and icon support. class UiButton extends StatelessWidget { - /// Creates a [UiButton] with a custom button builder. const UiButton({ super.key, @@ -17,6 +16,7 @@ class UiButton extends StatelessWidget { this.iconSize = 20, this.size = UiButtonSize.large, this.fullWidth = false, + this.isLoading = false, }) : assert( text != null || child != null, 'Either text or child must be provided', @@ -34,6 +34,7 @@ class UiButton extends StatelessWidget { this.iconSize = 20, this.size = UiButtonSize.large, this.fullWidth = false, + this.isLoading = false, }) : buttonBuilder = _elevatedButtonBuilder, assert( text != null || child != null, @@ -50,8 +51,9 @@ class UiButton extends StatelessWidget { this.trailingIcon, this.style, this.iconSize = 20, - this.size = UiButtonSize.large, + this.size = UiButtonSize.large, this.fullWidth = false, + this.isLoading = false, }) : buttonBuilder = _outlinedButtonBuilder, assert( text != null || child != null, @@ -70,6 +72,7 @@ class UiButton extends StatelessWidget { this.iconSize = 20, this.size = UiButtonSize.large, this.fullWidth = false, + this.isLoading = false, }) : buttonBuilder = _textButtonBuilder, assert( text != null || child != null, @@ -88,11 +91,13 @@ class UiButton extends StatelessWidget { this.iconSize = 20, this.size = UiButtonSize.large, this.fullWidth = false, + this.isLoading = false, }) : buttonBuilder = _textButtonBuilder, assert( text != null || child != null, 'Either text or child must be provided', ); + /// The text to display on the button. final String? text; @@ -129,18 +134,21 @@ class UiButton extends StatelessWidget { ) buttonBuilder; + /// Whether to show a loading indicator. + final bool isLoading; + @override /// Builds the button UI. Widget build(BuildContext context) { - final ButtonStyle mergedStyle = style != null - ? _getSizeStyle().merge(style) + final ButtonStyle mergedStyle = style != null + ? _getSizeStyle().merge(style) : _getSizeStyle(); - + final Widget button = buttonBuilder( context, - onPressed, + isLoading ? null : onPressed, mergedStyle, - _buildButtonContent(), + isLoading ? _buildLoadingContent() : _buildButtonContent(), ); if (fullWidth) { @@ -150,6 +158,15 @@ class UiButton extends StatelessWidget { return button; } + /// Builds the loading indicator. + Widget _buildLoadingContent() { + return const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ); + } + /// Gets the style based on the button size. ButtonStyle _getSizeStyle() { switch (size) { diff --git a/apps/mobile/packages/features/client/billing/lib/src/billing_module.dart b/apps/mobile/packages/features/client/billing/lib/src/billing_module.dart index e1315aa8..9ad44e3e 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/billing_module.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/billing_module.dart @@ -12,6 +12,7 @@ import 'domain/usecases/get_spending_breakdown.dart'; import 'domain/usecases/approve_invoice.dart'; import 'domain/usecases/dispute_invoice.dart'; import 'presentation/blocs/billing_bloc.dart'; +import 'presentation/blocs/shift_completion_review/shift_completion_review_bloc.dart'; import 'presentation/models/billing_invoice_model.dart'; import 'presentation/pages/billing_page.dart'; import 'presentation/pages/completion_review_page.dart'; @@ -44,6 +45,10 @@ class BillingModule extends Module { getPendingInvoices: i.get(), getInvoiceHistory: i.get(), getSpendingBreakdown: i.get(), + ), + ); + i.add( + () => ShiftCompletionReviewBloc( approveInvoice: i.get(), disputeInvoice: i.get(), ), diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_bloc.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_bloc.dart index 07c1b98d..e26088c2 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_bloc.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_bloc.dart @@ -8,8 +8,6 @@ import '../../domain/usecases/get_invoice_history.dart'; import '../../domain/usecases/get_pending_invoices.dart'; import '../../domain/usecases/get_savings_amount.dart'; import '../../domain/usecases/get_spending_breakdown.dart'; -import '../../domain/usecases/approve_invoice.dart'; -import '../../domain/usecases/dispute_invoice.dart'; import '../models/billing_invoice_model.dart'; import '../models/spending_breakdown_model.dart'; import 'billing_event.dart'; @@ -26,21 +24,15 @@ class BillingBloc extends Bloc required GetPendingInvoicesUseCase getPendingInvoices, required GetInvoiceHistoryUseCase getInvoiceHistory, required GetSpendingBreakdownUseCase getSpendingBreakdown, - required ApproveInvoiceUseCase approveInvoice, - required DisputeInvoiceUseCase disputeInvoice, }) : _getBankAccounts = getBankAccounts, _getCurrentBillAmount = getCurrentBillAmount, _getSavingsAmount = getSavingsAmount, _getPendingInvoices = getPendingInvoices, _getInvoiceHistory = getInvoiceHistory, _getSpendingBreakdown = getSpendingBreakdown, - _approveInvoice = approveInvoice, - _disputeInvoice = disputeInvoice, super(const BillingState()) { on(_onLoadStarted); on(_onPeriodChanged); - on(_onInvoiceApproved); - on(_onInvoiceDisputed); } final GetBankAccountsUseCase _getBankAccounts; @@ -49,8 +41,6 @@ class BillingBloc extends Bloc final GetPendingInvoicesUseCase _getPendingInvoices; final GetInvoiceHistoryUseCase _getInvoiceHistory; final GetSpendingBreakdownUseCase _getSpendingBreakdown; - final ApproveInvoiceUseCase _approveInvoice; - final DisputeInvoiceUseCase _disputeInvoice; Future _onLoadStarted( BillingLoadStarted event, @@ -136,38 +126,6 @@ class BillingBloc extends Bloc ); } - Future _onInvoiceApproved( - BillingInvoiceApproved event, - Emitter emit, - ) async { - await handleError( - emit: emit.call, - action: () async { - await _approveInvoice.call(event.invoiceId); - add(const BillingLoadStarted()); - }, - onError: (String errorKey) => - state.copyWith(status: BillingStatus.failure, errorMessage: errorKey), - ); - } - - Future _onInvoiceDisputed( - BillingInvoiceDisputed event, - Emitter emit, - ) async { - await handleError( - emit: emit.call, - action: () async { - await _disputeInvoice.call( - DisputeInvoiceParams(id: event.invoiceId, reason: event.reason), - ); - add(const BillingLoadStarted()); - }, - onError: (String errorKey) => - state.copyWith(status: BillingStatus.failure, errorMessage: errorKey), - ); - } - BillingInvoice _mapInvoiceToUiModel(Invoice invoice) { final DateFormat formatter = DateFormat('EEEE, MMMM d'); final String dateLabel = invoice.issueDate == null diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_event.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_event.dart index 929a1bf4..1b6996fe 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_event.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/billing_event.dart @@ -24,20 +24,3 @@ class BillingPeriodChanged extends BillingEvent { @override List get props => [period]; } - -class BillingInvoiceApproved extends BillingEvent { - const BillingInvoiceApproved(this.invoiceId); - final String invoiceId; - - @override - List get props => [invoiceId]; -} - -class BillingInvoiceDisputed extends BillingEvent { - const BillingInvoiceDisputed(this.invoiceId, this.reason); - final String invoiceId; - final String reason; - - @override - List get props => [invoiceId, reason]; -} diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_bloc.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_bloc.dart new file mode 100644 index 00000000..bbdb56f0 --- /dev/null +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_bloc.dart @@ -0,0 +1,71 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:krow_core/core.dart'; +import '../../../domain/usecases/approve_invoice.dart'; +import '../../../domain/usecases/dispute_invoice.dart'; +import 'shift_completion_review_event.dart'; +import 'shift_completion_review_state.dart'; + +class ShiftCompletionReviewBloc + extends Bloc + with BlocErrorHandler { + ShiftCompletionReviewBloc({ + required ApproveInvoiceUseCase approveInvoice, + required DisputeInvoiceUseCase disputeInvoice, + }) : _approveInvoice = approveInvoice, + _disputeInvoice = disputeInvoice, + super(const ShiftCompletionReviewState()) { + on(_onApproved); + on(_onDisputed); + } + + final ApproveInvoiceUseCase _approveInvoice; + final DisputeInvoiceUseCase _disputeInvoice; + + Future _onApproved( + ShiftCompletionReviewApproved event, + Emitter emit, + ) async { + emit(state.copyWith(status: ShiftCompletionReviewStatus.loading)); + await handleError( + emit: emit.call, + action: () async { + await _approveInvoice.call(event.invoiceId); + emit( + state.copyWith( + status: ShiftCompletionReviewStatus.success, + message: 'approved', + ), + ); + }, + onError: (String errorKey) => state.copyWith( + status: ShiftCompletionReviewStatus.failure, + errorMessage: errorKey, + ), + ); + } + + Future _onDisputed( + ShiftCompletionReviewDisputed event, + Emitter emit, + ) async { + emit(state.copyWith(status: ShiftCompletionReviewStatus.loading)); + await handleError( + emit: emit.call, + action: () async { + await _disputeInvoice.call( + DisputeInvoiceParams(id: event.invoiceId, reason: event.reason), + ); + emit( + state.copyWith( + status: ShiftCompletionReviewStatus.success, + message: 'disputed', + ), + ); + }, + onError: (String errorKey) => state.copyWith( + status: ShiftCompletionReviewStatus.failure, + errorMessage: errorKey, + ), + ); + } +} diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_event.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_event.dart new file mode 100644 index 00000000..10dde94b --- /dev/null +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_event.dart @@ -0,0 +1,37 @@ +import 'package:equatable/equatable.dart'; + +/// Base class for all shift completion review events. +abstract class ShiftCompletionReviewEvent extends Equatable { + /// Creates a [ShiftCompletionReviewEvent]. + const ShiftCompletionReviewEvent(); + + @override + List get props => []; +} + +/// Event triggered when an invoice is approved. +class ShiftCompletionReviewApproved extends ShiftCompletionReviewEvent { + /// Creates a [ShiftCompletionReviewApproved] event. + const ShiftCompletionReviewApproved(this.invoiceId); + + /// The ID of the invoice to approve. + final String invoiceId; + + @override + List get props => [invoiceId]; +} + +/// Event triggered when an invoice is disputed. +class ShiftCompletionReviewDisputed extends ShiftCompletionReviewEvent { + /// Creates a [ShiftCompletionReviewDisputed] event. + const ShiftCompletionReviewDisputed(this.invoiceId, this.reason); + + /// The ID of the invoice to dispute. + final String invoiceId; + + /// The reason for the dispute. + final String reason; + + @override + List get props => [invoiceId, reason]; +} diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_state.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_state.dart new file mode 100644 index 00000000..539fcc34 --- /dev/null +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/blocs/shift_completion_review/shift_completion_review_state.dart @@ -0,0 +1,51 @@ +import 'package:equatable/equatable.dart'; + +/// Status of the shift completion review process. +enum ShiftCompletionReviewStatus { + /// Initial state. + initial, + + /// Loading state. + loading, + + /// Success state. + success, + + /// Failure state. + failure, +} + +/// State for the [ShiftCompletionReviewBloc]. +class ShiftCompletionReviewState extends Equatable { + /// Creates a [ShiftCompletionReviewState]. + const ShiftCompletionReviewState({ + this.status = ShiftCompletionReviewStatus.initial, + this.message, + this.errorMessage, + }); + + /// Current status of the process. + final ShiftCompletionReviewStatus status; + + /// Success message (e.g., 'approved' or 'disputed'). + final String? message; + + /// Error message to display if [status] is [ShiftCompletionReviewStatus.failure]. + final String? errorMessage; + + /// Creates a copy of this state with the given fields replaced. + ShiftCompletionReviewState copyWith({ + ShiftCompletionReviewStatus? status, + String? message, + String? errorMessage, + }) { + return ShiftCompletionReviewState( + status: status ?? this.status, + message: message ?? this.message, + errorMessage: errorMessage ?? this.errorMessage, + ); + } + + @override + List get props => [status, message, errorMessage]; +} diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/models/billing_invoice_model.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/models/billing_invoice_model.dart index 6e8d8e11..9da0a498 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/models/billing_invoice_model.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/models/billing_invoice_model.dart @@ -11,7 +11,7 @@ class BillingInvoice extends Equatable { required this.workersCount, required this.totalHours, required this.status, - this.workers = const [], + this.workers = const [], this.startTime, this.endTime, }); @@ -70,7 +70,7 @@ class BillingWorkerRecord extends Equatable { final String? workerAvatarUrl; @override - List get props => [ + List get props => [ workerName, roleName, totalAmount, diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/completion_review_page.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/completion_review_page.dart index d12efc0a..1d49c5bb 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/completion_review_page.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/completion_review_page.dart @@ -1,6 +1,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_core/core.dart'; import '../models/billing_invoice_model.dart'; @@ -48,6 +49,7 @@ class _ShiftCompletionReviewPageState extends State { title: invoice.title, subtitle: invoice.clientName, showBackButton: true, + onLeadingPressed: () => Modular.to.toAwaitingApproval(), ), body: SafeArea( child: SingleChildScrollView( diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/invoice_ready_page.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/invoice_ready_page.dart index b1b3bce4..430b5193 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/invoice_ready_page.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/invoice_ready_page.dart @@ -37,7 +37,7 @@ class InvoiceReadyView extends StatelessWidget { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: [ const Icon( UiIcons.file, size: 64, @@ -81,7 +81,7 @@ class _InvoiceSummaryCard extends StatelessWidget { color: UiColors.white, borderRadius: UiConstants.radiusLg, border: Border.all(color: UiColors.border), - boxShadow: [ + boxShadow: [ BoxShadow( color: UiColors.black.withValues(alpha: 0.04), blurRadius: 10, @@ -91,10 +91,10 @@ class _InvoiceSummaryCard extends StatelessWidget { ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 10, @@ -124,10 +124,10 @@ class _InvoiceSummaryCard extends StatelessWidget { const Divider(height: 32), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ Text( 'TOTAL AMOUNT', style: UiTypography.titleUppercase4m.textSecondary, diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/pending_invoices_page.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/pending_invoices_page.dart index 246e2d08..d76b6d1a 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/pending_invoices_page.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/pages/pending_invoices_page.dart @@ -3,6 +3,7 @@ import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_core/core.dart'; import '../blocs/billing_bloc.dart'; import '../blocs/billing_state.dart'; @@ -20,6 +21,7 @@ class PendingInvoicesPage extends StatelessWidget { appBar: UiAppBar( title: t.client_billing.awaiting_approval, showBackButton: true, + onLeadingPressed: () => Modular.to.toClientBilling(), ), body: _buildBody(context, state), ); diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_actions.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_actions.dart index c8047b53..5e5feb2a 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_actions.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_actions.dart @@ -1,11 +1,13 @@ import 'package:core_localization/core_localization.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:krow_core/core.dart'; -import '../../blocs/billing_bloc.dart'; -import '../../blocs/billing_event.dart'; +import '../../blocs/shift_completion_review/shift_completion_review_bloc.dart'; +import '../../blocs/shift_completion_review/shift_completion_review_event.dart'; +import '../../blocs/shift_completion_review/shift_completion_review_state.dart'; class CompletionReviewActions extends StatelessWidget { const CompletionReviewActions({required this.invoiceId, super.key}); @@ -14,47 +16,80 @@ class CompletionReviewActions extends StatelessWidget { @override Widget build(BuildContext context) { - return Row( - spacing: UiConstants.space2, - children: [ - Expanded( - child: UiButton.secondary( - text: t.client_billing.actions.flag_review, - leadingIcon: UiIcons.warning, - onPressed: () => _showFlagDialog(context), - size: UiButtonSize.large, - style: OutlinedButton.styleFrom( - foregroundColor: UiColors.destructive, - side: BorderSide.none, - ), - ), - ), - Expanded( - child: UiButton.primary( - text: t.client_billing.actions.approve_pay, - leadingIcon: UiIcons.checkCircle, - onPressed: () { - Modular.get().add(BillingInvoiceApproved(invoiceId)); - Modular.to.pop(); - UiSnackbar.show( - context, - message: t.client_billing.approved_success, - type: UiSnackbarType.success, + return BlocProvider.value( + value: Modular.get(), + child: + BlocConsumer( + listener: (BuildContext context, ShiftCompletionReviewState state) { + if (state.status == ShiftCompletionReviewStatus.success) { + final String message = state.message == 'approved' + ? t.client_billing.approved_success + : t.client_billing.flagged_success; + final UiSnackbarType type = state.message == 'approved' + ? UiSnackbarType.success + : UiSnackbarType.warning; + + UiSnackbar.show(context, message: message, type: type); + Modular.to.toAwaitingApproval(); + } else if (state.status == ShiftCompletionReviewStatus.failure) { + UiSnackbar.show( + context, + message: state.errorMessage ?? t.errors.generic.unknown, + type: UiSnackbarType.error, + ); + } + }, + builder: (BuildContext context, ShiftCompletionReviewState state) { + final bool isLoading = + state.status == ShiftCompletionReviewStatus.loading; + + return Row( + spacing: UiConstants.space2, + children: [ + Expanded( + child: UiButton.secondary( + text: t.client_billing.actions.flag_review, + leadingIcon: UiIcons.warning, + onPressed: isLoading + ? null + : () => _showFlagDialog(context, state), + size: UiButtonSize.large, + style: OutlinedButton.styleFrom( + foregroundColor: UiColors.destructive, + side: BorderSide.none, + ), + ), + ), + Expanded( + child: UiButton.primary( + text: t.client_billing.actions.approve_pay, + leadingIcon: isLoading ? null : UiIcons.checkCircle, + isLoading: isLoading, + onPressed: isLoading + ? null + : () { + BlocProvider.of( + context, + ).add(ShiftCompletionReviewApproved(invoiceId)); + }, + size: UiButtonSize.large, + ), + ), + ], ); }, - size: UiButtonSize.large, ), - ), - ], ); } - void _showFlagDialog(BuildContext context) { + void _showFlagDialog(BuildContext context, ShiftCompletionReviewState state) { final TextEditingController controller = TextEditingController(); showDialog( context: context, builder: (BuildContext dialogContext) => AlertDialog( title: Text(t.client_billing.flag_dialog.title), + surfaceTintColor: Colors.white, + backgroundColor: Colors.white, content: TextField( controller: controller, decoration: InputDecoration( @@ -70,15 +105,10 @@ class CompletionReviewActions extends StatelessWidget { TextButton( onPressed: () { if (controller.text.isNotEmpty) { - Modular.get().add( - BillingInvoiceDisputed(invoiceId, controller.text), - ); - Modular.to.toClientBilling(); - UiSnackbar.show( - context, - message: t.client_billing.flagged_success, - type: UiSnackbarType.warning, + BlocProvider.of(context).add( + ShiftCompletionReviewDisputed(invoiceId, controller.text), ); + Navigator.pop(dialogContext); } }, child: Text(t.client_billing.flag_dialog.button), diff --git a/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_amount.dart b/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_amount.dart index 48f81801..401fd8c0 100644 --- a/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_amount.dart +++ b/apps/mobile/packages/features/client/billing/lib/src/presentation/widgets/completion_review/completion_review_amount.dart @@ -15,9 +15,9 @@ class CompletionReviewAmount extends StatelessWidget { width: double.infinity, padding: const EdgeInsets.all(UiConstants.space6), decoration: BoxDecoration( - color: const Color(0xFFEFF6FF), + color: UiColors.bgPopup, borderRadius: UiConstants.radiusLg, - border: Border.all(color: const Color(0xFFDBEAFE)), + border: Border.all(color: UiColors.border), ), child: Column( children: [