feat:filters done

This commit is contained in:
jahongireshonqulov
2025-10-24 18:06:43 +05:00
parent f2ab615b4e
commit e0f3d900d7
30 changed files with 635 additions and 44 deletions

View File

@@ -0,0 +1,26 @@
import '../../../../../food_delivery_client.dart';
class FiltersPage extends StatefulWidget {
const FiltersPage({super.key, required this.homeBloc});
final HomeBloc homeBloc;
@override
State<FiltersPage> createState() => _FiltersPageState();
}
class _FiltersPageState extends State<FiltersPage> {
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: widget.homeBloc,
child: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return WFiltersBody();
},
),
);
}
}

View File

@@ -0,0 +1,84 @@
import '../../../../../../food_delivery_client.dart';
class WDeliveryDuration extends StatelessWidget with FilterMixins {
WDeliveryDuration({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.loc.delivery,
style: AppTextStyles.size18Medium,
).paddingSymmetric(horizontal: 20),
15.verticalSpace,
SizedBox(
height: 60,
child: Stack(
alignment: AlignmentGeometry.center,
children: [
SizedBox(
height: 40,
width: context.w,
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: AppUtils.kBorderRadius8,
color: AppColors.cE6E6E6.newWithOpacity(.6),
),
),
),
Material(
color: AppColors.cTransparent,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(deliveryDurations.length, (
index,
) {
final isActive =
state.deliveryDuration == deliveryDurations[index];
return InkWell(
onTap: () {
context.read<HomeBloc>().add(
HomeEvent.durationChanged(
deliveryDurations[index],
),
);
},
borderRadius: AppUtils.kBorderRadius40,
child: Ink(
height: 60,
width: 60,
decoration: BoxDecoration(
color: isActive
? AppColors.c34A853
: AppColors.cTransparent,
borderRadius: AppUtils.kBorderRadius40,
),
child: Center(
child: Text(
deliveryDurations[index],
style: AppTextStyles.size16Medium.copyWith(
color: isActive
? AppColors.cFFFFFF
: AppColors.c000000,
),
),
),
),
);
}),
),
),
],
),
).paddingSymmetric(horizontal: 20),
25.verticalSpace,
],
);
},
);
}
}

View File

@@ -0,0 +1,25 @@
import '../../../../../../food_delivery_client.dart';
class WFiltersAppBar extends StatelessWidget {
const WFiltersAppBar({super.key});
@override
Widget build(BuildContext context) {
return AppBar(
centerTitle: true,
elevation: 30,
bottomOpacity: 1,
scrolledUnderElevation: 10,
backgroundColor: AppColors.cFFFFFF,
surfaceTintColor: AppColors.cTransparent,
useDefaultSemanticsOrder: true,
leading: IconButton(
onPressed: () {
context.pop();
},
icon: SvgPicture.asset(AppIcons.icClose),
),
title: Text(context.loc.allCategories, style: AppTextStyles.size20Medium),
);
}
}

View File

@@ -0,0 +1,38 @@
import '../../../../../../food_delivery_client.dart';
class WFilterDietary extends StatelessWidget with FilterMixins {
WFilterDietary({super.key});
@override
Widget build(BuildContext context) {
final List<String> dietaryTitles = [
context.loc.vegetarian,
context.loc.vegan,
context.loc.glutenFree,
context.loc.allergyFriendly,
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
25.verticalSpace,
Text(
context.loc.dietary,
style: AppTextStyles.size18Medium,
).paddingSymmetric(horizontal: 20),
15.verticalSpace,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(4, (index) {
return AppListTile(
onPressed: () {},
isSelected: false,
leading: Image.asset(filterDietary[index], height: 30, width: 30),
svgPath: filterDietary[index],
title: dietaryTitles[index],
);
}),
),
],
);
}
}

View File

