feat: add payment card grouping and analysis
This commit is contained in:
144
lib/screens/payment_card_management_screen.dart
Normal file
144
lib/screens/payment_card_management_screen.dart
Normal file
@@ -0,0 +1,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../l10n/app_localizations.dart';
|
||||
import '../models/payment_card_model.dart';
|
||||
import '../providers/payment_card_provider.dart';
|
||||
import '../utils/payment_card_utils.dart';
|
||||
import '../widgets/payment_card/payment_card_form_sheet.dart';
|
||||
|
||||
class PaymentCardManagementScreen extends StatelessWidget {
|
||||
const PaymentCardManagementScreen({super.key});
|
||||
|
||||
Future<void> _openForm(BuildContext context, {PaymentCardModel? card}) async {
|
||||
await PaymentCardFormSheet.show(context, card: card);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(loc.paymentCardManagement),
|
||||
),
|
||||
body: Consumer<PaymentCardProvider>(
|
||||
builder: (context, provider, child) {
|
||||
final cards = provider.cards;
|
||||
if (cards.isEmpty) {
|
||||
return Center(
|
||||
child: Text(
|
||||
loc.noPaymentCards,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.separated(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
itemCount: cards.length,
|
||||
separatorBuilder: (_, __) => const Divider(height: 1),
|
||||
itemBuilder: (context, index) {
|
||||
final card = cards[index];
|
||||
final color = PaymentCardUtils.colorFromHex(card.colorHex);
|
||||
final icon = PaymentCardUtils.iconForName(card.iconName);
|
||||
return ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: color.withValues(alpha: 0.15),
|
||||
child: Icon(icon, color: color),
|
||||
),
|
||||
title: Row(
|
||||
children: [
|
||||
Expanded(child: Text(card.issuerName)),
|
||||
if (card.isDefault)
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
loc.cardDefaultBadge,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimaryContainer,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
subtitle: Text('****${card.last4}'),
|
||||
trailing: PopupMenuButton<String>(
|
||||
onSelected: (value) =>
|
||||
_handleMenuSelection(context, value, card, provider),
|
||||
itemBuilder: (_) => [
|
||||
PopupMenuItem(
|
||||
value: 'default',
|
||||
child: Text(loc.setAsDefaultCard),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'edit',
|
||||
child: Text(loc.editPaymentCard),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'delete',
|
||||
child: Text(loc.delete),
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () => _openForm(context, card: card),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => _openForm(context),
|
||||
icon: const Icon(Icons.add),
|
||||
label: Text(loc.addPaymentCard),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleMenuSelection(
|
||||
BuildContext context,
|
||||
String value,
|
||||
PaymentCardModel card,
|
||||
PaymentCardProvider provider,
|
||||
) async {
|
||||
switch (value) {
|
||||
case 'default':
|
||||
await provider.setDefaultCard(card.id);
|
||||
break;
|
||||
case 'edit':
|
||||
await _openForm(context, card: card);
|
||||
break;
|
||||
case 'delete':
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (_) => AlertDialog(
|
||||
title: Text(AppLocalizations.of(context).delete),
|
||||
content: Text(AppLocalizations.of(context).areYouSure),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: Text(AppLocalizations.of(context).cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: Text(AppLocalizations.of(context).delete),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (confirmed == true) {
|
||||
await provider.deleteCard(card.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user