feat: Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:krow/core/application/clients/api/api_exception.dart';
|
||||
import 'package:krow/core/application/di/injectable.dart';
|
||||
import 'package:krow/core/data/models/staff/pivot.dart';
|
||||
import 'package:krow/core/entity/staff_contact_entity.dart';
|
||||
import 'package:krow/features/clock_manual/domain/clock_manual_repository.dart';
|
||||
|
||||
part 'clock_manual_event.dart';
|
||||
part 'clock_manual_state.dart';
|
||||
|
||||
class ClockManualBloc extends Bloc<ClockManualEvent, ClockManualState> {
|
||||
var staffContacts = <StaffContact>[];
|
||||
|
||||
ClockManualBloc({required this.staffContacts})
|
||||
: super(ClockManualState(
|
||||
timers: Map.fromEntries(
|
||||
staffContacts.map((e) => MapEntry(e.id, ValueNotifier<int>(0)))),
|
||||
ongoingStaffContacts: staffContacts
|
||||
.where((element) => element.status == PivotStatus.ongoing)
|
||||
.toList()
|
||||
..sort((a, b) => a.startAt.compareTo(b.startAt)),
|
||||
confirmedStaffContacts: staffContacts
|
||||
.where((element) => element.status == PivotStatus.confirmed)
|
||||
.toList()
|
||||
..sort((a, b) => a.startAt.compareTo(b.startAt)),
|
||||
)) {
|
||||
on<ChangeSelectedTabIndexClockManual>(_onChangeSelectedTabIndexStaffManual);
|
||||
on<ClockInManual>(_onClockInStaffManual);
|
||||
on<SortStaffContactsClockManual>(_sortStaffContactsClockManual);
|
||||
on<ClockOutManual>(_onClockOutStaff);
|
||||
on<CancelClockInManual>(_onCancelClockInStaffManual);
|
||||
}
|
||||
|
||||
void _onChangeSelectedTabIndexStaffManual(
|
||||
ChangeSelectedTabIndexClockManual event, Emitter<ClockManualState> emit) {
|
||||
emit(state.copyWith(selectedTabIndex: event.index));
|
||||
}
|
||||
|
||||
void _onClockInStaffManual(ClockInManual event, emit) async {
|
||||
emit(state.copyWith(inLoading: true));
|
||||
try {
|
||||
await getIt<ClockManualRepository>()
|
||||
.trackClientClockin(event.staffContact.id);
|
||||
|
||||
_startCountdownTimer(
|
||||
state.timers[event.staffContact.id]!, event.staffContact);
|
||||
} catch (e) {
|
||||
if (e is DisplayableException) {
|
||||
emit(state.copyWith(
|
||||
errorMessage: e.message,
|
||||
));
|
||||
}
|
||||
}
|
||||
emit(state.copyWith(inLoading: false));
|
||||
}
|
||||
|
||||
void _onClockOutStaff(ClockOutManual event, emit) async {
|
||||
emit(state.copyWith(inLoading: false));
|
||||
try {
|
||||
await getIt<ClockManualRepository>()
|
||||
.trackClientClockout(event.staffContact.id);
|
||||
event.staffContact.status = PivotStatus.completed;
|
||||
add(SortStaffContactsClockManual());
|
||||
} catch (e) {
|
||||
if (e is DisplayableException) {
|
||||
emit(state.copyWith(
|
||||
errorMessage: e.message,
|
||||
));
|
||||
}
|
||||
}
|
||||
emit(state.copyWith(inLoading: false));
|
||||
}
|
||||
|
||||
void _onCancelClockInStaffManual(CancelClockInManual event, emit) async {
|
||||
emit(state.copyWith(inLoading: true));
|
||||
try {
|
||||
await getIt<ClockManualRepository>().cancelClockin(event.staffContact.id);
|
||||
state.timers[event.staffContact.id]!.value = -1;
|
||||
event.staffContact.status = PivotStatus.confirmed;
|
||||
add(SortStaffContactsClockManual());
|
||||
} catch (e) {
|
||||
if (e is DisplayableException) {
|
||||
emit(state.copyWith(
|
||||
errorMessage: e.message,
|
||||
));
|
||||
}
|
||||
}
|
||||
emit(state.copyWith(inLoading: false));
|
||||
}
|
||||
|
||||
void _sortStaffContactsClockManual(SortStaffContactsClockManual event, emit) {
|
||||
emit(state.copyWith(
|
||||
ongoingStaffContacts: staffContacts
|
||||
.where((element) => element.status == PivotStatus.ongoing)
|
||||
.toList()
|
||||
..sort((a, b) => a.startAt.compareTo(b.startAt)),
|
||||
confirmedStaffContacts: staffContacts
|
||||
.where((element) => element.status == PivotStatus.confirmed)
|
||||
.toList()
|
||||
..sort((a, b) => a.startAt.compareTo(b.startAt)),
|
||||
));
|
||||
}
|
||||
|
||||
void _startCountdownTimer(ValueNotifier<int> cancelTimer, staffContact) {
|
||||
cancelTimer.value = 5;
|
||||
Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
if (cancelTimer.value > 0) {
|
||||
cancelTimer.value -= 1;
|
||||
} else if (cancelTimer.value == 0) {
|
||||
staffContact.status = PivotStatus.ongoing;
|
||||
add(SortStaffContactsClockManual());
|
||||
timer.cancel();
|
||||
} else {
|
||||
timer.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
part of 'clock_manual_bloc.dart';
|
||||
|
||||
@immutable
|
||||
sealed class ClockManualEvent {}
|
||||
|
||||
class ChangeSelectedTabIndexClockManual extends ClockManualEvent {
|
||||
final int index;
|
||||
|
||||
ChangeSelectedTabIndexClockManual(this.index);
|
||||
}
|
||||
|
||||
class ClockInManual extends ClockManualEvent {
|
||||
final StaffContact staffContact;
|
||||
|
||||
ClockInManual(this.staffContact);
|
||||
}
|
||||
|
||||
class SortStaffContactsClockManual extends ClockManualEvent {}
|
||||
|
||||
class ClockOutManual extends ClockManualEvent {
|
||||
final StaffContact staffContact;
|
||||
|
||||
ClockOutManual(this.staffContact);
|
||||
}
|
||||
|
||||
class CancelClockInManual extends ClockManualEvent {
|
||||
final StaffContact staffContact;
|
||||
|
||||
CancelClockInManual(this.staffContact);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
part of 'clock_manual_bloc.dart';
|
||||
|
||||
@immutable
|
||||
class ClockManualState {
|
||||
final List<StaffContact> confirmedStaffContacts;
|
||||
final List<StaffContact> ongoingStaffContacts;
|
||||
final int selectedTabIndex;
|
||||
final bool inLoading;
|
||||
final String? errorMessage;
|
||||
|
||||
final Map<String, ValueNotifier<int>> timers ;
|
||||
|
||||
const ClockManualState(
|
||||
{required this.confirmedStaffContacts,
|
||||
required this.ongoingStaffContacts,
|
||||
this.inLoading = false,
|
||||
this.errorMessage,
|
||||
this.timers = const {},
|
||||
this.selectedTabIndex = 0});
|
||||
|
||||
copyWith({
|
||||
List<StaffContact>? confirmedStaffContacts,
|
||||
List<StaffContact>? ongoingStaffContacts,
|
||||
bool? inLoading,
|
||||
String? errorMessage,
|
||||
int? selectedTabIndex,
|
||||
Map<String, ValueNotifier<int>>? timers,
|
||||
}) {
|
||||
return ClockManualState(
|
||||
timers: timers ?? this.timers,
|
||||
confirmedStaffContacts:
|
||||
confirmedStaffContacts ?? this.confirmedStaffContacts,
|
||||
ongoingStaffContacts: ongoingStaffContacts ?? this.ongoingStaffContacts,
|
||||
inLoading: inLoading ?? this.inLoading,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
selectedTabIndex: selectedTabIndex ?? this.selectedTabIndex,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class ClockManualRepository {
|
||||
Future<void> trackClientClockin(String positionStaffId);
|
||||
|
||||
Future<void> trackClientClockout(String positionStaffId);
|
||||
|
||||
Future<void> cancelClockin(String positionStaffId);
|
||||
}
|
||||
Reference in New Issue
Block a user