Refactor updateStaffProfile method to accept staff ID and data map, and update PersonalInfoBloc to handle form values
This commit is contained in:
@@ -48,16 +48,28 @@ class PersonalInfoRepositoryImpl implements PersonalInfoRepositoryInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Staff> updateStaffProfile(Staff staff) async {
|
Future<Staff> updateStaffProfile({required String staffId, required Map<String, dynamic> data}) async {
|
||||||
// Update staff data through Firebase Data Connect
|
// Start building the update mutation
|
||||||
|
var updateBuilder = _dataConnect.updateStaff(id: staffId);
|
||||||
|
|
||||||
|
// Apply updates from map if present
|
||||||
|
if (data.containsKey('name')) {
|
||||||
|
updateBuilder = updateBuilder.fullName(data['name'] as String);
|
||||||
|
}
|
||||||
|
if (data.containsKey('email')) {
|
||||||
|
updateBuilder = updateBuilder.email(data['email'] as String);
|
||||||
|
}
|
||||||
|
if (data.containsKey('phone')) {
|
||||||
|
updateBuilder = updateBuilder.phone(data['phone'] as String?);
|
||||||
|
}
|
||||||
|
if (data.containsKey('avatar')) {
|
||||||
|
updateBuilder = updateBuilder.photoUrl(data['avatar'] as String?);
|
||||||
|
}
|
||||||
|
// Add other fields as they become available in the schema and map
|
||||||
|
|
||||||
|
// Execute the update
|
||||||
final OperationResult<UpdateStaffData, UpdateStaffVariables> result =
|
final OperationResult<UpdateStaffData, UpdateStaffVariables> result =
|
||||||
await _dataConnect
|
await updateBuilder.execute();
|
||||||
.updateStaff(id: staff.id)
|
|
||||||
.fullName(staff.name)
|
|
||||||
.email(staff.email)
|
|
||||||
.phone(staff.phone)
|
|
||||||
.photoUrl(staff.avatar)
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
if (result.data.staff_update == null) {
|
if (result.data.staff_update == null) {
|
||||||
throw Exception('Failed to update staff profile');
|
throw Exception('Failed to update staff profile');
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ abstract interface class PersonalInfoRepositoryInterface {
|
|||||||
|
|
||||||
/// Updates the staff profile information.
|
/// Updates the staff profile information.
|
||||||
///
|
///
|
||||||
/// Takes a [Staff] entity with updated fields and persists changes
|
/// Takes a [Staff] entity ID and updated fields map and persists changes
|
||||||
/// through the data layer. Returns the updated [Staff] entity.
|
/// through the data layer. Returns the updated [Staff] entity.
|
||||||
Future<Staff> updateStaffProfile(Staff staff);
|
Future<Staff> updateStaffProfile({required String staffId, required Map<String, dynamic> data});
|
||||||
|
|
||||||
/// Uploads a profile photo and returns the URL.
|
/// Uploads a profile photo and returns the URL.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -2,12 +2,29 @@ import 'package:krow_core/core.dart';
|
|||||||
import 'package:krow_domain/krow_domain.dart';
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
import '../repositories/personal_info_repository_interface.dart';
|
import '../repositories/personal_info_repository_interface.dart';
|
||||||
|
|
||||||
|
/// Arguments for updating staff profile information.
|
||||||
|
class UpdatePersonalInfoParams extends UseCaseArgument {
|
||||||
|
/// The staff member's ID.
|
||||||
|
final String staffId;
|
||||||
|
|
||||||
|
/// The fields to update.
|
||||||
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
|
const UpdatePersonalInfoParams({
|
||||||
|
required this.staffId,
|
||||||
|
required this.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [staffId, data];
|
||||||
|
}
|
||||||
|
|
||||||
/// Use case for updating staff profile information.
|
/// Use case for updating staff profile information.
|
||||||
///
|
///
|
||||||
/// This use case updates the staff profile information
|
/// This use case updates the staff profile information
|
||||||
/// through the repository, which delegates to the data_connect layer.
|
/// through the repository, which delegates to the data_connect layer.
|
||||||
class UpdatePersonalInfoUseCase
|
class UpdatePersonalInfoUseCase
|
||||||
implements UseCase<Staff, Staff> {
|
implements UseCase<UpdatePersonalInfoParams, Staff> {
|
||||||
final PersonalInfoRepositoryInterface _repository;
|
final PersonalInfoRepositoryInterface _repository;
|
||||||
|
|
||||||
/// Creates an [UpdatePersonalInfoUseCase].
|
/// Creates an [UpdatePersonalInfoUseCase].
|
||||||
@@ -16,7 +33,10 @@ class UpdatePersonalInfoUseCase
|
|||||||
UpdatePersonalInfoUseCase(this._repository);
|
UpdatePersonalInfoUseCase(this._repository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Staff> call(Staff arguments) {
|
Future<Staff> call(UpdatePersonalInfoParams params) {
|
||||||
return _repository.updateStaffProfile(arguments);
|
return _repository.updateStaffProfile(
|
||||||
|
staffId: params.staffId,
|
||||||
|
data: params.data,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_modular/flutter_modular.dart';
|
import 'package:flutter_modular/flutter_modular.dart';
|
||||||
import 'package:krow_core/core.dart';
|
|
||||||
import 'package:krow_domain/krow_domain.dart';
|
import 'package:krow_domain/krow_domain.dart';
|
||||||
|
|
||||||
import '../../domain/usecases/get_personal_info_usecase.dart';
|
import '../../domain/usecases/get_personal_info_usecase.dart';
|
||||||
@@ -41,9 +40,20 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
|||||||
emit(state.copyWith(status: PersonalInfoStatus.loading));
|
emit(state.copyWith(status: PersonalInfoStatus.loading));
|
||||||
try {
|
try {
|
||||||
final Staff staff = await _getPersonalInfoUseCase();
|
final Staff staff = await _getPersonalInfoUseCase();
|
||||||
|
|
||||||
|
// Initialize form values from staff entity
|
||||||
|
final Map<String, dynamic> initialValues = {
|
||||||
|
'name': staff.name,
|
||||||
|
'email': staff.email,
|
||||||
|
'phone': staff.phone,
|
||||||
|
'address': staff.address,
|
||||||
|
'avatar': staff.avatar,
|
||||||
|
};
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
status: PersonalInfoStatus.loaded,
|
status: PersonalInfoStatus.loaded,
|
||||||
staff: staff,
|
staff: staff,
|
||||||
|
formValues: initialValues,
|
||||||
));
|
));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@@ -58,47 +68,9 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
|||||||
PersonalInfoFieldUpdated event,
|
PersonalInfoFieldUpdated event,
|
||||||
Emitter<PersonalInfoState> emit,
|
Emitter<PersonalInfoState> emit,
|
||||||
) {
|
) {
|
||||||
if (state.staff == null) return;
|
final Map<String, dynamic> updatedValues = Map.from(state.formValues);
|
||||||
|
updatedValues[event.field] = event.value;
|
||||||
final Staff updatedStaff = _updateField(state.staff!, event.field, event.value);
|
emit(state.copyWith(formValues: updatedValues));
|
||||||
emit(state.copyWith(staff: updatedStaff));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Updates a specific field in the Staff entity.
|
|
||||||
///
|
|
||||||
/// Returns a new Staff instance with the updated field.
|
|
||||||
Staff _updateField(Staff staff, String field, String value) {
|
|
||||||
// Note: Staff entity doesn't have a copyWith method or bio/languages/locations fields
|
|
||||||
// These fields would need to be added to the Staff entity or handled differently
|
|
||||||
// For now, we're just returning the same staff
|
|
||||||
// TODO: Add support for bio, languages, preferred locations to Staff entity
|
|
||||||
switch (field) {
|
|
||||||
case 'phone':
|
|
||||||
// Since Staff is immutable and doesn't have copyWith, we'd need to create a new instance
|
|
||||||
return Staff(
|
|
||||||
id: staff.id,
|
|
||||||
authProviderId: staff.authProviderId,
|
|
||||||
name: staff.name,
|
|
||||||
email: staff.email,
|
|
||||||
phone: value,
|
|
||||||
status: staff.status,
|
|
||||||
address: staff.address,
|
|
||||||
avatar: staff.avatar,
|
|
||||||
);
|
|
||||||
case 'address':
|
|
||||||
return Staff(
|
|
||||||
id: staff.id,
|
|
||||||
authProviderId: staff.authProviderId,
|
|
||||||
name: staff.name,
|
|
||||||
email: staff.email,
|
|
||||||
phone: staff.phone,
|
|
||||||
status: staff.status,
|
|
||||||
address: value,
|
|
||||||
avatar: staff.avatar,
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return staff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles saving staff profile information.
|
/// Handles saving staff profile information.
|
||||||
@@ -111,11 +83,25 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
|||||||
emit(state.copyWith(status: PersonalInfoStatus.saving));
|
emit(state.copyWith(status: PersonalInfoStatus.saving));
|
||||||
try {
|
try {
|
||||||
final Staff updatedStaff = await _updatePersonalInfoUseCase(
|
final Staff updatedStaff = await _updatePersonalInfoUseCase(
|
||||||
state.staff!,
|
UpdatePersonalInfoParams(
|
||||||
|
staffId: state.staff!.id,
|
||||||
|
data: state.formValues,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Update local state with the returned staff and keep form values in sync
|
||||||
|
final Map<String, dynamic> newValues = {
|
||||||
|
'name': updatedStaff.name,
|
||||||
|
'email': updatedStaff.email,
|
||||||
|
'phone': updatedStaff.phone,
|
||||||
|
'address': updatedStaff.address,
|
||||||
|
'avatar': updatedStaff.avatar,
|
||||||
|
};
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
status: PersonalInfoStatus.saved,
|
status: PersonalInfoStatus.saved,
|
||||||
staff: updatedStaff,
|
staff: updatedStaff,
|
||||||
|
formValues: newValues,
|
||||||
));
|
));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ class PersonalInfoState extends Equatable {
|
|||||||
/// The staff profile information.
|
/// The staff profile information.
|
||||||
final Staff? staff;
|
final Staff? staff;
|
||||||
|
|
||||||
|
/// The form values being edited.
|
||||||
|
final Map<String, dynamic> formValues;
|
||||||
|
|
||||||
/// Error message if an error occurred.
|
/// Error message if an error occurred.
|
||||||
final String? errorMessage;
|
final String? errorMessage;
|
||||||
|
|
||||||
@@ -42,6 +45,7 @@ class PersonalInfoState extends Equatable {
|
|||||||
const PersonalInfoState({
|
const PersonalInfoState({
|
||||||
this.status = PersonalInfoStatus.initial,
|
this.status = PersonalInfoStatus.initial,
|
||||||
this.staff,
|
this.staff,
|
||||||
|
this.formValues = const {},
|
||||||
this.errorMessage,
|
this.errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -49,15 +53,17 @@ class PersonalInfoState extends Equatable {
|
|||||||
PersonalInfoState copyWith({
|
PersonalInfoState copyWith({
|
||||||
PersonalInfoStatus? status,
|
PersonalInfoStatus? status,
|
||||||
Staff? staff,
|
Staff? staff,
|
||||||
|
Map<String, dynamic>? formValues,
|
||||||
String? errorMessage,
|
String? errorMessage,
|
||||||
}) {
|
}) {
|
||||||
return PersonalInfoState(
|
return PersonalInfoState(
|
||||||
status: status ?? this.status,
|
status: status ?? this.status,
|
||||||
staff: staff ?? this.staff,
|
staff: staff ?? this.staff,
|
||||||
|
formValues: formValues ?? this.formValues,
|
||||||
errorMessage: errorMessage,
|
errorMessage: errorMessage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [status, staff, errorMessage];
|
List<Object?> get props => [status, staff, formValues, errorMessage];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user