feat: Implement profile completion check in shifts management

This commit is contained in:
Achintha Isuru
2026-02-19 14:54:46 -05:00
parent 4959ec1da4
commit 5fb9d75c58
5 changed files with 94 additions and 19 deletions

View File

@@ -1,6 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:krow_core/core.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:meta/meta.dart';
@@ -22,6 +23,7 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
final GetPendingAssignmentsUseCase getPendingAssignments;
final GetCancelledShiftsUseCase getCancelledShifts;
final GetHistoryShiftsUseCase getHistoryShifts;
final GetProfileCompletionUseCase getProfileCompletion;
ShiftsBloc({
required this.getMyShifts,
@@ -29,6 +31,7 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
required this.getPendingAssignments,
required this.getCancelledShifts,
required this.getHistoryShifts,
required this.getProfileCompletion,
}) : super(ShiftsInitial()) {
on<LoadShiftsEvent>(_onLoadShifts);
on<LoadHistoryShiftsEvent>(_onLoadHistoryShifts);
@@ -36,6 +39,7 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
on<LoadFindFirstEvent>(_onLoadFindFirst);
on<LoadShiftsForRangeEvent>(_onLoadShiftsForRange);
on<FilterAvailableShiftsEvent>(_onFilterAvailableShifts);
on<CheckProfileCompletionEvent>(_onCheckProfileCompletion);
}
Future<void> _onLoadShifts(
@@ -268,6 +272,25 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
}
}
Future<void> _onCheckProfileCompletion(
CheckProfileCompletionEvent event,
Emitter<ShiftsState> emit,
) async {
final currentState = state;
if (currentState is! ShiftsLoaded) return;
await handleError(
emit: emit,
action: () async {
final bool isComplete = await getProfileCompletion();
emit(currentState.copyWith(profileComplete: isComplete));
},
onError: (String errorKey) {
return currentState.copyWith(profileComplete: false);
},
);
}
List<DateTime> _getCalendarDaysForOffset(int weekOffset) {
final now = DateTime.now();
final int reactDayIndex = now.weekday == 7 ? 0 : now.weekday;

View File

@@ -54,3 +54,10 @@ class DeclineShiftEvent extends ShiftsEvent {
@override
List<Object?> get props => [shiftId];
}
class CheckProfileCompletionEvent extends ShiftsEvent {
const CheckProfileCompletionEvent();
@override
List<Object?> get props => [];
}

View File

@@ -25,6 +25,7 @@ class ShiftsLoaded extends ShiftsState {
final bool myShiftsLoaded;
final String searchQuery;
final String jobType;
final bool? profileComplete;
const ShiftsLoaded({
required this.myShifts,
@@ -39,6 +40,7 @@ class ShiftsLoaded extends ShiftsState {
required this.myShiftsLoaded,
required this.searchQuery,
required this.jobType,
this.profileComplete,
});
ShiftsLoaded copyWith({
@@ -54,6 +56,7 @@ class ShiftsLoaded extends ShiftsState {
bool? myShiftsLoaded,
String? searchQuery,
String? jobType,
bool? profileComplete,
}) {
return ShiftsLoaded(
myShifts: myShifts ?? this.myShifts,
@@ -68,6 +71,7 @@ class ShiftsLoaded extends ShiftsState {
myShiftsLoaded: myShiftsLoaded ?? this.myShiftsLoaded,
searchQuery: searchQuery ?? this.searchQuery,
jobType: jobType ?? this.jobType,
profileComplete: profileComplete ?? this.profileComplete,
);
}
@@ -85,6 +89,7 @@ class ShiftsLoaded extends ShiftsState {
myShiftsLoaded,
searchQuery,
jobType,
profileComplete ?? '',
];
}

View File

@@ -43,6 +43,8 @@ class _ShiftsPageState extends State<ShiftsPage> {
_bloc.add(LoadAvailableShiftsEvent());
}
}
// Check profile completion
_bloc.add(const CheckProfileCompletionEvent());
}
@override
@@ -138,15 +140,23 @@ class _ShiftsPageState extends State<ShiftsPage> {
// Tabs
Row(
children: [
_buildTab(
"myshifts",
t.staff_shifts.tabs.my_shifts,
UiIcons.calendar,
myShifts.length,
showCount: myShiftsLoaded,
enabled: !blockTabsForFind,
),
const SizedBox(width: UiConstants.space2),
if (state is ShiftsLoaded && state.profileComplete != false)
Expanded(
child: _buildTab(
"myshifts",
t.staff_shifts.tabs.my_shifts,
UiIcons.calendar,
myShifts.length,
showCount: myShiftsLoaded,
enabled: !blockTabsForFind && (state.profileComplete ?? false),
),
)
else
const SizedBox.shrink(),
if (state is ShiftsLoaded && state.profileComplete != false)
const SizedBox(width: UiConstants.space2)
else
const SizedBox.shrink(),
_buildTab(
"find",
t.staff_shifts.tabs.find_work,
@@ -155,15 +165,25 @@ class _ShiftsPageState extends State<ShiftsPage> {
showCount: availableLoaded,
enabled: baseLoaded,
),
const SizedBox(width: UiConstants.space2),
_buildTab(
"history",
t.staff_shifts.tabs.history,
UiIcons.clock,
historyShifts.length,
showCount: historyLoaded,
enabled: !blockTabsForFind && baseLoaded,
),
if (state is ShiftsLoaded && state.profileComplete != false)
const SizedBox(width: UiConstants.space2)
else
const SizedBox.shrink(),
if (state is ShiftsLoaded && state.profileComplete != false)
Expanded(
child: _buildTab(
"history",
t.staff_shifts.tabs.history,
UiIcons.clock,
historyShifts.length,
showCount: historyLoaded,
enabled: !blockTabsForFind &&
baseLoaded &&
(state.profileComplete ?? false),
),
)
else
const SizedBox.shrink(),
],
),
],

View File

@@ -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_my_shifts_usecase.dart';
@@ -17,6 +18,18 @@ import 'presentation/pages/shifts_page.dart';
class StaffShiftsModule extends Module {
@override
void binds(Injector i) {
// StaffConnectorRepository for profile completion
i.addLazySingleton<StaffConnectorRepository>(
() => StaffConnectorRepositoryImpl(),
);
// Profile completion use case
i.addLazySingleton<GetProfileCompletionUseCase>(
() => GetProfileCompletionUseCase(
repository: i.get<StaffConnectorRepository>(),
),
);
// Repository
i.add<ShiftsRepositoryInterface>(ShiftsRepositoryImpl.new);
@@ -32,7 +45,14 @@ class StaffShiftsModule extends Module {
i.add(GetShiftDetailsUseCase.new);
// Bloc
i.add(ShiftsBloc.new);
i.add(() => ShiftsBloc(
getMyShifts: i.get(),
getAvailableShifts: i.get(),
getPendingAssignments: i.get(),
getCancelledShifts: i.get(),
getHistoryShifts: i.get(),
getProfileCompletion: i.get(),
));
i.add(ShiftDetailsBloc.new);
}