Created
November 2, 2024 23:47
-
-
Save oyewalekehinde/623375425fd3c557adee0e747ad53a2f to your computer and use it in GitHub Desktop.
httpservice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class HttpService { | |
| Dio? _dio; | |
| final String baseUrl; | |
| final bool hasAuthorization; | |
| final bool isFormType; | |
| HttpService( | |
| {required this.baseUrl, | |
| this.hasAuthorization = false, | |
| this.isFormType = false}) { | |
| _dio = Dio(BaseOptions( | |
| baseUrl: baseUrl, | |
| connectTimeout: const Duration(seconds: 10), | |
| receiveTimeout: const Duration(seconds: 8), | |
| )); | |
| _interceptorsInit(); | |
| } | |
| static const int timeoutDuration = 1; | |
| Future<Response> getRequest( | |
| urlEndPoint, { | |
| Map<String, dynamic>? queryParameters, | |
| }) async { | |
| Response response; | |
| if (kDebugMode) log(urlEndPoint); | |
| response = await _dio! | |
| .get(urlEndPoint, queryParameters: queryParameters) | |
| .timeout(const Duration(minutes: timeoutDuration)); | |
| if(response.statusCode==401){ | |
| } | |
| return response; | |
| } | |
| Future<Response> post( | |
| urlEndpoint, { | |
| data, | |
| Map<String, dynamic>? queryParameters, | |
| }) async { | |
| Response response; | |
| if (kDebugMode) log(urlEndpoint.toString()); | |
| response = await _dio! | |
| .post(urlEndpoint, data: data, queryParameters: queryParameters) | |
| .timeout(const Duration(minutes: timeoutDuration)); | |
| return response; | |
| } | |
| Future<Response> put(urlEndpoint, | |
| {data, Map<String, dynamic>? queryParameters}) async { | |
| Response response; | |
| response = await _dio! | |
| .put(urlEndpoint, data: data, queryParameters: queryParameters) | |
| .timeout(const Duration(minutes: timeoutDuration)); | |
| return response; | |
| } | |
| Future<Response> delete(urlEndpoint, | |
| {data, Map<String, dynamic>? queryParameters}) async { | |
| Response response; | |
| response = await _dio! | |
| .delete(urlEndpoint, data: data, queryParameters: queryParameters) | |
| .timeout(const Duration(minutes: timeoutDuration)); | |
| return response; | |
| } | |
| Future<Response> patch(urlEndpoint, | |
| {data, Map<String, dynamic>? queryParameters}) async { | |
| Response response; | |
| response = await _dio! | |
| .patch(urlEndpoint, data: data, queryParameters: queryParameters) | |
| .timeout(const Duration(minutes: timeoutDuration)); | |
| return response; | |
| } | |
| _interceptorsInit() { | |
| _dio!.interceptors.add(HeaderInterceptor( | |
| hasToken: hasAuthorization, | |
| dio: _dio!, | |
| contentType: isFormType | |
| ? HeaderContentType.formType | |
| : HeaderContentType.jsonType)); | |
| } | |
| } |
and here also
import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:u_360_v2_mobile_app/beneficiary_management/api/beneficiary_management_api.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:u_360_v2_mobile_app/core/common/widgets/popup_widgets.dart';
import '../../authentication/api_client/auth_api_cient.dart';
import '../../config/config.dart';
import '../../core/common/storage/secure_storage.dart';
import '../../transfer/models/beneficiary_state.dart';
import '../../transfer/single_transfer/api/single_transfer_api.dart';
import '../notifier/beneficiary_management_notifier.dart';
part 'beneficiary_management_controller.g.dart';
final beneficiariesProvider =
StateProvider<List<BeneficiaryState>>((ref) => []);
@riverpod
class BeneficiaryManagementController extends _$BeneficiaryManagementController {
TextEditingController bankNameController = TextEditingController();
TextEditingController accountNumberController = TextEditingController();
TextEditingController accountNameController = TextEditingController();
TextEditingController bankCodeController = TextEditingController();
TextEditingController accountCurrencyController = TextEditingController();
TextEditingController corporateNameController = TextEditingController();
bool nameEnquiryStatus = false;
String? beneficiaryAccountName = "";
final apiClient = ApiClient();
final beneficiaryManagementApi = BeneficiaryManagementApi();
void setAccountNumberValue(String beneficiaryAccountNumber, WidgetRef ref) {
ref.read(accountNumberProvider.notifier).state = beneficiaryAccountNumber;
}
// Initialize with an empty instance of BeneficiaryState
@override
BeneficiaryState build() {
return BeneficiaryState();
}
Future<String?> fetchCorporateAccountName({
required String accountNumber,
WidgetRef? ref,
String? bankCode,
}) async {
if (accountNumber.length == 10 && ref != null) {
final result = await SingleTransferApi(ref: ref)
.nameEnquiry(accountNumber: accountNumber, bankCode: bankCode);
if (hasAuthenticationOrProcessingError(result)) {
nameEnquiryStatus = true;
} else if (result?.code == "00") {
beneficiaryAccountName = result?.accountName;
nameEnquiryStatus = true;
return result?.accountName;
}
}
nameEnquiryStatus = true;
return null;
}
Future<void> loadBeneficiaries(WidgetRef ref) async {
log("Loading beneficiaries");
var userResponse = await Storage.loadUserProfile();
var userCorpId = userResponse?.corpId;
var userSubsidiaryId = userResponse?.subsidiaryId;
var beneficiaryWithCorpIdPayload = {
"corpId": userCorpId,
"subsidiaryId": userSubsidiaryId,
"userId": '13'
};
var beneficiariesResponse = await apiClient.postCustomRequest(
Config.getBeneficiariesByCorpId ?? "",
beneficiaryWithCorpIdPayload,
);
final beneficiaries = (beneficiariesResponse.data as List<dynamic>)
.map((item) => BeneficiaryState.fromJson(item as Map<String, dynamic>))
.toList();
ref.read(beneficiariesProvider.notifier).state = beneficiaries;
}
Future<void> addBeneficiaries({
required WidgetRef ref,
BuildContext? context,
BeneficiaryManagementNotifier? beneficiaryNotifier,
String? beneficiaryAccountName,
String? bankCode,
}) async {
final accountNumber = ref.read(accountNumberProvider);
try {
await beneficiaryManagementApi.addBeneficiary(
bankName: bankNameController.text,
beneficiaryAccountNumber: accountNumber,
beneficiaryAccountName: accountNameController.text,
accountCurrency: accountCurrencyController.text,
bankCode: bankCodeController.text,
);
// Reload beneficiaries after adding a new one to update the UI
await loadBeneficiaries(ref);
} catch (e) {
toastInfo("An error occurred");
log("An error occurred: $e");
}
}
Future<void> deleteBeneficiaries({
required int? beneficiaryId,
required WidgetRef ref,
}) async {
await beneficiaryManagementApi.deleteBeneficiary(
beneficiaryId: beneficiaryId ?? 0,
);
await loadBeneficiaries(ref);
}
}
@riverpod
class UpdateBeneficiaryController {}
final accountNumberProvider = StateProvider<String>((ref) => "");
bool hasAuthenticationOrProcessingError(dynamic result) {
return result?.message == "Authentication Failed" ||
result?.message == "Error processing request" ||
result?.code == "401" ||
result?.code == "96";
}
i dey read the value for this widget
`import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:u_360_v2_mobile_app/authentication/sign_up/notifier/sign_up_notifier.dart';
import 'package:u_360_v2_mobile_app/beneficiary_management/controller/beneficiary_management_controller.dart';
import 'package:u_360_v2_mobile_app/core/common/models/banks.dart';
import 'package:u_360_v2_mobile_app/core/common/utils/image_res.dart';
import 'package:u_360_v2_mobile_app/core/common/widgets/app_shadow.dart';
import 'package:u_360_v2_mobile_app/core/common/widgets/app_textfields.dart';
import 'package:u_360_v2_mobile_app/core/common/widgets/button_widgets.dart';
import 'package:u_360_v2_mobile_app/core/common/widgets/image_widgets.dart';
import 'package:u_360_v2_mobile_app/core/common/widgets/text_widgets.dart';
import 'package:u_360_v2_mobile_app/transfer/provider/name_enquiry_provider.dart';
import '../../../authentication/login/controller/custom_api_controller.dart';
import '../../../authentication/widgets/decorated_container.dart';
import '../../../core/common/provider/global_loader.dart';
import '../../../core/constants/colors.dart';
import '../../../transfer/widgets/transfer_widgets.dart';
import '../../notifier/beneficiary_management_notifier.dart';
class BeneficiaryItems extends ConsumerStatefulWidget {
const BeneficiaryItems({super.key});
@override
ConsumerState<BeneficiaryItems> createState() => _BeneficiaryItemsState();
}
class _BeneficiaryItemsState extends ConsumerState<BeneficiaryItems> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
final beneficiaryState = ref.watch(beneficiaryStateNotifierProvider);
final loader = ref.watch(appLoaderProvider);
return beneficiaryState.when(
data: (data) => ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return Padding(
padding:
const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 8.0),
child: Container(
decoration: appBoxDecorationTextField(),
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 1,
child: Align(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width:
MediaQuery.of(context).size.width * 0.5,
child: text14Normal(
text:
data[index].beneficiaryAccountName ??
"",
color: AppColors.black,
),
),
const SizedBox(height: 15),
text14Medium(
text:
data[index].beneficiaryAccountNumber ??
"",
color: AppColors.black,
),
],
),
),
),
Flexible(
flex: 1,
child: Align(
alignment: Alignment.topRight,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: text14Medium(text: "..."),
onTap: () {
displayDeleteBottomSheet(
context: context,
ref: ref,
beneficiaryId:
data[index].beneficiaryId,
);
},
),
const SizedBox(height: 15),
SizedBox(
width:
MediaQuery.of(context).size.width * 0.5,
child: text14Normal(
isEndText: true,
text: data[index].bankName ?? "",
color: AppColors.black,
),
),
],
),
),
),
],
),
),
),
);
},
),
error: (err, stackTrace) {
log("error message: $err");
log("stack trace message: $err");
return text14Bold(text: "Error Loading Page");
},
loading: () => const Center(child: CircularProgressIndicator()));
}
}
Future displayDeleteBottomSheet({
required BuildContext context,
required WidgetRef ref,
required int? beneficiaryId,
}) {
return showModalBottomSheet(
context: context,
isDismissible: false,
enableDrag: false,
builder: (context) => Container(
constraints: const BoxConstraints(
maxHeight: 500,
),
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 20),
appImage(
imagePath: ImageRes.errorLargeIcon,
height: 70,
width: 70,
),
const SizedBox(height: 20),
text16BoldCenter(text: "Confirm Action", isCenterText: true),
text14Normal(
text: "Are you sure you want to delete this beneficiary?",
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(vertical: 28.0),
child: Row(
children: [
Expanded(
child: AppButton(
buttonTextColor: AppColors.black,
buttonColor: AppColors.greyCard,
buttonName: "Cancel",
height: 45,
extraCornerRadius: true,
isButtonPair: true,
func: () {
Navigator.pop(context);
},
),
),
const SizedBox(width: 20),
Expanded(
child: AppButton(
buttonTextColor: AppColors.whiteColor,
buttonName: "Yes, Delete",
extraCornerRadius: true,
height: 45,
isButtonPair: true,
func: () {
ref
.watch(beneficiaryManagementControllerProvider
.notifier)
.deleteBeneficiaries(
beneficiaryId: beneficiaryId, ref: ref);
ref
.read(beneficiaryManagementControllerProvider
.notifier)
.loadBeneficiaries(ref);
Navigator.pop(context);
},
),
),
],
),
)
],
),
),
),
);
}
Future displayApprovedBottomSheet(
{required BuildContext context,
required WidgetRef ref,
required Function() setStateFunc}) {
final beneficiaryName =
ref.watch(beneficiaryManagementControllerProvider).beneficiaryAccountName;
return showModalBottomSheet(
context: context,
isDismissible: false,
enableDrag: false,
builder: (context) => Container(
constraints: const BoxConstraints(
maxHeight: 500,
),
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 20),
text16BoldCenter(text: "Add Beneficiary", isCenterText: true),
const SizedBox(height: 20),
appImage(
imagePath: ImageRes.successLargeIcon, height: 80, width: 80),
const SizedBox(height: 20),
text16BoldCenter(
text: "Beneficiary Added Successfully", isCenterText: true),
text14Normal(
text:
"$beneficiaryName has been added successfully as your beneficiary",
isCenterText: true),
const SizedBox(height: 20),
AppButton(
buttonWidth: 50,
buttonName: "Close",
func: setStateFunc,
),
const SizedBox(height: 20),
],
))));
}
Future displayBottomSheet(
{required BuildContext context,
required WidgetRef ref,
String? dropdownValue1,
AsyncValue<List<GETBANKLISTITEM>>? bankListAsyncState,
TextEditingController? accountNumberController,
required Function() setStateFunc}) {
final beneficiaryManagementNotifier =
ref.watch(beneficiaryManagementProvider.notifier);
return showModalBottomSheet(
context: context,
isDismissible: false,
enableDrag: false,
builder: (context) => Container(
constraints: const BoxConstraints(
maxHeight: 500,
),
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
bankListAsyncState?.when(
data: (data) => transferDropdownContainer<GETBANKLISTITEM>(
headerText: "Bank name",
hintText: '-select bank-',
dropdownValue: dropdownValue1 ?? "",
onChanged: (value) {
GETBANKLISTITEM? selectedItem = data.firstWhere(
(item) => item.bNKNAME == value,
orElse: () => GETBANKLISTITEM(),
);
var bankCode = selectedItem.bNKCODE;
var bankName = selectedItem.bNKNAME;
},
asyncList: bankListAsyncState,
),
error: (error, stackTrace) =>
const Center(child: Text("Error loading data")),
loading: () => buildCustomCircularProgressIndicator(),
) ??
const SizedBox(height: 10),
const SizedBox(height: 20),
appTextField<String>(
hintText: "Account Number",
textFieldHeight: 45,
textWidget: text12Normal(text: "Account num"),
paddingLeft: 0,
paddingRight: 0,
isAccountNumber: true,
isNumberKeyboard: true,
controller: accountNumberController,
isPostFailureFixIconEnabled: (ref
.watch(nameEnquiryProvider.notifier)
.nameEnquiryStatus ??
false) &&
ref
.watch(beneficiaryManagementControllerProvider.notifier)
.accountNumberController
.text
.isEmpty,
isPostSuccessFixIconEnabled: (ref
.watch(nameEnquiryProvider.notifier)
.nameEnquiryStatus ??
false) &&
ref
.watch(beneficiaryManagementControllerProvider.notifier)
.accountNumberController
.text
.isNotEmpty,
func: (value) {
if (value.length == 10) {
ref
.read(beneficiaryManagementControllerProvider.notifier)
.setAccountNumberValue(value, ref);
ref
.read(beneficiaryManagementControllerProvider.notifier)
.fetchCorporateAccountName(
accountNumber: value, ref: ref);
}
},
),
const SizedBox(height: 20),
appTextField(
textWidget: text12Normal(text: "Account name"),
text: "Account Name",
backgroundColor: AppColors.skyBlueBackground,
controller: ref
.watch(corporateProfileStateNotifierProvider.notifier)
.corporateAccountEmailController,
readOnly: true,
textFieldHeight: 45,
hintText: "Account Name",
paddingLeft: 0,
paddingRight: 0),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(vertical: 28.0),
child: Row(
children: [
Expanded(
child: AppButton(
buttonTextColor: AppColors.black,
buttonColor: AppColors.greyCard,
buttonName: "Cancel",
height: 45,
extraCornerRadius: true,
isButtonPair: true,
func: () {
accountNumberController?.text = "";
Navigator.pop(context);
}),
),
const SizedBox(width: 20),
Expanded(
child: AppButton(
buttonTextColor: AppColors.whiteColor,
buttonName: "Save",
extraCornerRadius: true,
height: 45,
isButtonPair: true,
func: () async {
await displayApprovedBottomSheet(
context: context,
ref: ref,
setStateFunc: setStateFunc);
ref
.watch(beneficiaryManagementControllerProvider
.notifier)
.addBeneficiaries(
ref: ref,
context: context,
beneficiaryNotifier:
beneficiaryManagementNotifier);
ref.refresh(beneficiaryStateNotifierProvider);
accountNumberController?.text = "";
Navigator.pop(context);
},
),
),
],
),
)
],
),
),
),
barrierColor: Colors.black.withOpacity(0.5),
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
),
);
}
`
Author
if (response.statusCode == 401 || response.statusCode == 403) {
// call refresh token function
try {
final refreshResponse = await _dio!.get(
'https://api.example.com/refresh',
data: {'refresh_token': ""},
);
if (response.statusCode == 200) {
final newAccessToken = response.data['access_token'];
await UserTokenManager.insertAccessToken(newAccessToken);
Response newResponse = await _dio!
.get(urlEndPoint, queryParameters: queryParameters)
.timeout(const Duration(minutes: timeoutDuration));
response = newResponse;
}
} catch (e) {
throw Exception();
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.