product categories and other improvements

This commit is contained in:
esche 2023-06-25 21:11:10 +02:00
parent 000f141b5a
commit df255d71b8
5 changed files with 80 additions and 116 deletions

View file

@ -2,11 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'sample_data.dart';
/* todo:
- individuelle Icons je nach Kategorie
- editing
*/
class ShowBasket extends StatelessWidget {
final int index;
final bool editable;
@ -37,7 +32,7 @@ class ShowBasket extends StatelessWidget {
children: [
FloatingActionButton(
backgroundColor: Colors.redAccent.shade100,
child: const Icon(Icons.delete),
child: const Icon(Icons.remove_shopping_cart),
onPressed: () {}),
const SizedBox(
width: 10,
@ -54,50 +49,29 @@ class ShowBasket extends StatelessWidget {
ListView getBasket(List<Basket> basket) {
return ListView.builder(
itemCount: null,
itemCount: basket.length,
itemBuilder: (context, index) {
if (index < basket.length) {
return Card(
child: ListTile(
leading: getLeading(basket[index].products.category),
title: Text(basket[index].products.name),
subtitle: Text(
'${basket[index].amount} ${basket[index].products.unit}'),
trailing: editable
? SizedBox(
width: 100,
child: TextField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
]),
)
: null),
);
} else {
return null;
}
return Card(
child: ListTile(
leading: Text(
basket[index].products.category.icon,
style: const TextStyle(fontSize: 24),
),
title: Text(basket[index].products.name),
subtitle: Text(
'${basket[index].amount} ${basket[index].products.unit}'),
trailing: editable
? SizedBox(
width: 100,
child: TextField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
]),
)
: null),
);
},
);
}
Widget getLeading(Category category) {
switch (category) {
case Category.obstUndGemuese:
return const Text("🍒");
case Category.brotCerealienUndAufstriche:
return const Text(
'🍞',
style: TextStyle(fontSize: 24),
);
case Category.drogerieUndHaushalt:
case Category.getraenke:
case Category.kochenUndBacken:
case Category.pfand:
case Category.suessesUndKnabbereien:
case Category.oeleSossenUndGewuerze:
default:
return const Icon(Icons.error);
}
}
}

View file

