feat:restaurants by category page done

This commit is contained in:
jahongireshonqulov
2025-10-24 19:44:52 +05:00
parent e0f3d900d7
commit ffbc153b55
20 changed files with 409 additions and 30 deletions

View File

@@ -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

View File

@@ -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';
}
}

View File

@@ -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';
}
}

View File

@@ -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 dokonlar';
@override
String opensAt(String time) {
return 'Soat $time dan ochiladi';
}
@override
String spendAndSave(String spend, String save) {
return '$spend sarflang, $save tejang';
}
}

View File

@@ -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),
),
),
],
);

View File

@@ -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';
}

View File

@@ -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);
}

View File

@@ -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";

View File

@@ -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,
);
}
/*

View File

@@ -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';
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';

View File

@@ -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],
),

View File

@@ -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,

View File

@@ -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),
),
);
}
}

View File

@@ -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),
),
);
}
}

View File

@@ -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()
],
),
);
}
}

View File

@@ -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),
),
);
}
}