feat: Implement accept shift functionality with localization support for success messages

This commit is contained in:
Achintha Isuru
2026-03-19 15:55:27 -04:00
parent fea679b84c
commit 3d80e6b7ac
7 changed files with 50 additions and 2 deletions

View File

@@ -1362,6 +1362,7 @@
"go_to_certificates": "Go to Certificates", "go_to_certificates": "Go to Certificates",
"shift_booked": "Shift successfully booked!", "shift_booked": "Shift successfully booked!",
"shift_not_found": "Shift not found", "shift_not_found": "Shift not found",
"shift_accepted": "Shift accepted successfully!",
"shift_declined_success": "Shift declined", "shift_declined_success": "Shift declined",
"complete_account_title": "Complete Your Account", "complete_account_title": "Complete Your Account",
"complete_account_description": "Complete your account to book this shift and start earning" "complete_account_description": "Complete your account to book this shift and start earning"

View File

@@ -1357,6 +1357,7 @@
"go_to_certificates": "Ir a Certificados", "go_to_certificates": "Ir a Certificados",
"shift_booked": "¡Turno reservado con éxito!", "shift_booked": "¡Turno reservado con éxito!",
"shift_not_found": "Turno no encontrado", "shift_not_found": "Turno no encontrado",
"shift_accepted": "¡Turno aceptado con éxito!",
"shift_declined_success": "Turno rechazado", "shift_declined_success": "Turno rechazado",
"complete_account_title": "Completa Tu Cuenta", "complete_account_title": "Completa Tu Cuenta",
"complete_account_description": "Completa tu cuenta para reservar este turno y comenzar a ganar" "complete_account_description": "Completa tu cuenta para reservar este turno y comenzar a ganar"

View File

