diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index f1f9408..91c0db0 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -296,7 +296,39 @@ class WorkListApiClient { "RequestType": requestType, "TaskID": taskId, "ItemID": itemId, - "EmployeeNumber": "15153", + "EmployeeNumber": employeeNumber, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + ItgFormsModel responseData = ItgFormsModel.fromJson(json); + return responseData.itgRequest; + }, url, postParams); + } + + Future rejectITGRequest(String requestType, int taskId, int itemId, String employeeNumber, String comments) async { + String url = "${ApiConsts.cocRest}ITGRejectRequest"; + Map postParams = { + "RequestType": requestType, + "TaskID": taskId, + "ItemID": itemId, + "EmployeeNumber": employeeNumber, + "Comments": comments, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + ItgFormsModel responseData = ItgFormsModel.fromJson(json); + return responseData.itgRequest; + }, url, postParams); + } + + Future approveITGRequest(String requestType, int taskId, int itemId, String employeeNumber, String comments) async { + String url = "${ApiConsts.cocRest}ITGApproveRequest"; + Map postParams = { + "RequestType": requestType, + "TaskID": taskId, + "ItemID": itemId, + "EmployeeNumber": employeeNumber, + "Comments": comments, }; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index 78ceeaa..b5d5dad 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -72,6 +72,33 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { return true; } + void initProvider() { + isAttendanceTrackingLoading = true; + endTime = 0; + isTimeRemainingInSeconds = 0; + progress = 0.0; + attendanceTracking = null; + + isWorkListLoading = true; + workListCounter = 0; + + isMissingSwipeLoading = true; + missingSwipeCounter = 0; + + isLeaveTicketBalanceLoading = true; + accrualList = null; + leaveBalanceAccrual = null; + + ticketBalance = 0; + isServicesMenusLoading = true; + homeMenus = null; + getMenuEntriesList = null; + isOffersLoading = true; + getOffersList = []; + + notifyListeners(); + } + int calculateSeconds(String time) { int hour = int.parse(time.split(":")[0]); int mints = int.parse(time.split(":")[1]); @@ -81,12 +108,6 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { void update(context) { fetchAttendanceTracking(context); - // isAttendanceTrackingLoading = !isAttendanceTrackingLoading; - // isWorkListLoading = !isWorkListLoading; - // attendanceTracking?.pSwipeIn = "a"; - // isTimeRemainingInSeconds = calculateSeconds("00:10:30"); - // endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds; - // notifyListeners(); } ItgFormsModel? itgFormsModel; diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 050b78d..95b39e8 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -23,6 +23,7 @@ import 'package:mohem_flutter_app/widgets/mark_attendance_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart'; import 'package:provider/provider.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; class DashboardScreen extends StatefulWidget { DashboardScreen({Key? key}) : super(key: key); @@ -37,12 +38,24 @@ class _DashboardScreenState extends State { late DashboardProviderModel data; final GlobalKey _scaffoldState = GlobalKey(); + final RefreshController _refreshController = RefreshController(initialRefresh: false); + int currentIndex = 0; @override void initState() { super.initState(); data = Provider.of(context, listen: false); + _onRefresh(); + } + + @override + void dispose() { + super.dispose(); + } + + void _onRefresh() async { + data.initProvider(); data.fetchListMenu(); data.fetchAttendanceTracking(context); data.fetchWorkListCounter(context); @@ -50,11 +63,7 @@ class _DashboardScreenState extends State { data.fetchLeaveTicketBalance(context, DateTime.now()); data.fetchMenuEntries(); data.getCategoryOffersListAPI(context); - } - - @override - void dispose() { - super.dispose(); + _refreshController.refreshCompleted(); } @override @@ -71,7 +80,9 @@ class _DashboardScreenState extends State { mainAxisSize: MainAxisSize.min, children: [ Image.memory( - Utils.getPostBytes(AppState().memberInformationList!.eMPLOYEEIMAGE ?? ""), + Utils.getPostBytes( + AppState().memberInformationList!.eMPLOYEEIMAGE ?? "", + ), errorBuilder: (BuildContext context, error, stackTrace) { return SvgPicture.asset( "assets/images/user.svg", @@ -120,243 +131,243 @@ class _DashboardScreenState extends State { ], ).paddingOnly(left: 21, right: 21, top: 48, bottom: 7), Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), - (AppState().memberInformationList!.eMPLOYEENAME ?? "").toText24(isBold: true), - 16.height, - Row( - children: [ - Expanded( - child: AspectRatio( - aspectRatio: 159 / 159, - child: Consumer( - builder: (context, model, child) { - return (model.isAttendanceTrackingLoading - ? GetAttendanceTrackingShimmer() - : Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ - MyColors.gradiantEndColor, - MyColors.gradiantStartColor, - ]), - ), - child: Stack( - alignment: Alignment.center, - children: [ - if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), - if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white), - if (model.isTimeRemainingInSeconds != 0) - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 9.height, - CountdownTimer( - endTime: model.endTime, - onEnd: null, - endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), - textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), - ), - LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), - 9.height, - ClipRRect( - borderRadius: BorderRadius.all( - Radius.circular(20), - ), - child: LinearProgressIndicator( - value: model.progress, - minHeight: 8, - valueColor: const AlwaysStoppedAnimation(Colors.white), - backgroundColor: const Color(0xff196D73), - ), - ), - ], - ), - ], - ).paddingOnly(top: 12, right: 15, left: 12), - ), - Row( + child: SmartRefresher( + enablePullDown: true, + enablePullUp: false, + header: const MaterialClassicHeader(color: MyColors.gradiantEndColor,), + controller: _refreshController, + onRefresh: _onRefresh, + child: SingleChildScrollView( + child: Column( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color), + (AppState().memberInformationList!.eMPLOYEENAME ?? "").toText24(isBold: true), + 16.height, + Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 159 / 159, + child: Consumer( + builder: (context, model, child) { + return (model.isAttendanceTrackingLoading + ? GetAttendanceTrackingShimmer() + : Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ]), + ), + child: Stack( + alignment: Alignment.center, + children: [ + if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true), + if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white), + if (model.isTimeRemainingInSeconds != 0) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.checkIn.tr().toText12(color: Colors.white), - (model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn) - .toString() - .toText14(color: Colors.white, isBold: true), - 4.height, - ], - ).paddingOnly(right: AppState().isArabic(context) ? 12 : 0, left: AppState().isArabic(context) ? 0 : 12), + 9.height, + CountdownTimer( + endTime: model.endTime, + onEnd: null, + endWidget: "00:00:00".toText14(color: Colors.white, isBold: true), + textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold), ), - Container( - width: 45, - height: 45, - padding: const EdgeInsets.only(left: 14, right: 14), - decoration: BoxDecoration( - color: const Color(0xff259EA4), - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(AppState().isArabic(context) ? 0 : 15), - bottomLeft: Radius.circular(AppState().isArabic(context) ? 15 : 0), - ), + LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white), + 9.height, + ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(20), ), - child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"), - ).onPress(() { - // if (AppState().isArabic(context)) { - // context.setLocale(const Locale("en", "US")); - // } else { - // context.setLocale(const Locale("ar", "SA")); - // } - - showMyBottomSheet(context, child: MarkAttendanceWidget(model)); - }), + child: LinearProgressIndicator( + value: model.progress, + minHeight: 8, + valueColor: const AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xff196D73), + ), + ), ], ), - ], + ], + ).paddingOnly(top: 12, right: 15, left: 12), + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.checkIn.tr().toText12(color: Colors.white), + (model.attendanceTracking!.pSwipeIn == null ? "--:--" : model.attendanceTracking!.pSwipeIn) + .toString() + .toText14(color: Colors.white, isBold: true), + 4.height, + ], + ).paddingOnly(left: 12), ), + Container( + width: 45, + height: 45, + padding: const EdgeInsets.only(left: 14, right: 14), + decoration: const BoxDecoration( + color: Color(0xff259EA4), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + ), + ), + child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"), + ).onPress(() { + showMyBottomSheet(context, child: MarkAttendanceWidget(model)); + }), ], ), - ).onPress( - () { - Navigator.pushNamed(context, AppRoutes.todayAttendance); - }, - )) - .animatedSwither(); - }, + ], + ), + ], + ), + ).onPress( + () { + Navigator.pushNamed(context, AppRoutes.todayAttendance); + }, + )) + .animatedSwither(); + }, + ), ), ), - ), - 9.width, - Expanded( - child: MenusWidget(), - ), - ], - ), - ], - ).paddingOnly(left: 21, right: 21, top: 7), - ServicesWidget(), - // 8.height, - Container( - width: double.infinity, - padding: const EdgeInsets.only(top: 31), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), - border: Border.all(color: MyColors.lightGreyEDColor, width: 1), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ + 9.width, Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - LocaleKeys.offers.tr().toText12(), - Row( - children: [ - LocaleKeys.discounts.tr().toText24(isBold: true), - 6.width, - Container( - padding: const EdgeInsets.only(left: 8, right: 8), - decoration: BoxDecoration( - color: MyColors.yellowColor, - borderRadius: BorderRadius.circular(10), - ), - child: LocaleKeys.newString.tr().toText10(isBold: true)), - ], - ), - ], - ), + child: MenusWidget(), ), - LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true).onPress(() { - Navigator.pushNamed(context, AppRoutes.offersAndDiscounts); - }) ], - ).paddingOnly(left: 21, right: 21), - Consumer( - builder: (context, model, child) { - return SizedBox( - height: 103 + 33, - child: ListView.separated( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.only(left: 21, right: 21, top: 13), - scrollDirection: Axis.horizontal, - itemBuilder: (cxt, index) { - return model.isOffersLoading - ? const OffersShimmerWidget() - : InkWell( - onTap: () { - navigateToDetails(data.getOffersList[index]); - }, - child: SizedBox( - width: 73, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 73, - height: 73, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all( - Radius.circular(100), - ), - border: Border.all(color: MyColors.lightGreyE3Color, width: 1), - ), - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular(50), - ), - child: Hero( - tag: "ItemImage" + data.getOffersList[index].rowID!, - transitionOnUserGestures: true, - child: Image.network( - data.getOffersList[index].bannerImage!, - fit: BoxFit.contain, - ), - ), - ), + ), + ], + ).paddingOnly(left: 21, right: 21, top: 7), + ServicesWidget(), + // 8.height, + Container( + width: double.infinity, + padding: const EdgeInsets.only(top: 31), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + LocaleKeys.offers.tr().toText12(), + Row( + children: [ + LocaleKeys.discounts.tr().toText24(isBold: true), + 6.width, + Container( + padding: const EdgeInsets.only(left: 8, right: 8), + decoration: BoxDecoration( + color: MyColors.yellowColor, + borderRadius: BorderRadius.circular(10), + ), + child: LocaleKeys.newString.tr().toText10(isBold: true)), + ], + ), + ], + ), + ), + LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true).onPress(() { + Navigator.pushNamed(context, AppRoutes.offersAndDiscounts); + }) + ], + ).paddingOnly(left: 21, right: 21), + Consumer( + builder: (context, model, child) { + return SizedBox( + height: 103 + 33, + child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.only(left: 21, right: 21, top: 13), + scrollDirection: Axis.horizontal, + itemBuilder: (cxt, index) { + return model.isOffersLoading + ? const OffersShimmerWidget() + : InkWell( + onTap: () { + navigateToDetails(data.getOffersList[index]); + }, + child: SizedBox( + width: 73, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 73, + height: 73, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all( + Radius.circular(100), ), - 4.height, - Expanded( - child: AppState().isArabic(context) - ? data.getOffersList[index].titleAR!.toText12(isCenter: true, maxLine: 1) - : data.getOffersList[index].title!.toText12(isCenter: true, maxLine: 1), + border: Border.all(color: MyColors.lightGreyE3Color, width: 1), + ), + child: ClipRRect( + borderRadius: const BorderRadius.all( + Radius.circular(50), ), - ], + child: Hero( + tag: "ItemImage" + data.getOffersList[index].rowID!, + transitionOnUserGestures: true, + child: Image.network( + data.getOffersList[index].bannerImage!, + fit: BoxFit.contain, + ), + ), + ), ), - ), - ); - }, - separatorBuilder: (cxt, index) => 8.width, - itemCount: 6), - ); - }, - ), - ], - ), - ) - ], + 4.height, + Expanded( + child: AppState().isArabic(context) + ? data.getOffersList[index].titleAR!.toText12(isCenter: true, maxLine: 1) + : data.getOffersList[index].title!.toText12(isCenter: true, maxLine: 1), + ), + ], + ), + ), + ); + }, + separatorBuilder: (cxt, index) => 8.width, + itemCount: 6), + ); + }, + ), + ], + ), + ) + ], + ), ), ), ) diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index 2bc697b..7a6e976 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -23,10 +23,10 @@ class ServicesWidget extends StatelessWidget { "assets/images/monthly_attendance.svg", "assets/images/ticket_request.svg", "assets/images/ticket_request.svg", - "assets/images/dynamic_screens.svg", - "assets/images/dynamic_screens.svg", - "assets/images/dynamic_screens.svg", - "assets/images/dynamic_screens.svg" + "assets/images/ticket_request.svg", + "assets/images/ticket_request.svg", + "assets/images/ticket_request.svg", + "assets/images/ticket_request.svg" ]; return Consumer( diff --git a/lib/ui/screens/items_for_sale/fragments/items_for_sale.dart b/lib/ui/screens/items_for_sale/fragments/items_for_sale.dart index 9189f0b..ca75a7a 100644 --- a/lib/ui/screens/items_for_sale/fragments/items_for_sale.dart +++ b/lib/ui/screens/items_for_sale/fragments/items_for_sale.dart @@ -25,6 +25,7 @@ class _ItemsForSaleFragmentState extends State { List getSaleCategoriesList = []; List getItemsForSaleList = []; + List _foundItemsForSaleList = []; ScrollController gridScrollController = ScrollController(); int currentPageNo = 1; @@ -61,20 +62,10 @@ class _ItemsForSaleFragmentState extends State { isInputTypeNum: false, isReadOnly: false, onChange: (String value) { - // _runFilter(value); + _runFilter(value); }, ).paddingOnly(left: 21, right: 21, top: 21), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.browseCategories.tr().toText17(), - // todo @haroon define the purpose of this icon button - IconButton( - icon: const Icon(Icons.filter_alt_sharp, color: MyColors.darkIconColor, size: 28.0), - onPressed: () => Navigator.pop(context), - ), - ], - ).paddingOnly(left: 21, right: 21), + LocaleKeys.browseCategories.tr().toText17().paddingOnly(left: 21, right: 21, top: 21), SizedBox( height: 105.0, child: getSaleCategoriesList.isNotEmpty @@ -132,10 +123,22 @@ class _ItemsForSaleFragmentState extends State { ); } + void _runFilter(String enteredKeyword) { + List results = []; + if (enteredKeyword.isEmpty) { + results = getItemsForSaleList; + } else { + results = getItemsForSaleList.where((offer) => offer.title!.toLowerCase().contains(enteredKeyword.toLowerCase())).toList(); + } + setState(() { + _foundItemsForSaleList = results; + }); + } + List getItemsForSaleWidgets() { List itemsList = []; - getItemsForSaleList.forEach((element) { + _foundItemsForSaleList.forEach((element) { itemsList.add(getItemCard(element)); }); @@ -200,6 +203,7 @@ class _ItemsForSaleFragmentState extends State { getItemsForSaleListLocal.clear(); getItemsForSaleListLocal = await ItemsForSaleApiClient().getItemsForSale(itgPageNo, itgCategoryID); getItemsForSaleList.addAll(getItemsForSaleListLocal); + _foundItemsForSaleList = getItemsForSaleList; Utils.hideLoading(context); setState(() {}); } catch (ex) { diff --git a/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart b/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart index fed4583..e33a161 100644 --- a/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart +++ b/lib/ui/screens/offers_and_discounts/offers_and_discounts_home.dart @@ -25,6 +25,7 @@ class OffersAndDiscountsHome extends StatefulWidget { class _OffersAndDiscountsHomeState extends State { List getCategoriesList = []; List getOffersList = []; + List _foundOffersList = []; int currentCategoryID = 0; @@ -54,18 +55,10 @@ class _OffersAndDiscountsHomeState extends State { isInputTypeNum: false, isReadOnly: false, onChange: (String value) { - // _runFilter(value); + _runFilter(value); }, ).paddingOnly(left: 21, right: 21, top: 21), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.browseCategories.tr().toText17(), - const Icon(Icons.filter_alt_sharp, color: MyColors.darkIconColor, size: 28.0).onPress(() { - Navigator.pop(context); - }), - ], - ).paddingOnly(left: 21, right: 21, top: 21), + LocaleKeys.browseCategories.tr().toText17().paddingOnly(left: 21, right: 21, top: 21), SizedBox( height: 110.0, child: getCategoriesList.isNotEmpty @@ -81,6 +74,7 @@ class _OffersAndDiscountsHomeState extends State { onTap: () { setState(() { currentCategoryID = getCategoriesList[index].id!; + getCategoryOffersListAPI(); // getItemsForSaleList.clear(); // currentPageNo = 1; // getItemsForSale(currentPageNo, currentCategoryID); @@ -146,7 +140,7 @@ class _OffersAndDiscountsHomeState extends State { List getItemsForSaleWidgets() { List itemsList = []; - for (var element in getOffersList) { + for (var element in _foundOffersList) { itemsList.add(getItemCard(element)); } @@ -213,6 +207,18 @@ class _OffersAndDiscountsHomeState extends State { ); } + void _runFilter(String enteredKeyword) { + List results = []; + if (enteredKeyword.isEmpty) { + results = getOffersList; + } else { + results = getOffersList.where((offer) => offer.title!.toLowerCase().contains(enteredKeyword.toLowerCase())).toList(); + } + setState(() { + _foundOffersList = results; + }); + } + void navigateToDetails(OffersListModel offersListModelObj) { List getOffersDetailList = []; getOffersDetailList.clear(); @@ -258,6 +264,7 @@ class _OffersAndDiscountsHomeState extends State { try { Utils.showLoading(context); getOffersList = await OffersAndDiscountsApiClient().getOffersList(currentCategoryID, 100); + _foundOffersList = getOffersList; Utils.hideLoading(context); setState(() {}); } catch (ex) { diff --git a/lib/ui/work_list/itg_detail_screen.dart b/lib/ui/work_list/itg_detail_screen.dart index 25eced3..e0c256c 100644 --- a/lib/ui/work_list/itg_detail_screen.dart +++ b/lib/ui/work_list/itg_detail_screen.dart @@ -11,8 +11,6 @@ import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; -import 'package:mohem_flutter_app/models/generic_response_model.dart'; -import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/allowed_actions_model.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/itg_request_model.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/request_detail_model.dart'; @@ -20,7 +18,7 @@ import 'package:mohem_flutter_app/ui/work_list/itg_fragments/approval_level_frag import 'package:mohem_flutter_app/ui/work_list/itg_fragments/request_detail_fragment.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:mohem_flutter_app/widgets/dialogs/accept_reject_input_dialog.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/itg_comments_dialog.dart'; class ItgDetailScreen extends StatefulWidget { ItgDetailScreen({Key? key}) : super(key: key); @@ -56,22 +54,21 @@ class _ItgDetailScreenState extends State { ITGRequest? itgRequest; void getItgData() async { - // try { + try { Utils.showLoading(context); - itgRequest = await WorkListApiClient().getITGFormDetails(requestDetails!.requestType!, requestDetails!.iD!, requestDetails!.itemID!, ""); + itgRequest = await WorkListApiClient().getITGFormDetails(requestDetails!.requestType!, requestDetails!.iD!, requestDetails!.itemID!, AppState().memberInformationList?.eMPLOYEENUMBER ?? ""); allowedActionList = itgRequest?.allowedActions ?? []; if (allowedActionList.isNotEmpty) { isCloseAvailable = allowedActionList.any((element) => element.action == "CLOSE"); isApproveAvailable = itgRequest!.allowedActions!.any((element) => element.action == "Approve"); - // isAnswerAvailable = itgRequest!.allowedActions!.any((element) => element.action == "Answer"); isRejectAvailable = itgRequest!.allowedActions!.any((element) => element.action == "Reject"); } Utils.hideLoading(context); setState(() {}); - // } catch (ex) { - // Utils.hideLoading(context); - // Utils.handleException(ex, context, null); - // } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } } void getDataFromState() { @@ -341,34 +338,39 @@ class _ItgDetailScreenState extends State { void performAction(String actionMode) { showDialog( context: context, - builder: (cxt) => AcceptRejectInputDialog( - message: LocaleKeys.requestedItems.tr(), - // notificationGetRespond: notificationNoteInput, + builder: (cxt) => ITGCommentsDialog( + message: LocaleKeys.writeComment.tr(), onTap: (note) { - Map payload = { - "P_ACTION_MODE": actionMode, - "P_APPROVER_INDEX": null, - "P_COMMENTS": "", - "P_FORWARD_TO_USER_NAME": "", - // "P_NOTIFICATION_ID": workListData!.nOTIFICATIONID!, - "RespondAttributeList": [ - // if (notificationNoteInput != null) {notificationNoteInput!.attributeName: note} - ], - }; - - performNotificationAction(payload); + if (actionMode == "APPROVED") { + performApproveAction(requestDetails!.requestType!, requestDetails!.iD!, requestDetails!.itemID!, AppState().memberInformationList?.eMPLOYEENUMBER ?? "", note); + } else { + performRejectAction(requestDetails!.requestType!, requestDetails!.iD!, requestDetails!.itemID!, AppState().memberInformationList?.eMPLOYEENUMBER ?? "", note); + } }, ), ); } - void performNotificationAction(Map payload) async { + void performRejectAction(String requestType, int taskId, int itemId, String employeeNumber, String comments) async { + try { + Utils.showLoading(context); + ITGRequest? itgRequest = await WorkListApiClient().rejectITGRequest(requestType, taskId, itemId, employeeNumber, comments); + Utils.hideLoading(context); + Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); + Navigator.pop(context, "delegate_reload"); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + void performApproveAction(String requestType, int taskId, int itemId, String employeeNumber, String comments) async { try { Utils.showLoading(context); - GenericResponseModel model = await WorkListApiClient().postNotificationActions(payload); + ITGRequest? itgRequest = await WorkListApiClient().approveITGRequest(requestType, taskId, itemId, employeeNumber, comments); Utils.hideLoading(context); Utils.showToast(LocaleKeys.yourChangeHasBeenSavedSuccessfully.tr()); - Navigator.pop(context, true); + Navigator.pop(context, "delegate_reload"); } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, null); diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 8196abb..dcdd580 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -32,17 +32,45 @@ class WorkListScreen extends StatefulWidget { class _WorkListScreenState extends State { List workListItemTypes = [ WorkListItemTypeModelData( - value: 0, name: 'HR', fullName: LocaleKeys.humanResource.tr(), active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'HRSSA', disable: false), + value: 0, + name: 'HR', + fullName: LocaleKeys.humanResource.tr(), + active: false, + color: [Color(0xff32D892), Color(0xff1AB170)], + icon: "assets/images/miss_swipe.svg", + key: 'HRSSA', + disable: false), WorkListItemTypeModelData( value: 0, name: 'MR', fullName: LocaleKeys.moveOrder.tr(), active: false, color: [Color(0xff58DCFA), Color(0xff3CB9D5)], icon: "assets/images/miss_swipe.svg", key: 'INVMOA', disable: false), WorkListItemTypeModelData( - value: 0, name: 'PR', fullName: LocaleKeys.purchaseRequisition.tr(), active: false, color: [Color(0xff48EACF), Color(0xff3DCAB3)], icon: "assets/images/miss_swipe.svg", key: 'REQAPPRV', disable: false), + value: 0, + name: 'PR', + fullName: LocaleKeys.purchaseRequisition.tr(), + active: false, + color: [Color(0xff48EACF), Color(0xff3DCAB3)], + icon: "assets/images/miss_swipe.svg", + key: 'REQAPPRV', + disable: false), WorkListItemTypeModelData( - value: 0, name: 'PO', fullName: LocaleKeys.purchaseOrder.tr(), active: false, color: [Color(0xff5099E3), Color(0xff3670AA)], icon: "assets/images/miss_swipe.svg", key: 'POAPPRV', disable: false), + value: 0, + name: 'PO', + fullName: LocaleKeys.purchaseOrder.tr(), + active: false, + color: [Color(0xff5099E3), Color(0xff3670AA)], + icon: "assets/images/miss_swipe.svg", + key: 'POAPPRV', + disable: false), WorkListItemTypeModelData( value: 0, name: 'ITG', fullName: LocaleKeys.ITGForms.tr(), active: false, color: [Color(0xffEB8C90), Color(0xffDE6C70)], icon: "assets/images/miss_swipe.svg", key: 'ITG', disable: false), WorkListItemTypeModelData( - value: 0, name: 'IC', fullName: LocaleKeys.itemCreation.tr(), active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'INVITEM', disable: false), + value: 0, + name: 'IC', + fullName: LocaleKeys.itemCreation.tr(), + active: false, + color: [Color(0xff32D892), Color(0xff1AB170)], + icon: "assets/images/miss_swipe.svg", + key: 'INVITEM', + disable: false), WorkListItemTypeModelData( value: 0, name: 'STAMP', fullName: LocaleKeys.stamp.tr(), active: false, color: [Color(0xff32D892), Color(0xff1AB170)], icon: "assets/images/miss_swipe.svg", key: 'STAMP', disable: false), ]; @@ -232,6 +260,7 @@ class _WorkListScreenState extends State { var shouldReloadData = await Navigator.pushNamed(context, AppRoutes.itgDetail); if (shouldReloadData != null) { if (shouldReloadData.toString() == "delegate_reload") { + providerData.itgFormsModel!.totalCount = providerData.itgFormsModel!.totalCount! - 1; calculateCounter(); getWorkList(); } diff --git a/lib/widgets/dialogs/itg_comments_dialog.dart b/lib/widgets/dialogs/itg_comments_dialog.dart new file mode 100644 index 0000000..b984851 --- /dev/null +++ b/lib/widgets/dialogs/itg_comments_dialog.dart @@ -0,0 +1,102 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; + +class ITGCommentsDialog extends StatelessWidget { + final String? title; + final String? message; + final String? okTitle; + final Function(String) onTap; + + ITGCommentsDialog({Key? key, this.title, @required this.message, this.okTitle, required this.onTap}) : super(key: key); + + String note = ""; + + @override + Widget build(BuildContext context) { + return Dialog( + backgroundColor: Colors.white, + shape: const RoundedRectangleBorder(), + insetPadding: const EdgeInsets.only(left: 21, right: 21), + child: Padding( + padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Text( + title ?? LocaleKeys.confirm.tr(), + style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Color(0xff2B353E), height: 35 / 24, letterSpacing: -0.96), + ), + ), + ), + IconButton( + padding: EdgeInsets.zero, + icon: const Icon(Icons.close), + color: const Color(0xff2B353E), + constraints: const BoxConstraints(), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ), + Text( + message ?? "", + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff808080), letterSpacing: -0.48), + ), + // if (notificationGetRespond != null) ...[ + 14.height, + InputWidget( + "Enter a Note", + LocaleKeys.comments.tr(), + TextEditingController(), + isBackgroundEnable: true, + isInputTypeNum: false, + lines: 3, + onChange: (String note) { + this.note = note; + }, + ), + // ], + 28.height, + Row( + children: [ + DefaultButton( + LocaleKeys.cancel.tr(), + () => Navigator.pop(context), + colors: const [MyColors.lightGreyEAColor, MyColors.lightGreyEAColor], + textColor: MyColors.darkTextColor, + ).expanded, + 10.width, + DefaultButton( + LocaleKeys.ok.tr(), + () { + Navigator.pop(context); + onTap(note); + }, + colors: const [ + Color(0xff28C884), + Color(0xff1BB271), + ], + ).expanded, + ], + ), + ], + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 14c034a..9a54f6c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -75,6 +75,7 @@ dependencies: url_launcher: ^6.0.15 share: 2.0.4 flutter_rating_bar: ^4.0.1 + pull_to_refresh: ^2.0.0 dev_dependencies: flutter_test: