feat: add remote products and qr code for payconic

This commit is contained in:
2026-10-22 00:10:26 +02:00
parent b15d94a805
commit 71af6f9ffe
31 changed files with 2053 additions and 179 deletions
+8 -17
View File
@@ -9,8 +9,6 @@ import '../l10n/app_localizations_helpers.dart';
import '../utils/money.dart';
import '../utils/navigation.dart';
import '../viewmodels/product_list_view_model.dart';
import '../viewmodels/remote_sync_view_model.dart';
import 'widgets/managed_on_website_notice.dart';
class ProductListView extends StatefulWidget {
const ProductListView({super.key});
@@ -33,8 +31,6 @@ class _ProductListViewState extends State<ProductListView> {
Widget build(BuildContext context) {
final viewModel = context.watch<ProductListViewModel>();
final l10n = AppLocalizations.of(context);
// A paired tablet gets its products from the website
final managedOnWebsite = context.watch<RemoteSyncViewModel>().isConfigured;
return Scaffold(
appBar: AppBar(
@@ -45,13 +41,11 @@ class _ProductListViewState extends State<ProductListView> {
title: Text(l10n.products),
),
resizeToAvoidBottomInset: false,
floatingActionButton: managedOnWebsite
? null
: FloatingActionButton.extended(
onPressed: () => context.push('/products/new'),
icon: const Icon(Icons.add),
label: Text(l10n.addProduct),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => context.push('/products/new'),
icon: const Icon(Icons.add),
label: Text(l10n.addProduct),
),
body: Builder(
builder: (context) {
if (viewModel.isLoading) {
@@ -62,19 +56,16 @@ class _ProductListViewState extends State<ProductListView> {
return Center(child: Text(l10n.errorText(viewModel.loadError)));
}
if (viewModel.products.isEmpty && !managedOnWebsite) {
if (viewModel.products.isEmpty) {
return Center(child: Text(l10n.noProductsYet));
}
// The notice takes the first row
final offset = managedOnWebsite ? 1 : 0;
return ListView.separated(
padding: const EdgeInsets.all(16),
itemCount: viewModel.products.length + offset,
itemCount: viewModel.products.length,
separatorBuilder: (_, _) => const SizedBox(height: 8),
itemBuilder: (context, index) {
if (index < offset) return const ManagedOnWebsiteNotice();
final product = viewModel.products[index - offset];
final product = viewModel.products[index];
return Card(
child: ListTile(