@@ -2,6 +2,7 @@ import 'package:bloc/bloc.dart';
import 'package:krow_core/core.dart'; import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart'; import 'package:krow_domain/krow_domain.dart';
import 'package:staff_shifts/src/domain/usecases/accept_shift_usecase.dart';
import 'package:staff_shifts/src/domain/usecases/apply_for_shift_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/apply_for_shift_usecase.dart';
import 'package:staff_shifts/src/domain/usecases/decline_shift_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/decline_shift_usecase.dart';
import 'package:staff_shifts/src/domain/usecases/get_profile_completion_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_profile_completion_usecase.dart';
@@ -18,10 +19,12 @@ class ShiftDetailsBloc extends Bloc<ShiftDetailsEvent, ShiftDetailsState>
required this.getShiftDetail, required this.getShiftDetail,
required this.applyForShift, required this.applyForShift,
required this.declineShift, required this.declineShift,
required this.acceptShift,
required this.getProfileCompletion, required this.getProfileCompletion,
}) : super(ShiftDetailsInitial()) { }) : super(ShiftDetailsInitial()) {
on<LoadShiftDetailsEvent>(_onLoadDetails); on<LoadShiftDetailsEvent>(_onLoadDetails);
on<BookShiftDetailsEvent>(_onBookShift); on<BookShiftDetailsEvent>(_onBookShift);
on<AcceptShiftDetailsEvent>(_onAcceptShift);
on<DeclineShiftDetailsEvent>(_onDeclineShift); on<DeclineShiftDetailsEvent>(_onDeclineShift);
} }
@@ -34,6 +37,9 @@ class ShiftDetailsBloc extends Bloc<ShiftDetailsEvent, ShiftDetailsState>
/// Use case for declining a shift. /// Use case for declining a shift.
final DeclineShiftUseCase declineShift; final DeclineShiftUseCase declineShift;
/// Use case for accepting an assigned shift.
final AcceptShiftUseCase acceptShift;
/// Use case for checking profile completion. /// Use case for checking profile completion.
final GetProfileCompletionUseCase getProfileCompletion; final GetProfileCompletionUseCase getProfileCompletion;
@@ -83,6 +89,25 @@ class ShiftDetailsBloc extends Bloc<ShiftDetailsEvent, ShiftDetailsState>
); );
} }
Future<void> _onAcceptShift(
AcceptShiftDetailsEvent event,
Emitter<ShiftDetailsState> emit,
) async {
await handleError(
emit: emit.call,
action: () async {
await acceptShift(event.shiftId);
emit(
ShiftActionSuccess(
'shift_accepted',
shiftDate: event.date,
),
);
},
onError: (String errorKey) => ShiftDetailsError(errorKey),
);
}
Future<void> _onDeclineShift( Future<void> _onDeclineShift(
DeclineShiftDetailsEvent event, DeclineShiftDetailsEvent event,
Emitter<ShiftDetailsState> emit, Emitter<ShiftDetailsState> emit,

View File

@@ -26,6 +26,21 @@ class BookShiftDetailsEvent extends ShiftDetailsEvent {
List<Object?> get props => [shiftId, roleId, date]; List<Object?> get props => [shiftId, roleId, date];
} }
/// Event dispatched when the worker accepts an already-assigned shift.
class AcceptShiftDetailsEvent extends ShiftDetailsEvent {
/// The shift to accept.
final String shiftId;
/// Optional date used for post-action navigation.
final DateTime? date;
/// Creates an [AcceptShiftDetailsEvent].
const AcceptShiftDetailsEvent(this.shiftId, {this.date});
@override
List<Object?> get props => <Object?>[shiftId, date];
}
class DeclineShiftDetailsEvent extends ShiftDetailsEvent { class DeclineShiftDetailsEvent extends ShiftDetailsEvent {
final String shiftId; final String shiftId;
const DeclineShiftDetailsEvent(this.shiftId); const DeclineShiftDetailsEvent(this.shiftId);

View File

@@ -166,9 +166,9 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
).add(DeclineShiftDetailsEvent(detail.shiftId)), ).add(DeclineShiftDetailsEvent(detail.shiftId)),
onAccept: () => onAccept: () =>
BlocProvider.of<ShiftDetailsBloc>(context).add( BlocProvider.of<ShiftDetailsBloc>(context).add(
BookShiftDetailsEvent( AcceptShiftDetailsEvent(
detail.shiftId, detail.shiftId,
roleId: detail.roleId, date: detail.date,
), ),
), ),
), ),
@@ -262,6 +262,8 @@ class _ShiftDetailsPageState extends State<ShiftDetailsPage> {
switch (key) { switch (key) {
case 'shift_booked': case 'shift_booked':
return context.t.staff_shifts.shift_details.shift_booked; return context.t.staff_shifts.shift_details.shift_booked;
case 'shift_accepted':
return context.t.staff_shifts.shift_details.shift_accepted;
case 'shift_declined_success': case 'shift_declined_success':
return context.t.staff_shifts.shift_details.shift_declined_success; return context.t.staff_shifts.shift_details.shift_declined_success;
default: default:

View File

@@ -4,6 +4,7 @@ import 'package:krow_domain/krow_domain.dart';
import 'package:staff_shifts/src/data/repositories_impl/shifts_repository_impl.dart'; import 'package:staff_shifts/src/data/repositories_impl/shifts_repository_impl.dart';
import 'package:staff_shifts/src/domain/repositories/shifts_repository_interface.dart'; import 'package:staff_shifts/src/domain/repositories/shifts_repository_interface.dart';
import 'package:staff_shifts/src/domain/usecases/accept_shift_usecase.dart';
import 'package:staff_shifts/src/domain/usecases/apply_for_shift_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/apply_for_shift_usecase.dart';
import 'package:staff_shifts/src/domain/usecases/decline_shift_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/decline_shift_usecase.dart';
import 'package:staff_shifts/src/domain/usecases/get_profile_completion_usecase.dart'; import 'package:staff_shifts/src/domain/usecases/get_profile_completion_usecase.dart';
@@ -30,6 +31,7 @@ class ShiftDetailsModule extends Module {
i.add(GetShiftDetailUseCase.new); i.add(GetShiftDetailUseCase.new);
i.add(ApplyForShiftUseCase.new); i.add(ApplyForShiftUseCase.new);
i.add(DeclineShiftUseCase.new); i.add(DeclineShiftUseCase.new);
i.add(AcceptShiftUseCase.new);
i.add(GetProfileCompletionUseCase.new); i.add(GetProfileCompletionUseCase.new);
// BLoC // BLoC
@@ -38,6 +40,7 @@ class ShiftDetailsModule extends Module {
getShiftDetail: i.get(), getShiftDetail: i.get(),
applyForShift: i.get(), applyForShift: i.get(),
declineShift: i.get(), declineShift: i.get(),
acceptShift: i.get(),
getProfileCompletion: i.get(), getProfileCompletion: i.get(),
), ),
); );

View File

@@ -74,6 +74,7 @@ class StaffShiftsModule extends Module {
getShiftDetail: i.get(), getShiftDetail: i.get(),
applyForShift: i.get(), applyForShift: i.get(),
declineShift: i.get(), declineShift: i.get(),
acceptShift: i.get(),
getProfileCompletion: i.get(), getProfileCompletion: i.get(),
), ),
); );