Files
retail/lib/features/home/presentation/pages/home_page.dart
Phuoc Nguyen b94c158004 runable
2025-10-10 16:38:07 +07:00

174 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../widgets/product_selector.dart';
import '../widgets/cart_summary.dart';
import '../providers/cart_provider.dart';
import '../../domain/entities/cart_item.dart';
/// Home page - POS interface with product selector and cart
class HomePage extends ConsumerWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final cartAsync = ref.watch(cartProvider);
final isWideScreen = MediaQuery.of(context).size.width > 600;
return Scaffold(
appBar: AppBar(
title: const Text('Point of Sale'),
actions: [
// Cart item count badge
cartAsync.whenOrNull(
data: (items) => items.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Center(
child: Badge(
label: Text('${items.length}'),
child: const Icon(Icons.shopping_cart),
),
),
)
: null,
) ?? const SizedBox.shrink(),
],
),
body: isWideScreen
? Row(
children: [
// Product selector on left
Expanded(
flex: 3,
child: ProductSelector(
onProductTap: (product) {
_showAddToCartDialog(context, ref, product);
},
),
),
// Divider
const VerticalDivider(width: 1),
// Cart on right
const Expanded(
flex: 2,
child: CartSummary(),
),
],
)
: Column(
children: [
// Product selector on top
Expanded(
flex: 2,
child: ProductSelector(
onProductTap: (product) {
_showAddToCartDialog(context, ref, product);
},
),
),
// Divider
const Divider(height: 1),
// Cart on bottom
const Expanded(
flex: 3,
child: CartSummary(),
),
],
),
);
}
void _showAddToCartDialog(
BuildContext context,
WidgetRef ref,
dynamic product,
) {
int quantity = 1;
showDialog(
context: context,
builder: (context) => StatefulBuilder(
builder: (context, setState) => AlertDialog(
title: const Text('Add to Cart'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
product.name,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: const Icon(Icons.remove_circle_outline),
onPressed: quantity > 1
? () => setState(() => quantity--)
: null,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
'$quantity',
style: Theme.of(context).textTheme.headlineSmall,
),
),
IconButton(
icon: const Icon(Icons.add_circle_outline),
onPressed: quantity < product.stockQuantity
? () => setState(() => quantity++)
: null,
),
],
),
if (product.stockQuantity < 5)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'Only ${product.stockQuantity} in stock',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.error,
),
),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
FilledButton.icon(
onPressed: () {
// Create cart item from product
final cartItem = CartItem(
productId: product.id,
productName: product.name,
price: product.price,
quantity: quantity,
imageUrl: product.imageUrl,
addedAt: DateTime.now(),
);
// Add to cart
ref.read(cartProvider.notifier).addItem(cartItem);
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Added ${product.name} to cart'),
duration: const Duration(seconds: 2),
),
);
},
icon: const Icon(Icons.add_shopping_cart),
label: const Text('Add'),
),
],
),
),
);
}
}