feat: Refactor code structure and optimize performance across multiple modules

This commit is contained in:
Achintha Isuru
2025-11-17 23:29:28 -05:00
parent 831570f2e0
commit a64cbd9edf
1508 changed files with 105319 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:image_picker/image_picker.dart';
import 'package:krow/core/application/clients/api/api_exception.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/features/profile/role_kit/data/models/mutate_kit_dto.dart';
import 'package:krow/features/profile/role_kit/data/staff_role_kit_repository.dart';
import 'package:krow/features/profile/role_kit/domain/bloc/role_kit_event.dart';
import 'package:krow/features/profile/role_kit/domain/bloc/role_kit_state.dart';
import 'package:krow/features/profile/role_kit/domain/role_kit_entity.dart';
import 'package:krow/features/profile/role_kit/domain/staff_role_kit_repository_impl.dart';
class RoleKitBloc extends Bloc<RoleKitEvent, RoleKitState> {
RoleKitBloc() : super(RoleKitState()) {
on<RoleKitEventFetch>(_onFetch);
on<RoleKitEventSelectRole>(_onSelectRole);
on<RoleKitEventSubmit>(_onSubmit);
on<RoleKiEventChangeState>(_onChangeState);
on<RoleKitEventUploadPhoto>(_onUploadPhoto);
on<RoleKitEventDeletePhoto>(_onDeletePhoto);
}
Future<void> _onFetch(
RoleKitEventFetch event, Emitter<RoleKitState> emit) async {
emit(state.copyWith(roleKitType: event.type, loading: true));
var roles = await getIt<StaffRoleKitRepository>().getStaffRole();
emit(state.copyWith(roles: roles, loading: false));
}
Future<void> _onSelectRole(
RoleKitEventSelectRole event, Emitter<RoleKitState> emit) async {
List<RoleKitEntity> roleKitViewModels = [];
var confirmedKits = state.roleKitType == RoleKitType.equipment
? event.role.confirmedEquipments
: event.role.confirmedUniforms;
(state.roleKitType == RoleKitType.equipment
? event.role.skill?.equipments
: event.role.skill?.uniforms)
?.forEach((item) {
var confirmed = confirmedKits
?.where((element) => element.skillKitId == item.id)
.firstOrNull;
roleKitViewModels.add(RoleKitEntity(
id: item.id,
title: item.name ?? '',
confirmed: confirmed != null,
imageUrl: confirmed?.photo,
isMandatory: (item.isRequired ?? false) || (item.photoRequired ?? false),
needPhoto: item.photoRequired ?? false));
});
emit(state.copyWith(
selectedRole: event.role, roleKitItems: roleKitViewModels));
}
void _onChangeState(
RoleKiEventChangeState event, Emitter<RoleKitState> emit) {
event.item.confirmed = !event.item.confirmed;
emit(state.copyWith(showError: false));
}
void _onUploadPhoto(
RoleKitEventUploadPhoto event, Emitter<RoleKitState> emit) async {
event.item.uploading = true;
emit(state.copyWith(showError: false));
try {
var image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image != null) {
var imagePath = image.path;
var result =
await getIt<StaffRoleKitRepository>().uploadImage(imagePath);
event.item.uploading = false;
event.item.imageToken = result['token'];
event.item.imageUrl = result['url'];
event.item.localImage = imagePath;
}
} catch(e){
if (e is DisplayableException) {
emit(state.copyWith(apiError: e.message,loading: false));
}
}finally {
event.item.uploading = false;
emit(state.copyWith());
}
}
void _onSubmit(RoleKitEventSubmit event, Emitter<RoleKitState> emit) async {
final allMandatoryItemsChecked = state.roleKitItems
.where((element) => element.isMandatory)
.every((element) => element.confirmed);
final allPhotoUploaded = state.roleKitItems
.where((element) => element.needPhoto)
.every((element) =>
element.imageUrl != null || element.localImage != null);
if (allMandatoryItemsChecked && allPhotoUploaded) {
emit(state.copyWith(loading: true));
var confirmed = state.roleKitItems
.where((e) => e.confirmed)
.map((e) => MutateKitDto(id: e.id, photo: e.imageToken ?? e.imageUrl))
.toList();
try {
await getIt<StaffRoleKitRepository>()
.putKit(
state.selectedRole!.skill!.id, confirmed, state.roleKitType);
}catch (e) {
if (e is DisplayableException) {
emit(state.copyWith(apiError: e.message));
}
return;
} finally {
emit(state.copyWith(loading: false));
}
emit(state.copyWith(success: true));
} else {
emit(state.copyWith(showError: true));
}
}
void _onDeletePhoto(
RoleKitEventDeletePhoto event, Emitter<RoleKitState> emit) {
event.item.imageUrl = null;
event.item.localImage = null;
event.item.imageToken = null;
emit(state.copyWith());
}
}

