|
@@ -1,13 +1,95 @@
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
+class Product {
|
|
|
|
+ final String id;
|
|
|
|
+ final String nombre;
|
|
|
|
+ final String descripcion;
|
|
|
|
+ final double precio;
|
|
|
|
+ final String imageUrl;
|
|
|
|
+ final List<String> availableToppings;
|
|
|
|
+ final List<String> availableDrinks;
|
|
|
|
+ final List<String> availableCookingTerms;
|
|
|
|
+ final bool hasCheeseOption;
|
|
|
|
+ final double cheeseprecio;
|
|
|
|
+
|
|
|
|
+ Product({
|
|
|
|
+ required this.id,
|
|
|
|
+ required this.nombre,
|
|
|
|
+ required this.descripcion,
|
|
|
|
+ required this.precio,
|
|
|
|
+ required this.imageUrl,
|
|
|
|
+ required this.availableToppings,
|
|
|
|
+ required this.availableDrinks,
|
|
|
|
+ required this.availableCookingTerms,
|
|
|
|
+ required this.hasCheeseOption,
|
|
|
|
+ required this.cheeseprecio,
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ factory Product.staticSandwich() {
|
|
|
|
+ return Product(
|
|
|
|
+ id: 'p1',
|
|
|
|
+ nombre: 'Sandwich de pollo',
|
|
|
|
+ descripcion:
|
|
|
|
+ 'Queso, Lechuga, tomate, cebolla, pepinillo, mayonesa, ketchup y moztaza. Acompañado de Papas y Soda',
|
|
|
|
+ precio: 115.00,
|
|
|
|
+ imageUrl:
|
|
|
|
+ 'https://cdn.pixabay.com/photo/2023/04/02/21/38/sandwich-7895477_1280.jpg',
|
|
|
|
+ availableToppings: [
|
|
|
|
+ 'Cebolla',
|
|
|
|
+ 'Pepperoni',
|
|
|
|
+ 'Champiñones',
|
|
|
|
+ 'Tocino',
|
|
|
|
+ 'Pimiento',
|
|
|
|
+ 'Jalapeño'
|
|
|
|
+ ],
|
|
|
|
+ availableDrinks: ['Coca-Cola', 'Sprite', 'Fanta', 'Agua mineral'],
|
|
|
|
+ availableCookingTerms: ['Término medio', 'Tres cuartos', 'Bien cocido'],
|
|
|
|
+ hasCheeseOption: true,
|
|
|
|
+ cheeseprecio: 5.00,
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
class ProductScreen extends StatefulWidget {
|
|
class ProductScreen extends StatefulWidget {
|
|
- const ProductScreen({super.key});
|
|
|
|
|
|
+ final Product product;
|
|
|
|
+
|
|
|
|
+ const ProductScreen({super.key, required this.product});
|
|
|
|
|
|
@override
|
|
@override
|
|
State<ProductScreen> createState() => _ProductScreenState();
|
|
State<ProductScreen> createState() => _ProductScreenState();
|
|
}
|
|
}
|
|
|
|
|
|
class _ProductScreenState extends State<ProductScreen> {
|
|
class _ProductScreenState extends State<ProductScreen> {
|
|
|
|
+ int quantity = 1;
|
|
|
|
+ double totalprecio = 0;
|
|
|
|
+
|
|
|
|
+ @override
|
|
|
|
+ void initState() {
|
|
|
|
+ super.initState();
|
|
|
|
+ totalprecio = widget.product.precio;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void _updateQuantity(int newQuantity) {
|
|
|
|
+ if (newQuantity >= 1) {
|
|
|
|
+ setState(() {
|
|
|
|
+ quantity = newQuantity;
|
|
|
|
+ _calculateTotalprecio();
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void _calculateTotalprecio() {
|
|
|
|
+ double baseprecio = widget.product.precio;
|
|
|
|
+ // Añadir precio del queso si está seleccionado
|
|
|
|
+ if (_toppingsViewKey.currentState?.isQuesoSelected == true) {
|
|
|
|
+ baseprecio += widget.product.cheeseprecio;
|
|
|
|
+ }
|
|
|
|
+ totalprecio = baseprecio * quantity;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ final GlobalKey<_ToppingsViewState> _toppingsViewKey =
|
|
|
|
+ GlobalKey<_ToppingsViewState>();
|
|
|
|
+
|
|
@override
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
return Scaffold(
|
|
@@ -17,12 +99,84 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
actions: [
|
|
actions: [
|
|
IconButton(
|
|
IconButton(
|
|
icon: const Icon(Icons.info),
|
|
icon: const Icon(Icons.info),
|
|
- onPressed: () => (context) {
|
|
|
|
|
|
+ onPressed: () {
|
|
Navigator.of(context).pop();
|
|
Navigator.of(context).pop();
|
|
},
|
|
},
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
|
|
+ bottomNavigationBar: SizedBox(
|
|
|
|
+ height: 110,
|
|
|
|
+ child: Container(
|
|
|
|
+ padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
+ color: Color.fromARGB(255, 47, 208, 229),
|
|
|
|
+ borderRadius: const BorderRadius.only(
|
|
|
|
+ topLeft: Radius.circular(25),
|
|
|
|
+ topRight: Radius.circular(25),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ child: Row(
|
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
+ children: [
|
|
|
|
+ ClipRRect(
|
|
|
|
+ borderRadius: BorderRadius.circular(5),
|
|
|
|
+ child: Row(
|
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
|
+ children: [
|
|
|
|
+ Container(
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
+ color: Color.fromARGB(255, 200, 214, 232),
|
|
|
|
+ borderRadius: BorderRadius.circular(2),
|
|
|
|
+ ),
|
|
|
|
+ child: IconButton(
|
|
|
|
+ icon: const Icon(Icons.remove),
|
|
|
|
+ onPressed: () => _updateQuantity(quantity - 1),
|
|
|
|
+ color: Colors.black,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ Container(
|
|
|
|
+ width: 48,
|
|
|
|
+ height: 48,
|
|
|
|
+ alignment: Alignment.center,
|
|
|
|
+ color: Colors.white,
|
|
|
|
+ child: Text(
|
|
|
|
+ quantity.toString(),
|
|
|
|
+ style: TextStyle(
|
|
|
|
+ color: Colors.black,
|
|
|
|
+ fontSize: 20,
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ Container(
|
|
|
|
+ color: Color.fromARGB(255, 200, 214, 232),
|
|
|
|
+ child: IconButton(
|
|
|
|
+ icon: const Icon(Icons.add),
|
|
|
|
+ onPressed: () => _updateQuantity(quantity + 1),
|
|
|
|
+ color: Colors.black,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ Container(
|
|
|
|
+ padding:
|
|
|
|
+ const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
|
|
|
+ color: Colors.black,
|
|
|
|
+ child: Text(
|
|
|
|
+ "MXN ${totalprecio.toStringAsFixed(2)}",
|
|
|
|
+ style: TextStyle(
|
|
|
|
+ color: Colors.white,
|
|
|
|
+ fontSize: 20,
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
backgroundColor: Colors.white,
|
|
backgroundColor: Colors.white,
|
|
body: SingleChildScrollView(
|
|
body: SingleChildScrollView(
|
|
child: Column(
|
|
child: Column(
|
|
@@ -50,8 +204,7 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
topRight: Radius.circular(25),
|
|
topRight: Radius.circular(25),
|
|
),
|
|
),
|
|
image: DecorationImage(
|
|
image: DecorationImage(
|
|
- image: NetworkImage(
|
|
|
|
- 'https://cdn.pixabay.com/photo/2023/04/02/21/38/sandwich-7895477_1280.jpg'),
|
|
|
|
|
|
+ image: NetworkImage(widget.product.imageUrl),
|
|
fit: BoxFit.cover,
|
|
fit: BoxFit.cover,
|
|
colorFilter: ColorFilter.mode(
|
|
colorFilter: ColorFilter.mode(
|
|
Colors.black.withOpacity(0.3),
|
|
Colors.black.withOpacity(0.3),
|
|
@@ -62,13 +215,13 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
)
|
|
)
|
|
]),
|
|
]),
|
|
const SizedBox(height: 20),
|
|
const SizedBox(height: 20),
|
|
- const Padding(
|
|
|
|
|
|
+ Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
|
padding: EdgeInsets.symmetric(horizontal: 20),
|
|
child: Column(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
children: [
|
|
Text(
|
|
Text(
|
|
- 'Sandwich de pollo',
|
|
|
|
|
|
+ widget.product.nombre,
|
|
style: TextStyle(
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
color: Colors.black,
|
|
fontSize: 44,
|
|
fontSize: 44,
|
|
@@ -77,7 +230,7 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
SizedBox(height: 10),
|
|
Text(
|
|
Text(
|
|
- 'Queso, Lechuga, tomate, cebolla, pepinillo, mayonesa, ketchup y moztaza. Acompañado de Papas y Soda',
|
|
|
|
|
|
+ widget.product.descripcion,
|
|
style: TextStyle(
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
color: Colors.black,
|
|
fontSize: 26,
|
|
fontSize: 26,
|
|
@@ -85,7 +238,7 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
SizedBox(height: 10),
|
|
Text(
|
|
Text(
|
|
- 'MXN 115.00',
|
|
|
|
|
|
+ 'MXN ${widget.product.precio.toStringAsFixed(2)}',
|
|
style: TextStyle(
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
color: Colors.black,
|
|
fontSize: 36,
|
|
fontSize: 36,
|
|
@@ -96,7 +249,13 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
height: 2,
|
|
height: 2,
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
SizedBox(height: 10),
|
|
- ToppingsView(),
|
|
|
|
|
|
+ ToppingsView(
|
|
|
|
+ key: _toppingsViewKey,
|
|
|
|
+ product: widget.product,
|
|
|
|
+ onOptionChanged: () {
|
|
|
|
+ _calculateTotalprecio();
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
@@ -108,7 +267,14 @@ class _ProductScreenState extends State<ProductScreen> {
|
|
}
|
|
}
|
|
|
|
|
|
class ToppingsView extends StatefulWidget {
|
|
class ToppingsView extends StatefulWidget {
|
|
- const ToppingsView({super.key});
|
|
|
|
|
|
+ final Product product;
|
|
|
|
+ final Function() onOptionChanged;
|
|
|
|
+
|
|
|
|
+ const ToppingsView({
|
|
|
|
+ super.key,
|
|
|
|
+ required this.product,
|
|
|
|
+ required this.onOptionChanged,
|
|
|
|
+ });
|
|
|
|
|
|
@override
|
|
@override
|
|
State<ToppingsView> createState() => _ToppingsViewState();
|
|
State<ToppingsView> createState() => _ToppingsViewState();
|
|
@@ -124,31 +290,14 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
// Estado para la selección de queso
|
|
// Estado para la selección de queso
|
|
bool isQuesoSelected = false;
|
|
bool isQuesoSelected = false;
|
|
|
|
|
|
- // Opciones para los dropdowns (como ejemplo)
|
|
|
|
- final List<String> toppingsOptions = [
|
|
|
|
- 'Cebolla',
|
|
|
|
- 'Pepperoni',
|
|
|
|
- 'Champiñones',
|
|
|
|
- 'Tocino',
|
|
|
|
- 'Pimiento',
|
|
|
|
- 'Jalapeño'
|
|
|
|
- ];
|
|
|
|
- final List<String> refrescoOptions = [
|
|
|
|
- 'Coca-Cola',
|
|
|
|
- 'Sprite',
|
|
|
|
- 'Fanta',
|
|
|
|
- 'Agua mineral'
|
|
|
|
- ];
|
|
|
|
- final List<String> coccionOptions = [
|
|
|
|
- 'Término medio',
|
|
|
|
- 'Tres cuartos',
|
|
|
|
- 'Bien cocido'
|
|
|
|
- ];
|
|
|
|
-
|
|
|
|
// Selecciones actuales
|
|
// Selecciones actuales
|
|
List<String> selectedToppings = [];
|
|
List<String> selectedToppings = [];
|
|
String? selectedRefresco;
|
|
String? selectedRefresco;
|
|
String? selectedCoccion;
|
|
String? selectedCoccion;
|
|
|
|
+ String comments = '';
|
|
|
|
+
|
|
|
|
+ // Para calcular el precio total basado en selecciones
|
|
|
|
+ double additionalprecio = 0.0;
|
|
|
|
|
|
@override
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget build(BuildContext context) {
|
|
@@ -203,19 +352,21 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
),
|
|
),
|
|
const Divider(color: Colors.grey),
|
|
const Divider(color: Colors.grey),
|
|
|
|
|
|
- // 4. Dropdown de Queso amarillo
|
|
|
|
- _buildDropdownSection(
|
|
|
|
- title: "Queso amarillo para papas",
|
|
|
|
- subtitle: null, // Sin subtítulo
|
|
|
|
- isExpanded: isQuesoExpanded,
|
|
|
|
- onTap: () {
|
|
|
|
- setState(() {
|
|
|
|
- isQuesoExpanded = !isQuesoExpanded;
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- content: isQuesoExpanded ? _buildQuesoContent() : null,
|
|
|
|
- ),
|
|
|
|
- const Divider(color: Colors.grey),
|
|
|
|
|
|
+ // 4. Dropdown de Queso amarillo - Solo si el producto tiene esta opción
|
|
|
|
+ if (widget.product.hasCheeseOption) ...[
|
|
|
|
+ _buildDropdownSection(
|
|
|
|
+ title: "Queso amarillo para papas",
|
|
|
|
+ subtitle: null, // Sin subtítulo
|
|
|
|
+ isExpanded: isQuesoExpanded,
|
|
|
|
+ onTap: () {
|
|
|
|
+ setState(() {
|
|
|
|
+ isQuesoExpanded = !isQuesoExpanded;
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ content: isQuesoExpanded ? _buildQuesoContent() : null,
|
|
|
|
+ ),
|
|
|
|
+ const Divider(color: Colors.grey),
|
|
|
|
+ ],
|
|
|
|
|
|
// 5. Sección de Comentarios
|
|
// 5. Sección de Comentarios
|
|
const SizedBox(height: 20),
|
|
const SizedBox(height: 20),
|
|
@@ -234,9 +385,12 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
border: Border.all(color: Colors.grey),
|
|
border: Border.all(color: Colors.grey),
|
|
),
|
|
),
|
|
height: 80,
|
|
height: 80,
|
|
- child: const TextField(
|
|
|
|
|
|
+ child: TextField(
|
|
style: TextStyle(color: Colors.black),
|
|
style: TextStyle(color: Colors.black),
|
|
maxLines: 3,
|
|
maxLines: 3,
|
|
|
|
+ onChanged: (value) {
|
|
|
|
+ comments = value;
|
|
|
|
+ },
|
|
decoration: InputDecoration(
|
|
decoration: InputDecoration(
|
|
contentPadding: EdgeInsets.all(12),
|
|
contentPadding: EdgeInsets.all(12),
|
|
border: InputBorder.none,
|
|
border: InputBorder.none,
|
|
@@ -246,19 +400,8 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
|
|
- // 6. Precio
|
|
|
|
|
|
+ // Espaciador final
|
|
const SizedBox(height: 30),
|
|
const SizedBox(height: 30),
|
|
- const Center(
|
|
|
|
- child: Text(
|
|
|
|
- "Precio: MXN 115.00",
|
|
|
|
- style: TextStyle(
|
|
|
|
- color: Colors.white,
|
|
|
|
- fontSize: 24,
|
|
|
|
- fontWeight: FontWeight.bold,
|
|
|
|
- ),
|
|
|
|
- ),
|
|
|
|
- ),
|
|
|
|
- const SizedBox(height: 20),
|
|
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
@@ -278,70 +421,67 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
return SingleChildScrollView(
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
child: Column(
|
|
children: [
|
|
children: [
|
|
- Row(
|
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
- children: [
|
|
|
|
- Expanded(
|
|
|
|
- child: Column(
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
- children: [
|
|
|
|
- const SizedBox(height: 16),
|
|
|
|
|
|
+ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
|
|
|
+ Expanded(
|
|
|
|
+ child: Column(
|
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
+ children: [
|
|
|
|
+ const SizedBox(height: 16),
|
|
|
|
+ Text(
|
|
|
|
+ title,
|
|
|
|
+ style: const TextStyle(
|
|
|
|
+ color: Colors.black,
|
|
|
|
+ fontSize: 20,
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ if (subtitle != null) ...[
|
|
|
|
+ const SizedBox(height: 4),
|
|
Text(
|
|
Text(
|
|
- title,
|
|
|
|
|
|
+ subtitle,
|
|
style: const TextStyle(
|
|
style: const TextStyle(
|
|
- color: Colors.black,
|
|
|
|
- fontSize: 20,
|
|
|
|
- fontWeight: FontWeight.bold,
|
|
|
|
|
|
+ color: Colors.grey,
|
|
|
|
+ fontSize: 16,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
- if (subtitle != null) ...[
|
|
|
|
- const SizedBox(height: 4),
|
|
|
|
- Text(
|
|
|
|
- subtitle,
|
|
|
|
- style: const TextStyle(
|
|
|
|
- color: Colors.grey,
|
|
|
|
- fontSize: 16,
|
|
|
|
- ),
|
|
|
|
- ),
|
|
|
|
- ],
|
|
|
|
- if (subtitle == null) const SizedBox(height: 16),
|
|
|
|
],
|
|
],
|
|
- ),
|
|
|
|
|
|
+ if (subtitle == null) const SizedBox(height: 16),
|
|
|
|
+ ],
|
|
),
|
|
),
|
|
- if (showObligatorio) ...[
|
|
|
|
- Container(
|
|
|
|
- padding:
|
|
|
|
- const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
|
|
- decoration: BoxDecoration(
|
|
|
|
- borderRadius: BorderRadius.circular(20),
|
|
|
|
- border: Border.all(color: Colors.grey),
|
|
|
|
- ),
|
|
|
|
- child: const Text(
|
|
|
|
- "Obligatorio",
|
|
|
|
- style: TextStyle(color: Colors.grey),
|
|
|
|
- ),
|
|
|
|
|
|
+ ),
|
|
|
|
+ if (showObligatorio) ...[
|
|
|
|
+ Container(
|
|
|
|
+ padding:
|
|
|
|
+ const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
+ borderRadius: BorderRadius.circular(20),
|
|
|
|
+ border: Border.all(color: Colors.grey),
|
|
),
|
|
),
|
|
- const SizedBox(width: 10),
|
|
|
|
- ],
|
|
|
|
- GestureDetector(
|
|
|
|
- onTap: onTap,
|
|
|
|
- child: Container(
|
|
|
|
- width: 40,
|
|
|
|
- height: 40,
|
|
|
|
- decoration: const BoxDecoration(
|
|
|
|
- color: Color(0xFF333333),
|
|
|
|
- shape: BoxShape.circle,
|
|
|
|
- ),
|
|
|
|
- child: Icon(
|
|
|
|
- isExpanded
|
|
|
|
- ? Icons.keyboard_arrow_up
|
|
|
|
- : Icons.keyboard_arrow_down,
|
|
|
|
- color: Colors.black,
|
|
|
|
- ),
|
|
|
|
|
|
+ child: const Text(
|
|
|
|
+ "Obligatorio",
|
|
|
|
+ style: TextStyle(color: Colors.grey),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
+ const SizedBox(width: 10),
|
|
],
|
|
],
|
|
- ),
|
|
|
|
|
|
+ GestureDetector(
|
|
|
|
+ onTap: onTap,
|
|
|
|
+ child: Container(
|
|
|
|
+ width: 40,
|
|
|
|
+ height: 40,
|
|
|
|
+ decoration: const BoxDecoration(
|
|
|
|
+ color: Colors.cyan,
|
|
|
|
+ shape: BoxShape.circle,
|
|
|
|
+ ),
|
|
|
|
+ child: Icon(
|
|
|
|
+ isExpanded
|
|
|
|
+ ? Icons.keyboard_arrow_up
|
|
|
|
+ : Icons.keyboard_arrow_down,
|
|
|
|
+ color: Colors.white,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ]),
|
|
if (content != null) content,
|
|
if (content != null) content,
|
|
const SizedBox(height: 8),
|
|
const SizedBox(height: 8),
|
|
],
|
|
],
|
|
@@ -351,7 +491,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
|
|
|
|
Widget _buildToppingsContent() {
|
|
Widget _buildToppingsContent() {
|
|
return Column(
|
|
return Column(
|
|
- children: toppingsOptions.map((topping) {
|
|
|
|
|
|
+ children: widget.product.availableToppings.map((topping) {
|
|
final isSelected = selectedToppings.contains(topping);
|
|
final isSelected = selectedToppings.contains(topping);
|
|
return CheckboxListTile(
|
|
return CheckboxListTile(
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
|
|
@@ -372,6 +512,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
} else {
|
|
} else {
|
|
selectedToppings.remove(topping);
|
|
selectedToppings.remove(topping);
|
|
}
|
|
}
|
|
|
|
+ widget.onOptionChanged();
|
|
});
|
|
});
|
|
},
|
|
},
|
|
);
|
|
);
|
|
@@ -382,7 +523,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
// Contenido del dropdown de Refresco
|
|
// Contenido del dropdown de Refresco
|
|
Widget _buildRefrescoContent() {
|
|
Widget _buildRefrescoContent() {
|
|
return Column(
|
|
return Column(
|
|
- children: refrescoOptions.map((refresco) {
|
|
|
|
|
|
+ children: widget.product.availableDrinks.map((refresco) {
|
|
return RadioListTile<String>(
|
|
return RadioListTile<String>(
|
|
title: Text(
|
|
title: Text(
|
|
refresco,
|
|
refresco,
|
|
@@ -397,6 +538,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
onChanged: (String? value) {
|
|
onChanged: (String? value) {
|
|
setState(() {
|
|
setState(() {
|
|
selectedRefresco = value;
|
|
selectedRefresco = value;
|
|
|
|
+ widget.onOptionChanged();
|
|
});
|
|
});
|
|
},
|
|
},
|
|
);
|
|
);
|
|
@@ -407,7 +549,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
// Contenido del dropdown de Cocción
|
|
// Contenido del dropdown de Cocción
|
|
Widget _buildCoccionContent() {
|
|
Widget _buildCoccionContent() {
|
|
return Column(
|
|
return Column(
|
|
- children: coccionOptions.map((coccion) {
|
|
|
|
|
|
+ children: widget.product.availableCookingTerms.map((coccion) {
|
|
return RadioListTile<String>(
|
|
return RadioListTile<String>(
|
|
title: Text(
|
|
title: Text(
|
|
coccion,
|
|
coccion,
|
|
@@ -422,6 +564,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
onChanged: (String? value) {
|
|
onChanged: (String? value) {
|
|
setState(() {
|
|
setState(() {
|
|
selectedCoccion = value;
|
|
selectedCoccion = value;
|
|
|
|
+ widget.onOptionChanged();
|
|
});
|
|
});
|
|
},
|
|
},
|
|
);
|
|
);
|
|
@@ -438,6 +581,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
onTap: () {
|
|
onTap: () {
|
|
setState(() {
|
|
setState(() {
|
|
isQuesoSelected = !isQuesoSelected;
|
|
isQuesoSelected = !isQuesoSelected;
|
|
|
|
+ widget.onOptionChanged();
|
|
});
|
|
});
|
|
},
|
|
},
|
|
child: Row(
|
|
child: Row(
|
|
@@ -454,7 +598,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
: null,
|
|
: null,
|
|
),
|
|
),
|
|
const SizedBox(width: 16),
|
|
const SizedBox(width: 16),
|
|
- const Column(
|
|
|
|
|
|
+ Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
children: [
|
|
Text(
|
|
Text(
|
|
@@ -466,7 +610,7 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Text(
|
|
Text(
|
|
- "+ MXN 5.00",
|
|
|
|
|
|
+ "+ MXN ${widget.product.cheeseprecio.toStringAsFixed(2)}",
|
|
style: TextStyle(
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontSize: 16,
|
|
@@ -480,3 +624,17 @@ class _ToppingsViewState extends State<ToppingsView> {
|
|
);
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// Ejemplo de cómo se usaría la pantalla con el modelo de producto
|
|
|
|
+class ExampleUsage extends StatelessWidget {
|
|
|
|
+ @override
|
|
|
|
+ Widget build(BuildContext context) {
|
|
|
|
+ // Crear un producto con datos estáticos
|
|
|
|
+ final product = Product.staticSandwich();
|
|
|
|
+
|
|
|
|
+ // Navegar a la pantalla del producto
|
|
|
|
+ return MaterialApp(
|
|
|
|
+ home: ProductScreen(product: product),
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+}
|