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

update project structure

parent bfff9e47
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
extension ColorExtension on Color { extension ColorExtension on Color {
......
import 'dart:convert'; import 'dart:convert';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl; import 'package:intl/intl.dart' as intl;
......
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/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 '../../widgets/custom_navigation_bar.dart'; import '../../shared/widgets/custom_navigation_bar.dart';
import '../home/models/achievement_model.dart'; import 'model/achievement_model.dart';
import 'achievement_viewmodel.dart'; import 'achievement_viewmodel.dart';
class AchievementListScreen extends StatefulWidget { class AchievementListScreen extends StatefulWidget {
...@@ -48,7 +48,7 @@ class _AchievementListScreenState extends State<AchievementListScreen> { ...@@ -48,7 +48,7 @@ class _AchievementListScreenState extends State<AchievementListScreen> {
Widget _buildAchievementContent() { Widget _buildAchievementContent() {
final items = _viewModel.achievements; final items = _viewModel.achievements;
if (items.isEmpty) { if (items.isEmpty) {
return EmptyWidget(); return EmptyWidget(isLoading: _viewModel.isLoading.value);
} }
return Padding( return Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
...@@ -82,7 +82,7 @@ class _AchievementListScreenState extends State<AchievementListScreen> { ...@@ -82,7 +82,7 @@ class _AchievementListScreenState extends State<AchievementListScreen> {
Widget _buildPointHuntingContent() { Widget _buildPointHuntingContent() {
final items = _viewModel.achievements; final items = _viewModel.achievements;
return items.isEmpty return items.isEmpty
? EmptyWidget() ? EmptyWidget(isLoading: _viewModel.isLoading.value)
: RefreshIndicator( : RefreshIndicator(
onRefresh: () => _viewModel.fetchAchievements(), onRefresh: () => _viewModel.fetchAchievements(),
child: CustomScrollView( child: CustomScrollView(
......
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/core/network/restful_api_client_all_request.dart';
import '../../networking/restful_api_viewmodel.dart'; import '../../core/network/restful_api_viewmodel.dart';
import '../../preference/data_preference.dart'; import '../../shared/preferences/data_preference.dart';
import '../home/models/achievement_model.dart'; import 'model/achievement_model.dart';
class AchievementViewModel extends RestfulApiViewModel { class AchievementViewModel extends RestfulApiViewModel {
final bool isPointHunting; final bool isPointHunting;
...@@ -28,9 +28,9 @@ class AchievementViewModel extends RestfulApiViewModel { ...@@ -28,9 +28,9 @@ class AchievementViewModel extends RestfulApiViewModel {
await callApi<AchievementListResponse>( await callApi<AchievementListResponse>(
request: () => client.getAchievementList(body), request: () => client.getAchievementList(body),
onSuccess: (data, _) { onSuccess: (data, _) {
achievements.assignAll(data?.achievements ?? []); achievements.assignAll(data.achievements ?? []);
}, },
onFailure: (msg, _, __) async { onFailure: (msg, _, _) async {
achievements.clear(); achievements.clear();
}, },
showAppNavigatorDialog: false, showAppNavigatorDialog: false,
......
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:mypoint_flutter_app/directional/directional_screen.dart'; import 'package:mypoint_flutter_app/shared/navigation/directional_screen.dart';
part 'achievement_model.g.dart'; part 'achievement_model.g.dart';
@JsonSerializable() @JsonSerializable()
......
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/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 'model/affiliate_brand_model.dart'; import 'model/affiliate_brand_model.dart';
...@@ -40,7 +40,7 @@ void showAffiliateBrandPopup(BuildContext context, List<AffiliateBrandModel> bra ...@@ -40,7 +40,7 @@ void showAffiliateBrandPopup(BuildContext context, List<AffiliateBrandModel> bra
shrinkWrap: true, shrinkWrap: true,
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
itemCount: brands.length, itemCount: brands.length,
separatorBuilder: (_, __) => const SizedBox(height: 4), separatorBuilder: (_, _) => const SizedBox(height: 4),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final brand = brands[index]; final brand = brands[index];
return GestureDetector( return GestureDetector(
...@@ -83,7 +83,7 @@ void showAffiliateBrandPopup(BuildContext context, List<AffiliateBrandModel> bra ...@@ -83,7 +83,7 @@ void showAffiliateBrandPopup(BuildContext context, List<AffiliateBrandModel> bra
style: const TextStyle(color: Colors.black54, fontSize: 13), style: const TextStyle(color: Colors.black54, fontSize: 13),
children: [ children: [
TextSpan( TextSpan(
text: brand.showCommision ?? '', text: brand.showCommision,
style: const TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold, fontSize: 14), style: const TextStyle(color: Colors.deepOrange, fontWeight: FontWeight.bold, fontSize: 14),
), ),
], ],
......
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/screen/affiliate/sub_widget/build_affiliate_brand.dart'; import 'package:mypoint_flutter_app/features/affiliate/sub_widget/build_affiliate_brand.dart';
import 'package:mypoint_flutter_app/screen/affiliate/sub_widget/build_affiliate_category.dart'; import 'package:mypoint_flutter_app/features/affiliate/sub_widget/build_affiliate_category.dart';
import 'package:mypoint_flutter_app/screen/affiliate/sub_widget/build_affiliate_product_topsale.dart'; import 'package:mypoint_flutter_app/features/affiliate/sub_widget/build_affiliate_product_topsale.dart';
import 'package:mypoint_flutter_app/widgets/back_button.dart'; import 'package:mypoint_flutter_app/shared/widgets/back_button.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 '../../directional/directional_action_type.dart'; import '../../app/routing/directional_action_type.dart';
import '../../resources/base_color.dart'; import '../../core/theme/base_color.dart';
import '../../shared/router_gage.dart'; import '../../shared/router_gage.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 '../home/header_home_viewmodel.dart'; import '../home/custom_widget/banner_carousel_widget.dart';
import '../popup_manager/popup_manager_screen.dart';
import '../popup_manager/popup_manager_viewmodel.dart';
import '../popup_manager/popup_runner_helper.dart'; import '../popup_manager/popup_runner_helper.dart';
import 'affiliate_overview.dart'; import 'affiliate_overview.dart';
import 'affiliate_popup_brands.dart'; import 'affiliate_popup_brands.dart';
...@@ -39,6 +37,7 @@ class _AffiliateTabScreenState extends BaseState<AffiliateTabScreen> with BasicS ...@@ -39,6 +37,7 @@ class _AffiliateTabScreenState extends BaseState<AffiliateTabScreen> with BasicS
_canBackButton = args['can_back_button'] as bool; _canBackButton = args['can_back_button'] as bool;
} }
viewModel.onShowAffiliateBrandPopup = (data) { viewModel.onShowAffiliateBrandPopup = (data) {
if (!mounted) return;
showAffiliateBrandPopup(context, data.$1, title: data.$2); showAffiliateBrandPopup(context, data.$1, title: data.$2);
}; };
runPopupCheck(DirectionalScreenName.pointBack); runPopupCheck(DirectionalScreenName.pointBack);
...@@ -117,13 +116,27 @@ class _AffiliateTabScreenState extends BaseState<AffiliateTabScreen> with BasicS ...@@ -117,13 +116,27 @@ class _AffiliateTabScreenState extends BaseState<AffiliateTabScreen> with BasicS
), ),
), ),
AffiliateBrand(brands: viewModel.affiliateBrands.value), AffiliateBrand(brands: viewModel.affiliateBrands.value),
AffiliateCategory(categories: viewModel.affiliateCategories.value, onTap: (category) { if (viewModel.banners.isNotEmpty)...[
if (category.code == AffiliateCategoryType.other) { const SizedBox(height: 16),
Get.toNamed(affiliateCategoryGridScreen, arguments: {"categories": viewModel.allAffiliateCategories}); BannerCarousel(
return; banners: viewModel.banners,
} sectionConfig: null,
viewModel.affiliateBrandGetListBuyCategory(category); onTap: (item) => item.directionalScreen?.begin(),
},), ),
],
AffiliateCategory(
categories: viewModel.affiliateCategories.value,
onTap: (category) {
if (category.code == AffiliateCategoryType.other) {
Get.toNamed(
affiliateCategoryGridScreen,
arguments: {"categories": viewModel.allAffiliateCategories},
);
return;
}
viewModel.affiliateBrandGetListBuyCategory(category);
},
),
AffiliateProductTopSale(products: viewModel.affiliateProducts.value), AffiliateProductTopSale(products: viewModel.affiliateProducts.value),
], ],
), ),
......
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/networking/api/affiliate_api.dart' deferred as affiliate_api; import 'package:mypoint_flutter_app/core/network/api/affiliate_api.dart' deferred as affiliate_api;
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 '../home/models/banner_model.dart';
import 'model/affiliate_brand_model.dart'; import 'model/affiliate_brand_model.dart';
import 'model/affiliate_category_model.dart'; import 'model/affiliate_category_model.dart';
import 'model/affiliate_category_type.dart'; import 'model/affiliate_category_type.dart';
...@@ -9,11 +10,11 @@ import 'model/affiliate_product_top_sale_model.dart'; ...@@ -9,11 +10,11 @@ import 'model/affiliate_product_top_sale_model.dart';
import 'model/cashback_overview_model.dart'; import 'model/cashback_overview_model.dart';
class AffiliateTabViewModel extends RestfulApiViewModel { class AffiliateTabViewModel extends RestfulApiViewModel {
final RxList<BannerModel> banners = <BannerModel>[].obs;
final RxList<AffiliateBrandModel> affiliateBrands = <AffiliateBrandModel>[].obs; final RxList<AffiliateBrandModel> affiliateBrands = <AffiliateBrandModel>[].obs;
final RxList<AffiliateCategoryModel> affiliateCategories = <AffiliateCategoryModel>[].obs; final RxList<AffiliateCategoryModel> affiliateCategories = <AffiliateCategoryModel>[].obs;
final RxList<AffiliateCategoryModel> allAffiliateCategories = <AffiliateCategoryModel>[].obs; final RxList<AffiliateCategoryModel> allAffiliateCategories = <AffiliateCategoryModel>[].obs;
final RxList<AffiliateProductTopSaleModel> affiliateProducts = <AffiliateProductTopSaleModel>[].obs; final RxList<AffiliateProductTopSaleModel> affiliateProducts = <AffiliateProductTopSaleModel>[].obs;
final RxBool isLoading = false.obs;
final Rxn<CashbackOverviewModel> overview = Rxn<CashbackOverviewModel>(); final Rxn<CashbackOverviewModel> overview = Rxn<CashbackOverviewModel>();
void Function((List<AffiliateBrandModel>, String) data)? onShowAffiliateBrandPopup; void Function((List<AffiliateBrandModel>, String) data)? onShowAffiliateBrandPopup;
...@@ -41,6 +42,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -41,6 +42,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
await Future.wait([ await Future.wait([
_getAffiliateOverview(), _getAffiliateOverview(),
_getAffiliateBrandGetList(), _getAffiliateBrandGetList(),
_getAffiliateBanners(),
_getAffiliateCategoryGetList(), _getAffiliateCategoryGetList(),
_getAffiliateProductTopSale(), _getAffiliateProductTopSale(),
]); ]);
...@@ -53,7 +55,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -53,7 +55,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
onSuccess: (data, _) { onSuccess: (data, _) {
affiliateBrands.assignAll(data); affiliateBrands.assignAll(data);
}, },
onFailure: (msg, _, __) async { onFailure: (msg, _, _) async {
affiliateBrands.clear(); affiliateBrands.clear();
}, },
withLoading: false, withLoading: false,
...@@ -93,13 +95,26 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -93,13 +95,26 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
); );
} }
Future<void> _getAffiliateBanners() async {
await callApi<List<BannerModel>>(
request: () => _callAffiliate((api) => api.affiliateGetBanners()),
onSuccess: (data, _) {
banners.assignAll(data);
},
onFailure: (msg, _, _) async {
banners.clear();
},
withLoading: false,
);
}
Future<void> _getAffiliateOverview() async { Future<void> _getAffiliateOverview() async {
await callApi<CashbackOverviewModel>( await callApi<CashbackOverviewModel>(
request: () => _callAffiliate((api) => api.getCashBackOverview()), request: () => _callAffiliate((api) => api.getCashBackOverview()),
onSuccess: (data, _) { onSuccess: (data, _) {
overview.value = data; overview.value = data;
}, },
onFailure: (msg, _, __) async { onFailure: (msg, _, _) async {
overview.value = null; overview.value = null;
}, },
withLoading: false, withLoading: false,
...@@ -114,7 +129,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel { ...@@ -114,7 +129,7 @@ class AffiliateTabViewModel extends RestfulApiViewModel {
), ),
onSuccess: (data, _) { onSuccess: (data, _) {
if (data.isNotEmpty) { if (data.isNotEmpty) {
onShowAffiliateBrandPopup?.call((data, category.name ?? '')); onShowAffiliateBrandPopup?.call((data, category.name));
} }
}, },
); );
......
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import '../../../configs/constants.dart'; import '../../../app/config/constants.dart';
import '../../../directional/directional_action_type.dart'; import '../../../app/routing/directional_action_type.dart';
import '../../../directional/directional_screen.dart'; import '../../../shared/navigation/directional_screen.dart';
part 'affiliate_brand_model.g.dart'; part 'affiliate_brand_model.g.dart';
@JsonSerializable() @JsonSerializable()
......
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