import 'package:common/localization/l10n_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:payment_plugin/domain/models/stored_payment_method.dart';
import 'package:payment_plugin/presentation/app/bloc/payment_cards_state.dart';
import 'package:payment_plugin/presentation/components/add_card.dart';
import 'package:payment_plugin/presentation/components/card_item.dart';
import 'package:payment_plugin/presentation/components/comwell_error_widget.dart';
import 'package:payment_plugin/presentation/components/edit_card_dialog.dart';
import 'package:payment_plugin/presentation/components/payment_cards_shimmer_loader.dart';
import '../app/bloc/payment_cards_cubit.dart';
class PaymentCardsPage extends StatelessWidget {
final bool needScaffold;
final PreferredSizeWidget appBar;
const PaymentCardsPage({
super.key,
this.needScaffold = false,
required this.appBar,
});
@override
Widget build(BuildContext context) {
if (needScaffold) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.surface,
appBar: appBar,
body: BlocBuilder<PaymentCardsCubit, PaymentCardsState>(
builder: (context, state) {
final cubit = context.read<PaymentCardsCubit>();
if (cubit.state.isLoading) {
return const Center(child: PaymentCardsShimmerLoader());
}
if (cubit.state.hasError) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ComwellErrorWidget(
title: context.strings.generic_error_title,
subtitle: context.strings.payment_cards_error_subtitle,
border: false,
),
],
);
}
return _buildPaymentCards(context, state, cubit);
},
),
);
} else {
return BlocBuilder<PaymentCardsCubit, PaymentCardsState>(
builder: (context, state) {
final cubit = context.read<PaymentCardsCubit>();
if (cubit.state.isLoading) {
return const Center(child: PaymentCardsShimmerLoader());
}
if (cubit.state.hasError) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ComwellErrorWidget(
title: context.strings.generic_error_title,
subtitle: context.strings.payment_cards_error_subtitle,
border: false,
),
],
);
}
return _buildPaymentCards(context, state, cubit);
},
);
}
}
Widget _buildPaymentCards(
BuildContext context,
PaymentCardsState state,
PaymentCardsCubit cubit,
) {
final cards = state.cards;
final theme = Theme.of(context);
final showPaymentError =
state.missingPaymentMethod && state.selectedPaymentMethod == null;
return _buildCardsList(context, theme, cards, cubit, showPaymentError);
}
Widget _buildCardsList(
BuildContext context,
ThemeData theme,
Iterable<StoredPaymentMethod> cards,
PaymentCardsCubit cubit,
bool showPaymentError,
) {
return ListView(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 40),
Text(
context.strings.payment_cards_title,
style: theme.textTheme.headlineLarge,
),
const SizedBox(height: 40),
Text(
context.strings.payment_cards_my_cards,
style: theme.textTheme.headlineMedium,
),
const SizedBox(height: 20),
if (showPaymentError) ...[
Container(
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.only(bottom: 12),
decoration: BoxDecoration(
color: theme.colorScheme.error.withValues(alpha: 0.1),
border: Border.all(color: theme.colorScheme.error),
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Icon(
Icons.error_outline,
color: theme.colorScheme.error,
size: 20,
),
const SizedBox(width: 8),
Expanded(
child: Text(
context
.strings
.payment_cards_missing_payment_method_subtitle,
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.error,
),
),
),
],
),
),
],
...cards.map(
(card) => InkWell(
onTap: () {
showModalBottomSheet<void>(
context: context,
backgroundColor: Theme.of(context).colorScheme.surface,
builder: (context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: EditCardDialog(
storedPaymentMethod: card,
onRemoveCard: () {
cubit.onRemoveCard(card.id);
},
),
);
},
);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: theme.colorScheme.outline),
),
padding: const EdgeInsets.all(12),
child: CardItem(
needsScaffold: needScaffold,
paymentMethod: card,
onSelect: () {
cubit.selectPaymentMethod(card);
},
isSelectedPaymentMethod:
cubit.state.selectedPaymentMethod?.id == card.id,
),
),
),
),
),
const SizedBox(height: 12),
const AddCard(),
],
),
),
],
);
}
}