diff --git a/trackeroo/lib/frontend/utils/category_listtile.dart b/trackeroo/lib/frontend/utils/category_listtile.dart index b3de6e0aeac56a7c50598c42e1beb437bc67df28..9ffeec0c8ee18a96df4d57d6865478b0a73bc78d 100644 --- a/trackeroo/lib/frontend/utils/category_listtile.dart +++ b/trackeroo/lib/frontend/utils/category_listtile.dart @@ -71,7 +71,14 @@ class CategoryListtile extends StatelessWidget { ), ], ), - const SizedBox(height: 48.0), + Text( + 'Budget: ${category.budget}', + style: const TextStyle( + fontSize: 17.0, + color: Color.fromARGB(255, 81, 78, 78), + ), + ), + const SizedBox(height: 22.0), Container( height: 6.0, decoration: BoxDecoration( @@ -86,4 +93,4 @@ class CategoryListtile extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/trackeroo/lib/frontend/views/edit_category_view.dart b/trackeroo/lib/frontend/views/edit_category_view.dart index 4c29978c05a06627d6f72829d47763e5be86cf4c..a15e500e8773e56963780a14e51c87efe4714041 100644 --- a/trackeroo/lib/frontend/views/edit_category_view.dart +++ b/trackeroo/lib/frontend/views/edit_category_view.dart @@ -16,6 +16,8 @@ class _EditCategoryPageState extends State<EditCategoryPage> { TextEditingController _nameController = TextEditingController(); Color _selectedColor = Colors.red; IconData _selectedIcon = Icons.star; + double _budget = 0; + bool _showIconPicker = false; @override void initState() { @@ -23,6 +25,7 @@ class _EditCategoryPageState extends State<EditCategoryPage> { _nameController.text = widget.category.title; _selectedColor = Color(widget.category.colorValue); _selectedIcon = _getValidIconData(widget.category.iconCodePoint); + _budget = widget.category.budget ?? 0; } IconData _getValidIconData(int codePoint) { @@ -50,7 +53,7 @@ class _EditCategoryPageState extends State<EditCategoryPage> { iconFontFamily: 'MaterialIcons', colorValue: _selectedColor.value, spendings: widget.category.spendings, - budget: widget.category.budget, + budget: _budget, ); final categoryBox = await Hive.openBox<Category>('categories'); @@ -105,8 +108,10 @@ class _EditCategoryPageState extends State<EditCategoryPage> { } } - Widget _buildIconContainer(IconData iconData) { + Widget _buildIconContainer(IconData iconData, double size) { return Container( + width: size, + height: size, decoration: BoxDecoration( color: _selectedColor, shape: BoxShape.circle, @@ -114,10 +119,19 @@ class _EditCategoryPageState extends State<EditCategoryPage> { child: Icon( iconData, color: Colors.white, + size: size * 0.6, ), ); } + void _deleteCategory() async { + final categoryBox = await Hive.openBox<Category>('categories'); + categoryBox.delete(widget.category.id); + categoryBox.close(); + + Navigator.pop(context); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -137,18 +151,74 @@ class _EditCategoryPageState extends State<EditCategoryPage> { ), ), const SizedBox(height: 16.0), - TextField( - controller: _nameController, - decoration: const InputDecoration( - labelText: 'Name', - - ), + Row( + children: [ + GestureDetector( + onTap: () { + setState(() { + _showIconPicker = !_showIconPicker; + }); + }, + child: _buildIconContainer(_selectedIcon, 48.0), + ), + const SizedBox(width: 16.0), + Expanded( + child: TextField( + controller: _nameController, + decoration: const InputDecoration( + labelText: 'Name', + ), + ), + ), + ], ), + if (_showIconPicker) + Expanded( + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 6, + childAspectRatio: 1.0, + children: [ + Icons.star, + Icons.favorite, + Icons.attach_money, + Icons.shopping_cart, + Icons.home, + Icons.work, + Icons.school, + Icons.pets, + Icons.luggage, + Icons.savings, + Icons.liquor, + Icons.celebration, + ].map((iconData) { + return GestureDetector( + onTap: () { + setState(() { + _onIconChanged(iconData); + _showIconPicker = false; + }); + }, + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: _selectedIcon == iconData + ? Colors.blue + : Colors.transparent, + width: 2.0, + ), + ), + child: _buildIconContainer(iconData, 32.0), + ), + ); + }).toList(), + ), + ), const SizedBox(height: 16.0), Row( children: [ const Text( - 'Farbe', + 'Budget', style: TextStyle( fontSize: 19.0, fontWeight: FontWeight.bold, @@ -156,76 +226,120 @@ class _EditCategoryPageState extends State<EditCategoryPage> { ), const SizedBox(width: 16.0), GestureDetector( - onTap: _showColorPicker, + onTap: () { + showDialog( + context: context, + builder: (BuildContext context) { + TextEditingController _budgetController = + TextEditingController(text: _budget.toString()); + + return AlertDialog( + title: const Text('Budget ändern'), + content: TextField( + controller: _budgetController, + keyboardType: const TextInputType.numberWithOptions( + decimal: true, + ), + decoration: const InputDecoration( + labelText: 'Neues Budget', + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text('Abbrechen'), + ), + TextButton( + onPressed: () { + double newBudget = double.tryParse( + _budgetController.text) ?? + 0; + setState(() { + _budget = newBudget; + }); + Navigator.of(context).pop(); + }, + child: const Text('OK'), + ), + ], + ); + }, + ); + }, child: Container( - width: 32.0, - height: 32.0, + padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: _selectedColor, - shape: BoxShape.circle, + border: Border.all( + color: Colors.black12, + width: 1.0, + ), + ), + child: Text( + '${_budget.toStringAsFixed(2)} €', + style: const TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), ), ), ), ], ), const SizedBox(height: 16.0), -Row( - children: [ - const Text( - 'Icon', - style: TextStyle( - fontSize: 19.0, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(width: 16.0), - Expanded( - child: GridView.count( - shrinkWrap: true, - crossAxisCount: 6, - childAspectRatio: 1.0, - children: [ - Icons.star, - Icons.favorite, - Icons.attach_money, - Icons.shopping_cart, - Icons.home, - Icons.work, - Icons.school, - Icons.pets, - Icons.luggage, - Icons.savings, - Icons.liquor, - Icons.celebration, - ].map((iconData) { - return GestureDetector( - onTap: () { - _onIconChanged(iconData); - }, - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: _selectedIcon == iconData - ? Colors.blue - : Colors.transparent, - width: 2.0, + GestureDetector( + onTap: _showColorPicker, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: _selectedColor, + borderRadius: BorderRadius.circular(8.0), + ), + child: const Text( + 'Farbe auswählen', + style: TextStyle( + color: Colors.black, + fontSize: 19.0, + fontWeight: FontWeight.bold, + ), ), ), - child: _buildIconContainer(iconData), ), - ); - }).toList(), - ), - ), - ], -), -const SizedBox(height: 16.0), -ElevatedButton( - - onPressed: _updateCategoryName, - child: const Text('Speichern'), - -), + const SizedBox(height: 16.0), + ElevatedButton( + onPressed: _updateCategoryName, + child: const Text('Speichern'), + ), + const SizedBox(height: 16.0), + ElevatedButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Kategorie löschen'), + content: const Text('Möchten Sie diese Kategorie wirklich löschen?'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text('Abbrechen'), + ), + TextButton( + onPressed: () { + _deleteCategory(); + }, + child: const Text('Löschen'), + ), + ], + ); + }, + ); + }, + child: const Text('Löschen'), + ), ], ), ), diff --git a/trackeroo/lib/frontend/views/new_category_view.dart b/trackeroo/lib/frontend/views/new_category_view.dart new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/trackeroo/lib/logic/models/category.dart b/trackeroo/lib/logic/models/category.dart index de5c9571b678d756ae2a9fb603a866fad712ff1c..1a99cb0b17f81e7d227b95b7ca3cf4afd7515485 100644 --- a/trackeroo/lib/logic/models/category.dart +++ b/trackeroo/lib/logic/models/category.dart @@ -32,7 +32,7 @@ class Category { this.iconFontFamily = 'MaterialIcons', required this.colorValue, this.spendings = 0, - this.budget = -1, + this.budget = -1, }); factory Category.fromJson(Map<String, dynamic> parsedJson) {