You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

300 lines
13KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/End.dart';
  3. import 'package:farm_tpf/data/api/app_exception.dart';
  4. import 'package:farm_tpf/data/repository/repository.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_description.dart';
  12. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  15. import 'package:farm_tpf/utils/const_common.dart';
  16. import 'package:farm_tpf/utils/const_string.dart';
  17. import 'package:farm_tpf/utils/pref.dart';
  18. import 'package:farm_tpf/utils/validators.dart';
  19. import 'package:flutter/material.dart';
  20. import 'package:flutter_bloc/flutter_bloc.dart';
  21. import 'package:get/get.dart';
  22. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  23. import 'package:farm_tpf/utils/formatter.dart';
  24. import '../util_action.dart';
  25. class EditActionEndScreen extends StatefulWidget {
  26. final int cropId;
  27. final bool isEdit;
  28. final int activityId;
  29. EditActionEndScreen(
  30. {@required this.cropId, this.isEdit = false, this.activityId});
  31. @override
  32. _EditActionEndScreenState createState() => _EditActionEndScreenState();
  33. }
  34. class _EditActionEndScreenState extends State<EditActionEndScreen> {
  35. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  36. final _repository = Repository();
  37. GlobalKey<FormState> _formKey = GlobalKey();
  38. bool _autoValidate = false;
  39. End _end = End();
  40. final _descriptionController = TextEditingController();
  41. final _executeByController = TextEditingController();
  42. var pref = LocalPref();
  43. DateTime executeTime = DateTime.now();
  44. List<String> filePaths = List<String>();
  45. var changeFileController = Get.put(ChangeFileController());
  46. Future<Null> getSharedPrefs() async {
  47. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  48. _executeByController.text = currentFullName ?? "";
  49. }
  50. @override
  51. void initState() {
  52. super.initState();
  53. getSharedPrefs();
  54. changeFileController.initValue();
  55. _end.cropId = widget.cropId;
  56. }
  57. _validateInputs() async {
  58. if (_formKey.currentState.validate()) {
  59. _formKey.currentState.save();
  60. LoadingDialog.showLoadingDialog(context);
  61. filePaths = Get.find<ChangeFileController>().newFiles;
  62. try {
  63. _end.mediaDel = Get.find<ChangeFileController>().deleteFiles;
  64. var activityEnd = jsonEncode(_end.toJson()).toString();
  65. //ADD NEW
  66. if (_end.activityId == null) {
  67. _repository.createAction((value) {
  68. LoadingDialog.hideLoadingDialog(context);
  69. Get.back(result: value);
  70. Utils.showSnackBarSuccess(message: label_add_success);
  71. }, (error) {
  72. LoadingDialog.hideLoadingDialog(context);
  73. Utils.showSnackBarError(message: AppException.handleError(error));
  74. },
  75. apiAddAction: ConstCommon.apiAddEnd,
  76. paramActivity: ConstCommon.paramsActionEnd,
  77. activityAction: activityEnd,
  78. filePaths: filePaths);
  79. } else {
  80. //UPDATE
  81. _repository.updateAction((value) {
  82. LoadingDialog.hideLoadingDialog(context);
  83. Get.back(result: value);
  84. Utils.showSnackBarSuccess(message: label_update_success);
  85. }, (error) {
  86. LoadingDialog.hideLoadingDialog(context);
  87. Utils.showSnackBarError(message: AppException.handleError(error));
  88. },
  89. apiUpdateAction: ConstCommon.apiUpdateEnd,
  90. paramActivity: ConstCommon.paramsActionEnd,
  91. activityAction: activityEnd,
  92. filePaths: filePaths);
  93. }
  94. } catch (e) {
  95. LoadingDialog.hideLoadingDialog(context);
  96. print(e.toString());
  97. }
  98. } else {
  99. _autoValidate = true;
  100. }
  101. }
  102. Widget _btnExecuteTimePicker() {
  103. return WidgetFieldDateTimePicker(
  104. initDateTime: executeTime,
  105. onUpdateDateTime: (selectedDate) {
  106. _end.executeDate =
  107. selectedDate.convertLocalDateTimeToStringUtcDateTime();
  108. });
  109. }
  110. Widget _descriptionField() {
  111. return TextFieldDescriptionWidget(
  112. controller: _descriptionController,
  113. onSaved: (newValue) {
  114. _end.description = newValue;
  115. });
  116. }
  117. Widget _executeByField() {
  118. return TextFormField(
  119. keyboardType: TextInputType.text,
  120. decoration: InputDecoration(labelText: "Người thực hiện"),
  121. enabled: false,
  122. controller: _executeByController,
  123. onSaved: (newValue) {},
  124. );
  125. }
  126. @override
  127. Widget build(BuildContext context) => KeyboardDismisser(
  128. gestures: [
  129. GestureType.onTap,
  130. GestureType.onPanUpdateDownDirection,
  131. ],
  132. child: Scaffold(
  133. backgroundColor: Colors.white,
  134. key: _scaffoldKey,
  135. appBar: AppBarWidget(
  136. isBack: true,
  137. action: InkWell(
  138. child: Text(
  139. 'Huỷ',
  140. style: TextStyle(
  141. color: Colors.red, fontWeight: FontWeight.normal),
  142. ),
  143. onTap: () {
  144. if (Get.isSnackbarOpen) Get.back();
  145. Get.back();
  146. },
  147. ),
  148. ),
  149. body: KeyboardDismisser(
  150. child: MultiBlocProvider(
  151. providers: [
  152. BlocProvider<ActionDetailBloc>(
  153. create: (context) =>
  154. ActionDetailBloc(repository: Repository())
  155. ..add(FetchData(
  156. isNeedFetchData: widget.isEdit,
  157. apiActivity: ConstCommon.apiDetailEnd,
  158. activityId: widget.activityId))),
  159. BlocProvider<MediaHelperBloc>(
  160. create: (context) =>
  161. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  162. )
  163. ],
  164. child: Form(
  165. key: _formKey,
  166. autovalidate: _autoValidate,
  167. child: SafeArea(
  168. child: SingleChildScrollView(
  169. child:
  170. BlocConsumer<ActionDetailBloc, ActionDetailState>(
  171. listener: (context, state) async {
  172. if (state is ActionDetailFailure) {
  173. LoadingDialog.hideLoadingDialog(context);
  174. } else if (state is ActionDetailSuccess) {
  175. LoadingDialog.hideLoadingDialog(context);
  176. _end = End.fromJson(state.item);
  177. _end.activityId = widget.activityId;
  178. _descriptionController.text =
  179. _end.description ?? "";
  180. _executeByController.text = _end.createdByName;
  181. Get.find<ChangeDateTimePicker>().change(_end
  182. .executeDate
  183. .convertStringServerDateTimeToLocalDateTime());
  184. //Show media
  185. if (Validators.stringNotNullOrEmpty(_end.media)) {
  186. BlocProvider.of<MediaHelperBloc>(context).add(
  187. ChangeListMedia(
  188. items:
  189. UtilAction.convertFilePathToMedia(
  190. _end.media)));
  191. }
  192. } else if (state is ActionDetailInitial) {
  193. } else if (state is ActionDetailLoading) {
  194. LoadingDialog.showLoadingDialog(context);
  195. }
  196. },
  197. builder: (context, state) {
  198. return Column(
  199. children: [
  200. Padding(
  201. padding: const EdgeInsets.all(8.0),
  202. child: Column(
  203. crossAxisAlignment:
  204. CrossAxisAlignment.start,
  205. children: <Widget>[
  206. Text(
  207. plot_action_finish,
  208. style: TextStyle(
  209. fontWeight: FontWeight.w500,
  210. fontSize: 22),
  211. ),
  212. SizedBox(
  213. height: 8.0,
  214. ),
  215. Container(
  216. width: double.infinity,
  217. child: Text(
  218. "Ngày thực hiện *",
  219. style: TextStyle(
  220. color: Colors.black54,
  221. fontSize: 13.0),
  222. ),
  223. ),
  224. _btnExecuteTimePicker(),
  225. SizedBox(
  226. height: 8.0,
  227. ),
  228. _descriptionField(),
  229. SizedBox(
  230. height: 8.0,
  231. ),
  232. _executeByField(),
  233. SizedBox(
  234. height: 8.0,
  235. ),
  236. ],
  237. ),
  238. ),
  239. Container(
  240. width: double.infinity,
  241. height: 16,
  242. color: Colors.grey[200],
  243. ),
  244. BlocBuilder<MediaHelperBloc, MediaHelperState>(
  245. builder: (context, state) {
  246. if (state is MediaHelperSuccess) {
  247. return WidgetMediaPicker(
  248. currentItems: state.items,
  249. onChangeFiles: (newPathFiles,
  250. deletePathFiles) async {
  251. Get.find<ChangeFileController>()
  252. .change(newPathFiles,
  253. deletePathFiles);
  254. });
  255. } else {
  256. return Center(
  257. child: CircularProgressIndicator());
  258. }
  259. }),
  260. Padding(
  261. padding: const EdgeInsets.all(8.0),
  262. child: ButtonWidget(
  263. title: 'CẬP NHẬT',
  264. onPressed: () {
  265. FocusScopeNode currentFocus =
  266. FocusScope.of(context);
  267. if (!currentFocus.hasPrimaryFocus) {
  268. currentFocus.unfocus();
  269. }
  270. _validateInputs();
  271. }),
  272. ),
  273. ],
  274. );
  275. },
  276. ),
  277. ),
  278. )),
  279. ))));
  280. @override
  281. void dispose() {
  282. _descriptionController.dispose();
  283. _executeByController.dispose();
  284. super.dispose();
  285. }
  286. }