Fix summary
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
- Цветовая палитра черно-белая
|
||||
- Все настройки цветов выноси в тему
|
||||
- Все элементы должны разбиваться на мелкие и иметь логичную структуру по попкам
|
||||
- Весь текст должен иметь локализацию
|
||||
- Весь текст должен иметь локализацию чрезе flutter_localizations. Смотри папку l10n
|
||||
|
||||
## Coding Style:
|
||||
|
||||
|
||||
+4
-1
@@ -23,5 +23,8 @@
|
||||
"defaultUser": "Default User",
|
||||
"currencySetting": "Default Currency",
|
||||
"currencyDescription": "Set the default currency for transactions",
|
||||
"transactionsHistoryTitle": "Transactions History"
|
||||
"transactionsHistoryTitle": "Transactions History",
|
||||
"balance": "Balance",
|
||||
"income": "Income",
|
||||
"expense": "Expense"
|
||||
}
|
||||
@@ -241,6 +241,24 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'Transactions History'**
|
||||
String get transactionsHistoryTitle;
|
||||
|
||||
/// No description provided for @balance.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Balance'**
|
||||
String get balance;
|
||||
|
||||
/// No description provided for @income.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Income'**
|
||||
String get income;
|
||||
|
||||
/// No description provided for @expense.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Expense'**
|
||||
String get expense;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -81,4 +81,13 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get transactionsHistoryTitle => 'Transactions History';
|
||||
|
||||
@override
|
||||
String get balance => 'Balance';
|
||||
|
||||
@override
|
||||
String get income => 'Income';
|
||||
|
||||
@override
|
||||
String get expense => 'Expense';
|
||||
}
|
||||
|
||||
@@ -82,4 +82,13 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get transactionsHistoryTitle => 'История транзакций';
|
||||
|
||||
@override
|
||||
String get balance => 'Баланс';
|
||||
|
||||
@override
|
||||
String get income => 'Доходы';
|
||||
|
||||
@override
|
||||
String get expense => 'Расходы';
|
||||
}
|
||||
|
||||
+4
-1
@@ -23,5 +23,8 @@
|
||||
"defaultUser": "Пользователь по умолчанию",
|
||||
"currencySetting": "Валюта по умолчанию",
|
||||
"currencyDescription": "Установить валюту по умолчанию для транзакций",
|
||||
"transactionsHistoryTitle": "История транзакций"
|
||||
"transactionsHistoryTitle": "История транзакций",
|
||||
"balance": "Баланс",
|
||||
"income": "Доходы",
|
||||
"expense": "Расходы"
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import '../../logic/transaction/transaction_bloc.dart';
|
||||
import '../home/widgets/summary_widget.dart'; // Импортируем новый виджет сводки
|
||||
import '../reports_page.dart'; // Импортируем новую страницу отчетов
|
||||
import '../settings_page.dart';
|
||||
import '../../services/user_service.dart'; // Добавлен импорт для UserService
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
const HomePage({super.key});
|
||||
@@ -121,7 +122,31 @@ class TransactionsPage extends StatelessWidget {
|
||||
return ListView(
|
||||
children: [
|
||||
// Виджет сводки
|
||||
const SummaryWidget(),
|
||||
// Рассчитываем доходы, расходы и баланс из транзакций
|
||||
Builder(
|
||||
builder: (context) {
|
||||
double income = 0.0;
|
||||
double expense = 0.0;
|
||||
for (var transaction in state.transactions) {
|
||||
if (transaction.isIncome) {
|
||||
income += transaction.amount;
|
||||
} else {
|
||||
expense += transaction.amount;
|
||||
}
|
||||
}
|
||||
final balance = income - expense;
|
||||
// Получаем текущего пользователя для определения валюты
|
||||
final userService = GetIt.instance<UserService>();
|
||||
final currencySymbol = userService.currentUser?.defaultCurrency ?? '₽'; // Валюта по умолчанию, если не найдена
|
||||
|
||||
return SummaryWidget(
|
||||
income: income,
|
||||
expense: expense,
|
||||
balance: balance,
|
||||
currencySymbol: currencySymbol, // Передаем символ валюты
|
||||
); // Передаем реальные данные в SummaryWidget
|
||||
},
|
||||
),
|
||||
// Заголовок для списка транзакций
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
|
||||
@@ -1,60 +1,105 @@
|
||||
|
||||
import 'package:animated_digit/animated_digit.dart';
|
||||
import 'package:budget_app/l10n/app_localizations.dart';
|
||||
import 'package:budget_app/theme/custom_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Виджет для отображения сводки по доходам и расходам.
|
||||
class SummaryWidget extends StatelessWidget {
|
||||
const SummaryWidget({super.key});
|
||||
// Добавлены параметры для отображения реальных данных
|
||||
final double income;
|
||||
final double expense;
|
||||
final double balance;
|
||||
final String currencySymbol; // Добавлен параметр для символа валюты
|
||||
|
||||
const SummaryWidget({
|
||||
super.key,
|
||||
required this.income,
|
||||
required this.expense,
|
||||
required this.balance,
|
||||
required this.currencySymbol, // Обязательный параметр
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Получаем локализацию и тему.
|
||||
final localizations = AppLocalizations.of(context)!;
|
||||
final customColors = Theme.of(context).extension<CustomColors>()!;
|
||||
final theme = Theme.of(context);
|
||||
|
||||
// Определяем цвет для градиента в зависимости от темы.
|
||||
final isDarkMode = theme.brightness == Brightness.dark;
|
||||
final gradientColor = isDarkMode ? Colors.grey[800]! : Colors.grey[200]!;
|
||||
|
||||
// Используем Card для придания виджету тени и скругленных углов.
|
||||
return Card(
|
||||
elevation: 4.0,
|
||||
margin: const EdgeInsets.all(16.0),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
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),
|
||||
// Добавляем градиентный фон для более современного вида.
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
theme.colorScheme.surface,
|
||||
gradientColor,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
),
|
||||
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,
|
||||
// Центральный блок с балансом.
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
// Заголовок секции.
|
||||
Text(
|
||||
localizations.balance,
|
||||
style: theme.textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 8.0),
|
||||
// Анимированное отображение общей суммы.
|
||||
AnimatedDigitWidget(
|
||||
value: balance,
|
||||
fractionDigits: 2,
|
||||
textStyle: theme.textTheme.headlineMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
suffix: ' $currencySymbol',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16.0),
|
||||
|
||||
// Добавляем разделитель для лучшей структуры.
|
||||
const Divider(height: 24.0),
|
||||
|
||||
// Разделение на доходы и расходы.
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
// Виджет для отображения доходов.
|
||||
_buildIncomeExpense(
|
||||
context,
|
||||
'Доходы',
|
||||
'23456.78 ₽', // TODO: Заменить на реальные данные
|
||||
Colors.green,
|
||||
localizations.income,
|
||||
income,
|
||||
customColors.income!, // Используем цвет дохода из темы
|
||||
Icons.arrow_upward,
|
||||
),
|
||||
// Виджет для отображения расходов.
|
||||
_buildIncomeExpense(
|
||||
context,
|
||||
'Расходы',
|
||||
'11111.11 ₽', // TODO: Заменить на реальные данные
|
||||
Colors.red,
|
||||
localizations.expense,
|
||||
expense,
|
||||
customColors.expense!, // Используем цвет расхода из темы
|
||||
Icons.arrow_downward,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -66,21 +111,34 @@ class SummaryWidget extends StatelessWidget {
|
||||
|
||||
// Вспомогательный метод для создания виджета дохода/расхода.
|
||||
Widget _buildIncomeExpense(
|
||||
BuildContext context, String title, String amount, Color color) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
BuildContext context, String title, double amount, Color color, IconData icon) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
// Иконка для наглядности.
|
||||
Icon(
|
||||
icon,
|
||||
color: color,
|
||||
size: 28.0,
|
||||
),
|
||||
const SizedBox(height: 4.0),
|
||||
Text(
|
||||
amount,
|
||||
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: color,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
const SizedBox(width: 8.0),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 4.0),
|
||||
// Анимированное отображение суммы.
|
||||
AnimatedDigitWidget(
|
||||
value: amount,
|
||||
fractionDigits: 2,
|
||||
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: color,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'custom_colors.dart';
|
||||
|
||||
class AppTheme {
|
||||
// Светлая тема в черно-белой гамме
|
||||
@@ -11,7 +13,6 @@ class AppTheme {
|
||||
primary: Colors.black, // Основной цвет - черный
|
||||
secondary: Colors.grey[800]!, // Вторичный цвет - темно-серый
|
||||
surface: Colors.white, // Фон поверхностей
|
||||
|
||||
),
|
||||
appBarTheme: const AppBarTheme(
|
||||
backgroundColor: Colors.white, // Белый фон AppBar
|
||||
@@ -36,6 +37,12 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
extensions: const <ThemeExtension<dynamic>>[
|
||||
CustomColors(
|
||||
income: Colors.green,
|
||||
expense: Colors.red,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,7 +56,6 @@ class AppTheme {
|
||||
primary: Colors.white, // Основной цвет - белый
|
||||
secondary: Colors.grey[300]!, // Вторичный цвет - светлый серый
|
||||
surface: Colors.grey[900]!, // Фон поверхностей
|
||||
|
||||
),
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: Colors.grey[900]!, // Темно-серый фон AppBar
|
||||
@@ -75,6 +81,13 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
extensions: const <ThemeExtension<dynamic>>[
|
||||
CustomColors(
|
||||
income: Colors.greenAccent,
|
||||
expense: Colors.redAccent,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.5.2"
|
||||
animated_digit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: animated_digit
|
||||
sha256: "22300a550b83e08ac4a0ef9c6fc7e800bbebc34978d997e6346da03d69fbb7a8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.3"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -30,6 +30,7 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
animated_digit: ^3.2.0
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
|
||||
Reference in New Issue
Block a user