feat: add image upload functionality to poultry science feature, including repository and data source updates for handling image uploads
This commit is contained in:
@@ -3,3 +3,5 @@ abstract class PoultryFarmLocalDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ abstract class PoultryFarmRemoteDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ abstract class PoultryFarmRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -89,4 +89,9 @@ abstract class PoultryScienceRemoteDataSource {
|
|||||||
required String token,
|
required String token,
|
||||||
required String orderId,
|
required String orderId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Future<List<String>?> uploadImages({
|
||||||
|
required String token,
|
||||||
|
required List<XFile> images,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -245,5 +245,21 @@ class PoultryScienceRemoteDataSourceImpl
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<String>?> uploadImages({
|
||||||
|
required String token,
|
||||||
|
required List<XFile> images,
|
||||||
|
}) async {
|
||||||
|
var res = await _httpClient.post<List<String>?>(
|
||||||
|
'/upload_image_to_server_for_poultry_science/',
|
||||||
|
headers: {'Authorization': 'Bearer $token'},
|
||||||
|
data: FormData.fromMap({
|
||||||
|
'file': images.map((e) => MultipartFile.fromFileSync(e.path)).toList(),
|
||||||
|
}),
|
||||||
|
fromJson: (json) => List<String>.from(json['urls'] as List),
|
||||||
|
);
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,4 +89,9 @@ abstract class PoultryScienceRepository {
|
|||||||
required String token,
|
required String token,
|
||||||
required String orderId,
|
required String orderId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Future<List<String>?> uploadImages({
|
||||||
|
required String token,
|
||||||
|
required List<XFile> images,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,4 +180,12 @@ class PoultryScienceRepositoryImpl implements PoultryScienceRepository {
|
|||||||
}) async {
|
}) async {
|
||||||
return await _dataSource.deletePoultryOder(token: token, orderId: orderId);
|
return await _dataSource.deletePoultryOder(token: token, orderId: orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<String>?> uploadImages({
|
||||||
|
required String token,
|
||||||
|
required List<XFile> images,
|
||||||
|
}) async {
|
||||||
|
return await _dataSource.uploadImages(token: token, images: images);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
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/model/response/hatching/hatching_models.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart';
|
||||||
@@ -22,7 +23,7 @@ class ActiveHatchingLogic extends GetxController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
poultryScienceRepository = Get.find<PoultryScienceRepository>();
|
poultryScienceRepository = diChicken.get<PoultryScienceRepository>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/active_hatching/logic.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/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/utils/nested_keys_utils.dart';
|
||||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
@@ -50,7 +52,6 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
|||||||
itemCount: data.value.data?.results?.length ?? 0,
|
itemCount: data.value.data?.results?.length ?? 0,
|
||||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||||
onLoadMore: () async => controller.getHatchingList(true),
|
onLoadMore: () async => controller.getHatchingList(true),
|
||||||
|
|
||||||
);
|
);
|
||||||
}, controller.activeHatchingList);
|
}, controller.activeHatchingList);
|
||||||
}
|
}
|
||||||
@@ -58,7 +59,10 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
|||||||
Container itemListExpandedWidget(HatchingModel item) {
|
Container itemListExpandedWidget(HatchingModel item) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
@@ -111,7 +115,10 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
buildRow(title: 'شماره مجوز جوجه ریزی', value: item.licenceNumber ?? 'N/A'),
|
buildRow(
|
||||||
|
title: 'شماره مجوز جوجه ریزی',
|
||||||
|
value: item.licenceNumber ?? 'N/A',
|
||||||
|
),
|
||||||
buildUnitRow(
|
buildUnitRow(
|
||||||
title: 'حجم جوجه ریزی',
|
title: 'حجم جوجه ریزی',
|
||||||
value: item.quantity.separatedByCommaFa,
|
value: item.quantity.separatedByCommaFa,
|
||||||
@@ -122,21 +129,52 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
|||||||
value: item.leftOver.separatedByCommaFa,
|
value: item.leftOver.separatedByCommaFa,
|
||||||
unit: '(قطعه)',
|
unit: '(قطعه)',
|
||||||
),
|
),
|
||||||
buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)'),
|
buildUnitRow(
|
||||||
|
title: 'تلفات',
|
||||||
|
value: item.losses.separatedByCommaFa,
|
||||||
|
unit: '(قطعه)',
|
||||||
|
),
|
||||||
buildRow(
|
buildRow(
|
||||||
title: 'دامپزشک فارم',
|
title: 'دامپزشک فارم',
|
||||||
value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
|
value:
|
||||||
|
'${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
|
||||||
),
|
),
|
||||||
buildRow(
|
buildRow(
|
||||||
title: 'شرح بازرسی',
|
title: 'شرح بازرسی',
|
||||||
value: item.reportInfo?.image == false ? 'ارسال تصویر جوجه ریزی فارم ' : 'تکمیل شده',
|
value: item.reportInfo?.image == false
|
||||||
|
? 'ارسال تصویر جوجه ریزی فارم '
|
||||||
|
: 'تکمیل شده',
|
||||||
titleStyle: AppFonts.yekan14.copyWith(
|
titleStyle: AppFonts.yekan14.copyWith(
|
||||||
color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark,
|
color: (item.reportInfo?.image ?? false)
|
||||||
|
? AppColor.greenNormal
|
||||||
|
: AppColor.redDark,
|
||||||
),
|
),
|
||||||
valueStyle: AppFonts.yekan14.copyWith(
|
valueStyle: AppFonts.yekan14.copyWith(
|
||||||
color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark,
|
color: (item.reportInfo?.image ?? false)
|
||||||
|
? AppColor.greenNormal
|
||||||
|
: AppColor.redDark,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
RElevated(
|
||||||
|
height: 40.h,
|
||||||
|
isFullWidth: true,
|
||||||
|
onPressed: () {
|
||||||
|
Get.find<CreateInspectionBottomSheetLogic>().setHatchingModel(
|
||||||
|
item,
|
||||||
|
);
|
||||||
|
Get.bottomSheet(
|
||||||
|
CreateInspectionBottomSheet(),
|
||||||
|
isScrollControlled: true,
|
||||||
|
ignoreSafeArea: false,
|
||||||
|
).then((value) {
|
||||||
|
if (Get.isRegistered<CreateInspectionBottomSheetLogic>()) {
|
||||||
|
Get.find<CreateInspectionBottomSheetLogic>().clearForm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Text('ثبت بازرسی'),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/cupertino.dart' hide LinearGradient;
|
import 'package:flutter/cupertino.dart' hide LinearGradient;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart';
|
||||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
|
||||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.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/base_page/view.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/pou
|
|||||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/view.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/view.dart';
|
||||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart';
|
import 'package:rasadyar_chicken/features/poultry_science/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/routes/global_binding.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
@@ -38,56 +39,76 @@ class PoultrySciencePages {
|
|||||||
name: PoultryScienceRoutes.inspectionPoultryScience,
|
name: PoultryScienceRoutes.inspectionPoultryScience,
|
||||||
page: () => InspectionPoultrySciencePage(),
|
page: () => InspectionPoultrySciencePage(),
|
||||||
middlewares: [AuthMiddleware()],
|
middlewares: [AuthMiddleware()],
|
||||||
binding: BindingsBuilder(() {
|
bindings: [
|
||||||
|
GlobalBinding(),
|
||||||
|
BindingsBuilder(() {
|
||||||
Get.lazyPut(() => InspectionPoultryScienceLogic());
|
Get.lazyPut(() => InspectionPoultryScienceLogic());
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: PoultryScienceRoutes.actionPoultryScience,
|
name: PoultryScienceRoutes.actionPoultryScience,
|
||||||
page: () => PoultryActionPage(),
|
page: () => PoultryActionPage(),
|
||||||
middlewares: [AuthMiddleware()],
|
middlewares: [AuthMiddleware()],
|
||||||
binding: BindingsBuilder(() {
|
bindings: [
|
||||||
|
GlobalBinding(),
|
||||||
|
BindingsBuilder(() {
|
||||||
Get.lazyPut(() => PoultryActionLogic());
|
Get.lazyPut(() => PoultryActionLogic());
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: PoultryScienceRoutes.farmPoultryScience,
|
name: PoultryScienceRoutes.farmPoultryScience,
|
||||||
page: () => FarmPage(),
|
page: () => FarmPage(),
|
||||||
middlewares: [AuthMiddleware()],
|
middlewares: [AuthMiddleware()],
|
||||||
binding: BindingsBuilder(() {
|
bindings: [
|
||||||
|
GlobalBinding(),
|
||||||
|
|
||||||
|
BindingsBuilder(() {
|
||||||
Get.lazyPut(() => FarmLogic());
|
Get.lazyPut(() => FarmLogic());
|
||||||
Get.lazyPut(() => PoultryScienceHomeLogic());
|
Get.lazyPut(() => PoultryScienceHomeLogic());
|
||||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: PoultryScienceRoutes.activeHatchingPoultryScience,
|
name: PoultryScienceRoutes.activeHatchingPoultryScience,
|
||||||
page: () => ActiveHatchingPage(),
|
page: () => ActiveHatchingPage(),
|
||||||
middlewares: [AuthMiddleware()],
|
middlewares: [AuthMiddleware()],
|
||||||
binding: BindingsBuilder(() {
|
bindings: [
|
||||||
|
GlobalBinding(),
|
||||||
|
BindingsBuilder(() {
|
||||||
Get.lazyPut(() => ActiveHatchingLogic());
|
Get.lazyPut(() => ActiveHatchingLogic());
|
||||||
|
Get.lazyPut(() => CreateInspectionBottomSheetLogic(), fenix: true);
|
||||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: PoultryScienceRoutes.genocidePoultryScience,
|
name: PoultryScienceRoutes.genocidePoultryScience,
|
||||||
page: () => GenocidePage(),
|
page: () => GenocidePage(),
|
||||||
middlewares: [AuthMiddleware()],
|
middlewares: [AuthMiddleware()],
|
||||||
binding: BindingsBuilder(() {
|
bindings: [
|
||||||
|
GlobalBinding(),
|
||||||
|
BindingsBuilder(() {
|
||||||
Get.lazyPut(() => GenocideLogic());
|
Get.lazyPut(() => GenocideLogic());
|
||||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||||
Get.lazyPut(() => KillingRegistrationLogic(), fenix: true);
|
Get.lazyPut(() => KillingRegistrationLogic(), fenix: true);
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: PoultryScienceRoutes.killingRegistrationPoultryScience,
|
name: PoultryScienceRoutes.killingRegistrationPoultryScience,
|
||||||
page: () => KillingRegistrationPage(),
|
page: () => KillingRegistrationPage(),
|
||||||
middlewares: [AuthMiddleware()],
|
middlewares: [AuthMiddleware()],
|
||||||
binding: BindingsBuilder(() {
|
bindings: [
|
||||||
|
GlobalBinding(),
|
||||||
|
BindingsBuilder(() {
|
||||||
Get.lazyPut(() => KillingRegistrationLogic());
|
Get.lazyPut(() => KillingRegistrationLogic());
|
||||||
Get.lazyPut(() => GenocideLogic());
|
Get.lazyPut(() => GenocideLogic());
|
||||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
Widget farmInfoWidget({
|
||||||
|
required CreateInspectionBottomSheetLogic controller,
|
||||||
|
required String title,
|
||||||
|
required Widget child,
|
||||||
|
EdgeInsets? padding,
|
||||||
|
}) {
|
||||||
|
return Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(width: 0.50, color: AppColor.mediumGrey),
|
||||||
|
),
|
||||||
|
|
||||||
|
padding:
|
||||||
|
padding ?? EdgeInsets.symmetric(horizontal: 12.w, vertical: 11.h),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: -17,
|
||||||
|
right: 7,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(width: 0.50, color: AppColor.mediumGrey),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: AppFonts.yekan14.copyWith(color: AppColor.iconColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget cardInfo({required Widget child, EdgeInsets? padding}) {
|
||||||
|
return Container(
|
||||||
|
width: Get.width,
|
||||||
|
padding: padding ?? EdgeInsets.symmetric(horizontal: 12.w, vertical: 14.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.bgLight,
|
||||||
|
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(width: 1, color: AppColor.blackLight),
|
||||||
|
),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
import 'step1_page.dart';
|
||||||
|
import 'step2_page.dart';
|
||||||
|
import 'step3_page.dart';
|
||||||
|
import 'step4_page.dart';
|
||||||
|
import 'step5_page.dart';
|
||||||
|
|
||||||
|
class CreateInspectionBottomSheet
|
||||||
|
extends GetWidget<CreateInspectionBottomSheetLogic> {
|
||||||
|
CreateInspectionBottomSheet({super.key});
|
||||||
|
|
||||||
|
List<Widget> get pages => [
|
||||||
|
step1Page(controller),
|
||||||
|
step2Page(controller),
|
||||||
|
step3Page(controller),
|
||||||
|
step4Page(controller),
|
||||||
|
step5Page(controller),
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BaseBottomSheet(
|
||||||
|
height: Get.height,
|
||||||
|
rootChild: Column(
|
||||||
|
children: [
|
||||||
|
ObxValue((data) {
|
||||||
|
return stepper(activeStep: data.value);
|
||||||
|
}, controller.activeStepperIndex),
|
||||||
|
Expanded(
|
||||||
|
child: PageView.builder(
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
reverse: true,
|
||||||
|
controller: controller.pageController,
|
||||||
|
itemBuilder: (context, index) => pages[index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
spacing: 16,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ObxValue((data) {
|
||||||
|
return RElevated(
|
||||||
|
height: 40.h,
|
||||||
|
enabled: data.value,
|
||||||
|
backgroundColor: AppColor.greenNormal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
Icon(Icons.arrow_back_ios, color: Colors.white),
|
||||||
|
|
||||||
|
Text('ادامه'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.activeStepperIndex.value < 4) {
|
||||||
|
controller.activeStepperIndex.value++;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}, controller.nextStepButtonEnabled),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ROutlinedElevated(
|
||||||
|
borderColor: AppColor.error,
|
||||||
|
height: 40.h,
|
||||||
|
child: Text('برگشت'),
|
||||||
|
enabled: controller.activeStepperIndex.value > 0,
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.activeStepperIndex.value > 0) {
|
||||||
|
controller.activeStepperIndex.value--;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, controller.activeStepperIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class stepper extends StatelessWidget {
|
||||||
|
const stepper({super.key, required this.activeStep});
|
||||||
|
final int activeStep;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 24,
|
||||||
|
width: Get.width,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: activeStep >= 0
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
child: Text(
|
||||||
|
'1',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: AppFonts.yekan16.copyWith(
|
||||||
|
color: activeStep >= 0 ? Colors.white : AppColor.iconColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: activeStep >= 1
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
thickness: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: activeStep >= 1
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
child: Text(
|
||||||
|
'2',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: AppFonts.yekan16.copyWith(
|
||||||
|
color: activeStep >= 1 ? Colors.white : AppColor.iconColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: activeStep >= 2
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
thickness: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: activeStep >= 2
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
child: Text(
|
||||||
|
'3',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: AppFonts.yekan16.copyWith(
|
||||||
|
color: activeStep >= 2 ? Colors.white : AppColor.iconColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: activeStep >= 3
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
thickness: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: activeStep >= 3
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
child: Text(
|
||||||
|
'4',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: AppFonts.yekan16.copyWith(
|
||||||
|
color: activeStep >= 3 ? Colors.white : AppColor.iconColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Divider(
|
||||||
|
color: activeStep >= 4
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
thickness: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: activeStep >= 4
|
||||||
|
? AppColor.greenNormalHover
|
||||||
|
: AppColor.whiteNormalActive,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
child: Text(
|
||||||
|
'5',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: AppFonts.yekan16.copyWith(
|
||||||
|
color: activeStep >= 3 ? Colors.white : AppColor.iconColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,545 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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_core/core.dart';
|
||||||
|
|
||||||
|
class CreateInspectionBottomSheetLogic extends GetxController
|
||||||
|
with GetSingleTickerProviderStateMixin {
|
||||||
|
HatchingModel? hatchingModel;
|
||||||
|
|
||||||
|
PoultryScienceRepository repository = diChicken
|
||||||
|
.get<PoultryScienceRepository>();
|
||||||
|
|
||||||
|
TokenStorageService tokenStorageService = Get.find<TokenStorageService>();
|
||||||
|
|
||||||
|
RxInt selectedSegmentIndex = 0.obs;
|
||||||
|
|
||||||
|
|
||||||
|
RxInt expandedIndex = RxInt(-1);
|
||||||
|
|
||||||
|
late TabController tabController;
|
||||||
|
|
||||||
|
RxInt selectedTabIndex = 0.obs;
|
||||||
|
|
||||||
|
RxInt activeStepperIndex = 0.obs;
|
||||||
|
|
||||||
|
PageController pageController = PageController(initialPage: 0);
|
||||||
|
|
||||||
|
RxBool nextStepButtonEnabled = false.obs;
|
||||||
|
|
||||||
|
RxInt casualtiesInformationHeight = 300.obs;
|
||||||
|
|
||||||
|
//step1
|
||||||
|
|
||||||
|
TextEditingController unitNameController = TextEditingController();
|
||||||
|
TextEditingController breedingUniqueIdController = TextEditingController();
|
||||||
|
TextEditingController healthLicenseController = TextEditingController();
|
||||||
|
TextEditingController tenantStatusController = TextEditingController();
|
||||||
|
TextEditingController tenantNameController = TextEditingController();
|
||||||
|
TextEditingController tenantNationalIdController = TextEditingController();
|
||||||
|
TextEditingController tenantPhoneNumberController = TextEditingController();
|
||||||
|
TextEditingController ownerNameController = TextEditingController();
|
||||||
|
TextEditingController ownerNationalCodeController = TextEditingController();
|
||||||
|
TextEditingController ownerPhoneNumberController = TextEditingController();
|
||||||
|
TextEditingController totalCapacityController = TextEditingController();
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
TextEditingController hatchingDateController = TextEditingController();
|
||||||
|
TextEditingController visitDateController = TextEditingController();
|
||||||
|
TextEditingController hatchingCountController = TextEditingController();
|
||||||
|
TextEditingController hatchingAverageWeightController =
|
||||||
|
TextEditingController();
|
||||||
|
TextEditingController hatchingBreedController = TextEditingController();
|
||||||
|
|
||||||
|
//step2
|
||||||
|
Resource<List<String>> causeOfUnusualCasualtiesList = Resource.success([
|
||||||
|
'بیماری',
|
||||||
|
'قطعی برق',
|
||||||
|
'استرس گرمایی',
|
||||||
|
'مشکلات دان',
|
||||||
|
'کیفیت جوجه',
|
||||||
|
'سایر (شرح…)',
|
||||||
|
]);
|
||||||
|
RxnString causeOfUnusualCasualties = RxnString();
|
||||||
|
RxBool isOthercauseOfUnusualCasualties = false.obs;
|
||||||
|
TextEditingController otherCauseOfUnusualCasualtiesController =
|
||||||
|
TextEditingController();
|
||||||
|
|
||||||
|
Resource<List<String>> typeOfDiseaseList = Resource.success([
|
||||||
|
'آنفلوانزا',
|
||||||
|
'نیوکاسل',
|
||||||
|
'IB',
|
||||||
|
'عفونتهای باکتریایی',
|
||||||
|
'مشکلات گوارشی',
|
||||||
|
'سایر (شرح)',
|
||||||
|
]);
|
||||||
|
RxnString typeOfDisease = RxnString();
|
||||||
|
RxBool isOtherTypeOfDiseaseSelected = false.obs;
|
||||||
|
TextEditingController otherTypeOfDiseaseController = TextEditingController();
|
||||||
|
|
||||||
|
RxList<String> pultryImagesUrls = RxList<String>();
|
||||||
|
RxMap<XFile, bool> pultryImages = RxMap<XFile, bool>();
|
||||||
|
|
||||||
|
TextEditingController hatchingTemperatureController = TextEditingController();
|
||||||
|
TextEditingController waterHardnessController = TextEditingController();
|
||||||
|
|
||||||
|
TextEditingController normalLossesController = TextEditingController();
|
||||||
|
TextEditingController abnormalLossesController = TextEditingController();
|
||||||
|
TextEditingController sourceOfHatchingController = TextEditingController();
|
||||||
|
|
||||||
|
RxBool samplingDone = false.obs;
|
||||||
|
TextEditingController technicalHealthOfficerNameController =
|
||||||
|
TextEditingController();
|
||||||
|
TextEditingController technicalEngineeringOfficerNameController =
|
||||||
|
TextEditingController();
|
||||||
|
|
||||||
|
RxInt sanitaryConditionOfTheHallIndex = (-1).obs;
|
||||||
|
RxInt ventilationStatusIndex = (-1).obs;
|
||||||
|
RxnString sanitaryConditionOfTheHall = RxnString();
|
||||||
|
RxnString ventilationStatus = RxnString();
|
||||||
|
|
||||||
|
RxInt beddingStatusIndex = (-1).obs;
|
||||||
|
RxnString beddingStatus = RxnString();
|
||||||
|
RxInt waterQualityIndex = (-1).obs;
|
||||||
|
RxnString waterQuality = RxnString();
|
||||||
|
RxInt fuelTypeIndex = (-1).obs;
|
||||||
|
|
||||||
|
RxInt sampleTypeIndex = (-1).obs;
|
||||||
|
RxnString sampleType = RxnString();
|
||||||
|
|
||||||
|
//step3
|
||||||
|
|
||||||
|
Resource<List<String>> inputStatusList = Resource.success([
|
||||||
|
'وابسته',
|
||||||
|
'مستقل',
|
||||||
|
]);
|
||||||
|
RxnString inputStatus = RxnString();
|
||||||
|
TextEditingController companyNameController = TextEditingController();
|
||||||
|
TextEditingController trackingCodeController = TextEditingController();
|
||||||
|
|
||||||
|
Resource<List<String>> typeOfGrainList = Resource.success([
|
||||||
|
'آردی',
|
||||||
|
'پلت',
|
||||||
|
'کرامبل و اکسترود ',
|
||||||
|
'مش ',
|
||||||
|
'پوره و وال',
|
||||||
|
]);
|
||||||
|
RxnString typeOfGrain = RxnString();
|
||||||
|
|
||||||
|
TextEditingController inputInventoryInWarehouseController =
|
||||||
|
TextEditingController();
|
||||||
|
TextEditingController inputInventoryUntilVisitController =
|
||||||
|
TextEditingController();
|
||||||
|
|
||||||
|
TextEditingController generatorTypeController = TextEditingController();
|
||||||
|
TextEditingController generatorModelController = TextEditingController();
|
||||||
|
TextEditingController generatorCountController = TextEditingController();
|
||||||
|
TextEditingController generatorCapacityController = TextEditingController();
|
||||||
|
TextEditingController emergencyFuelInventoryController =
|
||||||
|
TextEditingController();
|
||||||
|
TextEditingController powerCutDurationController = TextEditingController();
|
||||||
|
TextEditingController powerCutHourController = TextEditingController();
|
||||||
|
TextEditingController additionalNotesController = TextEditingController();
|
||||||
|
RxnString fuelType = RxnString();
|
||||||
|
RxBool powerCutHistory = false.obs;
|
||||||
|
|
||||||
|
RxInt grainQualityInputIndex = (-1).obs;
|
||||||
|
RxnString grainQualityInput = RxnString();
|
||||||
|
RxInt generatorOperatingStatusIndex = (-1).obs;
|
||||||
|
RxnString generatorOperatingStatus = RxnString();
|
||||||
|
RxInt workerContractStatusIndex = (-1).obs;
|
||||||
|
RxnString workerContractStatus = RxnString();
|
||||||
|
RxInt newBeneficiaryRequestIndex = (-1).obs;
|
||||||
|
RxBool trainingStatus = false.obs;
|
||||||
|
RxnString newBeneficiaryRequest = RxnString();
|
||||||
|
RxBool overdueStatus = false.obs;
|
||||||
|
TextEditingController paymentYearController = TextEditingController();
|
||||||
|
Rx<Jalali> selectedPaymentYear = Jalali.now().obs;
|
||||||
|
|
||||||
|
//step3 - worker fields
|
||||||
|
TextEditingController employedWorkersCountController =
|
||||||
|
TextEditingController();
|
||||||
|
TextEditingController nativeWorkersCountController = TextEditingController();
|
||||||
|
TextEditingController nonNativeWorkersCountController =
|
||||||
|
TextEditingController();
|
||||||
|
|
||||||
|
TextEditingController activeFacilityController = TextEditingController();
|
||||||
|
TextEditingController facilityTypeController = TextEditingController();
|
||||||
|
TextEditingController facilityAmountController = TextEditingController();
|
||||||
|
|
||||||
|
//step4
|
||||||
|
|
||||||
|
TextEditingController facilityYearController = TextEditingController();
|
||||||
|
Rx<Jalali> selectedFacilityYear = Jalali.now().obs;
|
||||||
|
|
||||||
|
RxInt inspectorConclusionIndex = (-1).obs;
|
||||||
|
RxnString inspectorConclusion = RxnString();
|
||||||
|
|
||||||
|
TextEditingController inspectorConclusionDescriptionController =
|
||||||
|
TextEditingController();
|
||||||
|
|
||||||
|
RxList<String> hallImagesUrls = RxList<String>();
|
||||||
|
RxMap<XFile, bool> hallImages = RxMap<XFile, bool>();
|
||||||
|
|
||||||
|
RxList<String> inputWarehouseImagesUrls = RxList<String>();
|
||||||
|
RxMap<XFile, bool> inputWarehouseImages = RxMap<XFile, bool>();
|
||||||
|
|
||||||
|
RxList<String> lossesImagesUrls = RxList<String>();
|
||||||
|
RxMap<XFile, bool> lossesImages = RxMap<XFile, bool>();
|
||||||
|
|
||||||
|
//location
|
||||||
|
Rxn<LatLng> currentLocation = Rxn<LatLng>();
|
||||||
|
RxBool isLoadingLocation = false.obs;
|
||||||
|
|
||||||
|
//images
|
||||||
|
ImagePicker imagePicker = ImagePicker();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
activeStepperIndex.listen((value) {
|
||||||
|
pageController.animateToPage(
|
||||||
|
value,
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
curve: Curves.linear,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
initData();
|
||||||
|
setUpNextButtonListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
// TODO: implement onClose
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initData() {
|
||||||
|
unitNameController.text =
|
||||||
|
hatchingModel?.poultry?.unitName ?? 'واحد مرغداری نامشخص';
|
||||||
|
|
||||||
|
breedingUniqueIdController.text =
|
||||||
|
hatchingModel?.poultry?.breedingUniqueId ?? 'کد یکتا/شناسه واحد نامشخص';
|
||||||
|
|
||||||
|
healthLicenseController.text =
|
||||||
|
hatchingModel?.poultry?.healthCertificateNumber ??
|
||||||
|
'پروانه بهداشتی ندارد ';
|
||||||
|
|
||||||
|
tenantStatusController.text = (hatchingModel?.poultry?.hasTenant == true)
|
||||||
|
? 'دارد'
|
||||||
|
: 'ندارد';
|
||||||
|
|
||||||
|
if (hatchingModel?.poultry?.hasTenant == true) {
|
||||||
|
tenantNameController.text =
|
||||||
|
hatchingModel?.tenantFullname ?? 'نام مستاجر نامشخص';
|
||||||
|
tenantNationalIdController.text =
|
||||||
|
hatchingModel?.tenantNationalCode ?? 'کد ملی مستاجر نامشخص';
|
||||||
|
tenantPhoneNumberController.text =
|
||||||
|
hatchingModel?.tenantMobile ?? 'شماره تماس مستاجر نامشخص';
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerNameController.text =
|
||||||
|
hatchingModel?.poultry?.user?.fullname ?? 'مالک واحد مرغداری نامشخص';
|
||||||
|
ownerNationalCodeController.text =
|
||||||
|
hatchingModel?.chainCompany?.user?.nationalId ??
|
||||||
|
'کد ملی مالک واحد مرغداری نامشخص';
|
||||||
|
ownerPhoneNumberController.text =
|
||||||
|
hatchingModel?.poultry?.user?.mobile ??
|
||||||
|
'شماره تماس مالک واحد مرغداری نامشخص';
|
||||||
|
totalCapacityController.text =
|
||||||
|
hatchingModel?.poultry?.totalCapacity?.toString() ??
|
||||||
|
'ظرفیت اسمی سالنها نامشخص';
|
||||||
|
|
||||||
|
hatchingDateController.text =
|
||||||
|
hatchingModel?.date?.toJalali.formatCompactDate() ??
|
||||||
|
'تاریخ جوجه ریزی نامشخص';
|
||||||
|
hatchingCountController.text =
|
||||||
|
hatchingModel?.quantity?.separatedByComma ?? 'تعداد جوجه ریزی نامشخص';
|
||||||
|
|
||||||
|
hatchingBreedController.text =
|
||||||
|
hatchingModel?.chickenBreed ?? 'نوع نژاد نامشخص';
|
||||||
|
|
||||||
|
visitDateController.text = Jalali.now().formatCompactDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleExpanded(int index) {
|
||||||
|
expandedIndex.value = expandedIndex.value == index ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHatchingModel(HatchingModel hatchingModel) {
|
||||||
|
this.hatchingModel = hatchingModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void changeSegmentIndex(int index) {
|
||||||
|
if (index == selectedSegmentIndex.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
expandedIndex.value = -1;
|
||||||
|
selectedSegmentIndex.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void changeTab(int index) {
|
||||||
|
if (index == selectedTabIndex.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedTabIndex.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearForm() {
|
||||||
|
unitNameController.clear();
|
||||||
|
activeStepperIndex.value = 0;
|
||||||
|
selectedTabIndex.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSanitaryConditionOfTheHallIndex(int index, String item) {
|
||||||
|
sanitaryConditionOfTheHall.value = item;
|
||||||
|
sanitaryConditionOfTheHallIndex.value =
|
||||||
|
index == sanitaryConditionOfTheHallIndex.value ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFuelTypeIndex(int index, String item) {
|
||||||
|
fuelType.value = item;
|
||||||
|
fuelTypeIndex.value = index == fuelTypeIndex.value ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVentilationStatusIndex(int index, String item) {
|
||||||
|
ventilationStatus.value = item;
|
||||||
|
ventilationStatusIndex.value = index == ventilationStatusIndex.value
|
||||||
|
? -1
|
||||||
|
: index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBeddingStatusIndex(int index, String item) {
|
||||||
|
beddingStatus.value = item;
|
||||||
|
beddingStatusIndex.value = index == beddingStatusIndex.value ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWaterQualityIndex(int index, String item) {
|
||||||
|
waterQuality.value = item;
|
||||||
|
waterQualityIndex.value = index == waterQualityIndex.value ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSampleTypeIndex(int index, String item) {
|
||||||
|
sampleType.value = item;
|
||||||
|
sampleTypeIndex.value = index == sampleTypeIndex.value ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setGrainQualityInput(int index, String item) {
|
||||||
|
grainQualityInput.value = item;
|
||||||
|
grainQualityInputIndex.value = index == grainQualityInputIndex.value
|
||||||
|
? -1
|
||||||
|
: index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setGeneratorOperatingStatusIndex(int index, String item) {
|
||||||
|
generatorOperatingStatus.value = item;
|
||||||
|
generatorOperatingStatusIndex.value =
|
||||||
|
index == generatorOperatingStatusIndex.value ? -1 : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWorkerContractStatusIndex(int index, String item) {
|
||||||
|
workerContractStatus.value = item;
|
||||||
|
|
||||||
|
workerContractStatusIndex.value = index == workerContractStatusIndex.value
|
||||||
|
? -1
|
||||||
|
: index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNewBeneficiaryRequestIndex(int index) {
|
||||||
|
newBeneficiaryRequestIndex.value = index == newBeneficiaryRequestIndex.value
|
||||||
|
? -1
|
||||||
|
: index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInspectorConclusionIndex(int index, String item) {
|
||||||
|
inspectorConclusion.value = item;
|
||||||
|
inspectorConclusionIndex.value = index == inspectorConclusionIndex.value
|
||||||
|
? -1
|
||||||
|
: index;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getCurrentLocation() async {
|
||||||
|
isLoadingLocation.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final hasPermission = await checkLocationPermission(request: true);
|
||||||
|
if (!hasPermission) {
|
||||||
|
throw Exception('دسترسی به موقعیت مکانی داده نشده است');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current location
|
||||||
|
final latLng = await determineCurrentLatLng();
|
||||||
|
currentLocation.value = latLng;
|
||||||
|
isLoadingLocation.value = false;
|
||||||
|
setUpNextButtonListeners();
|
||||||
|
} catch (e) {
|
||||||
|
isLoadingLocation.value = false;
|
||||||
|
currentLocation.value = null;
|
||||||
|
nextStepButtonEnabled.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpNextButtonListeners() {
|
||||||
|
if (activeStepperIndex.value == 0) {
|
||||||
|
nextStepButtonEnabled.value = currentLocation.value != null;
|
||||||
|
} else {
|
||||||
|
nextStepButtonEnabled.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> pickImageFromCamera() async {
|
||||||
|
try {
|
||||||
|
final XFile? image = await imagePicker.pickImage(
|
||||||
|
source: ImageSource.camera,
|
||||||
|
imageQuality: 50,
|
||||||
|
maxWidth: 1080,
|
||||||
|
maxHeight: 720,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (image != null) {
|
||||||
|
pultryImages[image] = false;
|
||||||
|
|
||||||
|
//await uploadImage(image);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Get.snackbar(
|
||||||
|
'خطا',
|
||||||
|
'خطا در باز کردن دوربین',
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
colorText: Colors.white,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> uploadImage(XFile imageFile) async {
|
||||||
|
await safeCall(
|
||||||
|
call: () async {
|
||||||
|
final urls = await repository.uploadImages(
|
||||||
|
token: tokenStorageService.accessToken.value ?? '',
|
||||||
|
images: [imageFile],
|
||||||
|
);
|
||||||
|
return urls;
|
||||||
|
},
|
||||||
|
onSuccess: (urls) {
|
||||||
|
if (urls != null) {
|
||||||
|
pultryImagesUrls.addAll(urls);
|
||||||
|
}
|
||||||
|
pultryImages[imageFile] = true;
|
||||||
|
},
|
||||||
|
onError: (error, e) {
|
||||||
|
pultryImages[imageFile] = false;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeImage(XFile image) {
|
||||||
|
pultryImages.remove(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTypeOfDiseaseIndex(String item) {
|
||||||
|
if (isOtherTypeOfDiseaseSelected.value && item != 'سایر (شرح)') {
|
||||||
|
casualtiesInformationHeight.value =
|
||||||
|
casualtiesInformationHeight.value - 50;
|
||||||
|
}
|
||||||
|
typeOfDisease.value = item;
|
||||||
|
isOtherTypeOfDiseaseSelected.value = item == 'سایر (شرح)';
|
||||||
|
if (isOtherTypeOfDiseaseSelected.value && item == 'سایر (شرح)') {
|
||||||
|
casualtiesInformationHeight.value =
|
||||||
|
casualtiesInformationHeight.value + 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCauseOfUnusualCasualtiesIndex(String item) {
|
||||||
|
if (isOthercauseOfUnusualCasualties.value && item != 'سایر (شرح…)') {
|
||||||
|
casualtiesInformationHeight.value =
|
||||||
|
casualtiesInformationHeight.value - 50;
|
||||||
|
}
|
||||||
|
causeOfUnusualCasualties.value = item;
|
||||||
|
isOthercauseOfUnusualCasualties.value = item == 'سایر (شرح…)';
|
||||||
|
if (item == 'سایر (شرح…)') {
|
||||||
|
casualtiesInformationHeight.value =
|
||||||
|
casualtiesInformationHeight.value + 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSamplingDone(String value) {
|
||||||
|
if (samplingDone.value && value != 'انجام شد') {
|
||||||
|
casualtiesInformationHeight.value =
|
||||||
|
casualtiesInformationHeight.value -80;
|
||||||
|
}
|
||||||
|
samplingDone.value = value == 'انجام شد';
|
||||||
|
if (value == 'انجام شد') {
|
||||||
|
casualtiesInformationHeight.value =
|
||||||
|
casualtiesInformationHeight.value + 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInputStatus(String item) {
|
||||||
|
inputStatus.value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTypeOfGrain(String item) {
|
||||||
|
typeOfGrain.value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFuelType(String item) {
|
||||||
|
fuelType.value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPowerCutHistory(String item) {
|
||||||
|
powerCutHistory.value = item == 'دارد';
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTrainingStatus(String item) {
|
||||||
|
trainingStatus.value = item == 'بله';
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNewBeneficiaryRequest(String item) {
|
||||||
|
newBeneficiaryRequest.value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOverdueStatus(String item) {
|
||||||
|
overdueStatus.value = item == 'دارای معوقه';
|
||||||
|
}
|
||||||
|
|
||||||
|
void showPaymentYearDatePicker() {
|
||||||
|
Get.bottomSheet(
|
||||||
|
modalDatePicker(
|
||||||
|
initialDate: selectedPaymentYear.value,
|
||||||
|
onDateSelected: (value) {
|
||||||
|
selectedPaymentYear.value = value;
|
||||||
|
paymentYearController.text = value.formatCompactDate();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFacilityYearDatePicker() {
|
||||||
|
Get.bottomSheet(
|
||||||
|
modalDatePicker(
|
||||||
|
initialDate: selectedFacilityYear.value,
|
||||||
|
onDateSelected: (value) {
|
||||||
|
selectedFacilityYear.value = value;
|
||||||
|
facilityYearController.text = value.formatCompactDate();
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeHallImage(XFile key) {
|
||||||
|
hallImages.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeInputWarehouseImage(XFile key) {
|
||||||
|
inputWarehouseImages.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeLossesImage(XFile key) {
|
||||||
|
lossesImages.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,232 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
Widget step1Page(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 25.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: controller.tenantStatusController.text == 'دارد'
|
||||||
|
? 570.h
|
||||||
|
: 445.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'اطلاعات پایه واحد',
|
||||||
|
child: basicUnitInformation(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 30.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 280.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'اطلاعات جوجه ریزی',
|
||||||
|
child: hatchingInformation(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column basicUnitInformation(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.unitNameController,
|
||||||
|
label: 'نام واحد مرغداری',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
readonly: true,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.breedingUniqueIdController,
|
||||||
|
label: 'کد یکتا / شناسه واحد',
|
||||||
|
filled: true,
|
||||||
|
readonly: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.healthLicenseController,
|
||||||
|
label: 'پروانه بهداشتی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.tenantStatusController,
|
||||||
|
label: 'وضعیت مستاجر',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
|
||||||
|
Visibility(
|
||||||
|
child: controller.tenantStatusController.text == 'دارد'
|
||||||
|
? Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
RTextField(
|
||||||
|
controller: controller.tenantNameController,
|
||||||
|
label: 'نام مستاجر',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.tenantNationalIdController,
|
||||||
|
label: 'کد ملی مستاجر',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.tenantPhoneNumberController,
|
||||||
|
label: 'شماره تماس مستاجر',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.ownerNationalCodeController,
|
||||||
|
label: 'کد ملی بهرهبردار',
|
||||||
|
filled: true,
|
||||||
|
readonly: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.ownerPhoneNumberController,
|
||||||
|
label: 'شماره تماس بهرهبردار',
|
||||||
|
filled: true,
|
||||||
|
readonly: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.totalCapacityController,
|
||||||
|
label: 'ظرفیت اسمی سالنها',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
|
||||||
|
Obx(
|
||||||
|
() => RElevated(
|
||||||
|
isFullWidth: true,
|
||||||
|
height: 40.h,
|
||||||
|
enabled: !controller.isLoadingLocation.value,
|
||||||
|
|
||||||
|
backgroundColor: AppColor.greenNormal,
|
||||||
|
onPressed: controller.isLoadingLocation.value
|
||||||
|
? null
|
||||||
|
: () => controller.getCurrentLocation(),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 4,
|
||||||
|
children: [
|
||||||
|
if (controller.isLoadingLocation.value)
|
||||||
|
SizedBox(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Icon(Icons.my_location_rounded, color: Colors.white, size: 24),
|
||||||
|
Text(
|
||||||
|
controller.currentLocation.value == null
|
||||||
|
? 'دریافت موقعیت جغرافیایی'
|
||||||
|
: 'موقعیت جغرافیایی دریافت شد',
|
||||||
|
|
||||||
|
style: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column hatchingInformation(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.hatchingDateController,
|
||||||
|
label: 'تاریخ جوجه ریزی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
readonly: true,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.visitDateController,
|
||||||
|
label: 'تاریخ بازدید',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
readonly: true,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.hatchingCountController,
|
||||||
|
label: 'تعداد جوجهریزی اولیه',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
readonly: true,
|
||||||
|
),
|
||||||
|
|
||||||
|
/* ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['سرابی', 'پژدر', 'روتوایلر', 'دیگر']),
|
||||||
|
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'نوع نژاد'),
|
||||||
|
), */
|
||||||
|
|
||||||
|
/* RTextField(
|
||||||
|
controller: controller.unitNameController,
|
||||||
|
label: 'گرید جوجه',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
readonly: true,
|
||||||
|
), */
|
||||||
|
RTextField(
|
||||||
|
controller: controller.hatchingBreedController,
|
||||||
|
label: 'نوع نژاد',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.hatchingAverageWeightController,
|
||||||
|
label: 'میانگین وزن جوجه',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,654 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
import 'create_inspection_bottom_sheet_logic.dart';
|
||||||
|
|
||||||
|
Widget step2Page(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 35.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 580.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'وضعیت عمومی سالن',
|
||||||
|
child: generalConditionOfTheHall(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 30.h),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Container(
|
||||||
|
height: data.value.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'تلفات',
|
||||||
|
child: casualtiesInformation(controller),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, controller.casualtiesInformationHeight),
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 130.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'بیماریها و وضعیت سلامت',
|
||||||
|
child: diseasesAndHealthInformation(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column generalConditionOfTheHall(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox.shrink(),
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 12, 12, 6),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
// Fix: Use spread .entries.map for map iteration, and correct image argument
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
...controller.pultryImages.entries
|
||||||
|
.map(
|
||||||
|
(entry) => Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.file(
|
||||||
|
File(entry.key.path),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Delete button
|
||||||
|
Positioned(
|
||||||
|
top: -4,
|
||||||
|
right: -4,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () =>
|
||||||
|
controller.removeImage(entry.key),
|
||||||
|
child: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.red,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Upload indicator
|
||||||
|
if (entry.value == false)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(
|
||||||
|
Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
// Add image button
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => controller.pickImageFromCamera(),
|
||||||
|
child: Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
padding: EdgeInsets.all(22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFE9E9E9),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Assets.vec.galleryAddSvg.svg(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'تعداد موجود فعلی',
|
||||||
|
style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'وضعیت بهداشتی سالن',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'عالی',
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setSanitaryConditionOfTheHallIndex(index, 'عالی'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'خوب',
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setSanitaryConditionOfTheHallIndex(index, 'خوب'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'متوسط',
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setSanitaryConditionOfTheHallIndex(index, 'متوسط'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 3,
|
||||||
|
label: 'ضعیف',
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setSanitaryConditionOfTheHallIndex(index, 'ضعیف'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.sanitaryConditionOfTheHallIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'وضعیت تهویه',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setVentilationStatusIndex(index, 'عالی'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'عالی',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setVentilationStatusIndex(index, 'خوب'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'خوب',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setVentilationStatusIndex(index, 'متوسط'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'متوسط',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setVentilationStatusIndex(index, 'ضعیف'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 3,
|
||||||
|
label: 'ضعیف',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.ventilationStatusIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'وضعیت بستر',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setBeddingStatusIndex(index, 'خشک'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'خشک',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setBeddingStatusIndex(index, 'نیمهمرطوب'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'نیمهمرطوب',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setBeddingStatusIndex(index, 'مرطوب'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'مرطوب',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.beddingStatusIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.hatchingTemperatureController,
|
||||||
|
label: 'دمای سالن',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
minLines: 1,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
' آب مصرفی',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setWaterQualityIndex(index, 'چاه'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'چاه',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setWaterQualityIndex(index, 'شهری'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'شهری',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setWaterQualityIndex(index, 'تصفیهشده'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'تصفیهشده',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setWaterQualityIndex(index, 'حمل تانکر'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 3,
|
||||||
|
label: 'حمل تانکر',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.waterQualityIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.waterHardnessController,
|
||||||
|
label: 'درصد سختی آب (PPM)',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
minLines: 1,
|
||||||
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChoiceChip formChips({
|
||||||
|
required int selectedIndex,
|
||||||
|
required int index,
|
||||||
|
required String label,
|
||||||
|
required Function(int) onTap,
|
||||||
|
}) {
|
||||||
|
return ChoiceChip(
|
||||||
|
selectedColor: AppColor.green1Normal,
|
||||||
|
labelStyle: index == selectedIndex
|
||||||
|
? AppFonts.yekan14Bold.copyWith(color: Colors.white)
|
||||||
|
: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||||
|
surfaceTintColor: Colors.white,
|
||||||
|
checkmarkColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
side: index == selectedIndex
|
||||||
|
? BorderSide.none
|
||||||
|
: BorderSide(width: 1, color: AppColor.blackLightHover),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
|
||||||
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
label: Text(label),
|
||||||
|
selected: index == selectedIndex,
|
||||||
|
onSelected: (value) => onTap(index),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column casualtiesInformation(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.normalLossesController,
|
||||||
|
label: 'تعداد تلفات عادی دوره',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
maxLines: 1,
|
||||||
|
minLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.abnormalLossesController,
|
||||||
|
label: 'تلفات غیرعادی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
maxLines: 1,
|
||||||
|
minLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: controller.causeOfUnusualCasualtiesList,
|
||||||
|
onChanged: (item) => controller.setCauseOfUnusualCasualtiesIndex(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'علت تلفات غیرعادی'),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Visibility(
|
||||||
|
visible: data.value,
|
||||||
|
child: RTextField(
|
||||||
|
controller: controller.otherCauseOfUnusualCasualtiesController,
|
||||||
|
label: 'علت تلفات غیرعادی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
minLines: 1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, controller.isOthercauseOfUnusualCasualties),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: controller.typeOfDiseaseList,
|
||||||
|
onChanged: (item) => controller.setTypeOfDiseaseIndex(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) =>
|
||||||
|
Text(selected ?? 'نوع بیماری تشخیص دادهشده / مشکوک'),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Visibility(
|
||||||
|
visible: data.value,
|
||||||
|
child: RTextField(
|
||||||
|
controller: controller.otherTypeOfDiseaseController,
|
||||||
|
label: 'نوع بیماری',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
minLines: 1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, controller.isOtherTypeOfDiseaseSelected),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['انجام شد', 'انجام نشد']),
|
||||||
|
onChanged: (item) => controller.setSamplingDone(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'نمونهبرداری انجامشده'),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Visibility(
|
||||||
|
visible: data.value,
|
||||||
|
child: cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'نوع نمونه',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(
|
||||||
|
color: AppColor.textColor2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setSampleTypeIndex(index, 'لاشه'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'لاشه',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setSampleTypeIndex(index, 'آب'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'آب',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setSampleTypeIndex(index, 'دانه'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'دانه',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.sampleTypeIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, controller.samplingDone),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column diseasesAndHealthInformation(
|
||||||
|
CreateInspectionBottomSheetLogic controller,
|
||||||
|
) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.technicalHealthOfficerNameController,
|
||||||
|
label: 'نام مسئول فنی بهداشتی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.technicalEngineeringOfficerNameController,
|
||||||
|
label: 'نام مسئول فنی نظام مهندسی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
GestureDetector containerChips({
|
||||||
|
required int selectedIndex,
|
||||||
|
required int index,
|
||||||
|
required String label,
|
||||||
|
required Function(int) onTap,
|
||||||
|
}) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => onTap(index),
|
||||||
|
child: Container(
|
||||||
|
height: 24.h,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: index == selectedIndex
|
||||||
|
? AppColor.green1Normal
|
||||||
|
: AppColor.whiteGreyNormal,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: index == selectedIndex
|
||||||
|
? Border.fromBorderSide(BorderSide.none)
|
||||||
|
: Border.all(width: 1, color: AppColor.blackLightHover),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 5,
|
||||||
|
children: [
|
||||||
|
if (index == selectedIndex)
|
||||||
|
Icon(Icons.check, color: Colors.white, size: 16),
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: index == selectedIndex
|
||||||
|
? AppFonts.yekan14Bold.copyWith(color: Colors.white)
|
||||||
|
: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,517 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
import 'create_inspection_bottom_sheet_logic.dart';
|
||||||
|
|
||||||
|
Widget step3Page(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 35.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 350.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'نهاده و خوراک',
|
||||||
|
child: agriculturalInput(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 30.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 600.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'زیرساخت و انرژی',
|
||||||
|
child: infrastructureAndEnergy(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 310.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'نیروی انسانی',
|
||||||
|
child: humanResources(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 320.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'تسهیلات و حمایتها',
|
||||||
|
child: facilitiesAndSupport(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column infrastructureAndEnergy(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.generatorTypeController,
|
||||||
|
label: 'نوع ژنراتور',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.generatorModelController,
|
||||||
|
label: 'مدل ژنراتور',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.generatorCountController,
|
||||||
|
label: 'تعداد ژنراتور',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['گازوئیل', 'نفت گاز']),
|
||||||
|
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'نوع سوخت'),
|
||||||
|
onChanged: (item) => controller.setFuelType(item),
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.generatorCapacityController,
|
||||||
|
label: 'ظرفیت (KVA)',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'وضعیت عملکرد ژنراتور',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setGeneratorOperatingStatusIndex(index, 'سالم'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'سالم',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setGeneratorOperatingStatusIndex(index, 'نیمهسالم'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'نیمهسالم',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller
|
||||||
|
.setGeneratorOperatingStatusIndex(index, 'معیوب'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'معیوب',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.generatorOperatingStatusIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.emergencyFuelInventoryController,
|
||||||
|
label: 'میزان موجودی سوخت اضطراری (لیتر)',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['ندارد', 'دارد']),
|
||||||
|
onChanged: (item) => controller.setPowerCutHistory(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) =>
|
||||||
|
Text(selected ?? 'سابقه قطعی برق دوره جاری'),
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.powerCutDurationController,
|
||||||
|
label: 'مدت قطعی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.powerCutHourController,
|
||||||
|
label: 'ساعت قطعی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.additionalNotesController,
|
||||||
|
label: 'توضیحات تکمیلی',
|
||||||
|
filled: true,
|
||||||
|
maxLines: 5,
|
||||||
|
minLines: 5,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column agriculturalInput(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox.shrink(),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: controller.inputStatusList,
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'وضعیت نهاده'),
|
||||||
|
onChanged: (item) => controller.setInputStatus(item),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
if (data.value == 'وابسته') {
|
||||||
|
return RTextField(
|
||||||
|
controller: controller.companyNameController,
|
||||||
|
label: 'نام کارخانه',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return RTextField(
|
||||||
|
controller: controller.trackingCodeController,
|
||||||
|
label: 'شناسه خرید یا کد پیگیری',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, controller.inputStatus),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.inputInventoryUntilVisitController,
|
||||||
|
label: 'موجودی نهاده مصرفی تا روز بازدید (کیلوگرم)',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: controller.typeOfGrainList,
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'نوع دان'),
|
||||||
|
onChanged: (item) => controller.setTypeOfGrain(item),
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.inputInventoryInWarehouseController,
|
||||||
|
label: 'موجودی نهاده موجود در انبار (کیلوگرم)',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'کیفیت دانه',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setGrainQualityInput(index, 'متوسط'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'خوب',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setGrainQualityInput(index, 'خوب'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'متوسط',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) =>
|
||||||
|
controller.setGrainQualityInput(index, 'ضعیف'),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'ضعیف',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.grainQualityInputIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column humanResources(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.employedWorkersCountController,
|
||||||
|
label: 'تعداد افراد شاغل',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.nativeWorkersCountController,
|
||||||
|
label: 'تعداد افراد بومی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.nonNativeWorkersCountController,
|
||||||
|
label: 'تعداد افراد غیر بومی',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'وضعیت قرارداد کارگران',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller.setWorkerContractStatusIndex(
|
||||||
|
index,
|
||||||
|
'دائم',
|
||||||
|
),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'دائم',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller.setWorkerContractStatusIndex(
|
||||||
|
index,
|
||||||
|
'موقت',
|
||||||
|
),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'موقت',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller.setWorkerContractStatusIndex(
|
||||||
|
index,
|
||||||
|
'روزمزدی',
|
||||||
|
),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'روزمزدی',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.workerContractStatusIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['بله', 'خیر']),
|
||||||
|
onChanged: (item) => controller.setTrainingStatus(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) =>
|
||||||
|
Text(selected ?? 'آموزشدیده در حوزه بهداشت و امنیت زیستی'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column facilitiesAndSupport(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.activeFacilityController,
|
||||||
|
label: 'تسهیلات دریافتی فعال',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.facilityTypeController,
|
||||||
|
label: 'نوع تسهیلات',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
controller: controller.facilityAmountController,
|
||||||
|
label: 'مبلغ',
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
SeparatorInputFormatter(),
|
||||||
|
],
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
RTextField(
|
||||||
|
controller: controller.paymentYearController,
|
||||||
|
label: 'سال دریافت',
|
||||||
|
filled: true,
|
||||||
|
readonly: true,
|
||||||
|
onTap: () => controller.showPaymentYearDatePicker(),
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['دارای معوقه', 'منظم']),
|
||||||
|
onChanged: (item) => controller.setOverdueStatus(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'وضعیت بازپرداخت'),
|
||||||
|
),
|
||||||
|
|
||||||
|
ResourceOverlayDropdown(
|
||||||
|
items: Resource.success(['نهاده', 'تسهیلات', 'واکسن', 'تجهیزات']),
|
||||||
|
onChanged: (item) => controller.setNewBeneficiaryRequest(item),
|
||||||
|
itemBuilder: (item) => Text(item),
|
||||||
|
labelBuilder: (selected) => Text(selected ?? 'درخواست جدید بهره بردار'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,495 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
import 'create_inspection_bottom_sheet_logic.dart';
|
||||||
|
|
||||||
|
Widget step4Page(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 35.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 430.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'مستندات',
|
||||||
|
child: documents(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 30.h),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 235.h,
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
width: Get.width,
|
||||||
|
child: farmInfoWidget(
|
||||||
|
controller: controller,
|
||||||
|
title: 'جمعبندی بازرس',
|
||||||
|
child: inspectorConclusion(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24.h),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column documents(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 12, 12, 6),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 10.h),
|
||||||
|
Obx(
|
||||||
|
() => SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
...controller.hallImages.entries
|
||||||
|
.map(
|
||||||
|
(entry) => Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.file(
|
||||||
|
File(entry.key.path),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Delete button
|
||||||
|
Positioned(
|
||||||
|
top: -4,
|
||||||
|
right: -4,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () =>
|
||||||
|
controller.removeImage(entry.key),
|
||||||
|
child: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.red,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Upload indicator
|
||||||
|
if (entry.value == false)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(
|
||||||
|
Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
// Add image button
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => controller.pickImageFromCamera(),
|
||||||
|
child: Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
padding: EdgeInsets.all(22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFE9E9E9),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Assets.vec.galleryAddSvg.svg(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: 'ثبت عکس سالن (حداقل ۳ زاویه) ',
|
||||||
|
style: AppFonts.yekan14.copyWith(
|
||||||
|
color: AppColor.textColorLight,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: '*',
|
||||||
|
style: AppFonts.yekan14.copyWith(color: Colors.red),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 12, 12, 6),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
...controller.inputWarehouseImages.entries
|
||||||
|
.map(
|
||||||
|
(entry) => Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.file(
|
||||||
|
File(entry.key.path),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Delete button
|
||||||
|
Positioned(
|
||||||
|
top: -4,
|
||||||
|
right: -4,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => controller
|
||||||
|
.removeInputWarehouseImage(entry.key),
|
||||||
|
child: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.red,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Upload indicator
|
||||||
|
if (entry.value == false)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(
|
||||||
|
Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
// Add image button
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => controller.pickImageFromCamera(),
|
||||||
|
child: Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
padding: EdgeInsets.all(22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFE9E9E9),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Assets.vec.galleryAddSvg.svg(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'ثبت عکس انبار نهادهها',
|
||||||
|
style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 12, 12, 6),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
...controller.lossesImages.entries
|
||||||
|
.map(
|
||||||
|
(entry) => Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Image.file(
|
||||||
|
File(entry.key.path),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Delete button
|
||||||
|
Positioned(
|
||||||
|
top: -4,
|
||||||
|
right: -4,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => controller
|
||||||
|
.removeInputWarehouseImage(entry.key),
|
||||||
|
child: Container(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.red,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Upload indicator
|
||||||
|
if (entry.value == false)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(
|
||||||
|
Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
// Add image button
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => controller.pickImageFromCamera(),
|
||||||
|
child: Container(
|
||||||
|
height: 80.h,
|
||||||
|
width: 80.w,
|
||||||
|
padding: EdgeInsets.all(22),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFE9E9E9),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Assets.vec.galleryAddSvg.svg(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'ثبت عکس تلفات',
|
||||||
|
style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column inspectorConclusion(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 1.h),
|
||||||
|
|
||||||
|
cardInfo(
|
||||||
|
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 9,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'وضعیت کلی واحد',
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2),
|
||||||
|
),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller.setInspectorConclusionIndex(
|
||||||
|
index,
|
||||||
|
'تایید شده',
|
||||||
|
),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 0,
|
||||||
|
label: 'تایید شده',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller.setInspectorConclusionIndex(
|
||||||
|
index,
|
||||||
|
'نیازمند اصلاح',
|
||||||
|
),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 1,
|
||||||
|
label: 'نیازمند اصلاح',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: containerChips(
|
||||||
|
onTap: (index) => controller.setInspectorConclusionIndex(
|
||||||
|
index,
|
||||||
|
'پرریسک',
|
||||||
|
),
|
||||||
|
selectedIndex: data.value,
|
||||||
|
index: 2,
|
||||||
|
label: 'پرریسک',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, controller.inspectorConclusionIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
RTextField(
|
||||||
|
height: 100.h,
|
||||||
|
controller: controller.inspectorConclusionDescriptionController,
|
||||||
|
hintText: 'توصیهها / اخطارها / اقدامات اصلاحی ...',
|
||||||
|
hintStyle: AppFonts.yekan14.copyWith(color: AppColor.textColorLight),
|
||||||
|
maxLines: 5,
|
||||||
|
minLines: 5,
|
||||||
|
filled: true,
|
||||||
|
filledColor: AppColor.bgLight,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,599 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart';
|
||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Widget step5Page(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: BouncingScrollPhysics(),
|
||||||
|
child: detailsWidget(controller),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget detailsWidget(CreateInspectionBottomSheetLogic controller) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
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),
|
||||||
|
ObxValue((data) {
|
||||||
|
return tabBarWidget(
|
||||||
|
['اطلاعات', 'پاییش سلامت', 'زیرساخت', 'مستندات'],
|
||||||
|
controller.selectedTabIndex.value,
|
||||||
|
(index) => controller.changeTab(index),
|
||||||
|
);
|
||||||
|
}, controller.selectedTabIndex),
|
||||||
|
|
||||||
|
ObxValue((data) {
|
||||||
|
switch (data.value) {
|
||||||
|
case 0:
|
||||||
|
return infoTable();
|
||||||
|
case 1:
|
||||||
|
return healthTable();
|
||||||
|
case 2:
|
||||||
|
return infrastructureTable();
|
||||||
|
case 3:
|
||||||
|
return documentsTable();
|
||||||
|
default:
|
||||||
|
return infoTable();
|
||||||
|
}
|
||||||
|
}, controller.selectedTabIndex),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
// Expanded در سطح بالاتر
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Column infoTable() {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
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: 'لذیذ'),
|
||||||
|
rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'),
|
||||||
|
rTableRow(title: 'نام مالک / بهرهبردار', value: 'مرغداری احمدی'),
|
||||||
|
rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'),
|
||||||
|
rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'),
|
||||||
|
|
||||||
|
rTableRow(title: 'سالن', value: '2'),
|
||||||
|
rTableRow(
|
||||||
|
title: 'تاریخ ثبت جوجه ریزی',
|
||||||
|
value: '1402/09/19 (10:12)',
|
||||||
|
),
|
||||||
|
rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'),
|
||||||
|
rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'),
|
||||||
|
|
||||||
|
rTableRow(title: 'سالن', value: '2'),
|
||||||
|
rTableRow(
|
||||||
|
title: 'تاریخ ثبت جوجه ریزی',
|
||||||
|
value: '1402/09/19 (10:12)',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget tabBarWidget(
|
||||||
|
List<String> tabs,
|
||||||
|
int selectedIndex,
|
||||||
|
Function(int) onTabSelected,
|
||||||
|
) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 38.h,
|
||||||
|
width: Get.width,
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Divider(
|
||||||
|
color: AppColor.blackLightHover,
|
||||||
|
height: 1,
|
||||||
|
thickness: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget healthTable() {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
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: 'لذیذ'),
|
||||||
|
rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'),
|
||||||
|
rTableRow(title: 'نام مالک / بهرهبردار', value: 'مرغداری احمدی'),
|
||||||
|
rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'),
|
||||||
|
rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'),
|
||||||
|
|
||||||
|
rTableRow(title: 'سالن', value: '2'),
|
||||||
|
rTableRow(
|
||||||
|
title: 'تاریخ ثبت جوجه ریزی',
|
||||||
|
value: '1402/09/19 (10:12)',
|
||||||
|
),
|
||||||
|
rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'),
|
||||||
|
rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'),
|
||||||
|
|
||||||
|
rTableRow(title: 'سالن', value: '2'),
|
||||||
|
rTableRow(
|
||||||
|
title: 'تاریخ ثبت جوجه ریزی',
|
||||||
|
value: '1402/09/19 (10:12)',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget infrastructureTable() {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
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: 'لذیذ'),
|
||||||
|
rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'),
|
||||||
|
rTableRow(title: 'نام مالک / بهرهبردار', value: 'مرغداری احمدی'),
|
||||||
|
rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'),
|
||||||
|
rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'),
|
||||||
|
|
||||||
|
rTableRow(title: 'سالن', value: '2'),
|
||||||
|
rTableRow(
|
||||||
|
title: 'تاریخ ثبت جوجه ریزی',
|
||||||
|
value: '1402/09/19 (10:12)',
|
||||||
|
),
|
||||||
|
rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'),
|
||||||
|
|
||||||
|
rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'),
|
||||||
|
rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'),
|
||||||
|
|
||||||
|
rTableRow(title: 'سالن', value: '2'),
|
||||||
|
rTableRow(
|
||||||
|
title: 'تاریخ ثبت جوجه ریزی',
|
||||||
|
value: '1402/09/19 (10:12)',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget documentsTable() {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'مستندات',
|
||||||
|
style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 135.h,
|
||||||
|
width: Get.width,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.bgLight,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 100.h,
|
||||||
|
width: Get.width,
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: 10,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
width: 80.w,
|
||||||
|
height: 80.h,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0x33000000),
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: NetworkImage(
|
||||||
|
"https://picsum.photos/150/150?random=$index",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: 6,
|
||||||
|
left: 6,
|
||||||
|
child: Container(
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
padding: EdgeInsets.all(4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.80),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Assets.vec.trashSvg.svg(
|
||||||
|
width: 16.w,
|
||||||
|
height: 16.h,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
AppColor.redNormal,
|
||||||
|
BlendMode.srcIn,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) => SizedBox(width: 10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 18),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'200 فارم در این سالن تخمین زده شده است.',
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(
|
||||||
|
color: AppColor.textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 135.h,
|
||||||
|
width: Get.width,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.bgLight,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 100.h,
|
||||||
|
width: Get.width,
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: 10,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
width: 80.w,
|
||||||
|
height: 80.h,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0x33000000),
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: NetworkImage(
|
||||||
|
"https://picsum.photos/150/150?random=${index * 2 + 1}",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: 6,
|
||||||
|
left: 6,
|
||||||
|
child: Container(
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
padding: EdgeInsets.all(4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.80),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Assets.vec.trashSvg.svg(
|
||||||
|
width: 16.w,
|
||||||
|
height: 16.h,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
AppColor.redNormal,
|
||||||
|
BlendMode.srcIn,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) => SizedBox(width: 10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 18),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'انبار نهاده ها',
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(
|
||||||
|
color: AppColor.textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
height: 135.h,
|
||||||
|
width: Get.width,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.bgLight,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 100.h,
|
||||||
|
width: Get.width,
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: 10,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Container(
|
||||||
|
width: 80.w,
|
||||||
|
height: 80.h,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0x33000000),
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: NetworkImage(
|
||||||
|
"https://picsum.photos/150/150?random=${index * 3 + 1}",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
top: 6,
|
||||||
|
left: 6,
|
||||||
|
child: Container(
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.h,
|
||||||
|
padding: EdgeInsets.all(4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.80),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Assets.vec.trashSvg.svg(
|
||||||
|
width: 16.w,
|
||||||
|
height: 16.h,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
AppColor.redNormal,
|
||||||
|
BlendMode.srcIn,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) => SizedBox(width: 10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 18),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'تلفات',
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
style: AppFonts.yekan14Bold.copyWith(
|
||||||
|
color: AppColor.textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
import 'package:rasadyar_chicken/features/common/presentation/page/profile/logic.dart';
|
import 'package:rasadyar_chicken/features/common/presentation/page/profile/logic.dart';
|
||||||
|
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
class GlobalBinding extends Bindings {
|
class GlobalBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
void dependencies() {
|
void dependencies() {
|
||||||
Get.lazyPut(() => BaseLogic(), fenix: true);
|
// Register ChickenBaseLogic and also as BasePageLogic/BaseLogic for compatibility
|
||||||
|
// Since ChickenBaseLogic extends BasePageLogic, we can use the same instance
|
||||||
|
Get.lazyPut<ChickenBaseLogic>(() => ChickenBaseLogic(), fenix: true);
|
||||||
|
// Register the same instance as BasePageLogic/BaseLogic
|
||||||
|
Get.lazyPut<BasePageLogic>(() => Get.find<ChickenBaseLogic>(), fenix: true);
|
||||||
Get.lazyPut(() => ProfileLogic(), fenix: true);
|
Get.lazyPut(() => ProfileLogic(), fenix: true);
|
||||||
|
|
||||||
//root logics
|
//root logics
|
||||||
|
|||||||
Reference in New Issue
Block a user