Adds the ability to manage categories in the settings page. This includes: - Registers CategoryCubit in the dependency injection container. - Introduces a new CategoryListPage for editing categories. - Adds translations for category management related text. - Adds unselected icon color to the theme. - Updates the date format in the transaction dialog.
122 lines
7.0 KiB
Dart
122 lines
7.0 KiB
Dart
import 'package:budget_app/pages/category/category_list_page.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import '/l10n/app_localizations.dart';
|
||
import '../logic/settings/settings_cubit.dart';
|
||
|
||
// Комментарий: Мы преобразуем SettingsPage из StatefulWidget в StatelessWidget.
|
||
// Это возможно, потому что теперь состояние управляется SettingsCubit,
|
||
// и виджету не нужно хранить собственное состояние, что делает код проще и эффективнее.
|
||
class SettingsPage extends StatelessWidget {
|
||
const SettingsPage({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
// Комментарий: Получаем экземпляр локализации для использования в тексте.
|
||
// Это позволяет нам отображать текст на языке, выбранном пользователем.
|
||
final localizations = AppLocalizations.of(context)!;
|
||
|
||
return Scaffold(
|
||
appBar: AppBar(
|
||
// Комментарий: Используем локализованную строку для заголовка страницы.
|
||
title: Text(localizations.settingsPageTitle),
|
||
),
|
||
// Комментарий: Используем BlocBuilder для перестройки UI при изменении состояния SettingsCubit.
|
||
// Он будет "слушать" изменения в SettingsCubit и автоматически перестраивать дочерние виджеты
|
||
// с новым состоянием (state).
|
||
body: BlocBuilder<SettingsCubit, SettingsState>(
|
||
builder: (context, state) {
|
||
// Комментарий: `state` - это текущее состояние настроек (тема и язык).
|
||
return Padding(
|
||
padding: const EdgeInsets.all(16.0),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
// Комментарий: SwitchListTile для переключения темной/светлой темы.
|
||
// Это удобный виджет, который объединяет переключатель с текстом.
|
||
SwitchListTile(
|
||
title: Text(localizations.darkModeSetting),
|
||
subtitle: Text(localizations.darkModeDescription),
|
||
// Комментарий: Значение переключателя (включен/выключен) берется из `state.isDarkMode`.
|
||
value: state.isDarkMode,
|
||
// Комментарий: При изменении положения переключателя (onChanged) мы вызываем метод `setDarkMode` у Cubit.
|
||
// `context.read<SettingsCubit>()` используется для доступа к Cubit без подписки на его изменения.
|
||
// Это хорошо для вызова методов.
|
||
onChanged: (value) {
|
||
context.read<SettingsCubit>().setDarkMode(value);
|
||
},
|
||
),
|
||
const Divider(),
|
||
// Комментарий: ListTile для смены языка.
|
||
ListTile(
|
||
title: Text(localizations.languageSetting),
|
||
subtitle: Text(localizations.languageDescription),
|
||
trailing: DropdownButton<String>(
|
||
// Комментарий: Текущее значение языка для выпадающего списка берется из `state.languageCode`.
|
||
value: state.languageCode,
|
||
// Комментарий: При выборе нового языка вызываем метод `setLanguageCode` у Cubit.
|
||
onChanged: (String? newValue) {
|
||
if (newValue != null) {
|
||
context.read<SettingsCubit>().setLanguageCode(newValue);
|
||
}
|
||
},
|
||
// Комментарий: Формируем список доступных языков.
|
||
items: <String>['en', 'ru']
|
||
.map<DropdownMenuItem<String>>((String value) {
|
||
return DropdownMenuItem<String>(
|
||
value: value,
|
||
// Комментарий: Отображаем локализованное название языка.
|
||
child: Text(value == 'en'
|
||
? localizations.englishLanguage
|
||
: localizations.russianLanguage),
|
||
);
|
||
}).toList(),
|
||
),
|
||
),
|
||
const Divider(),
|
||
// Комментарий: ListTile для выбора валюты по умолчанию.
|
||
ListTile(
|
||
title: Text(localizations.currencySetting),
|
||
subtitle: Text(localizations.currencyDescription),
|
||
trailing: DropdownButton<String>(
|
||
// Комментарий: Текущее значение валюты берется из `state.defaultCurrency`.
|
||
value: state.defaultCurrency,
|
||
// Комментарий: При выборе новой валюты вызываем метод `setDefaultCurrency` у Cubit.
|
||
onChanged: (String? newValue) {
|
||
if (newValue != null) {
|
||
context.read<SettingsCubit>().setDefaultCurrency(newValue);
|
||
}
|
||
},
|
||
// Комментарий: Формируем список доступных валют. Можно расширить этот список.
|
||
items: <String>['RUB', 'USD', 'EUR']
|
||
.map<DropdownMenuItem<String>>((String value) {
|
||
return DropdownMenuItem<String>(
|
||
value: value,
|
||
child: Text(value),
|
||
);
|
||
}).toList(),
|
||
),
|
||
),
|
||
const Divider(),
|
||
// Комментарий: ListTile для перехода на страницу редактирования категорий.
|
||
ListTile(
|
||
title: Text(localizations.editCategories),
|
||
subtitle: Text(localizations.editCategoriesDescription),
|
||
onTap: () {
|
||
Navigator.push(
|
||
context,
|
||
MaterialPageRoute(
|
||
builder: (context) => const CategoryListPage(),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
const Divider(),
|
||
],
|
||
),
|
||
);
|
||
},
|
||
),
|
||
);
|
||
}
|
||
} |