|
|
|
|
@ -18,6 +18,7 @@ import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_category
|
|
|
|
|
import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_retailer_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/post_params_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/bottom_sheets/confirm_bottom_sheet.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/info_chip_widget.dart';
|
|
|
|
|
import 'package:shimmer/shimmer.dart';
|
|
|
|
|
|
|
|
|
|
@ -34,6 +35,22 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
|
|
|
|
|
List<WalaPlusCategoryModel> categoriesList = [];
|
|
|
|
|
String currentCategoryId = "";
|
|
|
|
|
String selectedTypeFilter = "all";
|
|
|
|
|
|
|
|
|
|
// Subcategories of whichever main category is currently selected - fetched via
|
|
|
|
|
// getWalaPlusCategories(parentId: ...) whenever a main category card is tapped. Empty/cleared
|
|
|
|
|
// when "All Categories" (or nothing) is selected, since there's no specific parent to ask for.
|
|
|
|
|
List<WalaPlusCategoryModel> subcategoriesList = <WalaPlusCategoryModel>[];
|
|
|
|
|
bool isSubcategoriesLoading = false;
|
|
|
|
|
String? _selectedSubcategoryId;
|
|
|
|
|
|
|
|
|
|
// Filters bottom sheet state. Availability is single-select and functional - it drives the
|
|
|
|
|
// same selectedTypeFilter/offerType param the old chip row used. Sort/Distance/Minimum
|
|
|
|
|
// discount still have no backend support, so those remain UI-only for now. Committed on
|
|
|
|
|
// "Apply filters"; sort/distance/discount are 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 _filterMinDiscount = 'any';
|
|
|
|
|
bool isNearestOffers = true;
|
|
|
|
|
bool isLoading = true;
|
|
|
|
|
bool isLoadingMore = false;
|
|
|
|
|
@ -49,23 +66,6 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
|
|
|
|
|
final ScrollController _scrollController = ScrollController();
|
|
|
|
|
bool _hasRegisteredMobileLoginInfo = false;
|
|
|
|
|
|
|
|
|
|
List<String> get _availableTypeFilters {
|
|
|
|
|
Set<String> types = <String>{};
|
|
|
|
|
for (WalaPlusRetailerModel r in retailersList) {
|
|
|
|
|
String? t = r.normalizedType;
|
|
|
|
|
if (t != null && t.isNotEmpty) {
|
|
|
|
|
types.add(t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
List<String> list = <String>['all', 'instore', 'online'];
|
|
|
|
|
for (String t in types) {
|
|
|
|
|
if (!list.contains(t)) {
|
|
|
|
|
list.add(t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String _getTypeFilterTitle(String type) {
|
|
|
|
|
if (type == 'all') {
|
|
|
|
|
return LocaleKeys.allCategories.tr();
|
|
|
|
|
@ -239,6 +239,45 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fetches the subcategories under a main category (WP_ParentId). "All Categories" (or no
|
|
|
|
|
// category) has no specific parent, so that just clears the list instead of calling the API.
|
|
|
|
|
Future<void> fetchSubcategories(String? parentId) async {
|
|
|
|
|
if (parentId == null || parentId.isEmpty || parentId == "all") {
|
|
|
|
|
setState(() {
|
|
|
|
|
subcategoriesList = <WalaPlusCategoryModel>[];
|
|
|
|
|
_selectedSubcategoryId = null;
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
|
isSubcategoriesLoading = true;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
List<WalaPlusCategoryModel> list = await OffersAndDiscountsApiClient().getWalaPlusCategories(context: context, parentId: parentId);
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setState(() {
|
|
|
|
|
subcategoriesList = list;
|
|
|
|
|
_selectedSubcategoryId = null;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
debugPrint("Error fetching WalaPlus subcategories: $e");
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setState(() {
|
|
|
|
|
subcategoriesList = <WalaPlusCategoryModel>[];
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setState(() {
|
|
|
|
|
isSubcategoriesLoading = false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> fetchOffers({String? categoryId, String? query}) async {
|
|
|
|
|
String targetCategoryId = categoryId ?? (currentCategoryId.isEmpty ? "all" : currentCategoryId);
|
|
|
|
|
if (query != null) {
|
|
|
|
|
@ -592,7 +631,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
|
|
|
|
|
if (categoriesList.isNotEmpty) _buildCategoriesList(isAr) else _buildCategoriesShimmer(),
|
|
|
|
|
|
|
|
|
|
// Type Filter Chips (All, In Store, Online)
|
|
|
|
|
_buildTypeFilterChips(isAr),
|
|
|
|
|
_buildFiltersRow(isAr),
|
|
|
|
|
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
|
|
|
|
|
@ -711,6 +750,7 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
|
|
|
|
|
currentCategoryId = item.id ?? "";
|
|
|
|
|
});
|
|
|
|
|
fetchOffers(categoryId: currentCategoryId);
|
|
|
|
|
fetchSubcategories(currentCategoryId);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
@ -736,54 +776,280 @@ class _DashboardScreenForDependetState extends State<DashboardScreenForDependet>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildTypeFilterChips(bool isAr) {
|
|
|
|
|
List<String> types = _availableTypeFilters;
|
|
|
|
|
// 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).
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.only(top: 14, bottom: 2),
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
height: 38,
|
|
|
|
|
child: ListView.separated(
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
|
itemCount: types.length,
|
|
|
|
|
separatorBuilder: (BuildContext _, int __) => const SizedBox(width: 8),
|
|
|
|
|
itemBuilder: (BuildContext context, int index) {
|
|
|
|
|
String typeKey = types[index];
|
|
|
|
|
bool isSelected = selectedTypeFilter == typeKey;
|
|
|
|
|
String title = _getTypeFilterTitle(typeKey);
|
|
|
|
|
IconData icon = _getTypeFilterIcon(typeKey);
|
|
|
|
|
|
|
|
|
|
return InkWell(
|
|
|
|
|
child: Row(
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
InkWell(
|
|
|
|
|
borderRadius: BorderRadius.circular(6),
|
|
|
|
|
onTap: () {
|
|
|
|
|
if (selectedTypeFilter != typeKey) {
|
|
|
|
|
setState(() {
|
|
|
|
|
selectedTypeFilter = typeKey;
|
|
|
|
|
});
|
|
|
|
|
fetchOffers(categoryId: currentCategoryId.isEmpty ? "all" : currentCategoryId);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
onTap: _showFiltersBottomSheet,
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: isSelected ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
|
|
|
|
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: MyColors.lightGreyEAColor),
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
Icon(icon, size: 14, color: isSelected ? MyColors.white : MyColors.black),
|
|
|
|
|
SvgPicture.asset("assets/icons/filter_icon.svg", width: 14, height: 14, colorFilter: const ColorFilter.mode(MyColors.black, BlendMode.srcIn)),
|
|
|
|
|
const SizedBox(width: 5),
|
|
|
|
|
title.toText12(color: isSelected ? MyColors.white : MyColors.black),
|
|
|
|
|
LocaleKeys.filters.tr().toText12(color: MyColors.black),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
if (showSubcategoriesRow) ...<Widget>[
|
|
|
|
|
Container(margin: const EdgeInsets.symmetric(horizontal: 10), width: 1, height: 20, color: const Color(0xFFE2E8F0)),
|
|
|
|
|
Expanded(
|
|
|
|
|
child:
|
|
|
|
|
isSubcategoriesLoading
|
|
|
|
|
? const Center(child: SizedBox(width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF94A3B8))))
|
|
|
|
|
: ListView.separated(
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
|
// +1 for the leading "All" chip (clears the subcategory selection,
|
|
|
|
|
// falling back to just the parent main category).
|
|
|
|
|
itemCount: subcategoriesList.length + 1,
|
|
|
|
|
separatorBuilder: (BuildContext _, int __) => const SizedBox(width: 8),
|
|
|
|
|
itemBuilder: (BuildContext context, int index) {
|
|
|
|
|
bool isAllChip = index == 0;
|
|
|
|
|
WalaPlusCategoryModel? subcategory = isAllChip ? null : subcategoriesList[index - 1];
|
|
|
|
|
bool isSelected = isAllChip ? _selectedSubcategoryId == null : _selectedSubcategoryId == subcategory!.id;
|
|
|
|
|
String label = isAllChip ? LocaleKeys.allCategories.tr() : (subcategory!.name ?? "");
|
|
|
|
|
|
|
|
|
|
return InkWell(
|
|
|
|
|
borderRadius: BorderRadius.circular(6),
|
|
|
|
|
onTap: () {
|
|
|
|
|
setState(() {
|
|
|
|
|
_selectedSubcategoryId = isAllChip ? null : (isSelected ? null : subcategory!.id);
|
|
|
|
|
});
|
|
|
|
|
// Selecting a subcategory filters offers to just that subcategory;
|
|
|
|
|
// "All" (or deselecting) falls back to the parent main category.
|
|
|
|
|
fetchOffers(categoryId: _selectedSubcategoryId ?? currentCategoryId);
|
|
|
|
|
},
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(6), color: isSelected ? MyColors.darkIconColor : MyColors.lightGreyEAColor),
|
|
|
|
|
child: label.toText12(color: isSelected ? MyColors.white : MyColors.black),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Matches the shared Filters bottom sheet design. Availability is single-select and
|
|
|
|
|
// functional, driving selectedTypeFilter/offerType exactly like the old chip row did.
|
|
|
|
|
// Sort/Distance/Minimum discount still have no backend support, so those remain UI-only.
|
|
|
|
|
void _showFiltersBottomSheet() {
|
|
|
|
|
String draftAvailability = selectedTypeFilter;
|
|
|
|
|
String draftSortBy = _filterSortBy;
|
|
|
|
|
String draftDistance = _filterDistance;
|
|
|
|
|
String draftMinDiscount = _filterMinDiscount;
|
|
|
|
|
|
|
|
|
|
const Color darkBg = Color(0xFF202B33);
|
|
|
|
|
const Color borderColor = Color(0xFFE2E8F0);
|
|
|
|
|
|
|
|
|
|
showModalBottomSheet<void>(
|
|
|
|
|
context: context,
|
|
|
|
|
isScrollControlled: true,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
builder: (BuildContext sheetContext) {
|
|
|
|
|
return StatefulBuilder(
|
|
|
|
|
builder: (BuildContext context, StateSetter setSheetState) {
|
|
|
|
|
Widget buildOption(String label, bool isSelected, VoidCallback onTap, {IconData? icon}) {
|
|
|
|
|
return Expanded(
|
|
|
|
|
child: InkWell(
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
onTap: onTap,
|
|
|
|
|
child: Container(
|
|
|
|
|
height: 44,
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
color: isSelected ? darkBg : Colors.white,
|
|
|
|
|
border: Border.all(color: isSelected ? darkBg : borderColor),
|
|
|
|
|
),
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
if (icon != null) ...<Widget>[Icon(icon, size: 14, color: isSelected ? Colors.white : const Color(0xFF64748B)), const SizedBox(width: 5)],
|
|
|
|
|
Flexible(child: label.toText13(isBold: true, color: isSelected ? Colors.white : darkBg, maxlines: 1)),
|
|
|
|
|
if (isSelected) ...<Widget>[const SizedBox(width: 5), const Icon(Icons.check, size: 14, color: Colors.white)],
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget sectionHeader(String title, {String? hint}) {
|
|
|
|
|
return Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
title.toText14(isBold: true, color: darkBg),
|
|
|
|
|
if (hint != null) hint.toText12(color: const Color(0xFF94A3B8)),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SafeArea(
|
|
|
|
|
top: false,
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: const EdgeInsets.fromLTRB(20, 12, 20, 20),
|
|
|
|
|
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(24))),
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
Center(
|
|
|
|
|
child: Container(width: 44, height: 4.5, margin: const EdgeInsets.only(bottom: 16), decoration: BoxDecoration(color: const Color(0xFFCBD5E1), borderRadius: BorderRadius.circular(2.5))),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
LocaleKeys.filters.tr().toText20(isBold: true, color: darkBg),
|
|
|
|
|
InkWell(
|
|
|
|
|
borderRadius: BorderRadius.circular(16),
|
|
|
|
|
onTap: () => Navigator.pop(sheetContext),
|
|
|
|
|
child: Container(
|
|
|
|
|
width: 32,
|
|
|
|
|
height: 32,
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: const BoxDecoration(shape: BoxShape.circle, color: Color(0xFFF1F5F9)),
|
|
|
|
|
child: const Icon(Icons.close, size: 18, color: darkBg),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
20.height,
|
|
|
|
|
|
|
|
|
|
// Availability - single select, drives the real offerType filter.
|
|
|
|
|
LocaleKeys.availability.tr().toText14(isBold: true, color: darkBg),
|
|
|
|
|
10.height,
|
|
|
|
|
Row(
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
buildOption(LocaleKeys.allCategories.tr(), draftAvailability == 'all', () => setSheetState(() => draftAvailability = 'all')),
|
|
|
|
|
const SizedBox(width: 10),
|
|
|
|
|
buildOption(LocaleKeys.online.tr(), draftAvailability == 'online', () => setSheetState(() => draftAvailability = 'online')),
|
|
|
|
|
const SizedBox(width: 10),
|
|
|
|
|
buildOption(LocaleKeys.inStore.tr(), draftAvailability == 'instore', () => setSheetState(() => draftAvailability = 'instore')),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
20.height,
|
|
|
|
|
|
|
|
|
|
// Sort by - single select, Nearest and Newest only.
|
|
|
|
|
LocaleKeys.sortBy.tr().toText14(isBold: true, color: darkBg),
|
|
|
|
|
10.height,
|
|
|
|
|
Row(
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
buildOption(LocaleKeys.nearest.tr(), draftSortBy == 'nearest', () => setSheetState(() => draftSortBy = 'nearest'), icon: Icons.location_on_outlined),
|
|
|
|
|
const SizedBox(width: 10),
|
|
|
|
|
buildOption(LocaleKeys.newest.tr(), draftSortBy == 'newest', () => setSheetState(() => draftSortBy = 'newest')),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
20.height,
|
|
|
|
|
|
|
|
|
|
// Distance - single select.
|
|
|
|
|
sectionHeader(LocaleKeys.distance.tr(), hint: LocaleKeys.fromYourCurrentLocation.tr()),
|
|
|
|
|
10.height,
|
|
|
|
|
Row(
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
buildOption(LocaleKeys.any.tr(), draftDistance == 'any', () => setSheetState(() => draftDistance = 'any')),
|
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
|
buildOption(LocaleKeys.distanceKm.tr(args: <String>['5']), draftDistance == '5km', () => setSheetState(() => draftDistance = '5km')),
|
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
|
buildOption(LocaleKeys.distanceKm.tr(args: <String>['10']), draftDistance == '10km', () => setSheetState(() => draftDistance = '10km')),
|
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
|
buildOption(LocaleKeys.distanceKm.tr(args: <String>['25']), draftDistance == '25km', () => setSheetState(() => draftDistance = '25km')),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
20.height,
|
|
|
|
|
|
|
|
|
|
// Minimum discount - single select.
|
|
|
|
|
LocaleKeys.minimumDiscount.tr().toText14(isBold: true, color: darkBg),
|
|
|
|
|
10.height,
|
|
|
|
|
Row(
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
buildOption(LocaleKeys.any.tr(), draftMinDiscount == 'any', () => setSheetState(() => draftMinDiscount = 'any')),
|
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
|
buildOption(LocaleKeys.discountPercentPlus.tr(args: <String>['10']), draftMinDiscount == '10', () => setSheetState(() => draftMinDiscount = '10')),
|
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
|
buildOption(LocaleKeys.discountPercentPlus.tr(args: <String>['20']), draftMinDiscount == '20', () => setSheetState(() => draftMinDiscount = '20')),
|
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
|
buildOption(LocaleKeys.discountPercentPlus.tr(args: <String>['30']), draftMinDiscount == '30', () => setSheetState(() => draftMinDiscount = '30')),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
20.height,
|
|
|
|
|
const Divider(height: 1, thickness: 1, color: borderColor),
|
|
|
|
|
16.height,
|
|
|
|
|
|
|
|
|
|
Row(
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
Expanded(
|
|
|
|
|
child: DefaultButton(
|
|
|
|
|
LocaleKeys.reset.tr(),
|
|
|
|
|
() {
|
|
|
|
|
setSheetState(() {
|
|
|
|
|
draftAvailability = 'all';
|
|
|
|
|
draftSortBy = 'newest';
|
|
|
|
|
draftDistance = 'any';
|
|
|
|
|
draftMinDiscount = 'any';
|
|
|
|
|
});
|
|
|
|
|
setState(() {
|
|
|
|
|
selectedTypeFilter = draftAvailability;
|
|
|
|
|
_filterSortBy = draftSortBy;
|
|
|
|
|
_filterDistance = draftDistance;
|
|
|
|
|
_filterMinDiscount = draftMinDiscount;
|
|
|
|
|
});
|
|
|
|
|
Navigator.pop(sheetContext);
|
|
|
|
|
fetchOffers(categoryId: currentCategoryId.isEmpty ? "all" : currentCategoryId);
|
|
|
|
|
},
|
|
|
|
|
colors: const <Color>[Colors.white, Colors.white],
|
|
|
|
|
border: Border.all(color: borderColor),
|
|
|
|
|
textColor: darkBg,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
|
Expanded(
|
|
|
|
|
child: DefaultButton(LocaleKeys.applyFilters.tr(), () {
|
|
|
|
|
setState(() {
|
|
|
|
|
selectedTypeFilter = draftAvailability;
|
|
|
|
|
_filterSortBy = draftSortBy;
|
|
|
|
|
_filterDistance = draftDistance;
|
|
|
|
|
_filterMinDiscount = draftMinDiscount;
|
|
|
|
|
});
|
|
|
|
|
Navigator.pop(sheetContext);
|
|
|
|
|
fetchOffers(categoryId: currentCategoryId.isEmpty ? "all" : currentCategoryId);
|
|
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildCategoryCard(WalaPlusCategoryModel item, bool isSelected) {
|
|
|
|
|
const double cardSize = 84.0;
|
|
|
|
|
const double borderRadiusVal = 18.0;
|
|
|
|
|
|