feat: add payment card grouping and analysis
This commit is contained in:
124
lib/providers/payment_card_provider.dart
Normal file
124
lib/providers/payment_card_provider.dart
Normal file
@@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../models/payment_card_model.dart';
|
||||
|
||||
class PaymentCardProvider extends ChangeNotifier {
|
||||
late Box<PaymentCardModel> _cardBox;
|
||||
final List<PaymentCardModel> _cards = [];
|
||||
|
||||
List<PaymentCardModel> get cards => List.unmodifiable(_cards);
|
||||
|
||||
PaymentCardModel? get defaultCard {
|
||||
try {
|
||||
return _cards.firstWhere((card) => card.isDefault);
|
||||
} catch (_) {
|
||||
return _cards.isNotEmpty ? _cards.first : null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
_cardBox = await Hive.openBox<PaymentCardModel>('payment_cards');
|
||||
_cards
|
||||
..clear()
|
||||
..addAll(_cardBox.values);
|
||||
_sortCards();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<PaymentCardModel> addCard({
|
||||
required String issuerName,
|
||||
required String last4,
|
||||
required String colorHex,
|
||||
required String iconName,
|
||||
bool isDefault = false,
|
||||
}) async {
|
||||
if (isDefault) {
|
||||
await _unsetDefaultCard();
|
||||
}
|
||||
|
||||
final card = PaymentCardModel(
|
||||
id: const Uuid().v4(),
|
||||
issuerName: issuerName,
|
||||
last4: last4,
|
||||
colorHex: colorHex,
|
||||
iconName: iconName,
|
||||
isDefault: isDefault,
|
||||
);
|
||||
|
||||
await _cardBox.put(card.id, card);
|
||||
_cards.add(card);
|
||||
_sortCards();
|
||||
notifyListeners();
|
||||
return card;
|
||||
}
|
||||
|
||||
Future<void> updateCard(PaymentCardModel updated) async {
|
||||
final index = _cards.indexWhere((card) => card.id == updated.id);
|
||||
if (index == -1) return;
|
||||
|
||||
if (updated.isDefault) {
|
||||
await _unsetDefaultCard(exceptId: updated.id);
|
||||
}
|
||||
|
||||
_cards[index] = updated;
|
||||
await _cardBox.put(updated.id, updated);
|
||||
_sortCards();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> deleteCard(String id) async {
|
||||
await _cardBox.delete(id);
|
||||
_cards.removeWhere((card) => card.id == id);
|
||||
|
||||
if (!_cards.any((card) => card.isDefault) && _cards.isNotEmpty) {
|
||||
_cards.first.isDefault = true;
|
||||
await _cardBox.put(_cards.first.id, _cards.first);
|
||||
}
|
||||
|
||||
_sortCards();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> setDefaultCard(String id) async {
|
||||
final index = _cards.indexWhere((card) => card.id == id);
|
||||
if (index == -1) return;
|
||||
|
||||
await _unsetDefaultCard(exceptId: id);
|
||||
_cards[index].isDefault = true;
|
||||
await _cardBox.put(id, _cards[index]);
|
||||
_sortCards();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
PaymentCardModel? getCardById(String? id) {
|
||||
if (id == null) return null;
|
||||
try {
|
||||
return _cards.firstWhere((card) => card.id == id);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void _sortCards() {
|
||||
_cards.sort((a, b) {
|
||||
if (a.isDefault != b.isDefault) {
|
||||
return a.isDefault ? -1 : 1;
|
||||
}
|
||||
final issuerCompare =
|
||||
a.issuerName.toLowerCase().compareTo(b.issuerName.toLowerCase());
|
||||
if (issuerCompare != 0) return issuerCompare;
|
||||
return a.last4.compareTo(b.last4);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _unsetDefaultCard({String? exceptId}) async {
|
||||
for (final card in _cards) {
|
||||
if (card.isDefault && card.id != exceptId) {
|
||||
card.isDefault = false;
|
||||
await _cardBox.put(card.id, card);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user