new plus button

This commit is contained in:
davmar
2026-08-31 09:40:38 +02:00
parent 3b698a3667
commit 92581e6d55
17 changed files with 1336 additions and 152 deletions
+60 -1
View File
@@ -13,6 +13,8 @@ import 'utils/dates.dart';
import 'utils/money.dart';
import 'widgets/confirm_dialog.dart';
import 'widgets/item_edit_sheet.dart';
import 'widgets/name_dialog.dart';
import 'widgets/tag_editor.dart';
class ShopDetailScreen extends StatefulWidget {
const ShopDetailScreen({
@@ -31,11 +33,18 @@ class ShopDetailScreen extends StatefulWidget {
class _ShopDetailScreenState extends State<ShopDetailScreen> {
late Future<({Shop shop, List<ShopItem> items})> _future;
bool _editing = false;
List<String> _tagSuggestions = [];
@override
void initState() {
super.initState();
_future = _load();
widget.repository
.getUsedShopTags()
.then((tags) {
if (mounted) setState(() => _tagSuggestions = tags);
})
.catchError((_) {});
}
Future<({Shop shop, List<ShopItem> items})> _load() async {
@@ -111,6 +120,28 @@ class _ShopDetailScreenState extends State<ShopDetailScreen> {
if (mounted) _reload();
}
Future<void> _editName(Shop shop) async {
final name = await showNameDialog(
context,
title: 'Trip name',
label: 'Name',
initial: shop.name,
allowEmpty: true,
);
if (name == null || !mounted) return;
await widget.repository.updateShop(
id: shop.id,
name: name,
clearName: name.isEmpty,
);
if (mounted) _reload();
}
Future<void> _setTags(Shop shop, List<String> tags) async {
await widget.repository.updateShop(id: shop.id, tags: tags);
if (mounted) _reload();
}
Widget? _itemSubtitle(ShopItem item) {
final parts = [
if (item.quantity != null)
@@ -160,12 +191,40 @@ class _ShopDetailScreenState extends State<ShopDetailScreen> {
return ListView(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 32),
children: [
Text(shop.supermarket, style: theme.textTheme.headlineMedium),
if (_editing)
ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
shop.name?.isNotEmpty == true
? shop.name!
: 'Add a trip name',
),
subtitle: const Text('Optional name for this shop log'),
trailing: const Icon(Icons.edit_outlined),
onTap: () => _editName(shop),
)
else
Text(shop.displayName, style: theme.textTheme.headlineMedium),
if (_editing || (shop.name != null && shop.name!.isNotEmpty)) ...[
const SizedBox(height: 4),
Text(shop.supermarket, style: theme.textTheme.titleMedium),
],
const SizedBox(height: 4),
Text(
formatDate(shop.shoppedAt),
style: theme.textTheme.bodyLarge,
),
if (_editing) ...[
const SizedBox(height: 16),
TagEditor(
tags: shop.tags,
suggestions: _tagSuggestions,
onChanged: (tags) => _setTags(shop, tags),
),
] else if (shop.tags.isNotEmpty) ...[
const SizedBox(height: 12),
TagChips(tags: shop.tags),
],
if (hasReceipt) ...[
const SizedBox(height: 16),
GestureDetector(