toping_form.dart 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // ignore_for_file: use_build_context_synchronously
  2. import 'package:camera/camera.dart';
  3. import 'package:file_picker/file_picker.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:yoshi_papas_app/views/home/home_screen.dart';
  6. import 'package:yoshi_papas_app/widgets/widgets.dart';
  7. import 'package:provider/provider.dart';
  8. import '../../models/models.dart';
  9. import '../../viewmodels/viewmodels.dart';
  10. class TopingForm extends StatefulWidget {
  11. const TopingForm({Key? key}) : super(key: key);
  12. @override
  13. State<TopingForm> createState() => Formulario();
  14. }
  15. class Formulario extends State<TopingForm> {
  16. final _clave = TextEditingController();
  17. final _nombre = TextEditingController();
  18. final _descripcion = TextEditingController();
  19. final _costo = TextEditingController();
  20. final _categoria = TextEditingController();
  21. final _imagen = TextEditingController();
  22. @override
  23. void initState() {
  24. super.initState();
  25. Future(() async {
  26. Provider.of<TopingViewModel>(context, listen: false).setIsLoading(true);
  27. final mvm = Provider.of<TopingViewModel>(context, listen: false);
  28. Toping? modelo = mvm.selectedToping;
  29. if (modelo != null && modelo.id > 0) {
  30. setState(() {
  31. _clave.text = modelo.clave.toString();
  32. _nombre.text = modelo.nombre.toString();
  33. _descripcion.text = modelo.descripcion.toString();
  34. _costo.text = modelo.costo.toString();
  35. _categoria.text = modelo.idCategoria.toString();
  36. });
  37. }
  38. Provider.of<TopingViewModel>(context, listen: false).setIsLoading(false);
  39. });
  40. }
  41. @override
  42. void dispose() {
  43. super.dispose();
  44. _descripcion.dispose();
  45. _nombre.dispose();
  46. }
  47. @override
  48. Widget build(BuildContext context) {
  49. final mvm = Provider.of<TopingViewModel>(context);
  50. final modelo = mvm.selectedToping;
  51. final mediavm = Provider.of<MediaViewModel>(context);
  52. if (mvm.isLoading) return const Cargando();
  53. final Toping = mvm.selectedToping;
  54. List<Widget> _registros = [];
  55. if (modelo!.mediaToping.isNotEmpty) {
  56. for (int x = 0; x <= modelo.mediaToping.length - 1; x++) {
  57. _registros.add(itemMedia(context, x));
  58. }
  59. }
  60. Size s = MediaQuery.of(context).size;
  61. int axiscount = obtenerAxiscount(s);
  62. return Scaffold(
  63. appBar: encabezado(titulo: "Toping Categoria"),
  64. body: SingleChildScrollView(
  65. padding: const EdgeInsets.all(8),
  66. child: Column(
  67. children: [
  68. tarjeta(
  69. Padding(
  70. padding: const EdgeInsets.all(8),
  71. child: Column(
  72. children: [
  73. Row(
  74. children: [
  75. Expanded(
  76. child: AppTextField(
  77. maxLength: 100,
  78. etiqueta: 'Clave',
  79. controller: _clave,
  80. hintText: 'Clave Toping',
  81. ),
  82. ),
  83. ],
  84. ),
  85. Row(
  86. children: [
  87. Expanded(
  88. child: AppTextField(
  89. maxLength: 100,
  90. etiqueta: 'Nombre',
  91. controller: _nombre,
  92. hintText: 'Nombre Toping',
  93. ),
  94. ),
  95. ],
  96. ),
  97. Row(
  98. children: [
  99. Expanded(
  100. child: AppTextField(
  101. maxLength: 100,
  102. etiqueta: 'Categoria',
  103. controller: _categoria,
  104. hintText: 'Nombre Categoria',
  105. ),
  106. ),
  107. ],
  108. ),
  109. Row(
  110. children: [
  111. Expanded(
  112. child: AppTextField(
  113. maxLength: 100,
  114. etiqueta: 'Precio',
  115. controller: _costo,
  116. hintText: 'Precio Toping',
  117. ),
  118. ),
  119. ],
  120. ),
  121. Row(
  122. children: [
  123. Expanded(
  124. child: AppTextField(
  125. maxLength: 1000,
  126. maxLines: 3,
  127. etiqueta: 'Descripción',
  128. controller: _descripcion,
  129. hintText: 'Descripción de Toping',
  130. ),
  131. ),
  132. ],
  133. ),
  134. ],
  135. ),
  136. ),
  137. ),
  138. const SizedBox(height: 15),
  139. tarjeta(Column(children: [
  140. GridView.count(
  141. key: const Key("contenedor-1"),
  142. physics: const NeverScrollableScrollPhysics(),
  143. shrinkWrap: true,
  144. padding: const EdgeInsets.all(4),
  145. crossAxisCount: axiscount,
  146. crossAxisSpacing: 2,
  147. mainAxisSpacing: 1,
  148. children: [
  149. ..._registros,
  150. agregarMedia(accion: () async {
  151. Navigator.push(
  152. context,
  153. MaterialPageRoute(
  154. builder: (context) => const HomeScreen()),
  155. );
  156. }),
  157. ],
  158. ),
  159. const SizedBox(height: 30),
  160. ])),
  161. boton("Guardar", () async {
  162. Provider.of<TopingViewModel>(context, listen: false)
  163. .setIsLoading(true);
  164. await mvm.guardarModelo(
  165. modelo: Toping!,
  166. clave: _clave.text,
  167. nombre: _nombre.text,
  168. descripcion: _descripcion.text,
  169. );
  170. Provider.of<TopingViewModel>(context, listen: false)
  171. .setIsLoading(false);
  172. if (context.mounted) {
  173. Navigator.pop(context);
  174. }
  175. }),
  176. ],
  177. ),
  178. ),
  179. );
  180. }
  181. Widget itemMedia(BuildContext context, int index) {
  182. MediaToping mediaTC = Provider.of<TopingViewModel>(context, listen: false)
  183. .selectedToping!
  184. .mediaToping[index];
  185. // Asegúrate de que el objeto media no sea nulo
  186. if (mediaTC.media == null || mediaTC.media!.ruta!.isEmpty) {
  187. // Si es nulo, muestra un widget de placeholder
  188. return Container(
  189. alignment: Alignment.center,
  190. padding: EdgeInsets.all(8.0),
  191. child: Text('Imagen no disponible'),
  192. );
  193. }
  194. // Utiliza el objeto media para mostrar la imagen
  195. return Card(
  196. clipBehavior: Clip.antiAlias,
  197. child: Column(
  198. children: [
  199. Expanded(
  200. child: Image.network(
  201. mediaTC.media!.ruta!,
  202. fit: BoxFit.cover,
  203. errorBuilder: (context, error, stackTrace) {
  204. // Muestra un mensaje de error o imagen de placeholder
  205. return Center(child: Text('Error al cargar la imagen'));
  206. },
  207. ),
  208. ),
  209. Padding(
  210. padding: EdgeInsets.all(8.0),
  211. child: Text(mediaTC.media!.nombre ?? 'Sin nombre'),
  212. ),
  213. ],
  214. ),
  215. );
  216. }
  217. }