import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../models/expense.dart'; import '../../models/group.dart'; import 'expense_detail_dialog.dart'; class ExpensesTab extends StatelessWidget { final List expenses; final Group group; final String currentUserId; const ExpensesTab({ super.key, required this.expenses, required this.group, required this.currentUserId, }); @override Widget build(BuildContext context) { if (expenses.isEmpty) { return const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.receipt_long, size: 80, color: Colors.grey), SizedBox(height: 16), Text( 'Aucune dépense', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), SizedBox(height: 8), Text( 'Ajoutez votre première dépense', style: TextStyle(fontSize: 14, color: Colors.grey), ), ], ), ); } return ListView.builder( padding: const EdgeInsets.all(16), itemCount: expenses.length, itemBuilder: (context, index) { final expense = expenses[index]; return _buildExpenseCard(context, expense); }, ); } Widget _buildExpenseCard(BuildContext context, Expense expense) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; final dateFormat = DateFormat('dd/MM'); // Logique pour déterminer l'impact sur l'utilisateur bool isPayer = expense.paidById == currentUserId; double amountToDisplay = expense.amount; bool isPositive = isPayer; // Si je suis le payeur, je suis en positif (on me doit de l'argent) // Si je ne suis pas le payeur, je suis en négatif (je dois de l'argent) // Note: Pour être précis, il faudrait calculer ma part exacte, mais pour l'instant // on affiche le total avec la couleur indiquant si j'ai payé ou non. final amountColor = isPositive ? Colors.green : Colors.red; final prefix = isPositive ? '+' : '-'; return Container( margin: const EdgeInsets.only(bottom: 12), decoration: BoxDecoration( color: isDark ? theme.cardColor : Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Material( color: Colors.transparent, child: InkWell( onTap: () => _showExpenseDetail(context, expense), borderRadius: BorderRadius.circular(16), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ // Icone circulaire Container( width: 48, height: 48, decoration: BoxDecoration( color: _getCategoryColor( expense.category, ).withValues(alpha: 0.2), shape: BoxShape.circle, ), child: Icon( expense.category.icon, color: _getCategoryColor(expense.category), size: 24, ), ), const SizedBox(width: 16), // Détails Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( expense.description, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Row( children: [ Text( isPayer ? 'Payé par vous' : 'Payé par ${expense.paidByName}', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : Colors.grey[600], ), ), Text( ' • ${dateFormat.format(expense.date)}', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[500] : Colors.grey[500], ), ), ], ), ], ), ), // Montant Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( '$prefix${amountToDisplay.toStringAsFixed(2)} ${expense.currency.symbol}', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: amountColor, ), ), if (expense.currency != ExpenseCurrency.eur) Text( 'Total ${expense.amountInEur.toStringAsFixed(2)} €', style: TextStyle( fontSize: 11, color: isDark ? Colors.grey[500] : Colors.grey[400], ), ), ], ), ], ), ), ), ), ); } Color _getCategoryColor(ExpenseCategory category) { switch (category) { case ExpenseCategory.restaurant: return Colors.orange; case ExpenseCategory.transport: return Colors.blue; case ExpenseCategory.accommodation: return Colors.purple; case ExpenseCategory.entertainment: return Colors.pink; case ExpenseCategory.shopping: return Colors.teal; case ExpenseCategory.other: return Colors.grey; case ExpenseCategory.reimbursement: return Colors.green; } } void _showExpenseDetail(BuildContext context, Expense expense) { showDialog( context: context, builder: (context) => ExpenseDetailDialog(expense: expense, group: group), ); } }