feat: splash page done
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
export 'presentation/pages/home_page/home_page.dart';
|
||||
export 'presentation/blocs/home_bloc/home_bloc.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_home_headers.dart';
|
||||
export 'presentation/widgets/w_category_item.dart';
|
||||
export "presentation/pages/home_page/widgets/w_categories_header_item.dart";
|
||||
export 'presentation/pages/home_page/widgets/w_delivery_header.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_discount_part.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_offers_carouseL_slider.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_popular_near_you.dart';
|
||||
export 'presentation/pages/home_page/widgets/w_todays_offers.dart';
|
||||
export 'package:food_delivery_client/feature/home/presentation/pages/home_page/widgets/pick_it_for_free.dart';
|
||||
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';
|
||||
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';
|
||||
@@ -1,40 +0,0 @@
|
||||
import 'package:food_delivery_client/food_delivery_client.dart';
|
||||
|
||||
part 'home_event.dart';
|
||||
|
||||
part 'home_state.dart';
|
||||
|
||||
part 'home_bloc.freezed.dart';
|
||||
|
||||
@injectable
|
||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
HomeBloc() : super(const HomeState()) {
|
||||
on<_Changed>(_onChanged);
|
||||
on<_Filtered>(_onFiltered);
|
||||
on<_Rated>(_onRated);
|
||||
on<_DurationChanged>(_onDurationChanged);
|
||||
}
|
||||
|
||||
void _onChanged(_Changed event, Emitter<HomeState> emit) {
|
||||
emit(state.copyWith(currentIndex: event.index));
|
||||
}
|
||||
|
||||
void _onFiltered(_Filtered event, Emitter<HomeState> emit) {
|
||||
final oldFilters = List.from(state.filters);
|
||||
if (oldFilters.contains(event.filter)) {
|
||||
final newFilters = oldFilters..remove(event.filter);
|
||||
emit(state.copyWith(filters: newFilters));
|
||||
} else {
|
||||
final newFilters = oldFilters..add(event.filter);
|
||||
emit(state.copyWith(filters: newFilters));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -1,778 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'home_bloc.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$HomeEvent {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeEvent);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class $HomeEventCopyWith<$Res> {
|
||||
$HomeEventCopyWith(HomeEvent _, $Res Function(HomeEvent) __);
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [HomeEvent].
|
||||
extension HomeEventPatterns on HomeEvent {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return 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 _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();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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 _DurationChanged():
|
||||
return durationChanged(_that);case _Filtered():
|
||||
return filtered(_that);case _Rated():
|
||||
return rated(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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 _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;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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 _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();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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 _DurationChanged():
|
||||
return durationChanged(_that.filter);case _Filtered():
|
||||
return filtered(_that.filter);case _Rated():
|
||||
return rated(_that.filter);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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 _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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Started implements HomeEvent {
|
||||
const _Started();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Started);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.started()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Changed implements HomeEvent {
|
||||
const _Changed(this.index);
|
||||
|
||||
|
||||
final int index;
|
||||
|
||||
/// 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')
|
||||
_$ChangedCopyWith<_Changed> get copyWith => __$ChangedCopyWithImpl<_Changed>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Changed&&(identical(other.index, index) || other.index == index));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,index);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.changed(index: $index)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ChangedCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
|
||||
factory _$ChangedCopyWith(_Changed value, $Res Function(_Changed) _then) = __$ChangedCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int index
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ChangedCopyWithImpl<$Res>
|
||||
implements _$ChangedCopyWith<$Res> {
|
||||
__$ChangedCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Changed _self;
|
||||
final $Res Function(_Changed) _then;
|
||||
|
||||
/// Create a copy of HomeEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') $Res call({Object? index = null,}) {
|
||||
return _then(_Changed(
|
||||
null == index ? _self.index : index // ignore: cast_nullable_to_non_nullable
|
||||
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);
|
||||
|
||||
|
||||
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')
|
||||
_$FilteredCopyWith<_Filtered> get copyWith => __$FilteredCopyWithImpl<_Filtered>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Filtered&&(identical(other.filter, filter) || other.filter == filter));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,filter);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.filtered(filter: $filter)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$FilteredCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
|
||||
factory _$FilteredCopyWith(_Filtered value, $Res Function(_Filtered) _then) = __$FilteredCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String filter
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$FilteredCopyWithImpl<$Res>
|
||||
implements _$FilteredCopyWith<$Res> {
|
||||
__$FilteredCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Filtered _self;
|
||||
final $Res Function(_Filtered) _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(_Filtered(
|
||||
null == filter ? _self.filter : filter // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Rated implements HomeEvent {
|
||||
const _Rated(final List<String> filter): _filter = filter;
|
||||
|
||||
|
||||
final List<String> _filter;
|
||||
List<String> get filter {
|
||||
if (_filter is EqualUnmodifiableListView) return _filter;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_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')
|
||||
_$RatedCopyWith<_Rated> get copyWith => __$RatedCopyWithImpl<_Rated>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Rated&&const DeepCollectionEquality().equals(other._filter, _filter));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_filter));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeEvent.rated(filter: $filter)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$RatedCopyWith<$Res> implements $HomeEventCopyWith<$Res> {
|
||||
factory _$RatedCopyWith(_Rated value, $Res Function(_Rated) _then) = __$RatedCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<String> filter
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$RatedCopyWithImpl<$Res>
|
||||
implements _$RatedCopyWith<$Res> {
|
||||
__$RatedCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Rated _self;
|
||||
final $Res Function(_Rated) _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(_Rated(
|
||||
null == filter ? _self._filter : filter // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$HomeState {
|
||||
|
||||
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)
|
||||
@pragma('vm:prefer-inline')
|
||||
$HomeStateCopyWith<HomeState> get copyWith => _$HomeStateCopyWithImpl<HomeState>(this as HomeState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
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,deliveryDuration,const DeepCollectionEquality().hash(filters),const DeepCollectionEquality().hash(rating));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeState(currentIndex: $currentIndex, deliveryDuration: $deliveryDuration, filters: $filters, rating: $rating)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $HomeStateCopyWith<$Res> {
|
||||
factory $HomeStateCopyWith(HomeState value, $Res Function(HomeState) _then) = _$HomeStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int currentIndex, String deliveryDuration, List filters, List<String> rating
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$HomeStateCopyWithImpl<$Res>
|
||||
implements $HomeStateCopyWith<$Res> {
|
||||
_$HomeStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final HomeState _self;
|
||||
final $Res Function(HomeState) _then;
|
||||
|
||||
/// 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? 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,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>,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [HomeState].
|
||||
extension HomeStatePatterns on HomeState {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _HomeState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _HomeState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _HomeState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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.deliveryDuration,_that.filters,_that.rating);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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.deliveryDuration,_that.filters,_that.rating);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@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.deliveryDuration,_that.filters,_that.rating);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _HomeState implements HomeState {
|
||||
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;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_filters);
|
||||
}
|
||||
|
||||
final List<String> _rating;
|
||||
@override@JsonKey() List<String> get rating {
|
||||
if (_rating is EqualUnmodifiableListView) return _rating;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_rating);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of HomeState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$HomeStateCopyWith<_HomeState> get copyWith => __$HomeStateCopyWithImpl<_HomeState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
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,deliveryDuration,const DeepCollectionEquality().hash(_filters),const DeepCollectionEquality().hash(_rating));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeState(currentIndex: $currentIndex, deliveryDuration: $deliveryDuration, filters: $filters, rating: $rating)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$HomeStateCopyWith<$Res> implements $HomeStateCopyWith<$Res> {
|
||||
factory _$HomeStateCopyWith(_HomeState value, $Res Function(_HomeState) _then) = __$HomeStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int currentIndex, String deliveryDuration, List filters, List<String> rating
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$HomeStateCopyWithImpl<$Res>
|
||||
implements _$HomeStateCopyWith<$Res> {
|
||||
__$HomeStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _HomeState _self;
|
||||
final $Res Function(_HomeState) _then;
|
||||
|
||||
/// 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? 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,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>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,11 +0,0 @@
|
||||
part of 'home_bloc.dart';
|
||||
|
||||
@freezed
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
part of 'home_bloc.dart';
|
||||
|
||||
@freezed
|
||||
abstract class HomeState with _$HomeState {
|
||||
const factory HomeState({
|
||||
@Default(0) int currentIndex,
|
||||
@Default("60+") String deliveryDuration,
|
||||
@Default([]) List filters,
|
||||
@Default([]) List<String> rating
|
||||
|
||||
}) = _HomeState;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import 'package:food_delivery_client/core/core.dart';
|
||||
|
||||
mixin CategoriesMixin {
|
||||
List<String> images = [
|
||||
AppImages.imgConvenience,
|
||||
AppImages.imgAlcohol,
|
||||
AppImages.imgPetSupplies,
|
||||
AppImages.imgFlowers,
|
||||
AppImages.imgGrocery,
|
||||
AppImages.imgAmerican,
|
||||
AppImages.imgSpeciality,
|
||||
AppImages.imgTakeout,
|
||||
AppImages.imgAsian,
|
||||
AppImages.imgIceCream,
|
||||
AppImages.imgHalal,
|
||||
AppImages.imgRetails,
|
||||
AppImages.imgCarribean,
|
||||
AppImages.imgIndian,
|
||||
AppImages.imgFrench,
|
||||
AppImages.imgFastFoods,
|
||||
AppImages.imgBurger,
|
||||
AppImages.imgRide,
|
||||
AppImages.imgChinese,
|
||||
AppImages.imgDesert,
|
||||
];
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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];
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
mixin HomePageMixins {
|
||||
static const headers = [];
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
import 'package:food_delivery_client/feature/home/presentation/mixins/categories_mixin.dart';
|
||||
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class CategoriesPage extends StatelessWidget with CategoriesMixin {
|
||||
CategoriesPage({super.key});
|
||||
|
||||
show(BuildContext context) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
|
||||
builder: (context) => Wrap(children: [this]),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<String> _titles = [
|
||||
context.loc.convenience,
|
||||
context.loc.alcohol,
|
||||
context.loc.petSupplies,
|
||||
context.loc.flowers,
|
||||
context.loc.grocery,
|
||||
context.loc.american,
|
||||
context.loc.speciality,
|
||||
context.loc.takeout,
|
||||
context.loc.asian,
|
||||
context.loc.iceCream,
|
||||
context.loc.halal,
|
||||
context.loc.retails,
|
||||
context.loc.caribbean,
|
||||
context.loc.indian,
|
||||
context.loc.french,
|
||||
context.loc.fastFoods,
|
||||
context.loc.burger,
|
||||
context.loc.ride,
|
||||
context.loc.chinese,
|
||||
context.loc.dessert,
|
||||
];
|
||||
return Material(
|
||||
color: AppColors.cFFFFFF,
|
||||
borderRadius: AppUtils.kBorderRadius20,
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
24.verticalSpace,
|
||||
Text(context.loc.allCategories, style: AppTextStyles.size20Regular),
|
||||
30.verticalSpace,
|
||||
GridView.builder(
|
||||
itemCount: images.length,
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 5,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 78 / 100,
|
||||
),
|
||||
itemBuilder: (context, index) => WCategoryItem(
|
||||
onTap: () {
|
||||
context.push(
|
||||
Routes.restaurantsByCategory,
|
||||
extra: _titles[index],
|
||||
);
|
||||
},
|
||||
imgUrl: images[index],
|
||||
text: _titles[index],
|
||||
),
|
||||
),
|
||||
40.verticalSpace,
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
|
||||
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();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
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,
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
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],
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
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];
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
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,
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import '../../../../../food_delivery_client.dart';
|
||||
|
||||
class HomePage extends StatelessWidget {
|
||||
const HomePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => sl<HomeBloc>(),
|
||||
child: BlocBuilder<HomeBloc, HomeState>(
|
||||
builder: (context, state) {
|
||||
return WLayout(
|
||||
child: Scaffold(
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(child: WHomeHeader()),
|
||||
SliverToBoxAdapter(child: Column(children: [
|
||||
WDeliveryHeader(),
|
||||
WDiscountPart(),
|
||||
WOffersCarouselSlider(),
|
||||
WDiscountPart(),
|
||||
WPopularNearYou(),
|
||||
WTodayOffers(),
|
||||
WPickItUpForFree()
|
||||
])),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WPickItUpForFree extends StatelessWidget {
|
||||
const WPickItUpForFree({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment:MainAxisAlignment.start,
|
||||
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
12.verticalSpace,
|
||||
Column(
|
||||
mainAxisAlignment:MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Pick it up for free', style: AppTextStyles.size24Bold),
|
||||
Text(
|
||||
"Skip the fees when you order pick-up",
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.c545454,
|
||||
),
|
||||
),
|
||||
7.verticalSpace,
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
Container(
|
||||
height: 210,
|
||||
width: context.w,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(AppImages.imgPickUp),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
child: Align(
|
||||
alignment: AlignmentGeometry.topCenter,
|
||||
child: CarouselSlider.builder(
|
||||
options: CarouselOptions(
|
||||
height: 100.0,
|
||||
reverse: false,
|
||||
viewportFraction: 0.9,
|
||||
animateToClosest: true,
|
||||
autoPlay: true,
|
||||
autoPlayCurve: Curves.easeIn,
|
||||
initialPage: 0,
|
||||
padEnds: false,
|
||||
enableInfiniteScroll: true,
|
||||
scrollPhysics: const AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, index, realIndex) {
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
return PickItUpItem().paddingOnly(left: 15);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
10.verticalSpace,
|
||||
WFoodItem(),
|
||||
40.verticalSpace
|
||||
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PickItUpItem extends StatelessWidget {
|
||||
const PickItUpItem({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: AppColors.cTransparent,
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cFFFFFF,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.c000000.newWithOpacity(.25),
|
||||
offset: const Offset(0, 1),
|
||||
blurRadius: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
spacing: 6,
|
||||
children: [
|
||||
Image.network(
|
||||
AppLocaleKeys.imageUrl,
|
||||
height: 88,
|
||||
width: 96,
|
||||
fit: BoxFit.cover,
|
||||
).paddingAll(4),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Island Takeway", style: AppTextStyles.size17Bold),
|
||||
Text(
|
||||
"10-20 min",
|
||||
style: AppTextStyles.size14Medium.copyWith(
|
||||
color: AppColors.c6B6B6B,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingOnly(top: 4, bottom: 4, right: 40),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import 'package:flutter_bounceable/flutter_bounceable.dart';
|
||||
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WCategoriesHeaderItem extends StatelessWidget {
|
||||
const WCategoriesHeaderItem({
|
||||
super.key,
|
||||
required this.text,
|
||||
required this.imageUrl,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final String text;
|
||||
final String imageUrl;
|
||||
final VoidCallback onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: AppUtils.kBorderRadius10,
|
||||
child: Ink(
|
||||
height: 88,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius10,
|
||||
color: AppColors.cE6E6E6.newWithOpacity(.4),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Align(
|
||||
alignment: AlignmentGeometry.topRight,
|
||||
child: Image.asset(imageUrl).paddingOnly(top: 5, right: 5),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
text,
|
||||
style: AppTextStyles.size18Medium,
|
||||
).paddingOnly(left: 12, bottom: 6),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WDeliveryHeader extends StatelessWidget {
|
||||
const WDeliveryHeader({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<String> _titles = [
|
||||
context.loc.convenience,
|
||||
context.loc.alcohol,
|
||||
context.loc.petSupplies,
|
||||
context.loc.more,
|
||||
];
|
||||
/*
|
||||
Siz uchun
|
||||
Eng ommabop,
|
||||
Reyting
|
||||
Yetkazib berish vaqti,
|
||||
Aksiyalar
|
||||
|
||||
|
||||
*/
|
||||
List titles = [
|
||||
'',
|
||||
context.loc.pickedForYou,
|
||||
context.loc.mostPopular,
|
||||
context.loc.rating,
|
||||
context.loc.deliveryTime,
|
||||
context.loc.deals,
|
||||
];
|
||||
return BlocBuilder<HomeBloc, HomeState>(
|
||||
builder: (context, state) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
15.verticalSpace,
|
||||
Row(
|
||||
spacing: 12,
|
||||
children: [
|
||||
WCategoriesHeaderItem(
|
||||
onTap: () {
|
||||
context.push(
|
||||
Routes.restaurantsByCategory,
|
||||
extra: context.loc.american,
|
||||
);
|
||||
},
|
||||
text: context.loc.american,
|
||||
imageUrl: AppImages.imgAmerican,
|
||||
),
|
||||
WCategoriesHeaderItem(
|
||||
onTap: () {
|
||||
context.push(
|
||||
Routes.restaurantsByCategory,
|
||||
extra: context.loc.grocery,
|
||||
);
|
||||
},
|
||||
text: context.loc.grocery,
|
||||
imageUrl: AppImages.imgGrocery,
|
||||
),
|
||||
],
|
||||
),
|
||||
8.verticalSpace,
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: _titles.length,
|
||||
padding: EdgeInsets.zero,
|
||||
scrollDirection: Axis.vertical,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
keyboardDismissBehavior:
|
||||
ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 5,
|
||||
mainAxisSpacing: 10,
|
||||
mainAxisExtent: 118,
|
||||
// childAspectRatio: 78 / 100,
|
||||
),
|
||||
itemBuilder: (context, index) => WCategoryItem(
|
||||
onTap: () {
|
||||
if (index == 3) {
|
||||
CategoriesPage().show(context);
|
||||
} else {
|
||||
context.push(
|
||||
Routes.restaurantsByCategory,
|
||||
extra: _titles[index],
|
||||
);
|
||||
}
|
||||
},
|
||||
imgUrl: index != 3 ? _images[index] : null,
|
||||
text: _titles[index],
|
||||
child: index == 3
|
||||
? SizedBox(
|
||||
height: 55,
|
||||
width: 55,
|
||||
child: Icon(Icons.more_horiz),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
15.verticalSpace,
|
||||
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: titles.length,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
separatorBuilder: (context, index) => 10.horizontalSpace,
|
||||
itemBuilder: (context, index) => InkWell(
|
||||
onTap: () async {
|
||||
if (index != 3 && index != 0) {
|
||||
context.read<HomeBloc>().add(
|
||||
HomeEvent.filtered(titles[index]),
|
||||
);
|
||||
}
|
||||
|
||||
if (index == 3) {
|
||||
final response = await WRatingBottomSheet(
|
||||
savedRatings: state.rating ?? [],
|
||||
).show(context);
|
||||
|
||||
if (response != null) {
|
||||
context.read<HomeBloc>().add(
|
||||
HomeEvent.rated(response ?? []),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
child: Ink(
|
||||
padding: EdgeInsets.zero,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cEEEEEE,
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
if (index != 0 && state.filters.contains(titles[index]))
|
||||
SvgPicture.asset(
|
||||
AppIcons.icCheck1,
|
||||
).paddingOnly(right: 5),
|
||||
if (index == 0)
|
||||
Badge(
|
||||
isLabelVisible:
|
||||
state.filters.isNotEmpty ||
|
||||
state.rating.isNotEmpty,
|
||||
backgroundColor: AppColors.c34A853,
|
||||
child: SvgPicture.asset(AppIcons.icFilter),
|
||||
).paddingSymmetric(vertical: 6),
|
||||
|
||||
if (index == 3 && state.rating.isNotEmpty)
|
||||
SizedBox(
|
||||
height: 25,
|
||||
width: 25,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.c34A853,
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"${state.rating.length}",
|
||||
style: AppTextStyles.size14Regular.copyWith(
|
||||
color: AppColors.cFFFFFF,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
).paddingOnly(right: 8),
|
||||
Text(titles[index], style: AppTextStyles.size14Medium),
|
||||
if (index == 3) Icon(Icons.keyboard_arrow_down),
|
||||
],
|
||||
).paddingSymmetric(vertical: 0, horizontal: 15),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
10.verticalSpace,
|
||||
WDivider(),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List _images = [
|
||||
AppImages.imgConvenience,
|
||||
AppImages.imgAlcohol,
|
||||
AppImages.imgPetSupplies,
|
||||
];
|
||||
@@ -1,25 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WDiscountPart extends StatelessWidget {
|
||||
const WDiscountPart({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
scrollDirection: Axis.vertical,
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => WFoodItem(enableTag: true),
|
||||
separatorBuilder: (context, index) => 20.verticalSpace,
|
||||
itemCount: 3,
|
||||
),
|
||||
WDivider(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WHomeHeader extends StatelessWidget {
|
||||
const WHomeHeader({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<HomeBloc, HomeState>(
|
||||
builder: (context, state) {
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(color: AppColors.cFFFFFF),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
15.verticalSpace,
|
||||
Stack(
|
||||
alignment: AlignmentGeometry.center,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SvgPicture.asset(AppIcons.icLocation, height: 20),
|
||||
8.horizontalSpace,
|
||||
Text("London Hall", style: AppTextStyles.size18Medium),
|
||||
5.horizontalSpace,
|
||||
SvgPicture.asset(AppIcons.icArrowBottom),
|
||||
],
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentGeometry.topRight,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
context.push(
|
||||
Routes.filters,
|
||||
extra: context.read<HomeBloc>(),
|
||||
);
|
||||
},
|
||||
icon: SvgPicture.asset(
|
||||
AppIcons.icFilter,
|
||||
height: 36,
|
||||
width: 36,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WOffersCarouselSlider extends StatelessWidget {
|
||||
WOffersCarouselSlider({super.key});
|
||||
|
||||
List _colors = [
|
||||
AppColors.cD2D7F0,
|
||||
AppColors.c9EE2B8,
|
||||
AppColors.cE2CC9E,
|
||||
AppColors.cC99EE2,
|
||||
AppColors.cE29EC7,
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
16.verticalSpace,
|
||||
CarouselSlider.builder(
|
||||
options: CarouselOptions(
|
||||
height: 170.0,
|
||||
reverse: false,
|
||||
viewportFraction: 0.9,
|
||||
animateToClosest: true,
|
||||
autoPlay: true,
|
||||
autoPlayCurve: Curves.easeIn,
|
||||
initialPage: 0,
|
||||
padEnds: false,
|
||||
enableInfiniteScroll: true,
|
||||
scrollPhysics: const AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
itemBuilder: (context, index, realIndex) => Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: EdgeInsets.only(left: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: _colors[index],
|
||||
borderRadius: AppUtils.kBorderRadius16,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Order from these restaurants and save",
|
||||
style: AppTextStyles.size17Bold,
|
||||
),
|
||||
const Spacer(),
|
||||
Material(
|
||||
color: AppColors.cTransparent,
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
borderRadius: AppUtils.kBorderRadius30,
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.cFFFFFF,
|
||||
borderRadius: AppUtils.kBorderRadius30,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [Text('Browse offer')],
|
||||
).paddingSymmetric(horizontal: 8, vertical: 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15, vertical: 15),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: AppUtils.kBorderRadiusTop15Bottom15,
|
||||
child: Image.network(
|
||||
AppLocaleKeys.imageUrl,
|
||||
height: 170,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
itemCount: _colors.length,
|
||||
),
|
||||
8.verticalSpace,
|
||||
WDivider(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WPopularNearYou extends StatelessWidget {
|
||||
const WPopularNearYou({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
10.verticalSpace,
|
||||
WSeeAllRaw(title: "Popular near you", onPressed: () {}),
|
||||
10.verticalSpace,
|
||||
CarouselSlider.builder(
|
||||
options: CarouselOptions(
|
||||
height: 180.0,
|
||||
reverse: false,
|
||||
viewportFraction: 0.9,
|
||||
animateToClosest: true,
|
||||
autoPlay: true,
|
||||
autoPlayCurve: Curves.easeIn,
|
||||
initialPage: 0,
|
||||
padEnds: false,
|
||||
enableInfiniteScroll: true,
|
||||
scrollPhysics: const AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, index, realIndex) {
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
return WFoodItem(
|
||||
imageHeight: 130,
|
||||
textStyle1: AppTextStyles.size14Medium,
|
||||
textStyle2: AppTextStyles.size12Regular,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
13.verticalSpace,
|
||||
WDivider(),
|
||||
10.verticalSpace,
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) => WFoodItem(),
|
||||
separatorBuilder: (context, index) => 25.verticalSpace,
|
||||
itemCount: 5,
|
||||
),
|
||||
25.verticalSpace,
|
||||
WDivider(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WRatingBottomSheet extends StatefulWidget {
|
||||
const WRatingBottomSheet({super.key, required this.savedRatings});
|
||||
|
||||
final List<String> savedRatings;
|
||||
|
||||
Future<List<String>?> show(BuildContext context) {
|
||||
return showModalBottomSheet<List<String>>(
|
||||
context: context,
|
||||
builder: (context) => Wrap(children: [this]),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
State<WRatingBottomSheet> createState() => _WRatingBottomSheetState();
|
||||
}
|
||||
|
||||
class _WRatingBottomSheetState extends State<WRatingBottomSheet> {
|
||||
List<String> rating = [];
|
||||
|
||||
void updateRating(String value) {
|
||||
final list = List<String>.from(rating);
|
||||
if (list.contains(value)) {
|
||||
list.remove(value);
|
||||
setState(() {
|
||||
rating = list;
|
||||
});
|
||||
} else {
|
||||
list.add(value);
|
||||
setState(() {
|
||||
rating = list;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
rating = widget.savedRatings;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<String> value = [
|
||||
"${context.loc.atLeast} 4,9",
|
||||
"${context.loc.atLeast} 4,7",
|
||||
"${context.loc.atLeast} 4,5",
|
||||
];
|
||||
|
||||
return WCustomModalBottomSheet(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(context.loc.rating, style: AppTextStyles.size20Medium),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pop(null);
|
||||
},
|
||||
icon: SvgPicture.asset(AppIcons.icClose, height: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
15.verticalSpace,
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 15,
|
||||
children: List.generate(value.length, (index) {
|
||||
return WRatingButton(
|
||||
onTap: () {
|
||||
updateRating(value[index]);
|
||||
},
|
||||
isActive: rating.contains(value[index]),
|
||||
rating: value[index],
|
||||
);
|
||||
}),
|
||||
),
|
||||
25.verticalSpace,
|
||||
AppButton(
|
||||
name: context.loc.apply,
|
||||
onPressed: () {
|
||||
context.pop(rating);
|
||||
},
|
||||
),
|
||||
20.verticalSpace,
|
||||
],
|
||||
).paddingSymmetric(horizontal: 15),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class WRatingButton extends StatelessWidget {
|
||||
const WRatingButton({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
required this.isActive,
|
||||
required this.rating,
|
||||
});
|
||||
|
||||
final VoidCallback onTap;
|
||||
final bool isActive;
|
||||
final String rating;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
onTap: onTap,
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
color: isActive
|
||||
? AppColors.c34A853
|
||||
: AppColors.cE6E6E6.newWithOpacity(.6),
|
||||
borderRadius: AppUtils.kBorderRadius25,
|
||||
),
|
||||
child: Row(
|
||||
spacing: 4,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.star, color: AppColors.cYellow),
|
||||
Text(
|
||||
rating,
|
||||
style: AppTextStyles.size14Medium.copyWith(
|
||||
color: isActive ? AppColors.cFFFFFF : AppColors.c000000,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(vertical: 6, horizontal: 10),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import '../../../../../../food_delivery_client.dart';
|
||||
|
||||
class WTodayOffers extends StatelessWidget {
|
||||
const WTodayOffers({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
12.verticalSpace,
|
||||
WSeeAllRaw(
|
||||
title: "Today's offers",
|
||||
onPressed: () {},
|
||||
),
|
||||
10.verticalSpace,
|
||||
CarouselSlider.builder(
|
||||
options: CarouselOptions(
|
||||
height: 180.0,
|
||||
reverse: false,
|
||||
viewportFraction: 0.9,
|
||||
animateToClosest: true,
|
||||
autoPlay: true,
|
||||
autoPlayCurve: Curves.easeIn,
|
||||
initialPage: 0,
|
||||
padEnds: false,
|
||||
enableInfiniteScroll: true,
|
||||
scrollPhysics: const AlwaysScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, index, realIndex) {
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
return WFoodItem(
|
||||
imageHeight: 130,
|
||||
enableTag: true,
|
||||
textStyle1: AppTextStyles.size14Medium,
|
||||
textStyle2: AppTextStyles.size12Regular,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
10.verticalSpace,
|
||||
WDivider(),
|
||||
10.verticalSpace,
|
||||
ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemBuilder: (context, index) => WFoodItem(),
|
||||
separatorBuilder: (context, index) => 25.verticalSpace,
|
||||
itemCount: 3,
|
||||
),
|
||||
25.verticalSpace,
|
||||
WDivider()
|
||||
|
||||
|
||||
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
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()
|
||||
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import '../../../../food_delivery_client.dart';
|
||||
|
||||
class WCategoryItem extends StatelessWidget {
|
||||
const WCategoryItem({
|
||||
super.key,
|
||||
required this.onTap,
|
||||
this.text,
|
||||
this.imgUrl,
|
||||
this.child,
|
||||
});
|
||||
|
||||
final VoidCallback onTap;
|
||||
final String? text;
|
||||
final String? imgUrl;
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: AppUtils.kBorderRadius10,
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppUtils.kBorderRadius10,
|
||||
color: AppColors.cE6E6E6.newWithOpacity(.4),
|
||||
),
|
||||
child: SizedBox(
|
||||
height: 55,
|
||||
width: 55,
|
||||
child: child ?? Image.asset(imgUrl!, fit: BoxFit.cover),
|
||||
).paddingSymmetric(vertical: 8, horizontal: 12),
|
||||
),
|
||||
),
|
||||
3.verticalSpace,
|
||||
if (text != null)
|
||||
Text(
|
||||
text!,
|
||||
maxLines: 2,
|
||||
style: AppTextStyles.size14Medium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user