From d700ad609d8afe94e85ba7f9a399e77107f13c9b Mon Sep 17 00:00:00 2001 From: Vusumuzi Khoza Date: Fri, 29 May 2026 23:54:17 +0200 Subject: [PATCH] minor home screen fix --- lib/screens/home/home_controller.dart | 17 +++-- lib/screens/home/home_screen.dart | 62 ++++++++++++------- .../transactions/transaction_model.dart | 12 ++-- .../transactions/transaction_model.g.dart | 6 +- 4 files changed, 60 insertions(+), 37 deletions(-) diff --git a/lib/screens/home/home_controller.dart b/lib/screens/home/home_controller.dart index 5df95b4..dbeb2a0 100644 --- a/lib/screens/home/home_controller.dart +++ b/lib/screens/home/home_controller.dart @@ -108,8 +108,11 @@ class HomeController extends ChangeNotifier { model.isLoading = true; if (!_disposed) notifyListeners(); - List response = await http.get('/public/providers'); - model.providers = response.map((e) => BillProvider.fromJson(e)).toList(); + final response = await http.get('/public/providers?sort=priority,asc'); + List providers = PageableModel.fromJson(response).content + .map((e) => BillProvider.fromJson(e as Map)) + .toList(); + model.providers = providers; model.filterableProviders = model.providers; if (model.providers.isNotEmpty) { @@ -141,7 +144,9 @@ class HomeController extends ChangeNotifier { if (!_disposed) notifyListeners(); } - Future>>> getTransactions(String userId) async { + Future>>> getTransactions( + String userId, + ) async { model.isLoading = true; if (!_disposed) notifyListeners(); @@ -179,8 +184,10 @@ class HomeController extends ChangeNotifier { // Simulate fetching categories try { - List response = await http.get('/public/categories'); - model.categories = response.map((e) => Category.fromJson(e)).toList(); + final response = await http.get('/public/categories'); + model.categories = (response as List) + .map((e) => Category.fromJson(e as Map)) + .toList(); if (model.categories.isNotEmpty) { updateSelectedCategory(model.categories[0]); diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 75a3e49..aca3c13 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -35,6 +35,14 @@ class _HomeScreenState extends State with TickerProviderStateMixin { late Animation _transactionsSlideAnimation; late Animation _transactionsFadeAnimation; + // ── Vibrant category color map ────────────────────────────── + static const Map _categoryColorMap = { + 'ECONET': Color(0xFF1A73E8), // Deep green + 'NETONE': Color.fromARGB(255, 230, 127, 0), // Bold blue + 'TELECEL': Color(0xFF7B1FA2), // Vibrant purple + 'ZESA': Color.fromARGB(255, 230, 58, 0), // Fiery orange + }; + @override void initState() { super.initState(); @@ -156,6 +164,28 @@ class _HomeScreenState extends State with TickerProviderStateMixin { super.dispose(); } + /// Derives a vibrant accent colour from the provider's category. + Color _resolveProviderColor(BillProvider provider) { + // Try exact match on category + final exact = _categoryColorMap[provider.category.toUpperCase()]; + if (exact != null) return exact; + + // Try matching on label + final labelMatch = _categoryColorMap[provider.label.toUpperCase()]; + if (labelMatch != null) return labelMatch; + + // Try matching on provider name keywords + final name = provider.name.toUpperCase(); + for (final entry in _categoryColorMap.entries) { + if (name.contains(entry.key)) return entry.value; + } + + // Hash-based fallback – deterministic vibrant hue + final hash = provider.clientId.hashCode; + final hue = (hash % 360).toDouble(); + return HSVColor.fromAHSV(1.0, hue, 0.75, 0.85).toColor(); + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -352,6 +382,7 @@ class _HomeScreenState extends State with TickerProviderStateMixin { double availableWidth, ) { final cardWidth = (availableWidth / 2) - 6; + final accent = _resolveProviderColor(provider); return SizedBox( width: cardWidth, @@ -368,26 +399,13 @@ class _HomeScreenState extends State with TickerProviderStateMixin { child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [ - theme.colorScheme.primary.withValues(alpha: 0.08), - theme.colorScheme.tertiary.withValues(alpha: 0.03), - theme.colorScheme.primary.withValues(alpha: 0.05), - ], - stops: const [0.0, 0.5, 1.0], - ), + color: isDark ? const Color(0xFF1E1E1E) : Colors.white, borderRadius: BorderRadius.circular(16), - border: Border.all( - color: theme.colorScheme.primary.withValues(alpha: 0.1), - width: 1, - ), boxShadow: [ BoxShadow( - color: theme.colorScheme.primary.withValues(alpha: 0.06), - blurRadius: 10, - offset: const Offset(0, 3), + color: accent.withValues(alpha: 0.15), + blurRadius: 2, + offset: const Offset(0, 1), ), ], ), @@ -400,11 +418,9 @@ class _HomeScreenState extends State with TickerProviderStateMixin { Container( width: 40, height: 40, - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.all(1), decoration: BoxDecoration( - color: theme.colorScheme.primary.withValues( - alpha: 0.12, - ), + color: accent.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(12), ), child: Image( @@ -412,14 +428,14 @@ class _HomeScreenState extends State with TickerProviderStateMixin { errorBuilder: (_, __, ___) => Icon( Icons.payment_rounded, size: 20, - color: theme.colorScheme.primary, + color: accent, ), ), ), Icon( Icons.chevron_right_rounded, size: 20, - color: theme.colorScheme.primary.withValues(alpha: 0.5), + color: accent.withValues(alpha: 0.55), ), ], ), diff --git a/lib/screens/transactions/transaction_model.dart b/lib/screens/transactions/transaction_model.dart index eb51b67..5c7df91 100644 --- a/lib/screens/transactions/transaction_model.dart +++ b/lib/screens/transactions/transaction_model.dart @@ -74,9 +74,9 @@ class TransactionModel { final String? providerImage; final String? paymentProcessorImage; final String confirmationStatus; - final String paymentStatus; - final String integrationStatus; - final String pollingStatus; + final String? paymentStatus; + final String? integrationStatus; + final String? pollingStatus; final String? orderId; final String? orderTrace; final String? orderTransactionTrace; @@ -122,9 +122,9 @@ class TransactionModel { this.providerImage, this.paymentProcessorImage, required this.confirmationStatus, - required this.paymentStatus, - required this.integrationStatus, - required this.pollingStatus, + this.paymentStatus, + this.integrationStatus, + this.pollingStatus, this.orderId, this.orderTrace, this.orderTransactionTrace, diff --git a/lib/screens/transactions/transaction_model.g.dart b/lib/screens/transactions/transaction_model.g.dart index f7f7b48..deb4174 100644 --- a/lib/screens/transactions/transaction_model.g.dart +++ b/lib/screens/transactions/transaction_model.g.dart @@ -41,9 +41,9 @@ TransactionModel _$TransactionModelFromJson(Map json) => providerImage: json['providerImage'] as String?, paymentProcessorImage: json['paymentProcessorImage'] as String?, confirmationStatus: json['confirmationStatus'] as String, - paymentStatus: json['paymentStatus'] as String, - integrationStatus: json['integrationStatus'] as String, - pollingStatus: json['pollingStatus'] as String, + paymentStatus: json['paymentStatus'] as String?, + integrationStatus: json['integrationStatus'] as String?, + pollingStatus: json['pollingStatus'] as String?, orderId: json['orderId'] as String?, orderTrace: json['orderTrace'] as String?, orderTransactionTrace: json['orderTransactionTrace'] as String?,