feat:restaurants by category page done
This commit is contained in:
5
assets/icons/ic_dislike_grey.svg
Normal file
5
assets/icons/ic_dislike_grey.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="23" height="21" viewBox="0 0 23 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M15.5174 3.10349C18.1037 3.10349 19.6554 5.06903 19.6554 7.44837C19.6554 8.68976 19.0347 9.82771 18.3106 10.6553C17.0692 11.8967 11.3795 16.5519 11.3795 16.5519C11.3795 16.5519 5.68973 11.8967 4.44833 10.6553C3.62073 9.82771 3.10349 8.68976 3.10349 7.44837C3.10349 5.06903 4.65523 3.10349 7.24147 3.10349C9.00011 3.10349 10.6553 4.75868 11.3795 6.20697C12.1036 4.75868 13.7588 3.10349 15.5174 3.10349ZM15.5174 0C13.9657 0 12.5174 0.620697 11.3795 1.44829C10.2415 0.517248 8.79321 0 7.24147 0C3.10349 0 0 3.20694 0 7.44837C0 9.41391 0.827596 11.276 2.27589 12.8277C3.72418 14.3795 11.3795 20.5865 11.3795 20.5865C11.3795 20.5865 19.0347 14.3795 20.483 12.8277C21.9313 11.276 22.7589 9.41391 22.7589 7.44837C22.7589 3.20694 19.6554 0 15.5174 0Z"
|
||||
fill="#8A8A8A" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 894 B |
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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": {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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": {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -5,6 +5,5 @@ abstract class Routes {
|
||||
static const String main = '/main';
|
||||
static const String categories = '/categories';
|
||||
static const String filters = '/filters';
|
||||
|
||||
|
||||
static const String restaurantsByCategory = '/restaurants-by-category';
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -20,3 +20,6 @@ export 'package:food_delivery_client/feature/home/presentation/pages/filters_pag
|
||||
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';
|
||||
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';
|
||||
|
||||
@@ -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],
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user