Feat: Macht die Kontoliste und Versionsanzeige funktional

This commit is contained in:
2025-12-25 23:15:54 +01:00
parent 7916161e4f
commit a45169bf12
11 changed files with 488 additions and 326 deletions

View File

@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import '../../Controller/account_controller.dart';
import '../../Entities/drift_database.dart';
import '../../Entities/list_item.dart';
import '../Misc/editable_list.dart';
class AccountList extends StatefulWidget {
const AccountList({super.key});
@override
State<StatefulWidget> createState() => _AccountListState();
}
class _AccountListState extends State<AccountList> {
final AccountController _accountController = AccountController();
List<Account> _accounts = [];
@override
void initState() {
super.initState();
_accounts = _accountController.accounts.value;
_accountController.accounts.addListener(() {
setState(() {
if (context.mounted) {
_accounts = _accountController.accounts.value;
}
});
});
}
@override
Widget build(final BuildContext context) {
if (_accounts != []) {
final List<ListItem> formatedAccounts = [];
for (final Account data in _accounts) {
formatedAccounts.add(ListItem(id: data.id, name: data.name));
}
return EditableList(
name: 'Konten',
items: formatedAccounts,
onAdd: _accountController.newAccountHandler,
onRename: _accountController.renameAccountHandler,
onDelete: _accountController.deleteAccountHandler,
icon: const Icon(Icons.account_balance_wallet),
addTooltip: 'Konto hinzufügen',
menuTooltip: 'Menü anzeigen',
);
} else {
return const Center(child: CircularProgressIndicator());
}
}
}

View File

@@ -1,4 +1,7 @@
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'account_list.dart';
/// Eine Widget-Klasse, die die Einstellungsseite der Anwendung darstellt.
class Settings extends StatefulWidget {
@@ -10,110 +13,6 @@ class Settings extends StatefulWidget {
}
class _SettingsState extends State<Settings> {
final List<String> _accounts = <String>[
'Girokonto',
'Sparkonto',
'Kreditkarte',
];
Future<void> _addAccount() async {
final controller = TextEditingController();
await showDialog(
context: context,
builder: (final BuildContext context) => AlertDialog(
title: const Text('Konto hinzufügen'),
content: TextField(
controller: controller,
decoration: const InputDecoration(
labelText: 'Kontoname',
border: OutlineInputBorder(),
),
autofocus: true,
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Abbrechen'),
),
ElevatedButton(
onPressed: () {
if (controller.text.isNotEmpty) {
setState(() => _accounts.add(controller.text));
}
Navigator.pop(context);
},
child: const Text('Hinzufügen'),
),
],
),
);
}
Future<void> _renameAccount(final int index) async {
final controller = TextEditingController(
text: _accounts[index],
);
await showDialog(
context: context,
builder: (final BuildContext context) => AlertDialog(
title: const Text('Konto umbenennen'),
content: TextField(
controller: controller,
decoration: const InputDecoration(
labelText: 'Neuer Name',
border: OutlineInputBorder(),
),
autofocus: true,
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Abbrechen'),
),
ElevatedButton(
onPressed: () {
if (controller.text.isNotEmpty) {
setState(() => _accounts[index] = controller.text);
}
Navigator.pop(context);
},
child: const Text('Speichern'),
),
],
),
);
}
Future<void> _removeAccount(final int index) async {
await showDialog(
context: context,
builder: (final BuildContext context) => AlertDialog(
title: const Text('Konto entfernen'),
content: Text(
'Möchtest du das Konto "${_accounts[index]}" wirklich löschen?',
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Abbrechen'),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.error,
),
onPressed: () {
setState(() => _accounts.removeAt(index));
Navigator.pop(context);
},
child: const Text('Löschen'),
),
],
),
);
}
@override
Widget build(final BuildContext context) {
final ThemeData theme = Theme.of(context);
@@ -129,12 +28,9 @@ class _SettingsState extends State<Settings> {
'Einstellungen',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 24),
_accountHeader(),
const SizedBox(height: 8),
_accountList(),
const AccountList(),
const SizedBox(height: 8),
_versionNumber(theme),
@@ -145,60 +41,32 @@ class _SettingsState extends State<Settings> {
);
}
Widget _accountHeader() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text(
'Konten',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
IconButton(
onPressed: _addAccount,
icon: const Icon(Icons.add),
tooltip: 'Konto hinzufügen',
),
],
);
Widget _versionNumber(final ThemeData theme) {
final Future<PackageInfo> packageInfo = PackageInfo.fromPlatform();
Widget _accountList() => Expanded(
child: ListView.separated(
itemCount: _accounts.length,
separatorBuilder: (_, _) => const Divider(),
itemBuilder: (final BuildContext context, final int index) => ListTile(
contentPadding: EdgeInsets.zero,
title: Text(_accounts[index]),
leading: const Icon(Icons.account_balance_wallet),
trailing: PopupMenuButton<String>(
onSelected: (final String value) async {
if (value == 'rename') {
await _renameAccount(index);
} else if (value == 'delete') {
await _removeAccount(index);
}
},
itemBuilder: (final BuildContext context) =>
const <PopupMenuEntry<String>>[
PopupMenuItem<String>(
value: 'rename',
child: Text('Umbenennen'),
),
PopupMenuItem<String>(
value: 'delete',
child: Text('Entfernen'),
),
],
),
return Align(
alignment: Alignment.bottomLeft,
child: FutureBuilder(
future: packageInfo,
builder:
(
final BuildContext context,
final AsyncSnapshot<PackageInfo> snapshot,
) {
if (snapshot.hasData) {
return Text(
'${snapshot.data?.version}+${snapshot.data?.buildNumber}',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurface.withAlpha(
(0.6 * 255).round(),
),
),
);
} else {
return const CircularProgressIndicator();
}
},
),
),
);
Widget _versionNumber(final ThemeData theme) => Align(
alignment: Alignment.bottomLeft,
child: Text(
'Version 0.0.0+0',
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurface.withAlpha((0.6 * 255).round()),
),
),
);
);
}
}