diff --git a/lib/application/order/order_loader/order_loader_bloc.dart b/lib/application/order/order_loader/order_loader_bloc.dart index ee3589a..5c2777b 100644 --- a/lib/application/order/order_loader/order_loader_bloc.dart +++ b/lib/application/order/order_loader/order_loader_bloc.dart @@ -21,6 +21,9 @@ class OrderLoaderBloc extends Bloc { Emitter emit, ) { return event.map( + rangeDateChanged: (e) async { + emit(state.copyWith(dateFrom: e.dateFrom, dateTo: e.dateTo)); + }, statusChanged: (e) async { emit(state.copyWith(status: e.status)); }, @@ -63,9 +66,11 @@ class OrderLoaderBloc extends Bloc { } final failureOrOrder = await _repository.get( - status: state.status, + status: state.status == 'all' ? null : state.status, page: state.page, search: state.search, + dateFrom: state.dateFrom, + dateTo: state.dateTo, ); state = failureOrOrder.fold( diff --git a/lib/application/order/order_loader/order_loader_bloc.freezed.dart b/lib/application/order/order_loader/order_loader_bloc.freezed.dart index 4aed4c0..185cea5 100644 --- a/lib/application/order/order_loader/order_loader_bloc.freezed.dart +++ b/lib/application/order/order_loader/order_loader_bloc.freezed.dart @@ -19,18 +19,22 @@ final _privateConstructorUsedError = UnsupportedError( mixin _$OrderLoaderEvent { @optionalTypeArgs TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, required TResult Function(String status) statusChanged, required TResult Function(String search) searchChanged, required TResult Function(bool isRefresh) fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult? Function(String status)? statusChanged, TResult? Function(String search)? searchChanged, TResult? Function(bool isRefresh)? fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult Function(String status)? statusChanged, TResult Function(String search)? searchChanged, TResult Function(bool isRefresh)? fetched, @@ -38,18 +42,21 @@ mixin _$OrderLoaderEvent { }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_Fetched value) fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_Fetched value)? fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, TResult Function(_StatusChanged value)? statusChanged, TResult Function(_SearchChanged value)? searchChanged, TResult Function(_Fetched value)? fetched, @@ -79,6 +86,176 @@ class _$OrderLoaderEventCopyWithImpl<$Res, $Val extends OrderLoaderEvent> /// with the given fields replaced by the non-null parameter values. } +/// @nodoc +abstract class _$$RangeDateChangedImplCopyWith<$Res> { + factory _$$RangeDateChangedImplCopyWith( + _$RangeDateChangedImpl value, + $Res Function(_$RangeDateChangedImpl) then, + ) = __$$RangeDateChangedImplCopyWithImpl<$Res>; + @useResult + $Res call({DateTime dateFrom, DateTime dateTo}); +} + +/// @nodoc +class __$$RangeDateChangedImplCopyWithImpl<$Res> + extends _$OrderLoaderEventCopyWithImpl<$Res, _$RangeDateChangedImpl> + implements _$$RangeDateChangedImplCopyWith<$Res> { + __$$RangeDateChangedImplCopyWithImpl( + _$RangeDateChangedImpl _value, + $Res Function(_$RangeDateChangedImpl) _then, + ) : super(_value, _then); + + /// Create a copy of OrderLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({Object? dateFrom = null, Object? dateTo = null}) { + return _then( + _$RangeDateChangedImpl( + null == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as DateTime, + null == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as DateTime, + ), + ); + } +} + +/// @nodoc + +class _$RangeDateChangedImpl implements _RangeDateChanged { + const _$RangeDateChangedImpl(this.dateFrom, this.dateTo); + + @override + final DateTime dateFrom; + @override + final DateTime dateTo; + + @override + String toString() { + return 'OrderLoaderEvent.rangeDateChanged(dateFrom: $dateFrom, dateTo: $dateTo)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$RangeDateChangedImpl && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo)); + } + + @override + int get hashCode => Object.hash(runtimeType, dateFrom, dateTo); + + /// Create a copy of OrderLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$RangeDateChangedImplCopyWith<_$RangeDateChangedImpl> get copyWith => + __$$RangeDateChangedImplCopyWithImpl<_$RangeDateChangedImpl>( + this, + _$identity, + ); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, + required TResult Function(String status) statusChanged, + required TResult Function(String search) searchChanged, + required TResult Function(bool isRefresh) fetched, + }) { + return rangeDateChanged(dateFrom, dateTo); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, + TResult? Function(String status)? statusChanged, + TResult? Function(String search)? searchChanged, + TResult? Function(bool isRefresh)? fetched, + }) { + return rangeDateChanged?.call(dateFrom, dateTo); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, + TResult Function(String status)? statusChanged, + TResult Function(String search)? searchChanged, + TResult Function(bool isRefresh)? fetched, + required TResult orElse(), + }) { + if (rangeDateChanged != null) { + return rangeDateChanged(dateFrom, dateTo); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, + required TResult Function(_StatusChanged value) statusChanged, + required TResult Function(_SearchChanged value) searchChanged, + required TResult Function(_Fetched value) fetched, + }) { + return rangeDateChanged(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, + TResult? Function(_StatusChanged value)? statusChanged, + TResult? Function(_SearchChanged value)? searchChanged, + TResult? Function(_Fetched value)? fetched, + }) { + return rangeDateChanged?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, + TResult Function(_StatusChanged value)? statusChanged, + TResult Function(_SearchChanged value)? searchChanged, + TResult Function(_Fetched value)? fetched, + required TResult orElse(), + }) { + if (rangeDateChanged != null) { + return rangeDateChanged(this); + } + return orElse(); + } +} + +abstract class _RangeDateChanged implements OrderLoaderEvent { + const factory _RangeDateChanged( + final DateTime dateFrom, + final DateTime dateTo, + ) = _$RangeDateChangedImpl; + + DateTime get dateFrom; + DateTime get dateTo; + + /// Create a copy of OrderLoaderEvent + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$RangeDateChangedImplCopyWith<_$RangeDateChangedImpl> get copyWith => + throw _privateConstructorUsedError; +} + /// @nodoc abstract class _$$StatusChangedImplCopyWith<$Res> { factory _$$StatusChangedImplCopyWith( @@ -149,6 +326,8 @@ class _$StatusChangedImpl implements _StatusChanged { @override @optionalTypeArgs TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, required TResult Function(String status) statusChanged, required TResult Function(String search) searchChanged, required TResult Function(bool isRefresh) fetched, @@ -159,6 +338,7 @@ class _$StatusChangedImpl implements _StatusChanged { @override @optionalTypeArgs TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult? Function(String status)? statusChanged, TResult? Function(String search)? searchChanged, TResult? Function(bool isRefresh)? fetched, @@ -169,6 +349,7 @@ class _$StatusChangedImpl implements _StatusChanged { @override @optionalTypeArgs TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult Function(String status)? statusChanged, TResult Function(String search)? searchChanged, TResult Function(bool isRefresh)? fetched, @@ -183,6 +364,7 @@ class _$StatusChangedImpl implements _StatusChanged { @override @optionalTypeArgs TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_Fetched value) fetched, @@ -193,6 +375,7 @@ class _$StatusChangedImpl implements _StatusChanged { @override @optionalTypeArgs TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_Fetched value)? fetched, @@ -203,6 +386,7 @@ class _$StatusChangedImpl implements _StatusChanged { @override @optionalTypeArgs TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, TResult Function(_StatusChanged value)? statusChanged, TResult Function(_SearchChanged value)? searchChanged, TResult Function(_Fetched value)? fetched, @@ -297,6 +481,8 @@ class _$SearchChangedImpl implements _SearchChanged { @override @optionalTypeArgs TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, required TResult Function(String status) statusChanged, required TResult Function(String search) searchChanged, required TResult Function(bool isRefresh) fetched, @@ -307,6 +493,7 @@ class _$SearchChangedImpl implements _SearchChanged { @override @optionalTypeArgs TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult? Function(String status)? statusChanged, TResult? Function(String search)? searchChanged, TResult? Function(bool isRefresh)? fetched, @@ -317,6 +504,7 @@ class _$SearchChangedImpl implements _SearchChanged { @override @optionalTypeArgs TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult Function(String status)? statusChanged, TResult Function(String search)? searchChanged, TResult Function(bool isRefresh)? fetched, @@ -331,6 +519,7 @@ class _$SearchChangedImpl implements _SearchChanged { @override @optionalTypeArgs TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_Fetched value) fetched, @@ -341,6 +530,7 @@ class _$SearchChangedImpl implements _SearchChanged { @override @optionalTypeArgs TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_Fetched value)? fetched, @@ -351,6 +541,7 @@ class _$SearchChangedImpl implements _SearchChanged { @override @optionalTypeArgs TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, TResult Function(_StatusChanged value)? statusChanged, TResult Function(_SearchChanged value)? searchChanged, TResult Function(_Fetched value)? fetched, @@ -447,6 +638,8 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, required TResult Function(String status) statusChanged, required TResult Function(String search) searchChanged, required TResult Function(bool isRefresh) fetched, @@ -457,6 +650,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult? Function(String status)? statusChanged, TResult? Function(String search)? searchChanged, TResult? Function(bool isRefresh)? fetched, @@ -467,6 +661,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult Function(String status)? statusChanged, TResult Function(String search)? searchChanged, TResult Function(bool isRefresh)? fetched, @@ -481,6 +676,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, required TResult Function(_StatusChanged value) statusChanged, required TResult Function(_SearchChanged value) searchChanged, required TResult Function(_Fetched value) fetched, @@ -491,6 +687,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, TResult? Function(_StatusChanged value)? statusChanged, TResult? Function(_SearchChanged value)? searchChanged, TResult? Function(_Fetched value)? fetched, @@ -501,6 +698,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, TResult Function(_StatusChanged value)? statusChanged, TResult Function(_SearchChanged value)? searchChanged, TResult Function(_Fetched value)? fetched, @@ -530,11 +728,13 @@ mixin _$OrderLoaderState { List get orders => throw _privateConstructorUsedError; Option get failureOptionOrder => throw _privateConstructorUsedError; - String? get status => throw _privateConstructorUsedError; + String get status => throw _privateConstructorUsedError; String? get search => throw _privateConstructorUsedError; bool get isFetching => throw _privateConstructorUsedError; bool get hasReachedMax => throw _privateConstructorUsedError; int get page => throw _privateConstructorUsedError; + DateTime get dateFrom => throw _privateConstructorUsedError; + DateTime get dateTo => throw _privateConstructorUsedError; /// Create a copy of OrderLoaderState /// with the given fields replaced by the non-null parameter values. @@ -553,11 +753,13 @@ abstract class $OrderLoaderStateCopyWith<$Res> { $Res call({ List orders, Option failureOptionOrder, - String? status, + String status, String? search, bool isFetching, bool hasReachedMax, int page, + DateTime dateFrom, + DateTime dateTo, }); } @@ -578,11 +780,13 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState> $Res call({ Object? orders = null, Object? failureOptionOrder = null, - Object? status = freezed, + Object? status = null, Object? search = freezed, Object? isFetching = null, Object? hasReachedMax = null, Object? page = null, + Object? dateFrom = null, + Object? dateTo = null, }) { return _then( _value.copyWith( @@ -594,10 +798,10 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState> ? _value.failureOptionOrder : failureOptionOrder // ignore: cast_nullable_to_non_nullable as Option, - status: freezed == status + status: null == status ? _value.status : status // ignore: cast_nullable_to_non_nullable - as String?, + as String, search: freezed == search ? _value.search : search // ignore: cast_nullable_to_non_nullable @@ -614,6 +818,14 @@ class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState> ? _value.page : page // ignore: cast_nullable_to_non_nullable as int, + dateFrom: null == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as DateTime, + dateTo: null == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as DateTime, ) as $Val, ); @@ -632,11 +844,13 @@ abstract class _$$OrderLoaderStateImplCopyWith<$Res> $Res call({ List orders, Option failureOptionOrder, - String? status, + String status, String? search, bool isFetching, bool hasReachedMax, int page, + DateTime dateFrom, + DateTime dateTo, }); } @@ -656,11 +870,13 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res> $Res call({ Object? orders = null, Object? failureOptionOrder = null, - Object? status = freezed, + Object? status = null, Object? search = freezed, Object? isFetching = null, Object? hasReachedMax = null, Object? page = null, + Object? dateFrom = null, + Object? dateTo = null, }) { return _then( _$OrderLoaderStateImpl( @@ -672,10 +888,10 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res> ? _value.failureOptionOrder : failureOptionOrder // ignore: cast_nullable_to_non_nullable as Option, - status: freezed == status + status: null == status ? _value.status : status // ignore: cast_nullable_to_non_nullable - as String?, + as String, search: freezed == search ? _value.search : search // ignore: cast_nullable_to_non_nullable @@ -692,6 +908,14 @@ class __$$OrderLoaderStateImplCopyWithImpl<$Res> ? _value.page : page // ignore: cast_nullable_to_non_nullable as int, + dateFrom: null == dateFrom + ? _value.dateFrom + : dateFrom // ignore: cast_nullable_to_non_nullable + as DateTime, + dateTo: null == dateTo + ? _value.dateTo + : dateTo // ignore: cast_nullable_to_non_nullable + as DateTime, ), ); } @@ -703,11 +927,13 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState { const _$OrderLoaderStateImpl({ required final List orders, required this.failureOptionOrder, - this.status, + required this.status, this.search, this.isFetching = false, this.hasReachedMax = false, this.page = 1, + required this.dateFrom, + required this.dateTo, }) : _orders = orders; final List _orders; @@ -721,7 +947,7 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState { @override final Option failureOptionOrder; @override - final String? status; + final String status; @override final String? search; @override @@ -733,10 +959,14 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState { @override @JsonKey() final int page; + @override + final DateTime dateFrom; + @override + final DateTime dateTo; @override String toString() { - return 'OrderLoaderState(orders: $orders, failureOptionOrder: $failureOptionOrder, status: $status, search: $search, isFetching: $isFetching, hasReachedMax: $hasReachedMax, page: $page)'; + return 'OrderLoaderState(orders: $orders, failureOptionOrder: $failureOptionOrder, status: $status, search: $search, isFetching: $isFetching, hasReachedMax: $hasReachedMax, page: $page, dateFrom: $dateFrom, dateTo: $dateTo)'; } @override @@ -753,7 +983,10 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState { other.isFetching == isFetching) && (identical(other.hasReachedMax, hasReachedMax) || other.hasReachedMax == hasReachedMax) && - (identical(other.page, page) || other.page == page)); + (identical(other.page, page) || other.page == page) && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo)); } @override @@ -766,6 +999,8 @@ class _$OrderLoaderStateImpl implements _OrderLoaderState { isFetching, hasReachedMax, page, + dateFrom, + dateTo, ); /// Create a copy of OrderLoaderState @@ -784,11 +1019,13 @@ abstract class _OrderLoaderState implements OrderLoaderState { const factory _OrderLoaderState({ required final List orders, required final Option failureOptionOrder, - final String? status, + required final String status, final String? search, final bool isFetching, final bool hasReachedMax, final int page, + required final DateTime dateFrom, + required final DateTime dateTo, }) = _$OrderLoaderStateImpl; @override @@ -796,7 +1033,7 @@ abstract class _OrderLoaderState implements OrderLoaderState { @override Option get failureOptionOrder; @override - String? get status; + String get status; @override String? get search; @override @@ -805,6 +1042,10 @@ abstract class _OrderLoaderState implements OrderLoaderState { bool get hasReachedMax; @override int get page; + @override + DateTime get dateFrom; + @override + DateTime get dateTo; /// Create a copy of OrderLoaderState /// with the given fields replaced by the non-null parameter values. diff --git a/lib/application/order/order_loader/order_loader_event.dart b/lib/application/order/order_loader/order_loader_event.dart index 6b83945..307589b 100644 --- a/lib/application/order/order_loader/order_loader_event.dart +++ b/lib/application/order/order_loader/order_loader_event.dart @@ -2,6 +2,10 @@ part of 'order_loader_bloc.dart'; @freezed class OrderLoaderEvent with _$OrderLoaderEvent { + const factory OrderLoaderEvent.rangeDateChanged( + DateTime dateFrom, + DateTime dateTo, + ) = _RangeDateChanged; const factory OrderLoaderEvent.statusChanged(String status) = _StatusChanged; const factory OrderLoaderEvent.searchChanged(String search) = _SearchChanged; const factory OrderLoaderEvent.fetched({@Default(false) bool isRefresh}) = diff --git a/lib/application/order/order_loader/order_loader_state.dart b/lib/application/order/order_loader/order_loader_state.dart index 55e072a..cd0802a 100644 --- a/lib/application/order/order_loader/order_loader_state.dart +++ b/lib/application/order/order_loader/order_loader_state.dart @@ -5,13 +5,20 @@ class OrderLoaderState with _$OrderLoaderState { const factory OrderLoaderState({ required List orders, required Option failureOptionOrder, - String? status, + required String status, String? search, @Default(false) bool isFetching, @Default(false) bool hasReachedMax, @Default(1) int page, + required DateTime dateFrom, + required DateTime dateTo, }) = _OrderLoaderState; - factory OrderLoaderState.initial() => - OrderLoaderState(orders: [], failureOptionOrder: none()); + factory OrderLoaderState.initial() => OrderLoaderState( + orders: [], + failureOptionOrder: none(), + dateFrom: DateTime.now().subtract(const Duration(days: 30)), + dateTo: DateTime.now(), + status: 'all', + ); } diff --git a/lib/domain/order/repositories/i_order_repository.dart b/lib/domain/order/repositories/i_order_repository.dart index f36b198..8e3d008 100644 --- a/lib/domain/order/repositories/i_order_repository.dart +++ b/lib/domain/order/repositories/i_order_repository.dart @@ -6,5 +6,7 @@ abstract class IOrderRepository { int limit = 10, String? status, String? search, + required DateTime dateFrom, + required DateTime dateTo, }); } diff --git a/lib/infrastructure/order/datasource/remote_data_provider.dart b/lib/infrastructure/order/datasource/remote_data_provider.dart index bd787c7..834ac05 100644 --- a/lib/infrastructure/order/datasource/remote_data_provider.dart +++ b/lib/infrastructure/order/datasource/remote_data_provider.dart @@ -5,6 +5,7 @@ import 'package:injectable/injectable.dart'; import '../../../common/api/api_client.dart'; import '../../../common/api/api_failure.dart'; +import '../../../common/extension/extension.dart'; import '../../../common/function/app_function.dart'; import '../../../common/url/api_path.dart'; import '../../../domain/order/order.dart'; @@ -22,9 +23,16 @@ class OrderRemoteDataProvider { int limit = 10, String? status, String? search, + required DateTime dateFrom, + required DateTime dateTo, }) async { try { - Map params = {'page': page, 'limit': limit}; + Map params = { + 'page': page, + 'limit': limit, + 'date_from': dateFrom.toServerDate, + 'date_to': dateTo.toServerDate, + }; if (status != null && status.isNotEmpty) { params['status'] = status; diff --git a/lib/infrastructure/order/repositories/order_repository.dart b/lib/infrastructure/order/repositories/order_repository.dart index a80a321..bac3e8c 100644 --- a/lib/infrastructure/order/repositories/order_repository.dart +++ b/lib/infrastructure/order/repositories/order_repository.dart @@ -19,6 +19,8 @@ class OrderRepository implements IOrderRepository { int limit = 20, String? status, String? search, + required DateTime dateFrom, + required DateTime dateTo, }) async { try { final result = await _dataProvider.fetch( @@ -26,6 +28,8 @@ class OrderRepository implements IOrderRepository { limit: limit, status: status, search: search, + dateFrom: dateFrom, + dateTo: dateTo, ); if (result.hasError) { diff --git a/lib/presentation/pages/order/order_list/order_page.dart b/lib/presentation/pages/order/order_list/order_page.dart index 341e662..93f8e7b 100644 --- a/lib/presentation/pages/order/order_list/order_page.dart +++ b/lib/presentation/pages/order/order_list/order_page.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -11,7 +13,7 @@ import '../../../components/button/button.dart'; import '../../../components/spacer/spacer.dart'; import '../../../components/widgets/empty_widget.dart'; import '../../../router/app_router.gr.dart'; -import 'widgets/status_tile.dart'; +import 'widgets/filter_header_delegate.dart'; import 'widgets/order_tile.dart'; @RoutePage() @@ -38,7 +40,6 @@ class _OrderPageState extends State with TickerProviderStateMixin { final ScrollController _scrollController = ScrollController(); // Filter state - String selectedFilter = 'All'; final List filterOptions = ['All', 'Completed', 'Pending']; @override @@ -79,13 +80,27 @@ class _OrderPageState extends State with TickerProviderStateMixin { Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColor.background, - body: BlocListener( - listenWhen: (p, c) => p.status != c.status, - listener: (context, state) { - context.read().add( - OrderLoaderEvent.fetched(isRefresh: true), - ); - }, + body: MultiBlocListener( + listeners: [ + BlocListener( + listenWhen: (p, c) => p.status != c.status, + listener: (context, state) { + context.read().add( + OrderLoaderEvent.fetched(isRefresh: true), + ); + }, + ), + BlocListener( + listenWhen: (previous, current) => + previous.dateFrom != current.dateFrom || + previous.dateTo != current.dateTo, + listener: (context, state) { + context.read().add( + OrderLoaderEvent.fetched(isRefresh: true), + ); + }, + ), + ], child: BlocBuilder( builder: (context, state) { return NotificationListener( @@ -120,60 +135,36 @@ class _OrderPageState extends State with TickerProviderStateMixin { // Pinned Filter Section SliverPersistentHeader( pinned: true, - delegate: _FilterHeaderDelegate( - child: Container( - color: AppColor.background, - padding: EdgeInsets.fromLTRB( - AppValue.padding, - 10, - AppValue.padding, - 10, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: filterOptions.map((option) { - final index = filterOptions.indexOf(option); - return Padding( - padding: EdgeInsets.only( - right: index < filterOptions.length - 1 - ? 8 - : 0, - ), - child: OrderStatusTile( - label: option, - isSelected: option == selectedFilter, - onSelected: (isSelected) { - if (isSelected) { - setState(() { - selectedFilter = option; - }); - if (option.toLowerCase() == 'all') { - context.read().add( - OrderLoaderEvent.statusChanged( - '', - ), - ); - } else { - context.read().add( - OrderLoaderEvent.statusChanged( - option.toLowerCase(), - ), - ); - } - } - }, - ), - ); - }).toList(), - ), - ), - ], - ), + delegate: FilterHeaderDelegate( + backgroundColor: AppColor.background, + padding: EdgeInsets.fromLTRB( + AppValue.padding, + 10, + AppValue.padding, + 10, ), + startDate: state.dateFrom, + endDate: state.dateTo, + filterOptions: filterOptions, + selectedFilter: state.status, + onDateChanged: (startDate, endDate) { + if (startDate != null && endDate != null) { + log('Date changed'); + context.read().add( + OrderLoaderEvent.rangeDateChanged( + startDate, + endDate, + ), + ); + } + }, + onFilterChanged: (filter) { + final status = filter.toLowerCase(); + + context.read().add( + OrderLoaderEvent.statusChanged(status), + ); + }, ), ), @@ -189,13 +180,13 @@ class _OrderPageState extends State with TickerProviderStateMixin { child: Column( children: [ // Show filtered transaction count - if (selectedFilter != 'All') + if (state.status != 'all') Padding( padding: const EdgeInsets.only(bottom: 16), child: Row( children: [ Text( - '${state.orders.length} ${selectedFilter.toLowerCase()} order${state.orders.length != 1 ? 's' : ''}', + '${state.orders.length} ${state.status.toLowerCase()} order${state.orders.length != 1 ? 's' : ''}', style: TextStyle( color: AppColor.textSecondary, fontSize: 14, @@ -210,7 +201,7 @@ class _OrderPageState extends State with TickerProviderStateMixin { ? EmptyWidget( title: 'Order', message: - 'No ${selectedFilter.toLowerCase()} orders found', + 'No ${state.status.toLowerCase()} orders found', ) : ListView.builder( itemCount: state.orders.length, @@ -247,28 +238,3 @@ class _OrderPageState extends State with TickerProviderStateMixin { } // Custom delegate for pinned filter header -class _FilterHeaderDelegate extends SliverPersistentHeaderDelegate { - final Widget child; - - _FilterHeaderDelegate({required this.child}); - - @override - double get minExtent => 70; // Minimum height when collapsed - - @override - double get maxExtent => 70; // Maximum height when expanded - - @override - Widget build( - BuildContext context, - double shrinkOffset, - bool overlapsContent, - ) { - return child; - } - - @override - bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) { - return false; - } -} diff --git a/lib/presentation/pages/order/order_list/widgets/filter_header_delegate.dart b/lib/presentation/pages/order/order_list/widgets/filter_header_delegate.dart new file mode 100644 index 0000000..1d562fb --- /dev/null +++ b/lib/presentation/pages/order/order_list/widgets/filter_header_delegate.dart @@ -0,0 +1,99 @@ +import 'package:flutter/material.dart'; + +import '../../../../components/field/date_range_picker_field.dart'; +import 'status_tile.dart'; + +class FilterHeaderDelegate extends SliverPersistentHeaderDelegate { + final Color backgroundColor; + final EdgeInsets padding; + final DateTime? startDate; + final DateTime? endDate; + final List filterOptions; + final String selectedFilter; + final Function(DateTime?, DateTime?) onDateChanged; + final Function(String) onFilterChanged; + + FilterHeaderDelegate({ + required this.backgroundColor, + required this.padding, + required this.startDate, + required this.endDate, + required this.filterOptions, + required this.selectedFilter, + required this.onDateChanged, + required this.onFilterChanged, + }); + + @override + double get minExtent => 130; + + @override + double get maxExtent => 130; + + @override + Widget build( + BuildContext context, + double shrinkOffset, + bool overlapsContent, + ) { + print('FilterHeaderDelegate build called'); // Debug log + return Container( + color: backgroundColor, + padding: padding, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: DateRangePickerField( + maxDate: DateTime.now(), + startDate: startDate, + endDate: endDate, + onChanged: (start, end) { + print( + 'onChanged called in FilterHeaderDelegate: $start - $end', + ); // Debug log + onDateChanged(start, end); + }, + ), + ), + Expanded( + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: filterOptions.asMap().entries.map((entry) { + final index = entry.key; + final option = entry.value; + + return Padding( + padding: EdgeInsets.only( + right: index < filterOptions.length - 1 ? 8 : 0, + ), + child: OrderStatusTile( + label: option, + isSelected: option == selectedFilter, + onSelected: (isSelected) { + if (isSelected) { + onFilterChanged(option); + } + }, + ), + ); + }).toList(), + ), + ), + ), + ], + ), + ); + } + + @override + bool shouldRebuild(covariant FilterHeaderDelegate oldDelegate) { + return oldDelegate.startDate != startDate || + oldDelegate.endDate != endDate || + oldDelegate.selectedFilter != selectedFilter || + oldDelegate.filterOptions.length != filterOptions.length || + oldDelegate.backgroundColor != backgroundColor; + } +}