Commit 0bf528a4 authored by DatHV's avatar DatHV
Browse files

refactor logic

parent 89983084
...@@ -3,13 +3,14 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart'; ...@@ -3,13 +3,14 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart'; import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/screen/data_network_service/product_network_data_model.dart'; import 'package:mypoint_flutter_app/screen/data_network_service/product_network_data_model.dart';
import 'package:mypoint_flutter_app/widgets/custom_toast_message.dart';
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import '../../configs/constants.dart'; import '../../configs/constants.dart';
import '../../preference/contact_storage_service.dart'; import '../../preference/contact_storage_service.dart';
import '../../preference/point/point_manager.dart'; import '../../preference/point/point_manager.dart';
import '../topup/models/brand_network_model.dart';
import '../voucher/models/product_brand_model.dart'; import '../voucher/models/product_brand_model.dart';
import '../voucher/models/product_model.dart';
import '../voucher/models/product_type.dart';
class DataNetworkServiceViewModel extends RestfulApiViewModel { class DataNetworkServiceViewModel extends RestfulApiViewModel {
final RxList<String> histories = <String>[].obs; final RxList<String> histories = <String>[].obs;
...@@ -17,9 +18,9 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel { ...@@ -17,9 +18,9 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel {
final RxList<TopUpNetworkDataModel> topUpNetworkData = <TopUpNetworkDataModel>[].obs; final RxList<TopUpNetworkDataModel> topUpNetworkData = <TopUpNetworkDataModel>[].obs;
final Map<String, List<TopUpNetworkDataModel>> _allValue = {}; final Map<String, List<TopUpNetworkDataModel>> _allValue = {};
var selectedBrand = Rxn<ProductBrandModel>(); final Rxn<ProductBrandModel> selectedBrand = Rxn<ProductBrandModel>();
var selectedProduct = Rxn<ProductNetworkDataModel>(); final Rxn<ProductNetworkDataModel> selectedProduct = Rxn<ProductNetworkDataModel>();
var phoneNumber = ''.obs; final RxString phoneNumber = ''.obs;
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
void Function(String message)? onShowAlertRedeemSuccess; void Function(String message)? onShowAlertRedeemSuccess;
...@@ -48,43 +49,44 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel { ...@@ -48,43 +49,44 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel {
} }
} }
firstLoadNetworkData() async { Future<void> firstLoadNetworkData() async {
_getNetworkBrands(); await _getNetworkBrands();
} }
_getNetworkBrands() { Future<void> _getNetworkBrands() async {
showLoading(); await callApi<List<ProductBrandModel>>(
client.productTopUpBrands().then((response) { request: () => client.productTopUpBrands(),
topUpBrands.assignAll(response.data ?? []); onSuccess: (data, _) {
hideLoading(); topUpBrands.assignAll(data);
checkMobileNetwork(); checkMobileNetwork();
}).catchError((error) { },
hideLoading(); onFailure: (mgs, _, _) async {
print('Error fetching brands topup: $error'); topUpBrands.clear();
}); onShowAlertError?.call(mgs);
},
);
} }
checkMobileNetwork() { Future<void> checkMobileNetwork() async {
showLoading(); await callApi<BrandNameCheckResponse>(
client.checkMobileNetwork(phoneNumber.value).then((response) { request: () => client.checkMobileNetwork(phoneNumber.value),
final brandCode = response.data?.brand ?? ''; onSuccess: (data, _) {
final brand = topUpBrands.isNotEmpty final brandCode = data.brand ?? '';
? topUpBrands.firstWhere( var brand = topUpBrands.isNotEmpty
(brand) => brand.code == brandCode, ? topUpBrands.firstWhere(
orElse: () => topUpBrands.first, (b) => b.code == brandCode,
) : null; orElse: () => topUpBrands.first,
selectedBrand.value = brand; )
hideLoading(); : topUpBrands.firstOrNull;
getTelcoDetail(); selectedBrand.value = brand;
}).catchError((error) { getTelcoDetail();
final first = topUpBrands.firstOrNull; },
if (first != null) { onFailure: (_, _, _) async {
selectedBrand.value = first; final first = topUpBrands.firstOrNull;
} if (first != null) selectedBrand.value = first;
hideLoading(); getTelcoDetail();
getTelcoDetail(); },
print('Error checking mobile network: $error'); );
});
} }
Future<void> getTelcoDetail({String? selected}) async { Future<void> getTelcoDetail({String? selected}) async {
...@@ -94,12 +96,10 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel { ...@@ -94,12 +96,10 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel {
void makeSelected(List<TopUpNetworkDataModel> data) { void makeSelected(List<TopUpNetworkDataModel> data) {
bool didSelect = false; bool didSelect = false;
final list = data final list = data.expand((e) => e.products ?? []).toList();
.expand((e) => e.products ?? [])
.toList();
if (selected != null && selected.isNotEmpty) { if (selected != null && selected.isNotEmpty) {
for (var item in list) { for (var item in list) {
final isMatch = item == int.tryParse(selected); final isMatch = item.id == int.tryParse(selected);
if (isMatch) { if (isMatch) {
selectedProduct.value = item; selectedProduct.value = item;
didSelect = true; didSelect = true;
...@@ -117,43 +117,34 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel { ...@@ -117,43 +117,34 @@ class DataNetworkServiceViewModel extends RestfulApiViewModel {
makeSelected(cached); makeSelected(cached);
return; return;
} }
showLoading(); await callApi<List<TopUpNetworkDataModel>>(
try { request: () => client.getNetworkProducts((id ?? 0).toString()),
final result = await client.getNetworkProducts((id ?? 0).toString()); onSuccess: (data, _) {
var data = result.data ?? []; final filtered = (data)
data = data .where((e) => e.products?.isNotEmpty == true)
.where((e) => e.products?.isNotEmpty == true) .toList();
.toList(); _allValue[code ?? ""] = filtered;
_allValue[code ?? ""] = data; topUpNetworkData.assignAll(filtered);
topUpNetworkData.assignAll(data); makeSelected(filtered);
makeSelected(data); },
hideLoading(); onFailure: (_, _, _) async {},
} catch (error) { );
print("Error fetching all products: $error");
hideLoading();
}
} }
redeemProductMobileCard() async { Future<void> redeemProductMobileCard() async {
final id = selectedProduct.value?.id; final id = selectedProduct.value?.id;
if (id == null) { if (id == null) {
onShowAlertError?.call("Vui lòng chọn sản phẩm"); showToastMessage('Vui lòng chọn sản phẩm');
return;
}
showLoading();
try {
final response = await client.redeemProductTopUps(id, phoneNumber.value);
hideLoading();
if (!response.isSuccess) {
onShowAlertError?.call(response.errorMessage ?? Constants.commonError);
return;
}
final mgs = (response.errorMessage ?? "").isEmpty ? "Chúc mừng bạn đã đổi Ưu đãi data thành công" : (response.errorMessage ?? "");
onShowAlertRedeemSuccess?.call(mgs);
} catch (error) {
hideLoading();
onShowAlertError?.call(error.toString());
return; return;
} }
await callApi<EmptyCodable>(
request: () => client.redeemProductTopUps(id, phoneNumber.value),
onSuccess: (data, _) {
onShowAlertRedeemSuccess?.call("Chúc mừng bạn đã đổi Ưu đãi data thành công");
},
onFailure: (msg, _, _) async {
onShowAlertError?.call(msg.isNotEmpty ? msg : Constants.commonError);
},
);
} }
} }
\ No newline at end of file
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart'; import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/widgets/custom_toast_message.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import '../../configs/constants.dart'; import '../../configs/constants.dart';
import '../otp/delete_account_otp_repository.dart'; import '../otp/delete_account_otp_repository.dart';
import '../otp/model/create_otp_response_model.dart';
import '../otp/otp_screen.dart'; import '../otp/otp_screen.dart';
import '../otp/verify_otp_repository.dart';
class DeleteAccountViewModel extends RestfulApiViewModel { class DeleteAccountViewModel extends RestfulApiViewModel {
RxBool agreed = false.obs; final RxBool agreed = false.obs;
void confirmDelete() { Future<void> confirmDelete() async {
if (agreed.value) { if (!agreed.value) {
showLoading(); showToastMessage("Bạn cần đồng ý với điều khoản để tiếp tục.");
client.requestOtpDeleteAccount().then((value) { return;
hideLoading();
if (value.isSuccess) {
final phone = DataPreference.instance.phone ?? "";
Get.to(
() => OtpScreen(repository: DeleteAccountOtpRepository(phone, value.data?.resendAfterSecond ?? Constants.otpTtl)),
);
} else {
final mgs = value.errorMessage ?? Constants.commonError;
Get.snackbar("Thông báo", mgs);
}
});
} else {
Get.snackbar("Thông báo", "Bạn cần đồng ý với điều khoản để tiếp tục.");
} }
await callApi<CreateOTPResponseModel>(
request: () => client.requestOtpDeleteAccount(),
onSuccess: (data, _) {
final phone = DataPreference.instance.phone ?? "";
final ttl = data.resendAfterSecond ?? Constants.otpTtl;
Get.to(() => OtpScreen(repository: DeleteAccountOtpRepository(phone, ttl)));
},
onFailure: (msg, _, _) async {
showToastMessage(msg);
},
);
} }
} }
...@@ -5,54 +5,51 @@ import '../../networking/restful_api_viewmodel.dart'; ...@@ -5,54 +5,51 @@ import '../../networking/restful_api_viewmodel.dart';
import 'device_manager_model.dart'; import 'device_manager_model.dart';
class DeviceManagerViewModel extends RestfulApiViewModel { class DeviceManagerViewModel extends RestfulApiViewModel {
var logoutDevicesResponse = Rxn<DevicesLogoutListResponse>(); final Rxn<DevicesLogoutListResponse> logoutDevicesResponse = Rxn<DevicesLogoutListResponse>();
var currentDevice = Rxn<DeviceItemModel>(); final Rxn<DeviceItemModel> currentDevice = Rxn<DeviceItemModel>();
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
getData() { void getData() {
getLogoutDevicesResponse(); getLogoutDevicesResponse();
getCurrentDevice(); getCurrentDevice();
} }
Future<void> getLogoutDevicesResponse() async { Future<void> getLogoutDevicesResponse() async {
final body = {"page": 0, "limit": 200}; final body = {"page": 0, "limit": 200};
showLoading(); await callApi<DevicesLogoutListResponse>(
try { request: () => client.getLogoutDevices(body),
final response = await client.getLogoutDevices(body); onSuccess: (data, _) {
hideLoading(); logoutDevicesResponse.value = data;
if (response.isSuccess && response.data != null) { },
logoutDevicesResponse.value = response.data; onFailure: (msg, _, _) async {
} else { onShowAlertError?.call(msg);
onShowAlertError?.call(response.message ?? Constants.commonError); },
} );
} catch (error) {
hideLoading();
onShowAlertError?.call(Constants.commonError);
}
} }
Future<void> getCurrentDevice() async { Future<void> getCurrentDevice() async {
final response = await client.getCurrentDevice(); await callApi<DeviceItemModel>(
if (response.isSuccess && response.data != null) { request: () => client.getCurrentDevice(),
currentDevice.value = response.data; onSuccess: (data, _) {
} currentDevice.value = data;
},
onFailure: (_, _, _) async {},
withLoading: false,
);
} }
Future<void> deleteDevice(DeviceItemModel item) async { Future<void> deleteDevice(DeviceItemModel item) async {
if ((item.deviceKey ?? '').isEmpty) return; final key = item.deviceKey ?? '';
showLoading(); if (key.isEmpty) return;
try { await callApi<String>(
final response = await client.deleteDevice(item.deviceKey ?? ''); request: () => client.deleteDevice(key),
hideLoading(); onSuccess: (data, _) async {
if (response.isSuccess) { await getLogoutDevicesResponse();
getLogoutDevicesResponse(); onShowAlertError?.call(data);
onShowAlertError?.call(response.data ?? "Đã xóa thiết bị thành công"); },
} else { onFailure: (msg, _, _) async {
onShowAlertError?.call(response.message ?? Constants.commonError); onShowAlertError?.call(msg);
} },
} catch (error) { );
hideLoading();
onShowAlertError?.call("Error fetching product detail: $error");
}
} }
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
import 'package:mypoint_flutter_app/extensions/num_extension.dart'; import 'package:mypoint_flutter_app/extensions/num_extension.dart';
import 'package:mypoint_flutter_app/widgets/image_loader.dart'; import 'package:mypoint_flutter_app/widgets/image_loader.dart';
import '../../resources/base_color.dart'; import '../../resources/base_color.dart';
......
...@@ -2,48 +2,43 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart'; ...@@ -2,48 +2,43 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/extensions/collection_extension.dart'; import 'package:mypoint_flutter_app/extensions/collection_extension.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import '../../configs/constants.dart';
import '../transaction/model/payment_method_model.dart'; import '../transaction/model/payment_method_model.dart';
import 'models/customer_contract_object_model.dart'; import 'models/customer_contract_object_model.dart';
import 'models/electric_payment_response_model.dart'; import 'models/electric_payment_response_model.dart';
class ElectricPaymentBillViewModel extends RestfulApiViewModel { class ElectricPaymentBillViewModel extends RestfulApiViewModel {
var paymentMethods = RxList<PaymentMethodModel>(); final RxList<PaymentMethodModel> paymentMethods = <PaymentMethodModel>[].obs;
var selectedPaymentMethodIndex = 0.obs; final RxInt selectedPaymentMethodIndex = 0.obs;
void Function(ElectricPaymentResponseModel data)? customerEvnPaymentGatewayResponse; void Function(ElectricPaymentResponseModel data)? customerEvnPaymentGatewayResponse;
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
Future<void> getPaymentMethods() async { Future<void> getPaymentMethods() async {
showLoading(); await callApi<List<PaymentMethodModel>>(
try { request: () => client.getPreviewPaymentMethods(),
final response = await client.getPreviewPaymentMethods(); onSuccess: (data, _) {
hideLoading(); selectedPaymentMethodIndex.value = 0;
selectedPaymentMethodIndex.value = 0; paymentMethods.assignAll(data);
paymentMethods.value = response.data ?? []; },
} catch (error) { onFailure: (_, _, _) async {},
hideLoading(); );
}
} }
customerEvnPaymentGatewayRequest(CustomerContractModel bill) async { Future<void> customerEvnPaymentGatewayRequest(CustomerContractModel bill) async {
final paymentMethod = paymentMethods.value.safe(selectedPaymentMethodIndex.value ?? 0) ?? paymentMethods.firstOrNull; final paymentMethod = paymentMethods.safe(selectedPaymentMethodIndex.value) ?? paymentMethods.firstOrNull;
final paymentMethodType = paymentMethod?.type?.methodBillEVN ?? ''; final paymentMethodType = paymentMethod?.type?.methodBillEVN ?? '';
if (paymentMethodType.isEmpty) { if (paymentMethodType.isEmpty) {
onShowAlertError?.call("Vui lòng chọn phương thức thanh toán."); onShowAlertError?.call("Vui lòng chọn phương thức thanh toán.");
return; return;
} }
showLoading(); await callApi<ElectricPaymentResponseModel>(
try { request: () => client.customerEvnPaymentGatewayRequest(bill, paymentMethodType),
final response = await client.customerEvnPaymentGatewayRequest(bill, paymentMethodType); onSuccess: (data, _) {
hideLoading(); customerEvnPaymentGatewayResponse?.call(data);
if (response.isSuccess && response.data != null) { },
customerEvnPaymentGatewayResponse?.call(response.data!); onFailure: (msg, _, _) async {
} else { onShowAlertError?.call(msg);
onShowAlertError?.call(response.errorMessage ?? "Lỗi khi thanh toán, vui lòng thử lại sau."); },
} defaultError: "Lỗi khi thanh toán, vui lòng thử lại sau.",
} catch (error) { );
hideLoading();
onShowAlertError?.call(Constants.commonError);
}
} }
} }
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import '../../configs/constants.dart';
import 'electric_payment_bill_screen.dart'; import 'electric_payment_bill_screen.dart';
import 'models/customer_contract_object_model.dart'; import 'models/customer_contract_object_model.dart';
...@@ -10,47 +9,44 @@ class ElectricPaymentViewModel extends RestfulApiViewModel { ...@@ -10,47 +9,44 @@ class ElectricPaymentViewModel extends RestfulApiViewModel {
final RxList<CustomerContractModel> billContracts = <CustomerContractModel>[].obs; final RxList<CustomerContractModel> billContracts = <CustomerContractModel>[].obs;
void customerContractRequestSearch(String maKH) { void customerContractRequestSearch(String maKH) {
showLoading(); callApi<CustomerContractModel>(
client.customerContractRequestSearch(maKH).then((value) { request: () => client.customerContractRequestSearch(maKH),
hideLoading(); onSuccess: (data, _) {
final result = value.data; if ((data.amount ?? 0) == 0) {
if (!value.isSuccess) {
onShowAlertError?.call(
value.errorMessage ?? "Không tìm thấy thông tin mã khách hàng, vui lòng kiểm tra và thử lại.",
);
} else if (result != null) {
if ((result.amount ?? 0) == 0) {
onShowAlertError?.call("Bạn đã thanh toán hết hóa đơn."); onShowAlertError?.call("Bạn đã thanh toán hết hóa đơn.");
} else { } else {
Get.to(ElectricPaymentBillScreen(bill: result,)); Get.to(ElectricPaymentBillScreen(bill: data));
} }
} else { },
onShowAlertError?.call("Không tìm thấy thông tin mã khách hàng, vui lòng kiểm tra và thử lại."); onFailure: (msg, _, _) async {
} onShowAlertError?.call(msg);
}); },
defaultError: "Không tìm thấy thông tin mã khách hàng, vui lòng kiểm tra và thử lại."
);
} }
void customerContractSearchHistoryGetList() { void customerContractSearchHistoryGetList() {
showLoading(); callApi<List<CustomerContractModel>>(
client.customerContractSearchHistoryGetList().then((value) { request: () => client.customerContractSearchHistoryGetList(),
hideLoading(); onSuccess: (data, _) {
final result = value.data; billContracts.assignAll(data);
if (!value.isSuccess && result == null) { },
onShowAlertError?.call(value.errorMessage ?? Constants.commonError); onFailure: (msg, _, _) async {
} else { billContracts.clear();
billContracts.value = result ?? []; onShowAlertError?.call(msg);
} },
}); );
} }
void customerContractDelete(String code) { void customerContractDelete(String code) {
showLoading(); callApi<bool>(
client.customerContractDelete(code).then((value) { request: () => client.customerContractDelete(code),
hideLoading(); onSuccess: (_, _) {
if (!value.isSuccess) { customerContractSearchHistoryGetList();
onShowAlertError?.call(value.errorMessage ?? Constants.commonError,); },
} onFailure: (msg, _, _) async {
customerContractSearchHistoryGetList(); onShowAlertError?.call(msg);
}); },
);
} }
} }
...@@ -3,8 +3,10 @@ import 'package:flutter/material.dart'; ...@@ -3,8 +3,10 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/screen/pageDetail/campaign_detail_screen.dart'; import 'package:mypoint_flutter_app/screen/pageDetail/campaign_detail_screen.dart';
import 'package:mypoint_flutter_app/widgets/back_button.dart'; import 'package:mypoint_flutter_app/widgets/back_button.dart';
import 'package:mypoint_flutter_app/widgets/custom_toast_message.dart';
import '../../base/base_screen.dart'; import '../../base/base_screen.dart';
import '../../base/basic_state.dart'; import '../../base/basic_state.dart';
import '../../configs/constants.dart';
import '../../resources/base_color.dart'; import '../../resources/base_color.dart';
import '../../shared/router_gage.dart'; import '../../shared/router_gage.dart';
import '../../widgets/custom_navigation_bar.dart'; import '../../widgets/custom_navigation_bar.dart';
...@@ -27,9 +29,6 @@ class _FAQScreenState extends BaseState<FAQScreen> with BasicState { ...@@ -27,9 +29,6 @@ class _FAQScreenState extends BaseState<FAQScreen> with BasicState {
body: Column( body: Column(
children: [ children: [
Obx(() { Obx(() {
if (_controller.isLoading.value) {
return const Expanded(child: Center(child: CircularProgressIndicator()));
}
if (_controller.faqItems.isEmpty) { if (_controller.faqItems.isEmpty) {
return const Expanded(child: Center(child: Text("Không có dữ liệu."))); return const Expanded(child: Center(child: Text("Không có dữ liệu.")));
} }
...@@ -50,12 +49,7 @@ class _FAQScreenState extends BaseState<FAQScreen> with BasicState { ...@@ -50,12 +49,7 @@ class _FAQScreenState extends BaseState<FAQScreen> with BasicState {
if (item.pageId != null && item.pageId!.isNotEmpty) { if (item.pageId != null && item.pageId!.isNotEmpty) {
Get.toNamed(campaignDetailScreen, arguments: {"id": item.pageId}); Get.toNamed(campaignDetailScreen, arguments: {"id": item.pageId});
} else { } else {
Get.snackbar( showToastMessage(ErrorCodes.serverErrorMessage);
"Thông báo",
"Không thể mở chi tiết vì thiếu ID!",
backgroundColor: Colors.redAccent,
colorText: Colors.white,
);
} }
}, },
child: Column( child: Column(
......
import 'dart:convert';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import 'faqs_model.dart'; import 'faqs_model.dart';
class FAQViewModel extends RestfulApiViewModel { class FAQViewModel extends RestfulApiViewModel {
var faqItems = <PageItemModel>[].obs; final RxList<PageItemModel> faqItems = <PageItemModel>[].obs;
var isLoading = true.obs;
@override @override
void onInit() { void onInit() {
...@@ -15,12 +13,14 @@ class FAQViewModel extends RestfulApiViewModel { ...@@ -15,12 +13,14 @@ class FAQViewModel extends RestfulApiViewModel {
} }
Future<void> fetchFAQItems() async { Future<void> fetchFAQItems() async {
showLoading(); await callApi<FAQItemModelResponse>(
isLoading(true); request: () => client.websiteFolderGetPageList({"folder_uri": "FAQ"}),
client.websiteFolderGetPageList({"folder_uri": "FAQ"}).then((value) { onSuccess: (data, _) {
hideLoading(); faqItems.assignAll(data.items ?? []);
isLoading(false); },
faqItems.value = value.data?.items ?? []; onFailure: (_, _, _) async {
}); faqItems.clear();
},
);
} }
} }
...@@ -67,9 +67,6 @@ class _GameTabScreenState extends BaseState<GameTabScreen> with BasicState, Popu ...@@ -67,9 +67,6 @@ class _GameTabScreenState extends BaseState<GameTabScreen> with BasicState, Popu
], ],
), ),
body: Obx(() { body: Obx(() {
if (_viewModel.isLoading.value) {
return const Center(child: CircularProgressIndicator());
}
if (_viewModel.games.isEmpty) { if (_viewModel.games.isEmpty) {
return const Center(child: EmptyWidget()); return const Center(child: EmptyWidget());
} }
......
...@@ -4,38 +4,36 @@ import 'package:mypoint_flutter_app/screen/game/models/game_bundle_item_model.da ...@@ -4,38 +4,36 @@ import 'package:mypoint_flutter_app/screen/game/models/game_bundle_item_model.da
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import '../../configs/constants.dart'; import '../../configs/constants.dart';
import 'models/game_bundle_response.dart';
class GameTabViewModel extends RestfulApiViewModel { class GameTabViewModel extends RestfulApiViewModel {
final RxList<GameBundleItemModel> games = <GameBundleItemModel>[].obs; final RxList<GameBundleItemModel> games = <GameBundleItemModel>[].obs;
var turnsNumberText = "".obs; final RxString turnsNumberText = "".obs;
var isLoading = false.obs;
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
void Function(GameBundleItemModel data)? gotoGameDetail; void Function(GameBundleItemModel data)? gotoGameDetail;
void getGames() { void getGames() {
isLoading(true); callApi<GameBundleResponse>(
client.getGames().then((value) { request: () => client.getGames(),
if (!value.isSuccess) { onSuccess: (data, _) {
onShowAlertError?.call(value.errorMessage ?? Constants.commonError); games.assignAll(data.games ?? []);
} else { turnsNumberText.value = data.turnsNumberText ?? "";
games.value = value.data?.games ?? []; },
turnsNumberText.value = value.data?.turnsNumberText ?? ""; onFailure: (msg, _, _) async {
} onShowAlertError?.call(msg);
isLoading(false); },
}); );
} }
void getGameDetail(String gameId) { void getGameDetail(String gameId) {
isLoading(true); callApi<GameBundleItemModel>(
client.getGameDetail(gameId).then((value) { request: () => client.getGameDetail(gameId),
if (!value.isSuccess) { onSuccess: (data, _) {
onShowAlertError?.call(value.errorMessage ?? Constants.commonError); gotoGameDetail?.call(data);
} else if (value.data != null) { },
gotoGameDetail?.call(value.data!); onFailure: (msg, _, _) async {
} else { onShowAlertError?.call(msg);
onShowAlertError?.call(Constants.commonError); },
} );
isLoading(false);
});
} }
} }
\ No newline at end of file
...@@ -5,17 +5,18 @@ import '../../networking/restful_api_viewmodel.dart'; ...@@ -5,17 +5,18 @@ import '../../networking/restful_api_viewmodel.dart';
import 'health_book_model.dart'; import 'health_book_model.dart';
class HealthBookCardDetailViewModel extends RestfulApiViewModel { class HealthBookCardDetailViewModel extends RestfulApiViewModel {
var card = Rxn<HealthBookCardItemModel>(); final Rxn<HealthBookCardItemModel> card = Rxn<HealthBookCardItemModel>();
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
Future<void> getHealthBookCardDetail(String cardId) async { Future<void> getHealthBookCardDetail(String cardId) async {
showLoading(); await callApi<HealthBookCardItemModel>(
final response = await client.getDetailHealthBookCard(cardId); request: () => client.getDetailHealthBookCard(cardId),
hideLoading(); onSuccess: (data, _) {
if (response.isSuccess) { card.value = data;
card.value = response.data; },
} else { onFailure: (msg, _, _) async {
onShowAlertError?.call(response.errorMessage ?? Constants.commonError); onShowAlertError?.call(msg);
} },
);
} }
} }
\ No newline at end of file
...@@ -6,10 +6,10 @@ import '../../networking/restful_api_viewmodel.dart'; ...@@ -6,10 +6,10 @@ import '../../networking/restful_api_viewmodel.dart';
import 'health_book_model.dart'; import 'health_book_model.dart';
class HealthBookViewModel extends RestfulApiViewModel { class HealthBookViewModel extends RestfulApiViewModel {
var healthBookData = Rxn<HealthBookResponseModel>(); final Rxn<HealthBookResponseModel> healthBookData = Rxn<HealthBookResponseModel>();
var healthBookDataDetail = Rxn<HealthBookCardItemModel>(); final Rxn<HealthBookCardItemModel> healthBookDataDetail = Rxn<HealthBookCardItemModel>();
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
RxInt selectedIndex = 0.obs; final RxInt selectedIndex = 0.obs;
late List<HeaderFilterOrderModel> headerFilterOrder; late List<HeaderFilterOrderModel> headerFilterOrder;
@override @override
...@@ -45,58 +45,14 @@ class HealthBookViewModel extends RestfulApiViewModel { ...@@ -45,58 +45,14 @@ class HealthBookViewModel extends RestfulApiViewModel {
var body = headerFilterOrder[selectedIndex.value].params; var body = headerFilterOrder[selectedIndex.value].params;
body['page'] = 1; body['page'] = 1;
body['size'] = 10000; body['size'] = 10000;
showLoading(); await callApi<HealthBookResponseModel>(
try { request: () => client.getHealthBookCards(body),
final response = await client.getHealthBookCards(body); onSuccess: (data, _) {
hideLoading(); healthBookData.value = data;
// var data = HealthBookResponseModel(total: 20, products: makeFakeHealthBookCards(20)); },
// healthBookData.value = data; onFailure: (msg, _, _) async {
if (response.isSuccess) { onShowAlertError?.call(msg);
healthBookData.value = response.data; },
} else { );
onShowAlertError?.call(response.errorMessage ?? Constants.commonError);
}
} catch (error) {
hideLoading();
onShowAlertError?.call("Error fetching product detail: $error");
}
} }
// Future<void> getDetailHealthBookCard(String id) async {
// showLoading();
// try {
// final response = await client.getDetailHealthBookCard(id);
// hideLoading();
// if (response.isSuccess) {
// healthBookDataDetail.value = response.data;
// } else {
// onShowAlertError?.call(response.errorMessage ?? Constants.commonError);
// }
// } catch (error) {
// hideLoading();
// onShowAlertError?.call("Error fetching product detail: $error");
// }
// }
// List<HealthBookCardItemModel> makeFakeHealthBookCards(int n) {
// return List.generate(n, (i) {
// final id = 2000 + i;
// return HealthBookCardItemModel(
// itemId: id,
// cardName: 'Thẻ Khám #$id',
// fullName: 'User #$id',
// cardCode: 'MP-${id.toString().padLeft(4, '0')}',
// expireDate: '2025-12-31T00:00:00Z',
// phoneNumber: '09${(10000000 + i).toString().padLeft(8, '0')}',
// updatedAt: '2025-10-10T10:00:00Z',
// countCheckupUnused: i % 6,
// bottomButton: ButtonConfigModel(text: 'Sử dụng', action: 'use'),
// media: [
// ProductMediaItem(url: 'https://picsum.photos/seed/$id/300/300'),
// ],
// buyMoreNote: ButtonConfigModel(text: 'Mua thêm', action: 'buy_more'),
// active: ActiveTextConfig(text: 'Còn hiệu lực', textColor: '#0F9D58', bgColor: '#E6F4EA'),
// );
// });
// }
} }
\ No newline at end of file
...@@ -119,3 +119,4 @@ class HealthBookItem extends StatelessWidget { ...@@ -119,3 +119,4 @@ class HealthBookItem extends StatelessWidget {
); );
} }
} }
...@@ -3,6 +3,7 @@ import 'dart:math'; ...@@ -3,6 +3,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:mypoint_flutter_app/extensions/num_extension.dart';
import 'models/transaction_summary_by_date_model.dart'; import 'models/transaction_summary_by_date_model.dart';
class MonthlyPointsChart extends StatelessWidget { class MonthlyPointsChart extends StatelessWidget {
...@@ -26,12 +27,21 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -26,12 +27,21 @@ class MonthlyPointsChart extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print('🔍 MonthlyPointsChart Debug:');
print(' - items.length: ${items.length}');
print(' - date: $date');
print(' - monthSummary: $monthSummary');
for (int i = 0; i < items.length; i++) {
print(' - items[$i]: ${items[i].summaryDate} -> reward: ${items[i].rewardDayTotal}');
}
final parsed = _parseToDayMap(items, date); final parsed = _parseToDayMap(items, date);
print('items ${items.length}, parsed: $parsed'); print(' - parsed map: $parsed');
final daysInMonth = DateUtils.getDaysInMonth(date.year, date.month); final daysInMonth = DateUtils.getDaysInMonth(date.year, date.month);
final maxVal = (parsed.values.isEmpty ? 0 : parsed.values.reduce((a, b) => a > b ? a : b)).abs(); final maxVal = parsed.values.isEmpty ? 0 : parsed.values.reduce((a, b) => a > b ? a : b);
final yMax = _niceMax(maxVal.toDouble()); final yMax = _niceMax(maxVal.abs().toDouble());
final yStep = _niceStep(yMax); final yStep = _niceStep(yMax);
final stats = _statsByDay(items, date); final stats = _statsByDay(items, date);
final barGroups = List.generate(daysInMonth, (i) { final barGroups = List.generate(daysInMonth, (i) {
final day = i + 1; final day = i + 1;
...@@ -42,6 +52,12 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -42,6 +52,12 @@ class MonthlyPointsChart extends StatelessWidget {
barRods: [BarChartRodData(toY: v, width: 8, borderRadius: BorderRadius.circular(2), color: color)], barRods: [BarChartRodData(toY: v, width: 8, borderRadius: BorderRadius.circular(2), color: color)],
); );
}); });
print(' - daysInMonth: $daysInMonth');
print(' - maxVal: $maxVal');
print(' - yMax: $yMax');
print(' - yStep: $yStep');
print(' - barGroups.length: ${barGroups.length}');
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
...@@ -62,7 +78,7 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -62,7 +78,7 @@ class MonthlyPointsChart extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
_formatInt(_toDouble(monthSummary?.rewardMonthTotal ?? '0')), _toDouble(monthSummary?.rewardMonthTotal ?? '0').money(CurrencyUnit.noneSpace),
style: const TextStyle( style: const TextStyle(
fontSize: 40, fontSize: 40,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
...@@ -80,19 +96,19 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -80,19 +96,19 @@ class MonthlyPointsChart extends StatelessWidget {
child: BarChart( child: BarChart(
BarChartData( BarChartData(
minY: 0, minY: 0,
maxY: yMax, maxY: yMax > 0 ? yMax : 10, // Đảm bảo có giá trị tối thiểu
barGroups: barGroups, barGroups: barGroups,
gridData: FlGridData( gridData: FlGridData(
show: true, show: true,
drawVerticalLine: false, drawVerticalLine: false,
horizontalInterval: yStep, horizontalInterval: yStep > 0 ? yStep : 2,
getDrawingHorizontalLine: (v) => FlLine(color: Colors.black12, strokeWidth: 1), getDrawingHorizontalLine: (v) => FlLine(color: Colors.black12, strokeWidth: 1),
), ),
extraLinesData: ExtraLinesData( extraLinesData: ExtraLinesData(
extraLinesOnTop: true, extraLinesOnTop: true,
horizontalLines: [ horizontalLines: [
HorizontalLine(y: 0, color: Colors.black12, strokeWidth: 1), HorizontalLine(y: 0, color: Colors.black12, strokeWidth: 1),
HorizontalLine(y: yMax, color: Colors.black12, strokeWidth: 1), HorizontalLine(y: yMax > 0 ? yMax : 10, color: Colors.black12, strokeWidth: 1),
], ],
), ),
titlesData: FlTitlesData( titlesData: FlTitlesData(
...@@ -100,14 +116,22 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -100,14 +116,22 @@ class MonthlyPointsChart extends StatelessWidget {
rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)), rightTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
leftTitles: AxisTitles( leftTitles: AxisTitles(
sideTitles: SideTitles( sideTitles: SideTitles(
reservedSize: 28, reservedSize: 40, // Tăng độ rộng để chứa text dài
showTitles: true, showTitles: true,
interval: yStep, interval: yStep > 0 ? yStep : 2,
getTitlesWidget: getTitlesWidget: (value, meta) {
(value, meta) => Text( final text = _formatYAxisLabel(value.toInt());
value.toInt().toString(), return SizedBox(
style: const TextStyle(fontSize: 10, color: Colors.black54), width: 35, // Cố định độ rộng
child: Text(
text,
style: const TextStyle(fontSize: 9, color: Colors.black54),
textAlign: TextAlign.right,
maxLines: 1,
overflow: TextOverflow.ellipsis,
), ),
);
},
), ),
), ),
bottomTitles: AxisTitles( bottomTitles: AxisTitles(
...@@ -143,7 +167,7 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -143,7 +167,7 @@ class MonthlyPointsChart extends StatelessWidget {
return BarTooltipItem( return BarTooltipItem(
textAlign: TextAlign.center, textAlign: TextAlign.center,
'Ngày $day/${date.month}\n' 'Ngày $day/${date.month}\n'
'Tích điểm: ${_formatInt(r)}', 'Tích điểm: ${r.money(CurrencyUnit.noneSpace)}',
const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500), const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500),
); );
}, },
...@@ -222,12 +246,31 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -222,12 +246,31 @@ class MonthlyPointsChart extends StatelessWidget {
} }
static String _formatInt(double v) => v.toStringAsFixed(0); static String _formatInt(double v) => v.toStringAsFixed(0);
/// Format Y-axis label để hiển thị gọn gàng
String _formatYAxisLabel(int value) {
if (value >= 1000000) {
return '${(value / 1000000).toStringAsFixed(1)}M';
} else if (value >= 1000) {
return '${(value / 1000).toStringAsFixed(0)}K';
} else {
return value.toString();
}
}
/// Làm tròn max Y cho đẹp (bước 4/5) /// Làm tròn max Y cho đẹp (bước 4/5)
double _niceMax(double maxVal) { double _niceMax(double maxVal) {
if (maxVal <= 0) return 10; if (maxVal <= 0) return 10;
// làm tròn lên tới bội số 4 hoặc 5 gần nhất
final candidates = [4, 5, 10]; // Xử lý giá trị lớn (> 1000)
if (maxVal > 1000) {
// Làm tròn lên đến bội số 1000 gần nhất
final up = ((maxVal / 1000).ceil()) * 1000;
return up.toDouble();
}
// Xử lý giá trị nhỏ (< 1000)
final candidates = [4, 5, 10, 20, 50, 100];
for (final step in candidates) { for (final step in candidates) {
final up = ((maxVal / step).ceil()) * step; final up = ((maxVal / step).ceil()) * step;
if (up >= maxVal && up / step <= 6) return up.toDouble(); // tối đa 6 vạch cho gọn if (up >= maxVal && up / step <= 6) return up.toDouble(); // tối đa 6 vạch cho gọn
...@@ -239,7 +282,16 @@ class MonthlyPointsChart extends StatelessWidget { ...@@ -239,7 +282,16 @@ class MonthlyPointsChart extends StatelessWidget {
if (yMax <= 10) return 2; // 0,2,4,6,8,10 if (yMax <= 10) return 2; // 0,2,4,6,8,10
if (yMax <= 20) return 4; // 0,4,8,12,16,20 if (yMax <= 20) return 4; // 0,4,8,12,16,20
if (yMax <= 50) return 10; if (yMax <= 50) return 10;
return 20; if (yMax <= 100) return 20;
if (yMax <= 500) return 50;
if (yMax <= 1000) return 100;
if (yMax <= 5000) return 500;
if (yMax <= 10000) return 1000;
if (yMax <= 50000) return 5000;
if (yMax <= 100000) return 10000;
if (yMax <= 500000) return 50000;
if (yMax <= 1000000) return 100000;
return 200000; // cho giá trị rất lớn
} }
Map<int, _DayStat> _statsByDay(List<DaySummaryChartModel> list, DateTime month) { Map<int, _DayStat> _statsByDay(List<DaySummaryChartModel> list, DateTime month) {
......
...@@ -202,7 +202,7 @@ class _HistoryPointScreenState extends State<HistoryPointScreen> { ...@@ -202,7 +202,7 @@ class _HistoryPointScreenState extends State<HistoryPointScreen> {
final adjustTotal = item.adjustTotal?.toInt() ?? 0; final adjustTotal = item.adjustTotal?.toInt() ?? 0;
final value = rewardTotal - redeemTotal + adjustTotal; final value = rewardTotal - redeemTotal + adjustTotal;
final valueColor = value >= 0 ? const Color(0xFF21C777) : const Color(0xFFFE515A); final valueColor = value >= 0 ? const Color(0xFF21C777) : const Color(0xFFFE515A);
final valueText = '${value > 0 ? '+' : (value < 0 ? '-' : '')}${value.toInt()}'; final valueText = '${value > 0 ? '+' : (value < 0 ? '-' : '')}${value.money(CurrencyUnit.noneSpace)}';
final dateText = item.transactionDatetime?.toDate()?.toFormattedString(format: DateFormat.viFull); final dateText = item.transactionDatetime?.toDate()?.toFormattedString(format: DateFormat.viFull);
final transactionId = item.transactionSequenceId.orIfBlank(''); final transactionId = item.transactionSequenceId.orIfBlank('');
return InkWell( return InkWell(
......
...@@ -40,7 +40,7 @@ class HistoryPointViewModel extends RestfulApiViewModel { ...@@ -40,7 +40,7 @@ class HistoryPointViewModel extends RestfulApiViewModel {
onSuccess: (data, _) { onSuccess: (data, _) {
transactionSummary.value = data; transactionSummary.value = data;
}, },
onFailure: (msg, _, __) async { onFailure: (msg, _, _) async {
transactionSummary.value = null; transactionSummary.value = null;
}, },
); );
...@@ -62,7 +62,7 @@ class HistoryPointViewModel extends RestfulApiViewModel { ...@@ -62,7 +62,7 @@ class HistoryPointViewModel extends RestfulApiViewModel {
onSuccess: (data, _) { onSuccess: (data, _) {
historyPoint.value = data; historyPoint.value = data;
}, },
onFailure: (msg, _, __) async { onFailure: (msg, _, _) async {
historyPoint.value = null; historyPoint.value = null;
}, },
); );
......
import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/extensions/collection_extension.dart'; import 'package:mypoint_flutter_app/extensions/collection_extension.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../networking/restful_api_viewmodel.dart';
import 'models/history_point_cashback_model.dart'; import 'models/history_point_cashback_model.dart';
class HistoryPointCashBackViewModel extends RestfulApiViewModel { class HistoryPointCashBackViewModel extends RestfulApiViewModel {
late List<CashBackPointOrderStatus> tagStatus; late List<CashBackPointOrderStatus> tagStatus;
CashBackPointOrderStatus get selectedTag { CashBackPointOrderStatus get selectedTag => tagStatus.safe(selectedTabIndex.value) ?? CashBackPointOrderStatus.pending;
return tagStatus.safe(selectedTabIndex.value) ?? CashBackPointOrderStatus.pending;
}
final RxInt selectedTabIndex = 0.obs; final RxInt selectedTabIndex = 0.obs;
var pointCashBackData = Rxn<HistoryPointCashBackResponse>(); final Rxn<HistoryPointCashBackResponse> pointCashBackData = Rxn<HistoryPointCashBackResponse>();
List<HistoryPointCashBackOrderModel> get orders { List<HistoryPointCashBackOrderModel> get orders => pointCashBackData.value?.orders ?? [];
return pointCashBackData.value?.orders ?? [];
}
int _page = 1; int _page = 1;
...@@ -31,28 +26,23 @@ class HistoryPointCashBackViewModel extends RestfulApiViewModel { ...@@ -31,28 +26,23 @@ class HistoryPointCashBackViewModel extends RestfulApiViewModel {
freshData(isRefresh: true); freshData(isRefresh: true);
} }
void freshData({bool isRefresh = false}) { Future<void> freshData({bool isRefresh = false}) async {
if (isRefresh) { _page = isRefresh ? 1 : _page + 1;
_page = 1;
} else {
_page += 1;
}
final body = {"page": _page, "size": 20, "type": selectedTag.rawValue}; final body = {"page": _page, "size": 20, "type": selectedTag.rawValue};
client await callApi<HistoryPointCashBackResponse>(
.historyPointCashBackRequest(body) request: () => client.historyPointCashBackRequest(body),
.then((response) { onSuccess: (data, _) {
final result = response.data; if (isRefresh) {
if (isRefresh) { pointCashBackData.value = data;
pointCashBackData.value = result; } else {
} else { final next = data.orders ?? [];
final orders = result?.orders ?? []; pointCashBackData.value?.orders?.addAll(next);
pointCashBackData.value?.orders?.addAll(orders); pointCashBackData.refresh();
pointCashBackData.refresh(); }
} },
}) onFailure: (_, _, _) async {},
.catchError((error) { withLoading: isRefresh,
print('Error fetching products: $error'); );
});
} }
void selectTab(int index) { void selectTab(int index) {
......
...@@ -20,7 +20,6 @@ class HomeGreetingHeader extends StatelessWidget { ...@@ -20,7 +20,6 @@ class HomeGreetingHeader extends StatelessWidget {
final heightSize = heightContent ?? (width * 86 / 375 + 112); final heightSize = heightContent ?? (width * 86 / 375 + 112);
final name = DataPreference.instance.displayName; final name = DataPreference.instance.displayName;
final level = DataPreference.instance.rankName ?? "Hạng Đồng"; final level = DataPreference.instance.rankName ?? "Hạng Đồng";
final double statusBarHeight = MediaQuery.of(context).padding.top;
final double heightWhiteBox = 112; final double heightWhiteBox = 112;
return Stack( return Stack(
...@@ -149,23 +148,23 @@ class HomeGreetingHeader extends StatelessWidget { ...@@ -149,23 +148,23 @@ class HomeGreetingHeader extends StatelessWidget {
); );
} }
_onSearchTap() { void _onSearchTap() {
Get.toNamed(vouchersScreen, arguments: {"enableSearch": true}); Get.toNamed(vouchersScreen, arguments: {"enableSearch": true});
} }
_onNotificationTap() { void _onNotificationTap() {
Get.toNamed(notificationScreen); Get.toNamed(notificationScreen);
} }
_onPointTap() { void _onPointTap() {
Get.toNamed(historyPointScreen); Get.toNamed(historyPointScreen);
} }
_onMyVoucherTap() { void _onMyVoucherTap() {
Get.toNamed(myVoucherListScreen); Get.toNamed(myVoucherListScreen);
} }
_onRankTap() { void _onRankTap() {
Get.toNamed(membershipScreen); Get.toNamed(membershipScreen);
} }
} }
...@@ -11,7 +11,7 @@ class HeaderThemeController extends GetxController { ...@@ -11,7 +11,7 @@ class HeaderThemeController extends GetxController {
class HeaderHomeViewModel extends RestfulApiViewModel { class HeaderHomeViewModel extends RestfulApiViewModel {
final Rx<HeaderHomeModel?> _headerHomeData = Rx<HeaderHomeModel?>(null); final Rx<HeaderHomeModel?> _headerHomeData = Rx<HeaderHomeModel?>(null);
var notificationUnreadData = Rxn<NotificationUnreadData>(); final Rxn<NotificationUnreadData> notificationUnreadData = Rxn<NotificationUnreadData>();
HeaderHomeModel get headerData { HeaderHomeModel get headerData {
return _headerHomeData.value ?? return _headerHomeData.value ??
...@@ -32,21 +32,23 @@ class HeaderHomeViewModel extends RestfulApiViewModel { ...@@ -32,21 +32,23 @@ class HeaderHomeViewModel extends RestfulApiViewModel {
} }
Future<void> _getDynamicHeaderHome() async { Future<void> _getDynamicHeaderHome() async {
try { await callApi<HeaderHomeModel>(
final result = await client.getDynamicHeaderHome(); request: () => client.getDynamicHeaderHome(),
_headerHomeData.value = result.data; onSuccess: (data, _) {
Get.find<HeaderThemeController>().setBackground(_headerHomeData.value?.background); _headerHomeData.value = data;
} catch (error) { Get.find<HeaderThemeController>().setBackground(_headerHomeData.value?.background);
print("Error fetching getDynamicHeaderHome: $error"); },
} withLoading: false,
);
} }
Future<void> _getNotificationUnread() async { Future<void> _getNotificationUnread() async {
try { await callApi<NotificationUnreadData>(
final result = await client.getNotificationUnread(); request: () => client.getNotificationUnread(),
notificationUnreadData.value = result.data; onSuccess: (data, _) {
} catch (error) { notificationUnreadData.value = data;
print("Error fetching hot products: $error"); },
} withLoading: false,
);
} }
} }
...@@ -6,7 +6,6 @@ import 'package:mypoint_flutter_app/screen/pipi/pipi_detail_screen.dart'; ...@@ -6,7 +6,6 @@ import 'package:mypoint_flutter_app/screen/pipi/pipi_detail_screen.dart';
import 'package:mypoint_flutter_app/screen/voucher/models/product_model.dart'; import 'package:mypoint_flutter_app/screen/voucher/models/product_model.dart';
import 'package:mypoint_flutter_app/shared/router_gage.dart'; import 'package:mypoint_flutter_app/shared/router_gage.dart';
import '../../directional/directional_action_type.dart'; import '../../directional/directional_action_type.dart';
import '../../directional/directional_screen.dart';
import '../popup_manager/popup_runner_helper.dart'; import '../popup_manager/popup_runner_helper.dart';
import 'custom_widget/achievement_carousel_widget.dart'; import 'custom_widget/achievement_carousel_widget.dart';
import 'custom_widget/affiliate_brand_grid_widget.dart'; import 'custom_widget/affiliate_brand_grid_widget.dart';
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment