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.

440 lines
17KB

  1. import 'package:farm_tpf/custom_model/LocationUnit.dart';
  2. import 'package:farm_tpf/custom_model/account.dart';
  3. import 'package:farm_tpf/data/repository/user_repository.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_toast.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  9. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart';
  10. import 'package:farm_tpf/presentation/screens/location_unit/sc_location.dart';
  11. import 'package:farm_tpf/presentation/screens/profile/controller/check_change_another_dropdown.dart';
  12. import 'package:farm_tpf/presentation/screens/profile/sc_change_password.dart';
  13. import 'package:farm_tpf/utils/const_color.dart';
  14. import 'package:farm_tpf/utils/const_common.dart';
  15. import 'package:farm_tpf/utils/const_string.dart';
  16. import 'package:farm_tpf/utils/const_style.dart';
  17. import 'package:farm_tpf/utils/validators.dart';
  18. import 'package:flutter/material.dart';
  19. import 'package:get/get.dart';
  20. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  21. import 'package:package_info/package_info.dart';
  22. import 'bloc_get_account.dart';
  23. class UpdateProfileScreen extends StatefulWidget {
  24. static Route route() {
  25. return MaterialPageRoute<void>(builder: (_) => UpdateProfileScreen());
  26. }
  27. @override
  28. _UpdateProfileScreenState createState() => _UpdateProfileScreenState();
  29. }
  30. class _UpdateProfileScreenState extends State<UpdateProfileScreen> {
  31. final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  32. final _repository = UserRepository();
  33. GlobalKey<FormState> _formKey = GlobalKey();
  34. bool _autoValidate = false;
  35. Account _account = Account();
  36. TextEditingController _userNameController = TextEditingController();
  37. TextEditingController _fullNameController = TextEditingController();
  38. TextEditingController _emailController = TextEditingController();
  39. TextEditingController _addressController = TextEditingController();
  40. var checkChangeLocation = Get.put(CheckChangeAnotherDropdown());
  41. @override
  42. void initState() {
  43. super.initState();
  44. checkChangeLocation.initValue();
  45. getAccountBloc.getAccount((data) {
  46. _account = data;
  47. _userNameController.text = _account.login ?? '';
  48. _fullNameController.text = _account.fullName.toString();
  49. _emailController.text = _account.email.toString();
  50. _addressController.text = _account.address ?? '';
  51. checkChangeLocation.changeCountryByIdAndName(_account.countryId?.toInt() ?? -1, _account.countryName ?? '');
  52. checkChangeLocation.changeProvinceByIdAndName(_account.cityId?.toInt() ?? -1, _account.cityName ?? '');
  53. checkChangeLocation.changeDistrictByIdAndName(_account.districtId?.toInt() ?? -1, _account.districtName ?? '');
  54. checkChangeLocation.changeWardByIdAndName(_account.wardId?.toInt() ?? -1, _account.wardName ?? '');
  55. }, (err) {
  56. Utils.showSnackBarError(message: "Lỗi tải dữ liệu");
  57. });
  58. }
  59. _validateInputs() async {
  60. if (_formKey.currentState!.validate()) {
  61. _formKey.currentState!.save();
  62. _account.countryId = checkChangeLocation.currentCountry.id;
  63. _account.cityId = checkChangeLocation.currentProvince.id;
  64. _account.districtId = checkChangeLocation.currentDistrict.id;
  65. _account.wardId = checkChangeLocation.currentWard.id;
  66. LoadingDialog.showLoadingDialog(_scaffoldKey.currentContext!);
  67. _repository.updateProfile(_account).then((value) {
  68. LoadingDialog.hideLoadingDialog(_scaffoldKey.currentContext!);
  69. Utils.showSnackBarSuccess(message: 'Cập nhật thành công.');
  70. }).catchError((onError) {
  71. Utils.showSnackBarError(message: 'Cập nhật không thành công.');
  72. LoadingDialog.hideLoadingDialog(_scaffoldKey.currentContext!);
  73. print("error");
  74. });
  75. } else {
  76. _autoValidate = true;
  77. }
  78. }
  79. Widget _userNameField() {
  80. return TextFormField(
  81. keyboardType: TextInputType.text,
  82. enabled: false,
  83. decoration: const InputDecoration(labelText: "Tài khoản"),
  84. controller: _userNameController,
  85. validator: (String? value) {
  86. return Validators.validateNotNullOrEmpty(value ?? '', "Tài khoản");
  87. },
  88. onSaved: (newValue) {},
  89. );
  90. }
  91. Widget _fullNameField() {
  92. return TextFormField(
  93. keyboardType: TextInputType.text,
  94. decoration: const InputDecoration(labelText: "Họ và tên"),
  95. controller: _fullNameController,
  96. validator: (String? value) {
  97. return Validators.validateNotNullOrEmpty(value ?? '', "Họ và tên");
  98. },
  99. onSaved: (newValue) {
  100. _account.fullName = newValue ?? '';
  101. },
  102. );
  103. }
  104. Widget _emailField() {
  105. return TextFormField(
  106. keyboardType: TextInputType.emailAddress,
  107. decoration: const InputDecoration(labelText: "Email"),
  108. controller: _emailController,
  109. validator: (String? value) {
  110. return Validators.validateEmail(value ?? '');
  111. },
  112. onSaved: (newValue) {
  113. _account.email = newValue ?? '';
  114. },
  115. );
  116. }
  117. Widget _btnSelectCountry() {
  118. return GetBuilder<CheckChangeAnotherDropdown>(builder: (data) {
  119. return FlatButton(
  120. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  121. onPressed: () {
  122. if (Get.isSnackbarOpen) {
  123. Get.back();
  124. }
  125. Navigator.of(context)
  126. .push(MaterialPageRoute(
  127. builder: (_) => LocationScreen(
  128. titleName: "Quốc gia",
  129. type: LocationType.country,
  130. filterId: -1,
  131. selectedId: checkChangeLocation.currentCountry.id ?? -1,
  132. ),
  133. fullscreenDialog: false))
  134. .then((value) {
  135. if (value != null) {
  136. var result = value as LocationUnit;
  137. checkChangeLocation.changeCountry(result);
  138. }
  139. });
  140. },
  141. child: Container(
  142. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  143. decoration: const BoxDecoration(
  144. border: kBorderTextField,
  145. ),
  146. child: Row(
  147. children: [
  148. GetBuilder<ChangeSupply>(
  149. builder: (_) => Expanded(
  150. child: Text(checkChangeLocation.currentCountry.name ?? "Quốc gia",
  151. style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
  152. const Icon(
  153. Icons.arrow_drop_down,
  154. color: Colors.grey,
  155. ),
  156. ],
  157. )));
  158. });
  159. }
  160. Widget _btnSelectProvince() {
  161. return GetBuilder<CheckChangeAnotherDropdown>(builder: (data) {
  162. return FlatButton(
  163. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  164. onPressed: () {
  165. if (Get.isSnackbarOpen) {
  166. Get.back();
  167. }
  168. if (checkChangeLocation.currentCountry.id != null) {
  169. Navigator.of(context)
  170. .push(MaterialPageRoute(
  171. builder: (_) => LocationScreen(
  172. titleName: "Tỉnh/Thành phố",
  173. type: LocationType.province,
  174. filterId: checkChangeLocation.currentCountry.id ?? -1,
  175. selectedId: checkChangeLocation.currentProvince.id ?? -1,
  176. ),
  177. fullscreenDialog: false))
  178. .then((value) {
  179. if (value != null) {
  180. var result = value as LocationUnit;
  181. checkChangeLocation.changeProvince(result);
  182. }
  183. });
  184. } else {
  185. Utils.showSnackBarWarning(message: label_country_empty);
  186. }
  187. },
  188. child: Container(
  189. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  190. decoration: const BoxDecoration(
  191. border: kBorderTextField,
  192. ),
  193. child: Row(
  194. children: [
  195. GetBuilder<ChangeSupply>(
  196. builder: (_) => Expanded(
  197. child: Text(checkChangeLocation.currentProvince.name ?? "Tỉnh/Thành Phố",
  198. style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
  199. const Icon(
  200. Icons.arrow_drop_down,
  201. color: Colors.grey,
  202. ),
  203. ],
  204. )));
  205. });
  206. }
  207. Widget _btnSelectDistrict() {
  208. return GetBuilder<CheckChangeAnotherDropdown>(builder: (data) {
  209. return FlatButton(
  210. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  211. onPressed: () {
  212. if (Get.isSnackbarOpen) Get.back();
  213. if (checkChangeLocation.currentProvince.id != null) {
  214. Navigator.of(context)
  215. .push(MaterialPageRoute(
  216. builder: (_) => LocationScreen(
  217. titleName: "Quận/Huyện",
  218. type: LocationType.district,
  219. filterId: checkChangeLocation.currentProvince.id ?? -1,
  220. selectedId: checkChangeLocation.currentDistrict.id ?? -1,
  221. ),
  222. fullscreenDialog: false))
  223. .then((value) {
  224. if (value != null) {
  225. var result = value as LocationUnit;
  226. checkChangeLocation.changeDistrict(result);
  227. }
  228. });
  229. } else {
  230. Utils.showSnackBarWarning(message: label_province_empty);
  231. }
  232. },
  233. child: Container(
  234. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  235. decoration: const BoxDecoration(
  236. border: kBorderTextField,
  237. ),
  238. child: Row(
  239. children: [
  240. GetBuilder<ChangeSupply>(
  241. builder: (_) => Expanded(
  242. child: Text(checkChangeLocation.currentDistrict.name ?? "Quận/Huyện",
  243. style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
  244. const Icon(
  245. Icons.arrow_drop_down,
  246. color: Colors.grey,
  247. ),
  248. ],
  249. )));
  250. });
  251. }
  252. Widget _btnSelectWard() {
  253. return GetBuilder<CheckChangeAnotherDropdown>(builder: (data) {
  254. return FlatButton(
  255. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  256. onPressed: () {
  257. if (Get.isSnackbarOpen) Get.back();
  258. if (checkChangeLocation.currentDistrict.id != null) {
  259. Navigator.of(context)
  260. .push(MaterialPageRoute(
  261. builder: (_) => LocationScreen(
  262. titleName: "Phường/Xã",
  263. type: LocationType.ward,
  264. filterId: checkChangeLocation.currentDistrict.id ?? -1,
  265. selectedId: checkChangeLocation.currentWard.id ?? -1,
  266. ),
  267. fullscreenDialog: false))
  268. .then((value) {
  269. if (value != null) {
  270. var result = value as LocationUnit;
  271. checkChangeLocation.changeWard(result);
  272. }
  273. });
  274. } else {
  275. Utils.showSnackBarWarning(message: label_district_empty);
  276. }
  277. },
  278. child: Container(
  279. padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  280. decoration: const BoxDecoration(
  281. border: kBorderTextField,
  282. ),
  283. child: Row(
  284. children: [
  285. GetBuilder<ChangeSupply>(
  286. builder: (_) => Expanded(
  287. child: Text(checkChangeLocation.currentWard.name ?? "Phường/Xã",
  288. style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
  289. const Icon(
  290. Icons.arrow_drop_down,
  291. color: Colors.grey,
  292. ),
  293. ],
  294. )));
  295. });
  296. }
  297. Widget _addressField() {
  298. return TextFormField(
  299. keyboardType: TextInputType.text,
  300. decoration: const InputDecoration(labelText: "Địa chỉ"),
  301. controller: _addressController,
  302. onSaved: (newValue) {
  303. _account.address = newValue ?? '';
  304. },
  305. );
  306. }
  307. @override
  308. Widget build(BuildContext context) => KeyboardDismisser(
  309. child: Scaffold(
  310. backgroundColor: Colors.white,
  311. appBar: AppBarWidget(
  312. isBack: true,
  313. action: InkWell(
  314. child: const Text(
  315. 'Huỷ',
  316. style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
  317. ),
  318. onTap: () {
  319. if (Get.isSnackbarOpen) Get.back();
  320. Get.back();
  321. },
  322. ),
  323. ),
  324. key: _scaffoldKey,
  325. body: _buildContent()));
  326. Widget _buildContent() {
  327. return StreamBuilder(
  328. stream: getAccountBloc.actions,
  329. builder: (context, AsyncSnapshot<dynamic> snapshot) {
  330. if (snapshot.hasData) {
  331. return Form(
  332. key: _formKey,
  333. // autovalidate: _autoValidate,
  334. child: SingleChildScrollView(
  335. padding: const EdgeInsets.all(8.0),
  336. child: Column(
  337. crossAxisAlignment: CrossAxisAlignment.start,
  338. children: <Widget>[
  339. const Text(
  340. 'Tài khoản',
  341. style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
  342. ),
  343. _userNameField(),
  344. const SizedBox(
  345. height: 8.0,
  346. ),
  347. _fullNameField(),
  348. const SizedBox(
  349. height: 8.0,
  350. ),
  351. _emailField(),
  352. const SizedBox(
  353. height: 8.0,
  354. ),
  355. Container(
  356. width: double.infinity,
  357. child: const Text(
  358. "Quốc gia",
  359. style: TextStyle(color: Colors.black54, fontSize: 13.0),
  360. ),
  361. ),
  362. _btnSelectCountry(),
  363. Container(
  364. width: double.infinity,
  365. child: const Text(
  366. "Tỉnh/Thành phố",
  367. style: TextStyle(color: Colors.black54, fontSize: 13.0),
  368. ),
  369. ),
  370. _btnSelectProvince(),
  371. Container(
  372. width: double.infinity,
  373. child: const Text(
  374. "Quận/Huyện",
  375. style: TextStyle(color: Colors.black54, fontSize: 13.0),
  376. ),
  377. ),
  378. _btnSelectDistrict(),
  379. Container(
  380. width: double.infinity,
  381. child: const Text(
  382. "Phường/Xã",
  383. style: TextStyle(color: Colors.black54, fontSize: 13.0),
  384. ),
  385. ),
  386. _btnSelectWard(),
  387. const SizedBox(
  388. height: 8.0,
  389. ),
  390. _addressField(),
  391. const SizedBox(
  392. height: 16.0,
  393. ),
  394. ButtonWidget(
  395. title: 'CẬP NHẬT',
  396. onPressed: () {
  397. var currentFocus = FocusScope.of(context);
  398. if (!currentFocus.hasPrimaryFocus) {
  399. currentFocus.unfocus();
  400. }
  401. _validateInputs();
  402. }),
  403. ],
  404. ),
  405. ));
  406. } else {
  407. return const Center(
  408. child: CircularProgressIndicator(),
  409. );
  410. }
  411. });
  412. }
  413. @override
  414. void dispose() {
  415. super.dispose();
  416. _userNameController.dispose();
  417. _emailController.dispose();
  418. _fullNameController.dispose();
  419. _addressController.dispose();
  420. }
  421. }