Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Hoàng Văn Đạt
mypoint_flutter_app
Commits
f714cdcc
Commit
f714cdcc
authored
Aug 28, 2025
by
DatHV
Browse files
update logic, flutter refactor
parent
cc202df4
Changes
35
Show whitespace changes
Inline
Side-by-side
lib/screen/personal/personal_edit_screen.dart
View file @
f714cdcc
...
@@ -4,14 +4,11 @@ import 'package:mypoint_flutter_app/preference/data_preference.dart';
...
@@ -4,14 +4,11 @@ import 'package:mypoint_flutter_app/preference/data_preference.dart';
import
'package:mypoint_flutter_app/screen/personal/personal_edit_item_model.dart'
;
import
'package:mypoint_flutter_app/screen/personal/personal_edit_item_model.dart'
;
import
'package:mypoint_flutter_app/screen/personal/personal_edit_viewmodel.dart'
;
import
'package:mypoint_flutter_app/screen/personal/personal_edit_viewmodel.dart'
;
import
'package:mypoint_flutter_app/screen/personal/personal_gender.dart'
;
import
'package:mypoint_flutter_app/screen/personal/personal_gender.dart'
;
import
'package:mypoint_flutter_app/widgets/custom_app_bar.dart'
;
import
'../../base/base_screen.dart'
;
import
'../../base/base_screen.dart'
;
import
'../../base/basic_state.dart'
;
import
'../../base/basic_state.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../shared/router_gage.dart'
;
import
'../../widgets/alert/data_alert_model.dart'
;
import
'../../widgets/alert/data_alert_model.dart'
;
import
'../../widgets/bottom_sheet_helper.dart'
;
import
'../../widgets/custom_navigation_bar.dart'
;
import
'../../widgets/time_picker_widget.dart'
;
class
PersonalEditScreen
extends
BaseScreen
{
class
PersonalEditScreen
extends
BaseScreen
{
const
PersonalEditScreen
({
super
.
key
});
const
PersonalEditScreen
({
super
.
key
});
...
@@ -52,7 +49,7 @@ class _PersonalEditScreenState extends BaseState<PersonalEditScreen> with BasicS
...
@@ -52,7 +49,7 @@ class _PersonalEditScreenState extends BaseState<PersonalEditScreen> with BasicS
onTap:
()
=>
FocusScope
.
of
(
context
).
unfocus
(),
onTap:
()
=>
FocusScope
.
of
(
context
).
unfocus
(),
behavior:
HitTestBehavior
.
translucent
,
behavior:
HitTestBehavior
.
translucent
,
child:
Scaffold
(
child:
Scaffold
(
appBar:
Custom
AppBar
.
back
(
title:
"Chỉnh sửa thông tin cá nhân"
),
appBar:
Custom
NavigationBar
(
title:
"Chỉnh sửa thông tin cá nhân"
),
body:
Obx
(()
{
body:
Obx
(()
{
List
<
PersonalEditItemModel
>
items
;
List
<
PersonalEditItemModel
>
items
;
final
editDataModel
=
viewModel
.
editDataModel
.
value
;
final
editDataModel
=
viewModel
.
editDataModel
.
value
;
...
...
lib/screen/personal/personal_screen.dart
View file @
f714cdcc
...
@@ -30,17 +30,6 @@ class _PersonalScreenState extends BaseState<PersonalScreen> with BasicState, Po
...
@@ -30,17 +30,6 @@ class _PersonalScreenState extends BaseState<PersonalScreen> with BasicState, Po
super
.
initState
();
super
.
initState
();
_loadAppInfo
();
_loadAppInfo
();
_headerHomeVM
.
freshData
();
_headerHomeVM
.
freshData
();
// WidgetsBinding.instance.addPostFrameCallback((_) async {
// if (!mounted) return;
// await PopupManagerViewModel.instance.ensureLoaded();
// final popup = PopupManagerViewModel.instance.getForScreen(DirectionalScreenName.personal.rawValue);
// final id = popup?.id ?? '';
// if (id.isEmpty || popup == null) return;
// await showPopupManagerScreen(
// context,
// modelPopup: popup,
// );
// });
runPopupCheck
(
DirectionalScreenName
.
personal
);
runPopupCheck
(
DirectionalScreenName
.
personal
);
}
}
...
...
lib/screen/point_history/point_history_screen.dart
0 → 100644
View file @
f714cdcc
import
'package:flutter/material.dart'
;
import
'../../widgets/custom_navigation_bar.dart'
;
class
PointHistoryScreen
extends
StatefulWidget
{
const
PointHistoryScreen
({
super
.
key
});
@override
State
<
PointHistoryScreen
>
createState
()
=>
_PointHistoryScreenState
();
}
class
_PointHistoryScreenState
extends
State
<
PointHistoryScreen
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
CustomNavigationBar
(
title:
"Lịch sử điểm"
),
body:
SafeArea
(
child:
Center
(
child:
Text
(
'Point History Screen'
)),
),
);
}
}
lib/screen/register_campaign/model/form_input_description_model.dart
View file @
f714cdcc
import
'package:json_annotation/json_annotation.dart'
;
import
'package:json_annotation/json_annotation.dart'
;
import
'package:mypoint_flutter_app/directional/directional_screen.dart'
;
part
'form_input_description_model.g.dart'
;
part
'form_input_description_model.g.dart'
;
@JsonSerializable
()
@JsonSerializable
()
...
@@ -10,6 +11,13 @@ class FormInputDescriptionModel {
...
@@ -10,6 +11,13 @@ class FormInputDescriptionModel {
@JsonKey
(
name:
'click_action_param'
)
@JsonKey
(
name:
'click_action_param'
)
final
String
?
clickActionParam
;
final
String
?
clickActionParam
;
DirectionalScreen
?
get
directional
{
return
DirectionalScreen
.
build
(
clickActionType:
clickActionType
,
clickActionParam:
clickActionParam
,
);
}
FormInputDescriptionModel
({
FormInputDescriptionModel
({
this
.
title
,
this
.
title
,
this
.
checkbox
,
this
.
checkbox
,
...
...
lib/screen/register_campaign/register_form_input_screen.dart
View file @
f714cdcc
...
@@ -4,7 +4,7 @@ import 'package:get/get.dart';
...
@@ -4,7 +4,7 @@ import 'package:get/get.dart';
import
'package:mypoint_flutter_app/screen/register_campaign/register_form_input_viewmodel.dart'
;
import
'package:mypoint_flutter_app/screen/register_campaign/register_form_input_viewmodel.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../shared/router_gage.dart'
;
import
'../../shared/router_gage.dart'
;
import
'../../widgets/custom_
app
_bar.dart'
;
import
'../../widgets/custom_
navigation
_bar.dart'
;
import
'../voucher/models/product_model.dart'
;
import
'../voucher/models/product_model.dart'
;
import
'input_form_cell.dart'
;
import
'input_form_cell.dart'
;
import
'model/registration_form_package_model.dart'
;
import
'model/registration_form_package_model.dart'
;
...
@@ -51,10 +51,11 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> {
...
@@ -51,10 +51,11 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> {
return
GestureDetector
(
return
GestureDetector
(
onTap:
()
=>
FocusScope
.
of
(
context
).
unfocus
(),
onTap:
()
=>
FocusScope
.
of
(
context
).
unfocus
(),
child:
Scaffold
(
child:
Scaffold
(
appBar:
Custom
AppBar
.
back
(
title:
_title
),
appBar:
Custom
NavigationBar
(
title:
_title
),
body:
Obx
(()
{
body:
Obx
(()
{
final
form
=
_isConfirmScreen
?
_viewModel
.
form
.
value
?.
formConfirm
:
_viewModel
.
form
.
value
?.
formRegistration
;
final
form
=
_isConfirmScreen
?
_viewModel
.
form
.
value
?.
formConfirm
:
_viewModel
.
form
.
value
?.
formRegistration
;
final
inputItem
=
_viewModel
.
form
.
value
?.
formRegistration
?.
inputRequired
;
final
inputItem
=
_viewModel
.
form
.
value
?.
formRegistration
?.
inputRequired
;
_validateForm
();
if
(
form
==
null
)
{
if
(
form
==
null
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
return
const
Center
(
child:
CircularProgressIndicator
());
}
}
...
@@ -101,7 +102,13 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> {
...
@@ -101,7 +102,13 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> {
},
},
),
),
),
),
Expanded
(
child:
HtmlWidget
(
form
!.
footerDescription
!.
title
!)),
Expanded
(
child:
GestureDetector
(
onTap:
()
{
form
.
footerDescription
?.
directional
?.
begin
();
},
child:
HtmlWidget
(
form
!.
footerDescription
!.
title
!)),
),
],
],
),
),
),
),
...
...
lib/screen/topup/topup_screen.dart
View file @
f714cdcc
...
@@ -4,6 +4,7 @@ import 'package:intl/intl.dart';
...
@@ -4,6 +4,7 @@ import 'package:intl/intl.dart';
import
'package:mypoint_flutter_app/screen/topup/topup_viewmodel.dart'
;
import
'package:mypoint_flutter_app/screen/topup/topup_viewmodel.dart'
;
import
'package:mypoint_flutter_app/widgets/custom_navigation_bar.dart'
;
import
'package:mypoint_flutter_app/widgets/custom_navigation_bar.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'../../extensions/debouncer.dart'
;
import
'../../preference/data_preference.dart'
;
import
'../../preference/data_preference.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../shared/router_gage.dart'
;
import
'../../shared/router_gage.dart'
;
...
@@ -20,6 +21,7 @@ class PhoneTopUpScreen extends StatefulWidget {
...
@@ -20,6 +21,7 @@ class PhoneTopUpScreen extends StatefulWidget {
class
_PhoneTopUpScreenState
extends
State
<
PhoneTopUpScreen
>
{
class
_PhoneTopUpScreenState
extends
State
<
PhoneTopUpScreen
>
{
final
TopUpViewModel
_viewModel
=
Get
.
put
(
TopUpViewModel
());
final
TopUpViewModel
_viewModel
=
Get
.
put
(
TopUpViewModel
());
late
final
TextEditingController
_phoneController
;
late
final
TextEditingController
_phoneController
;
final
_deb
=
Debouncer
(
ms:
500
);
@override
@override
void
initState
()
{
void
initState
()
{
...
@@ -84,7 +86,7 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
...
@@ -84,7 +86,7 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
keyboardType:
TextInputType
.
phone
,
keyboardType:
TextInputType
.
phone
,
onChanged:
(
value
)
{
onChanged:
(
value
)
{
_viewModel
.
phoneNumber
.
value
=
value
;
_viewModel
.
phoneNumber
.
value
=
value
;
_viewModel
.
checkMobileNetwork
();
_deb
.
run
(()
=>
_viewModel
.
checkMobileNetwork
()
)
;
},
},
),
),
),
),
...
@@ -326,12 +328,12 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
...
@@ -326,12 +328,12 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
),
),
const
Spacer
(),
const
Spacer
(),
ElevatedButton
(
ElevatedButton
(
onPressed:
()
{
onPressed:
_viewModel
.
validatePhoneNumber
()
?
()
{
Get
.
toNamed
(
Get
.
toNamed
(
transactionDetailScreen
,
transactionDetailScreen
,
arguments:
{
"product"
:
product
,
"quantity"
:
1
,
"targetPhoneNumber"
:
_viewModel
.
phoneNumber
.
value
},
arguments:
{
"product"
:
product
,
"quantity"
:
1
,
"targetPhoneNumber"
:
_viewModel
.
phoneNumber
.
value
},
);
);
},
}
:
null
,
style:
ElevatedButton
.
styleFrom
(
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
BaseColor
.
primary500
,
backgroundColor:
BaseColor
.
primary500
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
10
)),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
10
)),
...
...
lib/screen/topup/topup_viewmodel.dart
View file @
f714cdcc
...
@@ -35,22 +35,29 @@ class TopUpViewModel extends RestfulApiViewModel {
...
@@ -35,22 +35,29 @@ class TopUpViewModel extends RestfulApiViewModel {
}
}
}
}
bool
validatePhoneNumber
()
{
final
phone
=
phoneNumber
.
value
.
replaceAll
(
RegExp
(
r'\s+'
),
''
);
final
regex
=
RegExp
(
r'^(0|\+84)(3[2-9]|5[6|8|9]|7[0|6-9]|8[1-5]|9[0-4|6-9])[0-9]{7}$'
);
return
regex
.
hasMatch
(
phone
);
}
firstLoadTopUpData
()
async
{
firstLoadTopUpData
()
async
{
showLoading
();
_getTopUpBrands
();
await
getTopUpBrands
();
await
checkMobileNetwork
();
hideLoading
();
}
}
getTopUpBrands
()
{
_getTopUpBrands
()
{
showLoading
();
client
.
getTopUpBrands
(
ProductType
.
topupMobile
).
then
((
response
)
{
client
.
getTopUpBrands
(
ProductType
.
topupMobile
).
then
((
response
)
{
topUpBrands
.
value
=
response
.
data
??
[];
topUpBrands
.
value
=
response
.
data
??
[];
hideLoading
();
checkMobileNetwork
();
}).
catchError
((
error
)
{
}).
catchError
((
error
)
{
print
(
'Error fetching brands topup:
$error
'
);
hideLoading
(
);
});
});
}
}
checkMobileNetwork
()
{
checkMobileNetwork
()
{
showLoading
();
client
.
checkMobileNetwork
(
phoneNumber
.
value
).
then
((
response
)
{
client
.
checkMobileNetwork
(
phoneNumber
.
value
).
then
((
response
)
{
final
brandCode
=
response
.
data
?.
brand
??
''
;
final
brandCode
=
response
.
data
?.
brand
??
''
;
final
brand
=
topUpBrands
.
isNotEmpty
final
brand
=
topUpBrands
.
isNotEmpty
...
@@ -60,12 +67,14 @@ class TopUpViewModel extends RestfulApiViewModel {
...
@@ -60,12 +67,14 @@ class TopUpViewModel extends RestfulApiViewModel {
)
)
:
null
;
:
null
;
selectedBrand
.
value
=
brand
;
selectedBrand
.
value
=
brand
;
hideLoading
();
getTelcoDetail
();
getTelcoDetail
();
}).
catchError
((
error
)
{
}).
catchError
((
error
)
{
final
first
=
topUpBrands
.
value
.
firstOrNull
;
final
first
=
topUpBrands
.
value
.
firstOrNull
;
if
(
first
!=
null
)
{
if
(
first
!=
null
)
{
selectedBrand
.
value
=
first
;
selectedBrand
.
value
=
first
;
}
}
hideLoading
();
getTelcoDetail
();
getTelcoDetail
();
print
(
'Error checking mobile network:
$error
'
);
print
(
'Error checking mobile network:
$error
'
);
});
});
...
@@ -75,7 +84,6 @@ class TopUpViewModel extends RestfulApiViewModel {
...
@@ -75,7 +84,6 @@ class TopUpViewModel extends RestfulApiViewModel {
final
code
=
selectedBrand
.
value
?.
code
;
final
code
=
selectedBrand
.
value
?.
code
;
final
id
=
selectedBrand
.
value
?.
id
;
final
id
=
selectedBrand
.
value
?.
id
;
if
(
code
==
null
||
id
==
null
)
return
;
if
(
code
==
null
||
id
==
null
)
return
;
void
makeSelected
(
List
<
ProductModel
>
list
)
{
void
makeSelected
(
List
<
ProductModel
>
list
)
{
bool
didSelect
=
false
;
bool
didSelect
=
false
;
if
(
selected
!=
null
&&
selected
.
isNotEmpty
)
{
if
(
selected
!=
null
&&
selected
.
isNotEmpty
)
{
...
@@ -116,8 +124,8 @@ class TopUpViewModel extends RestfulApiViewModel {
...
@@ -116,8 +124,8 @@ class TopUpViewModel extends RestfulApiViewModel {
final
data
=
result
.
data
??
[];
final
data
=
result
.
data
??
[];
_allValue
[
code
]
=
data
;
_allValue
[
code
]
=
data
;
products
.
value
=
result
.
data
??
[];
products
.
value
=
result
.
data
??
[];
makeSelected
(
data
);
hideLoading
();
hideLoading
();
makeSelected
(
data
);
}
catch
(
error
)
{
}
catch
(
error
)
{
print
(
"Error fetching all products:
$error
"
);
print
(
"Error fetching all products:
$error
"
);
hideLoading
();
hideLoading
();
...
...
lib/screen/transaction/transaction_detail_screen.dart
View file @
f714cdcc
...
@@ -5,7 +5,7 @@ import 'package:intl/intl.dart';
...
@@ -5,7 +5,7 @@ import 'package:intl/intl.dart';
import
'../../base/base_screen.dart'
;
import
'../../base/base_screen.dart'
;
import
'../../base/basic_state.dart'
;
import
'../../base/basic_state.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../resources/base_color.dart'
;
import
'../../widgets/custom_
app
_bar.dart'
;
import
'../../widgets/custom_
navigation
_bar.dart'
;
import
'../../widgets/image_loader.dart'
;
import
'../../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'
;
...
@@ -60,7 +60,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w
...
@@ -60,7 +60,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w
Widget
createBody
()
{
Widget
createBody
()
{
return
Scaffold
(
return
Scaffold
(
backgroundColor:
Colors
.
grey
.
shade50
,
backgroundColor:
Colors
.
grey
.
shade50
,
appBar:
Custom
AppBar
.
back
(
title:
"Thông tin thanh toán"
),
appBar:
Custom
NavigationBar
(
title:
"Thông tin thanh toán"
),
body:
Obx
(()
{
body:
Obx
(()
{
if
(
_viewModel
.
isLoading
.
value
)
{
if
(
_viewModel
.
isLoading
.
value
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
return
const
Center
(
child:
CircularProgressIndicator
());
...
...
lib/screen/voucher/detail/voucher_detail_viewmodel.dart
View file @
f714cdcc
...
@@ -48,7 +48,7 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
...
@@ -48,7 +48,7 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
liked
.
value
=
(
response
.
data
?.
id
??
0
)
!=
0
;
liked
.
value
=
(
response
.
data
?.
id
??
0
)
!=
0
;
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
onShowAlertError
?.
call
(
"Error toggling favorite:
$e
rror
"
);
onShowAlertError
?.
call
(
Constants
.
commonE
rror
);
}
}
}
}
...
...
lib/screen/voucher/models/like_product_reponse_model.dart
→
lib/screen/voucher/models/like_product_re
s
ponse_model.dart
View file @
f714cdcc
import
'package:json_annotation/json_annotation.dart'
;
import
'package:json_annotation/json_annotation.dart'
;
part
'like_product_reponse_model.g.dart'
;
part
'like_product_re
s
ponse_model.g.dart'
;
@JsonSerializable
()
@JsonSerializable
()
class
LikeProductReponseModel
{
class
LikeProductRe
s
ponseModel
{
@JsonKey
(
name:
'like_id'
)
@JsonKey
(
name:
'like_id'
)
final
int
?
id
;
final
int
?
id
;
LikeProductReponseModel
({
LikeProductRe
s
ponseModel
({
this
.
id
,
this
.
id
,
});
});
factory
LikeProductReponseModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$LikeProductReponseModelFromJson
(
json
);
factory
LikeProductRe
s
ponseModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$LikeProductRe
s
ponseModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$LikeProductReponseModelToJson
(
this
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$LikeProductRe
s
ponseModelToJson
(
this
);
}
}
lib/screen/voucher/models/like_product_reponse_model.g.dart
→
lib/screen/voucher/models/like_product_re
s
ponse_model.g.dart
View file @
f714cdcc
// GENERATED CODE - DO NOT MODIFY BY HAND
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'like_product_reponse_model.dart'
;
part of
'like_product_re
s
ponse_model.dart'
;
// **************************************************************************
// **************************************************************************
// JsonSerializableGenerator
// JsonSerializableGenerator
// **************************************************************************
// **************************************************************************
LikeProductReponseModel
_$LikeProductReponseModelFromJson
(
LikeProductRe
s
ponseModel
_$LikeProductRe
s
ponseModelFromJson
(
Map
<
String
,
dynamic
>
json
,
Map
<
String
,
dynamic
>
json
,
)
=>
LikeProductReponseModel
(
id:
(
json
[
'like_id'
]
as
num
?)?.
toInt
());
)
=>
LikeProductRe
s
ponseModel
(
id:
(
json
[
'like_id'
]
as
num
?)?.
toInt
());
Map
<
String
,
dynamic
>
_$LikeProductReponseModelToJson
(
Map
<
String
,
dynamic
>
_$LikeProductRe
s
ponseModelToJson
(
LikeProductReponseModel
instance
,
LikeProductRe
s
ponseModel
instance
,
)
=>
<
String
,
dynamic
>{
'like_id'
:
instance
.
id
};
)
=>
<
String
,
dynamic
>{
'like_id'
:
instance
.
id
};
lib/screen/voucher/my_voucher/my_product_list_widget.dart
View file @
f714cdcc
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'../../../shared/router_gage.dart'
;
import
'../../../shared/router_gage.dart'
;
import
'../../../widgets/custom_app_bar.dart'
;
import
'../../../widgets/custom_empty_widget.dart'
;
import
'../../../widgets/custom_empty_widget.dart'
;
import
'../../../widgets/custom_navigation_bar.dart'
;
import
'../../../widgets/image_loader.dart'
;
import
'../../../widgets/image_loader.dart'
;
import
'../../home/models/my_product_model.dart'
;
import
'../../home/models/my_product_model.dart'
;
import
'my_product_list_viewmodel.dart'
;
import
'my_product_list_viewmodel.dart'
;
...
@@ -28,15 +28,18 @@ class _MyVoucherListScreenState extends State<MyVoucherListScreen> {
...
@@ -28,15 +28,18 @@ class _MyVoucherListScreenState extends State<MyVoucherListScreen> {
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
final
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
return
Scaffold
(
return
Scaffold
(
appBar:
Custom
AppBar
.
back
(
title:
'Ưu đãi của tôi'
),
appBar:
Custom
NavigationBar
(
title:
'Ưu đãi của tôi'
),
body:
Obx
(
body:
Obx
(
()
=>
Column
(
()
=>
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
Row
(
Padding
(
padding:
const
EdgeInsets
.
all
(
8.0
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceAround
,
mainAxisAlignment:
MainAxisAlignment
.
spaceAround
,
children:
[
_buildTab
(
'Đang có'
,
0
),
_buildTab
(
'Đã sử dụng'
,
1
),
_buildTab
(
'Hết hạn'
,
2
)],
children:
[
_buildTab
(
'Đang có'
,
0
),
_buildTab
(
'Đã sử dụng'
,
1
),
_buildTab
(
'Hết hạn'
,
2
)],
),
),
),
const
Divider
(
height:
1
),
const
Divider
(
height:
1
),
if
(
_viewModel
.
myProducts
.
isEmpty
)
if
(
_viewModel
.
myProducts
.
isEmpty
)
Expanded
(
child:
EmptyWidget
(
size:
Size
(
screenWidth
/
2
,
screenWidth
/
2
)))
Expanded
(
child:
EmptyWidget
(
size:
Size
(
screenWidth
/
2
,
screenWidth
/
2
)))
...
...
lib/screen/voucher/voucher_tab_screen.dart
View file @
f714cdcc
...
@@ -37,7 +37,6 @@ class _VoucherTabScreenState extends State<VoucherTabScreen> with PopupOnInit {
...
@@ -37,7 +37,6 @@ class _VoucherTabScreenState extends State<VoucherTabScreen> with PopupOnInit {
appBar:
CustomNavigationBar
(
appBar:
CustomNavigationBar
(
title:
"Ưu đãi"
,
title:
"Ưu đãi"
,
leftButtons:
[],
leftButtons:
[],
backgroundImage:
_headerHomeVM
.
headerData
.
background
??
"assets/images/bg_header_navi.png"
,
rightButtons:
[
rightButtons:
[
IconButton
(
IconButton
(
icon:
const
Icon
(
Icons
.
search
,
color:
Colors
.
white
),
icon:
const
Icon
(
Icons
.
search
,
color:
Colors
.
white
),
...
...
lib/shared/router_gage.dart
View file @
f714cdcc
...
@@ -28,6 +28,7 @@ import '../screen/onboarding/onboarding_screen.dart';
...
@@ -28,6 +28,7 @@ import '../screen/onboarding/onboarding_screen.dart';
import
'../screen/order_menu/order_menu_screen.dart'
;
import
'../screen/order_menu/order_menu_screen.dart'
;
import
'../screen/pageDetail/campaign_detail_screen.dart'
;
import
'../screen/pageDetail/campaign_detail_screen.dart'
;
import
'../screen/personal/personal_edit_screen.dart'
;
import
'../screen/personal/personal_edit_screen.dart'
;
import
'../screen/point_history/point_history_screen.dart'
;
import
'../screen/quiz_campaign/quiz_campaign_screen.dart'
;
import
'../screen/quiz_campaign/quiz_campaign_screen.dart'
;
import
'../screen/register_campaign/register_form_input_screen.dart'
;
import
'../screen/register_campaign/register_form_input_screen.dart'
;
import
'../screen/setting/setting_screen.dart'
;
import
'../screen/setting/setting_screen.dart'
;
...
@@ -94,6 +95,7 @@ const deviceManagerScreen = '/deviceManagerScreen';
...
@@ -94,6 +95,7 @@ const deviceManagerScreen = '/deviceManagerScreen';
const
interestCategoriesScreen
=
'/interestCategoriesScreen'
;
const
interestCategoriesScreen
=
'/interestCategoriesScreen'
;
const
myMobileCardListScreen
=
'/myMobileCardListScreen'
;
const
myMobileCardListScreen
=
'/myMobileCardListScreen'
;
const
bankAccountManagerScreen
=
'/bankAccountManagerScreen'
;
const
bankAccountManagerScreen
=
'/bankAccountManagerScreen'
;
const
pointHistoryScreen
=
'/pointHistoryScreen'
;
class
RouterPage
{
class
RouterPage
{
static
List
<
GetPage
>
pages
()
{
static
List
<
GetPage
>
pages
()
{
...
@@ -157,6 +159,7 @@ class RouterPage {
...
@@ -157,6 +159,7 @@ class RouterPage {
GetPage
(
name:
myMobileCardListScreen
,
page:
()
=>
MyMobileCardListScreen
()),
GetPage
(
name:
myMobileCardListScreen
,
page:
()
=>
MyMobileCardListScreen
()),
GetPage
(
name:
interestCategoriesScreen
,
page:
()
=>
InterestCategoriesScreen
()),
GetPage
(
name:
interestCategoriesScreen
,
page:
()
=>
InterestCategoriesScreen
()),
GetPage
(
name:
bankAccountManagerScreen
,
page:
()
=>
BankAccountManagerScreen
()),
GetPage
(
name:
bankAccountManagerScreen
,
page:
()
=>
BankAccountManagerScreen
()),
GetPage
(
name:
pointHistoryScreen
,
page:
()
=>
PointHistoryScreen
()),
];
];
}
}
}
}
\ No newline at end of file
lib/widgets/custom_navigation_bar.dart
View file @
f714cdcc
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'../screen/home/header_home_viewmodel.dart'
;
import
'back_button.dart'
;
import
'back_button.dart'
;
import
'image_loader.dart'
;
import
'image_loader.dart'
;
...
@@ -7,45 +9,51 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget
...
@@ -7,45 +9,51 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget
final
String
?
backgroundImage
;
final
String
?
backgroundImage
;
final
List
<
Widget
>
leftButtons
;
final
List
<
Widget
>
leftButtons
;
final
List
<
Widget
>
rightButtons
;
final
List
<
Widget
>
rightButtons
;
final
_defaultBgImage
=
'assets/images/bg_header_navi.png'
;
const
CustomNavigationBar
({
const
CustomNavigationBar
({
super
.
key
,
super
.
key
,
required
this
.
title
,
required
this
.
title
,
this
.
backgroundImage
=
"assets/images/bg_header_navi.png"
,
this
.
backgroundImage
,
this
.
leftButtons
=
const
[
CustomBackButton
()],
this
.
leftButtons
=
const
[
CustomBackButton
()],
this
.
rightButtons
=
const
[],
this
.
rightButtons
=
const
[],
});
});
@override
@override
Size
get
preferredSize
=>
const
Size
.
fromHeight
(
kToolbarHeight
);
Size
get
preferredSize
=>
const
Size
.
fromHeight
(
kToolbarHeight
);
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
if
(
backgroundImage
!=
null
&&
backgroundImage
!.
isNotEmpty
)
{
final
bool
isHttp
=
return
_buildAppBar
(
backgroundImage
!,
context
);
backgroundImage
!=
null
&&
(
backgroundImage
!.
startsWith
(
'http://'
)
||
backgroundImage
!.
startsWith
(
'https://'
));
}
final
theme
=
Get
.
find
<
HeaderThemeController
>();
return
Obx
(()
{
final
bg
=
theme
.
background
.
value
??
_defaultBgImage
;
return
_buildAppBar
(
bg
,
context
);
});
}
Widget
_buildAppBar
(
String
bgImage
,
BuildContext
context
)
{
final
double
statusBarHeight
=
MediaQuery
.
of
(
context
).
padding
.
top
;
final
bool
isHttp
=
bgImage
.
startsWith
(
'http://'
)
||
bgImage
.
startsWith
(
'https://'
);
return
Container
(
return
Container
(
height:
statusBarHeight
+
kToolbarHeight
,
height:
statusBarHeight
+
kToolbarHeight
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
// image: backgroundImage != null
color:
bgImage
.
isEmpty
?
Colors
.
white
:
null
,
// ? DecorationImage(
// image: AssetImage(backgroundImage!),
// fit: BoxFit.cover,
// )
// : null,
color:
backgroundImage
==
null
?
Colors
.
white
:
null
,
),
),
child:
Stack
(
child:
Stack
(
fit:
StackFit
.
expand
,
fit:
StackFit
.
expand
,
children:
[
children:
[
if
(
b
ackgroundImage
!=
null
)
if
(
b
gImage
.
isNotEmpty
)
isHttp
isHttp
?
loadNetworkImage
(
?
loadNetworkImage
(
url:
b
ackground
Image
,
url:
b
g
Image
,
fit:
BoxFit
.
cover
,
fit:
BoxFit
.
cover
,
placeholderAsset:
'assets/images/bg_header_navi.png'
,
placeholderAsset:
_defaultBgImage
,
)
)
:
Image
.
asset
(
background
Image
!
,
fit:
BoxFit
.
cover
),
:
Image
.
asset
(
_defaultBg
Image
,
fit:
BoxFit
.
cover
),
SafeArea
(
SafeArea
(
bottom:
false
,
bottom:
false
,
child:
Stack
(
child:
Stack
(
...
@@ -57,8 +65,7 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget
...
@@ -57,8 +65,7 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget
style:
const
TextStyle
(
fontSize:
18
,
fontWeight:
FontWeight
.
w800
,
color:
Colors
.
white
),
style:
const
TextStyle
(
fontSize:
18
,
fontWeight:
FontWeight
.
w800
,
color:
Colors
.
white
),
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
center
,
),
),
// Back button bên trái
// Buttons bên trái
// if (showBackButton) Positioned(left: 12, child: CustomBackButton()),
if
(
leftButtons
.
isNotEmpty
)
if
(
leftButtons
.
isNotEmpty
)
Positioned
(
left:
12
,
child:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
leftButtons
)),
Positioned
(
left:
12
,
child:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
leftButtons
)),
// Buttons bên phải
// Buttons bên phải
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment