// ignore_for_file: use_build_context_synchronously import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:provider/provider.dart'; import '../widgets/local_text.dart'; import 'model/shipment_rate_model.dart'; class CargoEditor extends StatefulWidget { final CargoType? cargo; const CargoEditor({super.key, this.cargo}); @override _CargoEditorState createState() => _CargoEditorState(); } class _CargoEditorState extends State { TextEditingController descController = TextEditingController(); TextEditingController rateController = TextEditingController(); TextEditingController displayIndexController = TextEditingController(); bool _isLoading = false; late CargoType _cargo; bool _isNew = false; final _cargoFormKey = GlobalKey(); bool _isDefault = false; bool _isMixCargo = false; @override void initState() { super.initState(); if (widget.cargo != null) { _cargo = widget.cargo!; descController.text = _cargo.name ?? ""; rateController.text = _cargo.rate.toStringAsFixed(2); displayIndexController.text = _cargo.displayIndex.toString(); _isDefault = _cargo.isDefault; _isMixCargo = _cargo.isMixCargo; } else { _isNew = true; } } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { final typeBox = InputText( labelTextKey: 'cargo.type', iconData: Ionicons.text, controller: descController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { return "Please insert cargo type"; } return null; }, ); final rateBox = InputText( labelTextKey: 'cargo.rate', iconData: Fontisto.dollar, controller: rateController, textInputType: TextInputType.number, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { return "Please insert rate"; } return null; }, ); final displayIndexBox = InputText( labelTextKey: 'cargo.display_index', iconData: FontAwesome.sort_numeric_asc, controller: displayIndexController, textInputType: TextInputType.number, autovalidateMode: AutovalidateMode.onUserInteraction, // validator: (value) { // if (value == null || value.isEmpty) { // return "Please insert display index"; // } // return null; // }, ); final defaultBox = Padding( padding: const EdgeInsets.symmetric(vertical: 10), child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ LocalText( context, 'cargo.is_default', color: Colors.black54, fontSize: 15, ), ], ), ), Transform.scale( scale: 0.7, alignment: Alignment.centerRight, child: CupertinoSwitch( activeTrackColor: primaryColor, value: _isDefault, onChanged: (v) { setState(() { _isDefault = v; }); })) ]), ); final mixCargoBox = Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ LocalText( context, 'cargo.is_mix', color: Colors.black54, fontSize: 15, ), ], ), ), Transform.scale( scale: 0.7, alignment: Alignment.centerRight, child: CupertinoSwitch( activeTrackColor: primaryColor, value: _isMixCargo, onChanged: (v) { setState(() { _isMixCargo = v; }); })) ]); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: "cargo.form.title", backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor, onBack: () { if (isDataChanged()) { showConfirmDialog(context, "back.button_confirm", () { Navigator.of(context).pop(); }); } else { Navigator.of(context).pop(); } }, actions: [ _isNew ? Container() : IconButton( icon: Icon(Icons.delete, color: primaryColor), onPressed: _delete, ) ], ), body: Form( key: _cargoFormKey, child: Container( padding: EdgeInsets.all(18), child: Column( children: [ Expanded( child: ListView( children: [ typeBox, rateBox, displayIndexBox, SizedBox(height: 10), defaultBox, mixCargoBox, SizedBox(height: 30), ], ), ), fcsButton(context, getLocalString(context, "btn.save"), callack: _save), SizedBox(height: 30) ], ), ), ), ), ); } _save() async { if (!_cargoFormKey.currentState!.validate()) { return; } setState(() { _isLoading = true; }); try { var shipmentRateModel = Provider.of(context, listen: false); CargoType cargo = CargoType( name: descController.text, rate: double.parse(rateController.text), displayIndex: displayIndexController.text == '' ? 0 : int.parse(displayIndexController.text), isDefault: _isDefault, isMixCargo: _isMixCargo); if (_isNew) { await shipmentRateModel.addCargoType(cargo); } else { cargo.id = _cargo.id; await shipmentRateModel.updateCargoType(cargo); } Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } _delete() { showConfirmDialog(context, "cargo.edit.delete.confirm", _deleteCargoType); } _deleteCargoType() async { setState(() { _isLoading = true; }); try { var shipmentRateModel = Provider.of(context, listen: false); await shipmentRateModel.deleteCargoType(_cargo.id!); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } isDataChanged() { if (_isNew) { return descController.text != "" || rateController.text != "" || displayIndexController.text != "" || _isDefault != false || _isMixCargo != false; } else { CargoType cargo = CargoType( name: descController.text, rate: double.parse(rateController.text), displayIndex: int.parse(displayIndexController.text), isDefault: _isDefault, isMixCargo: _isMixCargo); return _cargo.isChangedForEdit(cargo); } } }