refactor : base page
This commit is contained in:
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 217 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 110 KiB |
Binary file not shown.
@@ -1,14 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/active_hatching/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_chicken/presentation/widget/page_route.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
import 'package:rasadyar_core/presentation/widget/list_item/list_item2.dart';
|
||||
import 'package:rasadyar_core/presentation/widget/list_view/r_paginated_list_view.dart';
|
||||
|
||||
class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
const ActiveHatchingPage({super.key});
|
||||
@@ -18,11 +14,22 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
return BasePage(
|
||||
hasSearch: false,
|
||||
hasFilter: false,
|
||||
routesWidget: buildContainerPageRoute(controller.routesName),
|
||||
routesWidget: buildContainerPageRoute(controller.routesName),
|
||||
onBackPressed: () => Get.back(id: poultryFirstKey),
|
||||
widgets: [
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Assets.vec.chickenPatternSvg.svg(
|
||||
fit: BoxFit.cover,
|
||||
colorFilter: ColorFilter.mode(Colors.grey.shade400, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
Positioned.fill(child: Column(children: [hatchingWidget()])),
|
||||
],
|
||||
),
|
||||
/*widgets: [
|
||||
hatchingWidget()
|
||||
],
|
||||
],*/
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,8 +106,10 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Text('نژاد:${item.breed?.first.breed ?? 'N/A'}', style: AppFonts.yekan14.copyWith(color: AppColor.textColor)),
|
||||
Text(
|
||||
'نژاد:${item.breed?.first.breed ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
Text(
|
||||
' سن${item.age} (روز)',
|
||||
|
||||
@@ -120,8 +129,12 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
value: item.quantity.separatedByCommaFa,
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(title: 'مانده در سالن', value: item.leftOver.separatedByCommaFa,unit: '(قطعه)',),
|
||||
buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa,unit: '(قطعه)',),
|
||||
buildUnitRow(
|
||||
title: 'مانده در سالن',
|
||||
value: item.leftOver.separatedByCommaFa,
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)'),
|
||||
buildRow(
|
||||
title: 'دامپزشک فارم',
|
||||
value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
|
||||
@@ -136,7 +149,6 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
|
||||
color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark,
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart';
|
||||
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_core/presentation/widget/base_page/widgets/back_ground_widget.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/page_route.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
@@ -16,9 +16,15 @@ class FarmPage extends GetView<FarmLogic> {
|
||||
return BasePage(
|
||||
hasFilter: false,
|
||||
hasSearch: false,
|
||||
routesWidget: buildContainerPageRoute(controller.routesName),
|
||||
isBase: true,
|
||||
routes: [],
|
||||
onBackPressed: () => Get.back(id: poultryFirstKey),
|
||||
widgets: [firstTagInformation(), farmListWidget()],
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(child: chickenBackground()),
|
||||
Positioned.fill(child: Column(children: [firstTagInformation(), farmListWidget()])),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,7 +140,11 @@ class FarmPage extends GetView<FarmLogic> {
|
||||
title: 'دامپزشک فارم',
|
||||
value: '${item.vetFarm?.fullName} (${item.vetFarm?.mobile ?? '-'})',
|
||||
),
|
||||
buildUnitRow(title: 'ظرفیت فارم', value: item.totalCapacity.separatedByCommaFa, unit: '(قطعه)'),
|
||||
buildUnitRow(
|
||||
title: 'ظرفیت فارم',
|
||||
value: item.totalCapacity.separatedByCommaFa,
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildRow(
|
||||
title: 'جوجه ریزی فعال (تعداد دوره) ',
|
||||
value:
|
||||
|
||||
@@ -19,13 +19,7 @@ class PoultryScienceHomePage extends GetView<PoultryScienceHomeLogic> {
|
||||
hasBack: false,
|
||||
hasFilter: false,
|
||||
hasSearch: false,
|
||||
additionalActions: [
|
||||
SizedBox(width: 12),
|
||||
Icon(CupertinoIcons.envelope_fill, color: Colors.white),
|
||||
SizedBox(width: 12),
|
||||
Icon(CupertinoIcons.bell_fill, color: Colors.white),
|
||||
SizedBox(width: 12),
|
||||
],
|
||||
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
|
||||
@@ -15,22 +15,32 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BasePage(
|
||||
return ChickenBasePage(
|
||||
hasBack: true,
|
||||
hasFilter: true,
|
||||
hasSearch: true,
|
||||
filteringWidget: filterBottomSheet(),
|
||||
onSearchChanged: (data) => controller.setSearchValue(data),
|
||||
backId: poultryFirstKey,
|
||||
routes: controller.routesName,
|
||||
//routesWidget: ObxValue((route) => buildContainerPageRoute(route), controller.routesName),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Assets.vec.chickenPatternSvg.svg(
|
||||
fit: BoxFit.cover,
|
||||
colorFilter: ColorFilter.mode(Color(0xFFC3CBDA), BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 50, child: segmentWidget()),
|
||||
|
||||
routesWidget: ObxValue((route) => buildContainerPageRoute(route), controller.routesName),
|
||||
onBackPressed: () => Get.back(id: poultryFirstKey),
|
||||
widgets: [
|
||||
segmentWidget(),
|
||||
|
||||
ObxValue((data) {
|
||||
return data.value == 0 ? hatchingWidget() : reportWidget();
|
||||
}, controller.selectedSegmentIndex),
|
||||
],
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return data.value == 0 ? hatchingWidget() : reportWidget();
|
||||
}, controller.selectedSegmentIndex),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -109,9 +119,10 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
||||
Text('نژاد:${ item.breed?.first.breed ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor)),
|
||||
Text(
|
||||
'نژاد:${item.breed?.first.breed ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
Text(
|
||||
' سن ${item.age} (روزه)',
|
||||
|
||||
@@ -133,12 +144,14 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(
|
||||
title: 'مانده در سالن', value: item.leftOver.separatedByCommaFa, unit: '(قطعه)',),
|
||||
buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)',),
|
||||
title: 'مانده در سالن',
|
||||
value: item.leftOver.separatedByCommaFa,
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)'),
|
||||
buildRow(
|
||||
title: 'دامپزشک فارم',
|
||||
value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
|
||||
|
||||
),
|
||||
buildRow(
|
||||
title: 'شرح بازرسی',
|
||||
@@ -188,77 +201,77 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
shrinkWrap: true,
|
||||
itemCount: controller.pickedImages.length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index + 1 < 7&& index == data.length) {
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
await controller.pickImages();
|
||||
},
|
||||
child: Container(
|
||||
width: 80.h,
|
||||
height: 80.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.lightGreyNormal,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.add_a_photo,
|
||||
color: AppColor.lightGreyDarker,
|
||||
size: 32.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
if (index + 1 < 7 && index == data.length) {
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
await controller.pickImages();
|
||||
},
|
||||
child: Container(
|
||||
width: 80.h,
|
||||
height: 80.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.lightGreyNormal,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Image.file(File(data[index].path), fit: BoxFit.cover),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.add_a_photo,
|
||||
color: AppColor.lightGreyDarker,
|
||||
size: 32.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
width: 80.h,
|
||||
height: 80.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.lightGreyNormal,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Image.file(File(data[index].path), fit: BoxFit.cover),
|
||||
),
|
||||
|
||||
Positioned(
|
||||
top: 4,
|
||||
left: 4,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.removeImage(index);
|
||||
},
|
||||
child: Container(
|
||||
width: 24.w,
|
||||
height: 24.h,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
padding: EdgeInsets.all(4),
|
||||
decoration: ShapeDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.80),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
Positioned(
|
||||
top: 4,
|
||||
left: 4,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.removeImage(index);
|
||||
},
|
||||
child: Container(
|
||||
width: 24.w,
|
||||
height: 24.h,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
padding: EdgeInsets.all(4),
|
||||
decoration: ShapeDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.80),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Assets.vec.trashSvg.svg(
|
||||
width: 8.w,
|
||||
height: 8.h,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.redNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
child: Assets.vec.trashSvg.svg(
|
||||
width: 8.w,
|
||||
height: 8.h,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.redNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}, );
|
||||
|
||||
},controller.pickedImages),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}, controller.pickedImages),
|
||||
|
||||
SizedBox(height: 35.h),
|
||||
Text(
|
||||
@@ -305,7 +318,7 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
),
|
||||
).whenComplete(() {
|
||||
controller.pickedImages.clear();
|
||||
},);
|
||||
});
|
||||
}
|
||||
|
||||
Padding segmentWidget() {
|
||||
@@ -410,8 +423,6 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
item.hatching?.chickenBreed ?? 'N/A',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
Text(
|
||||
@@ -428,23 +439,25 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
|
||||
buildRow(title: 'شماره مجوز جوجه ریزی', value: item.hatching?.licenceNumber ?? 'N/A'),
|
||||
buildUnitRow(
|
||||
title: 'حجم جوجه ریزی',
|
||||
value: item.hatching?.quantity.separatedByCommaFa ?? 'N/A',
|
||||
title: 'حجم جوجه ریزی',
|
||||
value: item.hatching?.quantity.separatedByCommaFa ?? 'N/A',
|
||||
|
||||
unit: '(قطعه)'
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(
|
||||
title: 'مانده در سالن',
|
||||
value: item.hatching?.leftOver.separatedByCommaFa ?? 'N/A',
|
||||
unit: '(قطعه)'
|
||||
title: 'مانده در سالن',
|
||||
value: item.hatching?.leftOver.separatedByCommaFa ?? 'N/A',
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(
|
||||
title: 'تلفات',
|
||||
value: item.hatching?.losses.separatedByCommaFa ?? 'N/A',
|
||||
unit: '(قطعه)',
|
||||
),
|
||||
buildUnitRow(title: 'تلفات',
|
||||
value: item.hatching?.losses.separatedByCommaFa ?? 'N/A',
|
||||
unit: '(قطعه)'),
|
||||
buildRow(
|
||||
title: 'دامپزشک فارم',
|
||||
value:
|
||||
'${item.hatching?.vetFarm?.vetFarmFullname}(${item.hatching?.vetFarm?.vetFarmMobile})',
|
||||
'${item.hatching?.vetFarm?.vetFarmFullname}(${item.hatching?.vetFarm?.vetFarmMobile})',
|
||||
),
|
||||
buildRow(
|
||||
title: 'شرح بازرسی',
|
||||
@@ -457,12 +470,16 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
Visibility(
|
||||
visible: item.realQuantityAi != null,
|
||||
child: buildRow(
|
||||
title: 'تعداد تاییده هوش مصنوعی', value: item.realQuantityAi.separatedByComma),
|
||||
title: 'تعداد تاییده هوش مصنوعی',
|
||||
value: item.realQuantityAi.separatedByComma,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: item.realQuantity != null,
|
||||
child: buildRow(
|
||||
title: 'تعداد تاییده', value: item.realQuantity.separatedByComma ?? '-'),
|
||||
title: 'تعداد تاییده',
|
||||
value: item.realQuantity.separatedByComma ?? '-',
|
||||
),
|
||||
),
|
||||
},
|
||||
|
||||
@@ -493,7 +510,6 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
visible: item.messageRegistererRole != null,
|
||||
child: buildRow(title: 'نقش کننده گزارش', value: item.messageRegistererRole ?? '-'),
|
||||
),
|
||||
|
||||
},
|
||||
|
||||
SizedBox(
|
||||
@@ -506,18 +522,17 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
mainAxisSpacing: 10,
|
||||
crossAxisSpacing: 10,
|
||||
),
|
||||
itemBuilder: (context, index) =>
|
||||
Container(
|
||||
height: 100.h,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(item.image?[index] ?? ''),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
itemBuilder: (context, index) => Container(
|
||||
height: 100.h,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
image: DecorationImage(
|
||||
image: NetworkImage(item.image?[index] ?? ''),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -639,7 +654,6 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget filterBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 200,
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/profile/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import '../widget/base_page/logic.dart';
|
||||
|
||||
class GlobalBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.put(BaseLogic(), permanent: true);
|
||||
|
||||
Get.lazyPut(() => ProfileLogic(), fenix: true);
|
||||
Get.lazyPut(() => SearchLogic(), fenix: true);
|
||||
|
||||
|
||||
//root logics
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/auth/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/auth/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/profile/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/profile/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/role/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/role/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/active_hatching/logic.dart';
|
||||
@@ -22,9 +20,7 @@ import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/view.da
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/steward.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/global_binding.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/captcha/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
sealed class ChickenPages {
|
||||
@@ -93,7 +89,6 @@ sealed class ChickenPages {
|
||||
page: () => SalesOutOfProvincePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
Get.lazyPut(() => SalesOutOfProvinceLogic());
|
||||
Get.lazyPut(() => SalesOutOfProvinceBuyersLogic());
|
||||
Get.lazyPut(() => SalesOutOfProvinceSalesListLogic());
|
||||
@@ -104,7 +99,6 @@ sealed class ChickenPages {
|
||||
page: () => SalesOutOfProvinceBuyersPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
Get.lazyPut(() => SalesOutOfProvinceLogic());
|
||||
Get.lazyPut(() => SalesOutOfProvinceBuyersLogic());
|
||||
Get.lazyPut(() => SalesOutOfProvinceSalesListLogic());
|
||||
@@ -117,7 +111,6 @@ sealed class ChickenPages {
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => BaseLogic());
|
||||
Get.lazyPut(() => SalesInProvinceLogic());
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -137,7 +130,6 @@ sealed class ChickenPages {
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => BaseLogic());
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
Get.lazyPut(() => BuyOutOfProvinceLogic());
|
||||
}),
|
||||
),
|
||||
@@ -147,7 +139,6 @@ sealed class ChickenPages {
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => BaseLogic());
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
Get.lazyPut(() => BuyInProvinceLogic());
|
||||
Get.lazyPut(() => BuyInProvinceWaitingLogic());
|
||||
Get.lazyPut(() => BuyInProvinceAllLogic());
|
||||
@@ -178,7 +169,7 @@ sealed class ChickenPages {
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => InspectionPoultryScienceLogic());
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
|
||||
}),
|
||||
),
|
||||
GetPage(
|
||||
|
||||
@@ -1,99 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
/// Creates a customized AppBar for the Rasadyar Chicken app.
|
||||
RAppBar chickenAppBar({
|
||||
bool hasBack = true,
|
||||
bool hasFilter = true,
|
||||
bool hasSearch = true,
|
||||
bool isBase = false,
|
||||
VoidCallback? onBackPressed,
|
||||
GestureTapCallback? onFilterTap,
|
||||
GestureTapCallback? onSearchTap,
|
||||
List<Widget>? additionalActions,
|
||||
bool hasNotification = false,
|
||||
bool hasNews = false,
|
||||
int? backId,
|
||||
VoidCallback? onBackTap,
|
||||
VoidCallback? onFilterTap,
|
||||
VoidCallback? onSearchTap,
|
||||
VoidCallback? onNewsTap,
|
||||
VoidCallback? onNotificationTap,
|
||||
}) {
|
||||
return RAppBar(
|
||||
hasBack: isBase == true ? false : hasBack,
|
||||
onBackPressed: onBackPressed,
|
||||
leadingWidth: 155,
|
||||
leading: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 6,
|
||||
children: [
|
||||
Text('رصدطیور', style: AppFonts.yekan16Bold.copyWith(color: Colors.white)),
|
||||
Assets.vec.chickenSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
],
|
||||
),
|
||||
additionalActions: [
|
||||
if (!isBase && hasSearch) searchWidget(onSearchTap),
|
||||
SizedBox(width: 8),
|
||||
if (!isBase && hasFilter) filterWidget(onFilterTap),
|
||||
SizedBox(width: 8),
|
||||
if (additionalActions != null) ...additionalActions,
|
||||
hasBack: hasBack,
|
||||
hasSearch: hasSearch,
|
||||
hasNotification: hasNotification,
|
||||
hasNews: hasNews,
|
||||
isBase: isBase,
|
||||
backId: backId,
|
||||
onSearchTap: onSearchTap,
|
||||
onBackTap: onBackTap,
|
||||
onNotificationTap: onNotificationTap,
|
||||
onNewsTap: onNewsTap,
|
||||
backgroundColor: AppColor.blueNormal,
|
||||
children: [
|
||||
Text('رصدطیور', style: AppFonts.yekan16Bold),
|
||||
const SizedBox(width: 6),
|
||||
Assets.vec.chickenSvg.svg(height: 24, width: 24),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
GestureDetector filterWidget(GestureTapCallback? onFilterTap) {
|
||||
return GestureDetector(
|
||||
onTap: onFilterTap,
|
||||
child: Stack(
|
||||
alignment: Alignment.topRight,
|
||||
children: [
|
||||
Assets.vec.filterOutlineSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
Obx(() {
|
||||
final controller = Get.find<BaseLogic>();
|
||||
return Visibility(
|
||||
visible: controller.isFilterSelected.value,
|
||||
child: Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.red,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
GestureDetector searchWidget(GestureTapCallback? onSearchTap) {
|
||||
return GestureDetector(
|
||||
onTap: onSearchTap,
|
||||
child: Stack(
|
||||
alignment: Alignment.topRight,
|
||||
children: [
|
||||
Assets.vec.searchSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
Obx(() {
|
||||
final controller = Get.find<SearchLogic>();
|
||||
return Visibility(
|
||||
visible: controller.searchValue.value!=null,
|
||||
child: Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.red,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class BaseLogic extends GetxController {
|
||||
final RxBool isFilterSelected = false.obs;
|
||||
|
||||
void toggleFilter() {
|
||||
isFilterSelected.value = !isFilterSelected.value;
|
||||
}
|
||||
}
|
||||
@@ -1,112 +1,70 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/app_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/page_route.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/search/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class BasePage extends StatefulWidget {
|
||||
const BasePage({
|
||||
class ChickenBasePage extends GetView<BaseLogic> {
|
||||
const ChickenBasePage({
|
||||
super.key,
|
||||
this.routes,
|
||||
this.widgets,
|
||||
this.routesWidget,
|
||||
this.floatingActionButtonLocation,
|
||||
this.floatingActionButton,
|
||||
this.onSearchChanged,
|
||||
this.child,
|
||||
this.hasBack = true,
|
||||
this.hasFilter = true,
|
||||
this.hasSearch = true,
|
||||
this.isBase = false,
|
||||
this.onBackPressed,
|
||||
this.hasNotification = false,
|
||||
this.hasNews = false,
|
||||
this.backId,
|
||||
this.onBackTap,
|
||||
this.onFilterTap,
|
||||
this.onSearchTap,
|
||||
this.onNewsTap,
|
||||
this.onNotificationTap,
|
||||
this.onSearchChanged,
|
||||
this.routes,
|
||||
this.routesWidget,
|
||||
this.widgets,
|
||||
this.child,
|
||||
this.scrollable = false,
|
||||
this.floatingActionButtonLocation,
|
||||
this.floatingActionButton,
|
||||
|
||||
this.filteringWidget,
|
||||
}) : assert(
|
||||
(routes != null) || routesWidget != null,
|
||||
'Either routes or routesWidget must be provided.',
|
||||
);
|
||||
|
||||
//AppBar properties`
|
||||
final bool hasBack;
|
||||
final bool hasFilter;
|
||||
final bool hasSearch;
|
||||
final bool isBase;
|
||||
final bool hasNotification;
|
||||
final bool hasNews;
|
||||
final int? backId;
|
||||
|
||||
final VoidCallback? onBackTap;
|
||||
final VoidCallback? onFilterTap;
|
||||
final VoidCallback? onSearchTap;
|
||||
final VoidCallback? onNewsTap;
|
||||
final VoidCallback? onNotificationTap;
|
||||
|
||||
final List<String>? routes;
|
||||
final Widget? routesWidget;
|
||||
final Breadcrumb? routesWidget;
|
||||
final List<Widget>? widgets;
|
||||
final Widget? child;
|
||||
final bool scrollable;
|
||||
|
||||
final FloatingActionButtonLocation? floatingActionButtonLocation;
|
||||
final Widget? floatingActionButton;
|
||||
final Widget? filteringWidget;
|
||||
final void Function(String?)? onSearchChanged;
|
||||
final bool hasBack;
|
||||
final bool hasFilter;
|
||||
final bool hasSearch;
|
||||
final bool isBase;
|
||||
final VoidCallback? onBackPressed;
|
||||
final GestureTapCallback? onFilterTap;
|
||||
final GestureTapCallback? onSearchTap;
|
||||
|
||||
@override
|
||||
State<BasePage> createState() => _BasePageState();
|
||||
}
|
||||
|
||||
class _BasePageState extends State<BasePage> {
|
||||
BaseLogic get controller => Get.find<BaseLogic>();
|
||||
Worker? filterWorker;
|
||||
bool _isBottomSheetOpen = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
/* filterWorker = ever(controller.isFilterSelected, (bool isSelected) {
|
||||
if (!mounted) return;
|
||||
|
||||
if (isSelected && widget.filteringWidget != null) {
|
||||
// بررسی اینکه آیا bottomSheet از قبل باز است یا نه
|
||||
if (_isBottomSheetOpen) {
|
||||
controller.isFilterSelected.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// بررسی اینکه آیا route فعلی current است یا نه
|
||||
if (ModalRoute.of(context)?.isCurrent != true) {
|
||||
controller.isFilterSelected.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_isBottomSheetOpen = true;
|
||||
Get.bottomSheet(
|
||||
widget.filteringWidget!,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
enableDrag: true,
|
||||
).then((_) {
|
||||
// تنظیم مقدار به false بعد از بسته شدن bottomSheet
|
||||
if (mounted) {
|
||||
_isBottomSheetOpen = false;
|
||||
controller.isFilterSelected.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
filterWorker?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onFilterTap() {
|
||||
if (widget.hasFilter && widget.filteringWidget != null) {
|
||||
// بررسی اینکه آیا این route در top است یا نه
|
||||
final currentRoute = ModalRoute.of(context);
|
||||
if (currentRoute?.isCurrent != true) {
|
||||
return;
|
||||
}
|
||||
if (hasFilter && filteringWidget != null) {
|
||||
final currentRoute = ModalRoute.of(Get.context!);
|
||||
if (currentRoute?.isCurrent != true) return;
|
||||
|
||||
// مستقیماً bottomSheet را باز کنید
|
||||
Get.bottomSheet(
|
||||
widget.filteringWidget!,
|
||||
filteringWidget!,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
enableDrag: true,
|
||||
@@ -116,140 +74,27 @@ class _BasePageState extends State<BasePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => widget.onBackPressed,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColor.bgLight,
|
||||
appBar: chickenAppBar(
|
||||
hasBack: widget.isBase ? false : widget.hasBack,
|
||||
onBackPressed: widget.onBackPressed,
|
||||
hasFilter: widget.hasFilter,
|
||||
hasSearch: widget.hasSearch,
|
||||
isBase: widget.isBase,
|
||||
onFilterTap: widget.hasFilter ? _onFilterTap : null,
|
||||
onSearchTap: widget.hasSearch ? () => Get.find<SearchLogic>().toggleSearch() : null,
|
||||
),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
widget.routesWidget != null ? widget.routesWidget! : buildPageRoute(widget.routes!),
|
||||
if (!widget.isBase && widget.hasSearch) ...{
|
||||
SearchWidget(onSearchChanged: widget.onSearchChanged),
|
||||
},
|
||||
|
||||
if (widget.child != null) ...{Expanded(child: widget.child!)},
|
||||
...?widget.widgets,
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: widget.floatingActionButtonLocation,
|
||||
floatingActionButton: widget.floatingActionButton,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BasePageWithScroll extends StatefulWidget {
|
||||
const BasePageWithScroll({
|
||||
super.key,
|
||||
this.routes,
|
||||
required this.widgets,
|
||||
this.routesWidget,
|
||||
this.floatingActionButtonLocation,
|
||||
this.floatingActionButton,
|
||||
this.onSearchChanged,
|
||||
this.hasBack = true,
|
||||
this.hasFilter = true,
|
||||
this.hasSearch = true,
|
||||
this.isBase = false,
|
||||
this.onBackPressed,
|
||||
this.onFilterTap,
|
||||
this.onSearchTap,
|
||||
this.filteringWidget,
|
||||
}) : assert(
|
||||
(routes != null) || routesWidget != null,
|
||||
'Either routes or routesWidget must be provided.',
|
||||
);
|
||||
|
||||
final List<String>? routes;
|
||||
final Widget? routesWidget;
|
||||
final List<Widget> widgets;
|
||||
final FloatingActionButtonLocation? floatingActionButtonLocation;
|
||||
final Widget? floatingActionButton;
|
||||
final Widget? filteringWidget;
|
||||
final void Function(String?)? onSearchChanged;
|
||||
final bool hasBack;
|
||||
final bool hasFilter;
|
||||
final bool hasSearch;
|
||||
final bool isBase;
|
||||
final VoidCallback? onBackPressed;
|
||||
final GestureTapCallback? onFilterTap;
|
||||
final GestureTapCallback? onSearchTap;
|
||||
|
||||
@override
|
||||
State<BasePageWithScroll> createState() => _BasePageWithScrollState();
|
||||
}
|
||||
|
||||
class _BasePageWithScrollState extends State<BasePageWithScroll> {
|
||||
BaseLogic get controller => Get.find<BaseLogic>();
|
||||
Worker? filterWorker;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
filterWorker?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onFilterTap() {
|
||||
if (widget.hasFilter && widget.filteringWidget != null) {
|
||||
// بررسی اینکه آیا این route در top است یا نه
|
||||
final currentRoute = ModalRoute.of(context);
|
||||
if (currentRoute?.isCurrent != true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// مستقیماً bottomSheet را باز کنید
|
||||
Get.bottomSheet(
|
||||
widget.filteringWidget!,
|
||||
isScrollControlled: true,
|
||||
isDismissible: true,
|
||||
enableDrag: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) => widget.onBackPressed,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColor.bgLight,
|
||||
appBar: chickenAppBar(
|
||||
hasBack: widget.isBase ? false : widget.hasBack,
|
||||
onBackPressed: widget.onBackPressed,
|
||||
hasFilter: widget.hasFilter,
|
||||
hasSearch: widget.hasSearch,
|
||||
isBase: widget.isBase,
|
||||
onFilterTap: widget.hasFilter ? _onFilterTap : null,
|
||||
onSearchTap: widget.hasSearch ? () => Get.find<SearchLogic>().toggleSearch() : null,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
widget.routesWidget != null ? widget.routesWidget! : buildPageRoute(widget.routes!),
|
||||
if (!widget.isBase && widget.hasSearch) ...{
|
||||
SearchWidget(onSearchChanged: widget.onSearchChanged),
|
||||
},
|
||||
...widget.widgets,
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButtonLocation: widget.floatingActionButtonLocation,
|
||||
floatingActionButton: widget.floatingActionButton,
|
||||
return BasePage(
|
||||
routes: routes,
|
||||
routesWidget: routesWidget,
|
||||
widgets: widgets,
|
||||
child: child,
|
||||
scrollable: scrollable,
|
||||
floatingActionButtonLocation: floatingActionButtonLocation,
|
||||
floatingActionButton: floatingActionButton,
|
||||
appBar: chickenAppBar(
|
||||
isBase: isBase,
|
||||
hasBack: isBase ? false : hasBack,
|
||||
onBackTap: onBackTap,
|
||||
onNewsTap: onNewsTap,
|
||||
hasFilter: hasFilter,
|
||||
hasSearch: hasSearch,
|
||||
hasNews: hasNews,
|
||||
hasNotification: hasNotification,
|
||||
backId: backId,
|
||||
onNotificationTap: onNotificationTap,
|
||||
onFilterTap: hasFilter ? _onFilterTap : null,
|
||||
onSearchTap: hasSearch ? controller.toggleSearch : null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,13 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
Widget buildPageRoute(List<String> route) {
|
||||
if(route.isEmpty){
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 4, 7, 4),
|
||||
child: Text(
|
||||
route.isEmpty ? 'خانه' : route.join(" > "),
|
||||
route.join(" > "),
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class SearchLogic extends GetxController {
|
||||
final RxBool isSearchSelected = false.obs;
|
||||
|
||||
final RxnString searchValue = RxnString();
|
||||
|
||||
void setSearchCallback(void Function(String)? onSearchChanged) {
|
||||
debounce<String?>(searchValue, (val) {
|
||||
if (val != null && val.trim().isNotEmpty) {
|
||||
onSearchChanged?.call(val);
|
||||
}
|
||||
}, time: const Duration(milliseconds: 600));
|
||||
}
|
||||
|
||||
void toggleSearch() {
|
||||
isSearchSelected.value = !isSearchSelected.value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -460,18 +460,12 @@ class $AssetsIconsGen {
|
||||
class $AssetsImagesGen {
|
||||
const $AssetsImagesGen();
|
||||
|
||||
/// File path: assets/images/bg_chicken_pattern.webp
|
||||
AssetGenImage get bgChickenPattern => const AssetGenImage('assets/images/bg_chicken_pattern.webp');
|
||||
|
||||
/// File path: assets/images/chicken.png
|
||||
AssetGenImage get chicken => const AssetGenImage('assets/images/chicken.png');
|
||||
|
||||
/// File path: assets/images/inner_splash.webp
|
||||
AssetGenImage get innerSplash => const AssetGenImage('assets/images/inner_splash.webp');
|
||||
|
||||
/// File path: assets/images/live_chicken.jpg
|
||||
AssetGenImage get liveChicken => const AssetGenImage('assets/images/live_chicken.jpg');
|
||||
|
||||
/// File path: assets/images/outter_splash.webp
|
||||
AssetGenImage get outterSplash => const AssetGenImage('assets/images/outter_splash.webp');
|
||||
|
||||
@@ -482,15 +476,7 @@ class $AssetsImagesGen {
|
||||
AssetGenImage get selectRole => const AssetGenImage('assets/images/select_role.webp');
|
||||
|
||||
/// List of all assets
|
||||
List<AssetGenImage> get values => [
|
||||
bgChickenPattern,
|
||||
chicken,
|
||||
innerSplash,
|
||||
liveChicken,
|
||||
outterSplash,
|
||||
placeHolder,
|
||||
selectRole,
|
||||
];
|
||||
List<AssetGenImage> get values => [chicken, innerSplash, outterSplash, placeHolder, selectRole];
|
||||
}
|
||||
|
||||
class $AssetsLogosGen {
|
||||
|
||||
31
packages/core/lib/presentation/widget/base_page/logic.dart
Normal file
31
packages/core/lib/presentation/widget/base_page/logic.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class BaseLogic extends GetxController {
|
||||
final RxBool isFilterSelected = false.obs;
|
||||
final RxBool isSearchSelected = false.obs;
|
||||
final RxnString searchValue = RxnString();
|
||||
final TextEditingController textEditingController = TextEditingController();
|
||||
|
||||
void setSearchCallback(void Function(String?)? onSearchChanged) {
|
||||
debounce<String?>(searchValue, (val) {
|
||||
if (val != null && val.trim().isNotEmpty) {
|
||||
onSearchChanged?.call(val);
|
||||
}
|
||||
}, time: const Duration(milliseconds: 600));
|
||||
}
|
||||
|
||||
void toggleSearch() {
|
||||
isSearchSelected.value = !isSearchSelected.value;
|
||||
}
|
||||
|
||||
void clearSearch() {
|
||||
textEditingController.clear();
|
||||
searchValue.value = null;
|
||||
isSearchSelected.value = false;
|
||||
}
|
||||
|
||||
void toggleFilter() {
|
||||
isFilterSelected.value = !isFilterSelected.value;
|
||||
}
|
||||
}
|
||||
91
packages/core/lib/presentation/widget/base_page/view.dart
Normal file
91
packages/core/lib/presentation/widget/base_page/view.dart
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class BasePage extends GetView<BaseLogic> {
|
||||
const BasePage({
|
||||
super.key,
|
||||
this.routes,
|
||||
this.routesWidget,
|
||||
this.widgets,
|
||||
this.child,
|
||||
this.scrollable = false,
|
||||
this.floatingActionButtonLocation,
|
||||
this.floatingActionButton,
|
||||
this.appBar,
|
||||
this.backGroundWidget,
|
||||
}) : assert(
|
||||
(routes != null) || routesWidget != null,
|
||||
'Either routes or routesWidget must be provided.',
|
||||
);
|
||||
|
||||
final List<String>? routes;
|
||||
final Breadcrumb? routesWidget;
|
||||
final List<Widget>? widgets;
|
||||
final Widget? child;
|
||||
final bool scrollable;
|
||||
final RAppBar? appBar;
|
||||
final BackGroundWidget? backGroundWidget;
|
||||
final FloatingActionButtonLocation? floatingActionButtonLocation;
|
||||
final Widget? floatingActionButton;
|
||||
|
||||
Widget _buildHeader() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
routesWidget ?? TextBreadcrumb(routes: routes!),
|
||||
if (controller.isSearchSelected.value) ...{SearchWidget()},
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
final content = [_buildHeader(), if (child != null) Expanded(child: child!), ...?widgets];
|
||||
|
||||
if (scrollable) {
|
||||
if (backGroundWidget != null) {
|
||||
return Stack(
|
||||
children: [
|
||||
?backGroundWidget,
|
||||
SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h),
|
||||
child: Column(children: content),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h),
|
||||
child: Column(children: content),
|
||||
);
|
||||
}
|
||||
|
||||
if (backGroundWidget != null) {
|
||||
return Stack(
|
||||
children: [
|
||||
?backGroundWidget,
|
||||
Column(children: content),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Column(children: content);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (!didPop) appBar?.onBackTap?.call();
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColor.bgLight,
|
||||
appBar: appBar,
|
||||
body: _buildBody(),
|
||||
floatingActionButtonLocation: floatingActionButtonLocation,
|
||||
floatingActionButton: floatingActionButton,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/presentation/common/assets.gen.dart';
|
||||
|
||||
class BackGroundWidget extends StatelessWidget {
|
||||
const BackGroundWidget({super.key, required this.gradient, required this.vecPath});
|
||||
|
||||
final Gradient gradient;
|
||||
final String vecPath;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(gradient: gradient),
|
||||
child: SvgGenImage.vec(vecPath).svg(fit: BoxFit.cover),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*Container chickenBackground() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient:
|
||||
gradient ??
|
||||
LinearGradient(
|
||||
begin: Alignment(1.00, 0.01),
|
||||
end: Alignment(0.04, 0.99),
|
||||
colors: [
|
||||
const Color(0xFFD6DCEF).withValues(alpha: .8),
|
||||
const Color(0xFFD6E6E9).withValues(alpha: .8),
|
||||
const Color(0xFFD6E4E3).withValues(alpha: .8),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Assets.vec.chickenPatternSvg.svg(fit: BoxFit.cover),
|
||||
);
|
||||
}*/
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
abstract class Breadcrumb extends StatelessWidget {
|
||||
const Breadcrumb({super.key, this.routes});
|
||||
|
||||
final List<String>? routes;
|
||||
}
|
||||
|
||||
class TextBreadcrumb extends Breadcrumb {
|
||||
const TextBreadcrumb({super.key, super.routes});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (routes?.isEmpty ?? true) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 4, 7, 4),
|
||||
child: Text(routes!.join(" > "), style: AppFonts.yekan14.copyWith(color: AppColor.bgDark)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ContainerBreadcrumb extends Breadcrumb {
|
||||
const ContainerBreadcrumb({super.key, super.routes});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (routes?.isEmpty ?? true) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return buildContainerPageRoute(routes!);
|
||||
}
|
||||
|
||||
Widget buildContainerPageRoute(List<String> route) {
|
||||
return Container(
|
||||
height: 24.h,
|
||||
margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
|
||||
decoration: BoxDecoration(color: Color(0xFFE3E3E3), borderRadius: BorderRadius.circular(2.r)),
|
||||
padding: EdgeInsets.symmetric(horizontal: 6.w),
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) => Center(
|
||||
child: Text(route[index], style: AppFonts.yekan14.copyWith(color: AppColor.labelTextColor)),
|
||||
),
|
||||
separatorBuilder: (context, index) =>
|
||||
Assets.vec.arrowLeftSvg.svg(height: 24.h, fit: BoxFit.fitHeight),
|
||||
itemCount: route.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,34 +1,50 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
|
||||
class RAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final String? title;
|
||||
final String? iconTitle;
|
||||
final Color backgroundColor;
|
||||
final Color iconColor;
|
||||
final bool hasBack;
|
||||
final List<Widget>? children;
|
||||
|
||||
final bool centerTitle;
|
||||
final TextStyle? titleTextStyle;
|
||||
final VoidCallback? onBackPressed;
|
||||
final List<Widget>? additionalActions;
|
||||
final double? leadingWidth;
|
||||
final Widget? leading;
|
||||
|
||||
final Color backgroundColor;
|
||||
|
||||
final bool isBase;
|
||||
|
||||
final bool hasBack;
|
||||
final VoidCallback? onBackTap;
|
||||
final int? backId;
|
||||
|
||||
final bool hasSearch;
|
||||
final VoidCallback? onSearchTap;
|
||||
|
||||
final bool hasNotification;
|
||||
|
||||
final VoidCallback? onNotificationTap;
|
||||
|
||||
final bool hasNews;
|
||||
final VoidCallback? onNewsTap;
|
||||
|
||||
/// Preferred size widget for the AppBar bottom.
|
||||
final PreferredSizeWidget? bottom;
|
||||
|
||||
const RAppBar({
|
||||
super.key,
|
||||
this.title,
|
||||
this.iconTitle,
|
||||
this.children,
|
||||
this.backgroundColor = AppColor.blueNormal,
|
||||
this.iconColor = Colors.white,
|
||||
this.titleTextStyle,
|
||||
this.onBackPressed,
|
||||
this.additionalActions,
|
||||
this.leading,
|
||||
this.hasBack = true,
|
||||
this.hasSearch = false,
|
||||
this.hasNews = false,
|
||||
this.hasNotification= false,
|
||||
this.isBase = false,
|
||||
this.centerTitle = false,
|
||||
this.leadingWidth,
|
||||
this.bottom,
|
||||
this.backId,
|
||||
this.onBackTap,
|
||||
this.onSearchTap,
|
||||
this.onNewsTap,
|
||||
this.onNotificationTap,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -39,46 +55,64 @@ class RAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
elevation: 0,
|
||||
excludeHeaderSemantics: true,
|
||||
scrolledUnderElevation: 0,
|
||||
centerTitle: centerTitle,
|
||||
titleTextStyle: titleTextStyle ?? AppFonts.yekan16.copyWith(color: Colors.white),
|
||||
title: title != null
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(title!),
|
||||
if (iconTitle != null) ...{const SizedBox(width: 8)},
|
||||
if (iconTitle != null) ...{SvgGenImage.vec(iconTitle!).svg(width: 24, height: 24)},
|
||||
],
|
||||
)
|
||||
: null,
|
||||
leadingWidth: leadingWidth?.toDouble(),
|
||||
leading: leading != null
|
||||
? Padding(padding: const EdgeInsets.only(right: 6), child: leading)
|
||||
: null,
|
||||
titleSpacing: 8,
|
||||
actions: [
|
||||
if (additionalActions != null) ...additionalActions!,
|
||||
if (hasBack) ...{
|
||||
GestureDetector(
|
||||
onTap: onBackPressed ?? () => Get.back(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 2, 0),
|
||||
child: Assets.vec.arrowLeftSvg.svg(
|
||||
width: 24.w,
|
||||
height: 24.h,
|
||||
colorFilter: ColorFilter.mode(iconColor ?? Colors.white, BlendMode.srcIn),
|
||||
title: Row(
|
||||
mainAxisAlignment: _getMainAxisAlignment(),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
textDirection: TextDirection.rtl, // Support for RTL languages
|
||||
children: [
|
||||
if (children != null) ...children!,
|
||||
|
||||
if (hasNews || hasBack || hasSearch || hasNotification) const Spacer(),
|
||||
|
||||
if (hasSearch) SearchWidget(),
|
||||
if (hasSearch) SizedBox(width: 8.w),
|
||||
|
||||
if (hasNews)
|
||||
GestureDetector(
|
||||
onTap: onNewsTap,
|
||||
child: Badge.count(
|
||||
count: 5,
|
||||
child: Icon(CupertinoIcons.news_solid, color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
],
|
||||
if (hasNews) SizedBox(width: 8.w),
|
||||
|
||||
if (hasNotification)
|
||||
Badge.count(count: 2, child: Icon(CupertinoIcons.bell_fill, color: Colors.white)),
|
||||
if (hasNotification) SizedBox(width: 8.w),
|
||||
|
||||
if (hasBack)
|
||||
GestureDetector(
|
||||
onTap: onBackTap ?? () => Get.back(id: backId),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 2, 0),
|
||||
child: Assets.vec.arrowLeftSvg.svg(
|
||||
width: 24.w,
|
||||
height: 24.h,
|
||||
colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (hasBack) SizedBox(width: 8.w),
|
||||
],
|
||||
),
|
||||
titleSpacing: 2,
|
||||
bottom: bottom,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||
Size get preferredSize => Size.fromHeight(kToolbarHeight + (bottom?.preferredSize.height ?? 0));
|
||||
|
||||
MainAxisAlignment _getMainAxisAlignment() {
|
||||
if (centerTitle) {
|
||||
return MainAxisAlignment.center;
|
||||
} else if (children != null && children!.isNotEmpty) {
|
||||
return MainAxisAlignment.start;
|
||||
} else {
|
||||
return MainAxisAlignment.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RAppBar2 extends StatelessWidget implements PreferredSizeWidget {
|
||||
@@ -1,27 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class SearchWidget extends StatefulWidget {
|
||||
const SearchWidget({super.key, this.onSearchChanged});
|
||||
|
||||
final void Function(String?)? onSearchChanged;
|
||||
|
||||
@override
|
||||
State<SearchWidget> createState() => _SearchWidgetState();
|
||||
}
|
||||
|
||||
class _SearchWidgetState extends State<SearchWidget> {
|
||||
late final SearchLogic controller;
|
||||
final TextEditingController textEditingController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
controller = Get.find<SearchLogic>();
|
||||
controller.setSearchCallback(widget.onSearchChanged);
|
||||
}
|
||||
class SearchWidget extends GetView<BaseLogic> {
|
||||
const SearchWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -48,10 +29,7 @@ class _SearchWidgetState extends State<SearchWidget> {
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
textEditingController.clear();
|
||||
controller.searchValue.value = null;
|
||||
controller.isSearchSelected.value = false;
|
||||
widget.onSearchChanged?.call(null);
|
||||
controller.clearSearch();
|
||||
},
|
||||
enableFeedback: true,
|
||||
padding: EdgeInsets.zero,
|
||||
@@ -70,7 +48,7 @@ class _SearchWidgetState extends State<SearchWidget> {
|
||||
hintStyle: AppFonts.yekan16.copyWith(color: AppColor.blueNormal),
|
||||
filledColor: Colors.white,
|
||||
filled: true,
|
||||
controller: textEditingController,
|
||||
controller: controller.textEditingController,
|
||||
onChanged: (val) => controller.searchValue.value = val,
|
||||
),
|
||||
),
|
||||
@@ -1,9 +1,17 @@
|
||||
export 'app_bar/r_app_bar.dart';
|
||||
export 'base_page/widgets/r_app_bar.dart';
|
||||
export 'bottom_navigation/r_bottom_navigation.dart';
|
||||
export 'bottom_navigation/wave_bottom_navigation.dart';
|
||||
export 'bottom_sheet/base_bottom_sheet.dart';
|
||||
export 'bottom_sheet/date_picker_bottom_sheet.dart';
|
||||
export 'check_box/check_box_widget.dart';
|
||||
//base page
|
||||
export 'base_page/view.dart';
|
||||
export 'base_page/logic.dart';
|
||||
export 'base_page/widgets/back_ground_widget.dart';
|
||||
export 'base_page/widgets/breadcrumb.dart';
|
||||
export 'base_page/widgets/search_widget.dart';
|
||||
|
||||
|
||||
//buttons
|
||||
export 'buttons/buttons.dart';
|
||||
export 'card/card_icon_widget.dart';
|
||||
|
||||
Reference in New Issue
Block a user