added categories, import export, settings

This commit is contained in:
davmar
2026-08-29 16:45:27 +02:00
parent 2a5a922aab
commit 732a0dc14a
30 changed files with 3700 additions and 167 deletions
+108
View File
@@ -0,0 +1,108 @@
/// Bottom navigation: products, scan, and shop log.
library;
import 'package:flutter/material.dart';
import 'products_screen.dart';
import 'scan_screen.dart';
import 'services/app_settings.dart';
import 'services/product_repository.dart';
import 'shop_log_screen.dart';
class HomeShell extends StatefulWidget {
const HomeShell({super.key, required this.repository});
final ProductRepository repository;
@override
State<HomeShell> createState() => _HomeShellState();
}
class _HomeShellState extends State<HomeShell> {
static const _scanIndex = 1;
static const _shopLogIndex = 2;
int _index = _scanIndex;
int _revision = 0;
AppSettings? _settings;
int _seenGeneration = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
final settings = SettingsScope.maybeOf(context);
if (settings != _settings) {
_settings?.removeListener(_onSettings);
_settings = settings;
_seenGeneration = settings?.catalogGeneration ?? 0;
_settings?.addListener(_onSettings);
}
}
@override
void dispose() {
_settings?.removeListener(_onSettings);
super.dispose();
}
void _onSettings() {
final generation = _settings?.catalogGeneration ?? 0;
if (generation == _seenGeneration) return;
_seenGeneration = generation;
if (mounted) setState(() => _revision++);
}
void _onTripSaved() {
setState(() {
_index = _shopLogIndex;
_revision++;
});
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Shopping trip saved.')),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: switch (_index) {
0 => ProductsScreen(
key: ValueKey('products-$_revision'),
repository: widget.repository,
),
1 => ScanScreen(
repository: widget.repository,
onTripSaved: _onTripSaved,
),
_ => ShopLogScreen(
key: ValueKey('shops-$_revision'),
repository: widget.repository,
),
},
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (index) => setState(() => _index = index),
destinations: const [
NavigationDestination(
icon: Icon(Icons.inventory_2_outlined),
selectedIcon: Icon(Icons.inventory_2),
label: 'Products',
),
NavigationDestination(
icon: Icon(Icons.photo_camera_outlined),
selectedIcon: Icon(Icons.photo_camera),
label: 'Scan',
),
NavigationDestination(
icon: Icon(Icons.receipt_long_outlined),
selectedIcon: Icon(Icons.receipt_long),
label: 'Shop log',
),
],
),
);
}
}