@ -7,6 +7,7 @@ import 'sample_data.dart';
/*
todo:
- Einkauf und Settings
- edit + Zeitspanne
- farbliche Hervorhebungen
- semanticLabels, Screenreader
- monatliche Aufladung: ausstehende Beträge
@ -37,28 +38,24 @@ class Finance extends StatelessWidget {
),
),
body: ListView.builder(
itemCount: null,
itemCount: SampleData().transactions.length,
itemBuilder: (context, index) {
if (index < SampleData().transactions.length) {
return Card(
child: ListTile(
leading: getIcon(SampleData().transactions[index].type),
title: Text(
gettitle(SampleData().transactions[index].type)),
subtitle: getSubtitle(SampleData().transactions[index]),
trailing: getTrailing(context, index),
onTap: (SampleData().transactions[index].basket != null)
? () {
showBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowBasket(index);
});
}
: null));
} else {
return null;
}
return Card(
child: ListTile(
leading: getIcon(SampleData().transactions[index].type),
title:
Text(gettitle(SampleData().transactions[index].type)),
subtitle: getSubtitle(SampleData().transactions[index]),
trailing: getTrailing(context, index),
onTap: (SampleData().transactions[index].basket != null)
? () {
showBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowBasket(index);
});
}
: null));
}));
}
@ -104,30 +101,15 @@ class Finance extends StatelessWidget {
getTrailing(BuildContext context, int index) {
if (SampleData().transactions[index].type == TransaktionArt.einkauf) {
return PopupMenuButton(
onSelected: (value) {
if (value == 'edit') {
showBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowBasket(index, editable: true);
});
}
return IconButton(
icon: const Icon(Icons.manage_history),
onPressed: () {
showBottomSheet(
context: context,
builder: (BuildContext context) {
return ShowBasket(index, editable: true);
});
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'edit',
child: ListTile(
leading: Icon(Icons.manage_history),
title: Text('Warenkorb bearbeiten')),
),
const PopupMenuItem<String>(
value: 'delete',
child: ListTile(
leading: Icon(Icons.remove_shopping_cart),
title: Text('Einkauf stornieren')),
),
],
);
} else {
return null;

View file

@ -79,7 +79,8 @@ class _MyHomePageState extends State<MyHomePage> {
],
),
body: <Widget>[
Shopping(),
//Shopping(),
const Shopping(),
const Finance(),
ListView(children: const <Widget>[
ListTile(

View file

@ -4,15 +4,10 @@ enum TransaktionArt { monatlBeitrag, aufladung, einkauf, korrektur }
enum Unit { stueck, menge }
enum Category {
obstUndGemuese,
brotCerealienUndAufstriche,
getraenke,
drogerieUndHaushalt,
kochenUndBacken,
oeleSossenUndGewuerze,
suessesUndKnabbereien,
pfand
class Category {
final String name;
final String icon;
const Category({required this.name, required this.icon});
}
class Transaction {
@ -47,15 +42,25 @@ class Basket {
}
class SampleData {
static const List<Product> products = [
Product('Apfel', Unit.stueck, 0.23, 7, Category.obstUndGemuese),
Product('Mehl', Unit.menge, 0.003, 19, Category.kochenUndBacken),
Product('Brot', Unit.stueck, 1.23, 7, Category.brotCerealienUndAufstriche),
Product('Milch', Unit.stueck, 2.23, 3, Category.getraenke),
Product('Zahnpasta', Unit.stueck, 0.23, 7, Category.drogerieUndHaushalt),
Product('Pfeffer', Unit.stueck, 0.23, 7, Category.oeleSossenUndGewuerze),
Product('Schokolade', Unit.menge, 0.23, 7, Category.suessesUndKnabbereien),
Product('Flaschenpfand', Unit.stueck, -0.15, 0, Category.pfand)
static const List<Category> categories = [
Category(name: 'Obst und Gemüse', icon: '🍒'),
Category(name: 'Kochen und Backen', icon: '🍝'),
Category(name: 'Brot, Cerealien & Aufstriche', icon: '🍞'),
Category(name: 'Getränke und Pfand', icon: '🫖'),
Category(name: 'Drogerie und Haushalt', icon: '🧼'),
Category(name: 'Öl, Soßen und Gewürze', icon: '🫚'),
Category(name: 'Süßes und Knabbereien', icon: '🍪')
];
static List<Product> products = [
Product('Apfel', Unit.stueck, 0.23, 7, categories[0]),
Product('Mehl', Unit.menge, 0.003, 19, categories[1]),
Product('Brot', Unit.stueck, 1.23, 7, categories[2]),
Product('Milch', Unit.stueck, 2.23, 3, categories[3]),
Product('Zahnpasta', Unit.stueck, 0.23, 7, categories[4]),
Product('Pfeffer', Unit.stueck, 0.23, 7, categories[5]),
Product('Schokolade', Unit.menge, 0.23, 7, categories[6]),
Product('Flaschenpfand', Unit.stueck, -0.15, 0, categories[3])
];
static List<Basket> basket = [

View file

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:mitgliederladen/sample_data.dart';
class Shopping extends StatelessWidget {
Shopping({super.key});
const Shopping({super.key});
@override
Widget build(BuildContext context) {
@ -13,22 +14,23 @@ class Shopping extends StatelessWidget {
body: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: SampleData.categories.length,
itemBuilder: ((context, index) {
return Card(
child: Column(children: [
const Expanded(
Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
'🍒',
style: TextStyle(fontSize: 400),
SampleData.categories[index].icon,
style: const TextStyle(fontSize: 400),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Obst und Gemüse',
SampleData.categories[index].name,
style: Theme.of(context).textTheme.labelLarge,
),
),