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.

195 lines
6.8KB

  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/themes/app_colors.dart';
  9. import 'package:farm_tpf/utils/const_common.dart';
  10. import 'package:flutter/cupertino.dart';
  11. import 'package:flutter/foundation.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:flutter_bloc/flutter_bloc.dart';
  14. import 'package:get/get.dart';
  15. import '../../../models/item_dropdown.dart';
  16. import '../../../themes/styles_text.dart';
  17. import '../../../utils/const_string.dart';
  18. import '../../../utils/helpers.dart';
  19. import '../../custom_widgets/bottom_loader.dart';
  20. import '../../custom_widgets/dropdown/multiple_select_bottom_sheet.dart';
  21. import '../../custom_widgets/loading_list_page.dart';
  22. import '../plot/widget_search.dart';
  23. import 'bloc/stamp_bloc.dart';
  24. class CodePage extends StatefulWidget {
  25. const CodePage({super.key});
  26. @override
  27. State<CodePage> createState() => _CodePageState();
  28. }
  29. class _CodePageState extends State<CodePage> {
  30. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  31. StampBloc bloc = StampBloc(Repository());
  32. final _scrollController = ScrollController();
  33. final _scrollThreshold = 250.0;
  34. @override
  35. void initState() {
  36. bloc.add(DataFetched());
  37. _scrollController.addListener(() {
  38. final maxScroll = _scrollController.position.maxScrollExtent;
  39. final currentScroll = _scrollController.position.pixels;
  40. if (maxScroll - currentScroll < _scrollThreshold) {
  41. bloc.add(DataFetched());
  42. }
  43. });
  44. super.initState();
  45. }
  46. @override
  47. void dispose() {
  48. _scrollController.dispose();
  49. super.dispose();
  50. }
  51. @override
  52. Widget build(BuildContext context) {
  53. return Scaffold(
  54. backgroundColor: Colors.white,
  55. key: _scaffoldKey,
  56. body: SafeArea(
  57. child: Column(
  58. crossAxisAlignment: CrossAxisAlignment.start,
  59. children: <Widget>[
  60. SizedBox(
  61. height: 8,
  62. ),
  63. Container(
  64. padding: EdgeInsets.all(8),
  65. color: Colors.white,
  66. child: Text(
  67. 'Danh sách tem',
  68. style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
  69. ),
  70. ),
  71. WidgetSearch(
  72. searchController: bloc.searchCtl,
  73. onPressed: (value) {
  74. Helpers.hideKeyboard(context);
  75. bloc.add(OnRefresh());
  76. },
  77. ),
  78. Row(
  79. children: [
  80. ValueListenableBuilder<String>(
  81. valueListenable: bloc.sort,
  82. builder: (context, sort, _) {
  83. return Button2Icon(
  84. leftIcon: (sort == describeEnum(SortType.asc)) ? CupertinoIcons.arrow_up : CupertinoIcons.arrow_down,
  85. title: 'Ngày tạo',
  86. onPressed: () {
  87. if (sort == describeEnum(SortType.asc)) {
  88. bloc.sort.value = describeEnum(SortType.desc);
  89. } else {
  90. bloc.sort.value = describeEnum(SortType.asc);
  91. }
  92. bloc.sort.notifyListeners();
  93. bloc.add(OnRefresh());
  94. },
  95. );
  96. },
  97. ),
  98. ValueListenableBuilder<List<ItemDropDown>>(
  99. valueListenable: bloc.selectedStatus,
  100. builder: (context, selecteds, _) {
  101. return ValueListenableBuilder<List<ItemDropDown>>(
  102. valueListenable: bloc.status,
  103. builder: (context, status, _) {
  104. return MultipleSelectBottomSheet(
  105. dataSources: status,
  106. initValue: selecteds,
  107. onSelected: (val) {
  108. bloc.selectedStatus.value = val;
  109. Helpers.hideKeyboard(context);
  110. bloc.add(OnRefresh());
  111. },
  112. hint: 'Trạng thái',
  113. );
  114. },
  115. );
  116. },
  117. ),
  118. const Spacer(),
  119. SecondButton(
  120. onPressed: () {
  121. Get.to(() => CreateStampPage())?.then((value) {
  122. if (value != null) {
  123. bloc.add(OnRefresh());
  124. }
  125. });
  126. },
  127. title: 'Tạo tem',
  128. leftIcon: CupertinoIcons.add,
  129. color: AppColors.primary1,
  130. textColor: Colors.white,
  131. borderColor: AppColors.primary1,
  132. ),
  133. ],
  134. ),
  135. Expanded(
  136. child: mainBody(),
  137. ),
  138. ],
  139. ),
  140. ),
  141. );
  142. }
  143. Widget mainBody() {
  144. return BlocBuilder<StampBloc, StampState>(
  145. bloc: bloc,
  146. builder: (context, state) {
  147. if (state is StampFailure) {
  148. return Center(child: Text(state.errorString));
  149. }
  150. if (state is StampSuccess) {
  151. if ((state.items ?? []).isEmpty) {
  152. return Center(child: Text(label_list_empty));
  153. }
  154. return RefreshIndicator(
  155. child: ListView.builder(
  156. physics: AlwaysScrollableScrollPhysics(),
  157. itemBuilder: (BuildContext context, int index) {
  158. return index >= (state.items ?? []).length
  159. ? BottomLoader()
  160. : ItemCode(
  161. item: state.items?[index],
  162. onPressed: () {
  163. Get.to(
  164. () => CodeDetailPage(
  165. stampId: state.items?[index].id,
  166. stampCode: state.items?[index].code,
  167. ),
  168. );
  169. },
  170. );
  171. },
  172. itemCount: (state.hasReachedMax ?? false) ? (state.items ?? []).length : (state.items ?? []).length + 1,
  173. controller: _scrollController,
  174. ),
  175. onRefresh: () async {
  176. bloc.add(OnRefresh());
  177. });
  178. }
  179. return Center(
  180. child: LoadingListPage(),
  181. );
  182. },
  183. );
  184. }
  185. }