feat: Refactor context reading in emergency contact and FAQs widgets
- Updated the context reading method in `EmergencyContactAddButton` and `EmergencyContactFormItem` to use `ReadContext`. - Modified the `FaqsWidget` to utilize `ReadContext` for fetching FAQs. - Adjusted the `PrivacySectionWidget` to read from `PrivacySecurityBloc` using `ReadContext`. feat: Implement Firebase Auth isolation pattern - Introduced `FirebaseAuthService` and `FirebaseAuthServiceImpl` to abstract Firebase Auth operations. - Ensured features do not directly import `firebase_auth`, adhering to architecture rules. feat: Create repository interfaces for billing and coverage - Added `BillingRepositoryInterface` for billing-related operations. - Created `CoverageRepositoryInterface` for coverage data access. feat: Add use cases for order management - Implemented use cases for fetching hubs, managers, and roles related to orders. - Created `GetHubsUseCase`, `GetManagersByHubUseCase`, and `GetRolesByVendorUseCase`. feat: Develop report use cases for client reports - Added use cases for fetching various reports including coverage, daily operations, forecast, no-show, performance, and spend reports. - Implemented `GetCoverageReportUseCase`, `GetDailyOpsReportUseCase`, `GetForecastReportUseCase`, `GetNoShowReportUseCase`, `GetPerformanceReportUseCase`, and `GetSpendReportUseCase`. feat: Establish profile repository and use cases - Created `ProfileRepositoryInterface` for staff profile data access. - Implemented use cases for retrieving staff profile and section statuses: `GetStaffProfileUseCase` and `GetProfileSectionsUseCase`. - Added `SignOutUseCase` for signing out the current user.
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import 'package:staff_profile/src/domain/repositories/profile_repository_interface.dart';
|
||||
|
||||
/// Repository implementation for the main profile page.
|
||||
///
|
||||
/// Uses the V2 API to fetch staff profile, section statuses, and completion.
|
||||
class ProfileRepositoryImpl {
|
||||
class ProfileRepositoryImpl implements ProfileRepositoryInterface {
|
||||
/// Creates a [ProfileRepositoryImpl].
|
||||
ProfileRepositoryImpl({required BaseApiService apiService})
|
||||
: _api = apiService;
|
||||
|
||||
final BaseApiService _api;
|
||||
|
||||
/// Fetches the staff profile from the V2 session endpoint.
|
||||
@override
|
||||
Future<Staff> getStaffProfile() async {
|
||||
final ApiResponse response =
|
||||
await _api.get(StaffEndpoints.session);
|
||||
@@ -20,7 +22,7 @@ class ProfileRepositoryImpl {
|
||||
return Staff.fromJson(json);
|
||||
}
|
||||
|
||||
/// Fetches the profile section completion statuses.
|
||||
@override
|
||||
Future<ProfileSectionStatus> getProfileSections() async {
|
||||
final ApiResponse response =
|
||||
await _api.get(StaffEndpoints.profileSections);
|
||||
@@ -29,7 +31,7 @@ class ProfileRepositoryImpl {
|
||||
return ProfileSectionStatus.fromJson(json);
|
||||
}
|
||||
|
||||
/// Signs out the current user.
|
||||
@override
|
||||
Future<void> signOut() async {
|
||||
await _api.post(AuthEndpoints.signOut);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
/// Abstract interface for the staff profile repository.
|
||||
///
|
||||
/// Defines the contract for fetching staff profile data,
|
||||
/// section completion statuses, and signing out.
|
||||
abstract interface class ProfileRepositoryInterface {
|
||||
/// Fetches the staff profile from the backend.
|
||||
Future<Staff> getStaffProfile();
|
||||
|
||||
/// Fetches the profile section completion statuses.
|
||||
Future<ProfileSectionStatus> getProfileSections();
|
||||
|
||||
/// Signs out the current user.
|
||||
Future<void> signOut();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import 'package:staff_profile/src/domain/repositories/profile_repository_interface.dart';
|
||||
|
||||
/// Use case for retrieving profile section completion statuses.
|
||||
class GetProfileSectionsUseCase implements NoInputUseCase<ProfileSectionStatus> {
|
||||
/// Creates a [GetProfileSectionsUseCase] with the required [repository].
|
||||
GetProfileSectionsUseCase(this._repository);
|
||||
|
||||
final ProfileRepositoryInterface _repository;
|
||||
|
||||
@override
|
||||
Future<ProfileSectionStatus> call() {
|
||||
return _repository.getProfileSections();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import 'package:staff_profile/src/domain/repositories/profile_repository_interface.dart';
|
||||
|
||||
/// Use case for retrieving the staff member's profile.
|
||||
class GetStaffProfileUseCase implements NoInputUseCase<Staff> {
|
||||
/// Creates a [GetStaffProfileUseCase] with the required [repository].
|
||||
GetStaffProfileUseCase(this._repository);
|
||||
|
||||
final ProfileRepositoryInterface _repository;
|
||||
|
||||
@override
|
||||
Future<Staff> call() {
|
||||
return _repository.getStaffProfile();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:krow_core/core.dart';
|
||||
|
||||
import 'package:staff_profile/src/domain/repositories/profile_repository_interface.dart';
|
||||
|
||||
/// Use case for signing out the current user.
|
||||
class SignOutUseCase implements NoInputUseCase<void> {
|
||||
/// Creates a [SignOutUseCase] with the required [repository].
|
||||
SignOutUseCase(this._repository);
|
||||
|
||||
final ProfileRepositoryInterface _repository;
|
||||
|
||||
@override
|
||||
Future<void> call() {
|
||||
return _repository.signOut();
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,30 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import 'package:staff_profile/src/data/repositories/profile_repository_impl.dart';
|
||||
import 'package:staff_profile/src/domain/usecases/get_profile_sections_usecase.dart';
|
||||
import 'package:staff_profile/src/domain/usecases/get_staff_profile_usecase.dart';
|
||||
import 'package:staff_profile/src/domain/usecases/sign_out_usecase.dart';
|
||||
import 'package:staff_profile/src/presentation/blocs/profile_state.dart';
|
||||
|
||||
/// Cubit for managing the Profile feature state.
|
||||
///
|
||||
/// Uses the V2 API via [ProfileRepositoryImpl] for all data fetching.
|
||||
/// Delegates all data fetching to use cases, following Clean Architecture.
|
||||
/// Loads the staff profile and section completion statuses in a single flow.
|
||||
class ProfileCubit extends Cubit<ProfileState>
|
||||
with BlocErrorHandler<ProfileState> {
|
||||
/// Creates a [ProfileCubit] with the required repository.
|
||||
ProfileCubit(this._repository) : super(const ProfileState());
|
||||
/// Creates a [ProfileCubit] with the required use cases.
|
||||
ProfileCubit({
|
||||
required GetStaffProfileUseCase getStaffProfileUseCase,
|
||||
required GetProfileSectionsUseCase getProfileSectionsUseCase,
|
||||
required SignOutUseCase signOutUseCase,
|
||||
}) : _getStaffProfileUseCase = getStaffProfileUseCase,
|
||||
_getProfileSectionsUseCase = getProfileSectionsUseCase,
|
||||
_signOutUseCase = signOutUseCase,
|
||||
super(const ProfileState());
|
||||
|
||||
final ProfileRepositoryImpl _repository;
|
||||
final GetStaffProfileUseCase _getStaffProfileUseCase;
|
||||
final GetProfileSectionsUseCase _getProfileSectionsUseCase;
|
||||
final SignOutUseCase _signOutUseCase;
|
||||
|
||||
/// Loads the staff member's profile.
|
||||
Future<void> loadProfile() async {
|
||||
@@ -23,7 +34,7 @@ class ProfileCubit extends Cubit<ProfileState>
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final Staff profile = await _repository.getStaffProfile();
|
||||
final Staff profile = await _getStaffProfileUseCase();
|
||||
emit(state.copyWith(status: ProfileStatus.loaded, profile: profile));
|
||||
},
|
||||
onError: (String errorKey) =>
|
||||
@@ -37,7 +48,7 @@ class ProfileCubit extends Cubit<ProfileState>
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final ProfileSectionStatus sections =
|
||||
await _repository.getProfileSections();
|
||||
await _getProfileSectionsUseCase();
|
||||
emit(state.copyWith(
|
||||
personalInfoComplete: sections.personalInfoCompleted,
|
||||
emergencyContactsComplete: sections.emergencyContactCompleted,
|
||||
@@ -62,7 +73,7 @@ class ProfileCubit extends Cubit<ProfileState>
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
await _repository.signOut();
|
||||
await _signOutUseCase();
|
||||
emit(state.copyWith(status: ProfileStatus.signedOut));
|
||||
},
|
||||
onError: (String _) =>
|
||||
|
||||
@@ -19,7 +19,7 @@ class LogoutButton extends StatelessWidget {
|
||||
/// sign-out process via the ProfileCubit.
|
||||
void _handleSignOut(BuildContext context, ProfileState state) {
|
||||
if (state.status != ProfileStatus.loading) {
|
||||
context.read<ProfileCubit>().signOut();
|
||||
ReadContext(context).read<ProfileCubit>().signOut();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class LogoutButton extends StatelessWidget {
|
||||
onTap: () {
|
||||
_handleSignOut(
|
||||
context,
|
||||
context.read<ProfileCubit>().state,
|
||||
ReadContext(context).read<ProfileCubit>().state,
|
||||
);
|
||||
},
|
||||
borderRadius: UiConstants.radiusLg,
|
||||
|
||||
@@ -4,13 +4,17 @@ import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import 'package:staff_profile/src/data/repositories/profile_repository_impl.dart';
|
||||
import 'package:staff_profile/src/domain/repositories/profile_repository_interface.dart';
|
||||
import 'package:staff_profile/src/domain/usecases/get_profile_sections_usecase.dart';
|
||||
import 'package:staff_profile/src/domain/usecases/get_staff_profile_usecase.dart';
|
||||
import 'package:staff_profile/src/domain/usecases/sign_out_usecase.dart';
|
||||
import 'package:staff_profile/src/presentation/blocs/profile_cubit.dart';
|
||||
import 'package:staff_profile/src/presentation/pages/staff_profile_page.dart';
|
||||
|
||||
/// The entry module for the Staff Profile feature.
|
||||
///
|
||||
/// Uses the V2 REST API via [BaseApiService] for all backend access.
|
||||
/// Section completion statuses are fetched in a single API call.
|
||||
/// Registers repository interface, use cases, and cubit for DI.
|
||||
class StaffProfileModule extends Module {
|
||||
@override
|
||||
List<Module> get imports => <Module>[CoreModule()];
|
||||
@@ -18,15 +22,36 @@ class StaffProfileModule extends Module {
|
||||
@override
|
||||
void binds(Injector i) {
|
||||
// Repository
|
||||
i.addLazySingleton<ProfileRepositoryImpl>(
|
||||
i.addLazySingleton<ProfileRepositoryInterface>(
|
||||
() => ProfileRepositoryImpl(
|
||||
apiService: i.get<BaseApiService>(),
|
||||
),
|
||||
);
|
||||
|
||||
// Use Cases
|
||||
i.addLazySingleton<GetStaffProfileUseCase>(
|
||||
() => GetStaffProfileUseCase(
|
||||
i.get<ProfileRepositoryInterface>(),
|
||||
),
|
||||
);
|
||||
i.addLazySingleton<GetProfileSectionsUseCase>(
|
||||
() => GetProfileSectionsUseCase(
|
||||
i.get<ProfileRepositoryInterface>(),
|
||||
),
|
||||
);
|
||||
i.addLazySingleton<SignOutUseCase>(
|
||||
() => SignOutUseCase(
|
||||
i.get<ProfileRepositoryInterface>(),
|
||||
),
|
||||
);
|
||||
|
||||
// Cubit
|
||||
i.addLazySingleton<ProfileCubit>(
|
||||
() => ProfileCubit(i.get<ProfileRepositoryImpl>()),
|
||||
() => ProfileCubit(
|
||||
getStaffProfileUseCase: i.get<GetStaffProfileUseCase>(),
|
||||
getProfileSectionsUseCase: i.get<GetProfileSectionsUseCase>(),
|
||||
signOutUseCase: i.get<SignOutUseCase>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user