|
@@ -1,703 +0,0 @@
|
|
|
-import 'package:flutter/foundation.dart';
|
|
|
-import 'package:flutter/material.dart';
|
|
|
-import 'package:yoshi_papas_app/widgets/widgets.dart';
|
|
|
-import '../../themes/themes.dart';
|
|
|
-
|
|
|
-class PedidoForm extends StatefulWidget {
|
|
|
- @override
|
|
|
- _PedidoFormState createState() => _PedidoFormState();
|
|
|
-}
|
|
|
-
|
|
|
-enum CustomizationStep { Base, Salsa, Aderezo, Toppings }
|
|
|
-
|
|
|
-class _PedidoFormState extends State<PedidoForm> {
|
|
|
- Map<String, bool> baseOptions = {};
|
|
|
- Map<String, bool> sauceOptions = {};
|
|
|
- Map<String, bool> dressingOptions = {};
|
|
|
- Map<String, bool> toppingOptions = {};
|
|
|
- bool isCustomizingProduct = false;
|
|
|
- Map<String, dynamic>? currentProductForCustomization;
|
|
|
- String? selectedBase;
|
|
|
- List<String> selectedSauce = [];
|
|
|
- List<String> selectedDressing = [];
|
|
|
- List<String> selectedToppings = [];
|
|
|
- List<Map<String, dynamic>> productsInCart = [];
|
|
|
- String currentCategory = 'Hamburguesa de pollo';
|
|
|
-
|
|
|
- Map<String, List<Map<String, dynamic>>> categoryProducts = {
|
|
|
- 'Hamburguesa de pollo': [
|
|
|
- {
|
|
|
- 'name': 'Rebanada de queso',
|
|
|
- 'price': 25,
|
|
|
- 'category': 'Hamburguesa de pollo'
|
|
|
- },
|
|
|
- {
|
|
|
- 'name': 'Porción de queso',
|
|
|
- 'price': 15,
|
|
|
- 'category': 'Hamburguesa de pollo'
|
|
|
- },
|
|
|
- {
|
|
|
- 'name': 'Hamburguesa de pollo',
|
|
|
- 'price': 110,
|
|
|
- 'category': 'Hamburguesa de pollo'
|
|
|
- },
|
|
|
- ],
|
|
|
- 'Postres': [
|
|
|
- {'name': 'Muffin', 'price': 35, 'category': 'Postres'},
|
|
|
- {'name': 'Rebanada de Pay de Nuez', 'price': 65, 'category': 'Postres'},
|
|
|
- ],
|
|
|
- 'Cono de papas': [
|
|
|
- {
|
|
|
- 'name': 'Cono de papas grande',
|
|
|
- 'price': 120,
|
|
|
- 'category': 'Cono de papas'
|
|
|
- },
|
|
|
- {
|
|
|
- 'name': 'Cono de papas mediano',
|
|
|
- 'price': 85,
|
|
|
- 'category': 'Cono de papas'
|
|
|
- },
|
|
|
- ],
|
|
|
- };
|
|
|
- List<Map<String, dynamic>> products = [];
|
|
|
-
|
|
|
- CustomizationStep _currentStep = CustomizationStep.Base;
|
|
|
- late Map<CustomizationStep, Widget> _stepWidgets;
|
|
|
-
|
|
|
- @override
|
|
|
- void initState() {
|
|
|
- super.initState();
|
|
|
- // Inicializa con la categoría actual
|
|
|
- products = categoryProducts[currentCategory]!;
|
|
|
- initializeCheckboxStates();
|
|
|
- _stepWidgets = {
|
|
|
- CustomizationStep.Base: _buildBaseOptions(),
|
|
|
- CustomizationStep.Salsa: _buildSauceOptions(),
|
|
|
- CustomizationStep.Aderezo: _buildDressingOptions(),
|
|
|
- CustomizationStep.Toppings: _buildToppingsOptions(),
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- void customizeProduct(Map<String, dynamic> product) {
|
|
|
- if (product['category'] == 'Cono de papas') {
|
|
|
- setState(() {
|
|
|
- isCustomizingProduct = true;
|
|
|
- currentProductForCustomization = product;
|
|
|
- });
|
|
|
- } else {
|
|
|
- addToCart(product);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void initializeCheckboxStates() {
|
|
|
- // Inicializa los mapas de opciones con valores false
|
|
|
- for (var base in [
|
|
|
- 'Papa Gajo',
|
|
|
- 'Papa Regilla',
|
|
|
- 'Papa Curly',
|
|
|
- 'Papa Smile',
|
|
|
- 'Papa Francesa'
|
|
|
- ]) {
|
|
|
- baseOptions[base] = false;
|
|
|
- }
|
|
|
- for (var sauce in [
|
|
|
- 'BBQ',
|
|
|
- 'HOTBBQ',
|
|
|
- 'BUFFALO',
|
|
|
- 'TERIYAKI',
|
|
|
- 'PARMESAN GARLIC',
|
|
|
- 'MANGO HABANERO'
|
|
|
- ]) {
|
|
|
- sauceOptions[sauce] = false;
|
|
|
- }
|
|
|
- for (var dressing in ['QUESO AMARILLO', 'RANCH', 'CHIPOTLE', 'KETCHUP']) {
|
|
|
- dressingOptions[dressing] = false;
|
|
|
- }
|
|
|
- for (var topping in [
|
|
|
- 'JALAPEÑO',
|
|
|
- 'QUESO BLANCO',
|
|
|
- 'TAKIS',
|
|
|
- 'RUFFLES',
|
|
|
- 'QUESO PARMESANO',
|
|
|
- 'ELOTE'
|
|
|
- ]) {
|
|
|
- toppingOptions[topping] = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void addToCart(Map<String, dynamic> product) {
|
|
|
- // Si es un "Cono de papas" y estamos personalizando
|
|
|
- if (product['category'] == 'Cono de papas' && isCustomizingProduct) {
|
|
|
- final Map<String, dynamic> customizedProduct = {
|
|
|
- ...product,
|
|
|
- 'customizations': {
|
|
|
- 'base': selectedBase,
|
|
|
- 'sauce': selectedSauce,
|
|
|
- 'dressing': selectedDressing,
|
|
|
- 'toppings': selectedToppings,
|
|
|
- },
|
|
|
- 'quantity':
|
|
|
- 1, // Asegúrate de que cada producto personalizado tenga una cantidad inicial de 1
|
|
|
- };
|
|
|
-
|
|
|
- setState(() {
|
|
|
- productsInCart
|
|
|
- .add(customizedProduct); // Añade el producto personalizado
|
|
|
- isCustomizingProduct = false; // Termina la personalización
|
|
|
- resetCustomizations(); // Llama a un método que restablecerá las personalizaciones
|
|
|
- });
|
|
|
- } else {
|
|
|
- // Si no es un "Cono de papas" o no estamos personalizando, añade directamente al carrito
|
|
|
- setState(() {
|
|
|
- int index = productsInCart.indexWhere((p) =>
|
|
|
- p['name'] == product['name'] &&
|
|
|
- p['customizations'] ==
|
|
|
- product[
|
|
|
- 'customizations']); // Comparar también las personalizaciones
|
|
|
- if (index != -1) {
|
|
|
- productsInCart[index]['quantity'] += 1;
|
|
|
- } else {
|
|
|
- productsInCart.add(
|
|
|
- {...product, 'quantity': 1}); // Añade con cantidad inicial de 1
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void resetCustomizations() {
|
|
|
- // Restablece las variables de estado de las personalizaciones
|
|
|
- selectedBase = null;
|
|
|
- selectedSauce = [];
|
|
|
- selectedDressing = [];
|
|
|
- selectedToppings = [];
|
|
|
- // Restablecer cualquier otro estado de personalización aquí
|
|
|
- }
|
|
|
-
|
|
|
- void finalizeCustomization() {
|
|
|
- // Aquí debes construir el producto basado en las selecciones de personalización
|
|
|
-
|
|
|
- selectedBase = baseOptions.entries
|
|
|
- .firstWhere((entry) => entry.value, orElse: () => MapEntry('', false))
|
|
|
- .key;
|
|
|
- selectedSauce = sauceOptions.entries
|
|
|
- .where((entry) => entry.value)
|
|
|
- .map((e) => e.key)
|
|
|
- .toList();
|
|
|
- selectedDressing = dressingOptions.entries
|
|
|
- .where((entry) => entry.value)
|
|
|
- .map((e) => e.key)
|
|
|
- .toList();
|
|
|
- selectedToppings = toppingOptions.entries
|
|
|
- .where((entry) => entry.value)
|
|
|
- .map((e) => e.key)
|
|
|
- .toList();
|
|
|
-
|
|
|
- Map<String, dynamic> customizedProduct = {
|
|
|
- ...currentProductForCustomization!,
|
|
|
- 'customizations': {
|
|
|
- 'base': selectedBase,
|
|
|
- 'sauce': selectedSauce,
|
|
|
- 'dressing': selectedDressing,
|
|
|
- 'toppings': selectedToppings,
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- addToCart(customizedProduct);
|
|
|
- setState(() {
|
|
|
- isCustomizingProduct = false;
|
|
|
- currentProductForCustomization = null;
|
|
|
- initializeCheckboxStates(); // Reinicia los estados de los checkbox
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- Widget buildCategoryButtons() {
|
|
|
- return Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- children: categoryProducts.keys.map((String key) {
|
|
|
- return Padding(
|
|
|
- padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
|
|
- child: OutlinedButton(
|
|
|
- onPressed: () {
|
|
|
- setState(() {
|
|
|
- currentCategory = key;
|
|
|
- products = categoryProducts[key]!;
|
|
|
- });
|
|
|
- },
|
|
|
- style: OutlinedButton.styleFrom(
|
|
|
- backgroundColor: Colors.white,
|
|
|
- foregroundColor: Colors.black,
|
|
|
- side: BorderSide(
|
|
|
- width: 2.0,
|
|
|
- color: currentCategory == key ? AppTheme.primary : Colors.grey,
|
|
|
- ),
|
|
|
- ),
|
|
|
- child: Text(key),
|
|
|
- ),
|
|
|
- );
|
|
|
- }).toList(),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- @override
|
|
|
- Widget build(BuildContext context) {
|
|
|
- return Scaffold(
|
|
|
- appBar: encabezado(
|
|
|
- titulo: "CREAR PEDIDO",
|
|
|
- ),
|
|
|
- body: Row(
|
|
|
- children: [
|
|
|
- // Sección izquierda con la lista del carrito - 30%
|
|
|
- Flexible(
|
|
|
- flex: 3,
|
|
|
- child: tarjeta(
|
|
|
- Column(
|
|
|
- children: [
|
|
|
- // Encabezados de la lista
|
|
|
- const Padding(
|
|
|
- padding:
|
|
|
- EdgeInsets.symmetric(horizontal: 8.0, vertical: 16.0),
|
|
|
- child: Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
- children: [
|
|
|
- Text('Producto',
|
|
|
- style: TextStyle(
|
|
|
- fontWeight: FontWeight.bold, fontSize: 18)),
|
|
|
- Text('Cantidad',
|
|
|
- style: TextStyle(
|
|
|
- fontWeight: FontWeight.bold, fontSize: 18)),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- // Lista de productos
|
|
|
- Expanded(
|
|
|
- child: ListView.builder(
|
|
|
- itemCount: productsInCart.length,
|
|
|
- itemBuilder: (context, index) {
|
|
|
- var product = productsInCart[index];
|
|
|
- return ListTile(
|
|
|
- title: _buildProductItem(product),
|
|
|
- trailing: Row(
|
|
|
- mainAxisSize: MainAxisSize.min,
|
|
|
- children: [
|
|
|
- IconButton(
|
|
|
- icon: const Icon(Icons.remove),
|
|
|
- onPressed: () {
|
|
|
- // Lógica para disminuir la cantidad
|
|
|
- setState(() {
|
|
|
- if (product['quantity'] > 1) {
|
|
|
- productsInCart[index]['quantity'] -= 1;
|
|
|
- } else {
|
|
|
- productsInCart.removeAt(index);
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- ),
|
|
|
- Text('${product['quantity'] ?? 1}'),
|
|
|
- IconButton(
|
|
|
- icon: const Icon(Icons.add),
|
|
|
- onPressed: () {
|
|
|
- // Lógica para aumentar la cantidad
|
|
|
- setState(() {
|
|
|
- productsInCart[index]['quantity'] += 1;
|
|
|
- });
|
|
|
- },
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- );
|
|
|
- },
|
|
|
- ),
|
|
|
- ),
|
|
|
- ElevatedButton(
|
|
|
- style: ButtonStyle(
|
|
|
- backgroundColor:
|
|
|
- MaterialStatePropertyAll(AppTheme.primary),
|
|
|
- textStyle: const MaterialStatePropertyAll(
|
|
|
- TextStyle(fontSize: 22)),
|
|
|
- foregroundColor:
|
|
|
- const MaterialStatePropertyAll(Colors.black),
|
|
|
- padding: const MaterialStatePropertyAll(
|
|
|
- EdgeInsets.fromLTRB(80, 20, 80, 20))),
|
|
|
- onPressed: () {
|
|
|
- // Aquí agregarías la lógica para guardar el pedido
|
|
|
- },
|
|
|
- child: const Text('Guardar'),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- color: Colors.white,
|
|
|
- padding: 8.0,
|
|
|
- ),
|
|
|
- ),
|
|
|
-
|
|
|
- const SizedBox(
|
|
|
- width: 35,
|
|
|
- ),
|
|
|
-
|
|
|
- // Sección derecha con los productos disponibles - 70%
|
|
|
- Flexible(
|
|
|
- flex: 7,
|
|
|
- child: Column(
|
|
|
- children: [
|
|
|
- // Botones de categorías de productos
|
|
|
- buildCategoryButtons(),
|
|
|
-
|
|
|
- // GridView de productos
|
|
|
- Expanded(
|
|
|
- child: isCustomizingProduct
|
|
|
- ? buildCustomizationOptions()
|
|
|
- : buildProductGrid(),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildProductItem(Map<String, dynamic> product) {
|
|
|
- List<Widget> customizationWidgets = [];
|
|
|
- if (product.containsKey('customizations')) {
|
|
|
- Map customizations = product['customizations'];
|
|
|
- customizationWidgets.addAll([
|
|
|
- Text(' - Base: ${customizations['base']}'),
|
|
|
- ...customizations['sauce']
|
|
|
- .map<Widget>((sauce) => Text(' - Salsa: $sauce'))
|
|
|
- .toList(),
|
|
|
- ...customizations['dressing']
|
|
|
- .map<Widget>((dressing) => Text(' - Aderezo: $dressing'))
|
|
|
- .toList(),
|
|
|
- ...customizations['toppings']
|
|
|
- .map<Widget>((topping) => Text(' - Topping: $topping'))
|
|
|
- .toList(),
|
|
|
- ]);
|
|
|
- }
|
|
|
-
|
|
|
- return Column(
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
- children: [
|
|
|
- Text(product['name']),
|
|
|
- ...customizationWidgets,
|
|
|
- ],
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget buildProductGrid() {
|
|
|
- return tarjeta(
|
|
|
- GridView.builder(
|
|
|
- itemCount: products.length,
|
|
|
- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
- crossAxisCount: 2, // Número de columnas
|
|
|
- childAspectRatio: 3 / 2, // Proporción de cada tarjeta
|
|
|
- crossAxisSpacing: 10, // Espaciado horizontal
|
|
|
- mainAxisSpacing: 10, // Espaciado vertical
|
|
|
- ),
|
|
|
- itemBuilder: (context, index) {
|
|
|
- final product = products[index];
|
|
|
- return tarjeta(
|
|
|
- InkWell(
|
|
|
- onTap: () => customizeProduct(product),
|
|
|
- child: Column(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- children: [
|
|
|
- // Añade el ícono aquí
|
|
|
- const Icon(Icons.fastfood,
|
|
|
- size: 80), // Tamaño del ícono ajustable
|
|
|
- const SizedBox(height: 8), // Espacio entre ícono y texto
|
|
|
- Text(
|
|
|
- product['name'],
|
|
|
- style: const TextStyle(fontSize: 16),
|
|
|
- textAlign: TextAlign.center,
|
|
|
- ),
|
|
|
- const SizedBox(height: 8), // Espacio entre texto y precio
|
|
|
- Text(
|
|
|
- '\$${product['price']}',
|
|
|
- style:
|
|
|
- const TextStyle(fontSize: 24, color: Color(0xFF008000)),
|
|
|
- textAlign: TextAlign.center,
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- color: const Color(0xFFF4F4F4),
|
|
|
- padding: 8.0,
|
|
|
- );
|
|
|
- },
|
|
|
- ),
|
|
|
- color: Colors.white,
|
|
|
- padding: 8.0,
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget buildCustomizationOptions() {
|
|
|
- Widget currentStepWidget;
|
|
|
- switch (_currentStep) {
|
|
|
- case CustomizationStep.Base:
|
|
|
- currentStepWidget = _buildBaseOptions();
|
|
|
- break;
|
|
|
- case CustomizationStep.Salsa:
|
|
|
- currentStepWidget = _buildSauceOptions();
|
|
|
- break;
|
|
|
- case CustomizationStep.Aderezo:
|
|
|
- currentStepWidget = _buildDressingOptions();
|
|
|
- break;
|
|
|
- case CustomizationStep.Toppings:
|
|
|
- currentStepWidget = _buildToppingsOptions();
|
|
|
- break;
|
|
|
- default:
|
|
|
- currentStepWidget = SizedBox.shrink();
|
|
|
- }
|
|
|
-
|
|
|
- // Solo muestra el botón de confirmación si isCustomizingProduct es true.
|
|
|
- Widget confirmButton = isCustomizingProduct
|
|
|
- ? Padding(
|
|
|
- padding: const EdgeInsets.symmetric(vertical: 16.0),
|
|
|
- child: _buildConfirmButton(),
|
|
|
- )
|
|
|
- : SizedBox.shrink();
|
|
|
-
|
|
|
- return tarjeta(
|
|
|
- Column(
|
|
|
- children: [
|
|
|
- Expanded(
|
|
|
- child: Row(
|
|
|
- children: [
|
|
|
- Flexible(
|
|
|
- flex: 3,
|
|
|
- child: ListView(
|
|
|
- children: CustomizationStep.values.map((step) {
|
|
|
- // Verifica si el paso es Salsa, Aderezo o Toppings para añadir el texto " (Max 2)"
|
|
|
- String stepName = describeEnum(step);
|
|
|
- if (step == CustomizationStep.Salsa ||
|
|
|
- step == CustomizationStep.Aderezo ||
|
|
|
- step == CustomizationStep.Toppings) {
|
|
|
- stepName +=
|
|
|
- " (Max 2)"; // Agrega " (Max 2)" al nombre del paso+
|
|
|
- }
|
|
|
-
|
|
|
- return ListTile(
|
|
|
- title: Text(stepName),
|
|
|
- selected: _currentStep == step,
|
|
|
- onTap: () => setState(() => _currentStep = step),
|
|
|
- );
|
|
|
- }).toList(),
|
|
|
- ),
|
|
|
- ),
|
|
|
- Flexible(
|
|
|
- flex: 7,
|
|
|
- child: currentStepWidget,
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ),
|
|
|
- Padding(
|
|
|
- padding: const EdgeInsets.symmetric(vertical: 16.0),
|
|
|
- child: _buildConfirmButton(),
|
|
|
- ), // Incluir el botón de confirmación aquí
|
|
|
- ],
|
|
|
- ),
|
|
|
- color: Colors.white,
|
|
|
- padding: 8.0,
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget buildCheckboxListTile({
|
|
|
- required String title,
|
|
|
- required Map<String, bool> optionsMap,
|
|
|
- required Function(String, bool?) onChanged,
|
|
|
- }) {
|
|
|
- return CheckboxListTile(
|
|
|
- title: Text(title),
|
|
|
- value: optionsMap[title] ?? false,
|
|
|
- onChanged: (bool? value) {
|
|
|
- setState(() {
|
|
|
- onChanged(title, value);
|
|
|
- });
|
|
|
- },
|
|
|
- secondary: Image.asset('assets/JoshiLogo.png', width: 30),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildBaseOptions() {
|
|
|
- return GridView.count(
|
|
|
- crossAxisCount: 3,
|
|
|
- children: baseOptions.keys.map((String key) {
|
|
|
- bool isSelected =
|
|
|
- baseOptions[key] ?? false; // Determina si está seleccionado
|
|
|
- return GestureDetector(
|
|
|
- onTap: () {
|
|
|
- setState(() {
|
|
|
- baseOptions.keys.forEach(
|
|
|
- (k) => baseOptions[k] = false); // Desmarca todos primero
|
|
|
- baseOptions[key] = true; // Marca el seleccionado
|
|
|
- });
|
|
|
- },
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: isSelected ? AppTheme.primary : const Color(0xFFF4F4F4),
|
|
|
- border: Border.all(color: isSelected ? Colors.red : Colors.grey),
|
|
|
- ),
|
|
|
- child: Center(
|
|
|
- child: Text(key,
|
|
|
- style: TextStyle(
|
|
|
- color: isSelected ? Colors.white : Colors.black)),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }).toList(),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildSauceOptions() {
|
|
|
- return GridView.count(
|
|
|
- crossAxisCount: 3,
|
|
|
- children: sauceOptions.keys.map((String key) {
|
|
|
- bool isSelected = sauceOptions[key] ?? false;
|
|
|
- return GestureDetector(
|
|
|
- onTap: () {
|
|
|
- int selectedCount = sauceOptions.values.where((b) => b).length;
|
|
|
- setState(() {
|
|
|
- // Si la salsa ya está seleccionada, la deselecciona.
|
|
|
- if (isSelected) {
|
|
|
- sauceOptions[key] = false;
|
|
|
- } else {
|
|
|
- // Si se están seleccionando menos de 2 salsas, permite esta selección.
|
|
|
- if (selectedCount < 2) {
|
|
|
- sauceOptions[key] = true;
|
|
|
- } else {
|
|
|
- // Si ya hay 2 salsas seleccionadas, primero deselecciona la primera seleccionada.
|
|
|
- final firstSelected = sauceOptions.keys.firstWhere(
|
|
|
- (k) => sauceOptions[k]!,
|
|
|
- orElse: () => '',
|
|
|
- );
|
|
|
- if (firstSelected.isNotEmpty) {
|
|
|
- sauceOptions[firstSelected] = false;
|
|
|
- sauceOptions[key] = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: isSelected ? AppTheme.primary : const Color(0xFFF4F4F4),
|
|
|
- border: Border.all(color: Colors.grey),
|
|
|
- ),
|
|
|
- child: Center(
|
|
|
- child: Text(key,
|
|
|
- style: TextStyle(
|
|
|
- color: isSelected ? Colors.white : Colors.black)),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }).toList(),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildDressingOptions() {
|
|
|
- return GridView.count(
|
|
|
- crossAxisCount: 3,
|
|
|
- children: dressingOptions.keys.map((String key) {
|
|
|
- bool isSelected = dressingOptions[key] ?? false;
|
|
|
- return GestureDetector(
|
|
|
- onTap: () {
|
|
|
- int selectedCount = dressingOptions.values.where((b) => b).length;
|
|
|
- setState(() {
|
|
|
- // Si la salsa ya está seleccionada, la deselecciona.
|
|
|
- if (isSelected) {
|
|
|
- dressingOptions[key] = false;
|
|
|
- } else {
|
|
|
- // Si se están seleccionando menos de 2 salsas, permite esta selección.
|
|
|
- if (selectedCount < 2) {
|
|
|
- dressingOptions[key] = true;
|
|
|
- } else {
|
|
|
- // Si ya hay 2 salsas seleccionadas, primero deselecciona la primera seleccionada.
|
|
|
- final firstSelected = dressingOptions.keys.firstWhere(
|
|
|
- (k) => dressingOptions[k]!,
|
|
|
- orElse: () => '',
|
|
|
- );
|
|
|
- if (firstSelected.isNotEmpty) {
|
|
|
- dressingOptions[firstSelected] = false;
|
|
|
- dressingOptions[key] = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: isSelected ? AppTheme.primary : const Color(0xFFF4F4F4),
|
|
|
- border: Border.all(color: Colors.grey),
|
|
|
- ),
|
|
|
- child: Center(
|
|
|
- child: Text(key,
|
|
|
- style: TextStyle(
|
|
|
- color: isSelected ? Colors.white : Colors.black)),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }).toList(),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildToppingsOptions() {
|
|
|
- return GridView.count(
|
|
|
- crossAxisCount: 3,
|
|
|
- children: toppingOptions.keys.map((String key) {
|
|
|
- bool isSelected = toppingOptions[key] ?? false;
|
|
|
- return GestureDetector(
|
|
|
- onTap: () {
|
|
|
- int selectedCount = toppingOptions.values.where((b) => b).length;
|
|
|
- setState(() {
|
|
|
- // Si la salsa ya está seleccionada, la deselecciona.
|
|
|
- if (isSelected) {
|
|
|
- toppingOptions[key] = false;
|
|
|
- } else {
|
|
|
- // Si se están seleccionando menos de 2 salsas, permite esta selección.
|
|
|
- if (selectedCount < 2) {
|
|
|
- toppingOptions[key] = true;
|
|
|
- } else {
|
|
|
- // Si ya hay 2 salsas seleccionadas, primero deselecciona la primera seleccionada.
|
|
|
- final firstSelected = toppingOptions.keys.firstWhere(
|
|
|
- (k) => toppingOptions[k]!,
|
|
|
- orElse: () => '',
|
|
|
- );
|
|
|
- if (firstSelected.isNotEmpty) {
|
|
|
- toppingOptions[firstSelected] = false;
|
|
|
- toppingOptions[key] = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- child: Container(
|
|
|
- decoration: BoxDecoration(
|
|
|
- color: isSelected ? AppTheme.primary : const Color(0xFFF4F4F4),
|
|
|
- border: Border.all(color: Colors.grey),
|
|
|
- ),
|
|
|
- child: Center(
|
|
|
- child: Text(key,
|
|
|
- style: TextStyle(
|
|
|
- color: isSelected ? Colors.white : Colors.black)),
|
|
|
- ),
|
|
|
- ),
|
|
|
- );
|
|
|
- }).toList(),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- Widget _buildConfirmButton() {
|
|
|
- return ElevatedButton(
|
|
|
- style: ElevatedButton.styleFrom(
|
|
|
- primary: AppTheme.primary, // Color del botón
|
|
|
- onPrimary: Colors.black,
|
|
|
- textStyle: const TextStyle(fontSize: 22),
|
|
|
- padding: const EdgeInsets.fromLTRB(80, 20, 80, 20)),
|
|
|
- onPressed: () {
|
|
|
- finalizeCustomization(); // Este método creará el pedido personalizado
|
|
|
- },
|
|
|
- child: Text('Confirmar Pedido'),
|
|
|
- );
|
|
|
- }
|
|
|
-}
|