diff --git a/assets/icons/chicken_pattern.svg b/assets/icons/chicken_pattern.svg
index d7c33e2..5392fa4 100644
--- a/assets/icons/chicken_pattern.svg
+++ b/assets/icons/chicken_pattern.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/assets/images/bg_chicken_pattern.webp b/assets/images/bg_chicken_pattern.webp
deleted file mode 100644
index 90eca17..0000000
Binary files a/assets/images/bg_chicken_pattern.webp and /dev/null differ
diff --git a/assets/images/live_chicken.jpg b/assets/images/live_chicken.jpg
deleted file mode 100644
index d88a231..0000000
Binary files a/assets/images/live_chicken.jpg and /dev/null differ
diff --git a/assets/vec/chicken_pattern.svg.vec b/assets/vec/chicken_pattern.svg.vec
index a8afc43..45ae488 100644
Binary files a/assets/vec/chicken_pattern.svg.vec and b/assets/vec/chicken_pattern.svg.vec differ
diff --git a/packages/chicken/lib/presentation/pages/poultry_science/active_hatching/view.dart b/packages/chicken/lib/presentation/pages/poultry_science/active_hatching/view.dart
index 49ebe5a..b415e1e 100644
--- a/packages/chicken/lib/presentation/pages/poultry_science/active_hatching/view.dart
+++ b/packages/chicken/lib/presentation/pages/poultry_science/active_hatching/view.dart
@@ -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 {
const ActiveHatchingPage({super.key});
@@ -18,11 +14,22 @@ class ActiveHatchingPage extends GetView {
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 {
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 {
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 {
color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark,
),
),
-
],
),
);
diff --git a/packages/chicken/lib/presentation/pages/poultry_science/farm/view.dart b/packages/chicken/lib/presentation/pages/poultry_science/farm/view.dart
index 007ed51..1a8d05a 100644
--- a/packages/chicken/lib/presentation/pages/poultry_science/farm/view.dart
+++ b/packages/chicken/lib/presentation/pages/poultry_science/farm/view.dart
@@ -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 {
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 {
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:
diff --git a/packages/chicken/lib/presentation/pages/poultry_science/home/view.dart b/packages/chicken/lib/presentation/pages/poultry_science/home/view.dart
index d77aed0..2d5adcc 100644
--- a/packages/chicken/lib/presentation/pages/poultry_science/home/view.dart
+++ b/packages/chicken/lib/presentation/pages/poultry_science/home/view.dart
@@ -19,13 +19,7 @@ class PoultryScienceHomePage extends GetView {
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(),
diff --git a/packages/chicken/lib/presentation/pages/poultry_science/inspection/view.dart b/packages/chicken/lib/presentation/pages/poultry_science/inspection/view.dart
index 4ff0916..bb25a47 100644
--- a/packages/chicken/lib/presentation/pages/poultry_science/inspection/view.dart
+++ b/packages/chicken/lib/presentation/pages/poultry_science/inspection/view.dart
@@ -15,22 +15,32 @@ class InspectionPoultrySciencePage extends GetView 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
- 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 ProfileLogic(), fenix: true);
- Get.lazyPut(() => SearchLogic(), fenix: true);
+
//root logics
}
diff --git a/packages/chicken/lib/presentation/routes/pages.dart b/packages/chicken/lib/presentation/routes/pages.dart
index 88af388..446ad3f 100644
--- a/packages/chicken/lib/presentation/routes/pages.dart
+++ b/packages/chicken/lib/presentation/routes/pages.dart
@@ -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(
diff --git a/packages/chicken/lib/presentation/widget/app_bar.dart b/packages/chicken/lib/presentation/widget/app_bar.dart
index 05a06fe..246fc43 100644
--- a/packages/chicken/lib/presentation/widget/app_bar.dart
+++ b/packages/chicken/lib/presentation/widget/app_bar.dart
@@ -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? 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();
- 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();
- return Visibility(
- visible: controller.searchValue.value!=null,
- child: Container(
- width: 8,
- height: 8,
- decoration: const BoxDecoration(
- color: Colors.red,
- shape: BoxShape.circle,
- ),
- ),
- );
- }),
- ],
- ),
- );
-}
\ No newline at end of file
diff --git a/packages/chicken/lib/presentation/widget/base_page/logic.dart b/packages/chicken/lib/presentation/widget/base_page/logic.dart
deleted file mode 100644
index f33fa71..0000000
--- a/packages/chicken/lib/presentation/widget/base_page/logic.dart
+++ /dev/null
@@ -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;
- }
-}
diff --git a/packages/chicken/lib/presentation/widget/base_page/view.dart b/packages/chicken/lib/presentation/widget/base_page/view.dart
index cb56875..8f2b8bf 100644
--- a/packages/chicken/lib/presentation/widget/base_page/view.dart
+++ b/packages/chicken/lib/presentation/widget/base_page/view.dart
@@ -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 {
+ 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? routes;
- final Widget? routesWidget;
+ final Breadcrumb? routesWidget;
final List? 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 createState() => _BasePageState();
-}
-
-class _BasePageState extends State {
- BaseLogic get controller => Get.find();
- 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 {
@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().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? routes;
- final Widget? routesWidget;
- final List 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 createState() => _BasePageWithScrollState();
-}
-
-class _BasePageWithScrollState extends State {
- BaseLogic get controller => Get.find();
- 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().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,
),
);
}
diff --git a/packages/chicken/lib/presentation/widget/page_route.dart b/packages/chicken/lib/presentation/widget/page_route.dart
index eeaaf25..7e0248e 100644
--- a/packages/chicken/lib/presentation/widget/page_route.dart
+++ b/packages/chicken/lib/presentation/widget/page_route.dart
@@ -2,10 +2,13 @@ import 'package:flutter/cupertino.dart';
import 'package:rasadyar_core/core.dart';
Widget buildPageRoute(List 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),
),
);
diff --git a/packages/chicken/lib/presentation/widget/search/logic.dart b/packages/chicken/lib/presentation/widget/search/logic.dart
deleted file mode 100644
index 4379a4a..0000000
--- a/packages/chicken/lib/presentation/widget/search/logic.dart
+++ /dev/null
@@ -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(searchValue, (val) {
- if (val != null && val.trim().isNotEmpty) {
- onSearchChanged?.call(val);
- }
- }, time: const Duration(milliseconds: 600));
- }
-
- void toggleSearch() {
- isSearchSelected.value = !isSearchSelected.value;
- }
-
-
-}
diff --git a/packages/core/lib/presentation/common/assets.gen.dart b/packages/core/lib/presentation/common/assets.gen.dart
index 512eff0..93f3921 100644
--- a/packages/core/lib/presentation/common/assets.gen.dart
+++ b/packages/core/lib/presentation/common/assets.gen.dart
@@ -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 get values => [
- bgChickenPattern,
- chicken,
- innerSplash,
- liveChicken,
- outterSplash,
- placeHolder,
- selectRole,
- ];
+ List get values => [chicken, innerSplash, outterSplash, placeHolder, selectRole];
}
class $AssetsLogosGen {
diff --git a/packages/core/lib/presentation/widget/base_page/logic.dart b/packages/core/lib/presentation/widget/base_page/logic.dart
new file mode 100644
index 0000000..bccafe7
--- /dev/null
+++ b/packages/core/lib/presentation/widget/base_page/logic.dart
@@ -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(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;
+ }
+}
diff --git a/packages/core/lib/presentation/widget/base_page/view.dart b/packages/core/lib/presentation/widget/base_page/view.dart
new file mode 100644
index 0000000..7fdeb4e
--- /dev/null
+++ b/packages/core/lib/presentation/widget/base_page/view.dart
@@ -0,0 +1,91 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_core/core.dart';
+
+class BasePage extends GetView {
+ 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? routes;
+ final Breadcrumb? routesWidget;
+ final List? 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,
+ ),
+ );
+ }
+}
diff --git a/packages/core/lib/presentation/widget/base_page/widgets/back_ground_widget.dart b/packages/core/lib/presentation/widget/base_page/widgets/back_ground_widget.dart
new file mode 100644
index 0000000..0ab96ab
--- /dev/null
+++ b/packages/core/lib/presentation/widget/base_page/widgets/back_ground_widget.dart
@@ -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),
+ );
+}*/
diff --git a/packages/core/lib/presentation/widget/base_page/widgets/breadcrumb.dart b/packages/core/lib/presentation/widget/base_page/widgets/breadcrumb.dart
new file mode 100644
index 0000000..e5f93a1
--- /dev/null
+++ b/packages/core/lib/presentation/widget/base_page/widgets/breadcrumb.dart
@@ -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? 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 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,
+ ),
+ );
+ }
+}
+
+
diff --git a/packages/core/lib/presentation/widget/app_bar/r_app_bar.dart b/packages/core/lib/presentation/widget/base_page/widgets/r_app_bar.dart
similarity index 55%
rename from packages/core/lib/presentation/widget/app_bar/r_app_bar.dart
rename to packages/core/lib/presentation/widget/base_page/widgets/r_app_bar.dart
index edfeaea..ddb2202 100644
--- a/packages/core/lib/presentation/widget/app_bar/r_app_bar.dart
+++ b/packages/core/lib/presentation/widget/base_page/widgets/r_app_bar.dart
@@ -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? children;
+
final bool centerTitle;
- final TextStyle? titleTextStyle;
- final VoidCallback? onBackPressed;
- final List? 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 {
diff --git a/packages/chicken/lib/presentation/widget/search/view.dart b/packages/core/lib/presentation/widget/base_page/widgets/search_widget.dart
similarity index 69%
rename from packages/chicken/lib/presentation/widget/search/view.dart
rename to packages/core/lib/presentation/widget/base_page/widgets/search_widget.dart
index 1e09056..d0d7ecb 100644
--- a/packages/chicken/lib/presentation/widget/search/view.dart
+++ b/packages/core/lib/presentation/widget/base_page/widgets/search_widget.dart
@@ -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 createState() => _SearchWidgetState();
-}
-
-class _SearchWidgetState extends State {
- late final SearchLogic controller;
- final TextEditingController textEditingController = TextEditingController();
-
- @override
- void initState() {
- super.initState();
- controller = Get.find();
- controller.setSearchCallback(widget.onSearchChanged);
- }
+class SearchWidget extends GetView {
+ const SearchWidget({super.key});
@override
Widget build(BuildContext context) {
@@ -48,10 +29,7 @@ class _SearchWidgetState extends State {
)
: 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 {
hintStyle: AppFonts.yekan16.copyWith(color: AppColor.blueNormal),
filledColor: Colors.white,
filled: true,
- controller: textEditingController,
+ controller: controller.textEditingController,
onChanged: (val) => controller.searchValue.value = val,
),
),
diff --git a/packages/core/lib/presentation/widget/widget.dart b/packages/core/lib/presentation/widget/widget.dart
index 9000624..293674f 100644
--- a/packages/core/lib/presentation/widget/widget.dart
+++ b/packages/core/lib/presentation/widget/widget.dart
@@ -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';