diff --git a/assets/icons/ic_dislike_grey.svg b/assets/icons/ic_dislike_grey.svg new file mode 100644 index 0000000..ab9926b --- /dev/null +++ b/assets/icons/ic_dislike_grey.svg @@ -0,0 +1,5 @@ + + + diff --git a/assets/translations/app_en.arb b/assets/translations/app_en.arb index baf37fd..91bb122 100644 --- a/assets/translations/app_en.arb +++ b/assets/translations/app_en.arb @@ -82,9 +82,34 @@ "popular": "Most popular", "topRated": "Top rated", "fast": "Fast", - "delivery": "Delivery" - - - + "delivery": "Delivery", + "featuredStores": "Featured stores", + "fromUberEats": "From {name}", + "@fromUberEats":{ + "placeholders": { + "name": { + "type": "String" + } + } + }, + "opensAt": "Opens at {time}", + "@opensAt": { + "placeholders":{ + "time": { + "type": "String" + } + } + }, + "spendAndSave": "Spend {spend}, save {save}", + "@spendAndSave": { + "placeholders":{ + "spend": { + "type": "String" + }, + "save": { + "type": "String" + } + } + } } \ No newline at end of file diff --git a/assets/translations/app_ru.arb b/assets/translations/app_ru.arb index 44e92aa..dce867d 100644 --- a/assets/translations/app_ru.arb +++ b/assets/translations/app_ru.arb @@ -89,7 +89,26 @@ "popular": "Самые популярные", "topRated": "Высокий рейтинг", "fast": "Быстро", - "delivery": "Доставка" + "delivery": "Доставка", + "featuredStores": "Популярные магазины", + "fromUberEats": "От {name}", + "@fromUberEats":{ + "placeholders": { + "name": { + "type": "String" + } + } + }, + "opensAt": "Открывается в {time}", + "opensAt@placeholders": { + "time": {} + }, + "spendAndSave": "Потратьте {spend}, сэкономьте {save}", + "spendAndSave@placeholders": { + "spend": {}, + "save": {} + } + diff --git a/assets/translations/app_uz.arb b/assets/translations/app_uz.arb index 8b65ce5..a837ad0 100644 --- a/assets/translations/app_uz.arb +++ b/assets/translations/app_uz.arb @@ -59,13 +59,13 @@ "dessert": "Desert", "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", + "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", @@ -89,7 +89,29 @@ "popular": "Eng ommabop", "topRated": "Yuqori reytingli", "fast": "Tezkor", - "delivery": "Yetkazish" + "delivery": "Yetkazish", + "featuredStores": "Mashhur do‘konlar", + "fromUberEats": "{name} tomonidan", + "@fromUberEats":{ + "placeholders": { + "name": { + "type": "String" + } + } + }, + "opensAt": "Soat {time} dan ochiladi", + "opensAt@placeholders": { + "time": {} + }, + "spendAndSave": "{spend} sarflang, {save} tejang", + "spendAndSave@placeholders": { + "spend": {}, + "save": {} + } + + + + diff --git a/lib/core/l10n/app_localizations.dart b/lib/core/l10n/app_localizations.dart index f0c723d..c4a1d5b 100644 --- a/lib/core/l10n/app_localizations.dart +++ b/lib/core/l10n/app_localizations.dart @@ -415,8 +415,8 @@ abstract class AppLocalizations { /// No description provided for @fromUberEats. /// /// In en, this message translates to: - /// **'From Uber Eats'** - String get fromUberEats; + /// **'From {name}'** + String fromUberEats(String name); /// No description provided for @deals. /// @@ -507,6 +507,24 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Fast'** String get fast; + + /// No description provided for @featuredStores. + /// + /// In en, this message translates to: + /// **'Featured stores'** + String get featuredStores; + + /// No description provided for @opensAt. + /// + /// In en, this message translates to: + /// **'Opens at {time}'** + String opensAt(String time); + + /// No description provided for @spendAndSave. + /// + /// In en, this message translates to: + /// **'Spend {spend}, save {save}'** + String spendAndSave(String spend, String save); } class _AppLocalizationsDelegate diff --git a/lib/core/l10n/app_localizations_en.dart b/lib/core/l10n/app_localizations_en.dart index 87ec60a..572a4f8 100644 --- a/lib/core/l10n/app_localizations_en.dart +++ b/lib/core/l10n/app_localizations_en.dart @@ -170,7 +170,9 @@ class AppLocalizationsEn extends AppLocalizations { String get deliveryTime => 'Delivery time'; @override - String get fromUberEats => 'From Uber Eats'; + String fromUberEats(String name) { + return 'From $name'; + } @override String get deals => 'Deals'; @@ -216,4 +218,17 @@ class AppLocalizationsEn extends AppLocalizations { @override String get fast => 'Fast'; + + @override + String get featuredStores => 'Featured stores'; + + @override + String opensAt(String time) { + return 'Opens at $time'; + } + + @override + String spendAndSave(String spend, String save) { + return 'Spend $spend, save $save'; + } } diff --git a/lib/core/l10n/app_localizations_ru.dart b/lib/core/l10n/app_localizations_ru.dart index c97a2fa..ad6200a 100644 --- a/lib/core/l10n/app_localizations_ru.dart +++ b/lib/core/l10n/app_localizations_ru.dart @@ -171,7 +171,9 @@ class AppLocalizationsRu extends AppLocalizations { String get deliveryTime => 'Время доставки'; @override - String get fromUberEats => 'От Uber Eats'; + String fromUberEats(String name) { + return 'От $name'; + } @override String get deals => 'Скидки'; @@ -217,4 +219,17 @@ class AppLocalizationsRu extends AppLocalizations { @override String get fast => 'Быстро'; + + @override + String get featuredStores => 'Популярные магазины'; + + @override + String opensAt(String time) { + return 'Открывается в $time'; + } + + @override + String spendAndSave(String spend, String save) { + return 'Потратьте $spend, сэкономьте $save'; + } } diff --git a/lib/core/l10n/app_localizations_uz.dart b/lib/core/l10n/app_localizations_uz.dart index f5bf7ee..bba85ea 100644 --- a/lib/core/l10n/app_localizations_uz.dart +++ b/lib/core/l10n/app_localizations_uz.dart @@ -171,7 +171,9 @@ class AppLocalizationsUz extends AppLocalizations { String get deliveryTime => 'Yetkazib berish vaqti'; @override - String get fromUberEats => 'Uber Eats dan'; + String fromUberEats(String name) { + return '$name tomonidan'; + } @override String get deals => 'Aksiyalar'; @@ -217,4 +219,17 @@ class AppLocalizationsUz extends AppLocalizations { @override String get fast => 'Tezkor'; + + @override + String get featuredStores => 'Mashhur do‘konlar'; + + @override + String opensAt(String time) { + return 'Soat $time dan ochiladi'; + } + + @override + String spendAndSave(String spend, String save) { + return '$spend sarflang, $save tejang'; + } } diff --git a/lib/core/router/app_routes.dart b/lib/core/router/app_routes.dart index 62e6fe4..6b63c17 100644 --- a/lib/core/router/app_routes.dart +++ b/lib/core/router/app_routes.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:food_delivery_client/feature/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart'; import '../../food_delivery_client.dart'; @@ -22,9 +23,15 @@ class AppRoutes { ), GoRoute( path: Routes.filters, - pageBuilder: (context, state) => CupertinoPage(child: FiltersPage( - homeBloc: state.extra as HomeBloc, - )), + pageBuilder: (context, state) => CupertinoPage( + child: FiltersPage(homeBloc: state.extra as HomeBloc), + ), + ), + GoRoute( + path: Routes.restaurantsByCategory, + pageBuilder: (context, state) => CupertinoPage( + child: RestaurantsByCategoryPage(categoryName: state.extra as String), + ), ), ], ); diff --git a/lib/core/router/routes_name.dart b/lib/core/router/routes_name.dart index e400c8a..c65b813 100644 --- a/lib/core/router/routes_name.dart +++ b/lib/core/router/routes_name.dart @@ -4,7 +4,6 @@ abstract class Routes { static const String register = '/register'; static const String main = '/main'; static const String categories = '/categories'; - static const String filters= '/filters'; - - + static const String filters = '/filters'; + static const String restaurantsByCategory = '/restaurants-by-category'; } diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index c424557..2c38e83 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -5,7 +5,6 @@ abstract class AppColors { static const Color cRed = Colors.red; static const Color cYellow = Colors.yellow; - static const Color cFFFFFF = Color(0xFFFFFFFF); static const Color c000000 = Color(0xFF000000); static const Color cB5B5B5 = Color(0xFFB5B5B5); @@ -21,5 +20,6 @@ abstract class AppColors { static const Color cC99EE2 = Color(0xFFC99EE2); static const Color cE29EC7 = Color(0xFFE29EC7); static const Color c545454 = Color(0xFF545454); - + static const Color cEFF3FE = Color(0xFFEFF3FE); + static const Color c05A357 = Color(0xFF05A357); } diff --git a/lib/core/theme/app_icons.dart b/lib/core/theme/app_icons.dart index 5462d8e..665c8bb 100644 --- a/lib/core/theme/app_icons.dart +++ b/lib/core/theme/app_icons.dart @@ -13,6 +13,7 @@ abstract class AppIcons { static const String icAccountActive = "$baseUrl/ic_account_active.svg"; static const String icBack = "$baseUrl/ic_back.svg"; static const String icDislike = "$baseUrl/ic_dislike.svg"; + static const String icDislikeGrey = "$baseUrl/ic_dislike_grey.svg"; static const String icEat = "$baseUrl/ic_eat.svg"; static const String icEye = "$baseUrl/ic_eye.svg"; static const String icFilter = "$baseUrl/ic_filter.svg"; diff --git a/lib/core/theme/app_textstyles.dart b/lib/core/theme/app_textstyles.dart index 33547af..9246b85 100644 --- a/lib/core/theme/app_textstyles.dart +++ b/lib/core/theme/app_textstyles.dart @@ -97,6 +97,20 @@ abstract class AppTextStyles { fontFamily: _fontBold, fontWeight: FontWeight.w700, ); + + static const TextStyle size30Bold = TextStyle( + color: _defaultColor, + fontSize: SizesCons.size_30, + fontFamily: _fontBold, + fontWeight: FontWeight.w700, + ); + + static const TextStyle size36Bold = TextStyle( + color: _defaultColor, + fontSize: SizesCons.size_36, + fontFamily: _fontBold, + fontWeight: FontWeight.w700, + ); } /* diff --git a/lib/feature/home/home.dart b/lib/feature/home/home.dart index 7fdc6e6..8d443fd 100644 --- a/lib/feature/home/home.dart +++ b/lib/feature/home/home.dart @@ -19,4 +19,7 @@ export 'package:food_delivery_client/feature/home/presentation/pages/filters_pag export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_delivery_duration.dart'; export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_filter_dietary.dart'; export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_filters_deals.dart'; -export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_filters_sort.dart'; \ No newline at end of file +export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_filters_sort.dart'; +export 'package:food_delivery_client/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_restaurants_by_category_body.dart'; +export 'package:food_delivery_client/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_featured_stores.dart'; +export 'package:food_delivery_client/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_stores_list.dart'; diff --git a/lib/feature/home/presentation/pages/categories_page/categories_page.dart b/lib/feature/home/presentation/pages/categories_page/categories_page.dart index c782c7a..341e13c 100644 --- a/lib/feature/home/presentation/pages/categories_page/categories_page.dart +++ b/lib/feature/home/presentation/pages/categories_page/categories_page.dart @@ -59,7 +59,12 @@ class CategoriesPage extends StatelessWidget with CategoriesMixin { childAspectRatio: 78 / 100, ), itemBuilder: (context, index) => WCategoryItem( - onTap: () {}, + onTap: () { + context.push( + Routes.restaurantsByCategory, + extra: _titles[index], + ); + }, imgUrl: images[index], text: _titles[index], ), 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 8908fac..5f976ec 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 @@ -40,12 +40,22 @@ class WDeliveryHeader extends StatelessWidget { spacing: 12, children: [ WCategoriesHeaderItem( - onTap: () {}, + onTap: () { + context.push( + Routes.restaurantsByCategory, + extra: context.loc.american, + ); + }, text: context.loc.american, imageUrl: AppImages.imgAmerican, ), WCategoriesHeaderItem( - onTap: () {}, + onTap: () { + context.push( + Routes.restaurantsByCategory, + extra: context.loc.grocery, + ); + }, text: context.loc.grocery, imageUrl: AppImages.imgGrocery, ), @@ -71,6 +81,11 @@ class WDeliveryHeader extends StatelessWidget { onTap: () { if (index == 3) { CategoriesPage().show(context); + } else { + context.push( + Routes.restaurantsByCategory, + extra: _titles[index], + ); } }, imgUrl: index != 3 ? _images[index] : null, diff --git a/lib/feature/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart b/lib/feature/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart new file mode 100644 index 0000000..0fa2a23 --- /dev/null +++ b/lib/feature/home/presentation/pages/restaurants_by_category_page/restaurants_by_category_page.dart @@ -0,0 +1,24 @@ +import '../../../../../food_delivery_client.dart'; + +class RestaurantsByCategoryPage extends StatelessWidget { + const RestaurantsByCategoryPage({super.key, required this.categoryName}); + + final String categoryName; + + @override + Widget build(BuildContext context) { + return WLayout( + child: Scaffold( + appBar: AppBar( + leading: IconButton( + onPressed: () { + context.pop(); + }, + icon: SvgPicture.asset(AppIcons.icBack), + ), + ), + body: WRestaurantsByCategoryBody(categoryName: categoryName), + ), + ); + } +} diff --git a/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_featured_stores.dart b/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_featured_stores.dart new file mode 100644 index 0000000..886f2af --- /dev/null +++ b/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_featured_stores.dart @@ -0,0 +1,66 @@ +import '../../../../../../food_delivery_client.dart'; + +class WFeaturedStores extends StatelessWidget { + const WFeaturedStores({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 200, + child: ListView.separated( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + padding: EdgeInsets.symmetric(horizontal: 20), + physics: const AlwaysScrollableScrollPhysics(), + itemBuilder: (context, index) => WFeaturedStoresItem(), + separatorBuilder: (context, index) => 7.horizontalSpace, + itemCount: 10, + ), + ); + } +} + +class WFeaturedStoresItem extends StatelessWidget { + const WFeaturedStoresItem({super.key}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () {}, + borderRadius: AppUtils.kBorderRadius16, + child: Ink( + height: 200, + width: 165, + decoration: BoxDecoration( + color: AppColors.cEFF3FE, + borderRadius: AppUtils.kBorderRadius16, + ), + child: Column( + spacing: 20, + children: [ + Expanded( + child: CachedNetworkImage(imageUrl: AppLocaleKeys.imageUrl), + ), + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text("7Eleven", style: AppTextStyles.size16Medium), + Text( + context.loc.opensAt("10:00 AM"), + textAlign: TextAlign.center, + style: AppTextStyles.size14Regular.copyWith( + color: AppColors.c6B6B6B, + + ), + ), + ], + ), + ), + ], + ).paddingAll(20), + ), + ); + } +} diff --git a/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_restaurants_by_category_body.dart b/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_restaurants_by_category_body.dart new file mode 100644 index 0000000..67a0dc7 --- /dev/null +++ b/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_restaurants_by_category_body.dart @@ -0,0 +1,42 @@ + +import '../../../../../../food_delivery_client.dart'; + +class WRestaurantsByCategoryBody extends StatelessWidget { + const WRestaurantsByCategoryBody({super.key, required this.categoryName}); + + final String categoryName; + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + scrollDirection: Axis.vertical, + physics: const AlwaysScrollableScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + categoryName, + style: AppTextStyles.size36Bold.copyWith( + height: 44/36 + ), + ).paddingSymmetric(horizontal: 15), + 15.verticalSpace, + Text( + context.loc.featuredStores, + style: AppTextStyles.size30Bold.copyWith( + height: 44/30 + ), + ).paddingSymmetric(horizontal: 15), + 15.verticalSpace, + WFeaturedStores(), + 16.verticalSpace, + WDivider(), + WStoresList() + + + + ], + ), + ); + } +} diff --git a/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_stores_list.dart b/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_stores_list.dart new file mode 100644 index 0000000..304daf8 --- /dev/null +++ b/lib/feature/home/presentation/pages/restaurants_by_category_page/widgets/w_stores_list.dart @@ -0,0 +1,69 @@ +import '../../../../../../food_delivery_client.dart'; + +class WStoresList extends StatelessWidget { + const WStoresList({super.key}); + + @override + Widget build(BuildContext context) { + return ListView.builder( + itemCount: 20, + shrinkWrap: true, + padding: EdgeInsets.symmetric(vertical: 17), + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return WStoreItem(); + }, + ); + } +} + +class WStoreItem extends StatelessWidget { + const WStoreItem({super.key}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () {}, + child: Ink( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: AppUtils.kBorderRadius36, + child: CachedNetworkImage( + imageUrl: AppLocaleKeys.imageUrl, + height: 70, + width: 70, + fit: BoxFit.cover, + ), + ), + 16.horizontalSpace, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Begs & Megs", style: AppTextStyles.size16Medium), + Text( + context.loc.opensAt("10:00"), + style: AppTextStyles.size14Regular.copyWith( + color: AppColors.c6B6B6B, + ), + ), + Text( + context.loc.spendAndSave("\$20", "\$5"), + style: AppTextStyles.size14Medium.copyWith( + color: AppColors.c05A357, + ), + ), + ], + ), + const Spacer(), + IconButton( + onPressed: () {}, + icon: SvgPicture.asset(AppIcons.icDislikeGrey), + ), + ], + ).paddingSymmetric(vertical: 10, horizontal: 18), + ), + ); + } +}