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.

384 lines
15KB

  1. import 'package:farm_tpf/custom_model/action_form/ActionUIField.dart';
  2. import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart';
  3. import 'package:farm_tpf/data/repository/repository.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/dropdown_supply_widget.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_action_field_date.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  12. import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_area.dart';
  13. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/cubit/action_ui_cubit.dart';
  15. import 'package:farm_tpf/utils/pref.dart';
  16. import 'package:farm_tpf/utils/validators.dart';
  17. import 'package:flutter/material.dart';
  18. import 'package:flutter_bloc/flutter_bloc.dart';
  19. import 'package:get/get.dart';
  20. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  21. import 'dung/widget_dung_supply.dart';
  22. import 'plant/widget_plant_supply.dart';
  23. import 'spraying/widget_spraying_supply.dart';
  24. import 'state_management_helper/change_file_controller.dart';
  25. class ActionScreen extends StatefulWidget {
  26. final int idAction;
  27. final String activityType;
  28. final String title;
  29. ActionScreen(
  30. {@required this.idAction,
  31. @required this.title,
  32. @required this.activityType});
  33. @override
  34. _ActionScreenState createState() => _ActionScreenState();
  35. }
  36. class _ActionScreenState extends State<ActionScreen> {
  37. final _scaffoldKey = GlobalKey<ScaffoldState>();
  38. var _formKey = GlobalKey<FormState>();
  39. var pref = LocalPref();
  40. final _executeByController = TextEditingController();
  41. DateTime executeTime = DateTime.now();
  42. List<String> filePaths = List<String>();
  43. var changeFileController = Get.put(ChangeFileController());
  44. Map<String, TextEditingController> textFieldControllers = {};
  45. Future<Null> getSharedPrefs() async {
  46. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  47. _executeByController.text = currentFullName ?? "";
  48. }
  49. @override
  50. void initState() {
  51. super.initState();
  52. getSharedPrefs();
  53. }
  54. _validateInputs() async {
  55. if (_formKey.currentState.validate()) {
  56. _formKey.currentState.save();
  57. LoadingDialog.showLoadingDialog(context);
  58. filePaths = Get.find<ChangeFileController>().newFiles;
  59. //Create request general model
  60. try {
  61. LoadingDialog.hideLoadingDialog(context);
  62. //ADD NEW
  63. //Update
  64. textFieldControllers.forEach((key, value) {
  65. print(textFieldControllers[key].text);
  66. });
  67. } catch (e) {
  68. LoadingDialog.hideLoadingDialog(context);
  69. print(e.toString());
  70. }
  71. } else {
  72. //
  73. }
  74. }
  75. Widget _btnExecuteTimePicker() {
  76. return WidgetFieldDateTimePicker(
  77. initDateTime: executeTime,
  78. onUpdateDateTime: (selectedDate) {
  79. //
  80. });
  81. }
  82. Widget _executeByField() {
  83. return TextFormField(
  84. keyboardType: TextInputType.text,
  85. decoration: InputDecoration(labelText: "Người thực hiện"),
  86. enabled: false,
  87. controller: _executeByController,
  88. onSaved: (newValue) {},
  89. );
  90. }
  91. //
  92. // GENERATE DYNAMIC FORM
  93. //
  94. Widget generateTextField(List<ActionUIField> fields) {
  95. return Wrap(
  96. children: [
  97. ListView.separated(
  98. shrinkWrap: true,
  99. physics: NeverScrollableScrollPhysics(),
  100. itemCount: fields.length,
  101. separatorBuilder: (context, index) {
  102. return SizedBox(
  103. height: 8,
  104. );
  105. },
  106. itemBuilder: (context, index) {
  107. var field = fields[index];
  108. if (field.tbControlTypeName == 'text') {
  109. return TextFormField(
  110. keyboardType: TextInputType.text,
  111. decoration: InputDecoration(labelText: field.description),
  112. controller: textFieldControllers[field.id.toString()],
  113. onSaved: (newValue) {},
  114. validator: field.isMandatory
  115. ? (String value) {
  116. return Validators.validateNotNullOrEmpty(
  117. value, 'Vui lòng nhập ${field.description}');
  118. }
  119. : null,
  120. );
  121. } else if (field.tbControlTypeName == 'number') {
  122. return WidgetTextFormFieldNumber(
  123. hintValue: field.description,
  124. textController: textFieldControllers[field.id.toString()],
  125. onSaved: (newValue) {},
  126. validator: field.isMandatory
  127. ? (String value) {
  128. return Validators.validNumberOrEmpty(
  129. value, 'Vui lòng nhập ${field.description}');
  130. }
  131. : null,
  132. );
  133. } else if (field.tbControlTypeName == 'textarea') {
  134. return TextFieldAreaWidget(
  135. hint: field.description,
  136. controller: textFieldControllers[field.id.toString()],
  137. onSaved: (newValue) {});
  138. } else if (field.tbControlTypeName == 'dropdown') {
  139. return DropdownSupplyWidget(
  140. titleName: field.description ?? '',
  141. tbSupply: field.tbActivityExtendTypeExternalTable ?? '',
  142. tag: field.name,
  143. value: field.description,
  144. hint:
  145. '${field.description} ${field.isMandatory ? '*' : ''}',
  146. condition: field.tbActivityExtendTypeCondition,
  147. invalidMessage: '',
  148. onPressed: (commonData) {
  149. print(commonData.name);
  150. });
  151. } else if (field.tbControlTypeName == 'date') {
  152. return FieldDateWidget(
  153. tag: field.name,
  154. value: field.description,
  155. hint:
  156. '${field.description} ${field.isMandatory ? '*' : ''}',
  157. invalidMessage: '',
  158. onPressed: (selectedDate) {
  159. print(selectedDate.day);
  160. });
  161. } else if (field.tbControlTypeName == 'radiobutton') {
  162. return DropdownSupplyWidget(
  163. titleName: field.description ?? '',
  164. tbSupply: field.tbActivityExtendTypeExternalTable ?? '',
  165. tag: field.name,
  166. value: field.description,
  167. hint:
  168. '${field.description} ${field.isMandatory ? '*' : ''}',
  169. condition: field.tbActivityExtendTypeCondition,
  170. invalidMessage: '',
  171. onPressed: (commonData) {
  172. print(commonData.name);
  173. });
  174. } else {
  175. return Container();
  176. }
  177. })
  178. ],
  179. );
  180. }
  181. //
  182. // GENERATE SUPPLY
  183. //
  184. Widget generateSupply(String activityType) {
  185. switch (activityType) {
  186. case 'ACTIVE_TYPE_NURSERY':
  187. return Container();
  188. break;
  189. case 'ACTIVE_TYPE_PLANTING':
  190. return Column(
  191. children: [
  192. Container(
  193. width: double.infinity,
  194. height: 16,
  195. color: Colors.grey[200],
  196. ),
  197. WidgetPlantSupply(currentItems: [], onChangeSupplies: (value) {}),
  198. ],
  199. );
  200. break;
  201. case 'ACTIVE_TYPE_FERTILIZE':
  202. return Column(
  203. children: [
  204. Container(
  205. width: double.infinity,
  206. height: 16,
  207. color: Colors.grey[200],
  208. ),
  209. WidgetDungSupply(currentItems: [], onChangeSupplies: (value) {}),
  210. ],
  211. );
  212. break;
  213. case 'ACTIVE_TYPE_SPRAYING_PESTICIDES':
  214. return Column(
  215. children: [
  216. Container(
  217. width: double.infinity,
  218. height: 16,
  219. color: Colors.grey[200],
  220. ),
  221. WidgetSprayingSupply(
  222. currentItems: [], onChangeSupplies: (value) {}),
  223. ],
  224. );
  225. break;
  226. default:
  227. return Container();
  228. break;
  229. }
  230. }
  231. @override
  232. Widget build(BuildContext context) => KeyboardDismisser(
  233. gestures: [
  234. GestureType.onTap,
  235. GestureType.onPanUpdateDownDirection,
  236. ],
  237. child: Scaffold(
  238. backgroundColor: Colors.white,
  239. key: _scaffoldKey,
  240. appBar: AppBarWidget(
  241. isBack: true,
  242. action: InkWell(
  243. child: Text(
  244. 'Lưu',
  245. style: TextStyle(
  246. color: Colors.red, fontWeight: FontWeight.normal),
  247. ),
  248. onTap: () {
  249. FocusScopeNode currentFocus = FocusScope.of(context);
  250. if (!currentFocus.hasPrimaryFocus) {
  251. currentFocus.unfocus();
  252. }
  253. _validateInputs();
  254. },
  255. ),
  256. ),
  257. body: KeyboardDismisser(
  258. child: MultiBlocProvider(
  259. providers: [
  260. BlocProvider<ActionUiCubit>(
  261. create: (context) =>
  262. ActionUiCubit(repository: Repository())
  263. ..getActionUIForm(widget.idAction)),
  264. BlocProvider<MediaHelperBloc>(
  265. create: (context) =>
  266. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  267. )
  268. ],
  269. child: Form(
  270. key: _formKey,
  271. child: SafeArea(
  272. child: SingleChildScrollView(
  273. child: BlocBuilder<ActionUiCubit, ActionUiState>(
  274. builder: (context, state) {
  275. if (state is ActionUiLoading) {
  276. print('loading...');
  277. return Center(child: CircularProgressIndicator());
  278. } else if (state is ActionUiSuccess) {
  279. var actionUiForm = state.item as ActionUIForm;
  280. actionUiForm.objectParameterDTOList
  281. .forEach((element) {
  282. var textEditingController =
  283. new TextEditingController();
  284. textFieldControllers.putIfAbsent(
  285. element.id.toString(),
  286. () => textEditingController);
  287. });
  288. return Column(
  289. children: [
  290. Padding(
  291. padding: const EdgeInsets.all(8.0),
  292. child: Column(
  293. children: <Widget>[
  294. Container(
  295. width: double.infinity,
  296. child: Text(
  297. "Ngày thực hiện *",
  298. style: TextStyle(
  299. color: Colors.black54,
  300. fontSize: 13.0),
  301. ),
  302. ),
  303. _btnExecuteTimePicker(),
  304. SizedBox(
  305. height: 8.0,
  306. ),
  307. generateTextField(actionUiForm
  308. .objectParameterDTOList),
  309. _executeByField(),
  310. SizedBox(
  311. height: 8.0,
  312. ),
  313. ],
  314. ),
  315. ),
  316. generateSupply(widget.activityType),
  317. Container(
  318. width: double.infinity,
  319. height: 16,
  320. color: Colors.grey[200],
  321. ),
  322. BlocBuilder<MediaHelperBloc,
  323. MediaHelperState>(
  324. builder: (context, state) {
  325. if (state is MediaHelperSuccess) {
  326. return WidgetMediaPicker(
  327. currentItems: state.items,
  328. onChangeFiles: (newPathFiles,
  329. deletePathFiles) async {
  330. Get.find<ChangeFileController>()
  331. .change(newPathFiles,
  332. deletePathFiles);
  333. });
  334. } else {
  335. return Center(
  336. child: CircularProgressIndicator());
  337. }
  338. }),
  339. Padding(
  340. padding: const EdgeInsets.all(8.0),
  341. child: ButtonWidget(
  342. title: 'CẬP NHẬT',
  343. onPressed: () {
  344. FocusScopeNode currentFocus =
  345. FocusScope.of(context);
  346. if (!currentFocus.hasPrimaryFocus) {
  347. currentFocus.unfocus();
  348. }
  349. _validateInputs();
  350. }),
  351. ),
  352. ],
  353. );
  354. } else if (state is ActionUiFailure) {
  355. print('error');
  356. return Text(state.errorString);
  357. // LoadingDialog.hideLoadingDialog(context);
  358. }
  359. },
  360. ),
  361. ),
  362. )),
  363. ))));
  364. @override
  365. void dispose() {
  366. _executeByController.dispose();
  367. super.dispose();
  368. }
  369. }