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.

305 lines
12KB

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