feat: search product and fix product

This commit is contained in:
efrilm 2025-08-07 12:19:25 +07:00
parent 5575596bfc
commit fe92082ceb
9 changed files with 349 additions and 118 deletions

View File

@ -17,6 +17,7 @@ class ProductRemoteDatasource {
int page = 1,
int limit = Variables.defaultLimit,
String? categoryId,
String? search,
}) async {
try {
final authData = await AuthLocalDataSource().getAuthData();
@ -31,6 +32,10 @@ class ProductRemoteDatasource {
queryParameters['category_id'] = categoryId;
}
if (search != null && search.isNotEmpty) {
queryParameters['search'] = search;
}
final response = await dio.get(
url,
queryParameters: queryParameters,

View File

@ -30,9 +30,14 @@ class CategoryLoaderBloc
updatedAt: DateTime.now(),
),
);
emit(_Loaded(categories));
emit(_Loaded(categories, null));
},
);
});
on<_SetCategoryId>((event, emit) async {
var currentState = state as _Loaded;
emit(_Loaded(currentState.categories, event.categoryId));
});
}
}

View File

@ -19,32 +19,38 @@ mixin _$CategoryLoaderEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() get,
required TResult Function(String categoryId) setCategoryId,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? get,
TResult? Function(String categoryId)? setCategoryId,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? get,
TResult Function(String categoryId)? setCategoryId,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Get value) get,
required TResult Function(_SetCategoryId value) setCategoryId,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Get value)? get,
TResult? Function(_SetCategoryId value)? setCategoryId,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Get value)? get,
TResult Function(_SetCategoryId value)? setCategoryId,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@ -111,6 +117,7 @@ class _$GetImpl implements _Get {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() get,
required TResult Function(String categoryId) setCategoryId,
}) {
return get();
}
@ -119,6 +126,7 @@ class _$GetImpl implements _Get {
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? get,
TResult? Function(String categoryId)? setCategoryId,
}) {
return get?.call();
}
@ -127,6 +135,7 @@ class _$GetImpl implements _Get {
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? get,
TResult Function(String categoryId)? setCategoryId,
required TResult orElse(),
}) {
if (get != null) {
@ -139,6 +148,7 @@ class _$GetImpl implements _Get {
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Get value) get,
required TResult Function(_SetCategoryId value) setCategoryId,
}) {
return get(this);
}
@ -147,6 +157,7 @@ class _$GetImpl implements _Get {
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Get value)? get,
TResult? Function(_SetCategoryId value)? setCategoryId,
}) {
return get?.call(this);
}
@ -155,6 +166,7 @@ class _$GetImpl implements _Get {
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Get value)? get,
TResult Function(_SetCategoryId value)? setCategoryId,
required TResult orElse(),
}) {
if (get != null) {
@ -168,13 +180,156 @@ abstract class _Get implements CategoryLoaderEvent {
const factory _Get() = _$GetImpl;
}
/// @nodoc
abstract class _$$SetCategoryIdImplCopyWith<$Res> {
factory _$$SetCategoryIdImplCopyWith(
_$SetCategoryIdImpl value, $Res Function(_$SetCategoryIdImpl) then) =
__$$SetCategoryIdImplCopyWithImpl<$Res>;
@useResult
$Res call({String categoryId});
}
/// @nodoc
class __$$SetCategoryIdImplCopyWithImpl<$Res>
extends _$CategoryLoaderEventCopyWithImpl<$Res, _$SetCategoryIdImpl>
implements _$$SetCategoryIdImplCopyWith<$Res> {
__$$SetCategoryIdImplCopyWithImpl(
_$SetCategoryIdImpl _value, $Res Function(_$SetCategoryIdImpl) _then)
: super(_value, _then);
/// Create a copy of CategoryLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? categoryId = null,
}) {
return _then(_$SetCategoryIdImpl(
null == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$SetCategoryIdImpl implements _SetCategoryId {
const _$SetCategoryIdImpl(this.categoryId);
@override
final String categoryId;
@override
String toString() {
return 'CategoryLoaderEvent.setCategoryId(categoryId: $categoryId)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SetCategoryIdImpl &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId));
}
@override
int get hashCode => Object.hash(runtimeType, categoryId);
/// Create a copy of CategoryLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$SetCategoryIdImplCopyWith<_$SetCategoryIdImpl> get copyWith =>
__$$SetCategoryIdImplCopyWithImpl<_$SetCategoryIdImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() get,
required TResult Function(String categoryId) setCategoryId,
}) {
return setCategoryId(categoryId);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? get,
TResult? Function(String categoryId)? setCategoryId,
}) {
return setCategoryId?.call(categoryId);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? get,
TResult Function(String categoryId)? setCategoryId,
required TResult orElse(),
}) {
if (setCategoryId != null) {
return setCategoryId(categoryId);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Get value) get,
required TResult Function(_SetCategoryId value) setCategoryId,
}) {
return setCategoryId(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Get value)? get,
TResult? Function(_SetCategoryId value)? setCategoryId,
}) {
return setCategoryId?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Get value)? get,
TResult Function(_SetCategoryId value)? setCategoryId,
required TResult orElse(),
}) {
if (setCategoryId != null) {
return setCategoryId(this);
}
return orElse();
}
}
abstract class _SetCategoryId implements CategoryLoaderEvent {
const factory _SetCategoryId(final String categoryId) = _$SetCategoryIdImpl;
String get categoryId;
/// Create a copy of CategoryLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$SetCategoryIdImplCopyWith<_$SetCategoryIdImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$CategoryLoaderState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<CategoryModel> categories) loaded,
required TResult Function(
List<CategoryModel> categories, String? categoryId)
loaded,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@ -182,7 +337,8 @@ mixin _$CategoryLoaderState {
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<CategoryModel> categories)? loaded,
TResult? Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@ -190,7 +346,8 @@ mixin _$CategoryLoaderState {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<CategoryModel> categories)? loaded,
TResult Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
@ -286,7 +443,9 @@ class _$InitialImpl implements _Initial {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<CategoryModel> categories) loaded,
required TResult Function(
List<CategoryModel> categories, String? categoryId)
loaded,
required TResult Function(String message) error,
}) {
return initial();
@ -297,7 +456,8 @@ class _$InitialImpl implements _Initial {
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<CategoryModel> categories)? loaded,
TResult? Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult? Function(String message)? error,
}) {
return initial?.call();
@ -308,7 +468,8 @@ class _$InitialImpl implements _Initial {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<CategoryModel> categories)? loaded,
TResult Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
@ -403,7 +564,9 @@ class _$LoadingImpl implements _Loading {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<CategoryModel> categories) loaded,
required TResult Function(
List<CategoryModel> categories, String? categoryId)
loaded,
required TResult Function(String message) error,
}) {
return loading();
@ -414,7 +577,8 @@ class _$LoadingImpl implements _Loading {
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<CategoryModel> categories)? loaded,
TResult? Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult? Function(String message)? error,
}) {
return loading?.call();
@ -425,7 +589,8 @@ class _$LoadingImpl implements _Loading {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<CategoryModel> categories)? loaded,
TResult Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
@ -483,7 +648,7 @@ abstract class _$$LoadedImplCopyWith<$Res> {
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
__$$LoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({List<CategoryModel> categories});
$Res call({List<CategoryModel> categories, String? categoryId});
}
/// @nodoc
@ -500,12 +665,17 @@ class __$$LoadedImplCopyWithImpl<$Res>
@override
$Res call({
Object? categories = null,
Object? categoryId = freezed,
}) {
return _then(_$LoadedImpl(
null == categories
? _value._categories
: categories // ignore: cast_nullable_to_non_nullable
as List<CategoryModel>,
freezed == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@ -513,7 +683,7 @@ class __$$LoadedImplCopyWithImpl<$Res>
/// @nodoc
class _$LoadedImpl implements _Loaded {
const _$LoadedImpl(final List<CategoryModel> categories)
const _$LoadedImpl(final List<CategoryModel> categories, this.categoryId)
: _categories = categories;
final List<CategoryModel> _categories;
@ -524,9 +694,12 @@ class _$LoadedImpl implements _Loaded {
return EqualUnmodifiableListView(_categories);
}
@override
final String? categoryId;
@override
String toString() {
return 'CategoryLoaderState.loaded(categories: $categories)';
return 'CategoryLoaderState.loaded(categories: $categories, categoryId: $categoryId)';
}
@override
@ -535,12 +708,14 @@ class _$LoadedImpl implements _Loaded {
(other.runtimeType == runtimeType &&
other is _$LoadedImpl &&
const DeepCollectionEquality()
.equals(other._categories, _categories));
.equals(other._categories, _categories) &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId));
}
@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(_categories));
int get hashCode => Object.hash(runtimeType,
const DeepCollectionEquality().hash(_categories), categoryId);
/// Create a copy of CategoryLoaderState
/// with the given fields replaced by the non-null parameter values.
@ -555,10 +730,12 @@ class _$LoadedImpl implements _Loaded {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<CategoryModel> categories) loaded,
required TResult Function(
List<CategoryModel> categories, String? categoryId)
loaded,
required TResult Function(String message) error,
}) {
return loaded(categories);
return loaded(categories, categoryId);
}
@override
@ -566,10 +743,11 @@ class _$LoadedImpl implements _Loaded {
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<CategoryModel> categories)? loaded,
TResult? Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult? Function(String message)? error,
}) {
return loaded?.call(categories);
return loaded?.call(categories, categoryId);
}
@override
@ -577,12 +755,13 @@ class _$LoadedImpl implements _Loaded {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<CategoryModel> categories)? loaded,
TResult Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(categories);
return loaded(categories, categoryId);
}
return orElse();
}
@ -626,9 +805,12 @@ class _$LoadedImpl implements _Loaded {
}
abstract class _Loaded implements CategoryLoaderState {
const factory _Loaded(final List<CategoryModel> categories) = _$LoadedImpl;
const factory _Loaded(
final List<CategoryModel> categories, final String? categoryId) =
_$LoadedImpl;
List<CategoryModel> get categories;
String? get categoryId;
/// Create a copy of CategoryLoaderState
/// with the given fields replaced by the non-null parameter values.
@ -707,7 +889,9 @@ class _$ErrorImpl implements _Error {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<CategoryModel> categories) loaded,
required TResult Function(
List<CategoryModel> categories, String? categoryId)
loaded,
required TResult Function(String message) error,
}) {
return error(message);
@ -718,7 +902,8 @@ class _$ErrorImpl implements _Error {
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<CategoryModel> categories)? loaded,
TResult? Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult? Function(String message)? error,
}) {
return error?.call(message);
@ -729,7 +914,8 @@ class _$ErrorImpl implements _Error {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<CategoryModel> categories)? loaded,
TResult Function(List<CategoryModel> categories, String? categoryId)?
loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {

View File

@ -3,4 +3,6 @@ part of 'category_loader_bloc.dart';
@freezed
class CategoryLoaderEvent with _$CategoryLoaderEvent {
const factory CategoryLoaderEvent.get() = _Get;
const factory CategoryLoaderEvent.setCategoryId(String categoryId) =
_SetCategoryId;
}

View File

@ -4,7 +4,7 @@ part of 'category_loader_bloc.dart';
class CategoryLoaderState with _$CategoryLoaderState {
const factory CategoryLoaderState.initial() = _Initial;
const factory CategoryLoaderState.loading() = _Loading;
const factory CategoryLoaderState.loaded(List<CategoryModel> categories) =
_Loaded;
const factory CategoryLoaderState.loaded(
List<CategoryModel> categories, String? categoryId) = _Loaded;
const factory CategoryLoaderState.error(String message) = _Error;
}

View File

@ -18,22 +18,22 @@ final _privateConstructorUsedError = UnsupportedError(
mixin _$ProductLoaderEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String? categoryId) getProduct,
required TResult Function(String? categoryId) loadMore,
required TResult Function(String? categoryId, String? search) getProduct,
required TResult Function(String? categoryId, String? search) loadMore,
required TResult Function() refresh,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String? categoryId)? getProduct,
TResult? Function(String? categoryId)? loadMore,
TResult? Function(String? categoryId, String? search)? getProduct,
TResult? Function(String? categoryId, String? search)? loadMore,
TResult? Function()? refresh,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String? categoryId)? getProduct,
TResult Function(String? categoryId)? loadMore,
TResult Function(String? categoryId, String? search)? getProduct,
TResult Function(String? categoryId, String? search)? loadMore,
TResult Function()? refresh,
required TResult orElse(),
}) =>
@ -89,7 +89,7 @@ abstract class _$$GetProductImplCopyWith<$Res> {
_$GetProductImpl value, $Res Function(_$GetProductImpl) then) =
__$$GetProductImplCopyWithImpl<$Res>;
@useResult
$Res call({String? categoryId});
$Res call({String? categoryId, String? search});
}
/// @nodoc
@ -106,12 +106,17 @@ class __$$GetProductImplCopyWithImpl<$Res>
@override
$Res call({
Object? categoryId = freezed,
Object? search = freezed,
}) {
return _then(_$GetProductImpl(
categoryId: freezed == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String?,
search: freezed == search
? _value.search
: search // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@ -119,14 +124,16 @@ class __$$GetProductImplCopyWithImpl<$Res>
/// @nodoc
class _$GetProductImpl implements _GetProduct {
const _$GetProductImpl({this.categoryId});
const _$GetProductImpl({this.categoryId, this.search});
@override
final String? categoryId;
@override
final String? search;
@override
String toString() {
return 'ProductLoaderEvent.getProduct(categoryId: $categoryId)';
return 'ProductLoaderEvent.getProduct(categoryId: $categoryId, search: $search)';
}
@override
@ -135,11 +142,12 @@ class _$GetProductImpl implements _GetProduct {
(other.runtimeType == runtimeType &&
other is _$GetProductImpl &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId));
other.categoryId == categoryId) &&
(identical(other.search, search) || other.search == search));
}
@override
int get hashCode => Object.hash(runtimeType, categoryId);
int get hashCode => Object.hash(runtimeType, categoryId, search);
/// Create a copy of ProductLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -152,33 +160,33 @@ class _$GetProductImpl implements _GetProduct {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String? categoryId) getProduct,
required TResult Function(String? categoryId) loadMore,
required TResult Function(String? categoryId, String? search) getProduct,
required TResult Function(String? categoryId, String? search) loadMore,
required TResult Function() refresh,
}) {
return getProduct(categoryId);
return getProduct(categoryId, search);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String? categoryId)? getProduct,
TResult? Function(String? categoryId)? loadMore,
TResult? Function(String? categoryId, String? search)? getProduct,
TResult? Function(String? categoryId, String? search)? loadMore,
TResult? Function()? refresh,
}) {
return getProduct?.call(categoryId);
return getProduct?.call(categoryId, search);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String? categoryId)? getProduct,
TResult Function(String? categoryId)? loadMore,
TResult Function(String? categoryId, String? search)? getProduct,
TResult Function(String? categoryId, String? search)? loadMore,
TResult Function()? refresh,
required TResult orElse(),
}) {
if (getProduct != null) {
return getProduct(categoryId);
return getProduct(categoryId, search);
}
return orElse();
}
@ -219,9 +227,11 @@ class _$GetProductImpl implements _GetProduct {
}
abstract class _GetProduct implements ProductLoaderEvent {
const factory _GetProduct({final String? categoryId}) = _$GetProductImpl;
const factory _GetProduct({final String? categoryId, final String? search}) =
_$GetProductImpl;
String? get categoryId;
String? get search;
/// Create a copy of ProductLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -236,7 +246,7 @@ abstract class _$$LoadMoreImplCopyWith<$Res> {
_$LoadMoreImpl value, $Res Function(_$LoadMoreImpl) then) =
__$$LoadMoreImplCopyWithImpl<$Res>;
@useResult
$Res call({String? categoryId});
$Res call({String? categoryId, String? search});
}
/// @nodoc
@ -253,12 +263,17 @@ class __$$LoadMoreImplCopyWithImpl<$Res>
@override
$Res call({
Object? categoryId = freezed,
Object? search = freezed,
}) {
return _then(_$LoadMoreImpl(
categoryId: freezed == categoryId
? _value.categoryId
: categoryId // ignore: cast_nullable_to_non_nullable
as String?,
search: freezed == search
? _value.search
: search // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@ -266,14 +281,16 @@ class __$$LoadMoreImplCopyWithImpl<$Res>
/// @nodoc
class _$LoadMoreImpl implements _LoadMore {
const _$LoadMoreImpl({this.categoryId});
const _$LoadMoreImpl({this.categoryId, this.search});
@override
final String? categoryId;
@override
final String? search;
@override
String toString() {
return 'ProductLoaderEvent.loadMore(categoryId: $categoryId)';
return 'ProductLoaderEvent.loadMore(categoryId: $categoryId, search: $search)';
}
@override
@ -282,11 +299,12 @@ class _$LoadMoreImpl implements _LoadMore {
(other.runtimeType == runtimeType &&
other is _$LoadMoreImpl &&
(identical(other.categoryId, categoryId) ||
other.categoryId == categoryId));
other.categoryId == categoryId) &&
(identical(other.search, search) || other.search == search));
}
@override
int get hashCode => Object.hash(runtimeType, categoryId);
int get hashCode => Object.hash(runtimeType, categoryId, search);
/// Create a copy of ProductLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -299,33 +317,33 @@ class _$LoadMoreImpl implements _LoadMore {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String? categoryId) getProduct,
required TResult Function(String? categoryId) loadMore,
required TResult Function(String? categoryId, String? search) getProduct,
required TResult Function(String? categoryId, String? search) loadMore,
required TResult Function() refresh,
}) {
return loadMore(categoryId);
return loadMore(categoryId, search);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String? categoryId)? getProduct,
TResult? Function(String? categoryId)? loadMore,
TResult? Function(String? categoryId, String? search)? getProduct,
TResult? Function(String? categoryId, String? search)? loadMore,
TResult? Function()? refresh,
}) {
return loadMore?.call(categoryId);
return loadMore?.call(categoryId, search);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String? categoryId)? getProduct,
TResult Function(String? categoryId)? loadMore,
TResult Function(String? categoryId, String? search)? getProduct,
TResult Function(String? categoryId, String? search)? loadMore,
TResult Function()? refresh,
required TResult orElse(),
}) {
if (loadMore != null) {
return loadMore(categoryId);
return loadMore(categoryId, search);
}
return orElse();
}
@ -366,9 +384,11 @@ class _$LoadMoreImpl implements _LoadMore {
}
abstract class _LoadMore implements ProductLoaderEvent {
const factory _LoadMore({final String? categoryId}) = _$LoadMoreImpl;
const factory _LoadMore({final String? categoryId, final String? search}) =
_$LoadMoreImpl;
String? get categoryId;
String? get search;
/// Create a copy of ProductLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -418,8 +438,8 @@ class _$RefreshImpl implements _Refresh {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String? categoryId) getProduct,
required TResult Function(String? categoryId) loadMore,
required TResult Function(String? categoryId, String? search) getProduct,
required TResult Function(String? categoryId, String? search) loadMore,
required TResult Function() refresh,
}) {
return refresh();
@ -428,8 +448,8 @@ class _$RefreshImpl implements _Refresh {
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String? categoryId)? getProduct,
TResult? Function(String? categoryId)? loadMore,
TResult? Function(String? categoryId, String? search)? getProduct,
TResult? Function(String? categoryId, String? search)? loadMore,
TResult? Function()? refresh,
}) {
return refresh?.call();
@ -438,8 +458,8 @@ class _$RefreshImpl implements _Refresh {
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String? categoryId)? getProduct,
TResult Function(String? categoryId)? loadMore,
TResult Function(String? categoryId, String? search)? getProduct,
TResult Function(String? categoryId, String? search)? loadMore,
TResult Function()? refresh,
required TResult orElse(),
}) {

View File

@ -2,8 +2,9 @@ part of 'product_loader_bloc.dart';
@freezed
class ProductLoaderEvent with _$ProductLoaderEvent {
const factory ProductLoaderEvent.getProduct({String? categoryId}) =
_GetProduct;
const factory ProductLoaderEvent.loadMore({String? categoryId}) = _LoadMore;
const factory ProductLoaderEvent.getProduct(
{String? categoryId, String? search}) = _GetProduct;
const factory ProductLoaderEvent.loadMore(
{String? categoryId, String? search}) = _LoadMore;
const factory ProductLoaderEvent.refresh() = _Refresh;
}

View File

@ -103,7 +103,8 @@ class _HomePageState extends State<HomePage> {
}).toList();
}
bool _handleScrollNotification(ScrollNotification notification) {
bool _handleScrollNotification(
ScrollNotification notification, String? categoryId) {
// Check if the ScrollController is attached before accessing position
if (!scrollController.hasClients) {
return false;
@ -111,9 +112,12 @@ class _HomePageState extends State<HomePage> {
if (notification is ScrollEndNotification &&
scrollController.position.extentAfter == 0) {
context
.read<ProductLoaderBloc>()
.add(const ProductLoaderEvent.loadMore());
context.read<ProductLoaderBloc>().add(
ProductLoaderEvent.loadMore(
categoryId: categoryId,
search: searchQuery,
),
);
return true;
}
return false;
@ -147,42 +151,46 @@ class _HomePageState extends State<HomePage> {
flex: 3,
child: Align(
alignment: AlignmentDirectional.topStart,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
HomeTitle(
controller: searchController,
onChanged: (value) {
setState(() {
searchQuery = value;
});
},
),
BlocBuilder<ProductLoaderBloc, ProductLoaderState>(
builder: (context, state) {
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
return state.maybeWhen(
orElse: () => false,
loaded: (products, hasReachedMax, currentPage,
isLoadingMore) {
return _handleScrollNotification(
notification);
},
);
},
child: Expanded(child: BlocBuilder<
CategoryLoaderBloc, CategoryLoaderState>(
builder: (contextCategory, stateCateogry) {
return stateCateogry.maybeWhen(
orElse: () => SizedBox.shrink(),
loading: () {
return const Center(
child: CircularProgressIndicator(),
child: BlocBuilder<CategoryLoaderBloc, CategoryLoaderState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () => Center(
child: CircularProgressIndicator(),
),
loaded: (categories, categoryId) => Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
HomeTitle(
controller: searchController,
onChanged: (value) {
setState(() {
searchQuery = value;
});
Future.delayed(Duration(milliseconds: 600), () {
context.read<ProductLoaderBloc>().add(
ProductLoaderEvent.getProduct(
categoryId: categoryId,
search: value,
),
);
});
},
),
BlocBuilder<ProductLoaderBloc, ProductLoaderState>(
builder: (context, state) {
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
return state.maybeWhen(
orElse: () => false,
loaded: (products, hasReachedMax,
currentPage, isLoadingMore) {
return _handleScrollNotification(
notification, categoryId);
},
);
},
loaded: (categories) {
return CategoryTabBar(
child: Expanded(
child: CategoryTabBar(
categories: categories,
tabViews: categories.map((category) {
return SizedBox(
@ -228,15 +236,15 @@ class _HomePageState extends State<HomePage> {
}),
);
}).toList(),
);
},
),
),
);
},
)),
);
},
),
],
),
],
),
);
},
),
),
),

View File

@ -1,5 +1,6 @@
import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/data/models/response/category_response_model.dart';
import 'package:enaklo_pos/presentation/home/bloc/category_loader/category_loader_bloc.dart';
import 'package:enaklo_pos/presentation/home/bloc/product_loader/product_loader_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -36,6 +37,9 @@ class _CategoryTabBarState extends State<CategoryTabBar>
context.read<ProductLoaderBloc>().add(
ProductLoaderEvent.getProduct(categoryId: selectedCategoryId),
);
context
.read<CategoryLoaderBloc>()
.add(CategoryLoaderEvent.setCategoryId(selectedCategoryId ?? ""));
}
}
});