fix : ui change's

This commit is contained in:
2025-07-09 14:54:28 +03:30
parent d51e0240bb
commit 0b921fa917
27 changed files with 611 additions and 1004 deletions

View File

@@ -0,0 +1,8 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.11631 15.1693C4.16298 15.1693 0.949646 11.9559 0.949646 8.0026C0.949646 4.04927 4.16298 0.835938 8.11631 0.835938C12.0696 0.835938 15.283 4.04927 15.283 8.0026C15.283 11.9559 12.0696 15.1693 8.11631 15.1693ZM8.11631 1.83594C4.71631 1.83594 1.94965 4.6026 1.94965 8.0026C1.94965 11.4026 4.71631 14.1693 8.11631 14.1693C11.5163 14.1693 14.283 11.4026 14.283 8.0026C14.283 4.6026 11.5163 1.83594 8.11631 1.83594Z"
fill="#FFFFFF"/>
<path d="M6.22898 10.3889C6.10232 10.3889 5.97565 10.3422 5.87565 10.2422C5.68232 10.0489 5.68232 9.72885 5.87565 9.53552L9.64898 5.76219C9.84232 5.56885 10.1623 5.56885 10.3557 5.76219C10.549 5.95552 10.549 6.27552 10.3557 6.46885L6.58232 10.2422C6.48898 10.3422 6.35565 10.3889 6.22898 10.3889Z"
fill="#FFFFFF"/>
<path d="M10.0023 10.3889C9.87565 10.3889 9.74898 10.3422 9.64898 10.2422L5.87565 6.46885C5.68232 6.27552 5.68232 5.95552 5.87565 5.76219C6.06899 5.56885 6.38898 5.56885 6.58232 5.76219L10.3557 9.53552C10.549 9.72885 10.549 10.0489 10.3557 10.2422C10.2557 10.3422 10.129 10.3889 10.0023 10.3889Z"
fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/widget/app_bar.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/sale_buy_card_item.dart'; import 'package:rasadyar_chicken/presentation/widget/sale_buy_card_item.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';

View File

@@ -31,7 +31,6 @@ class BuyInProvinceLogic extends GetxController {
ever(fromDateFilter, (callback) => _setFromDateFilter(callback)); ever(fromDateFilter, (callback) => _setFromDateFilter(callback));
ever(toDateFilter, (callback) => _setToDateFilter(callback)); ever(toDateFilter, (callback) => _setToDateFilter(callback));
} }
@override @override

View File

