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 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
|
||||
}
|
||||
|
||||
@@ -89,4 +89,9 @@ abstract class PoultryScienceRepository {
|
||||
required String token,
|
||||
required String orderId,
|
||||
});
|
||||
|
||||
Future<List<String>?> uploadImages({
|
||||
required String token,
|
||||
required List<XFile> images,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -180,4 +180,12 @@ class PoultryScienceRepositoryImpl implements PoultryScienceRepository {
|
||||
}) async {
|
||||
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/repositories/poultry_science_repository.dart';
|
||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart';
|
||||
@@ -22,7 +23,7 @@ class ActiveHatchingLogic extends GetxController {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
poultryScienceRepository = Get.find<PoultryScienceRepository>();
|
||||
poultryScienceRepository = diChicken.get<PoultryScienceRepository>();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
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/presentation/pages/active_hatching/logic.dart';
|
||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart';
|
||||
import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
@@ -50,7 +52,6 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
onLoadMore: () async => controller.getHatchingList(true),
|
||||
|
||||
);
|
||||
}, controller.activeHatchingList);
|
||||
}
|
||||
@@ -58,7 +59,10 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
Container itemListExpandedWidget(HatchingModel item) {
|
||||
return Container(
|
||||
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(
|
||||
spacing: 8,
|
||||
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(
|
||||
title: 'حجم جوجه ریزی',
|
||||
value: item.quantity.separatedByCommaFa,
|
||||
@@ -122,21 +129,52 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
value: item.leftOver.separatedByCommaFa,
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)'),
|
||||
buildUnitRow(
|
||||
title: 'تلفات',
|
||||
value: item.losses.separatedByCommaFa,
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildRow(
|
||||
title: 'دامپزشک فارم',
|
||||
value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
|
||||
value:
|
||||
'${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
|
||||
),
|
||||
buildRow(
|
||||
title: 'شرح بازرسی',
|
||||
value: item.reportInfo?.image == false ? 'ارسال تصویر جوجه ریزی فارم ' : 'تکمیل شده',
|
||||
value: item.reportInfo?.image == false
|
||||
? 'ارسال تصویر جوجه ریزی فارم '
|
||||
: 'تکمیل شده',
|
||||
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(
|
||||
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/material.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/widget/base_page/view.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/view.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_core/core.dart';
|
||||
|
||||
@@ -38,56 +39,76 @@ class PoultrySciencePages {
|
||||
name: PoultryScienceRoutes.inspectionPoultryScience,
|
||||
page: () => InspectionPoultrySciencePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => InspectionPoultryScienceLogic());
|
||||
}),
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => InspectionPoultryScienceLogic());
|
||||
}),
|
||||
],
|
||||
),
|
||||
GetPage(
|
||||
name: PoultryScienceRoutes.actionPoultryScience,
|
||||
page: () => PoultryActionPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => PoultryActionLogic());
|
||||
}),
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => PoultryActionLogic());
|
||||
}),
|
||||
],
|
||||
),
|
||||
GetPage(
|
||||
name: PoultryScienceRoutes.farmPoultryScience,
|
||||
page: () => FarmPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => FarmLogic());
|
||||
Get.lazyPut(() => PoultryScienceHomeLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
}),
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => FarmLogic());
|
||||
Get.lazyPut(() => PoultryScienceHomeLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
}),
|
||||
],
|
||||
),
|
||||
GetPage(
|
||||
name: PoultryScienceRoutes.activeHatchingPoultryScience,
|
||||
page: () => ActiveHatchingPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => ActiveHatchingLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
}),
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => ActiveHatchingLogic());
|
||||
Get.lazyPut(() => CreateInspectionBottomSheetLogic(), fenix: true);
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
}),
|
||||
],
|
||||
),
|
||||
GetPage(
|
||||
name: PoultryScienceRoutes.genocidePoultryScience,
|
||||
page: () => GenocidePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => GenocideLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
Get.lazyPut(() => KillingRegistrationLogic(), fenix: true);
|
||||
}),
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => GenocideLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
Get.lazyPut(() => KillingRegistrationLogic(), fenix: true);
|
||||
}),
|
||||
],
|
||||
),
|
||||
GetPage(
|
||||
name: PoultryScienceRoutes.killingRegistrationPoultryScience,
|
||||
page: () => KillingRegistrationPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => KillingRegistrationLogic());
|
||||
Get.lazyPut(() => GenocideLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
}),
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => KillingRegistrationLogic());
|
||||
Get.lazyPut(() => GenocideLogic());
|
||||
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/presentation/widget/base_page/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class GlobalBinding extends Bindings {
|
||||
@override
|
||||
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);
|
||||
|
||||
//root logics
|
||||
|
||||
Reference in New Issue
Block a user