/// This file defines the `BalancesTab` widget, which is responsible for displaying a list of user balances /// in a group. Each balance is represented as a card, showing the user's name, the amount they have paid, /// the amount they owe, and their overall balance status (to pay, to receive, or balanced). /// /// The widget handles both light and dark themes and provides a fallback UI for empty balance lists. import 'package:flutter/material.dart'; import '../../models/user_balance.dart'; /// A stateless widget that displays a list of user balances in a group. /// /// The `BalancesTab` widget takes a list of `UserBalance` objects and renders them as cards in a scrollable list. /// Each card provides detailed information about the user's financial status within the group. /// /// If the list of balances is empty, a placeholder message is displayed. class BalancesTab extends StatelessWidget { /// The list of user balances to display. final List balances; /// Creates a `BalancesTab` widget. /// /// The [balances] parameter must not be null. const BalancesTab({ super.key, required this.balances, }); @override Widget build(BuildContext context) { // Check if the balances list is empty and display a placeholder message if true. if (balances.isEmpty) { return const Center( child: Text('Aucune balance à afficher'), ); } // Render the list of balances as a scrollable list. return ListView.builder( padding: const EdgeInsets.all(16), itemCount: balances.length, itemBuilder: (context, index) { final balance = balances[index]; return _buildBalanceCard(context, balance); }, ); } /// Builds a card widget to display a single user's balance information. /// /// The card includes the user's name, their total paid and owed amounts, and their balance status. /// The card's appearance adapts to the app's current theme (light or dark). Widget _buildBalanceCard(BuildContext context, UserBalance balance) { // Determine if the app is in dark mode. final isDark = Theme.of(context).brightness == Brightness.dark; // Define variables for the balance's color, icon, and status text. Color balanceColor; IconData balanceIcon; String balanceText; // Determine the balance status and corresponding UI elements. if (balance.shouldReceive) { balanceColor = Colors.green; balanceIcon = Icons.arrow_downward; balanceText = 'À recevoir'; } else if (balance.shouldPay) { balanceColor = Colors.red; balanceIcon = Icons.arrow_upward; balanceText = 'À payer'; } else { balanceColor = Colors.grey; balanceIcon = Icons.check_circle; balanceText = 'Équilibré'; } // Build and return the card widget. return Card( margin: const EdgeInsets.only(bottom: 12), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ // Display the user's initial in a circular avatar. CircleAvatar( radius: 24, backgroundColor: isDark ? Colors.grey[800] : Colors.grey[200], child: Text( balance.userName.isNotEmpty ? balance.userName[0].toUpperCase() : '?', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 16), // Display the user's name and financial details. Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // User's name. Text( balance.userName, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), // User's total paid and owed amounts. Text( 'Payé: ${balance.totalPaid.toStringAsFixed(2)} € • Doit: ${balance.totalOwed.toStringAsFixed(2)} €', style: TextStyle( fontSize: 12, color: isDark ? Colors.grey[400] : Colors.grey[600], ), ), ], ), ), // Display the user's balance status and amount. Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Row( children: [ // Icon indicating the balance status. Icon(balanceIcon, size: 16, color: balanceColor), const SizedBox(width: 4), // User's absolute balance amount. Text( '${balance.absoluteBalance.toStringAsFixed(2)} €', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: balanceColor, ), ), ], ), // Text indicating the balance status (e.g., "À recevoir"). Text( balanceText, style: TextStyle( fontSize: 12, color: balanceColor, ), ), ], ), ], ), ), ); } }