From ff80897a3c34656515ccf4cb4676a146c3527935 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 8 Nov 2023 16:46:01 +0300 Subject: [PATCH] dashboard apis added. --- lib/controllers/api_routes/urls.dart | 2 + .../providers/api/all_requests_provider.dart | 250 +++++++++++++++--- lib/extensions/widget_extensions.dart | 15 ++ lib/models/all_requests_and_count_model.dart | 157 +++++++++++ .../progress_fragment.dart | 48 ++-- .../requests_fragment.dart | 112 ++++---- .../pages/land_page/dashboard_page.dart | 3 + .../equipment/equipment_status_buttons.dart | 1 + 8 files changed, 454 insertions(+), 134 deletions(-) create mode 100644 lib/models/all_requests_and_count_model.dart diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index ddc9dd25..09bdea74 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -32,6 +32,8 @@ class URLs { static get getAssets => "$_baseUrl/Asset/GetAssets"; // get static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 + + static get getAllRequestsAndCount => "$_baseUrl/CallRequest/GetAllRequestsAndCount"; // get // 08051 static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // get static get getServiceRequestById => "$_baseUrl/CallRequest/GetCallRequestById"; // get diff --git a/lib/controllers/providers/api/all_requests_provider.dart b/lib/controllers/providers/api/all_requests_provider.dart index 20bf362e..1a08fc91 100644 --- a/lib/controllers/providers/api/all_requests_provider.dart +++ b/lib/controllers/providers/api/all_requests_provider.dart @@ -1,47 +1,213 @@ +import 'dart:convert'; + import 'package:flutter/widgets.dart'; import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/all_requests_and_count_model.dart'; class AllRequestsProvider extends ChangeNotifier { - bool isLoading; - -// Future getAllRequests() async { -// if (isLoading == true) return -2; -// isLoading = true; -// if (serviceRequests?.isEmpty ?? false) notifyListeners(); -// Response response; -// try { -// Map body = {}; -// body.addAll(search.toMap()); -// body["pageNumber"] = (serviceRequests?.length ?? 0) ~/ pageItemNumber + 1; -// body["pageSize"] = pageItemNumber; -// -// response = await ApiManager.instance.post( -// URLs.getServiceRequests, -// body: body, -// ); -// -// stateCode = response.statusCode; -// if (response.statusCode >= 200 && response.statusCode < 300) { -// // client's request was successfully received -// List requestsListJson = json.decode(response.body)["data"]; -// List serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList(); -// serviceRequests ??= []; -// serviceRequests.addAll(serviceRequestsPage); -// notifyListeners(); -// if (serviceRequestsPage.length == pageItemNumber) { -// nextPage = true; -// } else { -// nextPage = false; -// } -// } -// isLoading = false; -// notifyListeners(); -// return response.statusCode; -// } catch (error) { -// isLoading = false; -// stateCode = -1; -// notifyListeners(); -// return -1; -// } -// } + bool isAllLoading = false; + bool isOpenLoading = false; + bool isInProgressLoading = false; + bool isCloseLoading = false; + bool isOverdueLoading = false; + bool isHighPriorityLoading = false; + + int stateCode; + + AllRequestsAndCount allRequestsAndCount; + AllRequestsAndCount openRequests; + AllRequestsAndCount inProgressRequests; + AllRequestsAndCount closeRequests; + AllRequestsAndCount overdueRequests; + AllRequestsAndCount highPriorityRequests; + + void getRequests() { + getHighPriorityRequests(); + getOverdueRequests(); + getOpenRequests(); + getInProgressRequests(); + getCloseRequests(); + } + + Future getAllRequests() async { + if (isAllLoading == true) return -2; + isAllLoading = true; + if (allRequestsAndCount == null) notifyListeners(); + Response response; + try { + Map body = { + "typeTransaction": [1, 2, 3, 4], + "statusTransaction": [1, 2, 3], + "priority": [0, 1], + "displayData": [1] + }; + response = await ApiManager.instance.post(URLs.getAllRequestsAndCount, body: body); + + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + allRequestsAndCount = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); + notifyListeners(); + } + isAllLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isAllLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } + + Future getHighPriorityRequests() async { + if (isHighPriorityLoading == true) return -2; + isHighPriorityLoading = true; + if (highPriorityRequests == null) notifyListeners(); + Response response; + try { + Map body = { + "typeTransaction": [1, 2, 3, 4], + "statusTransaction": [1, 2, 3], + "priority": [0], + "displayData": [] + }; + response = await ApiManager.instance.post(URLs.getAllRequestsAndCount, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + highPriorityRequests = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); + print("highPriorityRequests:${highPriorityRequests.total}"); + notifyListeners(); + } + isHighPriorityLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isHighPriorityLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } + + Future getOverdueRequests() async { + if (isOverdueLoading == true) return -2; + isOverdueLoading = true; + if (overdueRequests == null) notifyListeners(); + Response response; + try { + Map body = { + "typeTransaction": [1, 2, 3, 4], + "statusTransaction": [1, 2, 3], + "priority": [], + "displayData": [1] + }; + response = await ApiManager.instance.post(URLs.getAllRequestsAndCount, body: body); + + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + overdueRequests = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); + notifyListeners(); + } + isOverdueLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isOverdueLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } + + Future getOpenRequests() async { + if (isOpenLoading == true) return -2; + isOpenLoading = true; + if (openRequests == null) notifyListeners(); + Response response; + try { + Map body = { + "typeTransaction": [1, 2, 3, 4], + "statusTransaction": [1], + "priority": [], + "displayData": [] + }; + response = await ApiManager.instance.post(URLs.getAllRequestsAndCount, body: body); + + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + openRequests = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); + notifyListeners(); + } + isOpenLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isOpenLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } + + Future getInProgressRequests() async { + if (isInProgressLoading == true) return -2; + isInProgressLoading = true; + if (inProgressRequests == null) notifyListeners(); + Response response; + try { + Map body = { + "typeTransaction": [1, 2, 3, 4], + "statusTransaction": [2], + "priority": [], + "displayData": [] + }; + response = await ApiManager.instance.post(URLs.getAllRequestsAndCount, body: body); + + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + inProgressRequests = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); + notifyListeners(); + } + isInProgressLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isInProgressLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } + + Future getCloseRequests() async { + if (isCloseLoading == true) return -2; + isCloseLoading = true; + if (closeRequests == null) notifyListeners(); + Response response; + try { + Map body = { + "typeTransaction": [1, 2, 3, 4], + "statusTransaction": [3], + "priority": [], + "displayData": [] + }; + response = await ApiManager.instance.post(URLs.getAllRequestsAndCount, body: body); + + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + closeRequests = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); + notifyListeners(); + } + isCloseLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isCloseLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } } diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index a2f2a14b..444e7029 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; @@ -20,6 +21,20 @@ extension WidgetExtensions on Widget { Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this); + Widget toShimmer({bool isShow = true, double radius = 20}) => isShow + ? Shimmer.fromColors( + baseColor: const Color(0xffe8eff0), + highlightColor: Colors.white, + child: ClipRRect( + borderRadius: BorderRadius.circular(radius), + child: Container( + color: Colors.white, + child: this, + ), + ), + ) + : this; + Widget get toShadowContainer => Container( padding: const EdgeInsets.all(16), decoration: ShapeDecoration( diff --git a/lib/models/all_requests_and_count_model.dart b/lib/models/all_requests_and_count_model.dart new file mode 100644 index 00000000..115f0c72 --- /dev/null +++ b/lib/models/all_requests_and_count_model.dart @@ -0,0 +1,157 @@ +class AllRequestsAndCount { + CountServiceRequest countServiceRequest; + CountServiceRequest countGasRefill; + CountServiceRequest countAssetTransfer; + CountServiceRequest countPPM; + DetailsStatusTotal detailsStatusTotal; + CountServiceRequest total; + List requestsDetails; + + AllRequestsAndCount({this.countServiceRequest, this.countGasRefill, this.countAssetTransfer, this.countPPM, this.detailsStatusTotal, this.total, this.requestsDetails}); + + AllRequestsAndCount.fromJson(Map json) { + countServiceRequest = json['countServiceRequest'] != null ? new CountServiceRequest.fromJson(json['countServiceRequest']) : null; + countGasRefill = json['countGasRefill'] != null ? new CountServiceRequest.fromJson(json['countGasRefill']) : null; + countAssetTransfer = json['countAssetTransfer'] != null ? new CountServiceRequest.fromJson(json['countAssetTransfer']) : null; + countPPM = json['countPPM'] != null ? new CountServiceRequest.fromJson(json['countPPM']) : null; + detailsStatusTotal = json['detailsStatusTotal'] != null ? new DetailsStatusTotal.fromJson(json['detailsStatusTotal']) : null; + total = json['total'] != null ? new CountServiceRequest.fromJson(json['total']) : null; + if (json['requestsDetails'] != null) { + requestsDetails = []; + json['requestsDetails'].forEach((v) { + requestsDetails.add(new RequestsDetails.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.countServiceRequest != null) { + data['countServiceRequest'] = this.countServiceRequest.toJson(); + } + + if (this.countGasRefill != null) { + data['countGasRefill'] = this.countGasRefill.toJson(); + } + if (this.countAssetTransfer != null) { + data['countAssetTransfer'] = this.countAssetTransfer.toJson(); + } + if (this.countPPM != null) { + data['countPPM'] = this.countPPM.toJson(); + } + + if (this.detailsStatusTotal != null) { + data['detailsStatusTotal'] = this.detailsStatusTotal.toJson(); + } + if (this.total != null) { + data['total'] = this.total.toJson(); + } + if (this.requestsDetails != null) { + data['requestsDetails'] = this.requestsDetails.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class CountServiceRequest { + int count; + + CountServiceRequest({this.count}); + + CountServiceRequest.fromJson(Map json) { + count = json['count']; + } + + Map toJson() { + final Map data = new Map(); + data['count'] = this.count; + return data; + } +} + +class DetailsStatusTotal { + int open; + int inProgress; + int closed; + + DetailsStatusTotal({this.open, this.inProgress, this.closed}); + + DetailsStatusTotal.fromJson(Map json) { + open = json['open']; + inProgress = json['inProgress']; + closed = json['closed']; + } + + Map toJson() { + final Map data = new Map(); + data['open'] = this.open; + data['inProgress'] = this.inProgress; + data['closed'] = this.closed; + return data; + } +} + +class RequestsDetails { + String nameOfType; + String status; + String statusReceiver; + String assetName; + String assetNo; + String requestType; + String requestNo; + String gasType; + String site; + String assetTransferFrom; + String assetTransferTo; + String assetSN; + String code; + + RequestsDetails( + {this.nameOfType, + this.status, + this.statusReceiver, + this.assetName, + this.assetNo, + this.requestType, + this.requestNo, + this.gasType, + this.site, + this.assetTransferFrom, + this.assetTransferTo, + this.assetSN, + this.code}); + + RequestsDetails.fromJson(Map json) { + nameOfType = json['nameOfType']; + status = json['status']; + statusReceiver = json['statusReceiver']; + assetName = json['assetName']; + assetNo = json['assetNo']; + requestType = json['requestType']; + requestNo = json['requestNo']; + gasType = json['gasType']; + site = json['site']; + assetTransferFrom = json['assetTransferFrom']; + assetTransferTo = json['assetTransferTo']; + assetSN = json['assetSN']; + code = json['code']; + } + + Map toJson() { + final Map data = new Map(); + data['nameOfType'] = this.nameOfType; + data['status'] = this.status; + data['statusReceiver'] = this.statusReceiver; + data['assetName'] = this.assetName; + data['assetNo'] = this.assetNo; + data['requestType'] = this.requestType; + data['requestNo'] = this.requestNo; + data['gasType'] = this.gasType; + data['site'] = this.site; + data['assetTransferFrom'] = this.assetTransferFrom; + data['assetTransferTo'] = this.assetTransferTo; + data['assetSN'] = this.assetSN; + data['code'] = this.code; + return data; + } +} diff --git a/lib/new_views/pages/land_page/dashboard_fragments/progress_fragment.dart b/lib/new_views/pages/land_page/dashboard_fragments/progress_fragment.dart index 3b037be6..3414bb46 100644 --- a/lib/new_views/pages/land_page/dashboard_fragments/progress_fragment.dart +++ b/lib/new_views/pages/land_page/dashboard_fragments/progress_fragment.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:pie_chart/pie_chart.dart'; +import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; @@ -18,36 +19,23 @@ class ProgressFragment extends StatelessWidget { }; return Column( children: [ - Card( - child: Stack( - alignment: Alignment.center, - children: [ - PieChart( - dataMap: statuses, - animationDuration: const Duration(milliseconds: 800), - chartRadius: 190.toScreenWidth, - colorList: [AColors.statusGreen, AColors.statusBlue, AColors.statusYellowLight], - initialAngleInDegree: 270, - chartType: ChartType.ring, - ringStrokeWidth: 40.toScreenWidth, - legendOptions: const LegendOptions(showLegends: false), - chartValuesOptions: ChartValuesOptions( - chartValueBackgroundColor: Colors.transparent, - chartValueStyle: AppTextStyles.heading6.copyWith(color: AppColor.neutral20), - showChartValuesOutside: true, - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - "Total".heading5(context), - "20".heading6(context).custom(color: AppColor.neutral20), - ], - ) - ], - ).paddingAll(23), - ), + PieChart( + dataMap: statuses, + animationDuration: const Duration(milliseconds: 500), + chartRadius: 190.toScreenWidth, + colorList: [AColors.statusGreen, AColors.statusBlue, AColors.statusYellowLight], + initialAngleInDegree: 270, + chartType: ChartType.ring, + ringStrokeWidth: 40.toScreenWidth, + centerText: "Total\n20", + centerTextStyle: AppTextStyles.heading5.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + legendOptions: const LegendOptions(showLegends: false), + chartValuesOptions: ChartValuesOptions( + chartValueBackgroundColor: Colors.transparent, + chartValueStyle: AppTextStyles.heading6.copyWith(color: AppColor.neutral20), + showChartValuesOutside: false, + ), + ).paddingAll(8).toShadowContainer, ], ).paddingOnly(start: 16, end: 16); } diff --git a/lib/new_views/pages/land_page/dashboard_fragments/requests_fragment.dart b/lib/new_views/pages/land_page/dashboard_fragments/requests_fragment.dart index 91928b58..d886fb8b 100644 --- a/lib/new_views/pages/land_page/dashboard_fragments/requests_fragment.dart +++ b/lib/new_views/pages/land_page/dashboard_fragments/requests_fragment.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; @@ -15,71 +17,57 @@ class RequestsFragment extends StatelessWidget { return Scaffold( // todo check here, nurse can add request not engineer floatingActionButton: const AppFloatingActionButton(), - body: GridView( - padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 191 / 237, crossAxisSpacing: 16, mainAxisSpacing: 16), - children: [ - gridItem("12", "high_priority",context.translation.highPriorityRequests,context), - gridItem("12", "overdue", context.translation.overdueRequests,context), - gridItem("12", "new_request", context.translation.newRequests,context), - gridItem("12", "complete_request", context.translation.completedRequests ,context), - ], + body: Consumer( + builder: (context, snapshot, _) => GridView( + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 191 / 237, crossAxisSpacing: 16, mainAxisSpacing: 16), + children: [ + gridItem(snapshot.highPriorityRequests?.total?.count?.toString() ?? "-", "high_priority", context.translation.highPriorityRequests, context, snapshot.isHighPriorityLoading), + gridItem(snapshot.overdueRequests?.total?.count?.toString() ?? "-", "overdue", context.translation.overdueRequests, context, snapshot.isOverdueLoading), + gridItem(snapshot.openRequests?.total?.count?.toString() ?? "-", "new_request", context.translation.newRequests, context, snapshot.isOpenLoading), + gridItem(snapshot.closeRequests?.total?.count?.toString() ?? "-", "complete_request", context.translation.completedRequests, context, snapshot.isCloseLoading), + ], + ), ), ); } - Widget gridItem(String value, String icon, String title, BuildContext context) { - return Container( - padding: const EdgeInsets.all(16), - decoration: ShapeDecoration( - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), - shadows: const [ - BoxShadow( - color: Color(0x07000000), - blurRadius: 14, - offset: Offset(0, 0), - spreadRadius: 0, - ) - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - value, - style: AppTextStyles.heading1.copyWith(color: AppColor.neutral70, height: 1), - ).expanded, - SvgPicture.asset('assets/images/$icon.svg', height: 35, width: 35), - ], - ).expanded, - Text( - title, - style: AppTextStyles.heading5.copyWith(color: AppColor.neutral50), - ), - 8.height, - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - context.translation.viewDetails, - style: AppTextStyles.bodyText.copyWith(color: const Color(0xFF4A8DB7)), - ), - 4.width, - const Icon( - Icons.arrow_forward, - color: Color(0xFF4A8DB7), - size: 14, - ) - ], - ), - ], - ), - ); + Widget gridItem(String value, String icon, String title, BuildContext context, bool isLoading) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + value, + style: AppTextStyles.heading1.copyWith(color: AppColor.neutral70, height: 1), + ).toShimmer(isShow: isLoading).expanded, + 8.width, + SvgPicture.asset('assets/images/$icon.svg', height: 35, width: 35).toShimmer(isShow: isLoading), + ], + ).expanded, + Text( + title, + style: AppTextStyles.heading5.copyWith(color: AppColor.neutral50), + ).toShimmer(isShow: isLoading), + 8.height, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.translation.viewDetails, + style: AppTextStyles.bodyText.copyWith(color: const Color(0xFF4A8DB7)), + ), + 4.width, + const Icon( + Icons.arrow_forward, + color: Color(0xFF4A8DB7), + size: 14, + ) + ], + ).toShimmer(isShow: isLoading), + ], + ).toShadowContainer; } } diff --git a/lib/new_views/pages/land_page/dashboard_page.dart b/lib/new_views/pages/land_page/dashboard_page.dart index c952968a..4bf1a973 100644 --- a/lib/new_views/pages/land_page/dashboard_page.dart +++ b/lib/new_views/pages/land_page/dashboard_page.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; @@ -24,6 +26,7 @@ class _DashboardPageState extends State { @override void initState() { super.initState(); + Provider.of(context, listen: false).getRequests(); } @override diff --git a/lib/views/widgets/equipment/equipment_status_buttons.dart b/lib/views/widgets/equipment/equipment_status_buttons.dart index b1bf737c..f1f5d32e 100644 --- a/lib/views/widgets/equipment/equipment_status_buttons.dart +++ b/lib/views/widgets/equipment/equipment_status_buttons.dart @@ -12,6 +12,7 @@ import '../../../providers/service_request_providers/equipment_status_provider.d class EquipmentStatusButtons extends StatefulWidget { final Function(Lookup) onSelect; + const EquipmentStatusButtons({Key key, this.onSelect}) : super(key: key); @override