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.

202 lines
6.4KB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:farm_tpf/models/item_dropdown.dart';
  3. import 'package:farm_tpf/presentation/screens/codes/models/stamp_type.dart';
  4. import 'package:farm_tpf/presentation/screens/codes/widgets/item_column.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/scheduler.dart';
  7. import 'package:flutter/services.dart';
  8. import 'package:flutter/src/widgets/framework.dart';
  9. import 'package:flutter/src/widgets/placeholder.dart';
  10. import 'package:flutter_bloc/flutter_bloc.dart';
  11. import 'package:get/get.dart';
  12. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  13. import '../../../utils/utils.dart';
  14. import '../../custom_widgets/app_bar_widget.dart';
  15. import '../../custom_widgets/button_widget.dart';
  16. import '../../custom_widgets/date_picker/date_picker_widget.dart';
  17. import '../../custom_widgets/dropdown/dropdown_bottom_sheet.dart';
  18. import '../../custom_widgets/textfield/text_field_normal.dart';
  19. import 'cubit/create_stamp_cubit.dart';
  20. class CreateStampPage extends StatefulWidget {
  21. const CreateStampPage({
  22. super.key,
  23. });
  24. @override
  25. State<CreateStampPage> createState() => _CreateStampPageState();
  26. }
  27. class _CreateStampPageState extends State<CreateStampPage> {
  28. final bloc = CreateStampCubit();
  29. @override
  30. void initState() {
  31. super.initState();
  32. bloc.preparedData();
  33. }
  34. @override
  35. void dispose() {
  36. bloc.dispose();
  37. super.dispose();
  38. }
  39. @override
  40. Widget build(BuildContext context) {
  41. return Scaffold(
  42. appBar: AppBarWidget(),
  43. body: BlocListener<CreateStampCubit, CreateStampState>(
  44. bloc: bloc,
  45. listener: ((context, state) {
  46. if (state is CreateStampLoading) {
  47. SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
  48. UtilWidget.showLoading();
  49. });
  50. } else if (state is CreateStampFailure) {
  51. SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
  52. UtilWidget.hideLoading();
  53. // UtilWidget.showToastError(state.errorMessage);
  54. });
  55. } else if (state is CreateStampPrepareDataSuccessful) {
  56. SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
  57. UtilWidget.hideLoading();
  58. });
  59. }
  60. }),
  61. child: KeyboardDismisser(
  62. child: Container(
  63. child: Form(
  64. key: bloc.formKey,
  65. child: Column(
  66. children: [
  67. Expanded(
  68. child: _widgetBody(),
  69. ),
  70. Padding(
  71. padding: const EdgeInsets.all(8.0),
  72. child: ButtonWidget(
  73. title: 'Cập nhật',
  74. onPressed: () {
  75. bloc.onSubmit();
  76. },
  77. ),
  78. ),
  79. ],
  80. ),
  81. ),
  82. ),
  83. ),
  84. ),
  85. );
  86. }
  87. Widget _widgetBody() {
  88. return Container(
  89. padding: const EdgeInsets.all(16),
  90. child: SingleChildScrollView(
  91. child: Column(
  92. crossAxisAlignment: CrossAxisAlignment.start,
  93. children: [
  94. ItemColumnWidget(
  95. title: 'Mô tả',
  96. child: TextFieldNormal(
  97. controller: bloc.descriptionCtl,
  98. maxLines: 1,
  99. hint: 'Mô tả',
  100. ),
  101. ),
  102. const SizedBox(
  103. height: 8,
  104. ),
  105. ItemColumnWidget(
  106. title: 'Số lượng tem',
  107. child: TextFieldNormal(
  108. controller: bloc.quantityCtl,
  109. maxLines: 1,
  110. hint: 'Số lượng tem',
  111. ),
  112. ),
  113. const SizedBox(
  114. height: 8,
  115. ),
  116. ItemColumnWidget(
  117. title: 'Hạn sử dụng (ngày)',
  118. child: TextFieldNormal(
  119. controller: bloc.expiredDateCtl,
  120. maxLines: 1,
  121. keyboardType: TextInputType.number,
  122. inputFormatters: [
  123. FilteringTextInputFormatter.digitsOnly,
  124. ],
  125. hint: 'Hạn sử dụng (ngày)',
  126. ),
  127. ),
  128. const SizedBox(
  129. height: 8,
  130. ),
  131. ItemColumnWidget(
  132. title: 'Mẫu tem',
  133. child: ValueListenableBuilder<String>(
  134. valueListenable: bloc.selectedStampType,
  135. builder: (context, selected, _) {
  136. return ValueListenableBuilder<List<ItemDropDown>>(
  137. valueListenable: bloc.stampTypes,
  138. builder: (context, types, _) {
  139. return DropdownBottomSheet(
  140. dataSources: types,
  141. initValue: selected,
  142. onSelected: (val) {
  143. bloc.selectedStampType.value = val.key ?? '';
  144. },
  145. hint: 'Mẫu tem',
  146. );
  147. },
  148. );
  149. },
  150. ),
  151. ),
  152. const SizedBox(
  153. height: 8,
  154. ),
  155. ValueListenableBuilder<String>(
  156. valueListenable: bloc.selectedStampType,
  157. builder: (context, selected, _) {
  158. if (selected.isEmpty) {
  159. return const SizedBox.shrink();
  160. }
  161. var stamp = bloc.stampTypeRaws.firstWhere(
  162. (e) => selected == e.id?.toString(),
  163. orElse: () => StampType(),
  164. );
  165. return Container(
  166. child: CachedNetworkImage(
  167. imageUrl: stamp.exampleStampImage ?? '',
  168. width: Get.width,
  169. height: Get.width / 2,
  170. fit: BoxFit.contain,
  171. placeholder: (context, url) => Icon(
  172. Icons.image,
  173. size: 100,
  174. color: Colors.grey[200],
  175. ),
  176. errorWidget: (context, url, _) => Icon(
  177. Icons.image_not_supported,
  178. size: 100,
  179. color: Colors.grey[200],
  180. ),
  181. ),
  182. );
  183. },
  184. ),
  185. const SizedBox(
  186. height: 16,
  187. ),
  188. ],
  189. ),
  190. ),
  191. );
  192. }
  193. }