feat: aggrega duplicati nella lista della spesa con quantità

Quando si genera la lista dal piano pasti, gli alimenti ripetuti in
più giorni o slot vengono aggregati in un unico elemento con contatore.
Es. zucchine lunedì + mercoledì → "zucchine (x2)".

- ShoppingItem: aggiunto campo quantity (default 1, persistito in JSON)
- ShoppingListProvider.addAll: conta le occorrenze per nome
  (case-insensitive) e crea un ShoppingItem con quantity = conteggio
- ShoppingItemTile: mostra "(xN)" colorato in primary quando quantity > 1,
  diventa muted insieme al nome quando l'elemento è completato

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 18:54:22 +02:00
parent cba83c9559
commit 404a5f44ac
3 changed files with 51 additions and 17 deletions
@@ -2,29 +2,34 @@ class ShoppingItem {
final String id;
final String name;
final bool checked;
final int quantity;
const ShoppingItem({
required this.id,
required this.name,
this.checked = false,
this.quantity = 1,
});
ShoppingItem copyWith({String? id, String? name, bool? checked}) =>
ShoppingItem copyWith({String? id, String? name, bool? checked, int? quantity}) =>
ShoppingItem(
id: id ?? this.id,
name: name ?? this.name,
checked: checked ?? this.checked,
quantity: quantity ?? this.quantity,
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'checked': checked,
'quantity': quantity,
};
factory ShoppingItem.fromJson(Map<String, dynamic> json) => ShoppingItem(
id: json['id'] as String,
name: json['name'] as String,
checked: json['checked'] as bool? ?? false,
quantity: json['quantity'] as int? ?? 1,
);
}