facility_booking_page.dart 7.3 KB

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