View File

@@ -0,0 +1,38 @@
import 'package:krow/core/data/models/staff_role.dart';
import 'package:krow/features/profile/role_kit/domain/staff_role_kit_repository_impl.dart';
import 'package:krow/features/profile/role_kit/domain/role_kit_entity.dart';
sealed class RoleKitEvent {}
class RoleKitEventFetch extends RoleKitEvent {
final RoleKitType type;
RoleKitEventFetch({required this.type});
}
class RoleKitEventSubmit extends RoleKitEvent {}
class RoleKiEventChangeState extends RoleKitEvent {
final RoleKitEntity item;
RoleKiEventChangeState(this.item);
}
class RoleKitEventUploadPhoto extends RoleKitEvent {
final RoleKitEntity item;
final String photoPath;
RoleKitEventUploadPhoto({required this.item, required this.photoPath});
}
class RoleKitEventDeletePhoto extends RoleKitEvent {
final RoleKitEntity item;
RoleKitEventDeletePhoto(this.item);
}
class RoleKitEventSelectRole extends RoleKitEvent {
final StaffRole role;
RoleKitEventSelectRole({required this.role});
}

View File

@@ -0,0 +1,46 @@
import 'package:krow/core/data/models/staff_role.dart';
import 'package:krow/features/profile/role_kit/domain/staff_role_kit_repository_impl.dart';
import 'package:krow/features/profile/role_kit/domain/role_kit_entity.dart';
class RoleKitState {
final bool showError;
final bool loading;
final bool success;
final RoleKitType roleKitType;
final List<RoleKitEntity> roleKitItems;
final List<StaffRole> roles;
final StaffRole? selectedRole;
final String? apiError;
RoleKitState(
{this.showError = false,
this.roleKitItems = const [],
this.roles = const [],
this.loading = false,
this.selectedRole,
this.roleKitType = RoleKitType.uniform,
this.success = false,
this.apiError});
copyWith(
{bool? showError,
List<RoleKitEntity>? roleKitItems,
RoleKitType? roleKitType,
bool? loading,
bool? success,
List<StaffRole>? roles,
StaffRole? selectedRole,
String? apiError}) {
return RoleKitState(
showError: showError ?? this.showError,
roleKitItems: roleKitItems ?? this.roleKitItems,
loading: loading ?? false,
success: success ?? false,
roleKitType: roleKitType ?? this.roleKitType,
roles: roles ?? this.roles,
selectedRole: selectedRole ?? this.selectedRole,
apiError: apiError,
);
}
}

View File

@@ -0,0 +1,23 @@
class RoleKitEntity {
final String id;
final String title;
final bool isMandatory;
final bool needPhoto;
bool uploading;
bool confirmed;
String? imageUrl;
String? localImage;
String? imageToken;
RoleKitEntity({
required this.id,
required this.title,
this.isMandatory = false,
this.confirmed = false,
this.imageUrl,
this.needPhoto = false,
this.uploading = false,
this.localImage,
});
}

View File

@@ -0,0 +1,37 @@
import 'package:injectable/injectable.dart';
import 'package:krow/core/data/models/staff_role.dart';
import 'package:krow/features/profile/role_kit/data/models/mutate_kit_dto.dart';
import 'package:krow/features/profile/role_kit/data/staff_role_kit_api.dart';
import 'package:krow/features/profile/role_kit/data/staff_role_kit_repository.dart';
enum RoleKitType {
uniform,
equipment,
}
@Injectable(as: StaffRoleKitRepository)
class StaffRoleKitRepositoryImpl extends StaffRoleKitRepository {
final StaffRoleKitApiProvider _staffRoleApi;
StaffRoleKitRepositoryImpl(this._staffRoleApi);
@override
Future<List<StaffRole>> getStaffRole() async {
return _staffRoleApi.fetchStaffRoles();
}
@override
Future<void> putKit(
String skillId, List<MutateKitDto> kits, RoleKitType type) async {
if (type == RoleKitType.uniform) {
return _staffRoleApi.putUniform(skillId, kits);
} else {
return _staffRoleApi.putEquipment(skillId, kits);
}
}
@override
Future<Map<String, dynamic>> uploadImage(String imagePath) async {
return _staffRoleApi.uploadImage(imagePath);
}
}