import 'package:farm_tpf/custom_model/CropPlot.dart'; import 'package:farm_tpf/custom_model/TbCropDTO.dart'; import 'package:farm_tpf/data/api/app_exception.dart'; import 'package:farm_tpf/data/repository/repository.dart'; import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart'; import 'package:farm_tpf/presentation/custom_widgets/bloc/widget_row_plot_info.dart'; import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart'; import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; import 'package:farm_tpf/presentation/screens/plot_detail/bloc_plot_information.dart'; import 'package:farm_tpf/utils/const_color.dart'; import 'package:farm_tpf/utils/const_string.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:keyboard_dismisser/keyboard_dismisser.dart'; import 'package:farm_tpf/utils/formatter.dart'; class PlotInformationScreen extends StatefulWidget { final int cropId; final bool isShowAppbar; PlotInformationScreen({required this.cropId, this.isShowAppbar = false}); @override _PlotInformationScreenState createState() => _PlotInformationScreenState(); } class _PlotInformationScreenState extends State with AutomaticKeepAliveClientMixin { final GlobalKey _scaffoldKey = new GlobalKey(); GlobalKey _formKey = GlobalKey(); TextEditingController _descriptionController = TextEditingController(); bool _autoValidate = false; CropPlot cropPlot = CropPlot(); TbCropDTO _crop = TbCropDTO(); final controller = Get.put(DescriptionChangeControler()); Repository _repository = Repository(); String statusCrop = plot_status_unknown; String technicians = ''; @override void initState() { super.initState(); getPlotInfoBloc.getPlotInfo(widget.cropId, (data) { var result = data as CropPlot; cropPlot = result; _crop = result.tbCropDTO ?? TbCropDTO(); switch (_crop.status) { case "STATUS_ARE_ACTIVE": statusCrop = plot_status_active; break; case "STATUS_FINISHED": statusCrop = plot_status_end; break; default: statusCrop = plot_status_unknown; } _descriptionController.text = _crop.description == null ? "" : _crop.description.toString(); if (_crop.tbDetailUsers != null) { for (var i = 0; i < (_crop.tbDetailUsers ?? []).length; i++) { if (i == 0) { technicians += _crop.tbDetailUsers?[i].fullName ?? ''; } else { technicians += ', ${_crop.tbDetailUsers?[i].fullName ?? ''}'; } } } }, (err) {}); } _validateInputs() async { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); LoadingDialog.showLoadingDialog(context); _repository.updatePlot(_crop).then((value) { LoadingDialog.hideLoadingDialog(context); Utils.showSnackBarSuccess(message: label_update_success); controller.initValue(); }).catchError((error) { LoadingDialog.hideLoadingDialog(context); Utils.showSnackBarError(message: AppException.handleError(error)); }); } else { _autoValidate = true; } } Widget _descriptionField() { return Container( padding: EdgeInsets.all(8), color: AppColors.YELLOW.withOpacity(0.1), child: TextFormField( keyboardType: TextInputType.text, controller: _descriptionController, decoration: InputDecoration( labelText: "Ghi chú", hintText: 'Ghi chú', enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 0.35))), onSaved: (newValue) { _crop.description = newValue; }, onChanged: (newValue) { controller.changeValue(_crop.description ?? '', newValue); }, ), ); } @override Widget build(BuildContext context) => KeyboardDismisser( gestures: [GestureType.onTap], child: Container( color: AppColors.ITEM_BG, child: SafeArea( top: false, bottom: true, child: Scaffold( appBar: widget.isShowAppbar ? AppBarWidget() : null, // PreferredSize( // preferredSize: Size(0, 0), // child: SizedBox(), // ), key: _scaffoldKey, body: KeyboardDismisser( child: StreamBuilder( stream: getPlotInfoBloc.actions, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData) { return Form( key: _formKey, child: SingleChildScrollView( padding: EdgeInsets.all(8.0), child: Column( children: [ WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.1), name: 'Mã lô', value: '${cropPlot.tbCropDTO?.code ?? ''}'), WidgetRowPlotInfo(color: AppColors.DEFAULT.withOpacity(0.3), name: 'Trạng thái', value: '$statusCrop'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.1), name: 'Nhà màng', value: '${cropPlot.tbCropDTO?.netHouseName ?? '--'}'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.3), name: 'Giống', value: '${cropPlot.tbCropDTO?.suppliesName ?? '--'}'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.1), name: 'Ngày gieo trồng', value: cropPlot.tbCropDTO?.tbCropTypeId == 0 ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}' : '--'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.3), name: 'Ngày vô khây ươm', value: cropPlot.tbCropDTO?.tbCropTypeId == 1 ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}' : '--'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.1), name: 'Thời gian ngâm hạt', value: '${cropPlot.seedIncubationTime ?? '--'} ngày'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.3), name: 'Số lượng cây trồng', value: '${cropPlot.numberPlants ?? '--'}'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.1), name: 'Số lượng cây hiện tại', value: '${cropPlot.numberCurrentPlants ?? '--'}'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.3), name: 'Ngày kết thúc canh tác', value: '${cropPlot.tbCropDTO?.endDate?.format_DDMMYY_HHmm() ?? '--'}'), WidgetRowPlotInfo(color: AppColors.DEFAULT.withOpacity(0.1), name: 'Kỹ sư trực tiếp', value: '$technicians'), WidgetRowPlotInfo( color: AppColors.DEFAULT.withOpacity(0.3), name: 'Diện tích (m\u00B2)', value: '${cropPlot.tbCropDTO?.areaM2?.formatNumtoStringDecimal()}'), SizedBox( height: 8, ), _descriptionField(), SizedBox( height: 16, ), GetBuilder( builder: (_) { return ButtonWidget( title: 'CẬP NHẬT', onPressed: controller.isChanged == false ? () {} : () { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } _validateInputs(); }, ); }, ) ], ), )); } else if (snapshot.hasError) { return Center( child: Text(snapshot.error.toString()), ); } else { return LoadingListPage(); } }, ), ), ), ), ), ); @override void dispose() { _descriptionController?.dispose(); super.dispose(); } @override bool get wantKeepAlive => true; } class DescriptionChangeControler extends GetxController { bool isChanged = false; void initValue() { isChanged = false; update(); } void changeValue(String oldValue, String newValue) { if (oldValue != newValue) { isChanged = true; } else { isChanged = false; } if (oldValue.isNullOrBlank && newValue.isEmpty) { isChanged = false; } update(); } }