| CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | ||||
| CODE_SIGN_IDENTITY = "Apple Development"; | CODE_SIGN_IDENTITY = "Apple Development"; | ||||
| CODE_SIGN_STYLE = Automatic; | CODE_SIGN_STYLE = Automatic; | ||||
| CURRENT_PROJECT_VERSION = 29; | |||||
| CURRENT_PROJECT_VERSION = 30; | |||||
| DEVELOPMENT_TEAM = C3DTD2JH94; | DEVELOPMENT_TEAM = C3DTD2JH94; | ||||
| ENABLE_BITCODE = NO; | ENABLE_BITCODE = NO; | ||||
| FRAMEWORK_SEARCH_PATHS = ( | FRAMEWORK_SEARCH_PATHS = ( | ||||
| "$(inherited)", | "$(inherited)", | ||||
| "$(PROJECT_DIR)/Flutter", | "$(PROJECT_DIR)/Flutter", | ||||
| ); | ); | ||||
| MARKETING_VERSION = 1.1.10; | |||||
| MARKETING_VERSION = 1.1.11; | |||||
| PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.farmdemo; | PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.farmdemo; | ||||
| PRODUCT_NAME = "$(TARGET_NAME)"; | PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| PROVISIONING_PROFILE_SPECIFIER = ""; | PROVISIONING_PROFILE_SPECIFIER = ""; | ||||
| CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | ||||
| CODE_SIGN_IDENTITY = "Apple Development"; | CODE_SIGN_IDENTITY = "Apple Development"; | ||||
| CODE_SIGN_STYLE = Automatic; | CODE_SIGN_STYLE = Automatic; | ||||
| CURRENT_PROJECT_VERSION = 29; | |||||
| CURRENT_PROJECT_VERSION = 30; | |||||
| DEVELOPMENT_TEAM = C3DTD2JH94; | DEVELOPMENT_TEAM = C3DTD2JH94; | ||||
| ENABLE_BITCODE = NO; | ENABLE_BITCODE = NO; | ||||
| FRAMEWORK_SEARCH_PATHS = ( | FRAMEWORK_SEARCH_PATHS = ( | ||||
| "$(inherited)", | "$(inherited)", | ||||
| "$(PROJECT_DIR)/Flutter", | "$(PROJECT_DIR)/Flutter", | ||||
| ); | ); | ||||
| MARKETING_VERSION = 1.1.10; | |||||
| MARKETING_VERSION = 1.1.11; | |||||
| PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.farmdemo; | PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.farmdemo; | ||||
| PRODUCT_NAME = "$(TARGET_NAME)"; | PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| PROVISIONING_PROFILE_SPECIFIER = ""; | PROVISIONING_PROFILE_SPECIFIER = ""; | ||||
| CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; | ||||
| CODE_SIGN_IDENTITY = "Apple Development"; | CODE_SIGN_IDENTITY = "Apple Development"; | ||||
| CODE_SIGN_STYLE = Automatic; | CODE_SIGN_STYLE = Automatic; | ||||
| CURRENT_PROJECT_VERSION = 29; | |||||
| CURRENT_PROJECT_VERSION = 30; | |||||
| DEVELOPMENT_TEAM = C3DTD2JH94; | DEVELOPMENT_TEAM = C3DTD2JH94; | ||||
| ENABLE_BITCODE = NO; | ENABLE_BITCODE = NO; | ||||
| FRAMEWORK_SEARCH_PATHS = ( | FRAMEWORK_SEARCH_PATHS = ( | ||||
| "$(inherited)", | "$(inherited)", | ||||
| "$(PROJECT_DIR)/Flutter", | "$(PROJECT_DIR)/Flutter", | ||||
| ); | ); | ||||
| MARKETING_VERSION = 1.1.10; | |||||
| MARKETING_VERSION = 1.1.11; | |||||
| PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.farmdemo; | PRODUCT_BUNDLE_IDENTIFIER = vn.azteam.farmdemo; | ||||
| PRODUCT_NAME = "$(TARGET_NAME)"; | PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| PROVISIONING_PROFILE_SPECIFIER = ""; | PROVISIONING_PROFILE_SPECIFIER = ""; |
| String? sendDate; | String? sendDate; | ||||
| int? isRead; | int? isRead; | ||||
| String? type; | String? type; | ||||
| String? activityTypeName; | |||||
| int? activityTypeId; | |||||
| NotificationDTO({ | NotificationDTO({ | ||||
| this.id, | this.id, | ||||
| this.sendDate, | this.sendDate, | ||||
| this.type, | this.type, | ||||
| this.isRead, | this.isRead, | ||||
| this.activityTypeName, | |||||
| this.activityTypeId, | |||||
| }); | }); | ||||
| NotificationDTO.clone(NotificationDTO noti) { | NotificationDTO.clone(NotificationDTO noti) { | ||||
| this.id = noti.id; | this.id = noti.id; | ||||
| this.sendDate = noti.sendDate; | this.sendDate = noti.sendDate; | ||||
| this.type = noti.type; | this.type = noti.type; | ||||
| this.isRead = noti.isRead; | this.isRead = noti.isRead; | ||||
| this.activityTypeName = noti.activityTypeName; | |||||
| this.activityTypeId = noti.activityTypeId; | |||||
| } | } | ||||
| NotificationDTO.fromJson(Map<String, dynamic> json) { | NotificationDTO.fromJson(Map<String, dynamic> json) { | ||||
| id = json['id']; | id = json['id']; | ||||
| sendDate = json['sendDate']; | sendDate = json['sendDate']; | ||||
| type = json['type']; | type = json['type']; | ||||
| isRead = json['isRead']; | isRead = json['isRead']; | ||||
| activityTypeName = json['activityTypeName']; | |||||
| activityTypeId = json['activityTypeId']; | |||||
| } | } | ||||
| Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
| data['sendDate'] = this.sendDate; | data['sendDate'] = this.sendDate; | ||||
| data['type'] = this.type; | data['type'] = this.type; | ||||
| data['isRead'] = this.isRead; | data['isRead'] = this.isRead; | ||||
| data['activityTypeName'] = this.activityTypeName; | |||||
| data['activityTypeId'] = this.activityTypeId; | |||||
| return data; | return data; | ||||
| } | } | ||||
| } | } |
| } | } | ||||
| } | } | ||||
| Future<List<Employee>> getEmployeesByCropId(int cropId) async { | |||||
| try { | |||||
| var url = '${ConstCommon.baseUrl}/api/get-all-users-by-crop-id/$cropId'; | |||||
| var res = await dio.get( | |||||
| url, | |||||
| ); | |||||
| return (res.data as List).map((e) => Employee.fromJson(e)).toList(); | |||||
| } catch (e) { | |||||
| rethrow; | |||||
| } | |||||
| } | |||||
| Future<List<SupplyFilter>> getSuppliesFilter() async { | Future<List<SupplyFilter>> getSuppliesFilter() async { | ||||
| try { | try { | ||||
| var url = '${ConstCommon.baseUrl}/api/tb-supplies/by-login-info/'; | var url = '${ConstCommon.baseUrl}/api/tb-supplies/by-login-info/'; |
| import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
| import 'package:farm_tpf/utils/formatter.dart'; | import 'package:farm_tpf/utils/formatter.dart'; | ||||
| import 'package:flutter_svg/svg.dart'; | import 'package:flutter_svg/svg.dart'; | ||||
| import 'package:get/get.dart'; | |||||
| import '../actions/sc_action.dart'; | |||||
| import 'bloc/noti_bloc.dart'; | import 'bloc/noti_bloc.dart'; | ||||
| class NotificationScreen extends StatefulWidget { | class NotificationScreen extends StatefulWidget { | ||||
| currentReachedMax: currentReachedMax); | currentReachedMax: currentReachedMax); | ||||
| } | } | ||||
| }); | }); | ||||
| } else if (item.contents == 'ACTIVITY_CREATE' || item.contents == 'ACTIVITY_UPDATE') { | |||||
| Get.to(ActionScreen( | |||||
| isEdit: true, | |||||
| cropId: item.tbCropId ?? -1, | |||||
| activityId: item.externalId ?? -1, | |||||
| activityType: item.activityTypeName ?? '', | |||||
| title: 'ActionScreen', | |||||
| idAction: item.activityTypeId ?? -1, | |||||
| )); | |||||
| } else {} | } else {} | ||||
| }), | }), | ||||
| Container(padding: EdgeInsets.only(left: 16, right: 16), child: DashLineWidget()) | Container(padding: EdgeInsets.only(left: 16, right: 16), child: DashLineWidget()) |
| child: Column( | child: Column( | ||||
| crossAxisAlignment: CrossAxisAlignment.start, | crossAxisAlignment: CrossAxisAlignment.start, | ||||
| children: [ | children: [ | ||||
| // ItemColumnWidget( | |||||
| // title: 'Giao việc cho', | |||||
| // child: ValueListenableBuilder<String>( | |||||
| // valueListenable: bloc.selectedPEmployee, | |||||
| // builder: (context, selected, _) { | |||||
| // return ValueListenableBuilder<List<ItemDropDown>>( | |||||
| // valueListenable: bloc.employees, | |||||
| // builder: (context, employees, _) { | |||||
| // return DropdownBottomSheet( | |||||
| // dataSources: employees, | |||||
| // initValue: selected, | |||||
| // onSelected: (val) { | |||||
| // bloc.selectedPEmployee.value = val.key ?? ''; | |||||
| // }, | |||||
| // hint: 'Giao việc cho', | |||||
| // ); | |||||
| // }, | |||||
| // ); | |||||
| // }, | |||||
| // ), | |||||
| // ), | |||||
| // const SizedBox( | |||||
| // height: 8, | |||||
| // ), | |||||
| ItemColumnWidget( | |||||
| title: 'Giao việc cho', | |||||
| child: ValueListenableBuilder<String>( | |||||
| valueListenable: bloc.selectedPEmployee, | |||||
| builder: (context, selected, _) { | |||||
| return ValueListenableBuilder<List<ItemDropDown>>( | |||||
| valueListenable: bloc.employees, | |||||
| builder: (context, employees, _) { | |||||
| return DropdownBottomSheet( | |||||
| dataSources: employees, | |||||
| initValue: selected, | |||||
| onSelected: (val) { | |||||
| bloc.selectedPEmployee.value = val.key ?? ''; | |||||
| }, | |||||
| hint: 'Giao việc cho', | |||||
| ); | |||||
| }, | |||||
| ); | |||||
| }, | |||||
| ), | |||||
| ), | |||||
| const SizedBox( | |||||
| height: 8, | |||||
| ), | |||||
| ItemColumnWidget( | ItemColumnWidget( | ||||
| title: 'Tiêu đề', | title: 'Tiêu đề', | ||||
| child: TextFieldNormal( | child: TextFieldNormal( |
| final detailCtl = TextEditingController(); | final detailCtl = TextEditingController(); | ||||
| var deadline = ValueNotifier(DateTime.now()); | var deadline = ValueNotifier(DateTime.now()); | ||||
| // var employeeRaws = <Employee>[]; | |||||
| // var employees = ValueNotifier(<ItemDropDown>[]); | |||||
| // var selectedPEmployee = ValueNotifier(''); | |||||
| var employeeRaws = <Employee>[]; | |||||
| var employees = ValueNotifier(<ItemDropDown>[]); | |||||
| var selectedPEmployee = ValueNotifier(''); | |||||
| // var existedCreateTask = UpdateCreateTask(); | // var existedCreateTask = UpdateCreateTask(); | ||||
| void dispose() { | void dispose() { | ||||
| } | } | ||||
| Future<void> preparedData({required int cropId}) async { | Future<void> preparedData({required int cropId}) async { | ||||
| // try { | |||||
| // await Future.delayed(const Duration(seconds: 0)); | |||||
| // emit(CreateTaskLoading()); | |||||
| try { | |||||
| await Future.delayed(const Duration(seconds: 0)); | |||||
| emit(CreateTaskLoading()); | |||||
| // employeeRaws = await repository.getEmployees(); | |||||
| // employees.value = employeeRaws | |||||
| // .map( | |||||
| // (e) => ItemDropDown(key: e.id?.toString(), value: e.name), | |||||
| // ) | |||||
| // .toList(); | |||||
| // emit(CreateTaskPrepareDataSuccessful()); | |||||
| // } catch (e) { | |||||
| // emit(CreateTaskFailure(AppException.handleError(e))); | |||||
| // } | |||||
| employeeRaws = await repository.getEmployeesByCropId(cropId); | |||||
| employees.value = employeeRaws | |||||
| .map( | |||||
| (e) => ItemDropDown(key: e.id?.toString(), value: e.name), | |||||
| ) | |||||
| .toList(); | |||||
| emit(CreateTaskPrepareDataSuccessful()); | |||||
| } catch (e) { | |||||
| emit(CreateTaskFailure(AppException.handleError(e))); | |||||
| } | |||||
| } | } | ||||
| Future<void> onSubmit(int cropId) async { | Future<void> onSubmit(int cropId) async { | ||||
| if (formKey.currentState!.validate()) { | if (formKey.currentState!.validate()) { | ||||
| // if (selectedPEmployee.value.isEmpty) { | |||||
| // Utils.showSnackBarWarning(message: 'Vui lòng chọn nhân viên'); | |||||
| // return; | |||||
| // } | |||||
| if (selectedPEmployee.value.isEmpty) { | |||||
| Utils.showSnackBarWarning(message: 'Vui lòng chọn nhân viên'); | |||||
| return; | |||||
| } | |||||
| if (titleNameCtl.text.trim().isEmpty) { | if (titleNameCtl.text.trim().isEmpty) { | ||||
| Utils.showSnackBarWarning(message: 'Vui lòng nhập tiêu đề'); | Utils.showSnackBarWarning(message: 'Vui lòng nhập tiêu đề'); | ||||
| return; | return; | ||||
| ..cropId = cropId | ..cropId = cropId | ||||
| ..title = titleNameCtl.text | ..title = titleNameCtl.text | ||||
| ..detail = detailCtl.text | ..detail = detailCtl.text | ||||
| // ..userAssignedId = int.tryParse(selectedPEmployee.value) | |||||
| ..userAssignedId = int.tryParse(selectedPEmployee.value) | |||||
| ..deadline = deadline.value.convertLocalDateTimeToStringUtcDateTime(); | ..deadline = deadline.value.convertLocalDateTimeToStringUtcDateTime(); | ||||
| print(requestTask.toJson()); | print(requestTask.toJson()); | ||||
| UtilWidget.showLoading(); | UtilWidget.showLoading(); |
| import 'package:bloc/bloc.dart'; | import 'package:bloc/bloc.dart'; | ||||
| import 'package:equatable/equatable.dart'; | import 'package:equatable/equatable.dart'; | ||||
| import 'package:flutter/material.dart'; | |||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||
| import '../../../../data/api/app_exception.dart'; | import '../../../../data/api/app_exception.dart'; | ||||
| class TaskDetailCubit extends Cubit<TaskDetailState> { | class TaskDetailCubit extends Cubit<TaskDetailState> { | ||||
| final repository = Repository(); | final repository = Repository(); | ||||
| TaskDetailCubit() : super(TaskDetailInitial()); | TaskDetailCubit() : super(TaskDetailInitial()); | ||||
| final detailCtl = TextEditingController(); | |||||
| var isCompleted = ValueNotifier(true); | |||||
| void dispose() { | |||||
| detailCtl.dispose(); | |||||
| } | |||||
| Future<void> preparedData(int taskId) async { | Future<void> preparedData(int taskId) async { | ||||
| try { | try { | ||||
| await Future.delayed(const Duration(seconds: 0)); | await Future.delayed(const Duration(seconds: 0)); | ||||
| emit(TaskDetailLoading()); | emit(TaskDetailLoading()); | ||||
| var task = await repository.getTaskDetail(id: taskId); | var task = await repository.getTaskDetail(id: taskId); | ||||
| detailCtl.text = task.completedDetail ?? ''; | |||||
| isCompleted.value = task.isCompleted ?? false; | |||||
| isCompleted.notifyListeners(); | |||||
| emit(TaskDetailSuccessful(task)); | emit(TaskDetailSuccessful(task)); | ||||
| } catch (e) { | } catch (e) { | ||||
| emit(TaskDetailFailure(AppException.handleError(e))); | emit(TaskDetailFailure(AppException.handleError(e))); |
| String? executeDate; | String? executeDate; | ||||
| Assigned? assigned; | Assigned? assigned; | ||||
| bool? isCompleted; | bool? isCompleted; | ||||
| String? completedDetail; | |||||
| Task({ | Task({ | ||||
| this.id, | this.id, | ||||
| this.executeDate, | this.executeDate, | ||||
| this.assigned, | this.assigned, | ||||
| this.isCompleted, | this.isCompleted, | ||||
| this.completedDetail, | |||||
| }); | }); | ||||
| Task.fromJson(Map<String, dynamic> json) { | Task.fromJson(Map<String, dynamic> json) { | ||||
| executeDate = json['completedAt']; | executeDate = json['completedAt']; | ||||
| assigned = json['assigned'] != null ? new Assigned.fromJson(json['assigned']) : null; | assigned = json['assigned'] != null ? new Assigned.fromJson(json['assigned']) : null; | ||||
| isCompleted = json['completed']; | isCompleted = json['completed']; | ||||
| completedDetail = json['completedDetail']; | |||||
| } | } | ||||
| Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
| data['assigned'] = this.assigned?.toJson(); | data['assigned'] = this.assigned?.toJson(); | ||||
| } | } | ||||
| data['completed'] = this.isCompleted; | data['completed'] = this.isCompleted; | ||||
| data['completedDetail'] = this.completedDetail; | |||||
| return data; | return data; | ||||
| } | } | ||||
| this.executeDate = task.executeDate; | this.executeDate = task.executeDate; | ||||
| this.assigned = task.assigned; | this.assigned = task.assigned; | ||||
| this.isCompleted = task.isCompleted; | this.isCompleted = task.isCompleted; | ||||
| this.completedDetail = task.completedDetail; | |||||
| } | } | ||||
| } | } | ||||
| String? title; | String? title; | ||||
| String? detail; | String? detail; | ||||
| String? deadline; | String? deadline; | ||||
| // int? userAssignedId; | |||||
| int? userAssignedId; | |||||
| int? cropId; | int? cropId; | ||||
| RequestTask({ | RequestTask({ | ||||
| this.title, | this.title, | ||||
| this.detail, | this.detail, | ||||
| this.deadline, | this.deadline, | ||||
| // this.userAssignedId, | |||||
| this.userAssignedId, | |||||
| this.cropId, | this.cropId, | ||||
| }); | }); | ||||
| title = json['title']; | title = json['title']; | ||||
| detail = json['detail']; | detail = json['detail']; | ||||
| deadline = json['deadline']; | deadline = json['deadline']; | ||||
| // userAssignedId = json['user_assigned_id']; | |||||
| userAssignedId = json['user_assigned_id']; | |||||
| cropId = json['crop_id']; | cropId = json['crop_id']; | ||||
| } | } | ||||
| data['title'] = this.title; | data['title'] = this.title; | ||||
| data['detail'] = this.detail; | data['detail'] = this.detail; | ||||
| data['deadline'] = this.deadline; | data['deadline'] = this.deadline; | ||||
| // data['user_assigned_id'] = this.userAssignedId; | |||||
| data['user_assigned_id'] = this.userAssignedId; | |||||
| data['crop_id'] = this.cropId; | data['crop_id'] = this.cropId; | ||||
| return data; | return data; | ||||
| } | } |
| class RequestTaskUpdate { | class RequestTaskUpdate { | ||||
| int? id; | int? id; | ||||
| bool? completed; | bool? completed; | ||||
| String? completedDetail; | |||||
| RequestTaskUpdate({this.id, this.completed}); | |||||
| RequestTaskUpdate({ | |||||
| this.id, | |||||
| this.completed, | |||||
| this.completedDetail, | |||||
| }); | |||||
| RequestTaskUpdate.fromJson(Map<String, dynamic> json) { | RequestTaskUpdate.fromJson(Map<String, dynamic> json) { | ||||
| id = json['id']; | id = json['id']; | ||||
| completed = json['completed']; | completed = json['completed']; | ||||
| completedDetail = json['completedDetail']; | |||||
| } | } | ||||
| Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
| final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
| data['id'] = this.id; | data['id'] = this.id; | ||||
| data['completed'] = this.completed; | data['completed'] = this.completed; | ||||
| data['completedDetail'] = this.completedDetail; | |||||
| return data; | return data; | ||||
| } | } | ||||
| } | } |
| import '../../../themes/styles_text.dart'; | import '../../../themes/styles_text.dart'; | ||||
| import '../../custom_widgets/app_bar_widget.dart'; | import '../../custom_widgets/app_bar_widget.dart'; | ||||
| import '../../custom_widgets/button_widget.dart'; | |||||
| import '../../custom_widgets/loading_list_page.dart'; | import '../../custom_widgets/loading_list_page.dart'; | ||||
| import '../../custom_widgets/textfield/text_field_normal.dart'; | |||||
| import '../codes/widgets/item_column.dart'; | |||||
| import 'cubit/task_detail_cubit.dart'; | import 'cubit/task_detail_cubit.dart'; | ||||
| import 'package:farm_tpf/utils/formatter.dart'; | import 'package:farm_tpf/utils/formatter.dart'; | ||||
| class _TaskDetailPageState extends State<TaskDetailPage> { | class _TaskDetailPageState extends State<TaskDetailPage> { | ||||
| var bloc = TaskDetailCubit(); | var bloc = TaskDetailCubit(); | ||||
| @override | @override | ||||
| void initState() { | void initState() { | ||||
| super.initState(); | super.initState(); | ||||
| bloc.preparedData(widget.taskId); | bloc.preparedData(widget.taskId); | ||||
| } | } | ||||
| @override | |||||
| void dispose() { | |||||
| bloc.dispose(); | |||||
| super.dispose(); | |||||
| } | |||||
| @override | @override | ||||
| Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
| return Scaffold( | return Scaffold( | ||||
| child: Column( | child: Column( | ||||
| children: [ | children: [ | ||||
| Expanded( | Expanded( | ||||
| child: BlocBuilder<TaskDetailCubit, TaskDetailState>( | |||||
| bloc: bloc, | |||||
| builder: (context, state) { | |||||
| if (state is TaskDetailLoading) { | |||||
| return Center( | |||||
| child: LoadingListPage(), | |||||
| ); | |||||
| } else if (state is TaskDetailFailure) { | |||||
| return Center(child: Text(state.errorMessage)); | |||||
| } else if (state is TaskDetailSuccessful) { | |||||
| return SingleChildScrollView( | |||||
| child: Column( | |||||
| crossAxisAlignment: CrossAxisAlignment.start, | |||||
| children: [ | |||||
| _itemTaskDetail( | |||||
| title: '', | |||||
| detail: state.task.title ?? '', | |||||
| titleStyle: StylesText.body1, | |||||
| detailStyle: StylesText.body1.copyWith( | |||||
| color: Colors.blue, | |||||
| child: BlocBuilder<TaskDetailCubit, TaskDetailState>( | |||||
| bloc: bloc, | |||||
| builder: (context, state) { | |||||
| if (state is TaskDetailLoading) { | |||||
| return Center( | |||||
| child: LoadingListPage(), | |||||
| ); | |||||
| } else if (state is TaskDetailFailure) { | |||||
| return Center(child: Text(state.errorMessage)); | |||||
| } else if (state is TaskDetailSuccessful) { | |||||
| return SingleChildScrollView( | |||||
| child: Column( | |||||
| crossAxisAlignment: CrossAxisAlignment.start, | |||||
| children: [ | |||||
| _itemTaskDetail( | |||||
| title: '', | |||||
| detail: state.task.title ?? '', | |||||
| titleStyle: StylesText.body1, | |||||
| detailStyle: StylesText.body1.copyWith( | |||||
| color: Colors.blue, | |||||
| ), | |||||
| ), | ), | ||||
| ), | |||||
| _itemTaskDetail(title: 'Hạn chót : ', detail: state.task.dueDate?.format_DDMMYY().toString() ?? ''), | |||||
| (state.task.isCompleted ?? false) | |||||
| ? _itemTaskDetail(title: 'Thời gian hoàn thành : ', detail: state.task.executeDate?.format_DDMMYY().toString() ?? '') | |||||
| : const SizedBox.shrink(), | |||||
| Padding( | |||||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||||
| child: Text( | |||||
| 'Mô tả công việc :', | |||||
| style: StylesText.body2, | |||||
| _itemTaskDetail(title: 'Hạn chót : ', detail: state.task.dueDate?.format_DDMMYY().toString() ?? ''), | |||||
| (state.task.isCompleted ?? false) | |||||
| ? _itemTaskDetail(title: 'Thời gian hoàn thành : ', detail: state.task.executeDate?.format_DDMMYY().toString() ?? '') | |||||
| : const SizedBox.shrink(), | |||||
| Padding( | |||||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||||
| child: Text( | |||||
| 'Mô tả công việc :', | |||||
| style: StylesText.body2, | |||||
| ), | |||||
| ), | ), | ||||
| ), | |||||
| Padding( | |||||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||||
| child: Text( | |||||
| state.task.description ?? '', | |||||
| style: StylesText.body3, | |||||
| Padding( | |||||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||||
| child: Text( | |||||
| state.task.description ?? '', | |||||
| style: StylesText.body3, | |||||
| ), | |||||
| ), | ), | ||||
| ), | |||||
| Padding( | |||||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||||
| child: CheckboxWidget( | |||||
| title: 'Hoàn thành', | |||||
| style: StylesText.body2, | |||||
| isChecked: state.task.isCompleted ?? false, | |||||
| onChange: (status) { | |||||
| bloc.updateStatusTask( | |||||
| RequestTaskUpdate( | |||||
| id: widget.taskId, | |||||
| completed: status, | |||||
| ValueListenableBuilder<bool>( | |||||
| valueListenable: bloc.isCompleted, | |||||
| builder: (context, isCompleted, _) { | |||||
| return Padding( | |||||
| padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), | |||||
| child: CheckboxWidget( | |||||
| title: 'Hoàn thành', | |||||
| style: StylesText.body2, | |||||
| isChecked: isCompleted, | |||||
| onChange: (status) { | |||||
| bloc.isCompleted.value = status; | |||||
| // bloc.updateStatusTask( | |||||
| // RequestTaskUpdate( | |||||
| // id: widget.taskId, | |||||
| // completed: status, | |||||
| // ), | |||||
| // ); | |||||
| }, | |||||
| ), | ), | ||||
| ); | ); | ||||
| }, | }, | ||||
| ), | ), | ||||
| ), | |||||
| const SizedBox( | |||||
| height: 8, | |||||
| ), | |||||
| ], | |||||
| const SizedBox( | |||||
| height: 8, | |||||
| ), | |||||
| ItemColumnWidget( | |||||
| title: 'Mô tả công việc', | |||||
| child: TextFieldNormal( | |||||
| controller: bloc.detailCtl, | |||||
| maxLines: 3, | |||||
| hint: 'Mô tả', | |||||
| ), | |||||
| ), | |||||
| ], | |||||
| ), | |||||
| ); | |||||
| } | |||||
| return const SizedBox.shrink(); | |||||
| }, | |||||
| ), | |||||
| ), | |||||
| // const SizedBox( | |||||
| // height: 8, | |||||
| // ), | |||||
| Padding( | |||||
| padding: const EdgeInsets.all(8.0), | |||||
| child: ButtonWidget( | |||||
| title: 'Cập nhật hoàn thành', | |||||
| onPressed: () { | |||||
| bloc.updateStatusTask( | |||||
| RequestTaskUpdate( | |||||
| id: widget.taskId, | |||||
| completed: bloc.isCompleted.value, | |||||
| completedDetail: bloc.detailCtl.text, | |||||
| ), | ), | ||||
| ); | ); | ||||
| } | |||||
| return const SizedBox.shrink(); | |||||
| }, | |||||
| )), | |||||
| const SizedBox( | |||||
| height: 8, | |||||
| }, | |||||
| ), | |||||
| ), | ), | ||||
| ], | ], | ||||
| ), | ), |
| description: A new Flutter project. | description: A new Flutter project. | ||||
| publish_to: 'none' | publish_to: 'none' | ||||
| version: 1.1.10+29 | |||||
| version: 1.1.11+30 | |||||
| environment: | environment: | ||||
| sdk: ">=3.0.0 <4.0.0" | sdk: ">=3.0.0 <4.0.0" |