From 77d5f3be3e9fbfd93e2a5b84b41cab16116eee3c Mon Sep 17 00:00:00 2001 From: "mr.mojtaba" Date: Sun, 15 Jun 2025 17:16:04 +0330 Subject: [PATCH] feat : home page --- assets/icons/cube_bottom_rotation.svg | 10 + assets/icons/cube_top_rotation.svg | 10 + assets/vec/cube_bottom_rotation.svg.vec | Bin 0 -> 1001 bytes assets/vec/cube_top_rotation.svg.vec | Bin 0 -> 1001 bytes .../data/repositories/chicken_repository.dart | 2 +- .../repositories/chicken_repository_imp.dart | 2 + .../pages/entering_the_warehouse/logic.dart | 2 +- .../pages/entering_the_warehouse/view.dart | 4 +- .../lib/presentation/pages/home/logic.dart | 94 ++++- .../lib/presentation/pages/home/view.dart | 397 ++++++++++-------- .../lib/presentation/pages/root/logic.dart | 84 +--- .../lib/presentation/pages/root/view.dart | 4 +- .../pages/sales_in_province/logic.dart | 2 +- .../pages/sales_in_province/view.dart | 4 +- .../pages/sales_out_of_province/view.dart | 94 ++++- .../chicken/lib/presentation/utils/utils.dart | 22 + packages/core/lib/core.dart | 3 +- .../lib/presentation/common/assets.gen.dart | 16 + packages/core/lib/utils/map_utils.dart | 44 ++ packages/core/lib/utils/num_utils.dart | 8 + 20 files changed, 540 insertions(+), 262 deletions(-) create mode 100644 assets/icons/cube_bottom_rotation.svg create mode 100644 assets/icons/cube_top_rotation.svg create mode 100644 assets/vec/cube_bottom_rotation.svg.vec create mode 100644 assets/vec/cube_top_rotation.svg.vec create mode 100644 packages/chicken/lib/presentation/utils/utils.dart create mode 100644 packages/core/lib/utils/map_utils.dart create mode 100644 packages/core/lib/utils/num_utils.dart diff --git a/assets/icons/cube_bottom_rotation.svg b/assets/icons/cube_bottom_rotation.svg new file mode 100644 index 0000000..94089f8 --- /dev/null +++ b/assets/icons/cube_bottom_rotation.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/assets/icons/cube_top_rotation.svg b/assets/icons/cube_top_rotation.svg new file mode 100644 index 0000000..828ec46 --- /dev/null +++ b/assets/icons/cube_top_rotation.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/assets/vec/cube_bottom_rotation.svg.vec b/assets/vec/cube_bottom_rotation.svg.vec new file mode 100644 index 0000000000000000000000000000000000000000..17ce852ca46d1af7bafffd7d711400e6176b5488 GIT binary patch literal 1001 zcmXw&X>3eU6vyw(Fi}I%nuUs?ZMxA$Mr#=wJ%5v;KG>o@h}|?ImWYxulo49BlO{!I zNkfIy60MYGT53|7v1BZ%wX~Gh6kTHpGVZKp;%TSbxS3m0GQwnndw}F~|N7q>CI!Ykr2Jz_pVeEHdEGrrpGt38ntMlKX;> zNG`MF)A=n1d~7@^;~l38N#xsfHMH^hJBl>kql(toJhql!FCFTPLYi|@T~_9>aW<7vUdH!6UqwY0cUh@^N>7yHk?52l7?)k<%WEkFy_= zrC1Nc?^+7~V!#vET`E3lMEPS6k2T>`c(vrp`YOrq$K2#DGh)e}3d)*oM0(aX+Nue{ zYWHgD=+=tvP)(Iua-QK2&sj?TUUwx&nyV>kv7N3JxGDO~S}GV+LG{-+lRLYd+HSb$ z@Vs(TJi=7!9@qb#!d7vujtPNq_0Jy+kyCQt05L~KtqEdIbInkQ8jKBts3}9^#Sb81BF8-iD_wa9VkvBTd7S(m#gW4sX&-VW)gyWYlQO^818Rni_O*3X2ZvKG3{ z*C=WICz{yX2+yYXH2s#IJ2%kL?V*w-xtw{;wUtUudD1CIlVN57Hn0&u|lnSRY8ten(LD-xz4xul8jp=A8XX(H=fD;&CJ zN;glyrO&@;v^^R#F8`&X?g&^TG?@G-98q~%bY6`_h^8+*c~P*%>Tt0k4sTL}kT@p+ zk6vmqtI&ehq7g{&jY6DrES%p%aoTM`oVA@+6%CE;yHBbA+)hz*sEv@SCl zn!Syb?M^|wrUJ2z;IO$)IH$;Gk^IHAMIbI literal 0 HcmV?d00001 diff --git a/assets/vec/cube_top_rotation.svg.vec b/assets/vec/cube_top_rotation.svg.vec new file mode 100644 index 0000000000000000000000000000000000000000..aed0a349b47482dabc73530bf420ee7501f28419 GIT binary patch literal 1001 zcmXw&dq`A46vpqp>t=;LP_bgm*5|ffrJ_tiY5Pv%A5sV_h<`+hh1gSj2}Z`&W~E@E z5{3Cldup1d_@IXsrX>}oCM!{zqLkS7uof5H+V0G@!@cLn+?g|HzVFVYMw}N!y&$9z zdzU+vrV<3FQzHt3m!LFBl0^PUstro_b*~4!PXEH-vAOV)W|8%E37T7-n6ZW;W&97y zzei%Tj{`;94aiRZ4P#q0vIoDSFCzf!np$wTCkY9wO^DlY6@Ie`cpG~KM=Yr@ST3Pw z`ViuLOR)Q+2~B$|F%fD;{Olc67w1A8YCvVuDFm--QtBSXlMC$#iVwruWl!;{Qj4sf zcHCC`Vey`ai0W8~8mSGBO`cG9HsV-}2kiZI$f=qG&z%OO7lvc%&Ew5!X*c24qY*`6 z0n_Ue%cE*N`ydFJ!*-0B%}B5Er-rF&yz~s91D|W*s1BsA?TwserZ&!_H`;MMD1bT= zpY!?o3txcc2j*C@PqrZ{?>p`re!}PQ57-l}oSV`oICD>o^KsM55k6nLs|+l^Cglp) zdiKOiVCyrodW@_-8{bk_3pStakL9!d4%ologXJU=>VI;&b!bG%tyR&f{9YxxwQBpW zL2n&Fz3(98bAK@r^$A*|NcO~Wq@7oDP6p2BtdK)E&y?#Za%dFM!+Po%8$x)9Oi2|V zQ2$P*V*Pu}+Zax7n=G8x@&V3y`Tgj!%5?l@FV5!4G?`k0+?W+~-%x~^2#vCC0h*`% zIG4qGb9QHaQ#2P~ec=QibYDc_qH$P?iqT*mMa84b%J~^a@SRdrbq>R=LnEkMT3s@E zbZb4Q(-F^g1QW|Wvn`NVZmo4CF%R~4i^M#LXq@@)f$hHsHb^nd0~=amnFltMwCc!P zWrxwOr_p2wXp>B#{eQU!+GheW5AH3MICn>@IK>?v#5~xVrlyQcnQr9=(ZQe7&!$d6N!y*W!`zbWS|jF<-*Mm;eP+&b3yv(xHy`YU&rL2^O4&r0tfGeMDr literal 0 HcmV?d00001 diff --git a/packages/chicken/lib/data/repositories/chicken_repository.dart b/packages/chicken/lib/data/repositories/chicken_repository.dart index a39a053..a3b6eef 100644 --- a/packages/chicken/lib/data/repositories/chicken_repository.dart +++ b/packages/chicken/lib/data/repositories/chicken_repository.dart @@ -19,7 +19,7 @@ abstract class ChickenRepository { required String token, }); - Future getGeneralBarInformation({required String token}); + Future getGeneralBarInformation({required String token,Map? queryParameters}); Future getWaitingArrivals({ required String token, diff --git a/packages/chicken/lib/data/repositories/chicken_repository_imp.dart b/packages/chicken/lib/data/repositories/chicken_repository_imp.dart index 5c14e85..8cc819b 100644 --- a/packages/chicken/lib/data/repositories/chicken_repository_imp.dart +++ b/packages/chicken/lib/data/repositories/chicken_repository_imp.dart @@ -49,9 +49,11 @@ class ChickenRepositoryImpl implements ChickenRepository { @override Future getGeneralBarInformation({ required String token, + Map? queryParameters }) async { var res = await _httpClient.get( '/bars_for_kill_house_dashboard/?role=Steward', + queryParameters: queryParameters, headers: {'Authorization': 'Bearer $token'}, fromJson: BarInformation.fromJson, ); diff --git a/packages/chicken/lib/presentation/pages/entering_the_warehouse/logic.dart b/packages/chicken/lib/presentation/pages/entering_the_warehouse/logic.dart index 76e94f9..70de9f7 100644 --- a/packages/chicken/lib/presentation/pages/entering_the_warehouse/logic.dart +++ b/packages/chicken/lib/presentation/pages/entering_the_warehouse/logic.dart @@ -33,7 +33,7 @@ class EnteringTheWarehouseLogic extends GetxController { @override void onReady() { super.onReady(); - rootLogic.getInventory(); + //rootLogic.getInventory(); getBarGeneralInformation(); getWaitingArrivals(); getImportedEntried(); diff --git a/packages/chicken/lib/presentation/pages/entering_the_warehouse/view.dart b/packages/chicken/lib/presentation/pages/entering_the_warehouse/view.dart index cf09d6b..83ede6a 100644 --- a/packages/chicken/lib/presentation/pages/entering_the_warehouse/view.dart +++ b/packages/chicken/lib/presentation/pages/entering_the_warehouse/view.dart @@ -43,7 +43,7 @@ class EnteringTheWarehousePage extends GetView { ), ), SizedBox(height: 4), - ObxValue( + /* ObxValue( (data) => data.isEmpty ? Container( margin: const EdgeInsets.symmetric(vertical: 2), @@ -101,7 +101,7 @@ class EnteringTheWarehousePage extends GetView { }, ), controller.rootLogic.inventoryList, - ), + ),*/ ], ), ); diff --git a/packages/chicken/lib/presentation/pages/home/logic.dart b/packages/chicken/lib/presentation/pages/home/logic.dart index b8de756..4360c92 100644 --- a/packages/chicken/lib/presentation/pages/home/logic.dart +++ b/packages/chicken/lib/presentation/pages/home/logic.dart @@ -1,17 +1,103 @@ - - +import 'package:rasadyar_auth/data/utils/safe_call.dart'; +import 'package:rasadyar_chicken/chicken.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_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; class HomeLogic extends GetxController { + RootLogic root = Get.find(); + RxnInt totalWeightTodayBars = RxnInt(); + Rxn inventoryModel = Rxn(); + Rxn killHouseDistributionInfo = Rxn(); + + + @override + void onInit() { + super.onInit(); + getTodayBars(); + getInventory(); + getDistributionInformation(); + } + + Future getTodayBars() async { + await safeCall( + call: () async => await root.chickenRepository.getGeneralBarInformation( + token: root.tokenService.accessToken.value!, + queryParameters: buildQueryParams(fromDate: DateTime.now(), toDate: DateTime.now()), + ), + onSuccess: (result) { + if (result != null) { + totalWeightTodayBars.value = result.totalBarsWeight?.toInt(); + } + }, + onError: (error, stackTrace) { + switch (error.response?.statusCode) { + case 401: + errorHandler(error); + break; + case 403: + errorHandler(error); + break; + default: + errorHandler(error); + } + }, + ); + } + + Future getInventory() async { + await safeCall?>( + call: () async => await root.chickenRepository.getInventory(token: root.tokenService.accessToken.value!), + onSuccess: (result) { + if (result != null) { + inventoryModel.value = result.first; + } + }, + onError: (error, stackTrace) { + switch (error.response?.statusCode) { + case 401: + errorHandler(error); + break; + case 403: + errorHandler(error); + break; + default: + errorHandler(error); + } + }, + ); + } + + Future getDistributionInformation() async { + await safeCall( + call: () async => await root.chickenRepository.getIKillHouseDistributionInfo(token: root.tokenService.accessToken.value!), + onSuccess: (result) { + if (result != null) { + iLog(result); + killHouseDistributionInfo.value = result; + iLog(killHouseDistributionInfo.value); + } + }, + onError: (error, stackTrace) {}, + ); + } + + + void errorHandler(DioException error) { + handleGeneric(error, () { + root.tokenService.deleteTokens(); + }); + } + @override void onReady() { - super.onReady(); } @override void onClose() { - super.onClose(); } } diff --git a/packages/chicken/lib/presentation/pages/home/view.dart b/packages/chicken/lib/presentation/pages/home/view.dart index f455b43..fa00a71 100644 --- a/packages/chicken/lib/presentation/pages/home/view.dart +++ b/packages/chicken/lib/presentation/pages/home/view.dart @@ -2,7 +2,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart'; import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; @@ -70,111 +69,19 @@ class HomePage extends GetView { SizedBox(height: 8), _todayShipmentWidget(), - Padding( - padding: const EdgeInsets.fromLTRB(0, 10, 0, 13), - child: Row( - spacing: 8, - children: [ - Expanded( - child: _informationLabelCard( - title: 'مانده انبار', - description: '2،225،256', - iconPath: Assets.vec.cubeSearchSvg.path, - iconColor: const Color(0xFF426060), - bgDescriptionColor: const Color(0xFFC7DFE0), - bgLabelColor: const Color(0xFFA5D1D2), - ), - ), - Expanded( - child: _informationLabelCard( - title: 'توزیع شده', - description: '2،225،256', - iconPath: Assets.vec.cubeRotateSvg.path, - iconColor: Color(0xFF5C4D64), - bgLabelColor: Color(0xFFC8B8D1), - bgDescriptionColor: Color(0xFFDAD4DD), - ), - ), - ], - ), - ), + _inventoryWidget(), Row( children: [Text('اطلاعات بارها', textAlign: TextAlign.right, style: AppFonts.yekan16)], ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), - child: Row( - spacing: 8, - children: [ - Expanded( - child: _informationLabelCard( - title: 'داخل استان', - description: '2،225،256', - iconPath: Assets.vec.a3dCubeSquareSvg.path, - iconColor: const Color(0xFF6C5D60), - bgDescriptionColor: const Color(0xFFEDDCE0), - bgLabelColor: const Color(0xFFDDC0C7), - ), - ), - Expanded( - child: _informationLabelCard( - title: 'خارج استان', - description: '2،225،256', - iconPath: Assets.vec.cubeSearchSvg.path, - iconColor: Color(0xFF2D5FFF), - bgLabelColor: const Color(0xFFAFCBFF), - bgDescriptionColor: const Color(0xFFCEDFFF), - ), - ), - ], - ), - ), + _informationShipment(), Row( children: [Text('اطلاعات توزیع', textAlign: TextAlign.right, style: AppFonts.yekan16)], ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 8, - children: [ - Expanded( - child: _informationIconCard( - title: 'توزیع داخل استان', - description: '2،225،256', - iconPath: Assets.vec.truckSvg.path, - iconColor: const Color.fromRGBO(85, 97, 93, 1), - bgDescriptionColor: const Color(0xFFE6FAF5), - bgLabelColor: const Color(0xFFB0EFDF), - ), - ), - Expanded( - child: _informationIconCard( - title: 'توزیع خارج استان', - description: '2،225،256', - iconPath: Assets.vec.truckFastSvg.path, - iconColor: Color(0xFF647379), - bgDescriptionColor: const Color(0xFFEAEFFF), - bgLabelColor: const Color(0xFFD4DEFF), - ), - ), - Expanded( - child: _informationIconCard( - title: 'قطعه بندی', - description: '2،225،256', - iconPath: Assets.vec.convertCubeSvg.path, - iconColor: const Color(0xFF6F6164), - bgDescriptionColor: const Color(0xFFEDDCE0), - bgLabelColor: const Color(0xFFE0BCC5), - ), - ), - ], - ), - ), + distributionInformationWidget(), ], ), ), @@ -226,64 +133,190 @@ class HomePage extends GetView { ), ); } - Container _todayShipmentWidget() { - return Container( - height: 70, - width: Get.width / 2, - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), - clipBehavior: Clip.hardEdge, - child: Row( - children: [ - Expanded( - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [const Color(0xFFEAEFFF), Colors.white], - ), - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 4, - children: [ - Assets.icons.cubeScan.svg(width: 30, height: 30), - Text( - 'بارهای امروز', - textAlign: TextAlign.right, - style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), - ), - ], + + Widget distributionInformationWidget() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Expanded( + child: _informationIconCard( + title: 'توزیع داخل استان', + isLoading: data.value == null, + description: data.value?.freeSalesWeight.toFormatted ?? '0', + iconPath: Assets.vec.truckSvg.path, + iconColor: const Color.fromRGBO(85, 97, 93, 1), + bgDescriptionColor: const Color(0xFFE6FAF5), + bgLabelColor: const Color(0xFFB0EFDF), ), ), - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 4, - children: [ - Text( - '2،225،256', - textAlign: TextAlign.right, - style: AppFonts.yekan16.copyWith(color: AppColor.textColor), - ), - Text( - 'کیلوگرم', - textAlign: TextAlign.center, - style: AppFonts.yekan12.copyWith(color: AppColor.textColor), - ), - ], + Expanded( + child: _informationIconCard( + title: 'توزیع خارج استان', + isLoading: data.value == null, + description: data.value?.stewardAllocationsWeight.toFormatted ?? '0', + iconPath: Assets.vec.truckFastSvg.path, + iconColor: Color(0xFF647379), + bgDescriptionColor: const Color(0xFFEAEFFF), + bgLabelColor: const Color(0xFFD4DEFF), + ), ), - ), - ], - ), + Expanded( + child: _informationIconCard( + title: 'قطعه بندی', + description: '2،225،256', + iconPath: Assets.vec.convertCubeSvg.path, + iconColor: const Color(0xFF6F6164), + bgDescriptionColor: const Color(0xFFEDDCE0), + bgLabelColor: const Color(0xFFE0BCC5), + ), + ), + ], + ); + }, controller.killHouseDistributionInfo), ); } + Widget _informationShipment() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + return Row( + spacing: 8, + children: [ + Expanded( + child: _informationLabelCard( + title: 'داخل استان', + isLoading: data.value == null, + description: data.value != null + ? ((data.value?.provinceGovernmentalCarcassesWeight ?? 0) + + (data.value?.provinceFreeCarcassesWeight ?? 0)) + .toFormatted + : '0', + iconPath: Assets.vec.a3dCubeSquareSvg.path, + iconColor: const Color(0xFF6C5D60), + bgDescriptionColor: const Color(0xFFEDDCE0), + bgLabelColor: const Color(0xFFDDC0C7), + ), + ), + Expanded( + child: _informationLabelCard( + title: 'خارج استان', + isLoading: data.value == null, + description: data.value?.freeBuyingCarcassesWeight.toFormatted ?? '0', + iconPath: Assets.vec.cubeSearchSvg.path, + iconColor: Color(0xFF2D5FFF), + bgLabelColor: const Color(0xFFAFCBFF), + bgDescriptionColor: const Color(0xFFCEDFFF), + ), + ), + ], + ); + }, controller.inventoryModel), + ); + } + + Widget _inventoryWidget() { + return ObxValue((data) { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 13), + child: Row( + spacing: 8, + children: [ + Expanded( + child: _informationLabelCard( + title: 'مانده انبار', + isLoading: data.value == null, + description: data.value?.totalRemainWeight.toFormatted ?? '0', + iconPath: Assets.vec.cubeSearchSvg.path, + iconColor: const Color(0xFF426060), + bgDescriptionColor: const Color(0xFFC7DFE0), + bgLabelColor: const Color(0xFFA5D1D2), + ), + ), + Expanded( + child: _informationLabelCard( + title: 'توزیع شده', + isLoading: data.value == null, + description: data.value?.realAllocatedWeight.toFormatted ?? '0', + iconPath: Assets.vec.cubeRotateSvg.path, + iconColor: Color(0xFF5C4D64), + bgLabelColor: Color(0xFFC8B8D1), + bgDescriptionColor: Color(0xFFDAD4DD), + ), + ), + ], + ), + ); + }, controller.inventoryModel); + } + + Widget _todayShipmentWidget() { + return ObxValue((data) { + return Container( + height: 70, + width: Get.width / 2, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + child: Row( + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [const Color(0xFFEAEFFF), Colors.white], + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Assets.icons.cubeScan.svg(width: 30, height: 30), + Text( + 'بارهای امروز', + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + ), + Expanded( + child: data.value == null + ? CupertinoActivityIndicator() + : Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + data.value.toFormatted, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith(color: AppColor.textColor), + ), + Text( + 'کیلوگرم', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ], + ), + ); + }, controller.totalWeightTodayBars); + } + Container _informationLabelCard({ required String title, required String description, String unit = 'کیلوگرم', + bool isLoading = false, required String iconPath, required Color iconColor, required Color bgDescriptionColor, @@ -326,22 +359,24 @@ class HomePage extends GetView { color: bgDescriptionColor, borderRadius: BorderRadius.only(topLeft: Radius.circular(8), bottomLeft: Radius.circular(8)), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 4, - children: [ - Text( - description, - textAlign: TextAlign.right, - style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive), - ), - Text( - unit, - textAlign: TextAlign.center, - style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive), - ), - ], - ), + child: isLoading + ? Center(child: CupertinoActivityIndicator()) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + description, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive), + ), + Text( + unit, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive), + ), + ], + ), ), ), ], @@ -353,6 +388,7 @@ class HomePage extends GetView { required String title, required String description, String unit = 'کیلوگرم', + bool isLoading = false, required String iconPath, required Color iconColor, required Color bgDescriptionColor, @@ -385,11 +421,14 @@ class HomePage extends GetView { textAlign: TextAlign.right, style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive), ), - Text( - description, - textAlign: TextAlign.right, - style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive), - ), + + isLoading + ? Center(child: CupertinoActivityIndicator()) + : Text( + description, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive), + ), Text( unit, textAlign: TextAlign.center, @@ -483,7 +522,7 @@ class HomePage extends GetView { ); } -/* Column oldPage() { + /* Column oldPage() { return Column( children: [ inventoryWidget(), @@ -652,19 +691,19 @@ class HomePage extends GetView { ), child: model != null ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 10, - children: [ - Text( - 'اطلاعات ارسالی', - textAlign: TextAlign.right, - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), - ), - const SizedBox(height: 12), - buildRow('فروش و توزیع داخل استان (کیلوگرم)', model.stewardAllocationsWeight!.toInt().toString()), - buildRow('فروش و توزیع خارج استان (کیلوگرم)', model.freeSalesWeight!.toInt().toString()), - ], - ) + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 10, + children: [ + Text( + 'اطلاعات ارسالی', + textAlign: TextAlign.right, + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + const SizedBox(height: 12), + buildRow('فروش و توزیع داخل استان (کیلوگرم)', model.stewardAllocationsWeight!.toInt().toString()), + buildRow('فروش و توزیع خارج استان (کیلوگرم)', model.freeSalesWeight!.toInt().toString()), + ], + ) : const Center(child: CircularProgressIndicator()), ); } diff --git a/packages/chicken/lib/presentation/pages/root/logic.dart b/packages/chicken/lib/presentation/pages/root/logic.dart index 3d9a7b0..6cc4aeb 100644 --- a/packages/chicken/lib/presentation/pages/root/logic.dart +++ b/packages/chicken/lib/presentation/pages/root/logic.dart @@ -1,15 +1,14 @@ -import 'package:flutter/material.dart' show Text, EdgeInsets, Colors; +import 'package:flutter/material.dart' show Colors; import 'package:flutter/widgets.dart'; -import 'package:rasadyar_auth/data/models/local/user_local/user_local_model.dart'; import 'package:rasadyar_auth/data/services/token_storage_service.dart'; import 'package:rasadyar_auth/data/utils/safe_call.dart'; -import 'package:rasadyar_auth/presentation/routes/pages.dart'; import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart'; import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; import 'package:rasadyar_chicken/data/repositories/chicken_repository.dart'; import 'package:rasadyar_chicken/data/repositories/chicken_repository_imp.dart'; import 'package:rasadyar_chicken/presentation/pages/home/view.dart'; import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/view.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; enum ErrorLocationType { serviceDisabled, permissionDenied, none } @@ -24,15 +23,14 @@ class RootLogic extends GetxController { Container(color: Colors.amber), ]; - RxList errorLocationType = RxList(); - RxMap inventoryExpandedList = RxMap(); + late DioRemote dioRemote; var tokenService = Get.find(); late ChickenRepository chickenRepository; - late DioRemote dioRemote; - RxInt count = 5.obs; - RxList inventoryList = RxList(); - Rxn killHouseDistributionInfo = Rxn(); + RxList errorLocationType = RxList(); + RxMap inventoryExpandedList = RxMap(); + + @override void onInit() { @@ -40,8 +38,9 @@ class RootLogic extends GetxController { dioRemote = DioRemote(baseUrl: tokenService.baseurl.value); dioRemote.init(); chickenRepository = ChickenRepositoryImpl(dioRemote); - getInventory(); - getKillHouseDistributionInfo(); + + /*getInventory(); + getKillHouseDistributionInfo();*/ } void toggleExpanded(int index) { @@ -52,63 +51,16 @@ class RootLogic extends GetxController { } } - Future getInventory() async { - await safeCall?>( - call: () async => await chickenRepository.getInventory(token: tokenService.accessToken.value!), - onSuccess: (result) { - if (result != null) { - iLog(result); - inventoryList.clear(); - inventoryList.addAll(result); - iLog(inventoryList); - } - }, - onError: (error, stackTrace) { - switch (error.response?.statusCode) { - case 401: - _handleGeneric(error); - break; - case 403: - _handleGeneric(error); - break; - default: - _handleGeneric(error); - } - }, - ); + + + + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteTokens(); + }); } - Future getKillHouseDistributionInfo() async { - await safeCall( - call: () async => await chickenRepository.getIKillHouseDistributionInfo(token: tokenService.accessToken.value!), - onSuccess: (result) { - if (result != null) { - iLog(result); - killHouseDistributionInfo.value = result; - iLog(killHouseDistributionInfo.value); - } - }, - onError: (error, stackTrace) {}, - ); - } - - void _handleGeneric(DioException error) { - Get.showSnackbar(_errorSnackBar('اعتبار توکن شما منقضی شده است لطفا دوباره وارد شوید')); - tokenService.deleteTokens(); - Get.offAllNamed(AuthPaths.auth, arguments: Module.chicken); - } - - GetSnackBar _errorSnackBar(String message) { - return GetSnackBar( - titleText: Text('خطا', style: AppFonts.yekan14.copyWith(color: Colors.white)), - messageText: Text(message, style: AppFonts.yekan12.copyWith(color: Colors.white)), - backgroundColor: AppColor.error, - margin: EdgeInsets.symmetric(horizontal: 12, vertical: 8), - borderRadius: 12, - duration: Duration(milliseconds: 3500), - snackPosition: SnackPosition.TOP, - ); - } void changePage(int index) { currentPage.value = index; diff --git a/packages/chicken/lib/presentation/pages/root/view.dart b/packages/chicken/lib/presentation/pages/root/view.dart index e1e1c93..3c7515d 100644 --- a/packages/chicken/lib/presentation/pages/root/view.dart +++ b/packages/chicken/lib/presentation/pages/root/view.dart @@ -326,7 +326,7 @@ class RootPage extends GetView { ); } - Column oldPage() { + /*Column oldPage() { return Column( children: [ inventoryWidget(), @@ -455,7 +455,7 @@ class RootPage extends GetView { ), ], ); - } + }*/ Widget buildRow(String title, String value) { return Padding( diff --git a/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart b/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart index d9d71cd..90f6164 100644 --- a/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart +++ b/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart @@ -37,7 +37,7 @@ class SalesInProvinceLogic extends GetxController { @override void onInit() { super.onInit(); - rootLogic.getInventory(); + //rootLogic.getInventory(); getAllocatedMade(); getRolesProducts(); getGuilds(); diff --git a/packages/chicken/lib/presentation/pages/sales_in_province/view.dart b/packages/chicken/lib/presentation/pages/sales_in_province/view.dart index 67485c6..d07bbfa 100644 --- a/packages/chicken/lib/presentation/pages/sales_in_province/view.dart +++ b/packages/chicken/lib/presentation/pages/sales_in_province/view.dart @@ -48,7 +48,7 @@ class SalesInProvincePage extends GetView { ), ), SizedBox(height: 4), - ObxValue( + /* ObxValue( (data) => data.isEmpty ? Container( margin: const EdgeInsets.symmetric(vertical: 2), @@ -106,7 +106,7 @@ class SalesInProvincePage extends GetView { }, ), controller.rootLogic.inventoryList, - ), + ),*/ ], ), ); diff --git a/packages/chicken/lib/presentation/pages/sales_out_of_province/view.dart b/packages/chicken/lib/presentation/pages/sales_out_of_province/view.dart index fe0710f..eecc579 100644 --- a/packages/chicken/lib/presentation/pages/sales_out_of_province/view.dart +++ b/packages/chicken/lib/presentation/pages/sales_out_of_province/view.dart @@ -47,7 +47,14 @@ class SalesOutOfProvincePage extends GetView { ), body: Column( children: [ - SizedBox(height: 12), + _typeOuterInfoCard( + title: 'خرید خارج استان', + iconPath: Assets.vec.searchSvg.path, + backgroundColor: AppColor.blueLight, + foregroundColor: AppColor.blueNormal, + ), + + /* SizedBox(height: 12), ObxValue((model) => summaryOfInformation(model.value), controller.stewardFreeDashboard), Expanded( child: ListView.separated( @@ -107,11 +114,92 @@ class SalesOutOfProvincePage extends GetView { separatorBuilder: (BuildContext context, int index) => SizedBox(height: 6), itemCount: 3, ), + ),*/ + ], + ), + floatingActionButton: RFab.add( + onPressed: () { + Get.bottomSheet(addSaleOutOfTheProvinceBottomSheet()); + }, + ), + floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, + ); + } + + Widget addSaleOutOfTheProvinceBottomSheet() { + return BaseBottomSheet( + child: Column( + children: [ + const SizedBox(height: 20), + Align( + alignment: Alignment.centerRight, + child: Text('ثبت فروش خارج استان', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)), + ), + SizedBox(height: 4), + RElevated(text: 'ثبت توزیع/ فروش', onPressed: () {}), + ], + ), + ); + } + + Container _typeOuterInfoCard({ + required String title, + required String iconPath, + required Color backgroundColor, + required Color foregroundColor, + }) { + return Container( + height: 110, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + child: Stack( + alignment: Alignment.topCenter, + children: [ + Positioned( + bottom: 0, + right: 0, + left: 0, + child: Container( + height: 120, + decoration: BoxDecoration( + color: backgroundColor, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: foregroundColor), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive), + ), + ], + ), + ), + ), + Positioned( + top: 0, + child: Container( + width: 50, + height: 50, + decoration: ShapeDecoration( + color: backgroundColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + side: BorderSide(width: 1, color: foregroundColor), + ), + ), + child: Center( + child: SvgGenImage.vec( + iconPath, + ).svg(width: 36, height: 36, colorFilter: ColorFilter.mode(foregroundColor, BlendMode.srcIn)), + ), + ), ), ], ), - floatingActionButton: RFab.add(onPressed: () {}), - floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, ); } diff --git a/packages/chicken/lib/presentation/utils/utils.dart b/packages/chicken/lib/presentation/utils/utils.dart new file mode 100644 index 0000000..13b968a --- /dev/null +++ b/packages/chicken/lib/presentation/utils/utils.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_auth/data/models/local/user_local/user_local_model.dart'; +import 'package:rasadyar_auth/presentation/routes/pages.dart'; +import 'package:rasadyar_core/core.dart'; + +void handleGeneric(DioException error,[void Function()? onError]) { + Get.showSnackbar(_errorSnackBar('اعتبار توکن شما منقضی شده است لطفا دوباره وارد شوید')); + + Get.offAllNamed(AuthPaths.auth, arguments: Module.chicken); +} + +GetSnackBar _errorSnackBar(String message) { + return GetSnackBar( + titleText: Text('خطا', style: AppFonts.yekan14.copyWith(color: Colors.white)), + messageText: Text(message, style: AppFonts.yekan12.copyWith(color: Colors.white)), + backgroundColor: AppColor.error, + margin: EdgeInsets.symmetric(horizontal: 12, vertical: 8), + borderRadius: 12, + duration: Duration(milliseconds: 3500), + snackPosition: SnackPosition.TOP, + ); +} \ No newline at end of file diff --git a/packages/core/lib/core.dart b/packages/core/lib/core.dart index d1c0ae9..1ad8104 100644 --- a/packages/core/lib/core.dart +++ b/packages/core/lib/core.dart @@ -1,6 +1,5 @@ library; - //other packages export 'package:flutter_localizations/flutter_localizations.dart'; export 'package:flutter_map/flutter_map.dart'; @@ -44,3 +43,5 @@ export 'injection/di.dart'; export 'utils/logger_utils.dart'; export 'utils/safe_call_utils.dart'; export 'utils/date_time_utils.dart'; +export 'utils/num_utils.dart'; +export 'utils/map_utils.dart'; diff --git a/packages/core/lib/presentation/common/assets.gen.dart b/packages/core/lib/presentation/common/assets.gen.dart index 76f24c7..c8fa214 100644 --- a/packages/core/lib/presentation/common/assets.gen.dart +++ b/packages/core/lib/presentation/common/assets.gen.dart @@ -48,6 +48,9 @@ class $AssetsIconsGen { /// File path: assets/icons/cube.svg SvgGenImage get cube => const SvgGenImage('assets/icons/cube.svg'); + /// File path: assets/icons/cube_bottom_rotation.svg + SvgGenImage get cubeBottomRotation => const SvgGenImage('assets/icons/cube_bottom_rotation.svg'); + /// File path: assets/icons/cube_rotate.svg SvgGenImage get cubeRotate => const SvgGenImage('assets/icons/cube_rotate.svg'); @@ -57,6 +60,9 @@ class $AssetsIconsGen { /// File path: assets/icons/cube_search.svg SvgGenImage get cubeSearch => const SvgGenImage('assets/icons/cube_search.svg'); + /// File path: assets/icons/cube_top_rotation.svg + SvgGenImage get cubeTopRotation => const SvgGenImage('assets/icons/cube_top_rotation.svg'); + /// File path: assets/icons/diagram.svg SvgGenImage get diagram => const SvgGenImage('assets/icons/diagram.svg'); @@ -187,9 +193,11 @@ class $AssetsIconsGen { chicken, convertCube, cube, + cubeBottomRotation, cubeRotate, cubeScan, cubeSearch, + cubeTopRotation, diagram, download, edit, @@ -297,6 +305,9 @@ class $AssetsVecGen { /// File path: assets/vec/cube.svg.vec SvgGenImage get cubeSvg => const SvgGenImage.vec('assets/vec/cube.svg.vec'); + /// File path: assets/vec/cube_bottom_rotation.svg.vec + SvgGenImage get cubeBottomRotationSvg => const SvgGenImage.vec('assets/vec/cube_bottom_rotation.svg.vec'); + /// File path: assets/vec/cube_rotate.svg.vec SvgGenImage get cubeRotateSvg => const SvgGenImage.vec('assets/vec/cube_rotate.svg.vec'); @@ -306,6 +317,9 @@ class $AssetsVecGen { /// File path: assets/vec/cube_search.svg.vec SvgGenImage get cubeSearchSvg => const SvgGenImage.vec('assets/vec/cube_search.svg.vec'); + /// File path: assets/vec/cube_top_rotation.svg.vec + SvgGenImage get cubeTopRotationSvg => const SvgGenImage.vec('assets/vec/cube_top_rotation.svg.vec'); + /// File path: assets/vec/diagram.svg.vec SvgGenImage get diagramSvg => const SvgGenImage.vec('assets/vec/diagram.svg.vec'); @@ -436,9 +450,11 @@ class $AssetsVecGen { chickenSvg, convertCubeSvg, cubeSvg, + cubeBottomRotationSvg, cubeRotateSvg, cubeScanSvg, cubeSearchSvg, + cubeTopRotationSvg, diagramSvg, downloadSvg, editSvg, diff --git a/packages/core/lib/utils/map_utils.dart b/packages/core/lib/utils/map_utils.dart new file mode 100644 index 0000000..99866c8 --- /dev/null +++ b/packages/core/lib/utils/map_utils.dart @@ -0,0 +1,44 @@ +import 'package:rasadyar_core/presentation/utils/data_time_utils.dart'; + +Map buildQueryParams({ + Map? queryParams, + String? search, + String? value, + int? page, + int? pageSize, + DateTime? fromDate, + DateTime? toDate, + +}) { + final params = {}; + + if (queryParams != null) { + params.addAll(queryParams); + } + + if (fromDate != null) { + params['date1'] = fromDate.formattedDashedGregorian; + } + + if (toDate != null) { + params['date2'] = toDate.formattedDashedGregorian; + } + + if (search != null && search.isNotEmpty) { + params['search'] = search; + } + + if (value != null && value.isNotEmpty) { + params['value'] = value; + } + + if (page != null) { + params['page'] = page; + } + + if (pageSize != null) { + params['page_size'] = pageSize; + } + + return params; +} diff --git a/packages/core/lib/utils/num_utils.dart b/packages/core/lib/utils/num_utils.dart new file mode 100644 index 0000000..4df60b5 --- /dev/null +++ b/packages/core/lib/utils/num_utils.dart @@ -0,0 +1,8 @@ +import 'package:intl/intl.dart'; + +extension XNumExtension on num? { + String get toFormatted { + final formatter = NumberFormat('#,###', 'fa_IR'); + return this == null ? '':formatter.format(this); + } +}