diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 6635d82d..f07b470f 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -4,12 +4,12 @@ class ApiConsts { // static String baseUrl = "http://10.201.214.101:2027"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server // static String baseUrl = "http://10.201.204.101:2024"; // static String baseUrl = "https://webservices.hmg.com"; // PreProd // static String baseUrl = "https://hmgwebservices.com"; // Live server - // static String baseUrl = "https://mohemm.hmg.com"; // New Live server + static String baseUrl = "https://mohemm.hmg.com"; // New Live server static String ssoBaseUrl = "https://sso.hmg.com"; // New Live server // // static String baseUrl = "https://uat.hmgwebservices.com"; // diff --git a/lib/ui/landing/dashboard_screen_for_dependet.dart b/lib/ui/landing/dashboard_screen_for_dependet.dart index a28807e4..0c32f095 100644 --- a/lib/ui/landing/dashboard_screen_for_dependet.dart +++ b/lib/ui/landing/dashboard_screen_for_dependet.dart @@ -53,8 +53,8 @@ class _DashboardScreenForDependetState extends State // WP_Radius (null when "any"), _filterMinDiscount drives WP_Min_Discount (null when "any"). // Committed on "Apply filters"/"Reset"; persisted here so reopening the sheet shows the // last-applied selection (availability's source of truth is selectedTypeFilter itself). - String _filterSortBy = 'nearest'; - String _filterDistance = '5km'; + String _filterSortBy = 'newest'; + String _filterDistance = 'any'; String _filterMinDiscount = 'any'; bool isNearestOffers = true; bool isLoading = true; @@ -335,7 +335,11 @@ class _DashboardScreenForDependetState extends State try { int nextPage = currentPage + 1; - String catParam = (currentCategoryId == "all" || currentCategoryId == "0") ? "" : currentCategoryId; + // Must match fetchOffers's category resolution exactly (including the selected + // subcategory, if any) - otherwise pagination silently switches filters mid-scroll, + // fetching an overlapping result set under the same page number and duplicating items. + String effectiveCategoryId = _selectedSubcategoryId ?? currentCategoryId; + String catParam = (effectiveCategoryId == "all" || effectiveCategoryId == "0") ? "" : effectiveCategoryId; String? offerTypeParam = OffersAndDiscountsApiClient.mapOfferTypeFilter(selectedTypeFilter); String? queryParam = searchQuery.trim().isNotEmpty ? searchQuery.trim() : null; int? radiusParam = _radiusFromFilterDistance(_filterDistance); @@ -378,7 +382,8 @@ class _DashboardScreenForDependetState extends State } Future _onRefresh() async { - await Future.wait(>[fetchCategories(), fetchOffers(categoryId: currentCategoryId.isEmpty ? "all" : currentCategoryId, query: _searchController.text)]); + String effectiveCategoryId = _selectedSubcategoryId ?? (currentCategoryId.isEmpty ? "all" : currentCategoryId); + await Future.wait(>[fetchCategories(), fetchOffers(categoryId: effectiveCategoryId, query: _searchController.text)]); } // '5km'/'10km'/'25km' -> 5/10/25 for WP_Radius; 'any' -> null (omit the param - no distance cap). @@ -835,10 +840,22 @@ class _DashboardScreenForDependetState extends State // Replaces the old All/In Store/Online chip row: a fixed "Filters" chip (opens the filters // bottom sheet) + a divider, then a horizontally scrollable row of subcategory chips fetched // from the API for whichever main category is currently selected (see fetchSubcategories). + // How many of the 4 filter sections are away from their default value + // (Availability: all, Sort by: newest, Distance: any, Minimum discount: any). + int _activeFilterCount() { + int count = 0; + if (selectedTypeFilter != 'all') count++; + if (_filterSortBy != 'newest') count++; + if (_filterDistance != 'any') count++; + if (_filterMinDiscount != 'any') count++; + return count; + } + Widget _buildFiltersRow(bool isAr) { // "All Categories" (or nothing selected) has no subcategories to show at all - only a // specific main category, once it has actually loaded some, gets the divider + chip row. bool showSubcategoriesRow = currentCategoryId.isNotEmpty && currentCategoryId != "all" && (isSubcategoriesLoading || subcategoriesList.isNotEmpty); + int activeFilterCount = _activeFilterCount(); return Padding( padding: const EdgeInsets.only(top: 14, bottom: 2), @@ -846,22 +863,39 @@ class _DashboardScreenForDependetState extends State height: 38, child: Row( children: [ - InkWell( - borderRadius: BorderRadius.circular(6), - onTap: _showFiltersBottomSheet, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), - alignment: Alignment.center, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: MyColors.lightGreyEAColor), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - SvgPicture.asset("assets/icons/filter_icon.svg", width: 14, height: 14, colorFilter: const ColorFilter.mode(MyColors.black, BlendMode.srcIn)), - const SizedBox(width: 5), - LocaleKeys.filters.tr().toText12(color: MyColors.black), - ], + Stack( + clipBehavior: Clip.none, + children: [ + InkWell( + borderRadius: BorderRadius.circular(6), + onTap: _showFiltersBottomSheet, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), + alignment: Alignment.center, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: MyColors.lightGreyEAColor), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset("assets/icons/filter_icon.svg", width: 14, height: 14, colorFilter: const ColorFilter.mode(MyColors.black, BlendMode.srcIn)), + const SizedBox(width: 5), + LocaleKeys.filters.tr().toText12(color: MyColors.black), + ], + ), + ), ), - ), + if (activeFilterCount > 0) + PositionedDirectional( + top: -6, + end: -6, + child: Container( + width: 18, + height: 18, + alignment: Alignment.center, + decoration: const BoxDecoration(color: MyColors.darkIconColor, shape: BoxShape.circle), + child: '$activeFilterCount'.toText10(isBold: true, color: Colors.white), + ), + ), + ], ), if (showSubcategoriesRow) ...[ Container(margin: const EdgeInsets.symmetric(horizontal: 10), width: 1, height: 20, color: const Color(0xFFE2E8F0)),