123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- // 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<TopingForm> createState() => Formulario();
- }
- class Formulario extends State<TopingForm> {
- 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<void> _initializeForm() async {
- Provider.of<TopingViewModel>(context, listen: false).setIsLoading(true);
- final mvm = Provider.of<TopingViewModel>(context, listen: false);
- final tcv = Provider.of<TopingCategoriaViewModel>(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<TopingViewModel>(context, listen: false).setIsLoading(false);
- }
- @override
- void dispose() {
- super.dispose();
- _descripcion.dispose();
- _nombre.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final mvm = Provider.of<TopingViewModel>(context);
- final modelo = mvm.selectedToping;
- final mediavm = Provider.of<MediaViewModel>(context);
- final tcv = Provider.of<TopingCategoriaViewModel>(context, listen: false);
- if (mvm.isLoading) return const Cargando();
- final Toping = mvm.selectedToping;
- List<Widget> _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<TopingViewModel>(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<TopingViewModel>(context, listen: false)
- .setIsLoading(false);
- if (context.mounted) {
- Navigator.pop(context);
- }
- }),
- ],
- ),
- ),
- );
- }
- Widget itemMedia(BuildContext context, int index) {
- MediaToping mediaTC = Provider.of<TopingViewModel>(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'),
- ),
- ],
- ),
- );
- }
- }
|