feat: add rows count (broken), fix: bug with low stock items
This commit is contained in:
@@ -12,8 +12,10 @@ import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import '../models/bar_tab.dart';
|
||||
import '../models/product.dart';
|
||||
import '../models/tab_item.dart';
|
||||
import '../services/product_service.dart';
|
||||
import '../utils/app_updater.dart';
|
||||
import '../viewmodels/bar_screen_view_model.dart';
|
||||
import '../viewmodels/settings_view_model.dart';
|
||||
import '../l10n/app_localizations.dart';
|
||||
import '../l10n/app_localizations_helpers.dart';
|
||||
|
||||
@@ -38,6 +40,11 @@ class _BarScreenViewState extends State<BarScreenView> {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final viewModel = context.watch<BarScreenViewModel>();
|
||||
final productsViewModel = context.watch<ProductListViewModel>();
|
||||
final settings = context.watch<SettingsViewModel>().settings;
|
||||
final stockByProductId = {
|
||||
for (final product in productsViewModel.products)
|
||||
product.id: product.stockQuantity,
|
||||
};
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
@@ -118,6 +125,7 @@ class _BarScreenViewState extends State<BarScreenView> {
|
||||
flex: 2,
|
||||
child: _ProductGrid(
|
||||
products: productsViewModel.products,
|
||||
rows: settings.barGridRows,
|
||||
hasSelectedTab: viewModel.selectedTab != null,
|
||||
onProductTap: (product) async {
|
||||
if (viewModel.selectedTab == null) {
|
||||
@@ -130,10 +138,18 @@ class _BarScreenViewState extends State<BarScreenView> {
|
||||
try {
|
||||
await viewModel.addProductToSelectedTab(product);
|
||||
} catch (e, stack) {
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
if (e is! InsufficientStockException) {
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l10n.couldNotAddProductToTab)),
|
||||
SnackBar(
|
||||
content: Text(
|
||||
e is InsufficientStockException
|
||||
? l10n.productOutOfStock
|
||||
: l10n.couldNotAddProductToTab,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -146,6 +162,7 @@ class _BarScreenViewState extends State<BarScreenView> {
|
||||
tabs: viewModel.tabs,
|
||||
selectedTab: viewModel.selectedTab,
|
||||
selectedTabId: viewModel.selectedTabId,
|
||||
stockByProductId: stockByProductId,
|
||||
onNewTabPressed: () => showNewTabDialog(context),
|
||||
onTabSelected: viewModel.selectTab,
|
||||
onItemQuantityChanged: viewModel.changeItemQuantity,
|
||||
@@ -166,11 +183,13 @@ class _BarScreenViewState extends State<BarScreenView> {
|
||||
// ---------------------------------------------------------------------------
|
||||
class _ProductGrid extends StatelessWidget {
|
||||
final List<Product> products;
|
||||
final int rows;
|
||||
final bool hasSelectedTab;
|
||||
final ValueChanged<Product> onProductTap;
|
||||
|
||||
const _ProductGrid({
|
||||
required this.products,
|
||||
required this.rows,
|
||||
required this.hasSelectedTab,
|
||||
required this.onProductTap,
|
||||
});
|
||||
@@ -267,11 +286,26 @@ class _ProductGrid extends StatelessWidget {
|
||||
Expanded(
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final columns = ((constraints.maxWidth / 170).floor())
|
||||
.clamp(3, 5)
|
||||
.toInt();
|
||||
const horizontalPadding = 32.0;
|
||||
const verticalPadding = 28.0;
|
||||
const spacing = 12.0;
|
||||
final rowCount = rows.clamp(2, 6).toInt();
|
||||
final rowHeight =
|
||||
((constraints.maxHeight -
|
||||
verticalPadding -
|
||||
(rowCount - 1) * spacing) /
|
||||
rowCount)
|
||||
.clamp(96.0, 320.0)
|
||||
.toDouble();
|
||||
final columns =
|
||||
(((constraints.maxWidth - horizontalPadding + spacing) /
|
||||
(rowHeight + spacing))
|
||||
.ceil())
|
||||
.clamp(2, 8)
|
||||
.toInt();
|
||||
|
||||
return GridView.builder(
|
||||
key: ValueKey('product-grid-$rows'),
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
|
||||
itemCount: products.length,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
@@ -306,6 +340,7 @@ class _TabPanel extends StatefulWidget {
|
||||
final List<BarTab> tabs;
|
||||
final BarTab? selectedTab;
|
||||
final String? selectedTabId;
|
||||
final Map<String, int> stockByProductId;
|
||||
final VoidCallback onNewTabPressed;
|
||||
final ValueChanged<String> onTabSelected;
|
||||
final Future<void> Function(TabItem item, int quantity) onItemQuantityChanged;
|
||||
@@ -316,6 +351,7 @@ class _TabPanel extends StatefulWidget {
|
||||
required this.tabs,
|
||||
required this.selectedTab,
|
||||
required this.selectedTabId,
|
||||
required this.stockByProductId,
|
||||
required this.onNewTabPressed,
|
||||
required this.onTabSelected,
|
||||
required this.onItemQuantityChanged,
|
||||
@@ -452,6 +488,7 @@ class _TabPanelState extends State<_TabPanel> {
|
||||
)
|
||||
: _SelectedTabDetails(
|
||||
tab: widget.selectedTab!,
|
||||
stockByProductId: widget.stockByProductId,
|
||||
onItemQuantityChanged: widget.onItemQuantityChanged,
|
||||
onCloseTabPressed: widget.onCloseTabPressed,
|
||||
),
|
||||
@@ -596,11 +633,13 @@ class _OpenTabsList extends StatelessWidget {
|
||||
|
||||
class _SelectedTabDetails extends StatelessWidget {
|
||||
final BarTab tab;
|
||||
final Map<String, int> stockByProductId;
|
||||
final Future<void> Function(TabItem item, int quantity) onItemQuantityChanged;
|
||||
final VoidCallback onCloseTabPressed;
|
||||
|
||||
const _SelectedTabDetails({
|
||||
required this.tab,
|
||||
required this.stockByProductId,
|
||||
required this.onItemQuantityChanged,
|
||||
required this.onCloseTabPressed,
|
||||
});
|
||||
@@ -654,6 +693,7 @@ class _SelectedTabDetails extends StatelessWidget {
|
||||
|
||||
return _TabItemRow(
|
||||
item: item,
|
||||
stockByProductId: stockByProductId,
|
||||
onQuantityChanged: onItemQuantityChanged,
|
||||
);
|
||||
},
|
||||
@@ -706,14 +746,21 @@ class _SelectedTabDetails extends StatelessWidget {
|
||||
|
||||
class _TabItemRow extends StatelessWidget {
|
||||
final TabItem item;
|
||||
final Map<String, int> stockByProductId;
|
||||
final Future<void> Function(TabItem item, int quantity) onQuantityChanged;
|
||||
|
||||
const _TabItemRow({required this.item, required this.onQuantityChanged});
|
||||
const _TabItemRow({
|
||||
required this.item,
|
||||
required this.stockByProductId,
|
||||
required this.onQuantityChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final availableStock = stockByProductId[item.productId];
|
||||
final canIncrease = availableStock == null || availableStock > 0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
@@ -771,18 +818,28 @@ class _TabItemRow extends StatelessWidget {
|
||||
),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
onPressed: () async {
|
||||
try {
|
||||
await onQuantityChanged(item, item.quantity + 1);
|
||||
} catch (e, stack) {
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l10n.couldNotUpdateQuantity)),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
onPressed: canIncrease
|
||||
? () async {
|
||||
try {
|
||||
await onQuantityChanged(item, item.quantity + 1);
|
||||
} catch (e, stack) {
|
||||
if (e is! InsufficientStockException) {
|
||||
Sentry.captureException(e, stackTrace: stack);
|
||||
}
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
e is InsufficientStockException
|
||||
? l10n.productOutOfStock
|
||||
: l10n.couldNotUpdateQuantity,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
: null,
|
||||
icon: const Icon(Icons.add_rounded, size: 18),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user