feat: order search

This commit is contained in:
efrilm 2025-08-07 12:34:57 +07:00
parent fe92082ceb
commit ab2a59930c
5 changed files with 152 additions and 93 deletions

View File

@ -272,18 +272,26 @@ class OrderRemoteDatasource {
String status = 'completed',
required DateTime dateFrom,
required DateTime dateTo,
String? search,
}) async {
try {
final authData = await AuthLocalDataSource().getAuthData();
Map<String, dynamic> params = {
'page': page,
'limit': limit,
'status': status,
'date_from': DateFormat('dd-MM-yyyy').format(dateFrom),
'date_to': DateFormat('dd-MM-yyyy').format(dateTo),
};
if (search != null && search.isNotEmpty) {
params['search'] = search;
}
final response = await dio.get(
'${Variables.baseUrl}/api/v1/orders',
queryParameters: {
'page': page,
'limit': limit,
'status': status,
'date_from': DateFormat('dd-MM-yyyy').format(dateFrom),
'date_to': DateFormat('dd-MM-yyyy').format(dateTo),
},
queryParameters: params,
options: Options(
headers: {
'Authorization': 'Bearer ${authData.token}',

View File

@ -60,6 +60,7 @@ class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
status: event.status,
dateFrom: event.dateFrom,
dateTo: event.dateTo,
search: event.search,
);
await result.fold(
@ -108,6 +109,7 @@ class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
status: event.status,
dateFrom: event.dateFrom,
dateTo: event.dateTo,
search: event.search,
);
await result.fold(

View File

@ -18,33 +18,36 @@ final _privateConstructorUsedError = UnsupportedError(
mixin _$OrderLoaderEvent {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)
required TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)
getByStatus,
required TResult Function(String id) getById,
required TResult Function(String status, DateTime dateFrom, DateTime dateTo)
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)
loadMore,
required TResult Function(String status) refresh,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult? Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult? Function(String id)? getById,
TResult? Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult? Function(String status)? refresh,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult Function(String id)? getById,
TResult Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult Function(String status)? refresh,
required TResult orElse(),
@ -104,7 +107,12 @@ abstract class _$$GetByStatusImplCopyWith<$Res> {
_$GetByStatusImpl value, $Res Function(_$GetByStatusImpl) then) =
__$$GetByStatusImplCopyWithImpl<$Res>;
@useResult
$Res call({String status, DateTime dateFrom, DateTime dateTo, int? limit});
$Res call(
{String status,
DateTime dateFrom,
DateTime dateTo,
int? limit,
String? search});
}
/// @nodoc
@ -124,6 +132,7 @@ class __$$GetByStatusImplCopyWithImpl<$Res>
Object? dateFrom = null,
Object? dateTo = null,
Object? limit = freezed,
Object? search = freezed,
}) {
return _then(_$GetByStatusImpl(
null == status
@ -142,6 +151,10 @@ class __$$GetByStatusImplCopyWithImpl<$Res>
? _value.limit
: limit // ignore: cast_nullable_to_non_nullable
as int?,
search: freezed == search
? _value.search
: search // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@ -150,7 +163,7 @@ class __$$GetByStatusImplCopyWithImpl<$Res>
class _$GetByStatusImpl implements _GetByStatus {
const _$GetByStatusImpl(this.status,
{required this.dateFrom, required this.dateTo, this.limit});
{required this.dateFrom, required this.dateTo, this.limit, this.search});
@override
final String status;
@ -160,10 +173,12 @@ class _$GetByStatusImpl implements _GetByStatus {
final DateTime dateTo;
@override
final int? limit;
@override
final String? search;
@override
String toString() {
return 'OrderLoaderEvent.getByStatus(status: $status, dateFrom: $dateFrom, dateTo: $dateTo, limit: $limit)';
return 'OrderLoaderEvent.getByStatus(status: $status, dateFrom: $dateFrom, dateTo: $dateTo, limit: $limit, search: $search)';
}
@override
@ -175,11 +190,13 @@ class _$GetByStatusImpl implements _GetByStatus {
(identical(other.dateFrom, dateFrom) ||
other.dateFrom == dateFrom) &&
(identical(other.dateTo, dateTo) || other.dateTo == dateTo) &&
(identical(other.limit, limit) || other.limit == limit));
(identical(other.limit, limit) || other.limit == limit) &&
(identical(other.search, search) || other.search == search));
}
@override
int get hashCode => Object.hash(runtimeType, status, dateFrom, dateTo, limit);
int get hashCode =>
Object.hash(runtimeType, status, dateFrom, dateTo, limit, search);
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -192,45 +209,48 @@ class _$GetByStatusImpl implements _GetByStatus {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)
required TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)
getByStatus,
required TResult Function(String id) getById,
required TResult Function(String status, DateTime dateFrom, DateTime dateTo)
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)
loadMore,
required TResult Function(String status) refresh,
}) {
return getByStatus(status, dateFrom, dateTo, limit);
return getByStatus(status, dateFrom, dateTo, limit, search);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult? Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult? Function(String id)? getById,
TResult? Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult? Function(String status)? refresh,
}) {
return getByStatus?.call(status, dateFrom, dateTo, limit);
return getByStatus?.call(status, dateFrom, dateTo, limit, search);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult Function(String id)? getById,
TResult Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult Function(String status)? refresh,
required TResult orElse(),
}) {
if (getByStatus != null) {
return getByStatus(status, dateFrom, dateTo, limit);
return getByStatus(status, dateFrom, dateTo, limit, search);
}
return orElse();
}
@ -277,12 +297,14 @@ abstract class _GetByStatus implements OrderLoaderEvent {
const factory _GetByStatus(final String status,
{required final DateTime dateFrom,
required final DateTime dateTo,
final int? limit}) = _$GetByStatusImpl;
final int? limit,
final String? search}) = _$GetByStatusImpl;
String get status;
DateTime get dateFrom;
DateTime get dateTo;
int? get limit;
String? get search;
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -359,11 +381,12 @@ class _$GetByIdImpl implements _GetById {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)
required TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)
getByStatus,
required TResult Function(String id) getById,
required TResult Function(String status, DateTime dateFrom, DateTime dateTo)
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)
loadMore,
required TResult Function(String status) refresh,
}) {
@ -373,11 +396,12 @@ class _$GetByIdImpl implements _GetById {
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult? Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult? Function(String id)? getById,
TResult? Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult? Function(String status)? refresh,
}) {
@ -387,11 +411,12 @@ class _$GetByIdImpl implements _GetById {
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult Function(String id)? getById,
TResult Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult Function(String status)? refresh,
required TResult orElse(),
@ -458,7 +483,8 @@ abstract class _$$LoadMoreImplCopyWith<$Res> {
_$LoadMoreImpl value, $Res Function(_$LoadMoreImpl) then) =
__$$LoadMoreImplCopyWithImpl<$Res>;
@useResult
$Res call({String status, DateTime dateFrom, DateTime dateTo});
$Res call(
{String status, DateTime dateFrom, DateTime dateTo, String? search});
}
/// @nodoc
@ -477,6 +503,7 @@ class __$$LoadMoreImplCopyWithImpl<$Res>
Object? status = null,
Object? dateFrom = null,
Object? dateTo = null,
Object? search = freezed,
}) {
return _then(_$LoadMoreImpl(
null == status
@ -491,6 +518,10 @@ class __$$LoadMoreImplCopyWithImpl<$Res>
? _value.dateTo
: dateTo // ignore: cast_nullable_to_non_nullable
as DateTime,
search: freezed == search
? _value.search
: search // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
@ -499,7 +530,7 @@ class __$$LoadMoreImplCopyWithImpl<$Res>
class _$LoadMoreImpl implements _LoadMore {
const _$LoadMoreImpl(this.status,
{required this.dateFrom, required this.dateTo});
{required this.dateFrom, required this.dateTo, this.search});
@override
final String status;
@ -507,10 +538,12 @@ class _$LoadMoreImpl implements _LoadMore {
final DateTime dateFrom;
@override
final DateTime dateTo;
@override
final String? search;
@override
String toString() {
return 'OrderLoaderEvent.loadMore(status: $status, dateFrom: $dateFrom, dateTo: $dateTo)';
return 'OrderLoaderEvent.loadMore(status: $status, dateFrom: $dateFrom, dateTo: $dateTo, search: $search)';
}
@override
@ -521,11 +554,13 @@ class _$LoadMoreImpl implements _LoadMore {
(identical(other.status, status) || other.status == status) &&
(identical(other.dateFrom, dateFrom) ||
other.dateFrom == dateFrom) &&
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
(identical(other.dateTo, dateTo) || other.dateTo == dateTo) &&
(identical(other.search, search) || other.search == search));
}
@override
int get hashCode => Object.hash(runtimeType, status, dateFrom, dateTo);
int get hashCode =>
Object.hash(runtimeType, status, dateFrom, dateTo, search);
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -538,45 +573,48 @@ class _$LoadMoreImpl implements _LoadMore {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)
required TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)
getByStatus,
required TResult Function(String id) getById,
required TResult Function(String status, DateTime dateFrom, DateTime dateTo)
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)
loadMore,
required TResult Function(String status) refresh,
}) {
return loadMore(status, dateFrom, dateTo);
return loadMore(status, dateFrom, dateTo, search);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult? Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult? Function(String id)? getById,
TResult? Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult? Function(String status)? refresh,
}) {
return loadMore?.call(status, dateFrom, dateTo);
return loadMore?.call(status, dateFrom, dateTo, search);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult Function(String id)? getById,
TResult Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult Function(String status)? refresh,
required TResult orElse(),
}) {
if (loadMore != null) {
return loadMore(status, dateFrom, dateTo);
return loadMore(status, dateFrom, dateTo, search);
}
return orElse();
}
@ -622,11 +660,13 @@ class _$LoadMoreImpl implements _LoadMore {
abstract class _LoadMore implements OrderLoaderEvent {
const factory _LoadMore(final String status,
{required final DateTime dateFrom,
required final DateTime dateTo}) = _$LoadMoreImpl;
required final DateTime dateTo,
final String? search}) = _$LoadMoreImpl;
String get status;
DateTime get dateFrom;
DateTime get dateTo;
String? get search;
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@ -703,11 +743,12 @@ class _$RefreshImpl implements _Refresh {
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)
required TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)
getByStatus,
required TResult Function(String id) getById,
required TResult Function(String status, DateTime dateFrom, DateTime dateTo)
required TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)
loadMore,
required TResult Function(String status) refresh,
}) {
@ -717,11 +758,12 @@ class _$RefreshImpl implements _Refresh {
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult? Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult? Function(String id)? getById,
TResult? Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult? Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult? Function(String status)? refresh,
}) {
@ -731,11 +773,12 @@ class _$RefreshImpl implements _Refresh {
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, int? limit)?
TResult Function(String status, DateTime dateFrom, DateTime dateTo,
int? limit, String? search)?
getByStatus,
TResult Function(String id)? getById,
TResult Function(String status, DateTime dateFrom, DateTime dateTo)?
TResult Function(
String status, DateTime dateFrom, DateTime dateTo, String? search)?
loadMore,
TResult Function(String status)? refresh,
required TResult orElse(),

View File

@ -2,15 +2,19 @@ part of 'order_loader_bloc.dart';
@freezed
class OrderLoaderEvent with _$OrderLoaderEvent {
const factory OrderLoaderEvent.getByStatus(String status,
{required DateTime dateFrom,
required DateTime dateTo,
int? limit}) = _GetByStatus;
const factory OrderLoaderEvent.getByStatus(
String status, {
required DateTime dateFrom,
required DateTime dateTo,
int? limit,
String? search,
}) = _GetByStatus;
const factory OrderLoaderEvent.getById(String id) = _GetById;
const factory OrderLoaderEvent.loadMore(
String status, {
required DateTime dateFrom,
required DateTime dateTo,
String? search,
}) = _LoadMore;
const factory OrderLoaderEvent.refresh(String status) = _Refresh;
}

View File

@ -45,18 +45,6 @@ class _SalesPageState extends State<SalesPage> {
super.initState();
}
List<Order> _filterOrders(List<Order> orders) {
if (searchQuery.isEmpty) {
return orders;
}
return orders.where((order) {
final customerName = order.orderNumber?.toLowerCase() ?? "";
final queryLower = searchQuery.toLowerCase();
return customerName.contains(queryLower);
}).toList();
}
@override
Widget build(BuildContext context) {
return SafeArea(
@ -71,8 +59,13 @@ class _SalesPageState extends State<SalesPage> {
if (notification is ScrollEndNotification &&
scrollController.position.extentAfter == 0) {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.loadMore(widget.status,
dateFrom: startDate, dateTo: endDate));
OrderLoaderEvent.loadMore(
widget.status,
dateFrom: startDate,
dateTo: endDate,
search: searchQuery,
),
);
return true;
}
@ -92,6 +85,16 @@ class _SalesPageState extends State<SalesPage> {
setState(() {
searchQuery = value;
});
Future.delayed(const Duration(milliseconds: 800), () {
context.read<OrderLoaderBloc>().add(
OrderLoaderEvent.getByStatus(
widget.status,
dateFrom: startDate,
dateTo: endDate,
search: searchQuery,
),
);
});
},
onDateRangeChanged: (start, end) {
setState(() {
@ -125,8 +128,7 @@ class _SalesPageState extends State<SalesPage> {
),
loaded: (orders, totalOrder, hasReachedMax,
currentPage, isLoadingMore) {
final filtered = _filterOrders(orders);
if (filtered.isEmpty) {
if (orders.isEmpty) {
return Center(
child: Text(
"Belum ada transaksi saat ini. ",
@ -138,17 +140,17 @@ class _SalesPageState extends State<SalesPage> {
);
} else {
return ListView.builder(
itemCount: filtered.length,
itemCount: orders.length,
controller: scrollController,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
setState(() {
orderDetail = filtered[index];
orderDetail = orders[index];
});
context.read<OrderFormBloc>().add(
OrderFormEvent.started(
filtered[index]));
orders[index]));
},
child: SalesCard(
order: orders[index],