Commit 6b980613 authored by DatHV's avatar DatHV
Browse files

update project structure

parent bfff9e47
import 'dart:core'; import 'dart:core';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/extensions/num_extension.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/num_extension.dart';
import '../../base/base_screen.dart'; import '../../shared/widgets/base_view/base_screen.dart';
import '../../base/basic_state.dart'; import '../../shared/widgets/base_view/basic_state.dart';
import '../../resources/base_color.dart'; import '../../core/theme/base_color.dart';
import '../../widgets/custom_navigation_bar.dart'; import '../../shared/widgets/custom_navigation_bar.dart';
import '../../widgets/image_loader.dart'; import '../../shared/widgets/image_loader.dart';
import '../voucher/models/product_model.dart'; import '../voucher/models/product_model.dart';
import 'model/payment_bank_account_info_model.dart'; import 'model/payment_bank_account_info_model.dart';
import 'model/payment_method_model.dart'; import 'model/payment_method_model.dart';
...@@ -163,10 +163,10 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w ...@@ -163,10 +163,10 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w
children: [ children: [
Center(child: Image.asset('assets/images/ic_point.png', width: 30, height: 30)), Center(child: Image.asset('assets/images/ic_point.png', width: 30, height: 30)),
const SizedBox(width: 12), const SizedBox(width: 12),
Text(pointData!.textDisplay ?? '', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)), Text(pointData.textDisplay ?? '', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
], ],
), ),
if (pointData!.isEnableUsePoint) if (pointData.isEnableUsePoint)
Switch( Switch(
activeColor: Colors.white, activeColor: Colors.white,
activeTrackColor: Colors.green, activeTrackColor: Colors.green,
...@@ -177,7 +177,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w ...@@ -177,7 +177,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w
setState(() { setState(() {
_viewModel.usePoints.value = value; _viewModel.usePoints.value = value;
final total = _viewModel.previewData.value?.totalPrice ?? 0; final total = _viewModel.previewData.value?.totalPrice ?? 0;
final point = pointData!.point ?? 0; final point = pointData.point ?? 0;
shouldDisablePaymentMethods = value && (total - point <= 0); shouldDisablePaymentMethods = value && (total - point <= 0);
if (!value && _viewModel.selectedPaymentMethodIndex < 0) { if (!value && _viewModel.selectedPaymentMethodIndex < 0) {
if (_viewModel.paymentBankAccounts.value.isNotEmpty) { if (_viewModel.paymentBankAccounts.value.isNotEmpty) {
...@@ -401,7 +401,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w ...@@ -401,7 +401,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w
method.logo!, method.logo!,
width: 24, width: 24,
height: 24, height: 24,
errorBuilder: (_, __, ___) => const Icon(Icons.payment), errorBuilder: (_, _, _) => const Icon(Icons.payment),
), ),
), ),
Text(method.name ?? '', style: const TextStyle(fontSize: 16)), Text(method.name ?? '', style: const TextStyle(fontSize: 16)),
......
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/api/product_api.dart' deferred as product_api; import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import 'package:mypoint_flutter_app/shared/router_gage.dart'; import 'package:mypoint_flutter_app/shared/router_gage.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import '../../base/base_response_model.dart'; import '../../shared/widgets/base_view/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../core/network/restful_api_viewmodel.dart';
import '../../configs/constants.dart'; import '../../app/config/constants.dart';
import '../../preference/contact_storage_service.dart'; import '../../core/services/contact_storage_service.dart';
import '../../preference/data_preference.dart'; import '../../shared/preferences/data_preference.dart';
import '../voucher/models/product_model.dart'; import '../voucher/models/product_model.dart';
import '../webview/payment_web_view_screen.dart'; import '../webview/payment_web_view_screen.dart';
import 'model/payment_bank_account_info_model.dart'; import 'model/payment_bank_account_info_model.dart';
...@@ -19,7 +19,6 @@ class TransactionDetailViewModel extends RestfulApiViewModel { ...@@ -19,7 +19,6 @@ class TransactionDetailViewModel extends RestfulApiViewModel {
var previewData = Rxn<PreviewOrderPaymentModel>(); var previewData = Rxn<PreviewOrderPaymentModel>();
var paymentMethods = RxList<PaymentMethodModel>(); var paymentMethods = RxList<PaymentMethodModel>();
var paymentBankAccounts = RxList<PaymentBankAccountInfoModel>(); var paymentBankAccounts = RxList<PaymentBankAccountInfoModel>();
final RxBool isLoading = false.obs;
final ProductModel product; final ProductModel product;
String? metaData; String? metaData;
final int quantity; final int quantity;
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:month_picker_dialog/month_picker_dialog.dart'; import 'package:month_picker_dialog/month_picker_dialog.dart';
import 'package:mypoint_flutter_app/extensions/datetime_extensions.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/datetime_extensions.dart';
import 'package:mypoint_flutter_app/screen/transaction/transactions_history_viewmodel.dart'; import 'package:mypoint_flutter_app/features/transaction/transactions_history_viewmodel.dart';
import 'package:mypoint_flutter_app/widgets/custom_empty_widget.dart'; import 'package:mypoint_flutter_app/shared/widgets/custom_empty_widget.dart';
import 'package:mypoint_flutter_app/widgets/image_loader.dart'; import 'package:mypoint_flutter_app/shared/widgets/image_loader.dart';
import '../../resources/base_color.dart'; import '../../core/theme/base_color.dart';
import '../../shared/router_gage.dart'; import '../../shared/router_gage.dart';
import '../../widgets/custom_navigation_bar.dart'; import '../../shared/widgets/custom_navigation_bar.dart';
import 'history/transaction_history_model.dart'; import 'history/transaction_history_model.dart';
import 'history/transaction_history_response_model.dart'; import 'history/transaction_history_response_model.dart';
...@@ -33,7 +33,12 @@ class _TransactionHistoryScreenState extends State<TransactionHistoryScreen> { ...@@ -33,7 +33,12 @@ class _TransactionHistoryScreenState extends State<TransactionHistoryScreen> {
_buildCategoryTabs(), _buildCategoryTabs(),
_buildSummaryBox(summary), _buildSummaryBox(summary),
const SizedBox(height: 8), const SizedBox(height: 8),
if (items.isEmpty) Expanded(child: Center(child: EmptyWidget(size: Size(160, 160)))), if (items.isEmpty)
Expanded(
child: Center(
child: EmptyWidget(isLoading: _viewModel.isLoading.value),
),
),
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
...@@ -64,7 +69,7 @@ class _TransactionHistoryScreenState extends State<TransactionHistoryScreen> { ...@@ -64,7 +69,7 @@ class _TransactionHistoryScreenState extends State<TransactionHistoryScreen> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: _viewModel.categories.value.length, itemCount: _viewModel.categories.value.length,
separatorBuilder: (_, __) => const SizedBox(width: 8), separatorBuilder: (_, _) => const SizedBox(width: 8),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final category = _viewModel.categories.value[index]; final category = _viewModel.categories.value[index];
final isSelected = category.code == _viewModel.categorySelected?.code; final isSelected = category.code == _viewModel.categorySelected?.code;
......
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/datetime_extensions.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/datetime_extensions.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'; import 'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../core/network/restful_api_viewmodel.dart';
import 'history/transaction_category_model.dart'; import 'history/transaction_category_model.dart';
import 'history/transaction_history_response_model.dart'; import 'history/transaction_history_response_model.dart';
...@@ -11,7 +11,6 @@ class TransactionsHistoryViewModel extends RestfulApiViewModel { ...@@ -11,7 +11,6 @@ class TransactionsHistoryViewModel extends RestfulApiViewModel {
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
TransactionCategoryModel? categorySelected; TransactionCategoryModel? categorySelected;
DateTime date = DateTime.now(); DateTime date = DateTime.now();
bool _isLoading = false;
@override @override
onInit() { onInit() {
...@@ -20,39 +19,36 @@ class TransactionsHistoryViewModel extends RestfulApiViewModel { ...@@ -20,39 +19,36 @@ class TransactionsHistoryViewModel extends RestfulApiViewModel {
} }
Future<void> _getCategories() async { Future<void> _getCategories() async {
showLoading(); await callApi<List<TransactionCategoryModel>>(
try { request: () => client.getTransactionHistoryCategories(),
final response = await client.getTransactionHistoryCategories(); onSuccess: (data, _) {
categories.value = response.data ?? []; categories.value = data;
categorySelected = categories.isNotEmpty ? categories.first : null; categorySelected = categories.isNotEmpty ? categories.first : null;
hideLoading(); },
getTransactionHistoryResponse(); onFailure: (message, _, _) {
} catch (error) { onShowAlertError?.call(message);
hideLoading(); },
onShowAlertError?.call("Error fetching product detail: $error"); onComplete: () {
} getTransactionHistoryResponse();
},
);
} }
Future<void> getTransactionHistoryResponse() async { Future<void> getTransactionHistoryResponse() async {
if (_isLoading) return;
final body = { final body = {
'category_code': categorySelected?.code ?? '', 'category_code': categorySelected?.code ?? '',
'date': date.toFormattedString(format: 'yyyy-MM'), 'date': date.toFormattedString(format: 'yyyy-MM'),
'limit': 10000, 'limit': 10000,
'offset':0, 'offset':0,
}; };
_isLoading = true; await callApi<TransactionHistoryResponse>(
showLoading(); request: () => client.getTransactionHistoryResponse(body),
try { onSuccess: (data, _) {
final response = await client.getTransactionHistoryResponse(body); historyResponse.value = data;
final data = response.data; },
historyResponse.value = data; onFailure: (message, _, _) {
_isLoading = false; onShowAlertError?.call(message);
hideLoading(); },
} catch (error) { );
_isLoading = false;
hideLoading();
onShowAlertError?.call("Error fetching product detail: $error");
}
} }
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart'; import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
import 'package:mypoint_flutter_app/shared/direction_google_map.dart'; import 'package:mypoint_flutter_app/shared/direction_google_map.dart';
import '../models/product_store_model.dart'; import '../models/product_store_model.dart';
class StoreListSection extends StatefulWidget { class StoreListSection extends StatefulWidget {
...@@ -64,7 +63,7 @@ class _StoreListSectionState extends State<StoreListSection> { ...@@ -64,7 +63,7 @@ class _StoreListSectionState extends State<StoreListSection> {
}); });
} }
_onTapStore(ProductStoreModel store) { void _onTapStore(ProductStoreModel store) {
showGoogleMap(lat: store.latitude, lng: store.longitude); showGoogleMap(lat: store.latitude, lng: store.longitude);
} }
...@@ -82,7 +81,7 @@ class _StoreListSectionState extends State<StoreListSection> { ...@@ -82,7 +81,7 @@ class _StoreListSectionState extends State<StoreListSection> {
width: 20, width: 20,
height: 20, height: 20,
fit: BoxFit.cover, fit: BoxFit.cover,
errorBuilder: (_, __, ___) => Image.asset('assets/images/ic_logo.png', width: 20, height: 20), errorBuilder: (_, _, _) => Image.asset('assets/images/ic_logo.png', width: 20, height: 20),
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
......
import 'dart:math'; import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart'; import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:mypoint_flutter_app/extensions/num_extension.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/num_extension.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/screen/voucher/detail/store_list_section.dart'; import 'package:mypoint_flutter_app/features/voucher/detail/store_list_section.dart';
import 'package:mypoint_flutter_app/screen/voucher/models/product_type.dart'; import 'package:mypoint_flutter_app/features/voucher/models/product_type.dart';
import 'package:mypoint_flutter_app/screen/voucher/voucher_code_card_screen.dart'; import 'package:mypoint_flutter_app/features/voucher/voucher_code_card_screen.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../base/base_screen.dart'; import '../../../shared/widgets/base_view/base_screen.dart';
import '../../../base/basic_state.dart'; import '../../../shared/widgets/base_view/basic_state.dart';
import '../../../preference/point/point_manager.dart'; import '../../../shared/preferences/point/point_manager.dart';
import '../../../resources/base_color.dart'; import '../../../core/theme/base_color.dart';
import '../../../shared/router_gage.dart'; import '../../../shared/router_gage.dart';
import '../../../widgets/alert/data_alert_model.dart'; import '../../../shared/widgets/alert/data_alert_model.dart';
import '../../../widgets/back_button.dart'; import '../../../shared/widgets/back_button.dart';
import '../../../widgets/custom_empty_widget.dart'; import '../../../shared/widgets/custom_empty_widget.dart';
import '../../../widgets/custom_point_text_tag.dart'; import '../../../shared/widgets/custom_point_text_tag.dart';
import '../../../widgets/dashed_line.dart'; import '../../../shared/widgets/dashed_line.dart';
import '../../../widgets/image_loader.dart'; import '../../../shared/widgets/image_loader.dart';
import '../../../widgets/measure_size.dart'; import '../../../shared/widgets/measure_size.dart';
import '../models/cash_type.dart'; import '../models/cash_type.dart';
import '../models/my_product_status_type.dart'; import '../models/my_product_status_type.dart';
import '../models/product_model.dart'; import '../models/product_model.dart';
...@@ -71,14 +70,11 @@ class _VoucherDetailScreenState extends BaseState<VoucherDetailScreen> with Basi ...@@ -71,14 +70,11 @@ class _VoucherDetailScreenState extends BaseState<VoucherDetailScreen> with Basi
return Scaffold( return Scaffold(
backgroundColor: Colors.grey.shade100, backgroundColor: Colors.grey.shade100,
body: Obx(() { body: Obx(() {
if (_viewModel.isLoading.value) {
return const Center(child: CircularProgressIndicator());
}
final product = _viewModel.product.value; final product = _viewModel.product.value;
if (product == null) { if (product == null) {
return Stack( return Stack(
children: [ children: [
const Center(child: EmptyWidget()), Center(child: EmptyWidget(isLoading: _viewModel.isLoading.value)),
SafeArea(child: Padding(padding: const EdgeInsets.all(8), child: CustomBackButton())), SafeArea(child: Padding(padding: const EdgeInsets.all(8), child: CustomBackButton())),
], ],
); );
...@@ -259,7 +255,7 @@ class _VoucherDetailScreenState extends BaseState<VoucherDetailScreen> with Basi ...@@ -259,7 +255,7 @@ class _VoucherDetailScreenState extends BaseState<VoucherDetailScreen> with Basi
} }
Widget _buildExpireAndStock(ProductModel product) { Widget _buildExpireAndStock(ProductModel product) {
final bool isOutOfStock = !(product.inStock ?? true); final bool isOutOfStock = !(product.inStock);
final bool hasExpire = product.expire.isNotEmpty; final bool hasExpire = product.expire.isNotEmpty;
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
...@@ -381,7 +377,7 @@ class _VoucherDetailScreenState extends BaseState<VoucherDetailScreen> with Basi ...@@ -381,7 +377,7 @@ class _VoucherDetailScreenState extends BaseState<VoucherDetailScreen> with Basi
} }
Widget _buildBottomAction(ProductModel product) { Widget _buildBottomAction(ProductModel product) {
final bool isOutOfStock = !(product.inStock ?? true); final bool isOutOfStock = !(product.inStock);
if (product.isMyProduct && product.customerInfoModel?.status != MyProductStatusType.waiting) { if (product.isMyProduct && product.customerInfoModel?.status != MyProductStatusType.waiting) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
......
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/api/product_api.dart' deferred as product_api; import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import '../../../base/base_response_model.dart'; import '../../../shared/widgets/base_view/base_response_model.dart';
import '../../../networking/restful_api_viewmodel.dart'; import '../../../core/network/restful_api_viewmodel.dart';
import '../../../configs/constants.dart'; import '../../../app/config/constants.dart';
import '../../../shared/router_gage.dart'; import '../../../shared/router_gage.dart';
import '../../transaction/model/order_product_payment_response_model.dart';
import '../models/product_model.dart'; import '../models/product_model.dart';
import '../models/product_store_model.dart'; import '../models/product_store_model.dart';
...@@ -19,7 +20,6 @@ class VoucherDetailViewModel extends RestfulApiViewModel { ...@@ -19,7 +20,6 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
var stores = RxList<ProductStoreModel>(); var stores = RxList<ProductStoreModel>();
var product = Rxn<ProductModel>(); var product = Rxn<ProductModel>();
var isLoading = false.obs;
var liked = false.obs; var liked = false.obs;
void Function(String message)? onShowAlertError; void Function(String message)? onShowAlertError;
var quantity = 1.obs; var quantity = 1.obs;
...@@ -51,13 +51,13 @@ class VoucherDetailViewModel extends RestfulApiViewModel { ...@@ -51,13 +51,13 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
final value = product.value; final value = product.value;
if (value == null) return; if (value == null) return;
try { try {
if (value!.liked == true) { if (value.liked == true) {
await _callProductApi((api) => api.unlikeProduct(value?.likeId ?? 0)); await _callProductApi((api) => api.unlikeProduct(value.likeId ?? 0));
value?.likeId = 0; value.likeId = 0;
liked.value = false; liked.value = false;
} else { } else {
final response = await _callProductApi((api) => api.likeProduct(_id!)); final response = await _callProductApi((api) => api.likeProduct(_id!));
value?.likeId = response.data?.id; value.likeId = response.data?.id;
liked.value = (response.data?.id ?? 0) != 0; liked.value = (response.data?.id ?? 0) != 0;
} }
} catch (error) { } catch (error) {
...@@ -66,35 +66,33 @@ class VoucherDetailViewModel extends RestfulApiViewModel { ...@@ -66,35 +66,33 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
} }
Future<void> _getProductDetail() async { Future<void> _getProductDetail() async {
if (isLoading.value) return; await callApi<ProductModel>(
try { request: () =>
isLoading.value = true; isMyProduct ?
final response = _callProductApi((api) => api.getCustomerProductDetail(customerProductId ?? 0)) :
isMyProduct _callProductApi((api) => api.getProduct(productId ?? 0)),
? await _callProductApi((api) => api.getCustomerProductDetail(customerProductId ?? 0)) onSuccess: (data, _) {
: await _callProductApi((api) => api.getProduct(productId ?? 0)); product.value = data;
product.value = response.data; liked.value = product.value?.liked == true;
liked.value = product.value?.liked == true; },
} catch (error) { onFailure: (message, _, _) {
onShowAlertError?.call("Error fetching product detail: $error"); onShowAlertError?.call(message);
} finally { },
isLoading.value = false; );
if (isMyProduct) {
_getProductStores();
}
}
} }
Future<void> _getProductStores() async { Future<void> _getProductStores() async {
if (_id == null) return; if (_id == null) return;
try { await callApi<List<ProductStoreModel>>(
final response = await _callProductApi((api) => api.getProductStores(_id!)); request: () => _callProductApi((api) => api.getProductStores(_id!)),
stores.value = response.data ?? []; onSuccess: (data, _) {
stores.refresh(); stores.value = data;
} catch (error) { },
onShowAlertError?.call("Error product stores: $error"); onFailure: (message, _, _) {
debugPrint("Error product stores: $error"); onShowAlertError?.call(message);
} finally {} },
withLoading: false,
);
} }
Future<void> verifyOrderProduct(Function verified) async { Future<void> verifyOrderProduct(Function verified) async {
...@@ -122,29 +120,32 @@ class VoucherDetailViewModel extends RestfulApiViewModel { ...@@ -122,29 +120,32 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
} }
Future<void> redeemProduct() async { Future<void> redeemProduct() async {
showLoading();
final requestId = Uuid().v4(); final requestId = Uuid().v4();
try { await callApi<OrderProductPaymentResponseModel>(
final response = await _callProductApi( request: () =>
(api) => api.orderSubmitPayment( _callProductApi(
products: [product.value!], (api) =>
quantity: 1, api.orderSubmitPayment(
requestId: requestId, products: [product.value!],
point: product.value?.amountToBePaid ?? 0, quantity: 1,
), requestId: requestId,
); point: product.value?.amountToBePaid ?? 0,
if (response.isSuccess && (response.data?.id ?? "").isNotEmpty) { ),
Get.offNamed( ),
transactionHistoryDetailScreen, onSuccess: (data, _) {
arguments: {"orderId": response.data?.id ?? "", "canBack": false}, final id = data.id.orEmpty;
); if (id.isNotEmpty) {
} else { Get.offNamed(
onShowAlertError?.call(response.errorMessage ?? Constants.commonError); transactionHistoryDetailScreen,
} arguments: {"orderId": id, "canBack": false},
} catch (error) { );
onShowAlertError?.call(Constants.commonError); } else {
} finally { onShowAlertError?.call(Constants.commonError);
hideLoading(); }
} },
onFailure: (message, _, _) {
onShowAlertError?.call(message);
},
);
} }
} }
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../shared/widgets/custom_toast_message.dart';
import '../../../widgets/custom_toast_message.dart';
class RechargeSheet extends StatelessWidget { class RechargeSheet extends StatelessWidget {
final String code; final String code;
......
import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
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/num_extension.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/num_extension.dart';
import 'package:mypoint_flutter_app/networking/api/product_api.dart' deferred as product_api; import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import '../../../configs/constants.dart'; import '../../../app/config/constants.dart';
import '../../../networking/restful_api_viewmodel.dart'; import '../../../core/network/restful_api_viewmodel.dart';
import '../../mobile_card/models/usable_voucher_model.dart'; import '../../mobile_card/models/usable_voucher_model.dart';
import '../../../base/base_response_model.dart'; import '../../../shared/widgets/base_view/base_response_model.dart';
class MyMobileCardDetailViewModel extends RestfulApiViewModel { class MyMobileCardDetailViewModel extends RestfulApiViewModel {
String itemId; String itemId;
......
...@@ -2,11 +2,11 @@ import 'package:auto_size_text/auto_size_text.dart'; ...@@ -2,11 +2,11 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:mypoint_flutter_app/widgets/custom_toast_message.dart'; import 'package:mypoint_flutter_app/shared/widgets/custom_toast_message.dart';
import 'package:mypoint_flutter_app/widgets/image_loader.dart'; import 'package:mypoint_flutter_app/shared/widgets/image_loader.dart';
import '../../../resources/base_color.dart'; import '../../../core/theme/base_color.dart';
import '../../../widgets/bottom_sheet_helper.dart'; import '../../../shared/widgets/bottom_sheet_helper.dart';
import '../../../widgets/custom_navigation_bar.dart'; import '../../../shared/widgets/custom_navigation_bar.dart';
import 'card_recharge_sheet.dart'; import 'card_recharge_sheet.dart';
import 'my_mobile_card_detail_viewmodel.dart'; import 'my_mobile_card_detail_viewmodel.dart';
......
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/configs/constants.dart'; import 'package:mypoint_flutter_app/app/config/constants.dart';
import 'package:mypoint_flutter_app/networking/api/product_api.dart' deferred as product_api; import 'package:mypoint_flutter_app/core/network/api/product_api.dart' deferred as product_api;
import '../../../networking/restful_api_viewmodel.dart'; import '../../../core/network/restful_api_viewmodel.dart';
import '../../mobile_card/models/usable_voucher_model.dart'; import '../../mobile_card/models/usable_voucher_model.dart';
import '../models/my_product_status_type.dart'; import '../models/my_product_status_type.dart';
import '../../../base/base_response_model.dart'; import '../../../shared/widgets/base_view/base_response_model.dart';
class MyMobileCardListViewModel extends RestfulApiViewModel { class MyMobileCardListViewModel extends RestfulApiViewModel {
final RxInt selectedTabIndex = 0.obs; final RxInt selectedTabIndex = 0.obs;
...@@ -37,6 +37,7 @@ class MyMobileCardListViewModel extends RestfulApiViewModel { ...@@ -37,6 +37,7 @@ class MyMobileCardListViewModel extends RestfulApiViewModel {
} }
Future<void> freshData({bool isRefresh = false}) async { Future<void> freshData({bool isRefresh = false}) async {
isLoading.value = true;
if (isRefresh) { if (isRefresh) {
showLoading(); showLoading();
} }
...@@ -64,6 +65,7 @@ class MyMobileCardListViewModel extends RestfulApiViewModel { ...@@ -64,6 +65,7 @@ class MyMobileCardListViewModel extends RestfulApiViewModel {
if (isRefresh) { if (isRefresh) {
hideLoading(); hideLoading();
} }
isLoading.value = false;
} }
} }
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../../base/base_screen.dart'; import '../../../shared/widgets/base_view/base_screen.dart';
import '../../../base/basic_state.dart'; import '../../../shared/widgets/base_view/basic_state.dart';
import '../../../shared/router_gage.dart'; import '../../../shared/router_gage.dart';
import '../../../widgets/custom_empty_widget.dart'; import '../../../shared/widgets/custom_empty_widget.dart';
import '../../../widgets/custom_navigation_bar.dart'; import '../../../shared/widgets/custom_navigation_bar.dart';
import '../../../widgets/image_loader.dart'; import '../../../shared/widgets/image_loader.dart';
import '../../mobile_card/models/usable_voucher_model.dart'; import '../../mobile_card/models/usable_voucher_model.dart';
import '../../mobile_card/usable_mobile_card_popup.dart'; import '../../mobile_card/usable_mobile_card_popup.dart';
import 'my_mobile_card_list_viewmodel.dart'; import 'my_mobile_card_list_viewmodel.dart';
...@@ -36,7 +36,6 @@ class _MyMobileCardListScreenState extends BaseState<MyMobileCardListScreen> wit ...@@ -36,7 +36,6 @@ class _MyMobileCardListScreenState extends BaseState<MyMobileCardListScreen> wit
@override @override
Widget createBody() { Widget createBody() {
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold( return Scaffold(
appBar: CustomNavigationBar(title: 'Thẻ nạp của tôi',), appBar: CustomNavigationBar(title: 'Thẻ nạp của tôi',),
body: Obx( body: Obx(
...@@ -52,7 +51,9 @@ class _MyMobileCardListScreenState extends BaseState<MyMobileCardListScreen> wit ...@@ -52,7 +51,9 @@ class _MyMobileCardListScreenState extends BaseState<MyMobileCardListScreen> wit
), ),
const Divider(height: 1), const Divider(height: 1),
if (_viewModel.myCardModels.isEmpty) if (_viewModel.myCardModels.isEmpty)
Expanded(child: EmptyWidget(size: Size(screenWidth / 2, screenWidth / 2))) Expanded(
child: EmptyWidget(isLoading: _viewModel.isLoading.value),
)
else else
Expanded( Expanded(
child: RefreshIndicator( child: RefreshIndicator(
......
import '../../mobile_card/models/product_mobile_card_model.dart';
import '../../mobile_card/models/usable_voucher_model.dart'; import '../../mobile_card/models/usable_voucher_model.dart';
class MyVoucherResponse { class MyVoucherResponse {
......
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:mypoint_flutter_app/extensions/datetime_extensions.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/datetime_extensions.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart'; import 'package:mypoint_flutter_app/core/utils/extensions/string_extension.dart';
import '../../voucher/models/my_product_status_type.dart'; import 'my_product_status_type.dart';
class MyProductModel { class MyProductModel {
final int? id; final int? id;
......
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
part 'product_brand_model.g.dart'; part 'product_brand_model.g.dart';
@JsonSerializable() @JsonSerializable()
class ProductBrandModel { class ProductBrandModel {
final int? id; final int? id;
......
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