Add summary

This commit is contained in:
2025-06-28 13:47:47 +03:00
parent 145e57f410
commit f2f9f7871f
9 changed files with 158 additions and 33 deletions
+5 -3
View File
@@ -20,9 +20,6 @@ Future<void> initDependencies() async {
// Инициализация Hive
await HiveService.init();
// Регистрация сервисов
getIt.registerSingleton<SettingsCubit>(SettingsCubit(getIt())); // Регистрируем Cubit и передаем IUserRepository
// Регистрация репозиториев
getIt.registerSingleton<ICategoryRepository>(
HiveCategoryRepository(HiveService.categories),
@@ -43,6 +40,11 @@ Future<void> initDependencies() async {
UserService(getIt(), getIt(), getIt(), getIt()),
);
// Регистрация сервисов
getIt.registerSingleton<SettingsCubit>(
SettingsCubit(getIt()),
); // Регистрируем Cubit и передаем IUserRepository
// Blocs
getIt.registerFactory<AuthBloc>(() => AuthBloc(userService: getIt()));
getIt.registerFactory<TransactionBloc>(
+2 -1
View File
@@ -22,5 +22,6 @@
"englishLanguage": "English",
"defaultUser": "Default User",
"currencySetting": "Default Currency",
"currencyDescription": "Set the default currency for transactions"
"currencyDescription": "Set the default currency for transactions",
"transactionsHistoryTitle": "Transactions History"
}
+6
View File
@@ -235,6 +235,12 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Set the default currency for transactions'**
String get currencyDescription;
/// No description provided for @transactionsHistoryTitle.
///
/// In en, this message translates to:
/// **'Transactions History'**
String get transactionsHistoryTitle;
}
class _AppLocalizationsDelegate
+3
View File
@@ -78,4 +78,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get currencyDescription => 'Set the default currency for transactions';
@override
String get transactionsHistoryTitle => 'Transactions History';
}
+3
View File
@@ -79,4 +79,7 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get currencyDescription =>
'Установить валюту по умолчанию для транзакций';
@override
String get transactionsHistoryTitle => 'История транзакций';
}
+2 -1
View File
@@ -22,5 +22,6 @@
"englishLanguage": "Английский",
"defaultUser": "Пользователь по умолчанию",
"currencySetting": "Валюта по умолчанию",
"currencyDescription": "Установить валюту по умолчанию для транзакций"
"currencyDescription": "Установить валюту по умолчанию для транзакций",
"transactionsHistoryTitle": "История транзакций"
}
+1 -1
View File
@@ -5,7 +5,7 @@ import 'package:flutter_localizations/flutter_localizations.dart'; // Добав
import '/l10n/app_localizations.dart';
import 'logic/auth/auth_bloc.dart';
import 'pages/login/login_page.dart';
import 'package:budget_app/pages/home_page.dart';
import 'package:budget_app/pages/home/home_page.dart';
import 'theme/app_theme.dart';
import 'injection_container.dart' as di;
import 'logic/settings/settings_cubit.dart'; // Импортируем SettingsCubit
@@ -3,10 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import '/l10n/app_localizations.dart';
import '../logic/auth/auth_bloc.dart';
import '../logic/transaction/transaction_bloc.dart';
import 'reports_page.dart'; // Импортируем новую страницу отчетов
import 'settings_page.dart';
import '../../logic/auth/auth_bloc.dart';
import '../../logic/transaction/transaction_bloc.dart';
import '../home/widgets/summary_widget.dart'; // Импортируем новый виджет сводки
import '../reports_page.dart'; // Импортируем новую страницу отчетов
import '../settings_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@@ -114,32 +115,52 @@ class TransactionsPage extends StatelessWidget {
return BlocBuilder<TransactionBloc, TransactionState>(
builder: (context, state) {
if (state is TransactionLoading) {
return Center(child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
} else if (state is TransactionLoaded) {
if (state.transactions.isEmpty) {
return Center(
child: Text(localizations.noTransactionsText),
); // Локализованный текст
}
return ListView.builder(
itemCount: state.transactions.length,
itemBuilder: (context, index) {
final transaction = state.transactions[index];
return ListTile(
leading: Icon(
transaction.category.icon,
color: transaction.category.color,
// Используем ListView для вертикальной прокрутки
return ListView(
children: [
// Виджет сводки
const SummaryWidget(),
// Заголовок для списка транзакций
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
localizations.transactionsHistoryTitle,
style: Theme.of(context).textTheme.titleLarge,
),
title: Text(transaction.vendor),
subtitle: Text(transaction.category.name),
trailing: Text(
'${transaction.amount.toStringAsFixed(2)} ${transaction.currency}',
style: TextStyle(
color: transaction.isIncome ? Colors.green : Colors.red,
),
),
// Список транзакций
if (state.transactions.isEmpty)
Center(
child: Text(localizations.noTransactionsText),
) // Локализованный текст
else
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: state.transactions.length,
itemBuilder: (context, index) {
final transaction = state.transactions[index];
return ListTile(
leading: Icon(
transaction.category.icon,
color: transaction.category.color,
),
title: Text(transaction.vendor),
subtitle: Text(transaction.category.name),
trailing: Text(
'${transaction.amount.toStringAsFixed(2)} ${transaction.currency}',
style: TextStyle(
color: transaction.isIncome
? Colors.green
: Colors.red,
),
),
);
},
),
);
},
],
);
} else if (state is TransactionError) {
return Center(
@@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
// Виджет для отображения сводки по доходам и расходам.
class SummaryWidget extends StatelessWidget {
const SummaryWidget({super.key});
@override
Widget build(BuildContext context) {
// Используем Card для придания виджету тени и скругленных углов.
return Card(
elevation: 4.0,
margin: const EdgeInsets.all(16.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
child: Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
// Используем цвет из темы приложения.
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(12.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Заголовок секции.
Text(
'Общие траты',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8.0),
// Отображение общей суммы.
Text(
'12345.67 ₽', // TODO: Заменить на реальные данные
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16.0),
// Разделение на доходы и расходы.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Виджет для отображения доходов.
_buildIncomeExpense(
context,
'Доходы',
'23456.78 ₽', // TODO: Заменить на реальные данные
Colors.green,
),
// Виджет для отображения расходов.
_buildIncomeExpense(
context,
'Расходы',
'11111.11 ₽', // TODO: Заменить на реальные данные
Colors.red,
),
],
),
],
),
),
);
}
// Вспомогательный метод для создания виджета дохода/расхода.
Widget _buildIncomeExpense(
BuildContext context, String title, String amount, Color color) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 4.0),
Text(
amount,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: color,
fontWeight: FontWeight.bold,
),
),
],
);
}
}