From 18a459a453f7cb8166482faddde2144a1637e7e5 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Thu, 19 Mar 2026 16:11:16 -0400 Subject: [PATCH] feat: Implement GetMyShiftsData use case and integrate it into ShiftsBloc for improved shift data handling --- .../lib/src/domain/models/my_shifts_data.dart | 23 ++++++++++ .../usecases/get_my_shifts_data_usecase.dart | 40 ++++++++++++++++++ .../blocs/shifts/shifts_bloc.dart | 42 +++++++++---------- .../shifts/lib/src/staff_shifts_module.dart | 3 ++ 4 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 apps/mobile/packages/features/staff/shifts/lib/src/domain/models/my_shifts_data.dart create mode 100644 apps/mobile/packages/features/staff/shifts/lib/src/domain/usecases/get_my_shifts_data_usecase.dart diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/domain/models/my_shifts_data.dart b/apps/mobile/packages/features/staff/shifts/lib/src/domain/models/my_shifts_data.dart new file mode 100644 index 00000000..42669e27 --- /dev/null +++ b/apps/mobile/packages/features/staff/shifts/lib/src/domain/models/my_shifts_data.dart @@ -0,0 +1,23 @@ +import 'package:krow_domain/krow_domain.dart'; + +/// Combined result from loading all My Shifts tab data sources. +/// +/// Holds assigned shifts, pending assignments, and cancelled shifts +/// fetched in parallel from the V2 API. +class MyShiftsData { + /// Creates a [MyShiftsData] instance. + const MyShiftsData({ + required this.assignedShifts, + required this.pendingAssignments, + required this.cancelledShifts, + }); + + /// Assigned shifts for the requested date range. + final List assignedShifts; + + /// Pending assignments awaiting worker acceptance. + final List pendingAssignments; + + /// Cancelled shift assignments. + final List cancelledShifts; +} diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/domain/usecases/get_my_shifts_data_usecase.dart b/apps/mobile/packages/features/staff/shifts/lib/src/domain/usecases/get_my_shifts_data_usecase.dart new file mode 100644 index 00000000..f6f6952c --- /dev/null +++ b/apps/mobile/packages/features/staff/shifts/lib/src/domain/usecases/get_my_shifts_data_usecase.dart @@ -0,0 +1,40 @@ +import 'package:krow_core/core.dart'; +import 'package:krow_domain/krow_domain.dart'; + +import 'package:staff_shifts/src/domain/arguments/get_my_shifts_arguments.dart'; +import 'package:staff_shifts/src/domain/models/my_shifts_data.dart'; +import 'package:staff_shifts/src/domain/repositories/shifts_repository_interface.dart'; + +/// Fetches all data needed for the My Shifts tab in a single call. +/// +/// Calls [ShiftsRepositoryInterface.getAssignedShifts], +/// [ShiftsRepositoryInterface.getPendingAssignments], and +/// [ShiftsRepositoryInterface.getCancelledShifts] in parallel and returns +/// a unified [MyShiftsData]. +class GetMyShiftsDataUseCase + extends UseCase { + /// Creates a [GetMyShiftsDataUseCase]. + GetMyShiftsDataUseCase(this._repository); + + /// The shifts repository. + final ShiftsRepositoryInterface _repository; + + /// Loads assigned, pending, and cancelled shifts for the given date range. + @override + Future call(GetAssignedShiftsArguments arguments) async { + final List results = await Future.wait(>[ + _repository.getAssignedShifts( + start: arguments.start, + end: arguments.end, + ), + _repository.getPendingAssignments(), + _repository.getCancelledShifts(), + ]); + + return MyShiftsData( + assignedShifts: results[0] as List, + pendingAssignments: results[1] as List, + cancelledShifts: results[2] as List, + ); + } +} diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart index a63992b3..7c4a6905 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shifts/shifts_bloc.dart @@ -8,9 +8,11 @@ import 'package:staff_shifts/src/domain/arguments/get_available_shifts_arguments import 'package:staff_shifts/src/domain/arguments/get_my_shifts_arguments.dart'; import 'package:staff_shifts/src/domain/usecases/accept_shift_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/decline_shift_usecase.dart'; +import 'package:staff_shifts/src/domain/models/my_shifts_data.dart'; import 'package:staff_shifts/src/domain/usecases/get_available_shifts_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_cancelled_shifts_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_history_shifts_usecase.dart'; +import 'package:staff_shifts/src/domain/usecases/get_my_shifts_data_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_my_shifts_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_pending_assignments_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_profile_completion_usecase.dart'; @@ -34,6 +36,7 @@ class ShiftsBloc extends Bloc required this.acceptShift, required this.declineShift, required this.submitForApproval, + required this.getMyShiftsData, }) : super(const ShiftsState()) { on(_onLoadShifts); on(_onLoadHistoryShifts); @@ -74,6 +77,9 @@ class ShiftsBloc extends Bloc /// Use case for submitting a shift for timesheet approval. final SubmitForApprovalUseCase submitForApproval; + /// Use case that loads assigned, pending, and cancelled shifts in parallel. + final GetMyShiftsDataUseCase getMyShiftsData; + Future _onLoadShifts( LoadShiftsEvent event, Emitter emit, @@ -86,29 +92,16 @@ class ShiftsBloc extends Bloc emit: emit.call, action: () async { final List days = getCalendarDaysForOffset(0); - - // Load assigned, pending, and cancelled shifts in parallel. - final List results = await Future.wait(>[ - getAssignedShifts( - GetAssignedShiftsArguments(start: days.first, end: days.last), - ), - getPendingAssignments(), - getCancelledShifts(), - ]); - - final List myShiftsResult = - results[0] as List; - final List pendingResult = - results[1] as List; - final List cancelledResult = - results[2] as List; + final MyShiftsData data = await getMyShiftsData( + GetAssignedShiftsArguments(start: days.first, end: days.last), + ); emit( state.copyWith( status: ShiftsStatus.loaded, - myShifts: myShiftsResult, - pendingShifts: pendingResult, - cancelledShifts: cancelledResult, + myShifts: data.assignedShifts, + pendingShifts: data.pendingAssignments, + cancelledShifts: data.cancelledShifts, availableShifts: const [], historyShifts: const [], availableLoading: false, @@ -250,18 +243,23 @@ class ShiftsBloc extends Bloc LoadShiftsForRangeEvent event, Emitter emit, ) async { - emit(state.copyWith(myShifts: const [], myShiftsLoaded: false)); + emit(state.copyWith( + myShifts: const [], + myShiftsLoaded: false, + )); await handleError( emit: emit.call, action: () async { - final List myShiftsResult = await getAssignedShifts( + final MyShiftsData data = await getMyShiftsData( GetAssignedShiftsArguments(start: event.start, end: event.end), ); emit( state.copyWith( status: ShiftsStatus.loaded, - myShifts: myShiftsResult, + myShifts: data.assignedShifts, + pendingShifts: data.pendingAssignments, + cancelledShifts: data.cancelledShifts, myShiftsLoaded: true, clearErrorMessage: true, ), diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart b/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart index dc0911ba..f7dee609 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/staff_shifts_module.dart @@ -8,6 +8,7 @@ import 'package:staff_shifts/src/domain/usecases/apply_for_shift_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_available_shifts_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_cancelled_shifts_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_history_shifts_usecase.dart'; +import 'package:staff_shifts/src/domain/usecases/get_my_shifts_data_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_my_shifts_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_pending_assignments_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_profile_completion_usecase.dart'; @@ -52,6 +53,7 @@ class StaffShiftsModule extends Module { i.addLazySingleton( () => SubmitForApprovalUseCase(i.get()), ); + i.addLazySingleton(GetMyShiftsDataUseCase.new); i.addLazySingleton(GetAvailableOrdersUseCase.new); i.addLazySingleton(BookOrderUseCase.new); @@ -67,6 +69,7 @@ class StaffShiftsModule extends Module { acceptShift: i.get(), declineShift: i.get(), submitForApproval: i.get(), + getMyShiftsData: i.get(), ), ); i.add(