@@ -0,0 +1,42 @@
import '../../../../../../food_delivery_client.dart';
class WFiltersBody extends StatelessWidget {
const WFiltersBody({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return WLayout(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(56),
child: WFiltersAppBar(),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
18.verticalSpace,
WDeliveryDuration(),
WFiltersSort(),
WFiltersDeals(),
WFilterDietary(),
],
),
),
),
],
),
),
);
},
);
}
}

View File

@@ -0,0 +1,59 @@
import 'package:flutter/cupertino.dart';
import '../../../../../../food_delivery_client.dart';
class WFiltersDeals extends StatefulWidget {
const WFiltersDeals({super.key});
@override
State<WFiltersDeals> createState() => _WFiltersDealsState();
}
class _WFiltersDealsState extends State<WFiltersDeals> with FilterMixins {
List<bool> values = [false, false];
@override
Widget build(BuildContext context) {
final List<String> dealsTitle = [
context.loc.deals,
context.loc.bestOverall,
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
25.verticalSpace,
Text(
"From Uber eats",
style: AppTextStyles.size18Medium,
).paddingSymmetric(horizontal: 20),
15.verticalSpace,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(2, (index) {
return AppListTile(
onPressed: () {
setState(() {
values[index] = !values[index];
});
},
isSelected: false,
leading: index == 0
? SvgPicture.asset(filterDeals[index], height: 30, width: 30)
: Image.asset(filterDeals[index], height: 30, width: 30),
svgPath: filterDeals[index],
title: dealsTitle[index],
trailing: CupertinoSwitch(
value: values[index],
onChanged: (value) {
setState(() {
values[index] = !values[index];
});
},
),
);
}),
),
],
);
}
}

View File

@@ -0,0 +1,60 @@
import '../../../../../../food_delivery_client.dart';
class WFiltersSort extends StatelessWidget with FilterMixins {
WFiltersSort({super.key});
@override
Widget build(BuildContext context) {
final List<String> filterSortTitles = [
context.loc.pickedForYouDefault,
context.loc.mostPopular,
context.loc.topRated,
context.loc.fast,
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.loc.sort,
style: AppTextStyles.size18Medium,
).paddingSymmetric(horizontal: 20),
15.verticalSpace,
Column(
children: List.generate(filterSortTitles.length, (index) {
return AppListTile(
onPressed: () {},
isSelected: false,
svgPath: filterSortSvgs[index],
title: filterSortTitles[index],
);
}),
),
// AppListTile(
// onPressed: () {},
// isSelected: true,
// svgPath: AppIcons.icPicked,
// title: context.loc.pickedForYouDefault,
// ),
// AppListTile(
// onPressed: () {},
// isSelected: false,
// svgPath: AppIcons.icMostPopular,
// title: context.loc.popular,
// ),
// AppListTile(
// onPressed: () {},
// isSelected: false,
// svgPath: AppIcons.icStar,
// title: context.loc.topRated,
// ),
// AppListTile(
// onPressed: () {},
// isSelected: false,
// svgPath: AppIcons.icClock,
// title: context.loc.fast,
// ),
],
);
}
}

View File

@@ -9,8 +9,6 @@ class WHomeHeader extends StatelessWidget {
Widget build(BuildContext context) {
return BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
return DecoratedBox(
decoration: BoxDecoration(color: AppColors.cFFFFFF),
child: Column(
@@ -37,7 +35,12 @@ class WHomeHeader extends StatelessWidget {
Align(
alignment: AlignmentGeometry.topRight,
child: IconButton(
onPressed: () {},
onPressed: () {
context.push(
Routes.filters,
extra: context.read<HomeBloc>(),
);
},
icon: SvgPicture.asset(
AppIcons.icFilter,
height: 36,

View File

@@ -66,6 +66,7 @@ class _WRatingBottomSheetState extends State<WRatingBottomSheet> {
15.verticalSpace,
Wrap(
spacing: 10,
runSpacing: 15,
children: List.generate(value.length, (index) {
return WRatingButton(
onTap: () {