|
@@ -31,7 +31,8 @@ class _PedidoFormState extends State<PedidoForm> {
|
|
Producto? _productoActual;
|
|
Producto? _productoActual;
|
|
bool _estadoBusqueda = false;
|
|
bool _estadoBusqueda = false;
|
|
Pedido? pedidoActual;
|
|
Pedido? pedidoActual;
|
|
- ScrollController _gridViewController = ScrollController();
|
|
|
|
|
|
+ ScrollController _listViewController = ScrollController();
|
|
|
|
+ ScrollController _categoryScrollController = ScrollController();
|
|
final _searchController = TextEditingController();
|
|
final _searchController = TextEditingController();
|
|
final NumberFormat _numberFormat = NumberFormat.decimalPattern('es_MX');
|
|
final NumberFormat _numberFormat = NumberFormat.decimalPattern('es_MX');
|
|
int? selectedDescuento = 0;
|
|
int? selectedDescuento = 0;
|
|
@@ -91,10 +92,17 @@ class _PedidoFormState extends State<PedidoForm> {
|
|
Provider.of<DescuentoViewModel>(context, listen: false).cargarDescuentos();
|
|
Provider.of<DescuentoViewModel>(context, listen: false).cargarDescuentos();
|
|
}
|
|
}
|
|
|
|
|
|
- _onSearchChanged(String value) {
|
|
|
|
|
|
+ void _onSearchChanged(String value) {
|
|
if (value.isEmpty) {
|
|
if (value.isEmpty) {
|
|
- cargarProductosIniciales();
|
|
|
|
|
|
+ // Si no hay valor de búsqueda, cargar los productos iniciales y restaurar la categoría seleccionada.
|
|
|
|
+ cargarProductosPorCategoria(
|
|
|
|
+ categoriaSeleccionada?.id ?? categorias.first.id);
|
|
} else {
|
|
} else {
|
|
|
|
+ // Realiza la búsqueda y desactiva la categoría seleccionada para mostrar productos de todas las categorías.
|
|
|
|
+ setState(() {
|
|
|
|
+ _estadoBusqueda = true; // Indicamos que hay una búsqueda activa
|
|
|
|
+ categoriaSeleccionada = null; // Ignoramos la categoría seleccionada
|
|
|
|
+ });
|
|
Provider.of<ProductoViewModel>(context, listen: false)
|
|
Provider.of<ProductoViewModel>(context, listen: false)
|
|
.fetchLocalByName(nombre: value);
|
|
.fetchLocalByName(nombre: value);
|
|
}
|
|
}
|
|
@@ -585,8 +593,9 @@ class _PedidoFormState extends State<PedidoForm> {
|
|
|
|
|
|
@override
|
|
@override
|
|
void dispose() {
|
|
void dispose() {
|
|
- _gridViewController.dispose();
|
|
|
|
|
|
+ _listViewController.dispose();
|
|
_searchController.dispose();
|
|
_searchController.dispose();
|
|
|
|
+ _categoryScrollController.dispose();
|
|
super.dispose();
|
|
super.dispose();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1019,69 +1028,55 @@ class _PedidoFormState extends State<PedidoForm> {
|
|
Widget _buildProductsSection() {
|
|
Widget _buildProductsSection() {
|
|
return Column(
|
|
return Column(
|
|
children: [
|
|
children: [
|
|
|
|
+ const SizedBox(height: 5),
|
|
|
|
+ _buildSearchBar(),
|
|
const SizedBox(height: 10),
|
|
const SizedBox(height: 10),
|
|
_buildCategoryButtons(),
|
|
_buildCategoryButtons(),
|
|
const SizedBox(height: 15),
|
|
const SizedBox(height: 15),
|
|
Expanded(
|
|
Expanded(
|
|
child: Consumer<ProductoViewModel>(builder: (context, model, child) {
|
|
child: Consumer<ProductoViewModel>(builder: (context, model, child) {
|
|
productos = model.productos;
|
|
productos = model.productos;
|
|
- return GridView.builder(
|
|
|
|
- controller: _gridViewController,
|
|
|
|
- key: ValueKey<int>(categoriaSeleccionada?.id ?? 0),
|
|
|
|
- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
|
- crossAxisCount: 3,
|
|
|
|
- childAspectRatio: 3 / 2,
|
|
|
|
- ),
|
|
|
|
- itemCount: productos.length,
|
|
|
|
- itemBuilder: (context, index) {
|
|
|
|
- final producto = productos[index];
|
|
|
|
- if (producto.idCategoria != categoriaSeleccionada?.id) {
|
|
|
|
- return Container();
|
|
|
|
- }
|
|
|
|
- return Card(
|
|
|
|
- child: InkWell(
|
|
|
|
- onTap: () => agregarAlCarrito(producto),
|
|
|
|
- child: Column(
|
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
- children: [
|
|
|
|
- if (producto.imagen != null &&
|
|
|
|
- File(producto.imagen!).existsSync())
|
|
|
|
- Image.file(
|
|
|
|
- File(producto.imagen!),
|
|
|
|
- height: 120,
|
|
|
|
- fit: BoxFit.cover,
|
|
|
|
- )
|
|
|
|
- else
|
|
|
|
- const Icon(Icons.fastfood, size: 80),
|
|
|
|
- const SizedBox(height: 8),
|
|
|
|
- Padding(
|
|
|
|
- padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
|
|
|
- child: Text(
|
|
|
|
|
|
+ return Scrollbar(
|
|
|
|
+ controller: _listViewController,
|
|
|
|
+ thumbVisibility: true,
|
|
|
|
+ trackVisibility: true,
|
|
|
|
+ child: ListView.builder(
|
|
|
|
+ controller: _listViewController,
|
|
|
|
+ itemCount: productos.length,
|
|
|
|
+ itemBuilder: (context, index) {
|
|
|
|
+ final producto = productos[index];
|
|
|
|
+ return Card(
|
|
|
|
+ child: ListTile(
|
|
|
|
+ title: Row(
|
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
+ children: [
|
|
|
|
+ Text(
|
|
producto.nombre ?? '',
|
|
producto.nombre ?? '',
|
|
style: const TextStyle(
|
|
style: const TextStyle(
|
|
fontSize: 16,
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
- textAlign: TextAlign.center,
|
|
|
|
|
|
+ textAlign: TextAlign.left,
|
|
),
|
|
),
|
|
- ),
|
|
|
|
- const SizedBox(height: 8),
|
|
|
|
- Text(
|
|
|
|
- '\$${producto.precio}',
|
|
|
|
- style: const TextStyle(
|
|
|
|
- fontSize: 16,
|
|
|
|
- fontWeight: FontWeight.bold,
|
|
|
|
- color: Color(0xFF008000),
|
|
|
|
|
|
+ Text(
|
|
|
|
+ '\$${producto.precio}',
|
|
|
|
+ style: const TextStyle(
|
|
|
|
+ fontSize: 16,
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ color: Colors.green,
|
|
|
|
+ ),
|
|
|
|
+ textAlign: TextAlign.right,
|
|
),
|
|
),
|
|
- ),
|
|
|
|
- ],
|
|
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ onTap: () => agregarAlCarrito(producto),
|
|
),
|
|
),
|
|
- ),
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
);
|
|
);
|
|
}),
|
|
}),
|
|
- )
|
|
|
|
|
|
+ ),
|
|
],
|
|
],
|
|
);
|
|
);
|
|
}
|
|
}
|
|
@@ -1092,31 +1087,38 @@ class _PedidoFormState extends State<PedidoForm> {
|
|
|
|
|
|
return Container(
|
|
return Container(
|
|
height: 50,
|
|
height: 50,
|
|
- child: ListView.builder(
|
|
|
|
- scrollDirection: Axis.horizontal,
|
|
|
|
- itemCount: categoriasFiltradas.length,
|
|
|
|
- itemBuilder: (context, index) {
|
|
|
|
- final categoria = categoriasFiltradas[index];
|
|
|
|
- bool isSelected = categoriaSeleccionada?.id == categoria.id;
|
|
|
|
- return Padding(
|
|
|
|
- padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
|
|
|
- child: ElevatedButton(
|
|
|
|
- onPressed: () {
|
|
|
|
- cargarProductosPorCategoria(categoria.id);
|
|
|
|
- setState(() {
|
|
|
|
- categoriaSeleccionada = categoria;
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- style: ElevatedButton.styleFrom(
|
|
|
|
- primary: isSelected ? AppTheme.tertiary : Colors.grey,
|
|
|
|
- foregroundColor:
|
|
|
|
- isSelected ? AppTheme.quaternary : AppTheme.secondary,
|
|
|
|
- onPrimary: AppTheme.secondary,
|
|
|
|
|
|
+ child: Scrollbar(
|
|
|
|
+ thumbVisibility: true,
|
|
|
|
+ trackVisibility: true,
|
|
|
|
+ interactive: true,
|
|
|
|
+ controller: _categoryScrollController,
|
|
|
|
+ child: ListView.builder(
|
|
|
|
+ controller: _categoryScrollController,
|
|
|
|
+ scrollDirection: Axis.horizontal,
|
|
|
|
+ itemCount: categoriasFiltradas.length,
|
|
|
|
+ itemBuilder: (context, index) {
|
|
|
|
+ final categoria = categoriasFiltradas[index];
|
|
|
|
+ bool isSelected = categoriaSeleccionada?.id == categoria.id;
|
|
|
|
+ return Padding(
|
|
|
|
+ padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
|
|
|
+ child: ElevatedButton(
|
|
|
|
+ onPressed: () {
|
|
|
|
+ cargarProductosPorCategoria(categoria.id);
|
|
|
|
+ setState(() {
|
|
|
|
+ categoriaSeleccionada = categoria;
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ style: ElevatedButton.styleFrom(
|
|
|
|
+ primary: isSelected ? AppTheme.tertiary : Colors.grey,
|
|
|
|
+ foregroundColor:
|
|
|
|
+ isSelected ? AppTheme.quaternary : AppTheme.secondary,
|
|
|
|
+ onPrimary: AppTheme.secondary,
|
|
|
|
+ ),
|
|
|
|
+ child: Text(categoria.nombre!),
|
|
),
|
|
),
|
|
- child: Text(categoria.nombre!),
|
|
|
|
- ),
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
),
|
|
),
|
|
);
|
|
);
|
|
}
|
|
}
|
|
@@ -1129,9 +1131,23 @@ class _PedidoFormState extends State<PedidoForm> {
|
|
decoration: InputDecoration(
|
|
decoration: InputDecoration(
|
|
hintText: 'Buscar producto...',
|
|
hintText: 'Buscar producto...',
|
|
prefixIcon: const Icon(Icons.search),
|
|
prefixIcon: const Icon(Icons.search),
|
|
|
|
+ suffixIcon: IconButton(
|
|
|
|
+ icon: Icon(Icons.clear),
|
|
|
|
+ onPressed: () {
|
|
|
|
+ _searchController.clear();
|
|
|
|
+ _onSearchChanged('');
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
border: OutlineInputBorder(
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
borderRadius: BorderRadius.circular(12.0),
|
|
),
|
|
),
|
|
|
|
+ enabledBorder: OutlineInputBorder(
|
|
|
|
+ borderRadius: BorderRadius.circular(12.0),
|
|
|
|
+ borderSide: BorderSide(width: 1.5)),
|
|
|
|
+ focusedBorder: OutlineInputBorder(
|
|
|
|
+ borderSide: BorderSide(color: Colors.black),
|
|
|
|
+ borderRadius: BorderRadius.circular(12.0),
|
|
|
|
+ ),
|
|
),
|
|
),
|
|
onChanged: _onSearchChanged,
|
|
onChanged: _onSearchChanged,
|
|
),
|
|
),
|