From 856e7545f6978001c56ab42c858ae74655203336 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Wed, 4 Mar 2026 16:48:49 -0500 Subject: [PATCH] Implement profile completion checks in shift details flow and update UI accordingly --- .../staff_connector_repository_impl.dart | 1 - .../shift_details/shift_details_bloc.dart | 6 ++- .../shift_details/shift_details_state.dart | 5 ++- .../pages/shift_details_page.dart | 40 +++++++++++++------ .../shifts/lib/src/shift_details_module.dart | 11 +++++ .../shifts/lib/src/staff_shifts_module.dart | 20 +++++----- docs/MILESTONES/M4/demos/m4-client-note.md | 16 ++++++++ 7 files changed, 72 insertions(+), 27 deletions(-) diff --git a/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart b/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart index e5f0f4d5..770f1d68 100644 --- a/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart +++ b/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart @@ -20,7 +20,6 @@ class StaffConnectorRepositoryImpl implements StaffConnectorRepository { @override Future getProfileCompletion() async { - return true; return _service.run(() async { final String staffId = await _service.getStaffId(); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_bloc.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_bloc.dart index 5d46c536..3f5357b3 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_bloc.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_bloc.dart @@ -1,5 +1,6 @@ import 'package:bloc/bloc.dart'; import 'package:krow_core/core.dart'; +import 'package:krow_data_connect/krow_data_connect.dart'; import '../../../domain/usecases/apply_for_shift_usecase.dart'; import '../../../domain/usecases/decline_shift_usecase.dart'; import '../../../domain/usecases/get_shift_details_usecase.dart'; @@ -12,11 +13,13 @@ class ShiftDetailsBloc extends Bloc final GetShiftDetailsUseCase getShiftDetails; final ApplyForShiftUseCase applyForShift; final DeclineShiftUseCase declineShift; + final GetProfileCompletionUseCase getProfileCompletion; ShiftDetailsBloc({ required this.getShiftDetails, required this.applyForShift, required this.declineShift, + required this.getProfileCompletion, }) : super(ShiftDetailsInitial()) { on(_onLoadDetails); on(_onBookShift); @@ -34,8 +37,9 @@ class ShiftDetailsBloc extends Bloc final shift = await getShiftDetails( GetShiftDetailsArguments(shiftId: event.shiftId, roleId: event.roleId), ); + final isProfileComplete = await getProfileCompletion(); if (shift != null) { - emit(ShiftDetailsLoaded(shift)); + emit(ShiftDetailsLoaded(shift, isProfileComplete: isProfileComplete)); } else { emit(const ShiftDetailsError("Shift not found")); } diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_state.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_state.dart index cf6cda49..b9a0fbeb 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_state.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/blocs/shift_details/shift_details_state.dart @@ -14,10 +14,11 @@ class ShiftDetailsLoading extends ShiftDetailsState {} class ShiftDetailsLoaded extends ShiftDetailsState { final Shift shift; - const ShiftDetailsLoaded(this.shift); + final bool isProfileComplete; + const ShiftDetailsLoaded(this.shift, {this.isProfileComplete = false}); @override - List get props => [shift]; + List get props => [shift, isProfileComplete]; } class ShiftDetailsError extends ShiftDetailsState { diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart index 05449f48..06fd236f 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/presentation/pages/shift_details_page.dart @@ -125,6 +125,9 @@ class _ShiftDetailsPageState extends State { final Shift displayShift = widget.shift; final i18n = Translations.of(context).staff_shifts.shift_details; + final isProfileComplete = state is ShiftDetailsLoaded + ? state.isProfileComplete + : false; final duration = _calculateDuration(displayShift); final estimatedTotal = @@ -142,6 +145,16 @@ class _ShiftDetailsPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + if (!isProfileComplete) + Padding( + padding: const EdgeInsets.all(UiConstants.space6), + child: UiNoticeBanner( + title: 'Complete Your Account', + description: + 'Complete your account to book this shift and start earning', + icon: UiIcons.sparkles, + ), + ), ShiftDetailsHeader(shift: displayShift), const Divider(height: 1, thickness: 0.5), ShiftStatsRow( @@ -194,20 +207,21 @@ class _ShiftDetailsPageState extends State { ), ), ), - ShiftDetailsBottomBar( - shift: displayShift, - onApply: () => _bookShift(context, displayShift), - onDecline: () => BlocProvider.of( - context, - ).add(DeclineShiftDetailsEvent(displayShift.id)), - onAccept: () => - BlocProvider.of(context).add( - BookShiftDetailsEvent( - displayShift.id, - roleId: displayShift.roleId, + if (isProfileComplete) + ShiftDetailsBottomBar( + shift: displayShift, + onApply: () => _bookShift(context, displayShift), + onDecline: () => BlocProvider.of( + context, + ).add(DeclineShiftDetailsEvent(displayShift.id)), + onAccept: () => + BlocProvider.of(context).add( + BookShiftDetailsEvent( + displayShift.id, + roleId: displayShift.roleId, + ), ), - ), - ), + ), ], ), ); diff --git a/apps/mobile/packages/features/staff/shifts/lib/src/shift_details_module.dart b/apps/mobile/packages/features/staff/shifts/lib/src/shift_details_module.dart index f22fc524..fba55262 100644 --- a/apps/mobile/packages/features/staff/shifts/lib/src/shift_details_module.dart +++ b/apps/mobile/packages/features/staff/shifts/lib/src/shift_details_module.dart @@ -1,4 +1,5 @@ import 'package:flutter_modular/flutter_modular.dart'; +import 'package:krow_data_connect/krow_data_connect.dart'; import 'domain/repositories/shifts_repository_interface.dart'; import 'data/repositories_impl/shifts_repository_impl.dart'; import 'domain/usecases/get_shift_details_usecase.dart'; @@ -14,11 +15,21 @@ class ShiftDetailsModule extends Module { // Repository i.add(ShiftsRepositoryImpl.new); + // StaffConnectorRepository for profile completion + i.addLazySingleton( + () => StaffConnectorRepositoryImpl(), + ); + // UseCases i.add(GetShiftDetailsUseCase.new); i.add(AcceptShiftUseCase.new); i.add(DeclineShiftUseCase.new); i.add(ApplyForShiftUseCase.new); + i.addLazySingleton( + () => GetProfileCompletionUseCase( + repository: i.get(), + ), + ); // Bloc i.add(ShiftDetailsBloc.new); 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 5934588f..09866f32 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 @@ -32,18 +32,18 @@ class StaffShiftsModule extends Module { ); // Repository - i.add(ShiftsRepositoryImpl.new); + i.addLazySingleton(ShiftsRepositoryImpl.new); // UseCases - i.add(GetMyShiftsUseCase.new); - i.add(GetAvailableShiftsUseCase.new); - i.add(GetPendingAssignmentsUseCase.new); - i.add(GetCancelledShiftsUseCase.new); - i.add(GetHistoryShiftsUseCase.new); - i.add(AcceptShiftUseCase.new); - i.add(DeclineShiftUseCase.new); - i.add(ApplyForShiftUseCase.new); - i.add(GetShiftDetailsUseCase.new); + i.addLazySingleton(GetMyShiftsUseCase.new); + i.addLazySingleton(GetAvailableShiftsUseCase.new); + i.addLazySingleton(GetPendingAssignmentsUseCase.new); + i.addLazySingleton(GetCancelledShiftsUseCase.new); + i.addLazySingleton(GetHistoryShiftsUseCase.new); + i.addLazySingleton(AcceptShiftUseCase.new); + i.addLazySingleton(DeclineShiftUseCase.new); + i.addLazySingleton(ApplyForShiftUseCase.new); + i.addLazySingleton(GetShiftDetailsUseCase.new); // Bloc i.add( diff --git a/docs/MILESTONES/M4/demos/m4-client-note.md b/docs/MILESTONES/M4/demos/m4-client-note.md index 4f8c668d..a12c7ea3 100644 --- a/docs/MILESTONES/M4/demos/m4-client-note.md +++ b/docs/MILESTONES/M4/demos/m4-client-note.md @@ -54,6 +54,22 @@ M4 delivers three key areas of improvement: - OTP Code: `123456` (testing mode) - Name: "Mariana Torres" +**Note on Profile Completion:** +When a staff user hasn't completed their profile, they see an empty/incomplete state on their home screen. Currently tracked sections to mark as complete: +- Profile Information (full name, email, phone, preferred locations) +- Emergency Contact + +Future sections can be added as mandatory, such as Tax Forms, Bank Account, Documents, Certificates, and Attires. + +**Profile Blocking Rules:** +When the profile is incomplete, the following features are blocked to encourage completion: +- Clock-in page is hidden +- Payments are blocked +- "My Shifts" and History sections are hidden +- Users can view available shifts but cannot book them + +This ensures we have all necessary information for compliance and payroll before workers are allowed to work. + --- ## 3. M4 Key Deliverables