feat:filters done
This commit is contained in:
8
assets/icons/ic_clock.svg
Normal file
8
assets/icons/ic_clock.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="24" height="16" viewBox="0 0 24 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.7236 0.400391C20.0862 0.400391 23.5996 3.81531 23.5996 8C23.5996 12.1847 20.0862 15.5996 15.7236 15.5996C11.3612 15.5994 7.84863 12.1845 7.84863 8C7.84863 3.81546 11.3612 0.400637 15.7236 0.400391Z" stroke="black" stroke-width="0.8"/>
|
||||
<line x1="0.827637" y1="5.19998" x2="7.44833" y2="5.19998" stroke="black" stroke-width="0.8"/>
|
||||
<line x1="15.3241" y1="8" x2="15.3241" y2="1.6" stroke="black" stroke-width="0.8"/>
|
||||
<line x1="2.48267" y1="10" x2="6.6206" y2="10" stroke="black" stroke-width="0.8"/>
|
||||
<line y1="7.6" x2="6.62069" y2="7.6" stroke="black" stroke-width="0.8"/>
|
||||
<path d="M19.9827 11.2972L14.8965 7.2" stroke="black" stroke-width="0.8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 761 B |
@@ -77,7 +77,13 @@
|
||||
"halal": "Halal",
|
||||
"allergyFriendly": "Allergy friendly",
|
||||
"atLeast":"At least",
|
||||
"apply": "Apply"
|
||||
"apply": "Apply",
|
||||
"pickedForYouDefault": "Picked for you (default)",
|
||||
"popular": "Most popular",
|
||||
"topRated": "Top rated",
|
||||
"fast": "Fast",
|
||||
"delivery": "Delivery"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,13 @@
|
||||
"halal": "Халяль",
|
||||
"allergyFriendly": "Без аллергенов",
|
||||
"atLeast":"Kак минимум",
|
||||
"apply": "Применить"
|
||||
"apply": "Применить",
|
||||
"pickedForYouDefault": "Выбрано для вас (по умолчанию)",
|
||||
"popular": "Самые популярные",
|
||||
"topRated": "Высокий рейтинг",
|
||||
"fast": "Быстро",
|
||||
"delivery": "Доставка"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,13 @@
|
||||
"halal": "Halol",
|
||||
"allergyFriendly": "Allergiyaga mos",
|
||||
"atLeast":"Kаmida",
|
||||
"apply": "Qo‘llash"
|
||||
"apply": "Qo‘llash",
|
||||
"pickedForYouDefault": "Siz uchun tanlangan (standart)",
|
||||
"popular": "Eng ommabop",
|
||||
"topRated": "Yuqori reytingli",
|
||||
"fast": "Tezkor",
|
||||
"delivery": "Yetkazish"
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -483,6 +483,30 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'Apply'**
|
||||
String get apply;
|
||||
|
||||
/// No description provided for @pickedForYouDefault.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Picked for you (default)'**
|
||||
String get pickedForYouDefault;
|
||||
|
||||
/// No description provided for @popular.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Most popular'**
|
||||
String get popular;
|
||||
|
||||
/// No description provided for @topRated.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Top rated'**
|
||||
String get topRated;
|
||||
|
||||
/// No description provided for @fast.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Fast'**
|
||||
String get fast;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -204,4 +204,16 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get apply => 'Apply';
|
||||
|
||||
@override
|
||||
String get pickedForYouDefault => 'Picked for you (default)';
|
||||
|
||||
@override
|
||||
String get popular => 'Most popular';
|
||||
|
||||
@override
|
||||
String get topRated => 'Top rated';
|
||||
|
||||
@override
|
||||
String get fast => 'Fast';
|
||||
}
|
||||
|
||||
@@ -205,4 +205,16 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get apply => 'Применить';
|
||||
|
||||
@override
|
||||
String get pickedForYouDefault => 'Выбрано для вас (по умолчанию)';
|
||||
|
||||
@override
|
||||
String get popular => 'Самые популярные';
|
||||
|
||||
@override
|
||||
String get topRated => 'Высокий рейтинг';
|
||||
|
||||
@override
|
||||
String get fast => 'Быстро';
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class AppLocalizationsUz extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get delivery => 'Yetkazib berish';
|
||||
String get delivery => 'Yetkazish';
|
||||
|
||||
@override
|
||||
String get pickUp => 'Olib ketish';
|
||||
@@ -205,4 +205,16 @@ class AppLocalizationsUz extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get apply => 'Qo‘llash';
|
||||
|
||||
@override
|
||||
String get pickedForYouDefault => 'Siz uchun tanlangan (standart)';
|
||||
|
||||
@override
|
||||
String get popular => 'Eng ommabop';
|
||||
|
||||
@override
|
||||
String get topRated => 'Yuqori reytingli';
|
||||
|
||||
@override
|
||||
String get fast => 'Tezkor';
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:food_delivery_client/feature/home/presentation/pages/categories_page/categories_page.dart';
|
||||
import 'package:food_delivery_client/feature/on_boarding/presentation/pages/splash_page/splash_page.dart';
|
||||
|
||||
import '../../food_delivery_client.dart';
|
||||
|
||||
@@ -22,6 +20,12 @@ class AppRoutes {
|
||||
path: Routes.categories,
|
||||
pageBuilder: (context, state) => CupertinoPage(child: CategoriesPage()),
|
||||
),
|
||||
GoRoute(
|
||||
path: Routes.filters,
|
||||
pageBuilder: (context, state) => CupertinoPage(child: FiltersPage(
|
||||
homeBloc: state.extra as HomeBloc,
|
||||
)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,5 +4,7 @@ abstract class Routes {
|
||||
static const String register = '/register';
|
||||
static const String main = '/main';
|
||||
static const String categories = '/categories';
|
||||
static const String filters= '/filters';
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@ abstract class AppIcons {
|
||||
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";
|
||||
static const String icClock = "$baseUrl/ic_clock.svg";
|
||||
}
|
||||
|
||||
@@ -28,6 +28,13 @@ abstract class AppTextStyles {
|
||||
fontWeight: FontWeight.w400,
|
||||
);
|
||||
|
||||
static const TextStyle size16Regular = TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_16,
|
||||
fontFamily: _fontRegular,
|
||||
fontWeight: FontWeight.w400,
|
||||
);
|
||||
|
||||
static const TextStyle size20Regular = TextStyle(
|
||||
color: _defaultColor,
|
||||
fontSize: SizesCons.size_20,
|
||||
|
||||
44
lib/feature/common/presentation/widgets/app_list_tile.dart
Normal file
44
lib/feature/common/presentation/widgets/app_list_tile.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
class AppListTile extends StatelessWidget {
|
||||
const AppListTile({
|
||||
super.key,
|
||||
required this.onPressed,
|
||||
required this.isSelected,
|
||||
required this.svgPath,
|
||||
required this.title,
|
||||
this.contentPadding,
|
||||
this.leading,
|
||||
this.titleWidget,
|
||||
this.trailing,
|
||||
this.titleTextStyle,
|
||||
this.subTitle,
|
||||
});
|
||||
|
||||
final VoidCallback onPressed;
|
||||
final bool isSelected;
|
||||
final String svgPath;
|
||||
final String title;
|
||||
final EdgeInsets? contentPadding;
|
||||
final Widget? leading;
|
||||
final Widget? titleWidget;
|
||||
final Widget? trailing;
|
||||
final TextStyle? titleTextStyle;
|
||||
final Widget? subTitle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
onTap: onPressed,
|
||||
subtitle: subTitle,
|
||||
contentPadding:
|
||||
contentPadding ?? EdgeInsetsGeometry.only(left: 20, right: 27),
|
||||
leading: leading ?? SvgPicture.asset(svgPath),
|
||||
title:
|
||||
titleWidget ??
|
||||
Text(title, style: titleTextStyle ?? AppTextStyles.size16Regular),
|
||||
trailing:
|
||||
trailing ?? (isSelected ? SvgPicture.asset(AppIcons.icCheck) : null),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,3 +5,4 @@ export 'w_see_all_raw.dart';
|
||||
export 'w_stories_list_item.dart';
|
||||
export 'w_custom_modal_bottom_sheet.dart';
|
||||
export 'app_button.dart';
|
||||
export 'app_list_tile.dart';
|
||||
|
||||
@@ -12,3 +12,11 @@ export 'package:food_delivery_client/feature/home/presentation/pages/home_page/w
|
||||
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';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/filters_page.dart';
|
||||
export 'presentation/mixins/filter_mixins.dart';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_filter_app_bar.dart';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/filters_page/widgets/w_filters_body.dart';
|
||||
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';
|
||||
@@ -12,6 +12,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
on<_Changed>(_onChanged);
|
||||
on<_Filtered>(_onFiltered);
|
||||
on<_Rated>(_onRated);
|
||||
on<_DurationChanged>(_onDurationChanged);
|
||||
}
|
||||
|
||||
void _onChanged(_Changed event, Emitter<HomeState> emit) {
|
||||
@@ -29,9 +30,11 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _onRated(_Rated event, Emitter<HomeState> emit){
|
||||
void _onRated(_Rated event, Emitter<HomeState> emit) {
|
||||
emit(state.copyWith(rating: event.filter));
|
||||
}
|
||||
|
||||
void _onDurationChanged(_DurationChanged event, Emitter<HomeState> emit) {
|
||||
emit(state.copyWith(deliveryDuration: event.filter));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,13 @@ extension HomeEventPatterns on HomeEvent {
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Started value)? started,TResult Function( _Changed value)? changed,TResult Function( _Filtered value)? filtered,TResult Function( _Rated value)? rated,required TResult orElse(),}){
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Started value)? started,TResult Function( _Changed value)? changed,TResult Function( _DurationChanged value)? durationChanged,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 _Filtered() when filtered != null:
|
||||
return changed(_that);case _DurationChanged() when durationChanged != null:
|
||||
return durationChanged(_that);case _Filtered() when filtered != null:
|
||||
return filtered(_that);case _Rated() when rated != null:
|
||||
return rated(_that);case _:
|
||||
return orElse();
|
||||
@@ -80,12 +81,13 @@ return rated(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Started value) started,required TResult Function( _Changed value) changed,required TResult Function( _Filtered value) filtered,required TResult Function( _Rated value) rated,}){
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Started value) started,required TResult Function( _Changed value) changed,required TResult Function( _DurationChanged value) durationChanged,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 _Filtered():
|
||||
return changed(_that);case _DurationChanged():
|
||||
return durationChanged(_that);case _Filtered():
|
||||
return filtered(_that);case _Rated():
|
||||
return rated(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
@@ -104,12 +106,13 @@ return rated(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Started value)? started,TResult? Function( _Changed value)? changed,TResult? Function( _Filtered value)? filtered,TResult? Function( _Rated value)? rated,}){
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Started value)? started,TResult? Function( _Changed value)? changed,TResult? Function( _DurationChanged value)? durationChanged,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 _Filtered() when filtered != null:
|
||||
return changed(_that);case _DurationChanged() when durationChanged != null:
|
||||
return durationChanged(_that);case _Filtered() when filtered != null:
|
||||
return filtered(_that);case _Rated() when rated != null:
|
||||
return rated(_that);case _:
|
||||
return null;
|
||||
@@ -128,11 +131,12 @@ return rated(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? started,TResult Function( int index)? changed,TResult Function( String filter)? filtered,TResult Function( List<String> filter)? rated,required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? started,TResult Function( int index)? changed,TResult Function( String filter)? durationChanged,TResult Function( String filter)? filtered,TResult Function( List<String> 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 _Filtered() when filtered != null:
|
||||
return changed(_that.index);case _DurationChanged() when durationChanged != null:
|
||||
return durationChanged(_that.filter);case _Filtered() when filtered != null:
|
||||
return filtered(_that.filter);case _Rated() when rated != null:
|
||||
return rated(_that.filter);case _:
|
||||
return orElse();
|
||||
@@ -152,11 +156,12 @@ return rated(_that.filter);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() started,required TResult Function( int index) changed,required TResult Function( String filter) filtered,required TResult Function( List<String> filter) rated,}) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() started,required TResult Function( int index) changed,required TResult Function( String filter) durationChanged,required TResult Function( String filter) filtered,required TResult Function( List<String> filter) rated,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Started():
|
||||
return started();case _Changed():
|
||||
return changed(_that.index);case _Filtered():
|
||||
return changed(_that.index);case _DurationChanged():
|
||||
return durationChanged(_that.filter);case _Filtered():
|
||||
return filtered(_that.filter);case _Rated():
|
||||
return rated(_that.filter);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
@@ -175,11 +180,12 @@ return rated(_that.filter);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? started,TResult? Function( int index)? changed,TResult? Function( String filter)? filtered,TResult? Function( List<String> filter)? rated,}) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? started,TResult? Function( int index)? changed,TResult? Function( String filter)? durationChanged,TResult? Function( String filter)? filtered,TResult? Function( List<String> filter)? rated,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Started() when started != null:
|
||||
return started();case _Changed() when changed != null:
|
||||
return changed(_that.index);case _Filtered() when filtered != null:
|
||||
return changed(_that.index);case _DurationChanged() when durationChanged != null:
|
||||
return durationChanged(_that.filter);case _Filtered() when filtered != null:
|
||||
return filtered(_that.filter);case _Rated() when rated != null:
|
||||
return rated(_that.filter);case _:
|
||||
return null;
|
||||
@@ -290,6 +296,72 @@ as int,
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DurationChanged implements HomeEvent {
|
||||
const _DurationChanged(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')
|
||||
_$DurationChangedCopyWith<_DurationChanged> get copyWith => __$DurationChangedCopyWithImpl<_DurationChanged>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DurationChanged&&(identical(other.filter, filter) || other.filter == filter));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,filter);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.durationChanged(filter: $filter)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DurationChangedCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
|
||||
factory _$DurationChangedCopyWith(_DurationChanged value, $Res Function(_DurationChanged) _then) = __$DurationChangedCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String filter
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DurationChangedCopyWithImpl<$Res>
|
||||
implements _$DurationChangedCopyWith<$Res> {
|
||||
__$DurationChangedCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DurationChanged _self;
|
||||
final $Res Function(_DurationChanged) _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(_DurationChanged(
|
||||
null == filter ? _self.filter : filter // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Filtered implements HomeEvent {
|
||||
const _Filtered(this.filter);
|
||||
|
||||
@@ -428,7 +500,7 @@ as List<String>,
|
||||
/// @nodoc
|
||||
mixin _$HomeState {
|
||||
|
||||
int get currentIndex; List get filters; List<String> get rating;
|
||||
int get currentIndex; String get deliveryDuration; List get filters; List<String> get rating;
|
||||
/// Create a copy of HomeState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -439,16 +511,16 @@ $HomeStateCopyWith<HomeState> get copyWith => _$HomeStateCopyWithImpl<HomeState>
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
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));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&(identical(other.deliveryDuration, deliveryDuration) || other.deliveryDuration == deliveryDuration)&&const DeepCollectionEquality().equals(other.filters, filters)&&const DeepCollectionEquality().equals(other.rating, rating));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex,const DeepCollectionEquality().hash(filters),const DeepCollectionEquality().hash(rating));
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex,deliveryDuration,const DeepCollectionEquality().hash(filters),const DeepCollectionEquality().hash(rating));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeState(currentIndex: $currentIndex, filters: $filters, rating: $rating)';
|
||||
return 'HomeState(currentIndex: $currentIndex, deliveryDuration: $deliveryDuration, filters: $filters, rating: $rating)';
|
||||
}
|
||||
|
||||
|
||||
@@ -459,7 +531,7 @@ abstract mixin class $HomeStateCopyWith<$Res> {
|
||||
factory $HomeStateCopyWith(HomeState value, $Res Function(HomeState) _then) = _$HomeStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int currentIndex, List filters, List<String> rating
|
||||
int currentIndex, String deliveryDuration, List filters, List<String> rating
|
||||
});
|
||||
|
||||
|
||||
@@ -476,10 +548,11 @@ 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,Object? filters = null,Object? rating = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? currentIndex = null,Object? deliveryDuration = 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,filters: null == filters ? _self.filters : filters // ignore: cast_nullable_to_non_nullable
|
||||
as int,deliveryDuration: null == deliveryDuration ? _self.deliveryDuration : deliveryDuration // ignore: cast_nullable_to_non_nullable
|
||||
as String,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<String>,
|
||||
));
|
||||
@@ -566,10 +639,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int currentIndex, List filters, List<String> rating)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int currentIndex, String deliveryDuration, List filters, List<String> rating)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState() when $default != null:
|
||||
return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
return $default(_that.currentIndex,_that.deliveryDuration,_that.filters,_that.rating);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -587,10 +660,10 @@ return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int currentIndex, List filters, List<String> rating) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int currentIndex, String deliveryDuration, List filters, List<String> rating) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState():
|
||||
return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
return $default(_that.currentIndex,_that.deliveryDuration,_that.filters,_that.rating);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -607,10 +680,10 @@ return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int currentIndex, List filters, List<String> rating)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int currentIndex, String deliveryDuration, List filters, List<String> rating)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState() when $default != null:
|
||||
return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
return $default(_that.currentIndex,_that.deliveryDuration,_that.filters,_that.rating);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -622,10 +695,11 @@ return $default(_that.currentIndex,_that.filters,_that.rating);case _:
|
||||
|
||||
|
||||
class _HomeState implements HomeState {
|
||||
const _HomeState({this.currentIndex = 0, final List filters = const [], final List<String> rating = const []}): _filters = filters,_rating = rating;
|
||||
const _HomeState({this.currentIndex = 0, this.deliveryDuration = "60+", final List filters = const [], final List<String> rating = const []}): _filters = filters,_rating = rating;
|
||||
|
||||
|
||||
@override@JsonKey() final int currentIndex;
|
||||
@override@JsonKey() final String deliveryDuration;
|
||||
final List _filters;
|
||||
@override@JsonKey() List get filters {
|
||||
if (_filters is EqualUnmodifiableListView) return _filters;
|
||||
@@ -651,16 +725,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)&&const DeepCollectionEquality().equals(other._filters, _filters)&&const DeepCollectionEquality().equals(other._rating, _rating));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeState&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&(identical(other.deliveryDuration, deliveryDuration) || other.deliveryDuration == deliveryDuration)&&const DeepCollectionEquality().equals(other._filters, _filters)&&const DeepCollectionEquality().equals(other._rating, _rating));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex,const DeepCollectionEquality().hash(_filters),const DeepCollectionEquality().hash(_rating));
|
||||
int get hashCode => Object.hash(runtimeType,currentIndex,deliveryDuration,const DeepCollectionEquality().hash(_filters),const DeepCollectionEquality().hash(_rating));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeState(currentIndex: $currentIndex, filters: $filters, rating: $rating)';
|
||||
return 'HomeState(currentIndex: $currentIndex, deliveryDuration: $deliveryDuration, filters: $filters, rating: $rating)';
|
||||
}
|
||||
|
||||
|
||||
@@ -671,7 +745,7 @@ abstract mixin class _$HomeStateCopyWith<$Res> implements $HomeStateCopyWith<$Re
|
||||
factory _$HomeStateCopyWith(_HomeState value, $Res Function(_HomeState) _then) = __$HomeStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int currentIndex, List filters, List<String> rating
|
||||
int currentIndex, String deliveryDuration, List filters, List<String> rating
|
||||
});
|
||||
|
||||
|
||||
@@ -688,10 +762,11 @@ 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,Object? filters = null,Object? rating = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? currentIndex = null,Object? deliveryDuration = null,Object? filters = null,Object? rating = null,}) {
|
||||
return _then(_HomeState(
|
||||
currentIndex: null == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int,filters: null == filters ? _self._filters : filters // ignore: cast_nullable_to_non_nullable
|
||||
as int,deliveryDuration: null == deliveryDuration ? _self.deliveryDuration : deliveryDuration // ignore: cast_nullable_to_non_nullable
|
||||
as String,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<String>,
|
||||
));
|
||||
|
||||
@@ -4,6 +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.durationChanged(String filter) = _DurationChanged;
|
||||
const factory HomeEvent.filtered(String filter) = _Filtered;
|
||||
const factory HomeEvent.rated(List<String> filter) = _Rated;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ part of 'home_bloc.dart';
|
||||
abstract class HomeState with _$HomeState {
|
||||
const factory HomeState({
|
||||
@Default(0) int currentIndex,
|
||||
@Default("60+") String deliveryDuration,
|
||||
@Default([]) List filters,
|
||||
@Default([]) List<String> rating
|
||||
|
||||
|
||||
20
lib/feature/home/presentation/mixins/filter_mixins.dart
Normal file
20
lib/feature/home/presentation/mixins/filter_mixins.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import '../../../../core/theme/app_icons.dart';
|
||||
|
||||
mixin FilterMixins {
|
||||
final List<String> deliveryDurations = ["30", "45", "60", "60+"];
|
||||
final List<String> filterSortSvgs = [
|
||||
AppIcons.icPicked,
|
||||
AppIcons.icMostPopular,
|
||||
AppIcons.icStar,
|
||||
AppIcons.icDeliveryTime,
|
||||
];
|
||||
|
||||
final List<String> filterDietary = [
|
||||
AppIcons.icVegetarian,
|
||||
AppIcons.icVegen,
|
||||
AppIcons.icGlutenFree,
|
||||
AppIcons.icAllergyFriendly,
|
||||
];
|
||||
|
||||
final List<String> filterDeals = [AppIcons.icDeals, AppIcons.icBestOverall];
|
||||
}
|
||||
@@ -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();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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],
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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: () {
|
||||
|
||||
@@ -20,3 +20,4 @@ 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';
|
||||
export 'package:food_delivery_client/feature/on_boarding/presentation/pages/splash_page/splash_page.dart';
|
||||
|
||||
Reference in New Issue
Block a user