diff --git a/assets/icons/ic_check1.svg b/assets/icons/ic_check1.svg
new file mode 100644
index 0000000..c984c5c
--- /dev/null
+++ b/assets/icons/ic_check1.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/ic_clock.png b/assets/icons/ic_clock.png
new file mode 100644
index 0000000..6a6769b
Binary files /dev/null and b/assets/icons/ic_clock.png differ
diff --git a/assets/icons/ic_close.svg b/assets/icons/ic_close.svg
new file mode 100644
index 0000000..f64b147
--- /dev/null
+++ b/assets/icons/ic_close.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/icons/ic_current_loc.svg b/assets/icons/ic_current_loc.svg
new file mode 100644
index 0000000..8a94212
--- /dev/null
+++ b/assets/icons/ic_current_loc.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/ic_search.svg b/assets/icons/ic_search.svg
new file mode 100644
index 0000000..40fb2bf
--- /dev/null
+++ b/assets/icons/ic_search.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/translations/app_en.arb b/assets/translations/app_en.arb
index e8782f2..90ec32a 100644
--- a/assets/translations/app_en.arb
+++ b/assets/translations/app_en.arb
@@ -50,7 +50,35 @@
"ride": "Ride",
"chinese": "Chinese",
"dessert": "Dessert",
- "more":"More"
+ "more":"More",
+ "orderDetails": "Order details",
+ "deliverNow": "Deliver now",
+ "schedule": "Schedule",
+ "enterNewAddress": "Enter a new address",
+ "nearby": "Nearby",
+ "currentLocation": "Current location",
+ "enable": "Enable",
+ "recentLocations": "Recent locations",
+ "allFilters": "All filters",
+ "sort": "Sort",
+ "pickedForYou": "Picked for you (default)",
+ "mostPopular": "Most popular",
+ "rating": "Rating",
+ "deliveryTime": "Delivery time",
+ "fromUberEats": "From Uber Eats",
+ "deals": "Deals",
+ "bestOverall": "Best overall",
+ "priceRange": "Price range",
+ "maxDeliveryFee": "Max. Delivery Fee",
+ "dietary": "Dietary",
+ "vegetarian": "Vegetarian",
+ "vegan": "Vegan",
+ "glutenFree": "Gluten-free",
+ "halal": "Halal",
+ "allergyFriendly": "Allergy friendly",
+ "atLeast":"At least",
+ "apply": "Apply"
+
}
\ No newline at end of file
diff --git a/assets/translations/app_ru.arb b/assets/translations/app_ru.arb
index d358b51..e1ea54b 100644
--- a/assets/translations/app_ru.arb
+++ b/assets/translations/app_ru.arb
@@ -57,6 +57,35 @@
"ride": "Поездка",
"chinese": "Китайская",
"dessert": "Десерт",
- "more":"Ещё"
+ "more":"Ещё",
+ "orderDetails": "Детали заказа",
+ "deliverNow": "Доставить сейчас",
+ "schedule": "Запланировать",
+ "enterNewAddress": "Введите новый адрес",
+ "nearby": "Рядом",
+ "currentLocation": "Текущее местоположение",
+ "enable": "Включить",
+ "recentLocations": "Недавние адреса",
+ "allFilters": "Все фильтры",
+ "sort": "Сортировка",
+ "pickedForYou": "Подобрано для вас (по умолчанию)",
+ "mostPopular": "Самые популярные",
+ "rating": "Рейтинг",
+ "deliveryTime": "Время доставки",
+ "fromUberEats": "От Uber Eats",
+ "deals": "Скидки",
+ "bestOverall": "Лучший выбор",
+ "priceRange": "Диапазон цен",
+ "maxDeliveryFee": "Макс. стоимость доставки",
+ "dietary": "Диета",
+ "vegetarian": "Вегетарианское",
+ "vegan": "Веганское",
+ "glutenFree": "Без глютена",
+ "halal": "Халяль",
+ "allergyFriendly": "Без аллергенов",
+ "atLeast":"Kак минимум",
+ "apply": "Применить"
+
+
}
diff --git a/assets/translations/app_uz.arb b/assets/translations/app_uz.arb
index 027eab4..13d32ea 100644
--- a/assets/translations/app_uz.arb
+++ b/assets/translations/app_uz.arb
@@ -57,5 +57,34 @@
"ride": "Yo‘l",
"chinese": "Xitoy",
"dessert": "Desert",
- "more":"Ko'proq"
+ "more":"Ko'proq",
+ "orderDetails": "Buyurtma tafsilotlari",
+ "deliverNow": "Hozir yetkazish",
+ "schedule": "Rejalashtirish",
+ "enterNewAddress": "Yangi manzil kiriting",
+ "nearby": "Yaqin joylar",
+ "currentLocation": "Joriy joylashuv",
+ "enable": "Yoqqish",
+ "recentLocations": "Yaqinda ishlatilgan manzillar",
+ "allFilters": "Barcha filtrlar",
+ "sort": "Saralash",
+ "pickedForYou": "Siz uchun",
+ "mostPopular": "Eng ommabop",
+ "rating": "Reyting",
+ "deliveryTime": "Yetkazib berish vaqti",
+ "fromUberEats": "Uber Eats dan",
+ "deals": "Aksiyalar",
+ "bestOverall": "Eng yaxshisi",
+ "priceRange": "Narx oralig‘i",
+ "maxDeliveryFee": "Maks. yetkazish narxi",
+ "dietary": "Parhez",
+ "vegetarian": "Vegetarian",
+ "vegan": "Vegan",
+ "glutenFree": "Glutensiz",
+ "halal": "Halol",
+ "allergyFriendly": "Allergiyaga mos",
+ "atLeast":"Kаmida",
+ "apply": "Qo‘llash"
+
+
}
diff --git a/lib/core/constants/time_delay_cons.dart b/lib/core/constants/time_delay_cons.dart
index a81b840..b270c00 100644
--- a/lib/core/constants/time_delay_cons.dart
+++ b/lib/core/constants/time_delay_cons.dart
@@ -1,4 +1,5 @@
abstract class TimeDelayConst {
+ static const Duration durationMill150 = Duration(milliseconds: 150);
static const Duration durationMill300 = Duration(milliseconds: 300);
static const Duration durationMill800 = Duration(milliseconds: 800);
diff --git a/lib/core/di/injection_container.config.dart b/lib/core/di/injection_container.config.dart
index 2dd17c2..75fa593 100644
--- a/lib/core/di/injection_container.config.dart
+++ b/lib/core/di/injection_container.config.dart
@@ -31,9 +31,9 @@ extension GetItInjectableX on _i174.GetIt {
_i526.EnvironmentFilter? environmentFilter,
}) {
final gh = _i526.GetItHelper(this, environment, environmentFilter);
+ gh.factory<_i1007.HomeBloc>(() => _i1007.HomeBloc());
gh.factory<_i580.MainBloc>(() => _i580.MainBloc());
gh.factory<_i311.SplashBloc>(() => _i311.SplashBloc());
- gh.factory<_i1007.HomeBloc>(() => _i1007.HomeBloc());
gh.singleton<_i306.StorageService>(() => _i306.StorageService());
gh.singleton<_i152.AppRoutes>(() => _i152.AppRoutes());
gh.factory<_i942.LanguageBloc>(
diff --git a/lib/core/l10n/app_localizations.dart b/lib/core/l10n/app_localizations.dart
index 4262cb9..50461c8 100644
--- a/lib/core/l10n/app_localizations.dart
+++ b/lib/core/l10n/app_localizations.dart
@@ -327,6 +327,162 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'More'**
String get more;
+
+ /// No description provided for @orderDetails.
+ ///
+ /// In en, this message translates to:
+ /// **'Order details'**
+ String get orderDetails;
+
+ /// No description provided for @deliverNow.
+ ///
+ /// In en, this message translates to:
+ /// **'Deliver now'**
+ String get deliverNow;
+
+ /// No description provided for @schedule.
+ ///
+ /// In en, this message translates to:
+ /// **'Schedule'**
+ String get schedule;
+
+ /// No description provided for @enterNewAddress.
+ ///
+ /// In en, this message translates to:
+ /// **'Enter a new address'**
+ String get enterNewAddress;
+
+ /// No description provided for @nearby.
+ ///
+ /// In en, this message translates to:
+ /// **'Nearby'**
+ String get nearby;
+
+ /// No description provided for @currentLocation.
+ ///
+ /// In en, this message translates to:
+ /// **'Current location'**
+ String get currentLocation;
+
+ /// No description provided for @enable.
+ ///
+ /// In en, this message translates to:
+ /// **'Enable'**
+ String get enable;
+
+ /// No description provided for @recentLocations.
+ ///
+ /// In en, this message translates to:
+ /// **'Recent locations'**
+ String get recentLocations;
+
+ /// No description provided for @allFilters.
+ ///
+ /// In en, this message translates to:
+ /// **'All filters'**
+ String get allFilters;
+
+ /// No description provided for @sort.
+ ///
+ /// In en, this message translates to:
+ /// **'Sort'**
+ String get sort;
+
+ /// No description provided for @pickedForYou.
+ ///
+ /// In en, this message translates to:
+ /// **'Picked for you (default)'**
+ String get pickedForYou;
+
+ /// No description provided for @mostPopular.
+ ///
+ /// In en, this message translates to:
+ /// **'Most popular'**
+ String get mostPopular;
+
+ /// No description provided for @rating.
+ ///
+ /// In en, this message translates to:
+ /// **'Rating'**
+ String get rating;
+
+ /// No description provided for @deliveryTime.
+ ///
+ /// In en, this message translates to:
+ /// **'Delivery time'**
+ String get deliveryTime;
+
+ /// No description provided for @fromUberEats.
+ ///
+ /// In en, this message translates to:
+ /// **'From Uber Eats'**
+ String get fromUberEats;
+
+ /// No description provided for @deals.
+ ///
+ /// In en, this message translates to:
+ /// **'Deals'**
+ String get deals;
+
+ /// No description provided for @bestOverall.
+ ///
+ /// In en, this message translates to:
+ /// **'Best overall'**
+ String get bestOverall;
+
+ /// No description provided for @priceRange.
+ ///
+ /// In en, this message translates to:
+ /// **'Price range'**
+ String get priceRange;
+
+ /// No description provided for @maxDeliveryFee.
+ ///
+ /// In en, this message translates to:
+ /// **'Max. Delivery Fee'**
+ String get maxDeliveryFee;
+
+ /// No description provided for @dietary.
+ ///
+ /// In en, this message translates to:
+ /// **'Dietary'**
+ String get dietary;
+
+ /// No description provided for @vegetarian.
+ ///
+ /// In en, this message translates to:
+ /// **'Vegetarian'**
+ String get vegetarian;
+
+ /// No description provided for @vegan.
+ ///
+ /// In en, this message translates to:
+ /// **'Vegan'**
+ String get vegan;
+
+ /// No description provided for @glutenFree.
+ ///
+ /// In en, this message translates to:
+ /// **'Gluten-free'**
+ String get glutenFree;
+
+ /// No description provided for @allergyFriendly.
+ ///
+ /// In en, this message translates to:
+ /// **'Allergy friendly'**
+ String get allergyFriendly;
+
+ /// No description provided for @atLeast.
+ ///
+ /// In en, this message translates to:
+ /// **'At least'**
+ String get atLeast;
+
+ /// No description provided for @apply.
+ ///
+ /// In en, this message translates to:
+ /// **'Apply'**
+ String get apply;
}
class _AppLocalizationsDelegate
diff --git a/lib/core/l10n/app_localizations_en.dart b/lib/core/l10n/app_localizations_en.dart
index b931f9e..c141639 100644
--- a/lib/core/l10n/app_localizations_en.dart
+++ b/lib/core/l10n/app_localizations_en.dart
@@ -126,4 +126,82 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get more => 'More';
+
+ @override
+ String get orderDetails => 'Order details';
+
+ @override
+ String get deliverNow => 'Deliver now';
+
+ @override
+ String get schedule => 'Schedule';
+
+ @override
+ String get enterNewAddress => 'Enter a new address';
+
+ @override
+ String get nearby => 'Nearby';
+
+ @override
+ String get currentLocation => 'Current location';
+
+ @override
+ String get enable => 'Enable';
+
+ @override
+ String get recentLocations => 'Recent locations';
+
+ @override
+ String get allFilters => 'All filters';
+
+ @override
+ String get sort => 'Sort';
+
+ @override
+ String get pickedForYou => 'Picked for you (default)';
+
+ @override
+ String get mostPopular => 'Most popular';
+
+ @override
+ String get rating => 'Rating';
+
+ @override
+ String get deliveryTime => 'Delivery time';
+
+ @override
+ String get fromUberEats => 'From Uber Eats';
+
+ @override
+ String get deals => 'Deals';
+
+ @override
+ String get bestOverall => 'Best overall';
+
+ @override
+ String get priceRange => 'Price range';
+
+ @override
+ String get maxDeliveryFee => 'Max. Delivery Fee';
+
+ @override
+ String get dietary => 'Dietary';
+
+ @override
+ String get vegetarian => 'Vegetarian';
+
+ @override
+ String get vegan => 'Vegan';
+
+ @override
+ String get glutenFree => 'Gluten-free';
+
+ @override
+ String get allergyFriendly => 'Allergy friendly';
+
+ @override
+ String get atLeast => 'At least';
+
+ @override
+ String get apply => 'Apply';
}
diff --git a/lib/core/l10n/app_localizations_ru.dart b/lib/core/l10n/app_localizations_ru.dart
index 3798ca9..62a46fa 100644
--- a/lib/core/l10n/app_localizations_ru.dart
+++ b/lib/core/l10n/app_localizations_ru.dart
@@ -127,4 +127,82 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get more => 'Ещё';
+
+ @override
+ String get orderDetails => 'Детали заказа';
+
+ @override
+ String get deliverNow => 'Доставить сейчас';
+
+ @override
+ String get schedule => 'Запланировать';
+
+ @override
+ String get enterNewAddress => 'Введите новый адрес';
+
+ @override
+ String get nearby => 'Рядом';
+
+ @override
+ String get currentLocation => 'Текущее местоположение';
+
+ @override
+ String get enable => 'Включить';
+
+ @override
+ String get recentLocations => 'Недавние адреса';
+
+ @override
+ String get allFilters => 'Все фильтры';
+
+ @override
+ String get sort => 'Сортировка';
+
+ @override
+ String get pickedForYou => 'Подобрано для вас (по умолчанию)';
+
+ @override
+ String get mostPopular => 'Самые популярные';
+
+ @override
+ String get rating => 'Рейтинг';
+
+ @override
+ String get deliveryTime => 'Время доставки';
+
+ @override
+ String get fromUberEats => 'От Uber Eats';
+
+ @override
+ String get deals => 'Скидки';
+
+ @override
+ String get bestOverall => 'Лучший выбор';
+
+ @override
+ String get priceRange => 'Диапазон цен';
+
+ @override
+ String get maxDeliveryFee => 'Макс. стоимость доставки';
+
+ @override
+ String get dietary => 'Диета';
+
+ @override
+ String get vegetarian => 'Вегетарианское';
+
+ @override
+ String get vegan => 'Веганское';
+
+ @override
+ String get glutenFree => 'Без глютена';
+
+ @override
+ String get allergyFriendly => 'Без аллергенов';
+
+ @override
+ String get atLeast => 'Kак минимум';
+
+ @override
+ String get apply => 'Применить';
}
diff --git a/lib/core/l10n/app_localizations_uz.dart b/lib/core/l10n/app_localizations_uz.dart
index 4f53b63..323e137 100644
--- a/lib/core/l10n/app_localizations_uz.dart
+++ b/lib/core/l10n/app_localizations_uz.dart
@@ -127,4 +127,82 @@ class AppLocalizationsUz extends AppLocalizations {
@override
String get more => 'Ko\'proq';
+
+ @override
+ String get orderDetails => 'Buyurtma tafsilotlari';
+
+ @override
+ String get deliverNow => 'Hozir yetkazish';
+
+ @override
+ String get schedule => 'Rejalashtirish';
+
+ @override
+ String get enterNewAddress => 'Yangi manzil kiriting';
+
+ @override
+ String get nearby => 'Yaqin joylar';
+
+ @override
+ String get currentLocation => 'Joriy joylashuv';
+
+ @override
+ String get enable => 'Yoqqish';
+
+ @override
+ String get recentLocations => 'Yaqinda ishlatilgan manzillar';
+
+ @override
+ String get allFilters => 'Barcha filtrlar';
+
+ @override
+ String get sort => 'Saralash';
+
+ @override
+ String get pickedForYou => 'Siz uchun';
+
+ @override
+ String get mostPopular => 'Eng ommabop';
+
+ @override
+ String get rating => 'Reyting';
+
+ @override
+ String get deliveryTime => 'Yetkazib berish vaqti';
+
+ @override
+ String get fromUberEats => 'Uber Eats dan';
+
+ @override
+ String get deals => 'Aksiyalar';
+
+ @override
+ String get bestOverall => 'Eng yaxshisi';
+
+ @override
+ String get priceRange => 'Narx oralig‘i';
+
+ @override
+ String get maxDeliveryFee => 'Maks. yetkazish narxi';
+
+ @override
+ String get dietary => 'Parhez';
+
+ @override
+ String get vegetarian => 'Vegetarian';
+
+ @override
+ String get vegan => 'Vegan';
+
+ @override
+ String get glutenFree => 'Glutensiz';
+
+ @override
+ String get allergyFriendly => 'Allergiyaga mos';
+
+ @override
+ String get atLeast => 'Kаmida';
+
+ @override
+ String get apply => 'Qo‘llash';
}
diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart
index 0774c90..c424557 100644
--- a/lib/core/theme/app_colors.dart
+++ b/lib/core/theme/app_colors.dart
@@ -3,6 +3,8 @@ import '../../food_delivery_client.dart';
abstract class AppColors {
static const Color cTransparent = Colors.transparent;
static const Color cRed = Colors.red;
+ static const Color cYellow = Colors.yellow;
+
static const Color cFFFFFF = Color(0xFFFFFFFF);
static const Color c000000 = Color(0xFF000000);
diff --git a/lib/core/theme/app_icons.dart b/lib/core/theme/app_icons.dart
index 9b53a26..deb75d5 100644
--- a/lib/core/theme/app_icons.dart
+++ b/lib/core/theme/app_icons.dart
@@ -23,5 +23,24 @@ abstract class AppIcons {
static const String icLocation = "$baseUrl/ic_location.svg";
static const String icArrowBottom = "$baseUrl/ic_arrow_btm.svg";
+ static const String icPicked = "$baseUrl/ic_picked.svg";
+ static const String icMostPopular = "$baseUrl/ic_popular.svg";
+ static const String icStar = "$baseUrl/ic_rating.svg";
+ static const String icDeliveryTime = "$baseUrl/ic_delivery_time.svg";
+ static const String icDeals = "$baseUrl/ic_deals.svg";
+ static const String icClose = "$baseUrl/ic_close.svg";
+ static const String icCurrentLocation = "$baseUrl/ic_current_loc.svg";
+ static const String icEdit = "$baseUrl/ic_edit.svg";
+ static const String icSearch = "$baseUrl/ic_search.svg";
+ static const String icCheck= "$baseUrl/ic_check.svg";
+ static const String icCheck1= "$baseUrl/ic_check1.svg";
+
+
///.png icons
+ static const String icBestOverall = "$baseUrl/ic_best.png";
+ static const String icVegetarian = "$baseUrl/ic_vegetarian.png";
+ static const String icVegen = "$baseUrl/ic_vegen.png";
+ static const String icGlutenFree = "$baseUrl/ic_gluten_free.png";
+ static const String icAllergyFriendly = "$baseUrl/ic_allergy_friendly.png";
+ static const String icClock = "$baseUrl/ic_clock.png";
}
diff --git a/lib/core/theme/app_textstyles.dart b/lib/core/theme/app_textstyles.dart
index 7eaa8a5..99b8a00 100644
--- a/lib/core/theme/app_textstyles.dart
+++ b/lib/core/theme/app_textstyles.dart
@@ -63,6 +63,20 @@ abstract class AppTextStyles {
fontWeight: FontWeight.w500,
);
+ static const TextStyle size20Medium = TextStyle(
+ color: _defaultColor,
+ fontSize: SizesCons.size_20,
+ fontFamily: _fontMedium,
+ fontWeight: FontWeight.w500,
+ );
+
+ static const TextStyle size16Bold= TextStyle(
+ color: _defaultColor,
+ fontSize: SizesCons.size_16,
+ fontFamily: _fontBold,
+ fontWeight: FontWeight.w700,
+ );
+
static const TextStyle size17Bold = TextStyle(
color: _defaultColor,
fontSize: SizesCons.size_17,
diff --git a/lib/core/utils/app_utils.dart b/lib/core/utils/app_utils.dart
index 773c076..cb447f7 100644
--- a/lib/core/utils/app_utils.dart
+++ b/lib/core/utils/app_utils.dart
@@ -1,6 +1,8 @@
import '../../food_delivery_client.dart';
abstract class AppUtils {
+ static const SizedBox kSizedBox = SizedBox.shrink();
+
static const Radius kRadius = Radius.zero;
static const Radius kRadius8 = Radius.circular(8);
static const Radius kRadius12 = Radius.circular(12);
@@ -79,6 +81,10 @@ abstract class AppUtils {
static const BorderRadius kBorderRadius40 = BorderRadius.all(
Radius.circular(40),
);
+ static const BorderRadius kBorderRadiusTop20 = BorderRadius.only(
+ topLeft: kRadius20,
+ topRight: kRadius20,
+ );
static const BorderRadius kBorderRadiusTop20Bottom20 = BorderRadius.only(
bottomRight: kRadius20,
topRight: kRadius20,
diff --git a/lib/feature/common/presentation/widgets/app_button.dart b/lib/feature/common/presentation/widgets/app_button.dart
new file mode 100644
index 0000000..6bb5f46
--- /dev/null
+++ b/lib/feature/common/presentation/widgets/app_button.dart
@@ -0,0 +1,61 @@
+
+import '../../../../food_delivery_client.dart';
+
+
+class AppButton extends StatelessWidget {
+ const AppButton({
+ super.key,
+ required this.name,
+ required this.onPressed,
+ this.margin,
+ this.backgroundColor,
+ this.borderRadius,
+ this.height,
+ this.textColor,
+ this.width,
+ this.action,
+ this.trailing,
+ this.mainAxisAlignment,
+ });
+
+ final String name;
+ final VoidCallback onPressed;
+ final EdgeInsets? margin;
+ final Color? backgroundColor;
+ final Color? textColor;
+ final double? borderRadius;
+ final double? width;
+ final double? height;
+ final Widget? action;
+ final Widget? trailing;
+ final MainAxisAlignment? mainAxisAlignment;
+
+ @override
+ Widget build(BuildContext context) {
+ return Bounceable(
+ onTap: onPressed,
+ duration: TimeDelayConst.durationMill150,
+ child: Container(
+ width: width ?? double.infinity,
+ height: height ?? 55,
+ margin: margin,
+ alignment: Alignment.center,
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ decoration: BoxDecoration(
+ color: backgroundColor ?? AppColors.c000000,
+ borderRadius: BorderRadius.circular(borderRadius ?? 0),
+ ),
+ child: Row(
+ mainAxisAlignment: mainAxisAlignment ?? MainAxisAlignment.center,
+ children: [
+ action ?? AppUtils.kSizedBox,
+ Text(name, style: AppTextStyles.size16Bold.copyWith(
+ color: AppColors.cFFFFFF
+ )),
+ trailing ?? AppUtils.kSizedBox,
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/feature/common/presentation/widgets/w_custom_modal_bottom_sheet.dart b/lib/feature/common/presentation/widgets/w_custom_modal_bottom_sheet.dart
new file mode 100644
index 0000000..de320a6
--- /dev/null
+++ b/lib/feature/common/presentation/widgets/w_custom_modal_bottom_sheet.dart
@@ -0,0 +1,37 @@
+import '../../../../../../food_delivery_client.dart';
+
+class WCustomModalBottomSheet extends StatelessWidget {
+ const WCustomModalBottomSheet({super.key, required this.child});
+
+ final Widget child;
+
+ @override
+ Widget build(BuildContext context) {
+ return Material(
+ color: AppColors.cFFFFFF,
+ borderRadius: AppUtils.kBorderRadiusTop20,
+ child: SafeArea(
+ child: SizedBox(
+ width: context.w,
+ child: Column(
+ children: [
+ 10.verticalSpace,
+ SizedBox(
+ height: 6,
+ width: 100,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ borderRadius: AppUtils.kBorderRadius6,
+ color: AppColors.cE6E6E6.newWithOpacity(.6),
+ ),
+ ),
+ ),
+ 10.verticalSpace,
+ child,
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/feature/common/presentation/widgets/widgets.dart b/lib/feature/common/presentation/widgets/widgets.dart
index 8de4376..6261541 100644
--- a/lib/feature/common/presentation/widgets/widgets.dart
+++ b/lib/feature/common/presentation/widgets/widgets.dart
@@ -3,3 +3,5 @@ export 'w_food_item.dart';
export 'w_divider.dart';
export 'w_see_all_raw.dart';
export 'w_stories_list_item.dart';
+export 'w_custom_modal_bottom_sheet.dart';
+export 'app_button.dart';
diff --git a/lib/feature/home/home.dart b/lib/feature/home/home.dart
index be74602..31cbfa3 100644
--- a/lib/feature/home/home.dart
+++ b/lib/feature/home/home.dart
@@ -9,3 +9,6 @@ export 'presentation/pages/home_page/widgets/w_offers_carouseL_slider.dart';
export 'presentation/pages/home_page/widgets/w_popular_near_you.dart';
export 'presentation/pages/home_page/widgets/w_todays_offers.dart';
export 'package:food_delivery_client/feature/home/presentation/pages/home_page/widgets/pick_it_for_free.dart';
+export 'package:flutter_svg/flutter_svg.dart';
+export 'package:food_delivery_client/feature/home/presentation/pages/categories_page/categories_page.dart';
+export 'package:food_delivery_client/feature/home/presentation/pages/home_page/widgets/w_rating_btm_sheet.dart';
diff --git a/lib/feature/home/presentation/blocs/home_bloc/home_bloc.dart b/lib/feature/home/presentation/blocs/home_bloc/home_bloc.dart
index 1f98db5..efb321f 100644
--- a/lib/feature/home/presentation/blocs/home_bloc/home_bloc.dart
+++ b/lib/feature/home/presentation/blocs/home_bloc/home_bloc.dart
@@ -5,13 +5,33 @@ part 'home_event.dart';
part 'home_state.dart';
part 'home_bloc.freezed.dart';
+
@injectable
class HomeBloc extends Bloc {
HomeBloc() : super(const HomeState()) {
on<_Changed>(_onChanged);
+ on<_Filtered>(_onFiltered);
+ on<_Rated>(_onRated);
}
void _onChanged(_Changed event, Emitter emit) {
emit(state.copyWith(currentIndex: event.index));
}
+
+ void _onFiltered(_Filtered event, Emitter emit) {
+ final oldFilters = List.from(state.filters);
+ if (oldFilters.contains(event.filter)) {
+ final newFilters = oldFilters..remove(event.filter);
+ emit(state.copyWith(filters: newFilters));
+ } else {
+ final newFilters = oldFilters..add(event.filter);
+ emit(state.copyWith(filters: newFilters));
+ }
+ }
+
+
+ void _onRated(_Rated event, Emitter emit){
+ emit(state.copyWith(rating: event.filter));
+
+ }
}
diff --git a/lib/feature/home/presentation/blocs/home_bloc/home_bloc.freezed.dart b/lib/feature/home/presentation/blocs/home_bloc/home_bloc.freezed.dart
index 3365c1f..718c3ca 100644
--- a/lib/feature/home/presentation/blocs/home_bloc/home_bloc.freezed.dart
+++ b/lib/feature/home/presentation/blocs/home_bloc/home_bloc.freezed.dart
@@ -55,12 +55,14 @@ extension HomeEventPatterns on HomeEvent {
/// }
/// ```
-@optionalTypeArgs TResult maybeMap({TResult Function( _Started value)? started,TResult Function( _Changed value)? changed,required TResult orElse(),}){
+@optionalTypeArgs TResult maybeMap({TResult Function( _Started value)? started,TResult Function( _Changed value)? changed,TResult Function( _Filtered value)? filtered,TResult Function( _Rated value)? rated,required TResult orElse(),}){
final _that = this;
switch (_that) {
case _Started() when started != null:
return started(_that);case _Changed() when changed != null:
-return changed(_that);case _:
+return changed(_that);case _Filtered() when filtered != null:
+return filtered(_that);case _Rated() when rated != null:
+return rated(_that);case _:
return orElse();
}
@@ -78,12 +80,14 @@ return changed(_that);case _:
/// }
/// ```
-@optionalTypeArgs TResult map({required TResult Function( _Started value) started,required TResult Function( _Changed value) changed,}){
+@optionalTypeArgs TResult map({required TResult Function( _Started value) started,required TResult Function( _Changed value) changed,required TResult Function( _Filtered value) filtered,required TResult Function( _Rated value) rated,}){
final _that = this;
switch (_that) {
case _Started():
return started(_that);case _Changed():
-return changed(_that);case _:
+return changed(_that);case _Filtered():
+return filtered(_that);case _Rated():
+return rated(_that);case _:
throw StateError('Unexpected subclass');
}
@@ -100,12 +104,14 @@ return changed(_that);case _:
/// }
/// ```
-@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Started value)? started,TResult? Function( _Changed value)? changed,}){
+@optionalTypeArgs TResult? mapOrNull({TResult? Function( _Started value)? started,TResult? Function( _Changed value)? changed,TResult? Function( _Filtered value)? filtered,TResult? Function( _Rated value)? rated,}){
final _that = this;
switch (_that) {
case _Started() when started != null:
return started(_that);case _Changed() when changed != null:
-return changed(_that);case _:
+return changed(_that);case _Filtered() when filtered != null:
+return filtered(_that);case _Rated() when rated != null:
+return rated(_that);case _:
return null;
}
@@ -122,11 +128,13 @@ return changed(_that);case _:
/// }
/// ```
-@optionalTypeArgs TResult maybeWhen({TResult Function()? started,TResult Function( int index)? changed,required TResult orElse(),}) {final _that = this;
+@optionalTypeArgs TResult maybeWhen({TResult Function()? started,TResult Function( int index)? changed,TResult Function( String filter)? filtered,TResult Function( List filter)? rated,required TResult orElse(),}) {final _that = this;
switch (_that) {
case _Started() when started != null:
return started();case _Changed() when changed != null:
-return changed(_that.index);case _:
+return changed(_that.index);case _Filtered() when filtered != null:
+return filtered(_that.filter);case _Rated() when rated != null:
+return rated(_that.filter);case _:
return orElse();
}
@@ -144,11 +152,13 @@ return changed(_that.index);case _:
/// }
/// ```
-@optionalTypeArgs TResult when({required TResult Function() started,required TResult Function( int index) changed,}) {final _that = this;
+@optionalTypeArgs TResult when({required TResult Function() started,required TResult Function( int index) changed,required TResult Function( String filter) filtered,required TResult Function( List filter) rated,}) {final _that = this;
switch (_that) {
case _Started():
return started();case _Changed():
-return changed(_that.index);case _:
+return changed(_that.index);case _Filtered():
+return filtered(_that.filter);case _Rated():
+return rated(_that.filter);case _:
throw StateError('Unexpected subclass');
}
@@ -165,11 +175,13 @@ return changed(_that.index);case _:
/// }
/// ```
-@optionalTypeArgs TResult? whenOrNull({TResult? Function()? started,TResult? Function( int index)? changed,}) {final _that = this;
+@optionalTypeArgs TResult? whenOrNull({TResult? Function()? started,TResult? Function( int index)? changed,TResult? Function( String filter)? filtered,TResult? Function( List filter)? rated,}) {final _that = this;
switch (_that) {
case _Started() when started != null:
return started();case _Changed() when changed != null:
-return changed(_that.index);case _:
+return changed(_that.index);case _Filtered() when filtered != null:
+return filtered(_that.filter);case _Rated() when rated != null:
+return rated(_that.filter);case _:
return null;
}
@@ -273,12 +285,150 @@ as int,
}
+}
+
+/// @nodoc
+
+
+class _Filtered implements HomeEvent {
+ const _Filtered(this.filter);
+
+
+ final String filter;
+
+/// Create a copy of HomeEvent
+/// with the given fields replaced by the non-null parameter values.
+@JsonKey(includeFromJson: false, includeToJson: false)
+@pragma('vm:prefer-inline')
+_$FilteredCopyWith<_Filtered> get copyWith => __$FilteredCopyWithImpl<_Filtered>(this, _$identity);
+
+
+
+@override
+bool operator ==(Object other) {
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is _Filtered&&(identical(other.filter, filter) || other.filter == filter));
+}
+
+
+@override
+int get hashCode => Object.hash(runtimeType,filter);
+
+@override
+String toString() {
+ return 'HomeEvent.filtered(filter: $filter)';
+}
+
+
+}
+
+/// @nodoc
+abstract mixin class _$FilteredCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
+ factory _$FilteredCopyWith(_Filtered value, $Res Function(_Filtered) _then) = __$FilteredCopyWithImpl;
+@useResult
+$Res call({
+ String filter
+});
+
+
+
+
+}
+/// @nodoc
+class __$FilteredCopyWithImpl<$Res>
+ implements _$FilteredCopyWith<$Res> {
+ __$FilteredCopyWithImpl(this._self, this._then);
+
+ final _Filtered _self;
+ final $Res Function(_Filtered) _then;
+
+/// Create a copy of HomeEvent
+/// with the given fields replaced by the non-null parameter values.
+@pragma('vm:prefer-inline') $Res call({Object? filter = null,}) {
+ return _then(_Filtered(
+null == filter ? _self.filter : filter // ignore: cast_nullable_to_non_nullable
+as String,
+ ));
+}
+
+
+}
+
+/// @nodoc
+
+
+class _Rated implements HomeEvent {
+ const _Rated(final List filter): _filter = filter;
+
+
+ final List _filter;
+ List get filter {
+ if (_filter is EqualUnmodifiableListView) return _filter;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_filter);
+}
+
+
+/// Create a copy of HomeEvent
+/// with the given fields replaced by the non-null parameter values.
+@JsonKey(includeFromJson: false, includeToJson: false)
+@pragma('vm:prefer-inline')
+_$RatedCopyWith<_Rated> get copyWith => __$RatedCopyWithImpl<_Rated>(this, _$identity);
+
+
+
+@override
+bool operator ==(Object other) {
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is _Rated&&const DeepCollectionEquality().equals(other._filter, _filter));
+}
+
+
+@override
+int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_filter));
+
+@override
+String toString() {
+ return 'HomeEvent.rated(filter: $filter)';
+}
+
+
+}
+
+/// @nodoc
+abstract mixin class _$RatedCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
+ factory _$RatedCopyWith(_Rated value, $Res Function(_Rated) _then) = __$RatedCopyWithImpl;
+@useResult
+$Res call({
+ List filter
+});
+
+
+
+
+}
+/// @nodoc
+class __$RatedCopyWithImpl<$Res>
+ implements _$RatedCopyWith<$Res> {
+ __$RatedCopyWithImpl(this._self, this._then);
+
+ final _Rated _self;
+ final $Res Function(_Rated) _then;
+
+/// Create a copy of HomeEvent
+/// with the given fields replaced by the non-null parameter values.
+@pragma('vm:prefer-inline') $Res call({Object? filter = null,}) {
+ return _then(_Rated(
+null == filter ? _self._filter : filter // ignore: cast_nullable_to_non_nullable
+as List,
+ ));
+}
+
+
}
/// @nodoc
mixin _$HomeState {
- int get currentIndex;
+ int get currentIndex; List get filters; List get rating;
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -289,16 +439,16 @@ $HomeStateCopyWith get copyWith => _$HomeStateCopyWithImpl
@override
bool operator ==(Object other) {
- return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex));
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&const DeepCollectionEquality().equals(other.filters, filters)&&const DeepCollectionEquality().equals(other.rating, rating));
}
@override
-int get hashCode => Object.hash(runtimeType,currentIndex);
+int get hashCode => Object.hash(runtimeType,currentIndex,const DeepCollectionEquality().hash(filters),const DeepCollectionEquality().hash(rating));
@override
String toString() {
- return 'HomeState(currentIndex: $currentIndex)';
+ return 'HomeState(currentIndex: $currentIndex, filters: $filters, rating: $rating)';
}
@@ -309,7 +459,7 @@ abstract mixin class $HomeStateCopyWith<$Res> {
factory $HomeStateCopyWith(HomeState value, $Res Function(HomeState) _then) = _$HomeStateCopyWithImpl;
@useResult
$Res call({
- int currentIndex
+ int currentIndex, List filters, List rating
});
@@ -326,10 +476,12 @@ class _$HomeStateCopyWithImpl<$Res>
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
-@pragma('vm:prefer-inline') @override $Res call({Object? currentIndex = null,}) {
+@pragma('vm:prefer-inline') @override $Res call({Object? currentIndex = null,Object? filters = null,Object? rating = null,}) {
return _then(_self.copyWith(
currentIndex: null == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
-as int,
+as int,filters: null == filters ? _self.filters : filters // ignore: cast_nullable_to_non_nullable
+as List,rating: null == rating ? _self.rating : rating // ignore: cast_nullable_to_non_nullable
+as List,
));
}
@@ -414,10 +566,10 @@ return $default(_that);case _:
/// }
/// ```
-@optionalTypeArgs TResult maybeWhen(TResult Function( int currentIndex)? $default,{required TResult orElse(),}) {final _that = this;
+@optionalTypeArgs TResult maybeWhen(TResult Function( int currentIndex, List filters, List rating)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _HomeState() when $default != null:
-return $default(_that.currentIndex);case _:
+return $default(_that.currentIndex,_that.filters,_that.rating);case _:
return orElse();
}
@@ -435,10 +587,10 @@ return $default(_that.currentIndex);case _:
/// }
/// ```
-@optionalTypeArgs TResult when(TResult Function( int currentIndex) $default,) {final _that = this;
+@optionalTypeArgs TResult when(TResult Function( int currentIndex, List filters, List rating) $default,) {final _that = this;
switch (_that) {
case _HomeState():
-return $default(_that.currentIndex);case _:
+return $default(_that.currentIndex,_that.filters,_that.rating);case _:
throw StateError('Unexpected subclass');
}
@@ -455,10 +607,10 @@ return $default(_that.currentIndex);case _:
/// }
/// ```
-@optionalTypeArgs TResult? whenOrNull(TResult? Function( int currentIndex)? $default,) {final _that = this;
+@optionalTypeArgs TResult? whenOrNull(TResult? Function( int currentIndex, List filters, List rating)? $default,) {final _that = this;
switch (_that) {
case _HomeState() when $default != null:
-return $default(_that.currentIndex);case _:
+return $default(_that.currentIndex,_that.filters,_that.rating);case _:
return null;
}
@@ -470,10 +622,24 @@ return $default(_that.currentIndex);case _:
class _HomeState implements HomeState {
- const _HomeState({this.currentIndex = 0});
+ const _HomeState({this.currentIndex = 0, final List filters = const [], final List rating = const []}): _filters = filters,_rating = rating;
@override@JsonKey() final int currentIndex;
+ final List _filters;
+@override@JsonKey() List get filters {
+ if (_filters is EqualUnmodifiableListView) return _filters;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_filters);
+}
+
+ final List _rating;
+@override@JsonKey() List get rating {
+ if (_rating is EqualUnmodifiableListView) return _rating;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_rating);
+}
+
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
@@ -485,16 +651,16 @@ _$HomeStateCopyWith<_HomeState> get copyWith => __$HomeStateCopyWithImpl<_HomeSt
@override
bool operator ==(Object other) {
- return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex));
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&const DeepCollectionEquality().equals(other._filters, _filters)&&const DeepCollectionEquality().equals(other._rating, _rating));
}
@override
-int get hashCode => Object.hash(runtimeType,currentIndex);
+int get hashCode => Object.hash(runtimeType,currentIndex,const DeepCollectionEquality().hash(_filters),const DeepCollectionEquality().hash(_rating));
@override
String toString() {
- return 'HomeState(currentIndex: $currentIndex)';
+ return 'HomeState(currentIndex: $currentIndex, filters: $filters, rating: $rating)';
}
@@ -505,7 +671,7 @@ abstract mixin class _$HomeStateCopyWith<$Res> implements $HomeStateCopyWith<$Re
factory _$HomeStateCopyWith(_HomeState value, $Res Function(_HomeState) _then) = __$HomeStateCopyWithImpl;
@override @useResult
$Res call({
- int currentIndex
+ int currentIndex, List filters, List rating
});
@@ -522,10 +688,12 @@ class __$HomeStateCopyWithImpl<$Res>
/// Create a copy of HomeState
/// with the given fields replaced by the non-null parameter values.
-@override @pragma('vm:prefer-inline') $Res call({Object? currentIndex = null,}) {
+@override @pragma('vm:prefer-inline') $Res call({Object? currentIndex = null,Object? filters = null,Object? rating = null,}) {
return _then(_HomeState(
currentIndex: null == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
-as int,
+as int,filters: null == filters ? _self._filters : filters // ignore: cast_nullable_to_non_nullable
+as List,rating: null == rating ? _self._rating : rating // ignore: cast_nullable_to_non_nullable
+as List,
));
}
diff --git a/lib/feature/home/presentation/blocs/home_bloc/home_event.dart b/lib/feature/home/presentation/blocs/home_bloc/home_event.dart
index 051abcd..1a4661f 100644
--- a/lib/feature/home/presentation/blocs/home_bloc/home_event.dart
+++ b/lib/feature/home/presentation/blocs/home_bloc/home_event.dart
@@ -4,5 +4,7 @@ part of 'home_bloc.dart';
class HomeEvent with _$HomeEvent {
const factory HomeEvent.started() = _Started;
const factory HomeEvent.changed(int index) = _Changed;
+ const factory HomeEvent.filtered(String filter) = _Filtered;
+ const factory HomeEvent.rated(List filter) = _Rated;
}
diff --git a/lib/feature/home/presentation/blocs/home_bloc/home_state.dart b/lib/feature/home/presentation/blocs/home_bloc/home_state.dart
index 2890caf..280762b 100644
--- a/lib/feature/home/presentation/blocs/home_bloc/home_state.dart
+++ b/lib/feature/home/presentation/blocs/home_bloc/home_state.dart
@@ -3,6 +3,9 @@ part of 'home_bloc.dart';
@freezed
abstract class HomeState with _$HomeState {
const factory HomeState({
- @Default(0) int currentIndex
-}) = _HomeState;
+ @Default(0) int currentIndex,
+ @Default([]) List filters,
+ @Default([]) List rating
+
+ }) = _HomeState;
}
diff --git a/lib/feature/home/presentation/pages/home_page/widgets/w_delivery_header.dart b/lib/feature/home/presentation/pages/home_page/widgets/w_delivery_header.dart
index 87839a6..8908fac 100644
--- a/lib/feature/home/presentation/pages/home_page/widgets/w_delivery_header.dart
+++ b/lib/feature/home/presentation/pages/home_page/widgets/w_delivery_header.dart
@@ -1,5 +1,3 @@
-import 'package:food_delivery_client/feature/home/presentation/pages/categories_page/categories_page.dart';
-
import '../../../../../../food_delivery_client.dart';
class WDeliveryHeader extends StatelessWidget {
@@ -13,55 +11,167 @@ class WDeliveryHeader extends StatelessWidget {
context.loc.petSupplies,
context.loc.more,
];
- return Column(
- children: [
- 15.verticalSpace,
- Row(
- spacing: 12,
+ /*
+ Siz uchun
+ Eng ommabop,
+ Reyting
+ Yetkazib berish vaqti,
+ Aksiyalar
+
+
+ */
+ List titles = [
+ '',
+ context.loc.pickedForYou,
+ context.loc.mostPopular,
+ context.loc.rating,
+ context.loc.deliveryTime,
+ context.loc.deals,
+ ];
+ return BlocBuilder(
+ builder: (context, state) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- WCategoriesHeaderItem(
- onTap: () {},
- text: context.loc.american,
- imageUrl: AppImages.imgAmerican,
- ),
- WCategoriesHeaderItem(
- onTap: () {},
- text: context.loc.grocery,
- imageUrl: AppImages.imgGrocery,
+ Column(
+ children: [
+ 15.verticalSpace,
+ Row(
+ spacing: 12,
+ children: [
+ WCategoriesHeaderItem(
+ onTap: () {},
+ text: context.loc.american,
+ imageUrl: AppImages.imgAmerican,
+ ),
+ WCategoriesHeaderItem(
+ onTap: () {},
+ text: context.loc.grocery,
+ imageUrl: AppImages.imgGrocery,
+ ),
+ ],
+ ),
+ 8.verticalSpace,
+ GridView.builder(
+ shrinkWrap: true,
+ itemCount: _titles.length,
+ padding: EdgeInsets.zero,
+ scrollDirection: Axis.vertical,
+ physics: const NeverScrollableScrollPhysics(),
+ keyboardDismissBehavior:
+ ScrollViewKeyboardDismissBehavior.onDrag,
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 4,
+ crossAxisSpacing: 5,
+ mainAxisSpacing: 10,
+ mainAxisExtent: 118,
+ // childAspectRatio: 78 / 100,
+ ),
+ itemBuilder: (context, index) => WCategoryItem(
+ onTap: () {
+ if (index == 3) {
+ CategoriesPage().show(context);
+ }
+ },
+ imgUrl: index != 3 ? _images[index] : null,
+ text: _titles[index],
+ child: index == 3
+ ? SizedBox(
+ height: 55,
+ width: 55,
+ child: Icon(Icons.more_horiz),
+ )
+ : null,
+ ),
+ ),
+ ],
+ ).paddingSymmetric(horizontal: 15),
+ 15.verticalSpace,
+
+ SizedBox(
+ height: 40,
+ child: ListView.separated(
+ padding: EdgeInsets.symmetric(horizontal: 15),
+ scrollDirection: Axis.horizontal,
+ itemCount: titles.length,
+ physics: const AlwaysScrollableScrollPhysics(),
+ separatorBuilder: (context, index) => 10.horizontalSpace,
+ itemBuilder: (context, index) => InkWell(
+ onTap: () async {
+ if (index != 3 && index != 0) {
+ context.read().add(
+ HomeEvent.filtered(titles[index]),
+ );
+ }
+
+ if (index == 3) {
+ final response = await WRatingBottomSheet(
+ savedRatings: state.rating ?? [],
+ ).show(context);
+
+ if (response != null) {
+ context.read().add(
+ HomeEvent.rated(response ?? []),
+ );
+ }
+ }
+ },
+ borderRadius: AppUtils.kBorderRadius25,
+ child: Ink(
+ padding: EdgeInsets.zero,
+ decoration: BoxDecoration(
+ color: AppColors.cEEEEEE,
+ borderRadius: AppUtils.kBorderRadius25,
+ ),
+ child: Row(
+ children: [
+ if (index != 0 && state.filters.contains(titles[index]))
+ SvgPicture.asset(
+ AppIcons.icCheck1,
+ ).paddingOnly(right: 5),
+ if (index == 0)
+ Badge(
+ isLabelVisible:
+ state.filters.isNotEmpty ||
+ state.rating.isNotEmpty,
+ backgroundColor: AppColors.c34A853,
+ child: SvgPicture.asset(AppIcons.icFilter),
+ ).paddingSymmetric(vertical: 6),
+
+ if (index == 3 && state.rating.isNotEmpty)
+ SizedBox(
+ height: 25,
+ width: 25,
+ child: DecoratedBox(
+ decoration: BoxDecoration(
+ color: AppColors.c34A853,
+ borderRadius: AppUtils.kBorderRadius16,
+ ),
+ child: Center(
+ child: Text(
+ "${state.rating.length}",
+ style: AppTextStyles.size14Regular.copyWith(
+ color: AppColors.cFFFFFF,
+ ),
+ ),
+ ),
+ ),
+ ).paddingOnly(right: 8),
+ Text(titles[index], style: AppTextStyles.size14Medium),
+ if (index == 3) Icon(Icons.keyboard_arrow_down),
+ ],
+ ).paddingSymmetric(vertical: 0, horizontal: 15),
+ ),
+ ),
+ ),
),
+
+ 10.verticalSpace,
+ WDivider(),
],
- ),
- 8.verticalSpace,
- GridView.builder(
- shrinkWrap: true,
- itemCount: _titles.length,
- padding: EdgeInsets.zero,
- scrollDirection: Axis.vertical,
- physics: const NeverScrollableScrollPhysics(),
- keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
- gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 4,
- crossAxisSpacing: 5,
- mainAxisSpacing: 10,
- childAspectRatio: 78 / 100,
- ),
- itemBuilder: (context, index) => WCategoryItem(
- onTap: () {
- if (index == 3) {
- CategoriesPage().show(context);
- }
- },
- imgUrl: index != 3 ? _images[index] : null,
- text: _titles[index],
- child: index == 3
- ? SizedBox(height: 55, width: 55, child: Icon(Icons.more_horiz))
- : null,
- ),
- ),
- 8.verticalSpace,
- WDivider()
- ],
- ).paddingSymmetric(horizontal: 15);
+ );
+ },
+ );
}
}
diff --git a/lib/feature/home/presentation/pages/home_page/widgets/w_home_headers.dart b/lib/feature/home/presentation/pages/home_page/widgets/w_home_headers.dart
index cede191..06712db 100644
--- a/lib/feature/home/presentation/pages/home_page/widgets/w_home_headers.dart
+++ b/lib/feature/home/presentation/pages/home_page/widgets/w_home_headers.dart
@@ -9,6 +9,8 @@ class WHomeHeader extends StatelessWidget {
Widget build(BuildContext context) {
return BlocBuilder(
builder: (context, state) {
+
+
return DecoratedBox(
decoration: BoxDecoration(color: AppColors.cFFFFFF),
child: Column(
diff --git a/lib/feature/home/presentation/pages/home_page/widgets/w_rating_btm_sheet.dart b/lib/feature/home/presentation/pages/home_page/widgets/w_rating_btm_sheet.dart
new file mode 100644
index 0000000..30d29bf
--- /dev/null
+++ b/lib/feature/home/presentation/pages/home_page/widgets/w_rating_btm_sheet.dart
@@ -0,0 +1,133 @@
+import '../../../../../../food_delivery_client.dart';
+
+class WRatingBottomSheet extends StatefulWidget {
+ const WRatingBottomSheet({super.key, required this.savedRatings});
+
+ final List savedRatings;
+
+ Future?> show(BuildContext context) {
+ return showModalBottomSheet>(
+ context: context,
+ builder: (context) => Wrap(children: [this]),
+ );
+ }
+
+ @override
+ State createState() => _WRatingBottomSheetState();
+}
+
+class _WRatingBottomSheetState extends State {
+ List rating = [];
+
+ void updateRating(String value) {
+ final list = List.from(rating);
+ if (list.contains(value)) {
+ list.remove(value);
+ setState(() {
+ rating = list;
+ });
+ } else {
+ list.add(value);
+ setState(() {
+ rating = list;
+ });
+ }
+ }
+
+ @override
+ void initState() {
+ rating = widget.savedRatings;
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final List value = [
+ "${context.loc.atLeast} 4,9",
+ "${context.loc.atLeast} 4,7",
+ "${context.loc.atLeast} 4,5",
+ ];
+
+ return WCustomModalBottomSheet(
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(context.loc.rating, style: AppTextStyles.size20Medium),
+ IconButton(
+ onPressed: () {
+ context.pop(null);
+ },
+ icon: SvgPicture.asset(AppIcons.icClose, height: 15),
+ ),
+ ],
+ ),
+ 15.verticalSpace,
+ Wrap(
+ spacing: 10,
+ children: List.generate(value.length, (index) {
+ return WRatingButton(
+ onTap: () {
+ updateRating(value[index]);
+ },
+ isActive: rating.contains(value[index]),
+ rating: value[index],
+ );
+ }),
+ ),
+ 25.verticalSpace,
+ AppButton(
+ name: context.loc.apply,
+ onPressed: () {
+ context.pop(rating);
+ },
+ ),
+ 20.verticalSpace,
+ ],
+ ).paddingSymmetric(horizontal: 15),
+ );
+ }
+}
+
+class WRatingButton extends StatelessWidget {
+ const WRatingButton({
+ super.key,
+ required this.onTap,
+ required this.isActive,
+ required this.rating,
+ });
+
+ final VoidCallback onTap;
+ final bool isActive;
+ final String rating;
+
+ @override
+ Widget build(BuildContext context) {
+ return InkWell(
+ borderRadius: AppUtils.kBorderRadius25,
+ onTap: onTap,
+ child: Ink(
+ decoration: BoxDecoration(
+ color: isActive
+ ? AppColors.c34A853
+ : AppColors.cE6E6E6.newWithOpacity(.6),
+ borderRadius: AppUtils.kBorderRadius25,
+ ),
+ child: Row(
+ spacing: 4,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Icon(Icons.star, color: AppColors.cYellow),
+ Text(
+ rating,
+ style: AppTextStyles.size14Medium.copyWith(
+ color: isActive ? AppColors.cFFFFFF : AppColors.c000000,
+ ),
+ ),
+ ],
+ ).paddingSymmetric(vertical: 6, horizontal: 10),
+ ),
+ );
+ }
+}
diff --git a/lib/food_delivery_client.dart b/lib/food_delivery_client.dart
index 4605f52..12574fe 100644
--- a/lib/food_delivery_client.dart
+++ b/lib/food_delivery_client.dart
@@ -19,3 +19,4 @@ export 'package:freezed_annotation/freezed_annotation.dart';
export 'package:shared_preferences/shared_preferences.dart';
export 'package:cached_network_image/cached_network_image.dart';
export 'package:carousel_slider/carousel_slider.dart';
+export 'package:flutter_bounceable/flutter_bounceable.dart';