@@ -1,7 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_in_province_all/view.dart'; import 'package:rasadyar_chicken/presentation/pages/buy_in_province_all/view.dart';
import 'package:rasadyar_chicken/presentation/pages/buy_in_province_waiting/view.dart'; import 'package:rasadyar_chicken/presentation/pages/buy_in_province_waiting/view.dart';
import 'package:rasadyar_chicken/presentation/pages/root/logic.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/inventory_widget.dart';
import 'package:rasadyar_chicken/presentation/widget/page_route.dart'; import 'package:rasadyar_chicken/presentation/widget/page_route.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
@@ -18,7 +20,7 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
onSearchChanged: (data) => controller.setSearchValue(data), onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(), filteringWidget: filterBottomSheet(),
widgets: [ widgets: [
inventoryWidget(), inventoryWidget(controller.rootLogic),
segmentWidget(), segmentWidget(),
ObxValue((index) { ObxValue((index) {
return Expanded( return Expanded(
@@ -52,11 +54,11 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
Widget filterBottomSheet() { Widget filterBottomSheet() {
return BaseBottomSheet( return BaseBottomSheet(
height: 250, height: 200,
child: Column( child: Column(
spacing: 16, spacing: 16,
children: [ children: [
Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover)), Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)),
Row( Row(
spacing: 8, spacing: 8,
children: [ children: [
@@ -75,9 +77,12 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
), ),
], ],
), ),
SizedBox(height: 2),
RElevated( RElevated(
text: 'اعمال فیلتر', text: 'اعمال فیلتر',
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
onPressed: () { onPressed: () {
controller.submitFilter(); controller.submitFilter();
Get.back(); Get.back();
@@ -90,22 +95,5 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
); );
} }
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
} }

View File

@@ -130,7 +130,7 @@ class BuyInProvinceWaitingPage extends GetView<BuyInProvinceWaitingLogic> {
Container itemListExpandedWidget(WaitingArrivalModel item) { Container itemListExpandedWidget(WaitingArrivalModel item) {
return Container( return Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column( child: Column(
spacing: 8, spacing: 8,
@@ -155,7 +155,7 @@ class BuyInProvinceWaitingPage extends GetView<BuyInProvinceWaitingLogic> {
), ),
Container( Container(
height: 32, height: 32,
padding: EdgeInsets.symmetric(horizontal: 4), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: ShapeDecoration( decoration: ShapeDecoration(
color: AppColor.blueLight, color: AppColor.blueLight,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@@ -194,7 +194,6 @@ class BuyInProvinceWaitingPage extends GetView<BuyInProvinceWaitingLogic> {
), ),
), ),
// buildRow(title: 'مشخصات فروشنده', value: item.killHouseName ?? 'N/A'),
buildRow( buildRow(
title: 'نام و نام خانوادگی فروشنده', title: 'نام و نام خانوادگی فروشنده',
value: item.steward?.user?.fullname ?? 'N/A', value: item.steward?.user?.fullname ?? 'N/A',

View File

@@ -7,6 +7,7 @@ import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_pr
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/inventory_widget.dart';
import 'package:rasadyar_chicken/presentation/widget/list_item/list_item.dart'; import 'package:rasadyar_chicken/presentation/widget/list_item/list_item.dart';
import 'package:rasadyar_chicken/presentation/widget/list_row_item.dart'; import 'package:rasadyar_chicken/presentation/widget/list_row_item.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
@@ -24,7 +25,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
onSearchChanged: (data) => controller.setSearchValue(data), onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(), filteringWidget: filterBottomSheet(),
widgets: [ widgets: [
inventoryWidget(), inventoryWidget(controller.rootLogic),
Expanded( Expanded(
child: ObxValue((data) { child: ObxValue((data) {
return RPaginatedListView( return RPaginatedListView(
@@ -68,7 +69,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
Container itemListExpandedWidget(StewardFreeBar item) { Container itemListExpandedWidget(StewardFreeBar item) {
return Container( return Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column( child: Column(
spacing: 8, spacing: 8,
@@ -85,7 +86,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
), ),
Container( Container(
height: 32, height: 32,
padding: EdgeInsets.symmetric(horizontal: 4), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: ShapeDecoration( decoration: ShapeDecoration(
color: AppColor.blueLight, color: AppColor.blueLight,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@@ -153,7 +154,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
children: [ children: [
Text( Text(
'بارنامه', 'بارنامه',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover), style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
), ),
Image.network( Image.network(
@@ -166,7 +167,6 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
}, },
loadingBuilder: (context, child, loadingProgress) { loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child; if (loadingProgress == null) return child;
print('Loading progress: $loadingProgress');
return CupertinoActivityIndicator(); return CupertinoActivityIndicator();
}, },
), ),
@@ -300,7 +300,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
children: [ children: [
Text( Text(
isOnEdit ? 'ویرایش اطلاعات خرید' : 'ثبت اطلاعات خرید', isOnEdit ? 'ویرایش اطلاعات خرید' : 'ثبت اطلاعات خرید',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover), style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
), ),
_productDropDown(), _productDropDown(),
@@ -556,11 +556,11 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
Widget filterBottomSheet() { Widget filterBottomSheet() {
return BaseBottomSheet( return BaseBottomSheet(
height: 250, height: 200,
child: Column( child: Column(
spacing: 16, spacing: 16,
children: [ children: [
Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover)), Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)),
Row( Row(
spacing: 8, spacing: 8,
children: [ children: [
@@ -579,34 +579,20 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
), ),
], ],
), ),
SizedBox(height: 2),
RElevated( RElevated(
text: 'اعمال فیلتر', text: 'اعمال فیلتر',
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
onPressed: () { onPressed: () {
controller.getStewardPurchaseOutOfProvince(); controller.getStewardPurchaseOutOfProvince();
Get.back(); Get.back();
}, },
height: 40, height: 40,
), ),
SizedBox(height: 16),
], ],
), ),
); );
} }
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(color: AppColor.greenLight, borderRadius: BorderRadius.circular(8)),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
} }

View File

@@ -1,101 +0,0 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_auth/data/utils/safe_call.dart';
import 'package:rasadyar_chicken/chicken.dart';
import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart';
import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart';
import 'package:rasadyar_chicken/data/models/response/imported_loads_model/imported_loads_model.dart';
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart';
import 'package:rasadyar_core/core.dart';
class EnteringTheWarehouseLogic extends GetxController {
RootLogic rootLogic = Get.find<RootLogic>();
Rxn<BarInformation> barInformation = Rxn<BarInformation>();
Rxn<WaitingArrivalModel> waitingForArrival = Rxn<WaitingArrivalModel>();
Rxn<ImportedLoadsModel> importedLoads = Rxn<ImportedLoadsModel>();
RxInt acceptType = 1.obs;
TextEditingController weightController = TextEditingController();
TextEditingController volumeController = TextEditingController();
TextEditingController weightLossController = TextEditingController();
TextEditingController authenticationCodeController = TextEditingController();
final ScrollController scrollControllerImportedLoad = ScrollController();
final RxInt currentPageImportedLoad = 1.obs;
final RxBool isLoadingMoreImportedLoad = false.obs;
final RxBool addPageImportedLoad = false.obs;
final RxBool hasMoreDataImportedLoad = true.obs;
final ScrollController scrollControllerWaitingForArrival = ScrollController();
final RxInt currentPageWaitingForArrival = 1.obs;
final RxBool isLoadingMoreWaitingForArrival = false.obs;
final RxBool addPageWaitingForArrival = false.obs;
final RxBool hasMoreDataWaitingForArrival = true.obs;
@override
void onReady() {
super.onReady();
getBarGeneralInformation();
}
Future<void> getBarGeneralInformation() async {
safeCall(
call: () async =>
await rootLogic.chickenRepository.getGeneralBarInformation(
token: rootLogic.tokenService.accessToken.value!,
),
onError: (error, stackTrace) {
eLog(error);
},
onSuccess: (result) {
if (result != null) {
barInformation.value = result;
}
},
);
}
Future<void> getImportedEntried() async {
if (isLoadingMoreImportedLoad.value || !hasMoreDataImportedLoad.value) {
return;
}
if (addPageImportedLoad.value) {
currentPageImportedLoad.value++;
}
/* safeCall(
call: () async => await rootLogic.chickenRepository.getImportedLoadsModel(
token: rootLogic.tokenService.accessToken.value!,
page: currentPageImportedLoad.value,
),
onError: (error, stackTrace) {
isLoadingMoreImportedLoad.value = false;
},
onSuccess: (result) {
if (result != null) {
if (isLoadingMoreImportedLoad.value && result.results != null) {
importedLoads.value?.results?.addAll(result.results!);
} else {
importedLoads.value = result;
}
isLoadingMoreImportedLoad.value = false;
}
},
);*/
}
clearControllers() {
weightController.clear();
volumeController.clear();
weightLossController.clear();
authenticationCodeController.clear();
}
@override
void dispose() {
rootLogic.inventoryExpandedList.clear();
super.dispose();
}
}

View File

@@ -1,525 +0,0 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart';
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
import 'package:rasadyar_core/core.dart';
import 'logic.dart';
class EnteringTheWarehousePage extends GetView<EnteringTheWarehouseLogic> {
EnteringTheWarehousePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: RAppBar(title: 'ورود به انبار'),
body: SingleChildScrollView(
child: Column(
children: [
inventoryWidget(),
ObxValue((data) {
return generalBarInformation(data.value);
}, controller.barInformation),
// importedLoads(),
],
),
),
);
}
Widget inventoryWidget() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
children: [
const SizedBox(height: 20),
Align(
alignment: Alignment.centerRight,
child: Text(
'موجودی انبار',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
),
),
SizedBox(height: 4),
/* ObxValue(
(data) => data.isEmpty
? Container(
margin: const EdgeInsets.symmetric(vertical: 2),
height: 80,
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.blueNormal, width: 1),
),
child: Center(child: CircularProgressIndicator()),
)
: ListView.separated(
shrinkWrap: true,
itemCount: controller.rootLogic.inventoryList.length,
separatorBuilder: (context, index) =>
const SizedBox(height: 8),
itemBuilder: (context, index) {
return ObxValue((expand) {
return GestureDetector(
onTap: () {
controller.rootLogic.toggleExpanded(index);
},
behavior: HitTestBehavior.opaque,
child: AnimatedContainer(
onEnd: () {
controller
.rootLogic
.inventoryExpandedList[index] = !controller
.rootLogic
.inventoryExpandedList[index]!;
},
margin: const EdgeInsets.symmetric(vertical: 2),
padding: EdgeInsets.all(6),
curve: Curves.easeInOut,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: AppColor.blueNormal,
width: 1,
),
),
duration: const Duration(seconds: 1),
height: expand.keys.contains(index) ? 250 : 80,
child: inventoryItem(
isExpanded:
expand.keys.contains(index) && expand[index]!,
index: index,
model: controller.rootLogic.inventoryList[index],
),
),
);
}, controller.rootLogic.inventoryExpandedList);
},
),
controller.rootLogic.inventoryList,
),*/
],
),
);
}
Widget inventoryItem({
required bool isExpanded,
required int index,
required InventoryModel model,
}) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
buildRow('نام محصول', model.name ?? ''),
Visibility(
visible: isExpanded,
child: Column(
spacing: 8,
children: [
buildRow('وزن خریدهای دولتی داخل استان (کیلوگرم)', '0'),
buildRow(
'وزن خریدهای آزاد داخل استان (کیلوگرم)',
model.receiveFreeCarcassesWeight.toString(),
),
buildRow(
'وزن خریدهای خارج استان (کیلوگرم)',
model.freeBuyingCarcassesWeight.toString(),
),
buildRow(
'کل ورودی به انبار (کیلوگرم)',
model.totalFreeBarsCarcassesWeight.toString(),
),
buildRow('کل فروش (کیلوگرم)', model.realAllocatedWeight.toString()),
buildRow('مانده انبار (کیلوگرم)', model.totalRemainWeight.toString()),
],
),
),
],
);
}
Widget buildRow(String title, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 2,
child: Text(
title,
textAlign: TextAlign.right,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
),
),
Flexible(
flex: 1,
child: Text(
value,
textAlign: TextAlign.left,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
),
),
],
),
);
}
Widget generalBarInformation(BarInformation? model) {
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Align(
alignment: Alignment.centerRight,
child: Text(
'اطلاعات کلی بارها',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
),
),
),
Container(
height: 290,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.blueNormal, width: 1),
),
child: model != null
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
buildRow('تعداد کل بارها', model.totalBars!.toInt().toString()),
buildRow('وزن کل بارها (کیلوگرم)', model.totalBarsWeight!.toInt().toString()),
buildRow(
'تعداد کل بارهای وارد شده',
model.totalEnteredBars!.toInt().toString(),
),
buildRow(
'وزن کل بار وارد شده (کیلوگرم)',
model.totalEnteredBarsWeight!.toInt().toString(),
),
buildRow(
'تعداد کل بارهای وارد نشده',
model.totalNotEnteredBars!.toInt().toString(),
),
buildRow(
'وزن کل بار وارد نشده (کیلوگرم)',
model.totalNotEnteredKillHouseRequestsWeight!.toInt().toString(),
),
buildRow('تعداد کل بارهای رد شده', model.totalRejectedBars!.toInt().toString()),
buildRow(
' وزن کل بارهای رد شده',
model.totalRejectedBarsWeight!.toInt().toString(),
),
],
)
: const Center(child: CircularProgressIndicator()),
),
],
);
}
/* Widget waitingForArrival() {
return Column(
children: [
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Align(
alignment: Alignment.centerRight,
child: Text(
'موجودی انبار',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
),
),
),
ObxValue((data) {
if (data.value == null) {
return Container(
height: 80,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.blueNormal, width: 1),
),
child: Center(child: CircularProgressIndicator()),
);
} else if (data.value?.results.isEmpty ?? true) {
return Container(
height: 80,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.blueNormal, width: 1),
),
child: Center(child: Text('هیچ ورودی در انتظار نیست')),
);
} else {
return Container(
margin: const EdgeInsets.symmetric(vertical: 2),
height: 700,
padding: const EdgeInsets.all(6),
child: ListView.separated(
controller: controller.scrollControllerWaitingForArrival,
padding: const EdgeInsets.all(8.0),
itemCount: data.value!.results.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == data.value!.results!.length) {
return Obx(
() => controller.isLoadingMoreWaitingForArrival.value
? const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(child: CircularProgressIndicator()),
)
: const SizedBox(),
);
}
final result = data.value!.results[index];
return Card(
margin: const EdgeInsets.symmetric(vertical: 4.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: const BorderSide(
color: AppColor.blueNormal,
width: 1,
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildRow('ردیف', '${index + 1}'),
buildRow(
'تاریخ ثبت',
result.date!.formattedJalaliDate ?? 'N/A',
),
buildRow(
'نوع تخصیص',
result.allocationType?.faAllocationType ?? 'N/A',
),
buildRow(
'مشخصات خریدار',
result.toSteward?.user?.fullname ?? 'N/A',
),
buildRow(
'مشخصات فروشنده',
result.killHouse?.name ?? 'N/A',
),
buildRow(
'نوع فروش',
result.sellType?.faItem ?? 'N/A',
),
buildRow(
'قیمت هر کیلو',
'${result.amount ?? 0} تومان',
),
buildRow(
'قیمت کل',
'${result.totalAmount ?? 0} تومان',
),
buildRow(
'وزن تخصیصی',
'${result.weightOfCarcasses?.toInt() ?? 0} کیلوگرم',
),
buildRow('وضعیت', result.state?.faItem ?? 'N/A'),
Row(
children: [
Expanded(
child: RElevated(
text: 'تایید',
onPressed: () {
Get.bottomSheet(acceptBottomSheet(result));
},
height: 40,
),
),
SizedBox(width: 20),
Expanded(
child: RElevated(
text: 'رد',
onPressed: () {
controller.denyEntried(result.key!);
Get.back();
},
backgroundColor: AppColor.error,
height: 40,
),
),
],
),
],
),
),
);
},
separatorBuilder: (BuildContext context, int index) =>
SizedBox(height: 8),
),
);
}
}, controller.waitingForArrival),
],
);
}*/
/* Widget importedLoads() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildRow('ردیف', '${index + 1}'),
buildRow(
'تاریخ ثبت',
result.date!.formattedJalaliDate ?? 'N/A',
),
buildRow(
'نوع تخصیص',
result.allocationType?.faAllocationType ?? 'N/A',
),
buildRow(
'مشخصات خریدار',
'${result.toSteward?.user?.fullname} - ${result.toSteward?.guildsName}' ??
'N/A',
),
buildRow(
'مشخصات فروشنده',
result.killHouse?.name ?? 'N/A',
),
buildRow(
'نوع فروش',
result.sellType?.faItem ?? 'N/A',
),
buildRow(
'قیمت هر کیلو',
'${result.amount ?? 0} ریال ',
),
buildRow(
'قیمت کل',
'${result.totalAmount ?? 0} ریال',
),
buildRow(
'وزن تخصیصی',
'${result.weightOfCarcasses?.toInt() ?? 0} کیلوگرم',
),
buildRow(
'کداحراز',
result.registrationCode?.toString() ?? 'N/A',
),
buildRow(
'وضعیت کد احراز',
result.systemRegistrationCode == true
? "ارسال شده"
: "ارسال نشده" ?? 'N/A',
),
buildRow(
'افت وزن(کیلوگرم)',
result.weightLossOfCarcasses?.toInt().toString() ??
'N/A',
),
buildRow(
'وضعیت',
result.receiverState?.faItem ?? 'N/A',
),
],
),
);
}*/
/* Widget acceptBottomSheet(ResultModel resultModel) {
return BaseBottomSheet(
height: 500,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
RTextField(
controller: controller.weightController,
initText: resultModel.realWeightOfCarcasses?.toInt().toString(),
label: 'ورزن',
keyboardType: TextInputType.number,
),
const SizedBox(height: 8),
RTextField(
controller: controller.volumeController,
label: 'حجم',
keyboardType: TextInputType.number,
),
const SizedBox(height: 8),
RTextField(
controller: controller.weightLossController,
label: 'افت وزن(کیلوگرم)',
keyboardType: TextInputType.number,
),
const SizedBox(height: 8),
SizedBox(
height: 40,
child: ObxValue((data) {
return Row(
children: [
Radio(
value: 1,
groupValue: controller.acceptType.value,
onChanged: (value) {
controller.acceptType.value = value!;
},
),
Text('با کد احراز', style: AppFonts.yekan14),
SizedBox(width: 12),
Radio(
value: 2,
groupValue: controller.acceptType.value,
onChanged: (value) {
controller.acceptType.value = value!;
},
),
Text('با کد احراز', style: AppFonts.yekan14),
],
);
}, controller.acceptType),
),
const SizedBox(height: 8),
ObxValue(
(data) => Visibility(
visible: data.value == 1,
child: RTextField(
controller: controller.authenticationCodeController,
label: 'کد احراز',
keyboardType: TextInputType.number,
),
),
controller.acceptType,
),
RElevated(
text: 'تایید',
onPressed: () {
controller.acceptEntried(resultModel.key!);
Get.back();
},
),
],
),
);
}*/
}

View File

@@ -6,6 +6,7 @@ import 'package:rasadyar_chicken/data/models/response/roles_products/roles_produ
import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/inventory_widget.dart';
import 'package:rasadyar_chicken/presentation/widget/list_item/list_item.dart'; import 'package:rasadyar_chicken/presentation/widget/list_item/list_item.dart';
import 'package:rasadyar_chicken/presentation/widget/list_row_item.dart'; import 'package:rasadyar_chicken/presentation/widget/list_row_item.dart';
import 'package:rasadyar_chicken/presentation/widget/page_route.dart'; import 'package:rasadyar_chicken/presentation/widget/page_route.dart';
@@ -25,7 +26,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
onSearchChanged: (data) => controller.setSearchValue(data), onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(), filteringWidget: filterBottomSheet(),
widgets: [ widgets: [
inventoryWidget(), inventoryWidget(controller.rootLogic),
Expanded( Expanded(
child: ObxValue((data) { child: ObxValue((data) {
return RPaginatedListView( return RPaginatedListView(
@@ -99,22 +100,6 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
); );
} }
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(color: AppColor.greenLight, borderRadius: BorderRadius.circular(8)),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
itemListWidget(AllocatedMadeModel item) { itemListWidget(AllocatedMadeModel item) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@@ -193,7 +178,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
itemListExpandedWidget(AllocatedMadeModel item, int index) { itemListExpandedWidget(AllocatedMadeModel item, int index) {
return Container( return Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column( child: Column(
spacing: 8, spacing: 8,
@@ -218,7 +203,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
), ),
Container( Container(
height: 32, height: 32,
padding: EdgeInsets.symmetric(horizontal: 4), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: ShapeDecoration( decoration: ShapeDecoration(
color: AppColor.blueLight, color: AppColor.blueLight,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@@ -338,7 +323,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
children: [ children: [
Text( Text(
'${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش', '${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor), style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
productDropDown(), productDropDown(),
@@ -576,11 +561,11 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
Widget filterBottomSheet() { Widget filterBottomSheet() {
return BaseBottomSheet( return BaseBottomSheet(
height: 250, height: 200,
child: Column( child: Column(
spacing: 16, spacing: 16,
children: [ children: [
Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover)), Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)),
Row( Row(
spacing: 8, spacing: 8,
children: [ children: [
@@ -599,16 +584,16 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
), ),
], ],
), ),
SizedBox(height: 2),
RElevated( RElevated(
text: 'اعمال فیلتر', text: 'اعمال فیلتر',
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
onPressed: () { onPressed: () {
controller.getAllocatedMade(); controller.getAllocatedMade();
Get.back(); Get.back();
}, },
height: 40, height: 40,
), ),
SizedBox(height: 16),
], ],
), ),
); );

View File

@@ -43,12 +43,12 @@ class SalesOutOfProvinceLogic extends GetxController {
} }
void setSearchValue(String value) { void setSearchValue(String? value) {
searchedValue.value = value.trim(); searchedValue.value = value?.trim();
if (selectedSegmentIndex.value == 0) { if (selectedSegmentIndex.value == 0) {
saleListLogic.searchedValue.value = value.trim(); saleListLogic.searchedValue.value = value?.trim();
} else { } else {
buyersLogic.searchedValue.value = value.trim(); buyersLogic.searchedValue.value = value?.trim();
} }
} }

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province_buyers/view.dart'; import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province_buyers/view.dart';
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province_sales_list/view.dart'; import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province_sales_list/view.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart';
import 'package:rasadyar_chicken/presentation/widget/inventory_widget.dart';
import 'package:rasadyar_chicken/presentation/widget/page_route.dart'; import 'package:rasadyar_chicken/presentation/widget/page_route.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
@@ -13,15 +15,12 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BasePage( return BasePage(
routesWidget: ObxValue( routesWidget: ObxValue((route) => buildPageRoute(route), controller.routesName),
(route) => buildPageRoute(route),
controller.routesName,
),
onBackPressed: () => Get.back(id: 1), onBackPressed: () => Get.back(id: 1),
onSearchChanged: (data) => controller.setSearchValue(data), onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(), filteringWidget: filterBottomSheet(),
widgets: [ widgets: [
inventoryWidget(), inventoryWidget(controller.rootLogic),
segmentWidget(), segmentWidget(),
Expanded( Expanded(
child: ObxValue((index) { child: ObxValue((index) {
@@ -46,8 +45,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
borderColor: const Color(0xFFB4B4B4), borderColor: const Color(0xFFB4B4B4),
selectedBorderColor: AppColor.blueNormal, selectedBorderColor: AppColor.blueNormal,
selectedBackgroundColor: AppColor.blueLight, selectedBackgroundColor: AppColor.blueLight,
onSegmentSelected: (index) => onSegmentSelected: (index) => controller.selectedSegmentIndex.value = index,
controller.selectedSegmentIndex.value = index,
backgroundColor: AppColor.whiteGreyNormal, backgroundColor: AppColor.whiteGreyNormal,
), ),
), ),
@@ -56,68 +54,12 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
); );
} }
Widget filterBottomSheet() { Widget filterBottomSheet() => filterBottomSheetWidget(
return BaseBottomSheet( fromDate: controller.fromDateFilter,
height: 250, onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali,
child: Column( toDate: controller.toDateFilter,
spacing: 16, onChangedToDate: (jalali) => controller.toDateFilter.value = jalali,
children: [ onSubmit: () => controller.submitFilter(),
Text(
'فیلترها',
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
Row(
spacing: 8,
children: [
Expanded(
child: dateFilterWidget(
date: controller.fromDateFilter,
onChanged: (jalali) =>
controller.fromDateFilter.value = jalali,
),
),
Expanded(
child: dateFilterWidget(
isFrom: false,
date: controller.toDateFilter,
onChanged: (jalali) => controller.toDateFilter.value = jalali,
),
),
],
),
SizedBox(height: 2),
RElevated(
text: 'اعمال فیلتر',
onPressed: () {
controller.submitFilter();
Get.back();
},
height: 40,
),
SizedBox(height: 16),
],
),
); );
}
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
} }

View File

@@ -62,7 +62,7 @@ class SalesOutOfProvinceBuyersPage extends GetView<SalesOutOfProvinceBuyersLogic
children: [ children: [
Text( Text(
isOnEdit ? 'ویرایش خریدار' : 'افزودن خریدار', isOnEdit ? 'ویرایش خریدار' : 'افزودن خریدار',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover), style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
), ),
Container( Container(
@@ -192,14 +192,17 @@ class SalesOutOfProvinceBuyersPage extends GetView<SalesOutOfProvinceBuyersLogic
} }
itemListWidget(OutProvinceCarcassesBuyer item) { itemListWidget(OutProvinceCarcassesBuyer item) {
return Row( return Padding(
padding: const EdgeInsets.only(right: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
SizedBox(width: 12), SizedBox(width: 8),
Expanded( Expanded(
flex: 2, flex: 2,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
item.buyer?.fullname ?? 'N/A', item.buyer?.fullname ?? 'N/A',
@@ -234,12 +237,13 @@ class SalesOutOfProvinceBuyersPage extends GetView<SalesOutOfProvinceBuyersLogic
), ),
), ),
], ],
),
); );
} }
itemListExpandedWidget(OutProvinceCarcassesBuyer item) { itemListExpandedWidget(OutProvinceCarcassesBuyer item) {
return Container( return Container(
padding: EdgeInsets.fromLTRB(8, 12, 14, 12), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column( child: Column(

View File

@@ -121,8 +121,7 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
itemListExpandedWidget(StewardFreeSaleBar item, int index) { itemListExpandedWidget(StewardFreeSaleBar item, int index) {
return Container( return Container(
padding: EdgeInsets.fromLTRB(8, 12, 14, 12), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column( child: Column(
spacing: 8, spacing: 8,
@@ -139,7 +138,7 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
), ),
Container( Container(
height: 32, height: 32,
padding: EdgeInsets.symmetric(horizontal: 4), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: ShapeDecoration( decoration: ShapeDecoration(
color: AppColor.blueLight, color: AppColor.blueLight,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@@ -147,7 +146,35 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
), ),
child: buildRow(title: 'تاریخ', value: item.date?.formattedJalaliDateYHMS ?? 'N/A'), child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
spacing: 3,
children: [
Text(
item.date?.toJalali.formatter.wN ?? 'N/A',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
Text(
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'N/A'}',
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
],
),
Text(
'${item.date?.toJalali.formatter.y}',
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
),
Text(
'${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'N/A'}',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
],
),
), ),
buildRow(title: 'مشخصات خریدار', value: item.buyer?.fullname ?? 'N/A'), buildRow(title: 'مشخصات خریدار', value: item.buyer?.fullname ?? 'N/A'),
buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'N/A'), buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'N/A'),
@@ -208,7 +235,7 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
children: [ children: [
Text( Text(
isOnEdit ? 'ویرایش فروش' : 'افزودن فروش', isOnEdit ? 'ویرایش فروش' : 'افزودن فروش',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover), style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
), ),
_productDropDown(), _productDropDown(),

View File

@@ -1,4 +1,6 @@
import 'package:flutter/material.dart'; 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'; import 'package:rasadyar_core/core.dart';
RAppBar chickenAppBar({ RAppBar chickenAppBar({
@@ -22,7 +24,6 @@ RAppBar chickenAppBar({
Assets.vec.chickenSvg.svg( Assets.vec.chickenSvg.svg(
width: 24, width: 24,
height: 24, height: 24,
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
), ),
], ],
), ),
@@ -35,24 +36,62 @@ RAppBar chickenAppBar({
); );
} }
GestureDetector filterWidget(GestureTapCallback? onSearchTap) {
GestureDetector filterWidget(GestureTapCallback? onFilterTap) {
return GestureDetector( return GestureDetector(
onTap: onSearchTap, onTap: onFilterTap,
child: Assets.vec.filterOutlineSvg.svg( child: Stack(
alignment: Alignment.topRight,
children: [
Assets.vec.filterOutlineSvg.svg(
width: 20, width: 20,
height: 20, height: 20,
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), 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) {
GestureDetector searchWidget(GestureTapCallback? onFilterTap) {
return GestureDetector( return GestureDetector(
onTap: onFilterTap, onTap: onSearchTap,
child: Assets.vec.searchSvg.svg( child: Stack(
alignment: Alignment.topRight,
children: [
Assets.vec.searchSvg.svg(
width: 24, width: 24,
height: 24, height: 24,
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), 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,
),
),
);
}),
],
),
); );
} }

View File

@@ -35,7 +35,7 @@ class BasePage extends StatefulWidget {
final FloatingActionButtonLocation? floatingActionButtonLocation; final FloatingActionButtonLocation? floatingActionButtonLocation;
final Widget? floatingActionButton; final Widget? floatingActionButton;
final Widget? filteringWidget; final Widget? filteringWidget;
final void Function(String)? onSearchChanged; final void Function(String?)? onSearchChanged;
final bool hasBack; final bool hasBack;
final bool hasFilter; final bool hasFilter;
final bool hasSearch; final bool hasSearch;

View File

@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart';
Widget filterBottomSheetWidget({
required Rx<Jalali> fromDate,
required Function(Jalali jalali) onChangedFromDate,
required Rx<Jalali> toDate,
required Function(Jalali jalali) onChangedToDate,
required VoidCallback onSubmit,
}) {
return BaseBottomSheet(
height: 200,
child: Column(
spacing: 16,
children: [
Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)),
Row(
spacing: 8,
children: [
Expanded(
child: dateFilterWidget(date: fromDate, onChanged: onChangedFromDate),
),
Expanded(
child: dateFilterWidget(isFrom: false, date: toDate, onChanged: onChangedToDate),
),
],
),
RElevated(
height: 40,
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
text: 'اعمال فیلتر',
onPressed: () {
onSubmit();
Get.back();
},
),
],
),
);
}

View File

@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/presentation/pages/root/logic.dart';
import 'package:rasadyar_core/core.dart';
Widget inventoryWidget(RootLogic rootLogic) {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.textColor, width: 0.5),
),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, rootLogic.inventoryModel),
);
}

View File

@@ -6,7 +6,7 @@ import 'logic.dart';
class SearchWidget extends StatefulWidget { class SearchWidget extends StatefulWidget {
const SearchWidget({super.key, this.onSearchChanged}); const SearchWidget({super.key, this.onSearchChanged});
final void Function(String)? onSearchChanged; final void Function(String?)? onSearchChanged;
@override @override
State<SearchWidget> createState() => _SearchWidgetState(); State<SearchWidget> createState() => _SearchWidgetState();
@@ -14,6 +14,7 @@ class SearchWidget extends StatefulWidget {
class _SearchWidgetState extends State<SearchWidget> { class _SearchWidgetState extends State<SearchWidget> {
late final SearchLogic controller; late final SearchLogic controller;
final TextEditingController textEditingController = TextEditingController();
@override @override
void initState() { void initState() {
@@ -26,26 +27,50 @@ class _SearchWidgetState extends State<SearchWidget> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ObxValue((data) { return ObxValue((data) {
return AnimatedContainer( return AnimatedContainer(
margin: EdgeInsets.symmetric(vertical: 4),
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.only(top: 5),
curve: Curves.easeInOut, curve: Curves.easeInOut,
height: data.value ? 50 : 0, height: data.value ? 40 : 0,
child: Visibility( child: Visibility(
visible: data.value, visible: data.value,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: RTextField( child: RTextField(
suffixIcon: Padding( height: 40,
padding: const EdgeInsets.all(12.0), borderColor: AppColor.blackLight,
child: Assets.vec.searchSvg.svg( suffixIcon: ObxValue(
(data) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: (data.value == null)
? Assets.vec.searchSvg.svg(
width: 10, width: 10,
height: 10, height: 10,
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
)
: IconButton(
onPressed: () {
textEditingController.clear();
controller.searchValue.value = null;
controller.isSearchSelected.value = false;
widget.onSearchChanged?.call(null);
},
enableFeedback: true,
padding: EdgeInsets.zero,
iconSize: 24,
splashRadius: 50,
icon: Assets.vec.closeCircleSvg.svg(
width: 20,
height: 20,
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
), ),
), ),
hintText: 'جستجو', ),
controller: TextEditingController(), controller.searchValue,
),
hintText: 'جستجو کنید ...',
hintStyle: AppFonts.yekan16.copyWith(color: AppColor.blueNormal),
filledColor: Colors.white,
filled: true,
controller: textEditingController,
onChanged: (val) => controller.searchValue.value = val, onChanged: (val) => controller.searchValue.value = val,
), ),
), ),

View File

@@ -1,7 +1,6 @@
name: rasadyar_chicken name: rasadyar_chicken
description: A starting point for Dart libraries or applications. description: A starting point for Dart libraries or applications.
version: 1.0.0 version: 1.0.1
# repository: https://github.com/my_org/my_repo
environment: environment:
sdk: ^3.8.1 sdk: ^3.8.1

View File

@@ -74,6 +74,9 @@ class $AssetsIconsGen {
/// File path: assets/icons/clock.svg /// File path: assets/icons/clock.svg
SvgGenImage get clock => const SvgGenImage('assets/icons/clock.svg'); SvgGenImage get clock => const SvgGenImage('assets/icons/clock.svg');
/// File path: assets/icons/close_circle.svg
SvgGenImage get closeCircle => const SvgGenImage('assets/icons/close_circle.svg');
/// File path: assets/icons/close_square.svg /// File path: assets/icons/close_square.svg
SvgGenImage get closeSquare => const SvgGenImage('assets/icons/close_square.svg'); SvgGenImage get closeSquare => const SvgGenImage('assets/icons/close_square.svg');
@@ -259,6 +262,7 @@ class $AssetsIconsGen {
clipboardEye, clipboardEye,
clipboardTask, clipboardTask,
clock, clock,
closeCircle,
closeSquare, closeSquare,
convertCube, convertCube,
cube, cube,
@@ -395,6 +399,9 @@ class $AssetsVecGen {
/// File path: assets/vec/clock.svg.vec /// File path: assets/vec/clock.svg.vec
SvgGenImage get clockSvg => const SvgGenImage.vec('assets/vec/clock.svg.vec'); SvgGenImage get clockSvg => const SvgGenImage.vec('assets/vec/clock.svg.vec');
/// File path: assets/vec/close_circle.svg.vec
SvgGenImage get closeCircleSvg => const SvgGenImage.vec('assets/vec/close_circle.svg.vec');
/// File path: assets/vec/close_square.svg.vec /// File path: assets/vec/close_square.svg.vec
SvgGenImage get closeSquareSvg => const SvgGenImage.vec('assets/vec/close_square.svg.vec'); SvgGenImage get closeSquareSvg => const SvgGenImage.vec('assets/vec/close_square.svg.vec');
@@ -580,6 +587,7 @@ class $AssetsVecGen {
clipboardEyeSvg, clipboardEyeSvg,
clipboardTaskSvg, clipboardTaskSvg,
clockSvg, clockSvg,
closeCircleSvg,
closeSquareSvg, closeSquareSvg,
convertCubeSvg, convertCubeSvg,
cubeSvg, cubeSvg,

View File

@@ -1,7 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_core/presentation/common/app_color.dart'; import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_core/presentation/common/app_fonts.dart';
import 'package:rasadyar_core/presentation/utils/color_utils.dart';
class ROutlinedElevated extends StatefulWidget { class ROutlinedElevated extends StatefulWidget {
ROutlinedElevated({ ROutlinedElevated({
@@ -16,19 +14,17 @@ class ROutlinedElevated extends StatefulWidget {
this.radius, this.radius,
this.textStyle, this.textStyle,
this.child, this.child,
this.width = 150.0, this.width,
this.height = 56.0, this.height,
}); });
final String? text; final String? text;
final VoidCallback? onPressed; final VoidCallback? onPressed;
final double width; final double? width;
final double height; final double? height;
Color? foregroundColor; Color? foregroundColor;
Color? backgroundColor; Color? backgroundColor;
Color? borderColor; Color? borderColor;
Color? disabledBackgroundColor; Color? disabledBackgroundColor;
Color? pressedBackgroundColor; Color? pressedBackgroundColor;
double? radius; double? radius;
@@ -40,37 +36,64 @@ class ROutlinedElevated extends StatefulWidget {
} }
class _ROutlinedElevatedState extends State<ROutlinedElevated> { class _ROutlinedElevatedState extends State<ROutlinedElevated> {
final WidgetStatesController _statesController = WidgetStatesController();
final GlobalKey _widgetKey = GlobalKey();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_getWidgetHeight();
});
}
void _getWidgetHeight() {
final RenderBox? renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox?;
if (renderBox != null) {
final height = renderBox.size.height;
debugPrint('ارتفاع ویجت بعد از رندر شدن: $height');
} else {
debugPrint('ویجت هنوز رندر نشده است');
}
}
@override
void dispose() {
_statesController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OutlinedButton( return ConstrainedBox(
constraints: BoxConstraints.tightFor(
width: widget.width ?? 150.w,
height: widget.height ?? 40.h,
),
child: OutlinedButton(
key: _widgetKey,
statesController: _statesController,
onPressed: widget.onPressed, onPressed: widget.onPressed,
style: ButtonStyle( style: ButtonStyle(
side: WidgetStateProperty.resolveWith<BorderSide?>((states) { side: WidgetStateProperty.resolveWith<BorderSide?>((states) {
if (states.contains(WidgetState.pressed)) { if (states.contains(WidgetState.pressed)) {
return BorderSide( return BorderSide(color: widget.borderColor ?? AppColor.blueNormal, width: 2);
color: widget.borderColor ?? AppColor.blueNormal,
width: 2,
);
} else if (states.contains(WidgetState.disabled)) { } else if (states.contains(WidgetState.disabled)) {
return BorderSide( return BorderSide(
color: widget.borderColor ?? AppColor.blueNormal.withAlpha(38), color: widget.borderColor ?? AppColor.blueNormal.withAlpha(38),
width: 2, width: 2,
); );
} }
return BorderSide( return BorderSide(color: widget.borderColor ?? AppColor.blueNormal, width: 2);
color: widget.borderColor ?? AppColor.blueNormal,
width: 2,
);
}), }),
backgroundColor: WidgetStateProperty.resolveWith<Color?>((states) { backgroundColor: WidgetStateProperty.resolveWith<Color?>((states) {
if (states.contains(WidgetState.pressed)) { if (states.contains(WidgetState.pressed)) {
if (widget.pressedBackgroundColor != null) { if (widget.pressedBackgroundColor != null) {
return widget.pressedBackgroundColor; return widget.pressedBackgroundColor;
} }
return widget.backgroundColor?.pressedColor ?? AppColor.blueNormal; return widget.backgroundColor?.pressedColor ?? widget.borderColor?.pressedColor;
} else if (states.contains(WidgetState.hovered)) { } else if (states.contains(WidgetState.hovered)) {
return widget.backgroundColor?.hoverColor ?? return widget.backgroundColor?.hoverColor ?? AppColor.blueNormal.hoverColor;
AppColor.blueNormal.hoverColor;
} else if (states.contains(WidgetState.disabled)) { } else if (states.contains(WidgetState.disabled)) {
return widget.backgroundColor?.disabledColor ?? Colors.transparent; return widget.backgroundColor?.disabledColor ?? Colors.transparent;
} }
@@ -82,22 +105,23 @@ class _ROutlinedElevatedState extends State<ROutlinedElevated> {
} else if (states.contains(WidgetState.disabled)) { } else if (states.contains(WidgetState.disabled)) {
return AppColor.blueNormal.withAlpha(38); return AppColor.blueNormal.withAlpha(38);
} }
return AppColor.blueNormal; return widget.foregroundColor ?? widget.borderColor ?? AppColor.blueNormal;
}), }),
shape: WidgetStatePropertyAll( shape: WidgetStatePropertyAll(
RoundedRectangleBorder( RoundedRectangleBorder(borderRadius: BorderRadius.circular(widget.radius ?? 8)),
borderRadius: BorderRadius.circular(widget.radius ?? 8),
), ),
), fixedSize: WidgetStatePropertyAll(Size(widget.width ?? 150.w, widget.height ?? 56.h)),
fixedSize: WidgetStatePropertyAll(Size(widget.width, widget.height)),
padding: WidgetStatePropertyAll(EdgeInsets.zero), padding: WidgetStatePropertyAll(EdgeInsets.zero),
textStyle: WidgetStatePropertyAll( textStyle: WidgetStateProperty.resolveWith<TextStyle?>((states) {
widget.textStyle ?? if (states.contains(WidgetState.pressed)) {
AppFonts.yekan24.copyWith(color: AppColor.blueNormal), return widget.textStyle?.copyWith(color: Colors.white) ??
AppFonts.yekan20.copyWith(color: Colors.white);
}
return widget.textStyle ?? AppFonts.yekan20.copyWith(color: AppColor.blueNormal);
}),
), ),
child: Text(widget.text ?? ''),
), ),
child: widget.child ?? Text(widget.text!, style: widget.textStyle),
); );
} }
} }

View File

@@ -11,7 +11,7 @@ class EmptyWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Row(), Row(),
Assets.images.placeHolder.image(width: 170.w,height: 170.h), Assets.vec.emptySvg.svg(width: 170.w,height: 170.h),
Text('داده ای یافت نشد!', style: AppFonts.yekan20.copyWith(color: AppColor.textColor)), Text('داده ای یافت نشد!', style: AppFonts.yekan20.copyWith(color: AppColor.textColor)),
], ],
); );

View File

@@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@@ -37,40 +39,69 @@ class RTextField extends StatefulWidget {
final VoidCallback? onTap; final VoidCallback? onTap;
final List<TextInputFormatter>? inputFormatters; final List<TextInputFormatter>? inputFormatters;
final Widget? suffix; final Widget? suffix;
final FocusNode? focusNode;
final AutovalidateMode? autoValidateMode;
final TextAlign? textAlign;
final TextCapitalization textCapitalization;
final Color? cursorColor;
final bool? autocorrect;
final bool? enableSuggestions;
final TextInputAction? textInputAction;
final double? height;
const RTextField({ const RTextField({
super.key, super.key,
// 🔹 Core
required this.controller, required this.controller,
this.label, this.label,
this.hintText, this.hintText,
this.initText, this.initText,
this.onChanged,
this.onSubmitted,
this.onTap,
this.height,
// 🔸 Behavior
this.obscure = false, this.obscure = false,
this.readonly = false, this.readonly = false,
this.enabled = true, this.enabled = true,
this.maxLength, this.maxLength,
this.minLines, this.minLines,
this.maxLines = 1, this.maxLines = 1,
this.suffixIcon, this.textInputAction,
this.prefixIcon,
this.boxConstraints,
this.variant = RTextFieldVariant.normal,
this.filled = false,
this.filledColor,
this.showCounter = false,
this.isDense = false,
this.keyboardType, this.keyboardType,
this.focusNode,
// ⚙️ Input styling
this.textAlign,
this.textCapitalization = TextCapitalization.none,
this.cursorColor,
this.autocorrect,
this.enableSuggestions,
this.style, this.style,
this.hintStyle, this.hintStyle,
this.labelStyle, this.labelStyle,
this.errorStyle, this.errorStyle,
this.padding,
this.validator, // 🎨 Decorations
this.onChanged, this.suffixIcon,
this.onSubmitted, this.prefixIcon,
this.borderColor,
this.inputFormatters,
this.onTap,
this.suffix, this.suffix,
this.boxConstraints,
// 📐 Layout & appearance
this.borderColor,
this.filled = false,
this.filledColor,
this.padding,
this.variant = RTextFieldVariant.normal,
// 📋 Form validation
this.validator,
this.autoValidateMode,
this.inputFormatters,
this.showCounter = false,
this.isDense = false,
}); });
@override @override
@@ -92,6 +123,27 @@ class RTextField extends StatefulWidget {
class _RTextFieldState extends State<RTextField> { class _RTextFieldState extends State<RTextField> {
late bool obscure; late bool obscure;
late TextDirection textDirection;
Timer? _debounceTimer;
TextDirection _detectDirection(String text) {
final isPersian = RegExp(r'[\u0600-\u06FF]').hasMatch(text);
return isPersian ? TextDirection.rtl : TextDirection.ltr;
}
void _debouncedUpdateTextDirection() {
if (_debounceTimer?.isActive ?? false) _debounceTimer!.cancel();
_debounceTimer = Timer(const Duration(milliseconds: 300), () {
final newDirection = _detectDirection(widget.controller.text);
if (newDirection != textDirection) {
setState(() {
textDirection = newDirection;
});
}
});
}
@override @override
void initState() { void initState() {
@@ -100,20 +152,24 @@ class _RTextFieldState extends State<RTextField> {
widget.controller.text = widget.initText!; widget.controller.text = widget.initText!;
} }
obscure = widget.obscure; obscure = widget.obscure;
textDirection = _detectDirection(
widget.controller.text.isNotEmpty ? widget.controller.text : widget.initText ?? 'سلام',
);
widget.controller.addListener(_debouncedUpdateTextDirection);
} }
@override @override
void didUpdateWidget(covariant RTextField oldWidget) { void didUpdateWidget(covariant RTextField oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (widget.initText != null && widget.initText != oldWidget.initText) { if (widget.initText != null && widget.controller.text != widget.initText) {
widget.controller.text = widget.initText!; widget.controller.text = widget.initText!;
} }
} }
Widget _buildSuffixIcon() { Widget? _buildSuffixIcon() {
if (widget.suffixIcon != null) return widget.suffixIcon!; if (widget._isPassword || widget._passwordNoBorder) {
if (!widget._isPassword) return const SizedBox.shrink();
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: GestureDetector( child: GestureDetector(
@@ -129,13 +185,19 @@ class _RTextFieldState extends State<RTextField> {
), ),
); );
} }
return widget.suffixIcon;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return SizedBox(
height: widget.height,
child: Padding(
padding: widget.padding ?? EdgeInsets.zero, padding: widget.padding ?? EdgeInsets.zero,
child: TextFormField( child: TextFormField(
controller: widget.controller, controller: widget.controller,
focusNode: widget.focusNode,
textAlign: widget.textAlign ?? TextAlign.start,
readOnly: widget.readonly, readOnly: widget.readonly,
minLines: widget.minLines, minLines: widget.minLines,
maxLines: widget.maxLines, maxLines: widget.maxLines,
@@ -148,9 +210,15 @@ class _RTextFieldState extends State<RTextField> {
onTapOutside: (_) => FocusScope.of(context).unfocus(), onTapOutside: (_) => FocusScope.of(context).unfocus(),
onFieldSubmitted: widget.onSubmitted, onFieldSubmitted: widget.onSubmitted,
maxLength: widget.maxLength, maxLength: widget.maxLength,
textDirection: TextDirection.rtl, textDirection: textDirection,
style: widget.style, style: widget.style,
keyboardType: widget.keyboardType, keyboardType: widget.keyboardType,
autovalidateMode: widget.autoValidateMode ?? AutovalidateMode.disabled,
cursorColor: widget.cursorColor,
textCapitalization: widget.textCapitalization,
autocorrect: widget.autocorrect ?? true,
enableSuggestions: widget.enableSuggestions ?? true,
textInputAction: widget.textInputAction,
decoration: InputDecoration( decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(horizontal: 16), contentPadding: const EdgeInsets.symmetric(horizontal: 16),
errorStyle: widget.errorStyle, errorStyle: widget.errorStyle,
@@ -176,6 +244,14 @@ class _RTextFieldState extends State<RTextField> {
border: widget._inputBorder, border: widget._inputBorder,
), ),
), ),
),
); );
} }
@override
void dispose() {
_debounceTimer?.cancel();
widget.controller.removeListener(_debouncedUpdateTextDirection);
super.dispose();
}
} }

View File

@@ -1,7 +1,7 @@
name: rasadyar_app name: rasadyar_app
description: "A new Flutter project." description: "A new Flutter project."
publish_to: 'none' publish_to: 'none'
version: 1.2.0+2 version: 1.3.0+2
environment: environment:
sdk: ^3.8.1 sdk: ^3.8.1