Fix: Resolve critical linting issues and bugs (concurrency, syntax, dead code)
This commit is contained in:
@@ -1,28 +1,38 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../../domain/usecases/get_certificates_usecase.dart';
|
||||
import 'certificates_state.dart';
|
||||
|
||||
class CertificatesCubit extends Cubit<CertificatesState> {
|
||||
class CertificatesCubit extends Cubit<CertificatesState>
|
||||
with BlocErrorHandler<CertificatesState> {
|
||||
final GetCertificatesUseCase _getCertificatesUseCase;
|
||||
|
||||
CertificatesCubit(this._getCertificatesUseCase) : super(const CertificatesState()) {
|
||||
CertificatesCubit(this._getCertificatesUseCase)
|
||||
: super(const CertificatesState()) {
|
||||
loadCertificates();
|
||||
}
|
||||
|
||||
Future<void> loadCertificates() async {
|
||||
emit(state.copyWith(status: CertificatesStatus.loading));
|
||||
try {
|
||||
final List<StaffDocument> certificates = await _getCertificatesUseCase();
|
||||
emit(state.copyWith(
|
||||
status: CertificatesStatus.success,
|
||||
certificates: certificates,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: CertificatesStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<StaffDocument> certificates =
|
||||
await _getCertificatesUseCase();
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: CertificatesStatus.success,
|
||||
certificates: certificates,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: CertificatesStatus.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
|
||||
),
|
||||
];
|
||||
|
||||
/*
|
||||
try {
|
||||
final QueryResult<ListStaffDocumentsByStaffIdData,
|
||||
ListStaffDocumentsByStaffIdVariables> result =
|
||||
@@ -63,6 +64,7 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
|
||||
} catch (e) {
|
||||
throw Exception('Failed to fetch documents: $e');
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
domain.StaffDocument _mapToDomain(
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../../domain/usecases/get_documents_usecase.dart';
|
||||
import 'documents_state.dart';
|
||||
|
||||
class DocumentsCubit extends Cubit<DocumentsState> {
|
||||
class DocumentsCubit extends Cubit<DocumentsState>
|
||||
with BlocErrorHandler<DocumentsState> {
|
||||
final GetDocumentsUseCase _getDocumentsUseCase;
|
||||
|
||||
DocumentsCubit(this._getDocumentsUseCase) : super(const DocumentsState());
|
||||
|
||||
Future<void> loadDocuments() async {
|
||||
emit(state.copyWith(status: DocumentsStatus.loading));
|
||||
try {
|
||||
final List<StaffDocument> documents = await _getDocumentsUseCase();
|
||||
emit(state.copyWith(
|
||||
status: DocumentsStatus.success,
|
||||
documents: documents,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: DocumentsStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<StaffDocument> documents = await _getDocumentsUseCase();
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: DocumentsStatus.success,
|
||||
documents: documents,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: DocumentsStatus.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../../../domain/usecases/submit_i9_form_usecase.dart';
|
||||
import 'form_i9_state.dart';
|
||||
|
||||
class FormI9Cubit extends Cubit<FormI9State> {
|
||||
class FormI9Cubit extends Cubit<FormI9State> with BlocErrorHandler<FormI9State> {
|
||||
final SubmitI9FormUseCase _submitI9FormUseCase;
|
||||
String _formId = '';
|
||||
|
||||
@@ -16,31 +17,33 @@ class FormI9Cubit extends Cubit<FormI9State> {
|
||||
emit(const FormI9State()); // Reset to empty if no form
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final Map<String, dynamic> data = form.formData;
|
||||
_formId = form.id;
|
||||
emit(FormI9State(
|
||||
firstName: data['firstName'] as String? ?? '',
|
||||
lastName: data['lastName'] as String? ?? '',
|
||||
middleInitial: data['middleInitial'] as String? ?? '',
|
||||
otherLastNames: data['otherLastNames'] as String? ?? '',
|
||||
dob: data['dob'] as String? ?? '',
|
||||
ssn: data['ssn'] as String? ?? '',
|
||||
email: data['email'] as String? ?? '',
|
||||
phone: data['phone'] as String? ?? '',
|
||||
address: data['address'] as String? ?? '',
|
||||
aptNumber: data['aptNumber'] as String? ?? '',
|
||||
city: data['city'] as String? ?? '',
|
||||
state: data['state'] as String? ?? '',
|
||||
zipCode: data['zipCode'] as String? ?? '',
|
||||
citizenshipStatus: data['citizenshipStatus'] as String? ?? '',
|
||||
uscisNumber: data['uscisNumber'] as String? ?? '',
|
||||
admissionNumber: data['admissionNumber'] as String? ?? '',
|
||||
passportNumber: data['passportNumber'] as String? ?? '',
|
||||
countryIssuance: data['countryIssuance'] as String? ?? '',
|
||||
preparerUsed: data['preparerUsed'] as bool? ?? false,
|
||||
signature: data['signature'] as String? ?? '',
|
||||
));
|
||||
emit(
|
||||
FormI9State(
|
||||
firstName: data['firstName'] as String? ?? '',
|
||||
lastName: data['lastName'] as String? ?? '',
|
||||
middleInitial: data['middleInitial'] as String? ?? '',
|
||||
otherLastNames: data['otherLastNames'] as String? ?? '',
|
||||
dob: data['dob'] as String? ?? '',
|
||||
ssn: data['ssn'] as String? ?? '',
|
||||
email: data['email'] as String? ?? '',
|
||||
phone: data['phone'] as String? ?? '',
|
||||
address: data['address'] as String? ?? '',
|
||||
aptNumber: data['aptNumber'] as String? ?? '',
|
||||
city: data['city'] as String? ?? '',
|
||||
state: data['state'] as String? ?? '',
|
||||
zipCode: data['zipCode'] as String? ?? '',
|
||||
citizenshipStatus: data['citizenshipStatus'] as String? ?? '',
|
||||
uscisNumber: data['uscisNumber'] as String? ?? '',
|
||||
admissionNumber: data['admissionNumber'] as String? ?? '',
|
||||
passportNumber: data['passportNumber'] as String? ?? '',
|
||||
countryIssuance: data['countryIssuance'] as String? ?? '',
|
||||
preparerUsed: data['preparerUsed'] as bool? ?? false,
|
||||
signature: data['signature'] as String? ?? '',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void nextStep(int totalSteps) {
|
||||
@@ -58,8 +61,10 @@ class FormI9Cubit extends Cubit<FormI9State> {
|
||||
// Personal Info
|
||||
void firstNameChanged(String value) => emit(state.copyWith(firstName: value));
|
||||
void lastNameChanged(String value) => emit(state.copyWith(lastName: value));
|
||||
void middleInitialChanged(String value) => emit(state.copyWith(middleInitial: value));
|
||||
void otherLastNamesChanged(String value) => emit(state.copyWith(otherLastNames: value));
|
||||
void middleInitialChanged(String value) =>
|
||||
emit(state.copyWith(middleInitial: value));
|
||||
void otherLastNamesChanged(String value) =>
|
||||
emit(state.copyWith(otherLastNames: value));
|
||||
void dobChanged(String value) => emit(state.copyWith(dob: value));
|
||||
void ssnChanged(String value) => emit(state.copyWith(ssn: value));
|
||||
void emailChanged(String value) => emit(state.copyWith(email: value));
|
||||
@@ -73,55 +78,65 @@ class FormI9Cubit extends Cubit<FormI9State> {
|
||||
void zipCodeChanged(String value) => emit(state.copyWith(zipCode: value));
|
||||
|
||||
// Citizenship
|
||||
void citizenshipStatusChanged(String value) => emit(state.copyWith(citizenshipStatus: value));
|
||||
void uscisNumberChanged(String value) => emit(state.copyWith(uscisNumber: value));
|
||||
void admissionNumberChanged(String value) => emit(state.copyWith(admissionNumber: value));
|
||||
void passportNumberChanged(String value) => emit(state.copyWith(passportNumber: value));
|
||||
void countryIssuanceChanged(String value) => emit(state.copyWith(countryIssuance: value));
|
||||
void citizenshipStatusChanged(String value) =>
|
||||
emit(state.copyWith(citizenshipStatus: value));
|
||||
void uscisNumberChanged(String value) =>
|
||||
emit(state.copyWith(uscisNumber: value));
|
||||
void admissionNumberChanged(String value) =>
|
||||
emit(state.copyWith(admissionNumber: value));
|
||||
void passportNumberChanged(String value) =>
|
||||
emit(state.copyWith(passportNumber: value));
|
||||
void countryIssuanceChanged(String value) =>
|
||||
emit(state.copyWith(countryIssuance: value));
|
||||
|
||||
// Signature
|
||||
void preparerUsedChanged(bool value) => emit(state.copyWith(preparerUsed: value));
|
||||
void preparerUsedChanged(bool value) =>
|
||||
emit(state.copyWith(preparerUsed: value));
|
||||
void signatureChanged(String value) => emit(state.copyWith(signature: value));
|
||||
|
||||
Future<void> submit() async {
|
||||
emit(state.copyWith(status: FormI9Status.submitting));
|
||||
try {
|
||||
final Map<String, dynamic> formData = {
|
||||
'firstName': state.firstName,
|
||||
'lastName': state.lastName,
|
||||
'middleInitial': state.middleInitial,
|
||||
'otherLastNames': state.otherLastNames,
|
||||
'dob': state.dob,
|
||||
'ssn': state.ssn,
|
||||
'email': state.email,
|
||||
'phone': state.phone,
|
||||
'address': state.address,
|
||||
'aptNumber': state.aptNumber,
|
||||
'city': state.city,
|
||||
'state': state.state,
|
||||
'zipCode': state.zipCode,
|
||||
'citizenshipStatus': state.citizenshipStatus,
|
||||
'uscisNumber': state.uscisNumber,
|
||||
'admissionNumber': state.admissionNumber,
|
||||
'passportNumber': state.passportNumber,
|
||||
'countryIssuance': state.countryIssuance,
|
||||
'preparerUsed': state.preparerUsed,
|
||||
'signature': state.signature,
|
||||
};
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final Map<String, dynamic> formData = {
|
||||
'firstName': state.firstName,
|
||||
'lastName': state.lastName,
|
||||
'middleInitial': state.middleInitial,
|
||||
'otherLastNames': state.otherLastNames,
|
||||
'dob': state.dob,
|
||||
'ssn': state.ssn,
|
||||
'email': state.email,
|
||||
'phone': state.phone,
|
||||
'address': state.address,
|
||||
'aptNumber': state.aptNumber,
|
||||
'city': state.city,
|
||||
'state': state.state,
|
||||
'zipCode': state.zipCode,
|
||||
'citizenshipStatus': state.citizenshipStatus,
|
||||
'uscisNumber': state.uscisNumber,
|
||||
'admissionNumber': state.admissionNumber,
|
||||
'passportNumber': state.passportNumber,
|
||||
'countryIssuance': state.countryIssuance,
|
||||
'preparerUsed': state.preparerUsed,
|
||||
'signature': state.signature,
|
||||
};
|
||||
|
||||
final I9TaxForm form = I9TaxForm(
|
||||
id: _formId.isNotEmpty ? _formId : const Uuid().v4(),
|
||||
title: 'Form I-9',
|
||||
formData: formData,
|
||||
);
|
||||
final I9TaxForm form = I9TaxForm(
|
||||
id: _formId.isNotEmpty ? _formId : const Uuid().v4(),
|
||||
title: 'Form I-9',
|
||||
formData: formData,
|
||||
);
|
||||
|
||||
await _submitI9FormUseCase(form);
|
||||
emit(state.copyWith(status: FormI9Status.success));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: FormI9Status.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await _submitI9FormUseCase(form);
|
||||
emit(state.copyWith(status: FormI9Status.success));
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: FormI9Status.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../../domain/usecases/get_tax_forms_usecase.dart';
|
||||
import 'tax_forms_state.dart';
|
||||
|
||||
class TaxFormsCubit extends Cubit<TaxFormsState> {
|
||||
class TaxFormsCubit extends Cubit<TaxFormsState>
|
||||
with BlocErrorHandler<TaxFormsState> {
|
||||
final GetTaxFormsUseCase _getTaxFormsUseCase;
|
||||
|
||||
TaxFormsCubit(this._getTaxFormsUseCase) : super(const TaxFormsState());
|
||||
|
||||
Future<void> loadTaxForms() async {
|
||||
emit(state.copyWith(status: TaxFormsStatus.loading));
|
||||
try {
|
||||
final List<TaxForm> forms = await _getTaxFormsUseCase();
|
||||
emit(state.copyWith(
|
||||
status: TaxFormsStatus.success,
|
||||
forms: forms,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: TaxFormsStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<TaxForm> forms = await _getTaxFormsUseCase();
|
||||
emit(state.copyWith(status: TaxFormsStatus.success, forms: forms));
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: TaxFormsStatus.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../../../domain/usecases/submit_w4_form_usecase.dart';
|
||||
import 'form_w4_state.dart';
|
||||
|
||||
class FormW4Cubit extends Cubit<FormW4State> {
|
||||
class FormW4Cubit extends Cubit<FormW4State> with BlocErrorHandler<FormW4State> {
|
||||
final SubmitW4FormUseCase _submitW4FormUseCase;
|
||||
String _formId = '';
|
||||
|
||||
@@ -16,31 +17,33 @@ class FormW4Cubit extends Cubit<FormW4State> {
|
||||
emit(const FormW4State()); // Reset
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final Map<String, dynamic> data = form.formData;
|
||||
_formId = form.id;
|
||||
|
||||
|
||||
// Combine address parts if needed, or take existing
|
||||
final String city = data['city'] as String? ?? '';
|
||||
final String stateVal = data['state'] as String? ?? '';
|
||||
final String zip = data['zipCode'] as String? ?? '';
|
||||
final String cityStateZip = '$city, $stateVal $zip'.trim();
|
||||
|
||||
emit(FormW4State(
|
||||
firstName: data['firstName'] as String? ?? '',
|
||||
lastName: data['lastName'] as String? ?? '',
|
||||
ssn: data['ssn'] as String? ?? '',
|
||||
address: data['address'] as String? ?? '',
|
||||
cityStateZip: cityStateZip.contains(',') ? cityStateZip : '',
|
||||
filingStatus: data['filingStatus'] as String? ?? '',
|
||||
multipleJobs: data['multipleJobs'] as bool? ?? false,
|
||||
qualifyingChildren: data['qualifyingChildren'] as int? ?? 0,
|
||||
otherDependents: data['otherDependents'] as int? ?? 0,
|
||||
otherIncome: data['otherIncome'] as String? ?? '',
|
||||
deductions: data['deductions'] as String? ?? '',
|
||||
extraWithholding: data['extraWithholding'] as String? ?? '',
|
||||
signature: data['signature'] as String? ?? '',
|
||||
));
|
||||
emit(
|
||||
FormW4State(
|
||||
firstName: data['firstName'] as String? ?? '',
|
||||
lastName: data['lastName'] as String? ?? '',
|
||||
ssn: data['ssn'] as String? ?? '',
|
||||
address: data['address'] as String? ?? '',
|
||||
cityStateZip: cityStateZip.contains(',') ? cityStateZip : '',
|
||||
filingStatus: data['filingStatus'] as String? ?? '',
|
||||
multipleJobs: data['multipleJobs'] as bool? ?? false,
|
||||
qualifyingChildren: data['qualifyingChildren'] as int? ?? 0,
|
||||
otherDependents: data['otherDependents'] as int? ?? 0,
|
||||
otherIncome: data['otherIncome'] as String? ?? '',
|
||||
deductions: data['deductions'] as String? ?? '',
|
||||
extraWithholding: data['extraWithholding'] as String? ?? '',
|
||||
signature: data['signature'] as String? ?? '',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void nextStep(int totalSteps) {
|
||||
@@ -62,52 +65,65 @@ class FormW4Cubit extends Cubit<FormW4State> {
|
||||
void lastNameChanged(String value) => emit(state.copyWith(lastName: value));
|
||||
void ssnChanged(String value) => emit(state.copyWith(ssn: value));
|
||||
void addressChanged(String value) => emit(state.copyWith(address: value));
|
||||
void cityStateZipChanged(String value) => emit(state.copyWith(cityStateZip: value));
|
||||
void cityStateZipChanged(String value) =>
|
||||
emit(state.copyWith(cityStateZip: value));
|
||||
|
||||
// Form Data
|
||||
void filingStatusChanged(String value) => emit(state.copyWith(filingStatus: value));
|
||||
void multipleJobsChanged(bool value) => emit(state.copyWith(multipleJobs: value));
|
||||
void qualifyingChildrenChanged(int value) => emit(state.copyWith(qualifyingChildren: value));
|
||||
void otherDependentsChanged(int value) => emit(state.copyWith(otherDependents: value));
|
||||
|
||||
void filingStatusChanged(String value) =>
|
||||
emit(state.copyWith(filingStatus: value));
|
||||
void multipleJobsChanged(bool value) =>
|
||||
emit(state.copyWith(multipleJobs: value));
|
||||
void qualifyingChildrenChanged(int value) =>
|
||||
emit(state.copyWith(qualifyingChildren: value));
|
||||
void otherDependentsChanged(int value) =>
|
||||
emit(state.copyWith(otherDependents: value));
|
||||
|
||||
// Adjustments
|
||||
void otherIncomeChanged(String value) => emit(state.copyWith(otherIncome: value));
|
||||
void deductionsChanged(String value) => emit(state.copyWith(deductions: value));
|
||||
void extraWithholdingChanged(String value) => emit(state.copyWith(extraWithholding: value));
|
||||
void otherIncomeChanged(String value) =>
|
||||
emit(state.copyWith(otherIncome: value));
|
||||
void deductionsChanged(String value) =>
|
||||
emit(state.copyWith(deductions: value));
|
||||
void extraWithholdingChanged(String value) =>
|
||||
emit(state.copyWith(extraWithholding: value));
|
||||
void signatureChanged(String value) => emit(state.copyWith(signature: value));
|
||||
|
||||
Future<void> submit() async {
|
||||
emit(state.copyWith(status: FormW4Status.submitting));
|
||||
try {
|
||||
final Map<String, dynamic> formData = {
|
||||
'firstName': state.firstName,
|
||||
'lastName': state.lastName,
|
||||
'ssn': state.ssn,
|
||||
'address': state.address,
|
||||
'cityStateZip': state.cityStateZip, // Note: Repository should split this if needed.
|
||||
'filingStatus': state.filingStatus,
|
||||
'multipleJobs': state.multipleJobs,
|
||||
'qualifyingChildren': state.qualifyingChildren,
|
||||
'otherDependents': state.otherDependents,
|
||||
'otherIncome': state.otherIncome,
|
||||
'deductions': state.deductions,
|
||||
'extraWithholding': state.extraWithholding,
|
||||
'signature': state.signature,
|
||||
};
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final Map<String, dynamic> formData = {
|
||||
'firstName': state.firstName,
|
||||
'lastName': state.lastName,
|
||||
'ssn': state.ssn,
|
||||
'address': state.address,
|
||||
'cityStateZip':
|
||||
state.cityStateZip, // Note: Repository should split this if needed.
|
||||
'filingStatus': state.filingStatus,
|
||||
'multipleJobs': state.multipleJobs,
|
||||
'qualifyingChildren': state.qualifyingChildren,
|
||||
'otherDependents': state.otherDependents,
|
||||
'otherIncome': state.otherIncome,
|
||||
'deductions': state.deductions,
|
||||
'extraWithholding': state.extraWithholding,
|
||||
'signature': state.signature,
|
||||
};
|
||||
|
||||
final W4TaxForm form = W4TaxForm(
|
||||
id: _formId.isNotEmpty ? _formId : const Uuid().v4(),
|
||||
title: 'Form W-4',
|
||||
formData: formData,
|
||||
);
|
||||
final W4TaxForm form = W4TaxForm(
|
||||
id: _formId.isNotEmpty ? _formId : const Uuid().v4(),
|
||||
title: 'Form W-4',
|
||||
formData: formData,
|
||||
);
|
||||
|
||||
await _submitW4FormUseCase(form);
|
||||
emit(state.copyWith(status: FormW4Status.success));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: FormW4Status.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await _submitW4FormUseCase(form);
|
||||
emit(state.copyWith(status: FormW4Status.success));
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: FormW4Status.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,12 +147,12 @@ class TaxFormsPage extends StatelessWidget {
|
||||
if (form is I9TaxForm) {
|
||||
final result = await Modular.to.pushNamed('i9', arguments: form);
|
||||
if (result == true && context.mounted) {
|
||||
BlocProvider.of<TaxFormsCubit>(context).loadTaxForms();
|
||||
await BlocProvider.of<TaxFormsCubit>(context).loadTaxForms();
|
||||
}
|
||||
} else if (form is W4TaxForm) {
|
||||
final result = await Modular.to.pushNamed('w4', arguments: form);
|
||||
if (result == true && context.mounted) {
|
||||
BlocProvider.of<TaxFormsCubit>(context).loadTaxForms();
|
||||
await BlocProvider.of<TaxFormsCubit>(context).loadTaxForms();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,35 +1,42 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../domain/arguments/add_bank_account_params.dart';
|
||||
import '../../domain/usecases/add_bank_account_usecase.dart';
|
||||
import '../../domain/usecases/get_bank_accounts_usecase.dart';
|
||||
import 'bank_account_state.dart';
|
||||
|
||||
class BankAccountCubit extends Cubit<BankAccountState> {
|
||||
class BankAccountCubit extends Cubit<BankAccountState>
|
||||
with BlocErrorHandler<BankAccountState> {
|
||||
final GetBankAccountsUseCase _getBankAccountsUseCase;
|
||||
final AddBankAccountUseCase _addBankAccountUseCase;
|
||||
|
||||
BankAccountCubit({
|
||||
required GetBankAccountsUseCase getBankAccountsUseCase,
|
||||
required AddBankAccountUseCase addBankAccountUseCase,
|
||||
}) : _getBankAccountsUseCase = getBankAccountsUseCase,
|
||||
_addBankAccountUseCase = addBankAccountUseCase,
|
||||
super(const BankAccountState());
|
||||
}) : _getBankAccountsUseCase = getBankAccountsUseCase,
|
||||
_addBankAccountUseCase = addBankAccountUseCase,
|
||||
super(const BankAccountState());
|
||||
|
||||
Future<void> loadAccounts() async {
|
||||
emit(state.copyWith(status: BankAccountStatus.loading));
|
||||
try {
|
||||
final List<BankAccount> accounts = await _getBankAccountsUseCase();
|
||||
emit(state.copyWith(
|
||||
status: BankAccountStatus.loaded,
|
||||
accounts: accounts,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: BankAccountStatus.error,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<BankAccount> accounts = await _getBankAccountsUseCase();
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: BankAccountStatus.loaded,
|
||||
accounts: accounts,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: BankAccountStatus.error,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void toggleForm(bool show) {
|
||||
@@ -43,35 +50,47 @@ class BankAccountCubit extends Cubit<BankAccountState> {
|
||||
required String type,
|
||||
}) async {
|
||||
emit(state.copyWith(status: BankAccountStatus.loading));
|
||||
|
||||
|
||||
// Create domain entity
|
||||
final BankAccount newAccount = BankAccount(
|
||||
id: '', // Generated by server usually
|
||||
userId: '', // Handled by Repo/Auth
|
||||
bankName: bankName,
|
||||
accountNumber: accountNumber,
|
||||
accountName: '',
|
||||
sortCode: routingNumber,
|
||||
type: type == 'CHECKING' ? BankAccountType.checking : BankAccountType.savings,
|
||||
last4: accountNumber.length > 4 ? accountNumber.substring(accountNumber.length - 4) : accountNumber,
|
||||
isPrimary: false,
|
||||
id: '', // Generated by server usually
|
||||
userId: '', // Handled by Repo/Auth
|
||||
bankName: bankName,
|
||||
accountNumber: accountNumber,
|
||||
accountName: '',
|
||||
sortCode: routingNumber,
|
||||
type:
|
||||
type == 'CHECKING'
|
||||
? BankAccountType.checking
|
||||
: BankAccountType.savings,
|
||||
last4:
|
||||
accountNumber.length > 4
|
||||
? accountNumber.substring(accountNumber.length - 4)
|
||||
: accountNumber,
|
||||
isPrimary: false,
|
||||
);
|
||||
|
||||
try {
|
||||
await _addBankAccountUseCase(AddBankAccountParams(account: newAccount));
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
await _addBankAccountUseCase(AddBankAccountParams(account: newAccount));
|
||||
|
||||
// Re-fetch to get latest state including server-generated IDs
|
||||
await loadAccounts();
|
||||
|
||||
emit(state.copyWith(
|
||||
status: BankAccountStatus.accountAdded,
|
||||
showForm: false, // Close form on success
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
status: BankAccountStatus.error,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
// Re-fetch to get latest state including server-generated IDs
|
||||
await loadAccounts();
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: BankAccountStatus.accountAdded,
|
||||
showForm: false, // Close form on success
|
||||
),
|
||||
);
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: BankAccountStatus.error,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../domain/arguments/get_time_cards_arguments.dart';
|
||||
import '../../domain/usecases/get_time_cards_usecase.dart';
|
||||
@@ -8,35 +9,55 @@ part 'time_card_event.dart';
|
||||
part 'time_card_state.dart';
|
||||
|
||||
/// BLoC to manage Time Card state.
|
||||
class TimeCardBloc extends Bloc<TimeCardEvent, TimeCardState> {
|
||||
class TimeCardBloc extends Bloc<TimeCardEvent, TimeCardState>
|
||||
with BlocErrorHandler<TimeCardState> {
|
||||
final GetTimeCardsUseCase getTimeCards;
|
||||
|
||||
|
||||
TimeCardBloc({required this.getTimeCards}) : super(TimeCardInitial()) {
|
||||
on<LoadTimeCards>(_onLoadTimeCards);
|
||||
on<ChangeMonth>(_onChangeMonth);
|
||||
}
|
||||
|
||||
/// Handles fetching time cards for the requested month.
|
||||
Future<void> _onLoadTimeCards(LoadTimeCards event, Emitter<TimeCardState> emit) async {
|
||||
Future<void> _onLoadTimeCards(
|
||||
LoadTimeCards event,
|
||||
Emitter<TimeCardState> emit,
|
||||
) async {
|
||||
emit(TimeCardLoading());
|
||||
try {
|
||||
final List<TimeCard> cards = await getTimeCards(GetTimeCardsArguments(event.month));
|
||||
|
||||
final double totalHours = cards.fold(0.0, (double sum, TimeCard t) => sum + t.totalHours);
|
||||
final double totalEarnings = cards.fold(0.0, (double sum, TimeCard t) => sum + t.totalPay);
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<TimeCard> cards = await getTimeCards(
|
||||
GetTimeCardsArguments(event.month),
|
||||
);
|
||||
|
||||
emit(TimeCardLoaded(
|
||||
timeCards: cards,
|
||||
selectedMonth: event.month,
|
||||
totalHours: totalHours,
|
||||
totalEarnings: totalEarnings,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(TimeCardError(e.toString()));
|
||||
}
|
||||
final double totalHours = cards.fold(
|
||||
0.0,
|
||||
(double sum, TimeCard t) => sum + t.totalHours,
|
||||
);
|
||||
final double totalEarnings = cards.fold(
|
||||
0.0,
|
||||
(double sum, TimeCard t) => sum + t.totalPay,
|
||||
);
|
||||
|
||||
emit(
|
||||
TimeCardLoaded(
|
||||
timeCards: cards,
|
||||
selectedMonth: event.month,
|
||||
totalHours: totalHours,
|
||||
totalEarnings: totalEarnings,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (String errorKey) => TimeCardError(errorKey),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onChangeMonth(ChangeMonth event, Emitter<TimeCardState> emit) async {
|
||||
add(LoadTimeCards(event.month));
|
||||
|
||||
Future<void> _onChangeMonth(
|
||||
ChangeMonth event,
|
||||
Emitter<TimeCardState> emit,
|
||||
) async {
|
||||
add(LoadTimeCards(event.month));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import '../../domain/arguments/save_attire_arguments.dart';
|
||||
@@ -8,7 +9,8 @@ import '../../domain/usecases/save_attire_usecase.dart';
|
||||
import '../../domain/usecases/upload_attire_photo_usecase.dart';
|
||||
import 'attire_state.dart';
|
||||
|
||||
class AttireCubit extends Cubit<AttireState> {
|
||||
class AttireCubit extends Cubit<AttireState>
|
||||
with BlocErrorHandler<AttireState> {
|
||||
final GetAttireOptionsUseCase _getAttireOptionsUseCase;
|
||||
final SaveAttireUseCase _saveAttireUseCase;
|
||||
final UploadAttirePhotoUseCase _uploadAttirePhotoUseCase;
|
||||
@@ -23,30 +25,41 @@ class AttireCubit extends Cubit<AttireState> {
|
||||
|
||||
Future<void> loadOptions() async {
|
||||
emit(state.copyWith(status: AttireStatus.loading));
|
||||
try {
|
||||
final List<AttireItem> options = await _getAttireOptionsUseCase();
|
||||
|
||||
// Auto-select mandatory items initially as per prototype
|
||||
final List<String> mandatoryIds = options
|
||||
.where((AttireItem e) => e.isMandatory)
|
||||
.map((AttireItem e) => e.id)
|
||||
.toList();
|
||||
|
||||
final List<String> initialSelection = List<String>.from(state.selectedIds);
|
||||
for (final String id in mandatoryIds) {
|
||||
if (!initialSelection.contains(id)) {
|
||||
initialSelection.add(id);
|
||||
}
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<AttireItem> options = await _getAttireOptionsUseCase();
|
||||
|
||||
emit(state.copyWith(
|
||||
status: AttireStatus.success,
|
||||
options: options,
|
||||
selectedIds: initialSelection,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(status: AttireStatus.failure, errorMessage: e.toString()));
|
||||
}
|
||||
// Auto-select mandatory items initially as per prototype
|
||||
final List<String> mandatoryIds =
|
||||
options
|
||||
.where((AttireItem e) => e.isMandatory)
|
||||
.map((AttireItem e) => e.id)
|
||||
.toList();
|
||||
|
||||
final List<String> initialSelection = List<String>.from(
|
||||
state.selectedIds,
|
||||
);
|
||||
for (final String id in mandatoryIds) {
|
||||
if (!initialSelection.contains(id)) {
|
||||
initialSelection.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: AttireStatus.success,
|
||||
options: options,
|
||||
selectedIds: initialSelection,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: AttireStatus.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void toggleSelection(String id) {
|
||||
@@ -67,51 +80,81 @@ class AttireCubit extends Cubit<AttireState> {
|
||||
}
|
||||
|
||||
Future<void> uploadPhoto(String itemId) async {
|
||||
final Map<String, bool> currentUploading = Map<String, bool>.from(state.uploadingStatus);
|
||||
final Map<String, bool> currentUploading = Map<String, bool>.from(
|
||||
state.uploadingStatus,
|
||||
);
|
||||
currentUploading[itemId] = true;
|
||||
emit(state.copyWith(uploadingStatus: currentUploading));
|
||||
|
||||
try {
|
||||
final String url = await _uploadAttirePhotoUseCase(
|
||||
UploadAttirePhotoArguments(itemId: itemId),
|
||||
);
|
||||
|
||||
final Map<String, String> currentPhotos = Map<String, String>.from(state.photoUrls);
|
||||
currentPhotos[itemId] = url;
|
||||
|
||||
// Auto-select item on upload success if not selected
|
||||
final List<String> currentSelection = List<String>.from(state.selectedIds);
|
||||
if (!currentSelection.contains(itemId)) {
|
||||
currentSelection.add(itemId);
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final String url = await _uploadAttirePhotoUseCase(
|
||||
UploadAttirePhotoArguments(itemId: itemId),
|
||||
);
|
||||
|
||||
currentUploading[itemId] = false;
|
||||
emit(state.copyWith(
|
||||
uploadingStatus: currentUploading,
|
||||
photoUrls: currentPhotos,
|
||||
selectedIds: currentSelection,
|
||||
));
|
||||
} catch (e) {
|
||||
currentUploading[itemId] = false;
|
||||
emit(state.copyWith(
|
||||
uploadingStatus: currentUploading,
|
||||
final Map<String, String> currentPhotos = Map<String, String>.from(
|
||||
state.photoUrls,
|
||||
);
|
||||
currentPhotos[itemId] = url;
|
||||
|
||||
// Auto-select item on upload success if not selected
|
||||
final List<String> currentSelection = List<String>.from(
|
||||
state.selectedIds,
|
||||
);
|
||||
if (!currentSelection.contains(itemId)) {
|
||||
currentSelection.add(itemId);
|
||||
}
|
||||
|
||||
final Map<String, bool> updatedUploading = Map<String, bool>.from(
|
||||
state.uploadingStatus,
|
||||
);
|
||||
updatedUploading[itemId] = false;
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
uploadingStatus: updatedUploading,
|
||||
photoUrls: currentPhotos,
|
||||
selectedIds: currentSelection,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (String errorKey) {
|
||||
final Map<String, bool> updatedUploading = Map<String, bool>.from(
|
||||
state.uploadingStatus,
|
||||
);
|
||||
updatedUploading[itemId] = false;
|
||||
// Could handle error specifically via snackbar event
|
||||
));
|
||||
}
|
||||
// For now, attaching the error message but keeping state generally usable
|
||||
return state.copyWith(
|
||||
uploadingStatus: updatedUploading,
|
||||
errorMessage: errorKey,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> save() async {
|
||||
if (!state.canSave) return;
|
||||
|
||||
|
||||
emit(state.copyWith(status: AttireStatus.saving));
|
||||
try {
|
||||
await _saveAttireUseCase(SaveAttireArguments(
|
||||
selectedItemIds: state.selectedIds,
|
||||
photoUrls: state.photoUrls,
|
||||
));
|
||||
emit(state.copyWith(status: AttireStatus.saved));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(status: AttireStatus.failure, errorMessage: e.toString()));
|
||||
}
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
await _saveAttireUseCase(
|
||||
SaveAttireArguments(
|
||||
selectedItemIds: state.selectedIds,
|
||||
photoUrls: state.photoUrls,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(status: AttireStatus.saved));
|
||||
},
|
||||
onError:
|
||||
(String errorKey) => state.copyWith(
|
||||
status: AttireStatus.failure,
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../domain/arguments/get_emergency_contacts_arguments.dart';
|
||||
import '../../domain/arguments/save_emergency_contacts_arguments.dart';
|
||||
@@ -12,7 +13,8 @@ export 'emergency_contact_state.dart';
|
||||
|
||||
// BLoC
|
||||
class EmergencyContactBloc
|
||||
extends Bloc<EmergencyContactEvent, EmergencyContactState> {
|
||||
extends Bloc<EmergencyContactEvent, EmergencyContactState>
|
||||
with BlocErrorHandler<EmergencyContactState> {
|
||||
final GetEmergencyContactsUseCase getEmergencyContacts;
|
||||
final SaveEmergencyContactsUseCase saveEmergencyContacts;
|
||||
|
||||
@@ -28,29 +30,30 @@ class EmergencyContactBloc
|
||||
|
||||
add(EmergencyContactsLoaded());
|
||||
}
|
||||
|
||||
|
||||
Future<void> _onLoaded(
|
||||
EmergencyContactsLoaded event,
|
||||
Emitter<EmergencyContactState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: EmergencyContactStatus.loading));
|
||||
try {
|
||||
final contacts = await getEmergencyContacts(
|
||||
const GetEmergencyContactsArguments(),
|
||||
);
|
||||
emit(state.copyWith(
|
||||
status: EmergencyContactStatus.loaded,
|
||||
contacts: contacts.isNotEmpty
|
||||
? contacts
|
||||
: [EmergencyContact.empty()],
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final contacts = await getEmergencyContacts(
|
||||
const GetEmergencyContactsArguments(),
|
||||
);
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: EmergencyContactStatus.loaded,
|
||||
contacts: contacts.isNotEmpty ? contacts : [EmergencyContact.empty()],
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: EmergencyContactStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onAdded(
|
||||
@@ -85,18 +88,19 @@ class EmergencyContactBloc
|
||||
Emitter<EmergencyContactState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: EmergencyContactStatus.saving));
|
||||
try {
|
||||
await saveEmergencyContacts(
|
||||
SaveEmergencyContactsArguments(
|
||||
contacts: state.contacts,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(status: EmergencyContactStatus.saved));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
await saveEmergencyContacts(
|
||||
SaveEmergencyContactsArguments(contacts: state.contacts),
|
||||
);
|
||||
emit(state.copyWith(status: EmergencyContactStatus.saved));
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: EmergencyContactStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../domain/arguments/save_experience_arguments.dart';
|
||||
import '../../domain/usecases/get_staff_industries_usecase.dart';
|
||||
@@ -92,8 +93,8 @@ class ExperienceState extends Equatable {
|
||||
}
|
||||
|
||||
// BLoC
|
||||
class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
||||
|
||||
class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState>
|
||||
with BlocErrorHandler<ExperienceState> {
|
||||
final GetStaffIndustriesUseCase getIndustries;
|
||||
final GetStaffSkillsUseCase getSkills;
|
||||
final SaveExperienceUseCase saveExperience;
|
||||
@@ -102,10 +103,12 @@ class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
||||
required this.getIndustries,
|
||||
required this.getSkills,
|
||||
required this.saveExperience,
|
||||
}) : super(const ExperienceState(
|
||||
availableIndustries: Industry.values,
|
||||
availableSkills: ExperienceSkill.values,
|
||||
)) {
|
||||
}) : super(
|
||||
const ExperienceState(
|
||||
availableIndustries: Industry.values,
|
||||
availableSkills: ExperienceSkill.values,
|
||||
),
|
||||
) {
|
||||
on<ExperienceLoaded>(_onLoaded);
|
||||
on<ExperienceIndustryToggled>(_onIndustryToggled);
|
||||
on<ExperienceSkillToggled>(_onSkillToggled);
|
||||
@@ -120,26 +123,28 @@ class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
||||
Emitter<ExperienceState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: ExperienceStatus.loading));
|
||||
try {
|
||||
final results = await Future.wait([
|
||||
getIndustries(),
|
||||
getSkills(),
|
||||
]);
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final results = await Future.wait([getIndustries(), getSkills()]);
|
||||
|
||||
emit(state.copyWith(
|
||||
status: ExperienceStatus.initial,
|
||||
selectedIndustries: results[0]
|
||||
.map((e) => Industry.fromString(e))
|
||||
.whereType<Industry>()
|
||||
.toList(),
|
||||
selectedSkills: results[1],
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: ExperienceStatus.initial,
|
||||
selectedIndustries:
|
||||
results[0]
|
||||
.map((e) => Industry.fromString(e))
|
||||
.whereType<Industry>()
|
||||
.toList(),
|
||||
selectedSkills: results[1],
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: ExperienceStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onIndustryToggled(
|
||||
@@ -183,19 +188,22 @@ class ExperienceBloc extends Bloc<ExperienceEvent, ExperienceState> {
|
||||
Emitter<ExperienceState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: ExperienceStatus.loading));
|
||||
try {
|
||||
await saveExperience(
|
||||
SaveExperienceArguments(
|
||||
industries: state.selectedIndustries.map((e) => e.value).toList(),
|
||||
skills: state.selectedSkills,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(status: ExperienceStatus.success));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
await saveExperience(
|
||||
SaveExperienceArguments(
|
||||
industries: state.selectedIndustries.map((e) => e.value).toList(),
|
||||
skills: state.selectedSkills,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(status: ExperienceStatus.success));
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: ExperienceStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_modular/flutter_modular.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
|
||||
import '../../domain/usecases/get_personal_info_usecase.dart';
|
||||
@@ -13,17 +14,17 @@ import 'personal_info_state.dart';
|
||||
/// during onboarding or profile editing. It delegates business logic to
|
||||
/// use cases following Clean Architecture principles.
|
||||
class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
with BlocErrorHandler<PersonalInfoState>
|
||||
implements Disposable {
|
||||
|
||||
/// Creates a [PersonalInfoBloc].
|
||||
///
|
||||
/// Requires the use cases to load and update the profile.
|
||||
PersonalInfoBloc({
|
||||
required GetPersonalInfoUseCase getPersonalInfoUseCase,
|
||||
required UpdatePersonalInfoUseCase updatePersonalInfoUseCase,
|
||||
}) : _getPersonalInfoUseCase = getPersonalInfoUseCase,
|
||||
_updatePersonalInfoUseCase = updatePersonalInfoUseCase,
|
||||
super(const PersonalInfoState.initial()) {
|
||||
}) : _getPersonalInfoUseCase = getPersonalInfoUseCase,
|
||||
_updatePersonalInfoUseCase = updatePersonalInfoUseCase,
|
||||
super(const PersonalInfoState.initial()) {
|
||||
on<PersonalInfoLoadRequested>(_onLoadRequested);
|
||||
on<PersonalInfoFieldChanged>(_onFieldChanged);
|
||||
on<PersonalInfoAddressSelected>(_onAddressSelected);
|
||||
@@ -40,32 +41,37 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
Emitter<PersonalInfoState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: PersonalInfoStatus.loading));
|
||||
try {
|
||||
final Staff staff = await _getPersonalInfoUseCase();
|
||||
|
||||
// Initialize form values from staff entity
|
||||
// Note: Staff entity currently stores address as a string, but we want to map it to 'preferredLocations'
|
||||
final Map<String, dynamic> initialValues = <String, dynamic>{
|
||||
'name': staff.name,
|
||||
'email': staff.email,
|
||||
'phone': staff.phone,
|
||||
'preferredLocations': staff.address != null
|
||||
? <String?>[staff.address]
|
||||
: <dynamic>[], // TODO: Map correctly when Staff entity supports list
|
||||
'avatar': staff.avatar,
|
||||
};
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final Staff staff = await _getPersonalInfoUseCase();
|
||||
|
||||
emit(state.copyWith(
|
||||
status: PersonalInfoStatus.loaded,
|
||||
staff: staff,
|
||||
formValues: initialValues,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
// Initialize form values from staff entity
|
||||
// Note: Staff entity currently stores address as a string, but we want to map it to 'preferredLocations'
|
||||
final Map<String, dynamic> initialValues = <String, dynamic>{
|
||||
'name': staff.name,
|
||||
'email': staff.email,
|
||||
'phone': staff.phone,
|
||||
'preferredLocations':
|
||||
staff.address != null
|
||||
? <String?>[staff.address]
|
||||
: <dynamic>[], // TODO: Map correctly when Staff entity supports list
|
||||
'avatar': staff.avatar,
|
||||
};
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: PersonalInfoStatus.loaded,
|
||||
staff: staff,
|
||||
formValues: initialValues,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: PersonalInfoStatus.error,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Handles updating a field value in the current staff profile.
|
||||
@@ -86,43 +92,48 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
if (state.staff == null) return;
|
||||
|
||||
emit(state.copyWith(status: PersonalInfoStatus.saving));
|
||||
try {
|
||||
final Staff updatedStaff = await _updatePersonalInfoUseCase(
|
||||
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 = <String, dynamic>{
|
||||
'name': updatedStaff.name,
|
||||
'email': updatedStaff.email,
|
||||
'phone': updatedStaff.phone,
|
||||
'preferredLocations': updatedStaff.address != null
|
||||
? <String?>[updatedStaff.address]
|
||||
: <dynamic>[],
|
||||
'avatar': updatedStaff.avatar,
|
||||
};
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final Staff updatedStaff = await _updatePersonalInfoUseCase(
|
||||
UpdatePersonalInfoParams(
|
||||
staffId: state.staff!.id,
|
||||
data: state.formValues,
|
||||
),
|
||||
);
|
||||
|
||||
emit(state.copyWith(
|
||||
status: PersonalInfoStatus.saved,
|
||||
staff: updatedStaff,
|
||||
formValues: newValues,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
// Update local state with the returned staff and keep form values in sync
|
||||
final Map<String, dynamic> newValues = <String, dynamic>{
|
||||
'name': updatedStaff.name,
|
||||
'email': updatedStaff.email,
|
||||
'phone': updatedStaff.phone,
|
||||
'preferredLocations':
|
||||
updatedStaff.address != null
|
||||
? <String?>[updatedStaff.address]
|
||||
: <dynamic>[],
|
||||
'avatar': updatedStaff.avatar,
|
||||
};
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
status: PersonalInfoStatus.saved,
|
||||
staff: updatedStaff,
|
||||
formValues: newValues,
|
||||
),
|
||||
);
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: PersonalInfoStatus.error,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onAddressSelected(
|
||||
PersonalInfoAddressSelected event,
|
||||
Emitter<PersonalInfoState> emit,
|
||||
) {
|
||||
// TODO: Implement Google Places logic if needed
|
||||
// TODO: Implement Google Places logic if needed
|
||||
}
|
||||
|
||||
/// With _onPhotoUploadRequested and _onSaveRequested removed or renamed,
|
||||
@@ -133,3 +144,4 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user