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,91 @@
import 'package:collection/collection.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/features/profile/certificates/domain/certificates_repository.dart';
import 'package:krow/features/profile/certificates/data/models/staff_certificate.dart';
import 'package:krow/features/profile/certificates/domain/bloc/certificates_event.dart';
import 'package:krow/features/profile/certificates/domain/bloc/certificates_state.dart';
class CertificatesBloc extends Bloc<CertificatesEvent, CertificatesState> {
CertificatesBloc() : super(CertificatesState()) {
on<CertificatesEventFetch>(_onFetch);
on<CertificatesEventSubmit>(_onSubmit);
on<CertificatesEventUpload>(_onUploadPhoto);
on<CertificatesEventDelete>(_onDeleteCertificate);
}
void _onFetch(
CertificatesEventFetch event, Emitter<CertificatesState> emit) async {
emit(state.copyWith(loading: true));
var certificates = await getIt<CertificatesRepository>().getCertificates();
List<StaffCertificate> staffCertificates =
await getIt<CertificatesRepository>().getStaffCertificates();
var items = certificates.map((certificate) {
var staffCertificate = staffCertificates.firstWhereOrNull(
(e) => certificate.id == e.certificate.id,
);
return CertificatesViewModel(
id: staffCertificate?.id,
certificateId: certificate.id,
title: certificate.name,
imageUrl: staffCertificate?.file,
expirationDate: staffCertificate?.expirationDate,
status: staffCertificate?.status,
);
}).toList();
emit(state.copyWith(
loading: false,
certificatesItems: items,
));
}
void _onUploadPhoto(
CertificatesEventUpload event, Emitter<CertificatesState> emit) async {
event.item.uploading = true;
emit(state.copyWith());
try {
var split = event.expirationDate.split('.').reversed;
split = [split.elementAt(0), split.elementAt(2), split.elementAt(1)];
var formattedDate = split.join('-');
var newCertificate = await getIt<CertificatesRepository>()
.putStaffCertificate(
event.item.certificateId, event.path, formattedDate);
event.item.applyNewStaffCertificate(newCertificate);
} finally {
event.item.uploading = false;
emit(state.copyWith());
}
}
void _onSubmit(
CertificatesEventSubmit event, Emitter<CertificatesState> emit) async {
final allCertUploaded = state.certificatesItems.every((element) {
return element.certificateId == '3' ||
element.status == CertificateStatus.pending ||
element.status == CertificateStatus.verified;
});
if (allCertUploaded) {
emit(state.copyWith(success: true));
} else {
emit(state.copyWith(showError: true));
}
}
void _onDeleteCertificate(
CertificatesEventDelete event, Emitter<CertificatesState> emit) async {
emit(state.copyWith(loading: true));
try {
await getIt<CertificatesRepository>()
.deleteStaffCertificate(event.item.id ?? '0');
state.certificatesItems
.firstWhere((element) => element.id == event.item.id)
.clear();
} finally {
emit(state.copyWith(loading: false));
}
}
}

View File

@@ -0,0 +1,22 @@
import 'package:krow/features/profile/certificates/domain/bloc/certificates_state.dart';
sealed class CertificatesEvent {}
class CertificatesEventFetch extends CertificatesEvent {}
class CertificatesEventSubmit extends CertificatesEvent {}
class CertificatesEventUpload extends CertificatesEvent {
final String path;
final String expirationDate;
final CertificatesViewModel item;
CertificatesEventUpload(
{required this.path, required this.expirationDate, required this.item});
}
class CertificatesEventDelete extends CertificatesEvent {
final CertificatesViewModel item;
CertificatesEventDelete(this.item);
}

View File

@@ -0,0 +1,93 @@
import 'package:krow/features/profile/certificates/data/models/staff_certificate.dart';
class CertificatesState {
final bool showError;
final bool loading;
final bool success;
List<CertificatesViewModel> certificatesItems = [];
CertificatesState(
{this.showError = false,
this.certificatesItems = const [],
this.loading = false,
this.success = false});
copyWith(
{bool? showError,
List<CertificatesViewModel>? certificatesItems,
bool? loading,
bool? success}) {
return CertificatesState(
showError: showError ?? this.showError,
certificatesItems: certificatesItems ?? this.certificatesItems,
loading: loading ?? false,
success: success ?? false,
);
}
}
class CertificatesViewModel {
String? id;
String certificateId;
final String title;
bool uploading;
String? imageUrl;
String? expirationDate;
CertificateStatus? status;
CertificatesViewModel({
this.id,
required this.certificateId,
required this.title,
this.expirationDate,
this.imageUrl,
this.uploading = false,
this.status,
});
void clear() {
id = null;
imageUrl = null;
expirationDate = null;
status = null;
}
void applyNewStaffCertificate(StaffCertificate newCertificate) {
id = newCertificate.id;
imageUrl = newCertificate.file;
expirationDate = newCertificate.expirationDate;
status = newCertificate.status;
}
bool get isExpired {
if (expirationDate == null) return false;
DateTime expiration = DateTime.parse(expirationDate!);
DateTime now = DateTime.now();
return now.isAfter(expiration);
}
String getExpirationInfo() {
if (expirationDate == null) return '';
DateTime expiration = DateTime.parse(expirationDate!);
DateTime now = DateTime.now();
Duration difference = expiration.difference(now);
String formatted =
'${expiration.month.toString().padLeft(2, '0')}.${expiration.day.toString().padLeft(2, '0')}.${expiration.year}';
if (difference.inDays <= 0) {
return '$formatted (expired)';
} else if (difference.inDays < 14) {
return '$formatted (expires in ${difference.inDays} days)';
} else {
return formatted;
}
}
bool expireSoon() {
if (expirationDate == null) return false;
DateTime expiration = DateTime.parse(expirationDate!);
DateTime now = DateTime.now();
Duration difference = expiration.difference(now);
return difference.inDays <= 14;
}
}