From f32bd81a46c747f4e348f91ab63939556526b8e8 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Fri, 27 Feb 2026 02:00:51 -0500 Subject: [PATCH] refactor: update AttireRepositoryImpl to use constructor injection, reorganize profile sections by moving documents and adding certificates, and introduce new UI icons. --- .../design_system/lib/src/ui_icons.dart | 6 ++++ .../widgets/sections/compliance_section.dart | 16 ++++++++-- .../widgets/sections/onboarding_section.dart | 5 ---- .../lib/src/staff_certificates_module.dart | 3 ++ .../lib/src/staff_documents_module.dart | 3 ++ .../attire/lib/src/attire_module.dart | 11 ++++++- .../attire_repository_impl.dart | 29 +++++++++++-------- 7 files changed, 53 insertions(+), 20 deletions(-) diff --git a/apps/mobile/packages/design_system/lib/src/ui_icons.dart b/apps/mobile/packages/design_system/lib/src/ui_icons.dart index 537ef4f7..24801c39 100644 --- a/apps/mobile/packages/design_system/lib/src/ui_icons.dart +++ b/apps/mobile/packages/design_system/lib/src/ui_icons.dart @@ -279,4 +279,10 @@ class UiIcons { /// Gallery icon for gallery static const IconData gallery = _IconLib.galleryVertical; + + /// Certificate icon + static const IconData certificate = _IconLib.fileCheck; + + /// Circle dollar icon + static const IconData circleDollar = _IconLib.circleDollarSign; } diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart index 11d303df..b3a700e4 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/compliance_section.dart @@ -21,7 +21,9 @@ class ComplianceSection extends StatelessWidget { @override Widget build(BuildContext context) { - final TranslationsStaffProfileEn i18n = Translations.of(context).staff.profile; + final TranslationsStaffProfileEn i18n = Translations.of( + context, + ).staff.profile; return BlocBuilder( builder: (BuildContext context, ProfileState state) { @@ -33,11 +35,21 @@ class ComplianceSection extends StatelessWidget { crossAxisCount: 3, children: [ ProfileMenuItem( - icon: UiIcons.file, + icon: UiIcons.circleDollar, label: i18n.menu_items.tax_forms, completed: state.taxFormsComplete, onTap: () => Modular.to.toTaxForms(), ), + ProfileMenuItem( + icon: UiIcons.file, + label: i18n.menu_items.documents, + onTap: () => Modular.to.toDocuments(), + ), + ProfileMenuItem( + icon: UiIcons.certificate, + label: i18n.menu_items.certificates, + onTap: () => Modular.to.toCertificates(), + ), ], ), ], diff --git a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart index c704efd5..327e58ea 100644 --- a/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart +++ b/apps/mobile/packages/features/staff/profile/lib/src/presentation/widgets/sections/onboarding_section.dart @@ -56,11 +56,6 @@ class OnboardingSection extends StatelessWidget { label: i18n.menu_items.attire, onTap: () => Modular.to.toAttire(), ), - ProfileMenuItem( - icon: UiIcons.file, - label: i18n.menu_items.documents, - onTap: () => Modular.to.toDocuments(), - ), ], ), ], diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/staff_certificates_module.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/staff_certificates_module.dart index dd910afe..8865b89a 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/staff_certificates_module.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/certificates/lib/src/staff_certificates_module.dart @@ -15,6 +15,9 @@ import 'presentation/pages/certificate_upload_page.dart'; import 'presentation/pages/certificates_page.dart'; class StaffCertificatesModule extends Module { + @override + List get imports => [CoreModule()]; + @override void binds(Injector i) { i.addLazySingleton(CertificatesRepositoryImpl.new); diff --git a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/staff_documents_module.dart b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/staff_documents_module.dart index 58dda25d..130c6d19 100644 --- a/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/staff_documents_module.dart +++ b/apps/mobile/packages/features/staff/profile_sections/compliance/documents/lib/src/staff_documents_module.dart @@ -11,6 +11,9 @@ import 'presentation/pages/documents_page.dart'; import 'presentation/pages/document_upload_page.dart'; class StaffDocumentsModule extends Module { + @override + List get imports => [CoreModule()]; + @override void binds(Injector i) { i.addLazySingleton( diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/attire_module.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/attire_module.dart index f574b6d1..b50f671c 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/attire_module.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/attire_module.dart @@ -14,6 +14,9 @@ import 'presentation/pages/attire_capture_page.dart'; import 'presentation/pages/attire_page.dart'; class StaffAttireModule extends Module { + @override + List get imports => [CoreModule()]; + @override void binds(Injector i) { /// third party services @@ -25,7 +28,13 @@ class StaffAttireModule extends Module { ); // Repository - i.addLazySingleton(AttireRepositoryImpl.new); + i.addLazySingleton( + () => AttireRepositoryImpl( + uploadService: i.get(), + signedUrlService: i.get(), + verificationService: i.get(), + ), + ); // Use Cases i.addLazySingleton(GetAttireOptionsUseCase.new); diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart index 65645ad8..b3001b26 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/data/repositories_impl/attire_repository_impl.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter_modular/flutter_modular.dart'; import 'package:krow_core/core.dart'; import 'package:krow_data_connect/krow_data_connect.dart' hide AttireVerificationStatus; @@ -12,12 +11,22 @@ import '../../domain/repositories/attire_repository.dart'; /// Delegates data access to [StaffConnectorRepository]. class AttireRepositoryImpl implements AttireRepository { /// Creates an [AttireRepositoryImpl]. - AttireRepositoryImpl({StaffConnectorRepository? connector}) - : _connector = - connector ?? DataConnectService.instance.getStaffRepository(); + AttireRepositoryImpl({ + required FileUploadService uploadService, + required SignedUrlService signedUrlService, + required VerificationService verificationService, + StaffConnectorRepository? connector, + }) : _connector = + connector ?? DataConnectService.instance.getStaffRepository(), + _uploadService = uploadService, + _signedUrlService = signedUrlService, + _verificationService = verificationService; /// The Staff Connector repository. final StaffConnectorRepository _connector; + final FileUploadService _uploadService; + final SignedUrlService _signedUrlService; + final VerificationService _verificationService; @override Future> getAttireOptions() async { @@ -37,8 +46,7 @@ class AttireRepositoryImpl implements AttireRepository { @override Future uploadPhoto(String itemId, String filePath) async { // 1. Upload file to Core API - final FileUploadService uploadService = Modular.get(); - final FileUploadResponse uploadRes = await uploadService.uploadFile( + final FileUploadResponse uploadRes = await _uploadService.uploadFile( filePath: filePath, fileName: filePath.split('/').last, ); @@ -46,14 +54,11 @@ class AttireRepositoryImpl implements AttireRepository { final String fileUri = uploadRes.fileUri; // 2. Create signed URL for the uploaded file - final SignedUrlService signedUrlService = Modular.get(); - final SignedUrlResponse signedUrlRes = await signedUrlService + final SignedUrlResponse signedUrlRes = await _signedUrlService .createSignedUrl(fileUri: fileUri); final String photoUrl = signedUrlRes.signedUrl; // 3. Initiate verification job - final VerificationService verificationService = - Modular.get(); final Staff staff = await _connector.getStaffProfile(); // Get item details for verification rules @@ -64,7 +69,7 @@ class AttireRepositoryImpl implements AttireRepository { final String dressCode = '${targetItem.description ?? ''} ${targetItem.label}'.trim(); - final VerificationResponse verifyRes = await verificationService + final VerificationResponse verifyRes = await _verificationService .createVerification( type: 'attire', subjectType: 'worker', @@ -81,7 +86,7 @@ class AttireRepositoryImpl implements AttireRepository { bool isFinished = false; while (!isFinished && attempts < 5) { await Future.delayed(const Duration(seconds: 2)); - final VerificationResponse statusRes = await verificationService + final VerificationResponse statusRes = await _verificationService .getStatus(verificationId); currentStatus = statusRes.status; if (currentStatus != VerificationStatus.pending &&