facility_booking_page.dart 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import 'dart:math';
  2. import 'package:cpt_facility/modules/location/facility_location_page.dart';
  3. import 'package:cs_resources/generated/assets.dart';
  4. import 'package:cs_resources/generated/l10n.dart';
  5. import 'package:cs_resources/theme/app_colors_theme.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:auto_route/auto_route.dart';
  8. import 'package:flutter_hooks/flutter_hooks.dart';
  9. import 'package:hooks_riverpod/hooks_riverpod.dart';
  10. import 'package:router/ext/auto_router_extensions.dart';
  11. import 'package:shared/utils/date_time_utils.dart';
  12. import 'package:shared/utils/log_utils.dart';
  13. import 'package:widgets/ext/ex_widget.dart';
  14. import 'package:widgets/load_state_layout.dart';
  15. import 'package:widgets/my_appbar.dart';
  16. import 'package:widgets/my_button.dart';
  17. import 'package:widgets/my_load_image.dart';
  18. import 'package:widgets/my_text_view.dart';
  19. import 'package:widgets/shatter/select_calendar/calendar_bottom_sheet.dart';
  20. import 'package:widgets/widget_export.dart';
  21. import '../../router/page/facility_page_router.dart';
  22. import 'facility_booking_view_model.dart';
  23. @RoutePage()
  24. class FacilityBookingPage extends HookConsumerWidget {
  25. const FacilityBookingPage({Key? key}) : super(key: key);
  26. //启动当前页面
  27. static void startInstance({BuildContext? context}) {
  28. if (context != null) {
  29. context.router.push(const FacilityBookingPageRoute());
  30. } else {
  31. appRouter.push(const FacilityBookingPageRoute());
  32. }
  33. }
  34. @override
  35. Widget build(BuildContext context, WidgetRef ref) {
  36. final viewModel = ref.watch(facilityBookingViewModelProvider.notifier);
  37. final state = ref.watch(facilityBookingViewModelProvider);
  38. useEffect(() {
  39. // 组件挂载时执行 - 执行接口请求
  40. Future.microtask(() => viewModel.fetchListByDate());
  41. return () {
  42. // 组件卸载时执行
  43. };
  44. }, []);
  45. return Scaffold(
  46. appBar: MyAppBar.appBar(context, "Kids party room", backgroundColor: context.appColors.backgroundWhite, actions: [
  47. //去设施小区的定位图片
  48. const MyAssetImage(
  49. Assets.facilityTitleLocationIcon,
  50. width: 44,
  51. height: 44,
  52. ).marginOnly(right: 3).onTap(() {
  53. FacilityLocationPage.startInstance(context: context, imageUrls: [
  54. "https://mz.eastday.com/63074197.jpeg",
  55. "https://t10.baidu.com/it/u=3562774827,189123978&fm=30&app=106&f=PNG?w=640&h=479&s=DFBA6EC80A72B7CC02FC011F0300D0C2",
  56. "https://img1.baidu.com/it/u=4090167392,148087489&fm=253&fmt=auto&app=138&f=JPEG?w=484&h=300"
  57. ]);
  58. }),
  59. ]),
  60. backgroundColor: context.appColors.backgroundDark,
  61. body: Column(
  62. mainAxisSize: MainAxisSize.max,
  63. crossAxisAlignment: CrossAxisAlignment.center,
  64. children: [
  65. //顶部的选中的日期与日历选择
  66. Row(
  67. mainAxisSize: MainAxisSize.max,
  68. children: [
  69. MyTextView(
  70. "${DateTimeUtils.getWeekday(state.selectedDate, languageCode: 'en')}, ${DateTimeUtils.formatDate(state.selectedDate, format: 'dd MMM yyyy')}",
  71. textColor: context.appColors.textBlack,
  72. fontSize: 17,
  73. marginTop: 18,
  74. marginBottom: 16,
  75. marginLeft: 15,
  76. isFontMedium: true,
  77. ).expanded(),
  78. const MyAssetImage(Assets.facilityConfirmDateIcon, width: 22.5, height: 22.5).marginOnly(right: 10).onTap(() {
  79. //日历日期选择器
  80. _datePickerBottomSheet(context, ref);
  81. }, padding: 5),
  82. ],
  83. ),
  84. //二周的日期选择
  85. WeeklyCalendar(
  86. selectedDate: state.selectedDate,
  87. onChangedSelectedDate: (dateTime) {
  88. Log.d("onChangedSelectedDate选中 - ${dateTime}}");
  89. viewModel.changeSelectedDate(dateTime);
  90. },
  91. ),
  92. //每天的单独数据
  93. LoadStateLayout(
  94. state: state.loadingState,
  95. errorMessage: state.errorMessage,
  96. errorRetry: () {
  97. viewModel.retryRequest();
  98. },
  99. successSliverWidget: [
  100. SliverToBoxAdapter(
  101. child: MyTextView(
  102. S.current.quota_left_msg(1, DateTimeUtils.formatDate(state.selectedDate, format: 'dd MMM yyyy')),
  103. marginTop: 7,
  104. marginBottom: 15,
  105. textColor: context.appColors.textBlack,
  106. fontSize: 12,
  107. isFontMedium: true,
  108. ),
  109. ),
  110. SliverList(
  111. delegate: SliverChildBuilderDelegate(
  112. (context, index) {
  113. return _buildFacilityOption(context, state.datas[index]);
  114. },
  115. childCount: state.datas.length,
  116. ))
  117. ],
  118. ).marginOnly(top: 5).expanded(),
  119. //底部按钮
  120. MyButton(
  121. onPressed: viewModel.gotoConfirmPage,
  122. text: S.current.next,
  123. textColor: Colors.white,
  124. backgroundColor: context.appColors.btnBgDefault,
  125. fontWeight: FontWeight.w500,
  126. type: ClickType.throttle,
  127. fontSize: 16,
  128. minHeight: 50,
  129. radius: 0,
  130. )
  131. ],
  132. ),
  133. );
  134. }
  135. //日期日历的选择器,底部弹窗选择
  136. void _datePickerBottomSheet(BuildContext context, WidgetRef ref) {
  137. final viewModel = ref.watch(facilityBookingViewModelProvider.notifier);
  138. final state = ref.watch(facilityBookingViewModelProvider);
  139. showModalBottomSheet<void>(
  140. context: context,
  141. isScrollControlled: true,
  142. shape: const RoundedRectangleBorder(
  143. borderRadius: BorderRadius.only(topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)),
  144. ),
  145. builder: (BuildContext context) {
  146. return CustomCalendarBottomSheet(
  147. firstDate: DateTime.now(),
  148. lastDate: DateTime.now().add(const Duration(days: 365)),
  149. selectedDate: state.selectedDate,
  150. locale: "en",
  151. onDateChange: (dateTime) {
  152. Navigator.pop(context);
  153. viewModel.changeSelectedDate(dateTime);
  154. },
  155. );
  156. },
  157. );
  158. }
  159. //生产当前设施的选项
  160. Widget _buildFacilityOption(BuildContext context, String item) {
  161. return Column(
  162. children: [
  163. Container(
  164. width: double.infinity,
  165. height: 38,
  166. color: context.appColors.btnBgDefault,
  167. child: Center(
  168. child: MyTextView(
  169. item,
  170. fontSize: 16,
  171. textColor: Colors.white,
  172. textAlign: TextAlign.center,
  173. isFontMedium: true,
  174. ),
  175. ),
  176. ),
  177. GridView.builder(
  178. shrinkWrap: true,
  179. physics: const NeverScrollableScrollPhysics(),
  180. gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
  181. crossAxisCount: 4,
  182. childAspectRatio: 82 / 43,
  183. mainAxisSpacing: 6.5,
  184. crossAxisSpacing: 6.5,
  185. ),
  186. itemCount: 4,
  187. itemBuilder: (context, index) {
  188. return Container(
  189. decoration: BoxDecoration(
  190. color: context.appColors.whiteBG,
  191. borderRadius: BorderRadius.circular(5.0),
  192. ),
  193. child: Column(
  194. crossAxisAlignment: CrossAxisAlignment.center,
  195. mainAxisAlignment: MainAxisAlignment.center, // 垂直居中
  196. children: [
  197. MyTextView(
  198. "10.00 AM",
  199. fontSize: 12,
  200. textColor: context.appColors.textBlack,
  201. isFontMedium: true,
  202. ),
  203. MyTextView(
  204. "04.00 PM",
  205. fontSize: 12,
  206. textColor: context.appColors.textBlack,
  207. isFontMedium: true,
  208. ),
  209. ],
  210. ),
  211. );
  212. },
  213. ).marginSymmetric(horizontal: 10, vertical: 17),
  214. ],
  215. );
  216. }
  217. }