// ignore_for_file: use_build_context_synchronously import 'package:camera/camera.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:yoshi_papas_app/views/home/home_screen.dart'; import 'package:yoshi_papas_app/widgets/widgets.dart'; import 'package:provider/provider.dart'; import '../../models/models.dart'; import '../../viewmodels/viewmodels.dart'; class TopingForm extends StatefulWidget { const TopingForm({Key? key}) : super(key: key); @override State createState() => Formulario(); } class Formulario extends State { final _clave = TextEditingController(); final _nombre = TextEditingController(); final _descripcion = TextEditingController(); final _costo = TextEditingController(); final _categoria = TextEditingController(); int? _selectedCategoriaId; TopingCategoria? _selectedCategoria; final _imagen = TextEditingController(); bool activo = false; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _initializeForm(); }); } Future _initializeForm() async { Provider.of(context, listen: false).setIsLoading(true); final mvm = Provider.of(context, listen: false); final tcv = Provider.of(context, listen: false); Toping? modelo = mvm.selectedToping; if (modelo != null && modelo.id > 0) { activo = modelo.activo!; _clave.text = modelo.clave.toString(); _nombre.text = modelo.nombre.toString(); _descripcion.text = modelo.descripcion.toString(); _costo.text = modelo.costo.toString(); _selectedCategoriaId = modelo.idCategoria; // Asegurarse de que las categorías están cargadas if (tcv.registros.isEmpty) { await tcv.fetchRegistros(); } // Buscar la categoría seleccionada final TopingCategoria? categoriaSeleccionada = tcv.getById(_selectedCategoriaId!); if (categoriaSeleccionada != null) { setState(() { _selectedCategoria = categoriaSeleccionada; _categoria.text = categoriaSeleccionada.nombre!; }); } } Provider.of(context, listen: false).setIsLoading(false); } @override void dispose() { super.dispose(); _descripcion.dispose(); _nombre.dispose(); } @override Widget build(BuildContext context) { final mvm = Provider.of(context); final modelo = mvm.selectedToping; final mediavm = Provider.of(context); final tcv = Provider.of(context, listen: false); if (mvm.isLoading) return const Cargando(); final Toping = mvm.selectedToping; List _registros = []; if (modelo!.imagenes.isNotEmpty) { for (int x = 0; x <= modelo.imagenes.length - 1; x++) { _registros.add(itemMedia(context, x)); } } Size s = MediaQuery.of(context).size; int axiscount = obtenerAxiscount(s); return Scaffold( appBar: encabezado(titulo: "Toping"), body: SingleChildScrollView( padding: const EdgeInsets.all(8), child: Column( children: [ tarjeta( Padding( padding: const EdgeInsets.all(8), child: Column( children: [ Row( children: [ Expanded( child: AppTextField( maxLength: 100, etiqueta: 'Clave', controller: _clave, hintText: 'Clave Toping', ), ), ], ), Row( children: [ Expanded( child: AppTextField( maxLength: 100, etiqueta: 'Nombre', controller: _nombre, hintText: 'Nombre Toping', ), ), ], ), Row( children: [ Expanded( child: AppDropdownSearch( etiqueta: 'Categoría', controller: _categoria, selectedItem: _selectedCategoria, onPressedClear: () { setState(() { _selectedCategoria = null; _categoria.text = ""; }); }, itemAsString: (u) => '${u.clave}', asyncItems: (text) async { final r = await tcv.fetchRegistros( q: text, segmentar: true); return r; }, onChanged: (e) { setState(() { _selectedCategoria = e; _selectedCategoriaId = e?.id; _categoria.text = e?.nombre ?? ""; }); }, validator: (value) { if (value == null) { return 'Seleccione'; } return null; }, ) /*AppTextField( maxLength: 100, etiqueta: 'Categoria', controller: _categoria, hintText: 'Nombre Categoria', ),*/ ), ], ), Row( children: [ Expanded( child: AppTextField( maxLength: 100, etiqueta: 'Precio', controller: _costo, hintText: 'Precio Toping', ), ), ], ), Row( children: [ Expanded( child: AppTextField( maxLength: 1000, maxLines: 3, etiqueta: 'Descripción', controller: _descripcion, hintText: 'Descripción de Toping', ), ), ], ), Row( children: [ Expanded( flex: 0, child: Column(children: [ const Text("ACTIVO", style: TextStyle(fontWeight: FontWeight.bold)), Switch( activeColor: Colors.green, value: activo, onChanged: (value) { setState(() { activo = value; }); }, ) ])) ], ), ], ), ), ), const SizedBox(height: 15), tarjeta(Column(children: [ GridView.count( key: const Key("contenedor-1"), physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, padding: const EdgeInsets.all(4), crossAxisCount: axiscount, crossAxisSpacing: 2, mainAxisSpacing: 1, children: [ ..._registros, agregarMedia( accion: () async { FilePickerResult? r = await FilePicker.platform .pickFiles( type: FileType.custom, allowMultiple: true, allowedExtensions: ['jpg', 'png']); if (r == null) return; if (r.files.isEmpty) return; for (PlatformFile xf in r.files) { XFile? x = await mediavm.convertirPlatformFileAXFile(xf); mediavm.agregarArchivo(x); } }, titulo: "Agregar Media"), ], ), const SizedBox(height: 30), ])), boton("Guardar", () async { Provider.of(context, listen: false) .setIsLoading(true); await mvm.guardarModelo( modelo: Toping!, clave: _clave.text, nombre: _nombre.text, descripcion: _descripcion.text, categoria: _selectedCategoriaId!, costo: _costo.text, activo: activo, imagenes: mediavm.archivos); Provider.of(context, listen: false) .setIsLoading(false); if (context.mounted) { Navigator.pop(context); } }), ], ), ), ); } Widget itemMedia(BuildContext context, int index) { MediaToping mediaTC = Provider.of(context, listen: false) .selectedToping! .imagenes[index]; // Asegúrate de que el objeto media no sea nulo if (mediaTC.media == null || mediaTC.media!.ruta!.isEmpty) { // Si es nulo, muestra un widget de placeholder return Container( alignment: Alignment.center, padding: EdgeInsets.all(8.0), child: Text('Imagen no disponible'), ); } // Utiliza el objeto media para mostrar la imagen return Card( clipBehavior: Clip.antiAlias, child: Column( children: [ Expanded( child: Image.network( mediaTC.media!.ruta!, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { // Muestra un mensaje de error o imagen de placeholder return Center(child: Text('Error al cargar la imagen')); }, ), ), Padding( padding: EdgeInsets.all(8.0), child: Text(mediaTC.media!.nombre ?? 'Sin nombre'), ), ], ), ); } }