refactor: migrate shifts BLoC state management to a single state class with a status enum.
This commit is contained in:
@@ -32,7 +32,7 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
required this.getCancelledShifts,
|
required this.getCancelledShifts,
|
||||||
required this.getHistoryShifts,
|
required this.getHistoryShifts,
|
||||||
required this.getProfileCompletion,
|
required this.getProfileCompletion,
|
||||||
}) : super(ShiftsInitial()) {
|
}) : super(const ShiftsState()) {
|
||||||
on<LoadShiftsEvent>(_onLoadShifts);
|
on<LoadShiftsEvent>(_onLoadShifts);
|
||||||
on<LoadHistoryShiftsEvent>(_onLoadHistoryShifts);
|
on<LoadHistoryShiftsEvent>(_onLoadHistoryShifts);
|
||||||
on<LoadAvailableShiftsEvent>(_onLoadAvailableShifts);
|
on<LoadAvailableShiftsEvent>(_onLoadAvailableShifts);
|
||||||
@@ -46,8 +46,8 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
LoadShiftsEvent event,
|
LoadShiftsEvent event,
|
||||||
Emitter<ShiftsState> emit,
|
Emitter<ShiftsState> emit,
|
||||||
) async {
|
) async {
|
||||||
if (state is! ShiftsLoaded) {
|
if (state.status != ShiftsStatus.loaded) {
|
||||||
emit(ShiftsLoading());
|
emit(state.copyWith(status: ShiftsStatus.loading));
|
||||||
}
|
}
|
||||||
|
|
||||||
await handleError(
|
await handleError(
|
||||||
@@ -58,22 +58,26 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
GetMyShiftsArguments(start: days.first, end: days.last),
|
GetMyShiftsArguments(start: days.first, end: days.last),
|
||||||
);
|
);
|
||||||
|
|
||||||
emit(ShiftsLoaded(
|
emit(
|
||||||
myShifts: myShiftsResult,
|
state.copyWith(
|
||||||
pendingShifts: const [],
|
status: ShiftsStatus.loaded,
|
||||||
cancelledShifts: const [],
|
myShifts: myShiftsResult,
|
||||||
availableShifts: const [],
|
pendingShifts: const [],
|
||||||
historyShifts: const [],
|
cancelledShifts: const [],
|
||||||
availableLoading: false,
|
availableShifts: const [],
|
||||||
availableLoaded: false,
|
historyShifts: const [],
|
||||||
historyLoading: false,
|
availableLoading: false,
|
||||||
historyLoaded: false,
|
availableLoaded: false,
|
||||||
myShiftsLoaded: true,
|
historyLoading: false,
|
||||||
searchQuery: '',
|
historyLoaded: false,
|
||||||
jobType: 'all',
|
myShiftsLoaded: true,
|
||||||
));
|
searchQuery: '',
|
||||||
|
jobType: 'all',
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onError: (String errorKey) => ShiftsError(errorKey),
|
onError: (String errorKey) =>
|
||||||
|
state.copyWith(status: ShiftsStatus.error, errorMessage: errorKey),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,27 +85,29 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
LoadHistoryShiftsEvent event,
|
LoadHistoryShiftsEvent event,
|
||||||
Emitter<ShiftsState> emit,
|
Emitter<ShiftsState> emit,
|
||||||
) async {
|
) async {
|
||||||
final currentState = state;
|
if (state.status != ShiftsStatus.loaded) return;
|
||||||
if (currentState is! ShiftsLoaded) return;
|
if (state.historyLoading || state.historyLoaded) return;
|
||||||
if (currentState.historyLoading || currentState.historyLoaded) return;
|
|
||||||
|
|
||||||
emit(currentState.copyWith(historyLoading: true));
|
emit(state.copyWith(historyLoading: true));
|
||||||
await handleError(
|
await handleError(
|
||||||
emit: emit.call,
|
emit: emit.call,
|
||||||
action: () async {
|
action: () async {
|
||||||
final historyResult = await getHistoryShifts();
|
final historyResult = await getHistoryShifts();
|
||||||
emit(currentState.copyWith(
|
emit(
|
||||||
myShiftsLoaded: true,
|
state.copyWith(
|
||||||
historyShifts: historyResult,
|
myShiftsLoaded: true,
|
||||||
historyLoading: false,
|
historyShifts: historyResult,
|
||||||
historyLoaded: true,
|
historyLoading: false,
|
||||||
));
|
historyLoaded: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onError: (String errorKey) {
|
onError: (String errorKey) {
|
||||||
if (state is ShiftsLoaded) {
|
return state.copyWith(
|
||||||
return (state as ShiftsLoaded).copyWith(historyLoading: false);
|
historyLoading: false,
|
||||||
}
|
status: ShiftsStatus.error,
|
||||||
return ShiftsError(errorKey);
|
errorMessage: errorKey,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -110,33 +116,32 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
LoadAvailableShiftsEvent event,
|
LoadAvailableShiftsEvent event,
|
||||||
Emitter<ShiftsState> emit,
|
Emitter<ShiftsState> emit,
|
||||||
) async {
|
) async {
|
||||||
final currentState = state;
|
if (state.status != ShiftsStatus.loaded) return;
|
||||||
if (currentState is! ShiftsLoaded) return;
|
if (!event.force && (state.availableLoading || state.availableLoaded)) {
|
||||||
if (!event.force &&
|
|
||||||
(currentState.availableLoading || currentState.availableLoaded)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
emit(state.copyWith(availableLoading: true, availableLoaded: false));
|
||||||
availableLoading: true,
|
|
||||||
availableLoaded: false,
|
|
||||||
));
|
|
||||||
await handleError(
|
await handleError(
|
||||||
emit: emit.call,
|
emit: emit.call,
|
||||||
action: () async {
|
action: () async {
|
||||||
final availableResult =
|
final availableResult = await getAvailableShifts(
|
||||||
await getAvailableShifts(const GetAvailableShiftsArguments());
|
const GetAvailableShiftsArguments(),
|
||||||
emit(currentState.copyWith(
|
);
|
||||||
availableShifts: _filterPastShifts(availableResult),
|
emit(
|
||||||
availableLoading: false,
|
state.copyWith(
|
||||||
availableLoaded: true,
|
availableShifts: _filterPastShifts(availableResult),
|
||||||
));
|
availableLoading: false,
|
||||||
|
availableLoaded: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onError: (String errorKey) {
|
onError: (String errorKey) {
|
||||||
if (state is ShiftsLoaded) {
|
return state.copyWith(
|
||||||
return (state as ShiftsLoaded).copyWith(availableLoading: false);
|
availableLoading: false,
|
||||||
}
|
status: ShiftsStatus.error,
|
||||||
return ShiftsError(errorKey);
|
errorMessage: errorKey,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -145,62 +150,51 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
LoadFindFirstEvent event,
|
LoadFindFirstEvent event,
|
||||||
Emitter<ShiftsState> emit,
|
Emitter<ShiftsState> emit,
|
||||||
) async {
|
) async {
|
||||||
if (state is! ShiftsLoaded) {
|
if (state.status != ShiftsStatus.loaded) {
|
||||||
emit(const ShiftsLoaded(
|
emit(
|
||||||
myShifts: [],
|
state.copyWith(
|
||||||
pendingShifts: [],
|
status: ShiftsStatus.loading,
|
||||||
cancelledShifts: [],
|
myShifts: const [],
|
||||||
availableShifts: [],
|
pendingShifts: const [],
|
||||||
historyShifts: [],
|
cancelledShifts: const [],
|
||||||
availableLoading: false,
|
availableShifts: const [],
|
||||||
availableLoaded: false,
|
historyShifts: const [],
|
||||||
historyLoading: false,
|
availableLoading: false,
|
||||||
historyLoaded: false,
|
availableLoaded: false,
|
||||||
myShiftsLoaded: false,
|
historyLoading: false,
|
||||||
searchQuery: '',
|
historyLoaded: false,
|
||||||
jobType: 'all',
|
myShiftsLoaded: false,
|
||||||
));
|
searchQuery: '',
|
||||||
|
jobType: 'all',
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final currentState = state is ShiftsLoaded ? state as ShiftsLoaded : null;
|
if (state.availableLoaded) return;
|
||||||
if (currentState != null && currentState.availableLoaded) return;
|
|
||||||
|
|
||||||
if (currentState != null) {
|
emit(state.copyWith(availableLoading: true));
|
||||||
emit(currentState.copyWith(availableLoading: true));
|
|
||||||
}
|
|
||||||
|
|
||||||
await handleError(
|
await handleError(
|
||||||
emit: emit.call,
|
emit: emit.call,
|
||||||
action: () async {
|
action: () async {
|
||||||
final availableResult =
|
final availableResult = await getAvailableShifts(
|
||||||
await getAvailableShifts(const GetAvailableShiftsArguments());
|
const GetAvailableShiftsArguments(),
|
||||||
final loadedState = state is ShiftsLoaded
|
);
|
||||||
? state as ShiftsLoaded
|
emit(
|
||||||
: const ShiftsLoaded(
|
state.copyWith(
|
||||||
myShifts: [],
|
status: ShiftsStatus.loaded,
|
||||||
pendingShifts: [],
|
availableShifts: _filterPastShifts(availableResult),
|
||||||
cancelledShifts: [],
|
availableLoading: false,
|
||||||
availableShifts: [],
|
availableLoaded: true,
|
||||||
historyShifts: [],
|
),
|
||||||
availableLoading: true,
|
);
|
||||||
availableLoaded: false,
|
|
||||||
historyLoading: false,
|
|
||||||
historyLoaded: false,
|
|
||||||
myShiftsLoaded: false,
|
|
||||||
searchQuery: '',
|
|
||||||
jobType: 'all',
|
|
||||||
);
|
|
||||||
emit(loadedState.copyWith(
|
|
||||||
availableShifts: _filterPastShifts(availableResult),
|
|
||||||
availableLoading: false,
|
|
||||||
availableLoaded: true,
|
|
||||||
));
|
|
||||||
},
|
},
|
||||||
onError: (String errorKey) {
|
onError: (String errorKey) {
|
||||||
if (state is ShiftsLoaded) {
|
return state.copyWith(
|
||||||
return (state as ShiftsLoaded).copyWith(availableLoading: false);
|
availableLoading: false,
|
||||||
}
|
status: ShiftsStatus.error,
|
||||||
return ShiftsError(errorKey);
|
errorMessage: errorKey,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -216,31 +210,16 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
GetMyShiftsArguments(start: event.start, end: event.end),
|
GetMyShiftsArguments(start: event.start, end: event.end),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (state is ShiftsLoaded) {
|
emit(
|
||||||
final currentState = state as ShiftsLoaded;
|
state.copyWith(
|
||||||
emit(currentState.copyWith(
|
status: ShiftsStatus.loaded,
|
||||||
myShifts: myShiftsResult,
|
myShifts: myShiftsResult,
|
||||||
myShiftsLoaded: true,
|
myShiftsLoaded: true,
|
||||||
));
|
),
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
emit(ShiftsLoaded(
|
|
||||||
myShifts: myShiftsResult,
|
|
||||||
pendingShifts: const [],
|
|
||||||
cancelledShifts: const [],
|
|
||||||
availableShifts: const [],
|
|
||||||
historyShifts: const [],
|
|
||||||
availableLoading: false,
|
|
||||||
availableLoaded: false,
|
|
||||||
historyLoading: false,
|
|
||||||
historyLoaded: false,
|
|
||||||
myShiftsLoaded: true,
|
|
||||||
searchQuery: '',
|
|
||||||
jobType: 'all',
|
|
||||||
));
|
|
||||||
},
|
},
|
||||||
onError: (String errorKey) => ShiftsError(errorKey),
|
onError: (String errorKey) =>
|
||||||
|
state.copyWith(status: ShiftsStatus.error, errorMessage: errorKey),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,9 +227,8 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
FilterAvailableShiftsEvent event,
|
FilterAvailableShiftsEvent event,
|
||||||
Emitter<ShiftsState> emit,
|
Emitter<ShiftsState> emit,
|
||||||
) async {
|
) async {
|
||||||
final currentState = state;
|
if (state.status == ShiftsStatus.loaded) {
|
||||||
if (currentState is ShiftsLoaded) {
|
if (!state.availableLoaded && !state.availableLoading) {
|
||||||
if (!currentState.availableLoaded && !currentState.availableLoading) {
|
|
||||||
add(LoadAvailableShiftsEvent());
|
add(LoadAvailableShiftsEvent());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -258,21 +236,26 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
await handleError(
|
await handleError(
|
||||||
emit: emit.call,
|
emit: emit.call,
|
||||||
action: () async {
|
action: () async {
|
||||||
final result = await getAvailableShifts(GetAvailableShiftsArguments(
|
final result = await getAvailableShifts(
|
||||||
query: event.query ?? currentState.searchQuery,
|
GetAvailableShiftsArguments(
|
||||||
type: event.jobType ?? currentState.jobType,
|
query: event.query ?? state.searchQuery,
|
||||||
));
|
type: event.jobType ?? state.jobType,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
emit(currentState.copyWith(
|
emit(
|
||||||
availableShifts: _filterPastShifts(result),
|
state.copyWith(
|
||||||
searchQuery: event.query ?? currentState.searchQuery,
|
availableShifts: _filterPastShifts(result),
|
||||||
jobType: event.jobType ?? currentState.jobType,
|
searchQuery: event.query ?? state.searchQuery,
|
||||||
));
|
jobType: event.jobType ?? state.jobType,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onError: (String errorKey) {
|
onError: (String errorKey) {
|
||||||
// Stay on current state for filtering errors, maybe show a snackbar?
|
return state.copyWith(
|
||||||
// For now just logging is enough via handleError mixin.
|
status: ShiftsStatus.error,
|
||||||
return currentState;
|
errorMessage: errorKey,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -282,17 +265,14 @@ class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState>
|
|||||||
CheckProfileCompletionEvent event,
|
CheckProfileCompletionEvent event,
|
||||||
Emitter<ShiftsState> emit,
|
Emitter<ShiftsState> emit,
|
||||||
) async {
|
) async {
|
||||||
final currentState = state;
|
|
||||||
if (currentState is! ShiftsLoaded) return;
|
|
||||||
|
|
||||||
await handleError(
|
await handleError(
|
||||||
emit: emit.call,
|
emit: emit.call,
|
||||||
action: () async {
|
action: () async {
|
||||||
final bool isComplete = await getProfileCompletion();
|
final bool isComplete = await getProfileCompletion();
|
||||||
emit(currentState.copyWith(profileComplete: isComplete));
|
emit(state.copyWith(profileComplete: isComplete));
|
||||||
},
|
},
|
||||||
onError: (String errorKey) {
|
onError: (String errorKey) {
|
||||||
return currentState.copyWith(profileComplete: false);
|
return state.copyWith(profileComplete: false);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,9 @@
|
|||||||
part of 'shifts_bloc.dart';
|
part of 'shifts_bloc.dart';
|
||||||
|
|
||||||
@immutable
|
enum ShiftsStatus { initial, loading, loaded, error }
|
||||||
sealed class ShiftsState extends Equatable {
|
|
||||||
const ShiftsState();
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object> get props => [];
|
|
||||||
}
|
|
||||||
|
|
||||||
class ShiftsInitial extends ShiftsState {}
|
class ShiftsState extends Equatable {
|
||||||
|
final ShiftsStatus status;
|
||||||
class ShiftsLoading extends ShiftsState {}
|
|
||||||
|
|
||||||
class ShiftsLoaded extends ShiftsState {
|
|
||||||
final List<Shift> myShifts;
|
final List<Shift> myShifts;
|
||||||
final List<Shift> pendingShifts;
|
final List<Shift> pendingShifts;
|
||||||
final List<Shift> cancelledShifts;
|
final List<Shift> cancelledShifts;
|
||||||
@@ -26,24 +17,28 @@ class ShiftsLoaded extends ShiftsState {
|
|||||||
final String searchQuery;
|
final String searchQuery;
|
||||||
final String jobType;
|
final String jobType;
|
||||||
final bool? profileComplete;
|
final bool? profileComplete;
|
||||||
|
final String? errorMessage;
|
||||||
|
|
||||||
const ShiftsLoaded({
|
const ShiftsState({
|
||||||
required this.myShifts,
|
this.status = ShiftsStatus.initial,
|
||||||
required this.pendingShifts,
|
this.myShifts = const [],
|
||||||
required this.cancelledShifts,
|
this.pendingShifts = const [],
|
||||||
required this.availableShifts,
|
this.cancelledShifts = const [],
|
||||||
required this.historyShifts,
|
this.availableShifts = const [],
|
||||||
required this.availableLoading,
|
this.historyShifts = const [],
|
||||||
required this.availableLoaded,
|
this.availableLoading = false,
|
||||||
required this.historyLoading,
|
this.availableLoaded = false,
|
||||||
required this.historyLoaded,
|
this.historyLoading = false,
|
||||||
required this.myShiftsLoaded,
|
this.historyLoaded = false,
|
||||||
required this.searchQuery,
|
this.myShiftsLoaded = false,
|
||||||
required this.jobType,
|
this.searchQuery = '',
|
||||||
|
this.jobType = 'all',
|
||||||
this.profileComplete,
|
this.profileComplete,
|
||||||
|
this.errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
ShiftsLoaded copyWith({
|
ShiftsState copyWith({
|
||||||
|
ShiftsStatus? status,
|
||||||
List<Shift>? myShifts,
|
List<Shift>? myShifts,
|
||||||
List<Shift>? pendingShifts,
|
List<Shift>? pendingShifts,
|
||||||
List<Shift>? cancelledShifts,
|
List<Shift>? cancelledShifts,
|
||||||
@@ -57,8 +52,10 @@ class ShiftsLoaded extends ShiftsState {
|
|||||||
String? searchQuery,
|
String? searchQuery,
|
||||||
String? jobType,
|
String? jobType,
|
||||||
bool? profileComplete,
|
bool? profileComplete,
|
||||||
|
String? errorMessage,
|
||||||
}) {
|
}) {
|
||||||
return ShiftsLoaded(
|
return ShiftsState(
|
||||||
|
status: status ?? this.status,
|
||||||
myShifts: myShifts ?? this.myShifts,
|
myShifts: myShifts ?? this.myShifts,
|
||||||
pendingShifts: pendingShifts ?? this.pendingShifts,
|
pendingShifts: pendingShifts ?? this.pendingShifts,
|
||||||
cancelledShifts: cancelledShifts ?? this.cancelledShifts,
|
cancelledShifts: cancelledShifts ?? this.cancelledShifts,
|
||||||
@@ -72,32 +69,26 @@ class ShiftsLoaded extends ShiftsState {
|
|||||||
searchQuery: searchQuery ?? this.searchQuery,
|
searchQuery: searchQuery ?? this.searchQuery,
|
||||||
jobType: jobType ?? this.jobType,
|
jobType: jobType ?? this.jobType,
|
||||||
profileComplete: profileComplete ?? this.profileComplete,
|
profileComplete: profileComplete ?? this.profileComplete,
|
||||||
|
errorMessage: errorMessage ?? this.errorMessage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [
|
List<Object?> get props => [
|
||||||
myShifts,
|
status,
|
||||||
pendingShifts,
|
myShifts,
|
||||||
cancelledShifts,
|
pendingShifts,
|
||||||
availableShifts,
|
cancelledShifts,
|
||||||
historyShifts,
|
availableShifts,
|
||||||
availableLoading,
|
historyShifts,
|
||||||
availableLoaded,
|
availableLoading,
|
||||||
historyLoading,
|
availableLoaded,
|
||||||
historyLoaded,
|
historyLoading,
|
||||||
myShiftsLoaded,
|
historyLoaded,
|
||||||
searchQuery,
|
myShiftsLoaded,
|
||||||
jobType,
|
searchQuery,
|
||||||
profileComplete ?? '',
|
jobType,
|
||||||
];
|
profileComplete,
|
||||||
}
|
errorMessage,
|
||||||
|
];
|
||||||
class ShiftsError extends ShiftsState {
|
|
||||||
final String message;
|
|
||||||
|
|
||||||
const ShiftsError(this.message);
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object> get props => [message];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import 'package:design_system/design_system.dart';
|
|||||||
import 'package:core_localization/core_localization.dart';
|
import 'package:core_localization/core_localization.dart';
|
||||||
import 'package:krow_domain/krow_domain.dart';
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
import '../blocs/shifts/shifts_bloc.dart';
|
import '../blocs/shifts/shifts_bloc.dart';
|
||||||
|
import '../utils/shift_tab_type.dart';
|
||||||
import '../widgets/tabs/my_shifts_tab.dart';
|
import '../widgets/tabs/my_shifts_tab.dart';
|
||||||
import '../widgets/tabs/find_shifts_tab.dart';
|
import '../widgets/tabs/find_shifts_tab.dart';
|
||||||
import '../widgets/tabs/history_shifts_tab.dart';
|
import '../widgets/tabs/history_shifts_tab.dart';
|
||||||
|
|
||||||
class ShiftsPage extends StatefulWidget {
|
class ShiftsPage extends StatefulWidget {
|
||||||
final String? initialTab;
|
final ShiftTabType? initialTab;
|
||||||
final DateTime? selectedDate;
|
final DateTime? selectedDate;
|
||||||
final bool refreshAvailable;
|
final bool refreshAvailable;
|
||||||
const ShiftsPage({
|
const ShiftsPage({
|
||||||
@@ -25,7 +26,7 @@ class ShiftsPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ShiftsPageState extends State<ShiftsPage> {
|
class _ShiftsPageState extends State<ShiftsPage> {
|
||||||
late String _activeTab;
|
late ShiftTabType _activeTab;
|
||||||
DateTime? _selectedDate;
|
DateTime? _selectedDate;
|
||||||
bool _prioritizeFind = false;
|
bool _prioritizeFind = false;
|
||||||
bool _refreshAvailable = false;
|
bool _refreshAvailable = false;
|
||||||
@@ -35,9 +36,9 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_activeTab = widget.initialTab ?? 'myshifts';
|
_activeTab = widget.initialTab ?? ShiftTabType.find;
|
||||||
_selectedDate = widget.selectedDate;
|
_selectedDate = widget.selectedDate;
|
||||||
_prioritizeFind = widget.initialTab == 'find';
|
_prioritizeFind = _activeTab == ShiftTabType.find;
|
||||||
_refreshAvailable = widget.refreshAvailable;
|
_refreshAvailable = widget.refreshAvailable;
|
||||||
_pendingAvailableRefresh = widget.refreshAvailable;
|
_pendingAvailableRefresh = widget.refreshAvailable;
|
||||||
if (_prioritizeFind) {
|
if (_prioritizeFind) {
|
||||||
@@ -45,16 +46,15 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
} else {
|
} else {
|
||||||
_bloc.add(LoadShiftsEvent());
|
_bloc.add(LoadShiftsEvent());
|
||||||
}
|
}
|
||||||
if (_activeTab == 'history') {
|
if (_activeTab == ShiftTabType.history) {
|
||||||
_bloc.add(LoadHistoryShiftsEvent());
|
_bloc.add(LoadHistoryShiftsEvent());
|
||||||
}
|
}
|
||||||
if (_activeTab == 'find') {
|
if (_activeTab == ShiftTabType.find) {
|
||||||
if (!_prioritizeFind) {
|
if (!_prioritizeFind) {
|
||||||
_bloc.add(
|
_bloc.add(LoadAvailableShiftsEvent(force: _refreshAvailable));
|
||||||
LoadAvailableShiftsEvent(force: _refreshAvailable),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check profile completion
|
// Check profile completion
|
||||||
_bloc.add(const CheckProfileCompletionEvent());
|
_bloc.add(const CheckProfileCompletionEvent());
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
if (widget.initialTab != null && widget.initialTab != _activeTab) {
|
if (widget.initialTab != null && widget.initialTab != _activeTab) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_activeTab = widget.initialTab!;
|
_activeTab = widget.initialTab!;
|
||||||
_prioritizeFind = widget.initialTab == 'find';
|
_prioritizeFind = _activeTab == ShiftTabType.find;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (widget.selectedDate != null && widget.selectedDate != _selectedDate) {
|
if (widget.selectedDate != null && widget.selectedDate != _selectedDate) {
|
||||||
@@ -86,50 +86,31 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
value: _bloc,
|
value: _bloc,
|
||||||
child: BlocConsumer<ShiftsBloc, ShiftsState>(
|
child: BlocConsumer<ShiftsBloc, ShiftsState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state is ShiftsError) {
|
if (state.status == ShiftsStatus.error &&
|
||||||
|
state.errorMessage != null) {
|
||||||
UiSnackbar.show(
|
UiSnackbar.show(
|
||||||
context,
|
context,
|
||||||
message: translateErrorKey(state.message),
|
message: translateErrorKey(state.errorMessage!),
|
||||||
type: UiSnackbarType.error,
|
type: UiSnackbarType.error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (_pendingAvailableRefresh && state is ShiftsLoaded) {
|
if (_pendingAvailableRefresh && state.status == ShiftsStatus.loaded) {
|
||||||
_pendingAvailableRefresh = false;
|
_pendingAvailableRefresh = false;
|
||||||
_bloc.add(const LoadAvailableShiftsEvent(force: true));
|
_bloc.add(const LoadAvailableShiftsEvent(force: true));
|
||||||
}
|
}
|
||||||
final bool baseLoaded = state is ShiftsLoaded;
|
final bool baseLoaded = state.status == ShiftsStatus.loaded;
|
||||||
final List<Shift> myShifts = (state is ShiftsLoaded)
|
final List<Shift> myShifts = state.myShifts;
|
||||||
? state.myShifts
|
final List<Shift> availableJobs = state.availableShifts;
|
||||||
: [];
|
final bool availableLoading = state.availableLoading;
|
||||||
final List<Shift> availableJobs = (state is ShiftsLoaded)
|
final bool availableLoaded = state.availableLoaded;
|
||||||
? state.availableShifts
|
final List<Shift> pendingAssignments = state.pendingShifts;
|
||||||
: [];
|
final List<Shift> cancelledShifts = state.cancelledShifts;
|
||||||
final bool availableLoading = (state is ShiftsLoaded)
|
final List<Shift> historyShifts = state.historyShifts;
|
||||||
? state.availableLoading
|
final bool historyLoading = state.historyLoading;
|
||||||
: false;
|
final bool historyLoaded = state.historyLoaded;
|
||||||
final bool availableLoaded = (state is ShiftsLoaded)
|
final bool myShiftsLoaded = state.myShiftsLoaded;
|
||||||
? state.availableLoaded
|
|
||||||
: false;
|
|
||||||
final List<Shift> pendingAssignments = (state is ShiftsLoaded)
|
|
||||||
? state.pendingShifts
|
|
||||||
: [];
|
|
||||||
final List<Shift> cancelledShifts = (state is ShiftsLoaded)
|
|
||||||
? state.cancelledShifts
|
|
||||||
: [];
|
|
||||||
final List<Shift> historyShifts = (state is ShiftsLoaded)
|
|
||||||
? state.historyShifts
|
|
||||||
: [];
|
|
||||||
final bool historyLoading = (state is ShiftsLoaded)
|
|
||||||
? state.historyLoading
|
|
||||||
: false;
|
|
||||||
final bool historyLoaded = (state is ShiftsLoaded)
|
|
||||||
? state.historyLoaded
|
|
||||||
: false;
|
|
||||||
final bool myShiftsLoaded = (state is ShiftsLoaded)
|
|
||||||
? state.myShiftsLoaded
|
|
||||||
: false;
|
|
||||||
final bool blockTabsForFind = _prioritizeFind && !availableLoaded;
|
final bool blockTabsForFind = _prioritizeFind && !availableLoaded;
|
||||||
|
|
||||||
// Note: "filteredJobs" logic moved to FindShiftsTab
|
// Note: "filteredJobs" logic moved to FindShiftsTab
|
||||||
@@ -160,44 +141,47 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
// Tabs
|
// Tabs
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
if (state is ShiftsLoaded && state.profileComplete != false)
|
if (state.profileComplete != false)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _buildTab(
|
child: _buildTab(
|
||||||
"myshifts",
|
ShiftTabType.myShifts,
|
||||||
t.staff_shifts.tabs.my_shifts,
|
t.staff_shifts.tabs.my_shifts,
|
||||||
UiIcons.calendar,
|
UiIcons.calendar,
|
||||||
myShifts.length,
|
myShifts.length,
|
||||||
showCount: myShiftsLoaded,
|
showCount: myShiftsLoaded,
|
||||||
enabled: !blockTabsForFind && (state.profileComplete ?? false),
|
enabled:
|
||||||
|
!blockTabsForFind &&
|
||||||
|
(state.profileComplete ?? false),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
const SizedBox.shrink(),
|
const SizedBox.shrink(),
|
||||||
if (state is ShiftsLoaded && state.profileComplete != false)
|
if (state.profileComplete != false)
|
||||||
const SizedBox(width: UiConstants.space2)
|
const SizedBox(width: UiConstants.space2)
|
||||||
else
|
else
|
||||||
const SizedBox.shrink(),
|
const SizedBox.shrink(),
|
||||||
_buildTab(
|
_buildTab(
|
||||||
"find",
|
ShiftTabType.find,
|
||||||
t.staff_shifts.tabs.find_work,
|
t.staff_shifts.tabs.find_work,
|
||||||
UiIcons.search,
|
UiIcons.search,
|
||||||
availableJobs.length,
|
availableJobs.length,
|
||||||
showCount: availableLoaded,
|
showCount: availableLoaded,
|
||||||
enabled: baseLoaded,
|
enabled: baseLoaded,
|
||||||
),
|
),
|
||||||
if (state is ShiftsLoaded && state.profileComplete != false)
|
if (state.profileComplete != false)
|
||||||
const SizedBox(width: UiConstants.space2)
|
const SizedBox(width: UiConstants.space2)
|
||||||
else
|
else
|
||||||
const SizedBox.shrink(),
|
const SizedBox.shrink(),
|
||||||
if (state is ShiftsLoaded && state.profileComplete != false)
|
if (state.profileComplete != false)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _buildTab(
|
child: _buildTab(
|
||||||
"history",
|
ShiftTabType.history,
|
||||||
t.staff_shifts.tabs.history,
|
t.staff_shifts.tabs.history,
|
||||||
UiIcons.clock,
|
UiIcons.clock,
|
||||||
historyShifts.length,
|
historyShifts.length,
|
||||||
showCount: historyLoaded,
|
showCount: historyLoaded,
|
||||||
enabled: !blockTabsForFind &&
|
enabled:
|
||||||
|
!blockTabsForFind &&
|
||||||
baseLoaded &&
|
baseLoaded &&
|
||||||
(state.profileComplete ?? false),
|
(state.profileComplete ?? false),
|
||||||
),
|
),
|
||||||
@@ -212,9 +196,9 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
|
|
||||||
// Body Content
|
// Body Content
|
||||||
Expanded(
|
Expanded(
|
||||||
child: state is ShiftsLoading
|
child: state.status == ShiftsStatus.loading
|
||||||
? const Center(child: CircularProgressIndicator())
|
? const Center(child: CircularProgressIndicator())
|
||||||
: state is ShiftsError
|
: state.status == ShiftsStatus.error
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(UiConstants.space5),
|
padding: const EdgeInsets.all(UiConstants.space5),
|
||||||
@@ -222,7 +206,7 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
translateErrorKey(state.message),
|
translateErrorKey(state.errorMessage ?? ''),
|
||||||
style: UiTypography.body2r.textSecondary,
|
style: UiTypography.body2r.textSecondary,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
@@ -258,47 +242,45 @@ class _ShiftsPageState extends State<ShiftsPage> {
|
|||||||
bool historyLoading,
|
bool historyLoading,
|
||||||
) {
|
) {
|
||||||
switch (_activeTab) {
|
switch (_activeTab) {
|
||||||
case 'myshifts':
|
case ShiftTabType.myShifts:
|
||||||
return MyShiftsTab(
|
return MyShiftsTab(
|
||||||
myShifts: myShifts,
|
myShifts: myShifts,
|
||||||
pendingAssignments: pendingAssignments,
|
pendingAssignments: pendingAssignments,
|
||||||
cancelledShifts: cancelledShifts,
|
cancelledShifts: cancelledShifts,
|
||||||
initialDate: _selectedDate,
|
initialDate: _selectedDate,
|
||||||
);
|
);
|
||||||
case 'find':
|
case ShiftTabType.find:
|
||||||
if (availableLoading) {
|
if (availableLoading) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
return FindShiftsTab(availableJobs: availableJobs);
|
return FindShiftsTab(availableJobs: availableJobs);
|
||||||
case 'history':
|
case ShiftTabType.history:
|
||||||
if (historyLoading) {
|
if (historyLoading) {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
return HistoryShiftsTab(historyShifts: historyShifts);
|
return HistoryShiftsTab(historyShifts: historyShifts);
|
||||||
default:
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTab(
|
Widget _buildTab(
|
||||||
String id,
|
ShiftTabType type,
|
||||||
String label,
|
String label,
|
||||||
IconData icon,
|
IconData icon,
|
||||||
int count, {
|
int count, {
|
||||||
bool showCount = true,
|
bool showCount = true,
|
||||||
bool enabled = true,
|
bool enabled = true,
|
||||||
}) {
|
}) {
|
||||||
final isActive = _activeTab == id;
|
final isActive = _activeTab == type;
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: !enabled
|
onTap: !enabled
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
setState(() => _activeTab = id);
|
setState(() => _activeTab = type);
|
||||||
if (id == 'history') {
|
if (type == ShiftTabType.history) {
|
||||||
_bloc.add(LoadHistoryShiftsEvent());
|
_bloc.add(LoadHistoryShiftsEvent());
|
||||||
}
|
}
|
||||||
if (id == 'find') {
|
if (type == ShiftTabType.find) {
|
||||||
_bloc.add(LoadAvailableShiftsEvent());
|
_bloc.add(LoadAvailableShiftsEvent());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
enum ShiftTabType {
|
||||||
|
myShifts,
|
||||||
|
find,
|
||||||
|
history;
|
||||||
|
|
||||||
|
static ShiftTabType fromString(String? value) {
|
||||||
|
if (value == null) return ShiftTabType.find;
|
||||||
|
switch (value.toLowerCase()) {
|
||||||
|
case 'myshifts':
|
||||||
|
return ShiftTabType.myShifts;
|
||||||
|
case 'find':
|
||||||
|
return ShiftTabType.find;
|
||||||
|
case 'history':
|
||||||
|
return ShiftTabType.history;
|
||||||
|
default:
|
||||||
|
return ShiftTabType.find;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String get id {
|
||||||
|
switch (this) {
|
||||||
|
case ShiftTabType.myShifts:
|
||||||
|
return 'myshifts';
|
||||||
|
case ShiftTabType.find:
|
||||||
|
return 'find';
|
||||||
|
case ShiftTabType.history:
|
||||||
|
return 'history';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,6 @@ class MyShiftCard extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MyShiftCardState extends State<MyShiftCard> {
|
class _MyShiftCardState extends State<MyShiftCard> {
|
||||||
|
|
||||||
String _formatTime(String time) {
|
String _formatTime(String time) {
|
||||||
if (time.isEmpty) return '';
|
if (time.isEmpty) return '';
|
||||||
try {
|
try {
|
||||||
@@ -77,22 +76,23 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
String _getShiftType() {
|
String _getShiftType() {
|
||||||
// Handling potential localization key availability
|
// Handling potential localization key availability
|
||||||
try {
|
try {
|
||||||
final String orderType = (widget.shift.orderType ?? '').toUpperCase();
|
final String orderType = (widget.shift.orderType ?? '').toUpperCase();
|
||||||
if (orderType == 'PERMANENT') {
|
if (orderType == 'PERMANENT') {
|
||||||
return t.staff_shifts.filter.long_term;
|
return t.staff_shifts.filter.long_term;
|
||||||
}
|
}
|
||||||
if (orderType == 'RECURRING') {
|
if (orderType == 'RECURRING') {
|
||||||
return t.staff_shifts.filter.multi_day;
|
return t.staff_shifts.filter.multi_day;
|
||||||
}
|
}
|
||||||
if (widget.shift.durationDays != null && widget.shift.durationDays! > 30) {
|
if (widget.shift.durationDays != null &&
|
||||||
return t.staff_shifts.filter.long_term;
|
widget.shift.durationDays! > 30) {
|
||||||
}
|
return t.staff_shifts.filter.long_term;
|
||||||
if (widget.shift.durationDays != null && widget.shift.durationDays! > 1) {
|
}
|
||||||
return t.staff_shifts.filter.multi_day;
|
if (widget.shift.durationDays != null && widget.shift.durationDays! > 1) {
|
||||||
}
|
return t.staff_shifts.filter.multi_day;
|
||||||
return t.staff_shifts.filter.one_day;
|
}
|
||||||
|
return t.staff_shifts.filter.one_day;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return "One Day";
|
return "One Day";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,34 +110,34 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
|
|
||||||
// Fallback localization if keys missing
|
// Fallback localization if keys missing
|
||||||
try {
|
try {
|
||||||
if (status == 'confirmed') {
|
if (status == 'confirmed') {
|
||||||
statusText = t.staff_shifts.status.confirmed;
|
statusText = t.staff_shifts.status.confirmed;
|
||||||
statusColor = UiColors.textLink;
|
statusColor = UiColors.textLink;
|
||||||
statusBg = UiColors.primary;
|
statusBg = UiColors.primary;
|
||||||
} else if (status == 'checked_in') {
|
} else if (status == 'checked_in') {
|
||||||
statusText = 'Checked in';
|
statusText = 'Checked in';
|
||||||
statusColor = UiColors.textSuccess;
|
statusColor = UiColors.textSuccess;
|
||||||
statusBg = UiColors.iconSuccess;
|
statusBg = UiColors.iconSuccess;
|
||||||
} else if (status == 'pending' || status == 'open') {
|
} else if (status == 'pending' || status == 'open') {
|
||||||
statusText = t.staff_shifts.status.act_now;
|
statusText = t.staff_shifts.status.act_now;
|
||||||
statusColor = UiColors.destructive;
|
statusColor = UiColors.destructive;
|
||||||
statusBg = UiColors.destructive;
|
statusBg = UiColors.destructive;
|
||||||
} else if (status == 'swap') {
|
} else if (status == 'swap') {
|
||||||
statusText = t.staff_shifts.status.swap_requested;
|
statusText = t.staff_shifts.status.swap_requested;
|
||||||
statusColor = UiColors.textWarning;
|
statusColor = UiColors.textWarning;
|
||||||
statusBg = UiColors.textWarning;
|
statusBg = UiColors.textWarning;
|
||||||
statusIcon = UiIcons.swap;
|
statusIcon = UiIcons.swap;
|
||||||
} else if (status == 'completed') {
|
} else if (status == 'completed') {
|
||||||
statusText = t.staff_shifts.status.completed;
|
statusText = t.staff_shifts.status.completed;
|
||||||
statusColor = UiColors.textSuccess;
|
statusColor = UiColors.textSuccess;
|
||||||
statusBg = UiColors.iconSuccess;
|
statusBg = UiColors.iconSuccess;
|
||||||
} else if (status == 'no_show') {
|
} else if (status == 'no_show') {
|
||||||
statusText = t.staff_shifts.status.no_show;
|
statusText = t.staff_shifts.status.no_show;
|
||||||
statusColor = UiColors.destructive;
|
statusColor = UiColors.destructive;
|
||||||
statusBg = UiColors.destructive;
|
statusBg = UiColors.destructive;
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
statusText = status?.toUpperCase() ?? "";
|
statusText = status?.toUpperCase() ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
final schedules = widget.shift.schedules ?? <ShiftSchedule>[];
|
final schedules = widget.shift.schedules ?? <ShiftSchedule>[];
|
||||||
@@ -145,8 +145,9 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
final List<ShiftSchedule> visibleSchedules = schedules.length <= 5
|
final List<ShiftSchedule> visibleSchedules = schedules.length <= 5
|
||||||
? schedules
|
? schedules
|
||||||
: schedules.take(3).toList();
|
: schedules.take(3).toList();
|
||||||
final int remainingSchedules =
|
final int remainingSchedules = schedules.length <= 5
|
||||||
schedules.length <= 5 ? 0 : schedules.length - 3;
|
? 0
|
||||||
|
: schedules.length - 3;
|
||||||
final String scheduleRange = hasSchedules
|
final String scheduleRange = hasSchedules
|
||||||
? () {
|
? () {
|
||||||
final first = schedules.first.date;
|
final first = schedules.first.date;
|
||||||
@@ -192,7 +193,9 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
children: [
|
children: [
|
||||||
if (statusIcon != null)
|
if (statusIcon != null)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: UiConstants.space2),
|
padding: const EdgeInsets.only(
|
||||||
|
right: UiConstants.space2,
|
||||||
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
statusIcon,
|
statusIcon,
|
||||||
size: UiConstants.iconXs,
|
size: UiConstants.iconXs,
|
||||||
@@ -203,7 +206,9 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
Container(
|
Container(
|
||||||
width: 8,
|
width: 8,
|
||||||
height: 8,
|
height: 8,
|
||||||
margin: const EdgeInsets.only(right: UiConstants.space2),
|
margin: const EdgeInsets.only(
|
||||||
|
right: UiConstants.space2,
|
||||||
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: statusBg,
|
color: statusBg,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
@@ -257,14 +262,18 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
end: Alignment.bottomRight,
|
end: Alignment.bottomRight,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
borderRadius: BorderRadius.circular(
|
||||||
|
UiConstants.radiusBase,
|
||||||
|
),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: UiColors.primary.withValues(alpha: 0.09),
|
color: UiColors.primary.withValues(alpha: 0.09),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: widget.shift.logoUrl != null
|
child: widget.shift.logoUrl != null
|
||||||
? ClipRRect(
|
? ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(UiConstants.radiusBase),
|
borderRadius: BorderRadius.circular(
|
||||||
|
UiConstants.radiusBase,
|
||||||
|
),
|
||||||
child: Image.network(
|
child: Image.network(
|
||||||
widget.shift.logoUrl!,
|
widget.shift.logoUrl!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
@@ -290,8 +299,7 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment:
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.shift.title,
|
widget.shift.title,
|
||||||
@@ -347,11 +355,13 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: UiConstants.space1),
|
const SizedBox(height: UiConstants.space1),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 2),
|
padding: const EdgeInsets.only(bottom: 2),
|
||||||
child: Text(
|
child: Text(
|
||||||
scheduleRange,
|
scheduleRange,
|
||||||
style: UiTypography.footnote2r.copyWith(color: UiColors.primary),
|
style: UiTypography.footnote2r.copyWith(
|
||||||
|
color: UiColors.primary,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
...visibleSchedules.map(
|
...visibleSchedules.map(
|
||||||
(schedule) => Padding(
|
(schedule) => Padding(
|
||||||
@@ -368,7 +378,9 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
Text(
|
Text(
|
||||||
'+$remainingSchedules more schedules',
|
'+$remainingSchedules more schedules',
|
||||||
style: UiTypography.footnote2r.copyWith(
|
style: UiTypography.footnote2r.copyWith(
|
||||||
color: UiColors.primary.withOpacity(0.7),
|
color: UiColors.primary.withValues(
|
||||||
|
alpha: 0.7,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -410,10 +422,11 @@ class _MyShiftCardState extends State<MyShiftCard> {
|
|||||||
Text(
|
Text(
|
||||||
'... +${widget.shift.durationDays! - 1} more days',
|
'... +${widget.shift.durationDays! - 1} more days',
|
||||||
style: UiTypography.footnote2r.copyWith(
|
style: UiTypography.footnote2r.copyWith(
|
||||||
color:
|
color: UiColors.primary.withValues(
|
||||||
UiColors.primary.withOpacity(0.7),
|
alpha: 0.7,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import 'domain/usecases/apply_for_shift_usecase.dart';
|
|||||||
import 'domain/usecases/get_shift_details_usecase.dart';
|
import 'domain/usecases/get_shift_details_usecase.dart';
|
||||||
import 'presentation/blocs/shifts/shifts_bloc.dart';
|
import 'presentation/blocs/shifts/shifts_bloc.dart';
|
||||||
import 'presentation/blocs/shift_details/shift_details_bloc.dart';
|
import 'presentation/blocs/shift_details/shift_details_bloc.dart';
|
||||||
|
import 'presentation/utils/shift_tab_type.dart';
|
||||||
import 'presentation/pages/shifts_page.dart';
|
import 'presentation/pages/shifts_page.dart';
|
||||||
|
|
||||||
class StaffShiftsModule extends Module {
|
class StaffShiftsModule extends Module {
|
||||||
@@ -45,14 +46,16 @@ class StaffShiftsModule extends Module {
|
|||||||
i.add(GetShiftDetailsUseCase.new);
|
i.add(GetShiftDetailsUseCase.new);
|
||||||
|
|
||||||
// Bloc
|
// Bloc
|
||||||
i.add(() => ShiftsBloc(
|
i.add(
|
||||||
getMyShifts: i.get(),
|
() => ShiftsBloc(
|
||||||
getAvailableShifts: i.get(),
|
getMyShifts: i.get(),
|
||||||
getPendingAssignments: i.get(),
|
getAvailableShifts: i.get(),
|
||||||
getCancelledShifts: i.get(),
|
getPendingAssignments: i.get(),
|
||||||
getHistoryShifts: i.get(),
|
getCancelledShifts: i.get(),
|
||||||
getProfileCompletion: i.get(),
|
getHistoryShifts: i.get(),
|
||||||
));
|
getProfileCompletion: i.get(),
|
||||||
|
),
|
||||||
|
);
|
||||||
i.add(ShiftDetailsBloc.new);
|
i.add(ShiftDetailsBloc.new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,8 +66,9 @@ class StaffShiftsModule extends Module {
|
|||||||
child: (_) {
|
child: (_) {
|
||||||
final args = r.args.data as Map?;
|
final args = r.args.data as Map?;
|
||||||
final queryParams = r.args.queryParams;
|
final queryParams = r.args.queryParams;
|
||||||
|
final initialTabStr = queryParams['tab'] ?? args?['initialTab'];
|
||||||
return ShiftsPage(
|
return ShiftsPage(
|
||||||
initialTab: queryParams['tab'] ?? args?['initialTab'],
|
initialTab: ShiftTabType.fromString(initialTabStr),
|
||||||
selectedDate: args?['selectedDate'],
|
selectedDate: args?['selectedDate'],
|
||||||
refreshAvailable: args?['refreshAvailable'] == true,
|
refreshAvailable: args?['refreshAvailable'] == true,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user