From 3811cb6ca0caf84acaac117285644bb551d550b5 Mon Sep 17 00:00:00 2001 From: "mr.mojtaba" Date: Wed, 17 Sep 2025 14:20:35 +0330 Subject: [PATCH] feat : search and filter --- .../poultry_science_remote.dart | 5 + .../poultry_science_remote_imp.dart | 10 +- .../poultry_science_repository.dart | 5 +- .../poultry_science_repository_imp.dart | 8 ++ .../pages/poultry_science/genocide/logic.dart | 52 +++++--- .../pages/poultry_science/genocide/view.dart | 122 ++++++++++++++---- .../killing_registration/logic.dart | 9 +- .../date_picker_bottom_sheet.dart | 5 +- .../widget/buttons/outline_elevated_icon.dart | 34 ++--- 9 files changed, 181 insertions(+), 69 deletions(-) diff --git a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart b/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart index eb9e4b2..3a892c4 100644 --- a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart +++ b/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart @@ -86,4 +86,9 @@ abstract class PoultryScienceRemoteDatasource { required String token, Map? queryParameters, }); + + Future deletePoultryOder({ + required String token, + required String orderId, + }); } diff --git a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart b/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart index 132ac00..a201d6f 100644 --- a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart +++ b/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart @@ -223,14 +223,20 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc queryParameters: queryParameters, fromJson: (json) => PaginationModel.fromJson( json, - (data) => PoultryOrder.fromJson(data as Map), + (data) => PoultryOrder.fromJson(data as Map), ), ); - dLog(res.data.runtimeType); return res.data; } + @override + Future deletePoultryOder({required String token, required String orderId}) async { + await _httpClient.delete( + '/Poultry_Request/$orderId/', + headers: {'Authorization': 'Bearer $token'}, + ); + } //endregion } diff --git a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart b/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart index 52d9787..f1546fc 100644 --- a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart +++ b/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart @@ -84,5 +84,8 @@ abstract class PoultryScienceRepository { required String token, Map? queryParameters, }); - + Future deletePoultryOder({ + required String token, + required String orderId, + }); } diff --git a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart b/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart index cdcaca8..7bbed7c 100644 --- a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart +++ b/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart @@ -134,4 +134,12 @@ class PoultryScienceRepositoryImp implements PoultryScienceRepository { }) async { return await datasource.getPoultryOderList(token: token, queryParameters: queryParameters); } + + @override + Future deletePoultryOder({ + required String token, + required String orderId, + }) async { + await datasource.deletePoultryOder(token: token, orderId: orderId); + } } diff --git a/packages/chicken/lib/presentation/pages/poultry_science/genocide/logic.dart b/packages/chicken/lib/presentation/pages/poultry_science/genocide/logic.dart index 6f060c6..d86414e 100644 --- a/packages/chicken/lib/presentation/pages/poultry_science/genocide/logic.dart +++ b/packages/chicken/lib/presentation/pages/poultry_science/genocide/logic.dart @@ -16,12 +16,10 @@ class GenocideLogic extends GetxController { final RxBool isLoadingMore = false.obs; - Rx fromDateFilter = Jalali - .now() - .obs; - Rx toDateFilter = Jalali - .now() - .obs; + final RxBool isLoadingDelete = false.obs; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; RxnString searchedValue = RxnString(); /* final RxBool isLoadingMoreAllocationsMade = false.obs; @@ -52,20 +50,19 @@ class GenocideLogic extends GetxController { currentPage.value = 1; } await safeCall( - call: () => - rootLogic.poultryRepository.getPoultryOderList( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams( - pageSize: 20, - page: currentPage.value, - search: 'filter', - role: gService.getRole(Module.chicken), - value: searchedValue.value, - fromDate: fromDateFilter.value.toDateTime(), - toDate: toDateFilter.value.toDateTime(), - queryParams: {'today': null} - ), - ), + call: () async => await rootLogic.poultryRepository.getPoultryOderList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + pageSize: 20, + page: currentPage.value, + search: 'filter', + role: gService.getRole(Module.chicken), + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + queryParams: {'today': null}, + ), + ), onSuccess: (res) async { await Future.delayed(Duration(milliseconds: 500)); if ((res?.count ?? 0) == 0) { @@ -83,4 +80,19 @@ class GenocideLogic extends GetxController { }, ); } + + + + Future deletePoultryOrder(int id) async { + isExpandedList.clear(); + await safeCall( + call: () async => await rootLogic.poultryRepository.deletePoultryOder( + token: rootLogic.tokenService.accessToken.value!, + orderId: id.toString(), + ), + onSuccess: (_) { + defaultShowSuccessMessage('درخواست با موفقیت حذف شد'); + }, + ); + } } diff --git a/packages/chicken/lib/presentation/pages/poultry_science/genocide/view.dart b/packages/chicken/lib/presentation/pages/poultry_science/genocide/view.dart index aacb5b8..d1109ce 100644 --- a/packages/chicken/lib/presentation/pages/poultry_science/genocide/view.dart +++ b/packages/chicken/lib/presentation/pages/poultry_science/genocide/view.dart @@ -3,6 +3,7 @@ import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_orde import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; @@ -14,8 +15,13 @@ class GenocidePage extends GetView { Widget build(BuildContext context) { return BasePage( routes: controller.routes, - hasSearch: false, - hasFilter: false, + hasSearch: true, + hasFilter: true, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getPoultryOrderList(); + }, + filteringWidget: filterBottomSheet(), onBackPressed: () => Get.back(id: poultryFirstKey), floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, floatingActionButton: RFab.add( @@ -128,8 +134,41 @@ class GenocidePage extends GetView { buildRow(title: 'میانگین وزنی', value: '${(item.indexWeight)} (کیلوگرم)'), buildRow(title: 'قیمت مرغدار', value: '${item.amount.separatedByComma} (ریال)'), - buildRow(title: 'مانده در سالن ', value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)'), + buildRow( + title: 'مانده در سالن ', + value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)', + ), buildRow(title: ' وضعیت', value: getState(item)), + + Visibility( + visible: item.stateProcess == 'pending', + child: ObxValue((data) { + return ROutlinedElevatedIcon( + height: 40.h, + width: Get.width, + text: 'حذف', + icon: Assets.vec.trashSvg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode(AppColor.error, BlendMode.srcIn), + ), + textStyle: AppFonts.yekan16Bold.copyWith(color: AppColor.error), + borderColor: AppColor.error, + foregroundColor: AppColor.error, + pressedBackgroundColor: AppColor.error, + onPressed: data.value + ? null + : () => _buildDeleteDialog( + onConfirm: () async { + Get.back(); + await controller.deletePoultryOrder(item.id!); + controller.getPoultryOrderList(); + + }, + ), + ); + }, controller.isLoadingDelete), + ), ], ), ); @@ -191,32 +230,63 @@ class GenocidePage extends GetView { ], ); } -} -String getRequestType(PoultryOrder item) { - if (item.market ?? false) { - return 'پنل معاملات'; - } else if (item.union ?? false) { - return 'اتحادیه'; - } else { - return 'خرید مستقیم'; + String getRequestType(PoultryOrder item) { + if (item.market ?? false) { + return 'پنل معاملات'; + } else if (item.union ?? false) { + return 'اتحادیه'; + } else { + return 'خرید مستقیم'; + } } -} -String getKillType(PoultryOrder item) { - if (item.export ?? false) { - return 'صادرات'; - } else if (item.freezing ?? false) { - return 'انجماد'; - } else { - return 'عادی'; + String getKillType(PoultryOrder item) { + if (item.export ?? false) { + return 'صادرات'; + } else if (item.freezing ?? false) { + return 'انجماد'; + } else { + return 'عادی'; + } } -} -String getState(PoultryOrder item) { - if (item.stateProcess == 'pending') { - return 'در انتظار تایید'; - } else { - return 'تایید شده'; + String getState(PoultryOrder item) { + if (item.stateProcess == 'pending') { + return 'در انتظار تایید'; + } else { + return 'تایید شده'; + } } -} \ No newline at end of file + + void _buildDeleteDialog({required VoidCallback onConfirm}) { + Get.defaultDialog( + title: 'حذف درخواست کشتار', + middleText: 'آیا از حذف این درخواست کشتار مطمئن هستید؟', + confirm: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: AppColor.error, + foregroundColor: Colors.white, + ), + onPressed: onConfirm, + child: Text('بله'), + ), + cancel: ElevatedButton( + onPressed: () { + Get.back(); + }, + child: Text('خیر'), + ), + ); + } + + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.getPoultryOrderList(), + ); + +} diff --git a/packages/chicken/lib/presentation/pages/poultry_science/killing_registration/logic.dart b/packages/chicken/lib/presentation/pages/poultry_science/killing_registration/logic.dart index d8c5984..c48a20d 100644 --- a/packages/chicken/lib/presentation/pages/poultry_science/killing_registration/logic.dart +++ b/packages/chicken/lib/presentation/pages/poultry_science/killing_registration/logic.dart @@ -349,9 +349,14 @@ class KillingRegistrationLogic extends GetxController { onSuccess: (result) async { defaultShowSuccessMessage( 'ثبت با موفقیت انجام شد', - onDismissed: () { - Get.back(id: poultryFirstKey); + durationInSeconds: 2, + onDismissed: () async { + fLog('Kill Registration onDismissed'); + Future.delayed(Duration(milliseconds: 300), () { + Get.back(id: poultryFirstKey); + }); }, + ); }, onError: (error, stackTrace) {}, diff --git a/packages/core/lib/presentation/widget/bottom_sheet/date_picker_bottom_sheet.dart b/packages/core/lib/presentation/widget/bottom_sheet/date_picker_bottom_sheet.dart index 035d49b..1aa9a58 100644 --- a/packages/core/lib/presentation/widget/bottom_sheet/date_picker_bottom_sheet.dart +++ b/packages/core/lib/presentation/widget/bottom_sheet/date_picker_bottom_sheet.dart @@ -9,7 +9,10 @@ GestureDetector dateFilterWidget({ }) { return GestureDetector( onTap: () { - Get.bottomSheet(modalDatePicker(onDateSelected: (value) => onChanged(value))); + Get.bottomSheet(modalDatePicker(onDateSelected: (value) { + date = value.obs; + onChanged(value); + })); }, child: Container( height: 35, diff --git a/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart b/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart index 7260c6b..4052f6e 100644 --- a/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart +++ b/packages/core/lib/presentation/widget/buttons/outline_elevated_icon.dart @@ -22,14 +22,14 @@ class ROutlinedElevatedIcon extends StatefulWidget { final VoidCallback? onPressed; final double width; final double height; - Color? foregroundColor; - Color? backgroundColor; - Color? borderColor; - Color? disabledBackgroundColor; - Color? pressedBackgroundColor; - double? radius; - TextStyle? textStyle; - Widget? icon; + final Color? foregroundColor; + final Color? backgroundColor; + final Color? borderColor; + final Color? disabledBackgroundColor; + final Color? pressedBackgroundColor; + final double? radius; + final TextStyle? textStyle; + final Widget? icon; @override State createState() => _ROutlinedElevatedIconState(); @@ -40,7 +40,6 @@ class _ROutlinedElevatedIconState extends State { Widget build(BuildContext context) { return OutlinedButton.icon( icon: widget.icon, - label: Text(widget.text), onPressed: widget.onPressed, style: ButtonStyle( @@ -91,11 +90,9 @@ class _ROutlinedElevatedIconState extends State { if (states.contains(WidgetState.pressed)) { return Colors.white; } else if (states.contains(WidgetState.disabled)) { - return widget.foregroundColor?.disabledColor ?? - AppColor.blueNormal.withAlpha(38); + return widget.foregroundColor?.disabledColor ?? AppColor.blueNormal.withAlpha(38); } else if (states.contains(WidgetState.hovered)) { - return widget.foregroundColor?.hoverColor ?? - AppColor.blueNormal.withAlpha(50); + return widget.foregroundColor?.hoverColor ?? AppColor.blueNormal.withAlpha(50); } return widget.foregroundColor ?? AppColor.blueNormal; }), @@ -106,10 +103,13 @@ class _ROutlinedElevatedIconState extends State { ), fixedSize: WidgetStatePropertyAll(Size(widget.width, widget.height)), padding: WidgetStatePropertyAll(EdgeInsets.zero), - textStyle: WidgetStatePropertyAll( - widget.textStyle ?? - AppFonts.yekan24.copyWith(color: AppColor.blueNormal), - ), + textStyle: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.pressed)) { + return widget.textStyle?.copyWith(color: Colors.white) ?? + AppFonts.yekan18.copyWith(color: Colors.white); + } + return widget.textStyle ?? AppFonts.yekan18.copyWith(color: AppColor.blueNormal); + }), ), ); }