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.

205 lines
7.4KB

  1. import 'package:farm_tpf/data/repository/repository.dart';
  2. import 'package:farm_tpf/presentation/custom_widgets/button/button_2_icon.dart';
  3. import 'package:farm_tpf/presentation/custom_widgets/button/second_button.dart';
  4. import 'package:farm_tpf/presentation/screens/codes/code_detail_page.dart';
  5. import 'package:farm_tpf/presentation/screens/codes/create_stamp_page.dart';
  6. import 'package:farm_tpf/presentation/screens/codes/models/stamp.dart';
  7. import 'package:farm_tpf/presentation/screens/codes/widgets/item_code.dart';
  8. import 'package:farm_tpf/presentation/screens/task/models/task_update_request.dart';
  9. import 'package:farm_tpf/themes/app_colors.dart';
  10. import 'package:farm_tpf/utils/const_common.dart';
  11. import 'package:flutter/cupertino.dart';
  12. import 'package:flutter/foundation.dart';
  13. import 'package:flutter/material.dart';
  14. import 'package:flutter_bloc/flutter_bloc.dart';
  15. import 'package:get/get.dart';
  16. import '../../../models/item_dropdown.dart';
  17. import '../../../themes/styles_text.dart';
  18. import '../../../utils/const_string.dart';
  19. import '../../../utils/helpers.dart';
  20. import '../../custom_widgets/bottom_loader.dart';
  21. import '../../custom_widgets/dropdown/multiple_select_bottom_sheet.dart';
  22. import '../../custom_widgets/loading_list_page.dart';
  23. import '../plot/widget_search.dart';
  24. import 'bloc/task_bloc.dart';
  25. import 'create_task_page.dart';
  26. import 'task_detail_page.dart';
  27. import 'widgets/task_item.dart';
  28. class TaskPage extends StatefulWidget {
  29. final int cropId;
  30. const TaskPage({super.key, required this.cropId});
  31. @override
  32. State<TaskPage> createState() => _TaskPageState();
  33. }
  34. class _TaskPageState extends State<TaskPage> {
  35. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  36. TaskBloc bloc = TaskBloc(Repository());
  37. final _scrollController = ScrollController();
  38. final _scrollThreshold = 250.0;
  39. @override
  40. void initState() {
  41. bloc.cropId = widget.cropId;
  42. bloc.add(DataFetched());
  43. _scrollController.addListener(() {
  44. if (bloc.isFetching) return;
  45. final maxScroll = _scrollController.position.maxScrollExtent;
  46. final currentScroll = _scrollController.position.pixels;
  47. if (maxScroll - currentScroll < _scrollThreshold) {
  48. bloc.add(DataFetched());
  49. }
  50. });
  51. super.initState();
  52. }
  53. @override
  54. void dispose() {
  55. _scrollController.dispose();
  56. super.dispose();
  57. }
  58. @override
  59. Widget build(BuildContext context) {
  60. return Scaffold(
  61. backgroundColor: Colors.white,
  62. key: _scaffoldKey,
  63. body: SafeArea(
  64. child: Column(
  65. crossAxisAlignment: CrossAxisAlignment.start,
  66. children: <Widget>[
  67. Row(
  68. children: [
  69. ValueListenableBuilder<String>(
  70. valueListenable: bloc.sort,
  71. builder: (context, sort, _) {
  72. return Button2Icon(
  73. leftIcon: (sort == describeEnum(SortType.asc)) ? CupertinoIcons.arrow_up : CupertinoIcons.arrow_down,
  74. title: 'Hoàn thành',
  75. onPressed: () {
  76. if (sort == describeEnum(SortType.asc)) {
  77. bloc.sort.value = describeEnum(SortType.desc);
  78. } else {
  79. bloc.sort.value = describeEnum(SortType.asc);
  80. }
  81. bloc.sort.notifyListeners();
  82. bloc.add(OnRefresh());
  83. },
  84. );
  85. },
  86. ),
  87. ValueListenableBuilder<List<ItemDropDown>>(
  88. valueListenable: bloc.selectedStatus,
  89. builder: (context, selecteds, _) {
  90. return ValueListenableBuilder<List<ItemDropDown>>(
  91. valueListenable: bloc.status,
  92. builder: (context, status, _) {
  93. return MultipleSelectBottomSheet(
  94. dataSources: status,
  95. initValue: selecteds,
  96. onSelected: (val) {
  97. bloc.selectedStatus.value = val;
  98. Helpers.hideKeyboard(context);
  99. bloc.add(OnRefresh());
  100. },
  101. hint: 'Trạng thái',
  102. );
  103. },
  104. );
  105. },
  106. ),
  107. const Spacer(),
  108. SecondButton(
  109. onPressed: () {
  110. Get.to(() => CreateTaskPage(
  111. cropId: widget.cropId,
  112. ))?.then((value) {
  113. if (value != null) {
  114. bloc.add(OnRefresh());
  115. }
  116. });
  117. },
  118. title: 'Thêm',
  119. leftIcon: CupertinoIcons.add,
  120. color: AppColors.primary1,
  121. textColor: Colors.white,
  122. borderColor: AppColors.primary1,
  123. ),
  124. ],
  125. ),
  126. const SizedBox(
  127. height: 4,
  128. ),
  129. Expanded(
  130. child: mainBody(),
  131. ),
  132. ],
  133. ),
  134. ),
  135. );
  136. }
  137. Widget mainBody() {
  138. return BlocBuilder<TaskBloc, TaskState>(
  139. bloc: bloc,
  140. builder: (context, state) {
  141. if (state is TaskFailure) {
  142. return Center(child: Text(state.errorString));
  143. }
  144. if (state is TaskSuccess) {
  145. if ((state.items ?? []).isEmpty) {
  146. return Center(child: Text(label_list_empty));
  147. }
  148. return RefreshIndicator(
  149. child: ListView.builder(
  150. physics: AlwaysScrollableScrollPhysics(),
  151. itemBuilder: (BuildContext context, int index) {
  152. print('index: $index');
  153. print('state.items: ${state.items?.length}');
  154. return index >= (state.items ?? []).length
  155. ? BottomLoader()
  156. : ItemTask(
  157. item: state.items?[index],
  158. onPressed: () {
  159. Get.to(
  160. () => TaskDetailPage(
  161. taskId: state.items?[index].id,
  162. ),
  163. )?.then((value) {
  164. if (value != null) {
  165. bloc.add(OnRefresh());
  166. }
  167. });
  168. },
  169. onChangedStatus: (status) {
  170. bloc.updateStatusTask(
  171. RequestTaskUpdate(
  172. id: state.items?[index].id,
  173. completed: status,
  174. ),
  175. onSuccess: () {
  176. bloc.add(OnRefresh());
  177. },
  178. );
  179. },
  180. );
  181. },
  182. itemCount: (state.hasReachedMax ?? false) ? (state.items ?? []).length : (state.items ?? []).length + 1,
  183. controller: _scrollController,
  184. ),
  185. onRefresh: () async {
  186. bloc.add(OnRefresh());
  187. });
  188. }
  189. return Center(
  190. child: LoadingListPage(),
  191. );
  192. },
  193. );
  194. }
  195. }