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.

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