feat: Add User and UserBalance models with serialization methods

feat: Implement BalanceRepository for group balance calculations

feat: Create ExpenseRepository for managing expenses

feat: Add services for handling expenses and storage operations

fix: Update import paths for models in repositories and services

refactor: Rename CountContent to AccountContent in HomePage

chore: Add StorageService for image upload and management
This commit is contained in:
Dayron
2025-10-21 16:02:58 +02:00
parent 62eb434548
commit 4edbd1cf34
60 changed files with 1973 additions and 342 deletions

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:travel_mate/blocs/user/user_bloc.dart';
import '../../data/models/account.dart';
import '../../models/account.dart';
import '../../blocs/account/account_bloc.dart';
import '../../blocs/account/account_event.dart';
import '../../blocs/account/account_state.dart';

View File

@@ -3,12 +3,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import '../../blocs/account/account_bloc.dart';
import '../../blocs/account/account_event.dart';
import '../../blocs/account/account_state.dart';
import 'package:travel_mate/models/expense_split.dart';
import '../../blocs/expense/expense_bloc.dart';
import '../../blocs/expense/expense_event.dart';
import '../../blocs/expense/expense_state.dart';
import '../../blocs/user/user_state.dart' as user_state;
import '../../data/models/group.dart';
import '../../data/models/expense.dart';
import '../../models/group.dart';
import '../../models/expense.dart';
class AddExpenseDialog extends StatefulWidget {
final Group group;
@@ -148,8 +149,8 @@ class _AddExpenseDialogState extends State<AddExpenseDialog> {
try {
// Convertir en EUR
final amountInEur = context.read<CountBloc>().state is ExpensesLoaded
? (context.read<CountBloc>().state as ExpensesLoaded)
final amountInEur = context.read<ExpenseBloc>().state is ExpensesLoaded
? (context.read<ExpenseBloc>().state as ExpensesLoaded)
.exchangeRates[_selectedCurrency]! * amount
: amount;
@@ -168,15 +169,16 @@ class _AddExpenseDialogState extends State<AddExpenseDialog> {
splits: selectedSplits,
date: _selectedDate,
receiptUrl: widget.expenseToEdit?.receiptUrl,
createdAt: widget.expenseToEdit?.createdAt ?? DateTime.now(),
);
if (widget.expenseToEdit == null) {
context.read<CountBloc>().add(CreateExpense(
context.read<ExpenseBloc>().add(CreateExpense(
expense: expense,
receiptImage: _receiptImage,
));
} else {
context.read<CountBloc>().add(UpdateExpense(
context.read<ExpenseBloc>().add(UpdateExpense(
expense: expense,
newReceiptImage: _receiptImage,
));

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import '../../data/models/balance.dart';
import '../../models/user_balance.dart';
class BalancesTab extends StatelessWidget {
final List<Balance> balances;
final List<UserBalance> balances;
const BalancesTab({
super.key,
@@ -27,7 +27,7 @@ class BalancesTab extends StatelessWidget {
);
}
Widget _buildBalanceCard(BuildContext context, Balance balance) {
Widget _buildBalanceCard(BuildContext context, UserBalance balance) {
final isDark = Theme.of(context).brightness == Brightness.dark;
Color balanceColor;

View File

@@ -1,12 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import '../../blocs/account/account_bloc.dart';
import '../../blocs/account/account_event.dart';
import 'package:travel_mate/models/expense_split.dart';
import '../../blocs/expense/expense_bloc.dart';
import '../../blocs/expense/expense_event.dart';
import '../../blocs/user/user_bloc.dart';
import '../../blocs/user/user_state.dart' as user_state;
import '../../data/models/expense.dart';
import '../../data/models/group.dart';
import '../../models/expense.dart';
import '../../models/group.dart';
import 'add_expense_dialog.dart';
class ExpenseDetailDialog extends StatelessWidget {
@@ -267,8 +268,7 @@ class ExpenseDetailDialog extends StatelessWidget {
IconButton(
icon: const Icon(Icons.check_circle, color: Colors.green),
onPressed: () {
context.read<CountBloc>().add(MarkSplitAsPaid(
groupId: expense.groupId,
context.read<ExpenseBloc>().add(MarkSplitAsPaid(
expenseId: expense.id,
userId: split.userId,
));
@@ -287,7 +287,7 @@ class ExpenseDetailDialog extends StatelessWidget {
showDialog(
context: context,
builder: (dialogContext) => BlocProvider.value(
value: context.read<CountBloc>(),
value: context.read<ExpenseBloc>(),
child: AddExpenseDialog(
group: group,
currentUser: currentUser,
@@ -310,9 +310,8 @@ class ExpenseDetailDialog extends StatelessWidget {
),
TextButton(
onPressed: () {
context.read<CountBloc>().add(DeleteExpense(
groupId: expense.groupId,
expenseId: expense.id,
context.read<ExpenseBloc>().add(DeleteExpense(
expense.id,
));
Navigator.of(dialogContext).pop();
Navigator.of(context).pop();
@@ -338,9 +337,8 @@ class ExpenseDetailDialog extends StatelessWidget {
),
TextButton(
onPressed: () {
context.read<CountBloc>().add(ArchiveExpense(
groupId: expense.groupId,
expenseId: expense.id,
context.read<ExpenseBloc>().add(ArchiveExpense(
expense.id,
));
Navigator.of(dialogContext).pop();
Navigator.of(context).pop();

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../data/models/expense.dart';
import '../../data/models/group.dart';
import '../../models/expense.dart';
import '../../models/group.dart';
import 'expense_detail_dialog.dart';
class ExpensesTab extends StatelessWidget {

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import '../../data/models/balance.dart';
import '../../models/settlement.dart';
class SettlementsTab extends StatelessWidget {
final List<Settlement> settlements;