diff --git a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.dart b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.dart index 3848d7e..65dc0a8 100644 --- a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.dart +++ b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.dart @@ -24,6 +24,9 @@ class InventoryAnalyticLoaderBloc Emitter emit, ) { return event.map( + rangeDateChanged: (e) async { + emit(state.copyWith(dateFrom: e.dateFrom, dateTo: e.dateTo)); + }, fetched: (e) async { emit( state.copyWith( @@ -33,8 +36,8 @@ class InventoryAnalyticLoaderBloc ); final result = await _repository.getInventory( - dateFrom: DateTime.now().subtract(const Duration(days: 30)), - dateTo: DateTime.now(), + dateFrom: state.dateFrom, + dateTo: state.dateTo, ); var data = result.fold( diff --git a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.freezed.dart b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.freezed.dart index a069165..9a6d650 100644 --- a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.freezed.dart +++ b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_bloc.freezed.dart @@ -19,27 +19,34 @@ final _privateConstructorUsedError = UnsupportedError( mixin _$InventoryAnalyticLoaderEvent { @optionalTypeArgs TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, required TResult Function() fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult? Function()? fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult Function()? fetched, required TResult orElse(), }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, required TResult Function(_Fetched value) fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, TResult? Function(_Fetched value)? fetched, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, TResult Function(_Fetched value)? fetched, required TResult orElse(), }) => throw _privateConstructorUsedError; @@ -74,6 +81,165 @@ class _$InventoryAnalyticLoaderEventCopyWithImpl< /// 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 + _$InventoryAnalyticLoaderEventCopyWithImpl<$Res, _$RangeDateChangedImpl> + implements _$$RangeDateChangedImplCopyWith<$Res> { + __$$RangeDateChangedImplCopyWithImpl( + _$RangeDateChangedImpl _value, + $Res Function(_$RangeDateChangedImpl) _then, + ) : super(_value, _then); + + /// Create a copy of InventoryAnalyticLoaderEvent + /// 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 'InventoryAnalyticLoaderEvent.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 InventoryAnalyticLoaderEvent + /// 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() fetched, + }) { + return rangeDateChanged(dateFrom, dateTo); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, + TResult? Function()? fetched, + }) { + return rangeDateChanged?.call(dateFrom, dateTo); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, + TResult Function()? 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(_Fetched value) fetched, + }) { + return rangeDateChanged(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, + TResult? Function(_Fetched value)? fetched, + }) { + return rangeDateChanged?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, + TResult Function(_Fetched value)? fetched, + required TResult orElse(), + }) { + if (rangeDateChanged != null) { + return rangeDateChanged(this); + } + return orElse(); + } +} + +abstract class _RangeDateChanged implements InventoryAnalyticLoaderEvent { + const factory _RangeDateChanged( + final DateTime dateFrom, + final DateTime dateTo, + ) = _$RangeDateChangedImpl; + + DateTime get dateFrom; + DateTime get dateTo; + + /// Create a copy of InventoryAnalyticLoaderEvent + /// 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 _$$FetchedImplCopyWith<$Res> { factory _$$FetchedImplCopyWith( @@ -116,19 +282,27 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs - TResult when({required TResult Function() fetched}) { + TResult when({ + required TResult Function(DateTime dateFrom, DateTime dateTo) + rangeDateChanged, + required TResult Function() fetched, + }) { return fetched(); } @override @optionalTypeArgs - TResult? whenOrNull({TResult? Function()? fetched}) { + TResult? whenOrNull({ + TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, + TResult? Function()? fetched, + }) { return fetched?.call(); } @override @optionalTypeArgs TResult maybeWhen({ + TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged, TResult Function()? fetched, required TResult orElse(), }) { @@ -141,6 +315,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult map({ + required TResult Function(_RangeDateChanged value) rangeDateChanged, required TResult Function(_Fetched value) fetched, }) { return fetched(this); @@ -149,6 +324,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult? mapOrNull({ + TResult? Function(_RangeDateChanged value)? rangeDateChanged, TResult? Function(_Fetched value)? fetched, }) { return fetched?.call(this); @@ -157,6 +333,7 @@ class _$FetchedImpl implements _Fetched { @override @optionalTypeArgs TResult maybeMap({ + TResult Function(_RangeDateChanged value)? rangeDateChanged, TResult Function(_Fetched value)? fetched, required TResult orElse(), }) { @@ -177,6 +354,8 @@ mixin _$InventoryAnalyticLoaderState { Option get failureOptionInventoryAnalytic => throw _privateConstructorUsedError; bool get isFetching => throw _privateConstructorUsedError; + DateTime get dateFrom => throw _privateConstructorUsedError; + DateTime get dateTo => throw _privateConstructorUsedError; /// Create a copy of InventoryAnalyticLoaderState /// with the given fields replaced by the non-null parameter values. @@ -200,6 +379,8 @@ abstract class $InventoryAnalyticLoaderStateCopyWith<$Res> { InventoryAnalytic inventoryAnalytic, Option failureOptionInventoryAnalytic, bool isFetching, + DateTime dateFrom, + DateTime dateTo, }); $InventoryAnalyticCopyWith<$Res> get inventoryAnalytic; @@ -226,6 +407,8 @@ class _$InventoryAnalyticLoaderStateCopyWithImpl< Object? inventoryAnalytic = null, Object? failureOptionInventoryAnalytic = null, Object? isFetching = null, + Object? dateFrom = null, + Object? dateTo = null, }) { return _then( _value.copyWith( @@ -242,6 +425,14 @@ class _$InventoryAnalyticLoaderStateCopyWithImpl< ? _value.isFetching : isFetching // ignore: cast_nullable_to_non_nullable as bool, + 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, ); @@ -271,6 +462,8 @@ abstract class _$$InventoryAnalyticLoaderStateImplCopyWith<$Res> InventoryAnalytic inventoryAnalytic, Option failureOptionInventoryAnalytic, bool isFetching, + DateTime dateFrom, + DateTime dateTo, }); @override @@ -298,6 +491,8 @@ class __$$InventoryAnalyticLoaderStateImplCopyWithImpl<$Res> Object? inventoryAnalytic = null, Object? failureOptionInventoryAnalytic = null, Object? isFetching = null, + Object? dateFrom = null, + Object? dateTo = null, }) { return _then( _$InventoryAnalyticLoaderStateImpl( @@ -313,6 +508,14 @@ class __$$InventoryAnalyticLoaderStateImplCopyWithImpl<$Res> ? _value.isFetching : isFetching // ignore: cast_nullable_to_non_nullable as bool, + 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, ), ); } @@ -326,6 +529,8 @@ class _$InventoryAnalyticLoaderStateImpl required this.inventoryAnalytic, required this.failureOptionInventoryAnalytic, this.isFetching = false, + required this.dateFrom, + required this.dateTo, }); @override @@ -335,10 +540,14 @@ class _$InventoryAnalyticLoaderStateImpl @override @JsonKey() final bool isFetching; + @override + final DateTime dateFrom; + @override + final DateTime dateTo; @override String toString() { - return 'InventoryAnalyticLoaderState(inventoryAnalytic: $inventoryAnalytic, failureOptionInventoryAnalytic: $failureOptionInventoryAnalytic, isFetching: $isFetching)'; + return 'InventoryAnalyticLoaderState(inventoryAnalytic: $inventoryAnalytic, failureOptionInventoryAnalytic: $failureOptionInventoryAnalytic, isFetching: $isFetching, dateFrom: $dateFrom, dateTo: $dateTo)'; } @override @@ -355,7 +564,10 @@ class _$InventoryAnalyticLoaderStateImpl other.failureOptionInventoryAnalytic == failureOptionInventoryAnalytic) && (identical(other.isFetching, isFetching) || - other.isFetching == isFetching)); + other.isFetching == isFetching) && + (identical(other.dateFrom, dateFrom) || + other.dateFrom == dateFrom) && + (identical(other.dateTo, dateTo) || other.dateTo == dateTo)); } @override @@ -364,6 +576,8 @@ class _$InventoryAnalyticLoaderStateImpl inventoryAnalytic, failureOptionInventoryAnalytic, isFetching, + dateFrom, + dateTo, ); /// Create a copy of InventoryAnalyticLoaderState @@ -386,6 +600,8 @@ abstract class _InventoryAnalyticLoaderState required final InventoryAnalytic inventoryAnalytic, required final Option failureOptionInventoryAnalytic, final bool isFetching, + required final DateTime dateFrom, + required final DateTime dateTo, }) = _$InventoryAnalyticLoaderStateImpl; @override @@ -394,6 +610,10 @@ abstract class _InventoryAnalyticLoaderState Option get failureOptionInventoryAnalytic; @override bool get isFetching; + @override + DateTime get dateFrom; + @override + DateTime get dateTo; /// Create a copy of InventoryAnalyticLoaderState /// with the given fields replaced by the non-null parameter values. diff --git a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_event.dart b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_event.dart index 121d123..5d9a844 100644 --- a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_event.dart +++ b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_event.dart @@ -2,5 +2,9 @@ part of 'inventory_analytic_loader_bloc.dart'; @freezed class InventoryAnalyticLoaderEvent with _$InventoryAnalyticLoaderEvent { + const factory InventoryAnalyticLoaderEvent.rangeDateChanged( + DateTime dateFrom, + DateTime dateTo, + ) = _RangeDateChanged; const factory InventoryAnalyticLoaderEvent.fetched() = _Fetched; } diff --git a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_state.dart b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_state.dart index a4f7fb3..b71a7dc 100644 --- a/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_state.dart +++ b/lib/application/analytic/inventory_analytic_loader/inventory_analytic_loader_state.dart @@ -6,11 +6,15 @@ class InventoryAnalyticLoaderState with _$InventoryAnalyticLoaderState { required InventoryAnalytic inventoryAnalytic, required Option failureOptionInventoryAnalytic, @Default(false) bool isFetching, + required DateTime dateFrom, + required DateTime dateTo, }) = _InventoryAnalyticLoaderState; factory InventoryAnalyticLoaderState.initial() => InventoryAnalyticLoaderState( inventoryAnalytic: InventoryAnalytic.empty(), failureOptionInventoryAnalytic: none(), + dateFrom: DateTime.now().subtract(const Duration(days: 30)), + dateTo: DateTime.now(), ); } diff --git a/lib/presentation/pages/inventory/inventory_page.dart b/lib/presentation/pages/inventory/inventory_page.dart index f91b0f4..c864417 100644 --- a/lib/presentation/pages/inventory/inventory_page.dart +++ b/lib/presentation/pages/inventory/inventory_page.dart @@ -107,120 +107,143 @@ class _InventoryPageState extends State @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: AppColor.background, - body: - BlocBuilder< - InventoryAnalyticLoaderBloc, - InventoryAnalyticLoaderState - >( - builder: (context, state) { - return FadeTransition( - opacity: _fadeAnimation, - child: SlideTransition( - position: _slideAnimation, - child: NestedScrollView( - headerSliverBuilder: (context, innerBoxIsScrolled) { - return [ - _buildSliverAppBar(), - SliverPersistentHeader( - pinned: true, - delegate: InventorySliverTabBarDelegate( - tabBar: TabBar( - controller: _tabController, - indicator: BoxDecoration( - gradient: LinearGradient( - colors: AppColor.primaryGradient, - begin: Alignment.topLeft, - end: Alignment.bottomRight, + return BlocListener< + InventoryAnalyticLoaderBloc, + InventoryAnalyticLoaderState + >( + listenWhen: (previous, current) => + previous.dateFrom != current.dateFrom || + previous.dateTo != current.dateTo, + listener: (context, state) { + context.read().add( + InventoryAnalyticLoaderEvent.fetched(), + ); + }, + child: Scaffold( + backgroundColor: AppColor.background, + body: + BlocBuilder< + InventoryAnalyticLoaderBloc, + InventoryAnalyticLoaderState + >( + builder: (context, state) { + return FadeTransition( + opacity: _fadeAnimation, + child: SlideTransition( + position: _slideAnimation, + child: NestedScrollView( + headerSliverBuilder: (context, innerBoxIsScrolled) { + return [ + _buildSliverAppBar(), + SliverPersistentHeader( + pinned: true, + delegate: InventorySliverTabBarDelegate( + startDate: state.dateFrom, + endDate: state.dateTo, + onDateRangeChanged: (startDate, endDate) { + context.read().add( + InventoryAnalyticLoaderEvent.rangeDateChanged( + startDate!, + endDate!, + ), + ); + }, + tabBar: TabBar( + controller: _tabController, + indicator: BoxDecoration( + gradient: LinearGradient( + colors: AppColor.primaryGradient, + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(25), + boxShadow: [ + BoxShadow( + color: AppColor.primary.withOpacity(0.3), + blurRadius: 12, + offset: const Offset(0, 4), + ), + ], ), - borderRadius: BorderRadius.circular(25), - boxShadow: [ - BoxShadow( - color: AppColor.primary.withOpacity(0.3), - blurRadius: 12, - offset: const Offset(0, 4), + indicatorSize: TabBarIndicatorSize.tab, + indicatorPadding: const EdgeInsets.all(6), + labelColor: AppColor.textWhite, + unselectedLabelColor: AppColor.textSecondary, + labelStyle: const TextStyle( + fontWeight: FontWeight.w700, + fontSize: 13, + ), + unselectedLabelStyle: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 13, + ), + dividerColor: Colors.transparent, + splashFactory: NoSplash.splashFactory, + overlayColor: MaterialStateProperty.all( + Colors.transparent, + ), + tabs: [ + Tab( + height: 40, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + ), + child: const Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Icon( + Icons.inventory_2_rounded, + size: 16, + ), + SizedBox(width: 6), + Text('Produk'), + ], + ), + ), + ), + Tab( + height: 40, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + ), + child: const Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Icon( + Icons.restaurant_menu_rounded, + size: 16, + ), + SizedBox(width: 6), + Text('Bahan'), + ], + ), + ), ), ], ), - indicatorSize: TabBarIndicatorSize.tab, - indicatorPadding: const EdgeInsets.all(6), - labelColor: AppColor.textWhite, - unselectedLabelColor: AppColor.textSecondary, - labelStyle: const TextStyle( - fontWeight: FontWeight.w700, - fontSize: 13, - ), - unselectedLabelStyle: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: 13, - ), - dividerColor: Colors.transparent, - splashFactory: NoSplash.splashFactory, - overlayColor: MaterialStateProperty.all( - Colors.transparent, - ), - tabs: [ - Tab( - height: 40, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, - ), - child: const Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Icon( - Icons.inventory_2_rounded, - size: 16, - ), - SizedBox(width: 6), - Text('Produk'), - ], - ), - ), - ), - Tab( - height: 40, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, - ), - child: const Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Icon( - Icons.restaurant_menu_rounded, - size: 16, - ), - SizedBox(width: 6), - Text('Bahan'), - ], - ), - ), - ), - ], ), ), - ), - ]; - }, - body: TabBarView( - controller: _tabController, - children: [ - _buildProductTab(state.inventoryAnalytic), - _buildIngredientTab(state.inventoryAnalytic), - ], + ]; + }, + body: TabBarView( + controller: _tabController, + children: [ + _buildProductTab(state.inventoryAnalytic), + _buildIngredientTab(state.inventoryAnalytic), + ], + ), ), ), - ), - ); - }, - ), + ); + }, + ), + ), ); } diff --git a/lib/presentation/pages/inventory/widgets/tabbar_delegate.dart b/lib/presentation/pages/inventory/widgets/tabbar_delegate.dart index 22a92e3..8814d96 100644 --- a/lib/presentation/pages/inventory/widgets/tabbar_delegate.dart +++ b/lib/presentation/pages/inventory/widgets/tabbar_delegate.dart @@ -1,17 +1,26 @@ import 'package:flutter/material.dart'; import '../../../../common/theme/theme.dart'; +import '../../../components/field/date_range_picker_field.dart'; class InventorySliverTabBarDelegate extends SliverPersistentHeaderDelegate { final TabBar tabBar; + final DateTime? startDate; + final DateTime? endDate; + final Function(DateTime?, DateTime?)? onDateRangeChanged; - InventorySliverTabBarDelegate({required this.tabBar}); + InventorySliverTabBarDelegate({ + required this.tabBar, + this.startDate, + this.endDate, + this.onDateRangeChanged, + }); @override - double get minExtent => 60; + double get minExtent => 120; // Increased height to accommodate date picker @override - double get maxExtent => 60; + double get maxExtent => 120; @override Widget build( @@ -31,22 +40,40 @@ class InventorySliverTabBarDelegate extends SliverPersistentHeaderDelegate { ], ), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), - child: Container( - decoration: BoxDecoration( - color: AppColor.background, - borderRadius: BorderRadius.circular(30), - border: Border.all( - color: AppColor.primary.withOpacity(0.1), - width: 1, + child: Column( + children: [ + // Date Range Picker Section + if (onDateRangeChanged != null) + Expanded( + child: DateRangePickerField( + maxDate: DateTime.now(), + startDate: startDate, + endDate: endDate, + onChanged: onDateRangeChanged!, + ), + ), + const SizedBox(height: 8), + // Tab Bar Section + Container( + decoration: BoxDecoration( + color: AppColor.background, + borderRadius: BorderRadius.circular(30), + border: Border.all( + color: AppColor.primary.withOpacity(0.1), + width: 1, + ), + ), + child: tabBar, ), - ), - child: tabBar, + ], ), ); } @override bool shouldRebuild(InventorySliverTabBarDelegate oldDelegate) { - return false; + return oldDelegate.startDate != startDate || + oldDelegate.endDate != endDate || + oldDelegate.tabBar != tabBar; } }