feat: update profile setup and bank account management; enhance API integration and data handling

This commit is contained in:
Achintha Isuru
2026-03-17 14:32:26 -04:00
parent b6a655a261
commit de388c9a77
21 changed files with 142 additions and 85 deletions

View File

@@ -1,6 +1,7 @@
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:staff_bank_account/src/domain/arguments/add_bank_account_params.dart';
import 'package:staff_bank_account/src/domain/repositories/bank_account_repository.dart';
/// Implementation of [BankAccountRepository] using the V2 API.
@@ -17,7 +18,7 @@ class BankAccountRepositoryImpl implements BankAccountRepository {
Future<List<BankAccount>> getAccounts() async {
final ApiResponse response =
await _api.get(StaffEndpoints.bankAccounts);
final List<dynamic> items = response.data['accounts'] as List<dynamic>? ?? <dynamic>[];
final List<dynamic> items = response.data['items'] as List<dynamic>? ?? <dynamic>[];
return items
.map((dynamic json) =>
BankAccount.fromJson(json as Map<String, dynamic>))
@@ -25,10 +26,10 @@ class BankAccountRepositoryImpl implements BankAccountRepository {
}
@override
Future<void> addAccount(BankAccount account) async {
Future<void> addAccount(AddBankAccountParams params) async {
await _api.post(
StaffEndpoints.bankAccounts,
data: account.toJson(),
data: params.toJson(),
);
}
}

View File

@@ -1,16 +1,44 @@
import 'package:equatable/equatable.dart';
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:krow_domain/krow_domain.dart' show AccountType;
/// Arguments for adding a bank account.
class AddBankAccountParams extends UseCaseArgument with EquatableMixin {
/// Parameters for creating a new bank account via the V2 API.
///
/// Maps directly to the `bankAccountCreateSchema` zod schema:
/// `{ bankName, accountNumber, routingNumber, accountType }`.
class AddBankAccountParams extends UseCaseArgument {
/// Creates an [AddBankAccountParams].
const AddBankAccountParams({
required this.bankName,
required this.accountNumber,
required this.routingNumber,
required this.accountType,
});
const AddBankAccountParams({required this.account});
final BankAccount account;
/// Name of the bank / financial institution.
final String bankName;
/// Full account number.
final String accountNumber;
/// Routing / transit number.
final String routingNumber;
/// Account type (checking or savings).
final AccountType accountType;
/// Serialises to the V2 API request body.
Map<String, dynamic> toJson() => <String, dynamic>{
'bankName': bankName,
'accountNumber': accountNumber,
'routingNumber': routingNumber,
'accountType': accountType.toJson(),
};
@override
List<Object?> get props => <Object?>[account];
@override
bool? get stringify => true;
List<Object?> get props => <Object?>[
bankName,
accountNumber,
routingNumber,
accountType,
];
}

View File

@@ -1,12 +1,12 @@
import 'package:krow_domain/krow_domain.dart';
import 'package:krow_domain/krow_domain.dart' show BankAccount;
import '../arguments/add_bank_account_params.dart';
/// Repository interface for managing bank accounts.
///
/// Uses [BankAccount] from the V2 domain layer.
abstract class BankAccountRepository {
/// Fetches the list of bank accounts for the current staff member.
Future<List<BankAccount>> getAccounts();
/// Adds a new bank account.
Future<void> addAccount(BankAccount account);
/// Creates a new bank account with the given [params].
Future<void> addAccount(AddBankAccountParams params);
}

View File

@@ -1,15 +1,17 @@
import 'package:krow_core/core.dart';
import '../repositories/bank_account_repository.dart';
import '../arguments/add_bank_account_params.dart';
import '../repositories/bank_account_repository.dart';
/// Use case to add a bank account.
class AddBankAccountUseCase implements UseCase<AddBankAccountParams, void> {
/// Creates an [AddBankAccountUseCase].
AddBankAccountUseCase(this._repository);
final BankAccountRepository _repository;
@override
Future<void> call(AddBankAccountParams params) {
return _repository.addAccount(params.account);
return _repository.addAccount(params);
}
}

View File

@@ -1,6 +1,7 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:krow_domain/krow_domain.dart' show AccountType, BankAccount;
import '../../domain/arguments/add_bank_account_params.dart';
import '../../domain/usecases/add_bank_account_usecase.dart';
import '../../domain/usecases/get_bank_accounts_usecase.dart';
@@ -47,15 +48,10 @@ class BankAccountCubit extends Cubit<BankAccountState>
}) async {
emit(state.copyWith(status: BankAccountStatus.loading));
// Create domain entity
final BankAccount newAccount = BankAccount(
accountId: '', // Generated by server
final AddBankAccountParams params = AddBankAccountParams(
bankName: bankName,
providerReference: routingNumber,
last4: accountNumber.length > 4
? accountNumber.substring(accountNumber.length - 4)
: accountNumber,
isPrimary: false,
accountNumber: accountNumber,
routingNumber: routingNumber,
accountType: type == 'CHECKING'
? AccountType.checking
: AccountType.savings,
@@ -64,7 +60,7 @@ class BankAccountCubit extends Cubit<BankAccountState>
await handleError(
emit: emit,
action: () async {
await _addBankAccountUseCase(AddBankAccountParams(account: newAccount));
await _addBankAccountUseCase(params);
// Re-fetch to get latest state including server-generated IDs
await loadAccounts();

View File

@@ -22,7 +22,7 @@ class TimeCardRepositoryImpl implements TimeCardRepository {
'month': month.month,
},
);
final List<dynamic> items = response.data['entries'] as List<dynamic>? ?? <dynamic>[];
final List<dynamic> items = response.data['items'] as List<dynamic>? ?? <dynamic>[];
return items
.map((dynamic json) =>
TimeCardEntry.fromJson(json as Map<String, dynamic>))