diff --git a/assets/icons/inspection_poultry.svg b/assets/icons/inspection_poultry.svg new file mode 100644 index 0000000..62afa66 --- /dev/null +++ b/assets/icons/inspection_poultry.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/vec/inspection_poultry.svg.vec b/assets/vec/inspection_poultry.svg.vec new file mode 100644 index 0000000..0e70288 Binary files /dev/null and b/assets/vec/inspection_poultry.svg.vec differ diff --git a/packages/chicken/lib/data/common/fa_user_role.dart b/packages/chicken/lib/data/common/fa_user_role.dart index 52e19c2..af8e17f 100644 --- a/packages/chicken/lib/data/common/fa_user_role.dart +++ b/packages/chicken/lib/data/common/fa_user_role.dart @@ -1,4 +1,5 @@ import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/features/province_operator/presentation/routes/routes.dart'; @@ -149,7 +150,7 @@ Map getFaUserRoleWithOnTap(String? role) { case "Dispenser": return {"پخش کننده": null}; case "CityPoultry": - return {"طیور شهرستان": null}; + return {"طیور شهرستان": CityPoultryRoutes.initCityPoultry}; case "ParentCompany": return {"شرکت مادر": null}; case "ColdHouseSteward": diff --git a/packages/chicken/lib/data/di/chicken_di.dart b/packages/chicken/lib/data/di/chicken_di.dart index 483852e..65a6a7d 100644 --- a/packages/chicken/lib/data/di/chicken_di.dart +++ b/packages/chicken/lib/data/di/chicken_di.dart @@ -10,6 +10,7 @@ import 'package:rasadyar_chicken/features/steward/data/di/steward_di.dart'; import 'package:rasadyar_chicken/features/province_operator/data/di/province_operator_di.dart'; import 'package:rasadyar_chicken/features/province_inspector/data/di/province_inspector_di.dart'; import 'package:rasadyar_chicken/features/city_jahad/data/di/city_jahad_di.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/di/city_poultry_di.dart'; import 'package:rasadyar_chicken/features/vet_farm/data/di/vet_farm_di.dart'; import 'package:rasadyar_chicken/features/super_admin/data/di/super_admin_di.dart'; import 'package:rasadyar_chicken/features/province_supervisor/data/di/province_supervisor_di.dart'; @@ -74,6 +75,9 @@ Future setupChickenDI() async { // Setup city_jahad feature DI await setupCityJahadDI(diChicken, dioRemote); + // Setup city_poultry feature DI + await setupCityPoultryDI(diChicken, dioRemote); + // Setup vet_farm feature DI await setupVetFarmDI(diChicken, dioRemote); @@ -138,6 +142,7 @@ Future newSetupAuthDI(String newUrl) async { await setupProvinceOperatorDI(diChicken, dioRemote); await setupProvinceInspectorDI(diChicken, dioRemote); await setupCityJahadDI(diChicken, dioRemote); + await setupCityPoultryDI(diChicken, dioRemote); await setupVetFarmDI(diChicken, dioRemote); await setupSuperAdminDI(diChicken, dioRemote); await setupProvinceSupervisorDI(diChicken, dioRemote); diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart index 9f8d12a..219f702 100644 --- a/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/A', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart index dc3671a..b249908 100644 --- a/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart @@ -23,7 +23,7 @@ class CityJahadHomeLogic extends GetxController { CityJahadActionItem( title: "بازرسی مزارع طیور", route: CityJahadRoutes.newInspectionCityJahad, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/city_poultry/city_poultry.dart b/packages/chicken/lib/features/city_poultry/city_poultry.dart new file mode 100644 index 0000000..46c55f8 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/city_poultry.dart @@ -0,0 +1,4 @@ +export 'data/di/city_poultry_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; + diff --git a/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart new file mode 100644 index 0000000..06c1d93 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart @@ -0,0 +1,16 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class CityPoultryRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} + diff --git a/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart new file mode 100644 index 0000000..c50aefb --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart @@ -0,0 +1,40 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityPoultryRemoteDataSourceImpl implements CityPoultryRemoteDataSource { + final DioRemote _httpClient; + + CityPoultryRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} + diff --git a/packages/chicken/lib/features/city_poultry/data/di/city_poultry_di.dart b/packages/chicken/lib/features/city_poultry/data/di/city_poultry_di.dart new file mode 100644 index 0000000..b428c8d --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/data/di/city_poultry_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for city_poultry feature +Future setupCityPoultryDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => CityPoultryRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => CityPoultryRepositoryImpl(di.get()), + ); +} + +/// Re-register city_poultry dependencies (used when base URL changes) +Future reRegisterCityPoultryDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => CityPoultryRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => CityPoultryRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository.dart b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository.dart new file mode 100644 index 0000000..e20a362 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository.dart @@ -0,0 +1,16 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class CityPoultryRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} + diff --git a/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository_impl.dart b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository_impl.dart new file mode 100644 index 0000000..61f33ff --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository_impl.dart @@ -0,0 +1,31 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityPoultryRepositoryImpl implements CityPoultryRepository { + final CityPoultryRemoteDataSource _remote; + + CityPoultryRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} + diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..dbbd23d --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,96 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + CityPoultryRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'CityPoultry', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} + diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..27f71da --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/view.dart @@ -0,0 +1,236 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: cityPoultryActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + Container( + height: 32, + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: ShapeDecoration( + color: AppColor.blueLight, + shape: RoundedRectangleBorder( + side: BorderSide(width: 1, color: AppColor.blueLightHover), + borderRadius: BorderRadius.circular(8), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'ندارد', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'ندارد', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.licenceNumber ?? 'ندارد', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/home/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/home/logic.dart new file mode 100644 index 0000000..b7000b0 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/home/logic.dart @@ -0,0 +1,29 @@ +import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityPoultryActionItem { + final String title; + final String route; + final String icon; + + CityPoultryActionItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class CityPoultryHomeLogic extends GetxController { + RxList items = [ + CityPoultryActionItem( + title: "جوجه ریزی فعال", + route: CityPoultryRoutes.activeHatchingCityPoultry, + icon: Assets.vec.activeFramSvg.path, + ), + CityPoultryActionItem( + title: "بازرسی مزارع طیور", + route: CityPoultryRoutes.newInspectionCityPoultry, + icon: Assets.vec.inspectionPoultrySvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/home/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/home/view.dart new file mode 100644 index 0000000..80fd793 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/home/view.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class CityPoultryHomePage extends GetView { + CityPoultryHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: cityPoultryActionKey); + }, + ); + }, + ); + }, controller.items); + } +} + diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..ffde772 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,160 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + CityPoultryRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.cityPoultryRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'CityPoultry', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} + diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..d77fcc1 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: cityPoultryActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/root/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/root/logic.dart new file mode 100644 index 0000000..327dcb3 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/root/logic.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class CityPoultryRootLogic extends GetxController { + var tokenService = Get.find(); + + late CityPoultryRepository cityPoultryRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(cityPoultryActionKey), + onGenerateRoute: (settings) { + final page = CityPoultryPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => CityPoultryPages.pages.firstWhere( + (e) => e.name == CityPoultryRoutes.homeCityPoultry, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + cityPoultryRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final nestedKey = Get.nestedKey(cityPoultryActionKey); + + final currentRoute = Get.routing.current; + + // بررسی کن که آیا route فعلی یکی از route‌های داخلی است + final isInternalRoute = + currentRoute == CityPoultryRoutes.activeHatchingCityPoultry || + currentRoute == CityPoultryRoutes.newInspectionCityPoultry || + currentRoute == CityPoultryRoutes.actionCityPoultry; + + // فقط اگر می‌توان pop کرد و در یکی از صفحه‌های داخلی هستیم، pop کن + if ( isInternalRoute) { + Get.back(id: cityPoultryActionKey); + return; + } + + // اگر در صفحه home هستیم، منطق خروج از اپ را اجرا کن + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/root/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/root/view.dart new file mode 100644 index 0000000..27df552 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/pages/root/view.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class CityPoultryRootPage extends GetView { + const CityPoultryRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + cityPoultryActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + cityPoultryActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} + diff --git a/packages/chicken/lib/features/city_poultry/presentation/routes/pages.dart b/packages/chicken/lib/features/city_poultry/presentation/routes/pages.dart new file mode 100644 index 0000000..f0d97bc --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/routes/pages.dart @@ -0,0 +1,67 @@ +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityPoultryPages { + CityPoultryPages._(); + + static List get pages => [ + GetPage( + name: CityPoultryRoutes.initCityPoultry, + page: () => CityPoultryRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => CityPoultryRootLogic()); + Get.lazyPut(() => CityPoultryHomeLogic()); + }), + ], + ), + GetPage( + name: CityPoultryRoutes.homeCityPoultry, + page: () => CityPoultryHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(CityPoultryHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + + GetPage( + name: CityPoultryRoutes.activeHatchingCityPoultry, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: CityPoultryRoutes.newInspectionCityPoultry, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} + diff --git a/packages/chicken/lib/features/city_poultry/presentation/routes/routes.dart b/packages/chicken/lib/features/city_poultry/presentation/routes/routes.dart new file mode 100644 index 0000000..9c24c65 --- /dev/null +++ b/packages/chicken/lib/features/city_poultry/presentation/routes/routes.dart @@ -0,0 +1,11 @@ +sealed class CityPoultryRoutes { + CityPoultryRoutes._(); + + static const _base = '/chicken/cityPoultry'; + static const initCityPoultry = '$_base/'; + static const homeCityPoultry = '$_base/home'; + static const actionCityPoultry = '$_base/action'; + static const activeHatchingCityPoultry = '$_base/activeHatching'; + static const newInspectionCityPoultry = '$_base/newInspection'; +} + diff --git a/packages/chicken/lib/features/common/presentation/page/auth/logic.dart b/packages/chicken/lib/features/common/presentation/page/auth/logic.dart index 9842eec..c1a3286 100644 --- a/packages/chicken/lib/features/common/presentation/page/auth/logic.dart +++ b/packages/chicken/lib/features/common/presentation/page/auth/logic.dart @@ -131,6 +131,7 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { 'killhouse', 'provinceinspector', 'cityjahad', + 'citypoultry', 'jahad', 'vetfarm', 'provincesupervisor', diff --git a/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart index 6f0b218..47b6c15 100644 --- a/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart @@ -175,12 +175,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -195,12 +195,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart b/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart index f8d9114..ecb8033 100644 --- a/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart @@ -23,7 +23,7 @@ class JahadHomeLogic extends GetxController { JahadActionItem( title: "بازرسی مزارع طیور", route: JahadRoutes.newInspectionJahad, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart index 467cfad..03ac3b9 100644 --- a/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart index 9db46d1..ae7ae10 100644 --- a/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart @@ -40,7 +40,7 @@ class PoultryActionLogic extends GetxController { PoultryActionItem( title: "بازرسی مزارع طیور", route: PoultryScienceRoutes.newInspectionPoultryScience, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart index 4fa0611..95c0cfc 100644 --- a/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart index 5400e75..ae37109 100644 --- a/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart @@ -24,7 +24,7 @@ class ProvinceInspectorHomeLogic extends GetxController { ProvinceInspectorActionItem( title: "بازرسی مزارع طیور", route: ProvinceInspectorRoutes.newInspectionProvinceInspector, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart index 950ecaa..c0cd0dc 100644 --- a/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart index 778e68f..bd098b8 100644 --- a/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart @@ -24,7 +24,7 @@ class ProvinceOperatorHomeLogic extends GetxController { ProvinceOperatorHomeItem( title: "بازرسی مزارع طیور", route: ProvinceOperatorRoutes.newInspectionProvinceOperator, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart index 28553c4..3da44a2 100644 --- a/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart index 61d4abe..2e13b69 100644 --- a/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart @@ -24,7 +24,7 @@ class ProvinceSupervisorHomeLogic extends GetxController { ProvinceSupervisorActionItem( title: "بازرسی مزارع طیور", route: ProvinceSupervisorRoutes.newInspectionProvinceSupervisor, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart index c663465..9db13c9 100644 --- a/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart b/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart index 7a720d3..8b5805d 100644 --- a/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart @@ -20,7 +20,7 @@ class SuperAdminHomeLogic extends GetxController { SuperAdminHomeItem( title: "بازرسی مزارع طیور", route: SuperAdminRoutes.newInspectionSuperAdmin, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart index 3d0f986..b68eb54 100644 --- a/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart @@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView { spacing: 3, children: [ Text( - item.poultry?.user?.fullname ?? 'N/A', + item.poultry?.user?.fullname ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), Text( - item.poultry?.user?.mobile ?? 'N/A', + item.poultry?.user?.mobile ?? 'ندارد', textAlign: TextAlign.center, style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), @@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - item.poultry?.unitName ?? 'N/Aaq', + item.poultry?.unitName ?? 'ندارد', textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( - item.poultry?.licenceNumber ?? 'N/A', + item.licenceNumber ?? 'ندارد', textAlign: TextAlign.left, style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), ), diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart index 25da47a..56a6ac1 100644 --- a/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart @@ -19,7 +19,7 @@ class VetFarmHomeLogic extends GetxController { VetFarmHomeItem( title: "بازرسی مزارع طیور", route: VetFarmRoutes.newInspectionVetFarm, - icon: Assets.vec.activeFramSvg.path, + icon: Assets.vec.inspectionPoultrySvg.path, ), ].obs; } diff --git a/packages/chicken/lib/presentation/routes/pages.dart b/packages/chicken/lib/presentation/routes/pages.dart index e08ddce..469f555 100644 --- a/packages/chicken/lib/presentation/routes/pages.dart +++ b/packages/chicken/lib/presentation/routes/pages.dart @@ -1,3 +1,4 @@ +import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/pages.dart'; import 'package:rasadyar_chicken/features/common/common.dart'; import 'package:rasadyar_chicken/features/kill_house/action/logic.dart'; import 'package:rasadyar_chicken/features/kill_house/action/view.dart'; @@ -66,6 +67,10 @@ sealed class ChickenPages { ...JahadPages.pages, //endregion + //region City Poultry Pages + ...CityPoultryPages.pages, + //endregion + //region Poultry Farm Inspection GetPage( name: ChickenRoutes.poultryFarmInspectionHome, diff --git a/packages/chicken/lib/presentation/utils/nested_keys_utils.dart b/packages/chicken/lib/presentation/utils/nested_keys_utils.dart index 745df67..4f6dd52 100644 --- a/packages/chicken/lib/presentation/utils/nested_keys_utils.dart +++ b/packages/chicken/lib/presentation/utils/nested_keys_utils.dart @@ -41,6 +41,11 @@ const int cityJahadActionKey = 112; //endregion +//region city poultry Keys +const int cityPoultryActionKey = 117; + +//endregion + //region vet farm Keys const int vetFarmActionKey = 113; diff --git a/packages/core/lib/presentation/common/assets.gen.dart b/packages/core/lib/presentation/common/assets.gen.dart index 1108d38..e5d7b17 100644 --- a/packages/core/lib/presentation/common/assets.gen.dart +++ b/packages/core/lib/presentation/common/assets.gen.dart @@ -229,6 +229,9 @@ class $AssetsIconsGen { /// File path: assets/icons/inspection.svg SvgGenImage get inspection => const SvgGenImage('assets/icons/inspection.svg'); + /// File path: assets/icons/inspection_poultry.svg + SvgGenImage get inspectionPoultry => const SvgGenImage('assets/icons/inspection_poultry.svg'); + /// File path: assets/icons/key.svg SvgGenImage get key => const SvgGenImage('assets/icons/key.svg'); @@ -456,6 +459,7 @@ class $AssetsIconsGen { information, inside, inspection, + inspectionPoultry, key, liveStock, lock, @@ -748,6 +752,9 @@ class $AssetsVecGen { /// File path: assets/vec/inspection.svg.vec SvgGenImage get inspectionSvg => const SvgGenImage.vec('assets/vec/inspection.svg.vec'); + /// File path: assets/vec/inspection_poultry.svg.vec + SvgGenImage get inspectionPoultrySvg => const SvgGenImage.vec('assets/vec/inspection_poultry.svg.vec'); + /// File path: assets/vec/key.svg.vec SvgGenImage get keySvg => const SvgGenImage.vec('assets/vec/key.svg.vec'); @@ -975,6 +982,7 @@ class $AssetsVecGen { informationSvg, insideSvg, inspectionSvg, + inspectionPoultrySvg, keySvg, liveStockSvg, lockSvg,