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
8bef97c9
Commit
8bef97c9
authored
May 16, 2025
by
DatHV
Browse files
update payment detail
parent
7777aa65
Changes
32
Hide whitespace changes
Inline
Side-by-side
lib/configs/api_paths.dart
View file @
8bef97c9
...
...
@@ -39,4 +39,8 @@ class APIPaths {
static
const
String
affiliateProductTopSale
=
"/affiliateProductTopSale/1.0.0"
;
static
const
String
getCashbackOverview
=
"/cashback/overview"
;
static
const
String
getCashbackStatus
=
"/cashback/status"
;
static
const
String
getRegistrationForm
=
"/product/api/v2.0/cards/%@/registration_form"
;
static
const
String
getPreviewOrderInfo
=
"/order/api/v1.0/preview-order"
;
static
const
String
getPreviewOrderBankAccounts
=
"/order/api/v1.0/payment/bank-accounts"
;
static
const
String
getPreviewPaymentMethods
=
"/order/api/v1.0/payment/payment-methods"
;
}
\ No newline at end of file
lib/networking/restful_api_request.dart
View file @
8bef97c9
...
...
@@ -21,11 +21,15 @@ import '../screen/otp/model/create_otp_response_model.dart';
import
'../screen/otp/model/otp_verify_response_model.dart'
;
import
'../screen/pageDetail/model/campaign_detail_model.dart'
;
import
'../screen/pageDetail/model/detail_page_rule_type.dart'
;
import
'../screen/register_campaign/model/registration_form_package_model.dart'
;
import
'../screen/shopping/model/affiliate_brand_model.dart'
;
import
'../screen/shopping/model/affiliate_category_model.dart'
;
import
'../screen/shopping/model/affiliate_product_top_sale_model.dart'
;
import
'../screen/shopping/model/cashback_overview_model.dart'
;
import
'../screen/splash/splash_screen_viewmodel.dart'
;
import
'../screen/transaction/model/payment_bank_account_info_model.dart'
;
import
'../screen/transaction/model/payment_method_model.dart'
;
import
'../screen/transaction/model/preview_order_payment_model.dart'
;
import
'../screen/voucher/models/like_product_reponse_model.dart'
;
import
'../screen/voucher/models/product_store_model.dart'
;
import
'../screen/voucher/models/search_product_response_model.dart'
;
...
...
@@ -347,4 +351,35 @@ extension RestfullAPIClientAllApi on RestfulAPIClient {
return
CashbackOverviewModel
.
fromJson
(
data
as
Json
);
});
}
Future
<
BaseResponseModel
<
RegistrationFormPackageModel
>>
getRegistrationForm
(
String
id
)
async
{
final
path
=
APIPaths
.
getRegistrationForm
.
replaceAll
(
"%@"
,
id
);
return
requestNormal
(
path
,
Method
.
GET
,
{},
(
data
)
{
return
RegistrationFormPackageModel
.
fromJson
(
data
as
Json
);
});
}
Future
<
BaseResponseModel
<
PreviewOrderPaymentModel
>>
getPreviewOrderInfo
(
Json
body
)
async
{
return
requestNormal
(
APIPaths
.
getPreviewOrderInfo
,
Method
.
POST
,
body
,
(
data
)
{
return
PreviewOrderPaymentModel
.
fromJson
(
data
as
Json
);
});
}
Future
<
BaseResponseModel
<
List
<
PaymentBankAccountInfoModel
>>>
getPreviewOrderBankAccounts
()
async
{
return
requestNormal
(
APIPaths
.
getPreviewOrderBankAccounts
,
Method
.
GET
,
{},
(
data
)
{
final
list
=
data
as
List
<
dynamic
>;
return
list
.
map
((
e
)
=>
PaymentBankAccountInfoModel
.
fromJson
(
e
)).
toList
();
});
}
Future
<
BaseResponseModel
<
List
<
PaymentMethodModel
>>>
getPreviewPaymentMethods
()
async
{
return
requestNormal
(
APIPaths
.
getPreviewPaymentMethods
,
Method
.
GET
,
{},
(
data
)
{
final
list
=
data
as
List
<
dynamic
>;
return
list
.
map
((
e
)
=>
PaymentMethodModel
.
fromJson
(
e
)).
toList
();
});
}
}
lib/screen/register_campaign/input_form_cell.dart
0 → 100644
View file @
8bef97c9
import
'package:flutter/material.dart'
;
import
'model/input_cell_model.dart'
;
import
'model/input_data_default_code.dart'
;
class
InputFormCell
extends
StatefulWidget
{
final
InputCellModel
model
;
final
VoidCallback
?
onChanged
;
final
bool
isViewOnly
;
const
InputFormCell
({
super
.
key
,
required
this
.
model
,
this
.
onChanged
,
this
.
isViewOnly
=
false
,
});
@override
State
<
InputFormCell
>
createState
()
=>
_InputFormCellState
();
}
class
_InputFormCellState
extends
State
<
InputFormCell
>
{
late
TextEditingController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
TextEditingController
(
text:
widget
.
model
.
content
??
widget
.
model
.
defaultValue
??
''
,
);
}
@override
void
dispose
()
{
_controller
.
dispose
();
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
{
final
isEditable
=
(
widget
.
model
.
enableEdit
??
true
)
&&
!
widget
.
isViewOnly
;
final
isRequired
=
widget
.
model
.
require
==
true
;
final
title
=
isRequired
?
'
${widget.model.title ?? ''}
*'
:
widget
.
model
.
title
??
''
;
final
isBirthDate
=
widget
.
model
.
inputDefaultType
==
InputDataDefaultCode
.
birthDate
;
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
title
,
style:
const
TextStyle
(
fontSize:
14
,
fontWeight:
FontWeight
.
w500
),
),
const
SizedBox
(
height:
6
),
Container
(
decoration:
BoxDecoration
(
color:
isEditable
?
Colors
.
white
:
Colors
.
grey
.
shade200
,
border:
Border
.
all
(
color:
Colors
.
grey
.
shade400
),
borderRadius:
BorderRadius
.
circular
(
8
),
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
12
),
child:
Row
(
children:
[
Expanded
(
child:
TextFormField
(
enabled:
isEditable
&&
!
isBirthDate
,
controller:
_controller
,
maxLength:
widget
.
model
.
maxLength
,
keyboardType:
widget
.
model
.
keyboardType
,
decoration:
InputDecoration
(
hintText:
widget
.
model
.
placeholder
,
hintStyle:
const
TextStyle
(
color:
Colors
.
grey
),
border:
InputBorder
.
none
,
counterText:
''
,
),
style:
const
TextStyle
(
fontSize:
14
),
onChanged:
(
value
)
{
widget
.
model
.
content
=
value
;
// ✅ update model
widget
.
onChanged
?.
call
();
// ✅ callback để validate bên ngoài
},
readOnly:
isBirthDate
,
onTap:
()
{
if
(
isBirthDate
)
_pickDate
();
},
),
),
if
(
isBirthDate
)
IconButton
(
icon:
const
Icon
(
Icons
.
calendar_today_outlined
,
size:
20
),
onPressed:
isEditable
?
_pickDate
:
null
,
),
],
),
),
],
);
}
Future
<
void
>
_pickDate
()
async
{
DateTime
?
initialDate
=
DateTime
.
tryParse
(
_controller
.
text
)
??
DateTime
(
2000
);
DateTime
?
picked
=
await
showDatePicker
(
context:
context
,
initialDate:
initialDate
,
firstDate:
DateTime
(
1900
),
lastDate:
DateTime
.
now
(),
);
if
(
picked
!=
null
)
{
final
formatted
=
"
${picked.day.toString().padLeft(2, '0')}
/
${picked.month.toString().padLeft(2, '0')}
/
${picked.year}
"
;
_controller
.
text
=
formatted
;
widget
.
model
.
content
=
formatted
;
widget
.
onChanged
?.
call
();
}
}
}
lib/screen/register_campaign/model/form_input_description_model.dart
0 → 100644
View file @
8bef97c9
import
'package:json_annotation/json_annotation.dart'
;
part
'form_input_description_model.g.dart'
;
@JsonSerializable
()
class
FormInputDescriptionModel
{
final
String
?
title
;
final
bool
?
checkbox
;
@JsonKey
(
name:
'click_action_type'
)
final
String
?
clickActionType
;
@JsonKey
(
name:
'click_action_param'
)
final
String
?
clickActionParam
;
FormInputDescriptionModel
({
this
.
title
,
this
.
checkbox
,
this
.
clickActionType
,
this
.
clickActionParam
,
});
factory
FormInputDescriptionModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$FormInputDescriptionModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$FormInputDescriptionModelToJson
(
this
);
}
lib/screen/register_campaign/model/form_input_description_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'form_input_description_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
FormInputDescriptionModel
_$FormInputDescriptionModelFromJson
(
Map
<
String
,
dynamic
>
json
,
)
=>
FormInputDescriptionModel
(
title:
json
[
'title'
]
as
String
?,
checkbox:
json
[
'checkbox'
]
as
bool
?,
clickActionType:
json
[
'click_action_type'
]
as
String
?,
clickActionParam:
json
[
'click_action_param'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$FormInputDescriptionModelToJson
(
FormInputDescriptionModel
instance
,
)
=>
<
String
,
dynamic
>{
'title'
:
instance
.
title
,
'checkbox'
:
instance
.
checkbox
,
'click_action_type'
:
instance
.
clickActionType
,
'click_action_param'
:
instance
.
clickActionParam
,
};
lib/screen/register_campaign/model/input_cell_model.dart
0 → 100644
View file @
8bef97c9
import
'package:flutter/cupertino.dart'
;
import
'package:json_annotation/json_annotation.dart'
;
import
'input_data_default_code.dart'
;
part
'input_cell_model.g.dart'
;
@JsonSerializable
()
class
InputCellModel
{
final
String
?
id
;
@JsonKey
(
name:
'enable_remove'
)
final
bool
?
enableRemove
;
@JsonKey
(
name:
'parent_code'
)
final
String
?
parentCode
;
final
bool
?
require
;
@JsonKey
(
name:
'enable_edit'
)
final
bool
?
enableEdit
;
@JsonKey
(
name:
'max_length'
)
final
int
?
maxLength
;
final
String
?
type
;
final
String
?
title
;
final
String
?
code
;
@JsonKey
(
name:
'default_value'
)
final
String
?
defaultValue
;
final
String
?
key
;
final
String
?
placeholder
;
@JsonKey
(
name:
'code_default'
)
final
String
?
codeDefault
;
String
?
content
;
get
value
=>
content
??
defaultValue
??
''
;
TextInputType
get
keyboardType
{
if
(
type
==
"NUMBER"
)
return
TextInputType
.
number
;
if
(
inputDefaultType
==
InputDataDefaultCode
.
email
)
return
TextInputType
.
emailAddress
;
return
TextInputType
.
text
;
}
InputDataDefaultCode
?
get
inputDefaultType
=>
InputDataDefaultCodeExtension
.
fromRaw
(
code
);
InputCellModel
({
this
.
id
,
this
.
enableRemove
,
this
.
parentCode
,
this
.
require
,
this
.
enableEdit
,
this
.
maxLength
,
this
.
type
,
this
.
title
,
this
.
code
,
this
.
defaultValue
,
this
.
key
,
this
.
placeholder
,
this
.
codeDefault
,
this
.
content
,
});
factory
InputCellModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$InputCellModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$InputCellModelToJson
(
this
);
}
\ No newline at end of file
lib/screen/register_campaign/model/input_cell_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'input_cell_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
InputCellModel
_$InputCellModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
InputCellModel
(
id:
json
[
'id'
]
as
String
?,
enableRemove:
json
[
'enable_remove'
]
as
bool
?,
parentCode:
json
[
'parent_code'
]
as
String
?,
require:
json
[
'require'
]
as
bool
?,
enableEdit:
json
[
'enable_edit'
]
as
bool
?,
maxLength:
(
json
[
'max_length'
]
as
num
?)?.
toInt
(),
type:
json
[
'type'
]
as
String
?,
title:
json
[
'title'
]
as
String
?,
code:
json
[
'code'
]
as
String
?,
defaultValue:
json
[
'default_value'
]
as
String
?,
key:
json
[
'key'
]
as
String
?,
placeholder:
json
[
'placeholder'
]
as
String
?,
codeDefault:
json
[
'code_default'
]
as
String
?,
content:
json
[
'content'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$InputCellModelToJson
(
InputCellModel
instance
)
=>
<
String
,
dynamic
>{
'id'
:
instance
.
id
,
'enable_remove'
:
instance
.
enableRemove
,
'parent_code'
:
instance
.
parentCode
,
'require'
:
instance
.
require
,
'enable_edit'
:
instance
.
enableEdit
,
'max_length'
:
instance
.
maxLength
,
'type'
:
instance
.
type
,
'title'
:
instance
.
title
,
'code'
:
instance
.
code
,
'default_value'
:
instance
.
defaultValue
,
'key'
:
instance
.
key
,
'placeholder'
:
instance
.
placeholder
,
'code_default'
:
instance
.
codeDefault
,
'content'
:
instance
.
content
,
};
lib/screen/register_campaign/model/input_data_default_code.dart
0 → 100644
View file @
8bef97c9
enum
InputDataDefaultCode
{
fullName
,
phoneNumber
,
birthDate
,
locationDistrictCode
,
locationProvinceCode
,
email
,
addressFull
,
}
extension
InputDataDefaultCodeExtension
on
InputDataDefaultCode
{
static
InputDataDefaultCode
?
fromRaw
(
String
?
raw
)
{
switch
(
raw
)
{
case
'FULL_NAME'
:
return
InputDataDefaultCode
.
fullName
;
case
'PHONE_NUMBER'
:
return
InputDataDefaultCode
.
phoneNumber
;
case
'BIRTH_DATE'
:
return
InputDataDefaultCode
.
birthDate
;
case
'LOCATION_DISTRICT_CODE'
:
return
InputDataDefaultCode
.
locationDistrictCode
;
case
'LOCATION_PROVINCE_CODE'
:
return
InputDataDefaultCode
.
locationProvinceCode
;
case
'EMAIL'
:
return
InputDataDefaultCode
.
email
;
case
'ADDRESS_FULL'
:
return
InputDataDefaultCode
.
addressFull
;
default
:
return
null
;
}
}
}
lib/screen/register_campaign/model/input_form_registration_model.dart
0 → 100644
View file @
8bef97c9
import
'package:json_annotation/json_annotation.dart'
;
import
'form_input_description_model.dart'
;
import
'input_cell_model.dart'
;
part
'input_form_registration_model.g.dart'
;
@JsonSerializable
()
class
InputFormRegistrationModel
{
final
String
?
title
;
@JsonKey
(
name:
'input_required'
)
final
List
<
InputCellModel
>?
inputRequired
;
@JsonKey
(
name:
'header_description'
)
final
FormInputDescriptionModel
?
headerDescription
;
@JsonKey
(
name:
'footer_description'
)
final
FormInputDescriptionModel
?
footerDescription
;
@JsonKey
(
name:
'click_action_type'
)
final
String
?
clickActionType
;
@JsonKey
(
name:
'click_action_param'
)
final
String
?
clickActionParam
;
final
bool
?
checked
;
InputFormRegistrationModel
({
this
.
title
,
this
.
inputRequired
,
this
.
headerDescription
,
this
.
footerDescription
,
this
.
clickActionType
,
this
.
clickActionParam
,
this
.
checked
,
});
factory
InputFormRegistrationModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$InputFormRegistrationModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$InputFormRegistrationModelToJson
(
this
);
}
lib/screen/register_campaign/model/input_form_registration_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'input_form_registration_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
InputFormRegistrationModel
_$InputFormRegistrationModelFromJson
(
Map
<
String
,
dynamic
>
json
,
)
=>
InputFormRegistrationModel
(
title:
json
[
'title'
]
as
String
?,
inputRequired:
(
json
[
'input_required'
]
as
List
<
dynamic
>?)
?.
map
((
e
)
=>
InputCellModel
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
(),
headerDescription:
json
[
'header_description'
]
==
null
?
null
:
FormInputDescriptionModel
.
fromJson
(
json
[
'header_description'
]
as
Map
<
String
,
dynamic
>,
),
footerDescription:
json
[
'footer_description'
]
==
null
?
null
:
FormInputDescriptionModel
.
fromJson
(
json
[
'footer_description'
]
as
Map
<
String
,
dynamic
>,
),
clickActionType:
json
[
'click_action_type'
]
as
String
?,
clickActionParam:
json
[
'click_action_param'
]
as
String
?,
checked:
json
[
'checked'
]
as
bool
?,
);
Map
<
String
,
dynamic
>
_$InputFormRegistrationModelToJson
(
InputFormRegistrationModel
instance
,
)
=>
<
String
,
dynamic
>{
'title'
:
instance
.
title
,
'input_required'
:
instance
.
inputRequired
,
'header_description'
:
instance
.
headerDescription
,
'footer_description'
:
instance
.
footerDescription
,
'click_action_type'
:
instance
.
clickActionType
,
'click_action_param'
:
instance
.
clickActionParam
,
'checked'
:
instance
.
checked
,
};
lib/screen/register_campaign/model/registration_form_package_model.dart
0 → 100644
View file @
8bef97c9
import
'package:json_annotation/json_annotation.dart'
;
import
'package:mypoint_flutter_app/screen/register_campaign/model/registration_form_package_verify_model.dart'
;
import
'input_form_registration_model.dart'
;
part
'registration_form_package_model.g.dart'
;
@JsonSerializable
()
class
RegistrationFormPackageModel
{
@JsonKey
(
name:
'product_id'
)
final
String
?
productId
;
final
VerifyModel
?
verify
;
@JsonKey
(
name:
'is_checked_registration'
)
final
bool
?
isCheckedRegistration
;
final
String
?
id
;
final
String
?
title
;
@JsonKey
(
name:
'form_confirm'
)
final
InputFormRegistrationModel
?
formConfirm
;
@JsonKey
(
name:
'click_action_param'
)
final
String
?
clickActionParam
;
@JsonKey
(
name:
'click_action_type'
)
final
String
?
clickActionType
;
@JsonKey
(
name:
'form_registration'
)
final
InputFormRegistrationModel
?
formRegistration
;
RegistrationFormPackageModel
({
this
.
productId
,
this
.
verify
,
this
.
isCheckedRegistration
,
this
.
id
,
this
.
title
,
this
.
formConfirm
,
this
.
clickActionParam
,
this
.
clickActionType
,
this
.
formRegistration
,
});
factory
RegistrationFormPackageModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$RegistrationFormPackageModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$RegistrationFormPackageModelToJson
(
this
);
}
lib/screen/register_campaign/model/registration_form_package_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'registration_form_package_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RegistrationFormPackageModel
_$RegistrationFormPackageModelFromJson
(
Map
<
String
,
dynamic
>
json
,
)
=>
RegistrationFormPackageModel
(
productId:
json
[
'product_id'
]
as
String
?,
verify:
json
[
'verify'
]
==
null
?
null
:
VerifyModel
.
fromJson
(
json
[
'verify'
]
as
Map
<
String
,
dynamic
>),
isCheckedRegistration:
json
[
'is_checked_registration'
]
as
bool
?,
id:
json
[
'id'
]
as
String
?,
title:
json
[
'title'
]
as
String
?,
formConfirm:
json
[
'form_confirm'
]
==
null
?
null
:
InputFormRegistrationModel
.
fromJson
(
json
[
'form_confirm'
]
as
Map
<
String
,
dynamic
>,
),
clickActionParam:
json
[
'click_action_param'
]
as
String
?,
clickActionType:
json
[
'click_action_type'
]
as
String
?,
formRegistration:
json
[
'form_registration'
]
==
null
?
null
:
InputFormRegistrationModel
.
fromJson
(
json
[
'form_registration'
]
as
Map
<
String
,
dynamic
>,
),
);
Map
<
String
,
dynamic
>
_$RegistrationFormPackageModelToJson
(
RegistrationFormPackageModel
instance
,
)
=>
<
String
,
dynamic
>{
'product_id'
:
instance
.
productId
,
'verify'
:
instance
.
verify
,
'is_checked_registration'
:
instance
.
isCheckedRegistration
,
'id'
:
instance
.
id
,
'title'
:
instance
.
title
,
'form_confirm'
:
instance
.
formConfirm
,
'click_action_param'
:
instance
.
clickActionParam
,
'click_action_type'
:
instance
.
clickActionType
,
'form_registration'
:
instance
.
formRegistration
,
};
lib/screen/register_campaign/model/registration_form_package_verify_model.dart
0 → 100644
View file @
8bef97c9
import
'package:json_annotation/json_annotation.dart'
;
part
'registration_form_package_verify_model.g.dart'
;
@JsonSerializable
()
class
VerifyModel
{
final
String
?
url
;
VerifyModel
({
this
.
url
});
factory
VerifyModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$VerifyModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$VerifyModelToJson
(
this
);
}
lib/screen/register_campaign/model/registration_form_package_verify_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'registration_form_package_verify_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
VerifyModel
_$VerifyModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
VerifyModel
(
url:
json
[
'url'
]
as
String
?);
Map
<
String
,
dynamic
>
_$VerifyModelToJson
(
VerifyModel
instance
)
=>
<
String
,
dynamic
>{
'url'
:
instance
.
url
};
lib/screen/register_campaign/register_form_input_screen.dart
0 → 100644
View file @
8bef97c9
import
'package:flutter/material.dart'
;
import
'package:flutter_widget_from_html/flutter_widget_from_html.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/resouce/base_color.dart'
;
import
'package:mypoint_flutter_app/screen/register_campaign/register_form_input_viewmodel.dart'
;
import
'../../shared/router_gage.dart'
;
import
'../../widgets/custom_app_bar.dart'
;
import
'input_form_cell.dart'
;
import
'model/registration_form_package_model.dart'
;
class
RegisterFormInputScreen
extends
StatefulWidget
{
const
RegisterFormInputScreen
({
super
.
key
});
@override
State
<
RegisterFormInputScreen
>
createState
()
=>
_RegisterFormInputScreenState
();
}
class
_RegisterFormInputScreenState
extends
State
<
RegisterFormInputScreen
>
{
late
final
RegisterFormInputViewModel
_viewModel
;
String
_title
=
''
;
final
_isFormValid
=
false
.
obs
;
late
var
_isConfirmScreen
=
false
;
@override
void
initState
()
{
super
.
initState
();
_viewModel
=
Get
.
put
(
RegisterFormInputViewModel
());
final
args
=
Get
.
arguments
as
Map
<
String
,
dynamic
>?;
if
(
args
?[
'formConfirm'
]
!=
null
)
{
_isConfirmScreen
=
true
;
final
data
=
args
![
'formConfirm'
]
as
RegistrationFormPackageModel
;
_title
=
data
?.
formConfirm
?.
title
??
''
;
_viewModel
.
form
.
value
=
data
;
}
else
{
final
id
=
args
?[
'id'
]
as
int
?;
if
(
id
!=
null
)
{
_isConfirmScreen
=
false
;
_viewModel
.
fetchRegisterFormInput
(
id
.
toString
()).
then
((
_
)
{
setState
(()
{
_title
=
_viewModel
.
form
.
value
?.
title
??
''
;
});
});
}
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
GestureDetector
(
onTap:
()
=>
FocusScope
.
of
(
context
).
unfocus
(),
child:
Scaffold
(
appBar:
CustomAppBar
.
back
(
title:
_title
),
body:
Obx
(()
{
final
form
=
_isConfirmScreen
?
_viewModel
.
form
.
value
?.
formConfirm
:
_viewModel
.
form
.
value
?.
formRegistration
;
final
inputItem
=
_viewModel
.
form
.
value
?.
formRegistration
?.
inputRequired
;
if
(
form
==
null
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
}
return
SingleChildScrollView
(
padding:
const
EdgeInsets
.
all
(
16
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
// Header HTML
if
(
form
?.
headerDescription
?.
title
?.
isNotEmpty
==
true
)
Container
(
color:
BaseColor
.
primary50
,
child:
Padding
(
padding:
const
EdgeInsets
.
all
(
8.0
),
child:
HtmlWidget
(
form
!.
headerDescription
!.
title
!),
),
),
const
SizedBox
(
height:
12
),
// Inputs
if
(
inputItem
!=
null
)
...
inputItem
!.
map
(
(
item
)
=>
Padding
(
padding:
const
EdgeInsets
.
only
(
bottom:
16
),
child:
InputFormCell
(
model:
item
,
onChanged:
_validateForm
,
isViewOnly:
_isConfirmScreen
),
),
),
// Footer HTML + Checkbox nếu có
if
(
form
.
footerDescription
?.
title
?.
isNotEmpty
==
true
)
Padding
(
padding:
const
EdgeInsets
.
only
(
top:
16
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
if
(
form
?.
checked
==
true
&&
_isConfirmScreen
==
false
)
Obx
(
()
=>
Checkbox
(
activeColor:
BaseColor
.
primary400
,
value:
_viewModel
.
isChecked
.
value
,
onChanged:
(
val
)
{
_viewModel
.
isChecked
.
value
=
val
??
false
;
_validateForm
();
},
),
),
Expanded
(
child:
HtmlWidget
(
form
!.
footerDescription
!.
title
!)),
],
),
),
const
SizedBox
(
height:
24
),
_buildBottomButton
(),
],
),
);
}),
),
);
}
Widget
_buildBottomButton
()
{
if
(
_isConfirmScreen
)
{
return
SizedBox
(
width:
double
.
infinity
,
child:
Row
(
mainAxisSize:
MainAxisSize
.
max
,
mainAxisAlignment:
MainAxisAlignment
.
spaceEvenly
,
children:
[
Expanded
(
child:
OutlinedButton
(
onPressed:
()
{
Navigator
.
pop
(
context
);
},
style:
OutlinedButton
.
styleFrom
(
side:
const
BorderSide
(
color:
Colors
.
black54
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
)),
),
child:
const
Text
(
"Chỉnh sửa"
,
style:
TextStyle
(
color:
Colors
.
black
,
fontSize:
16
)),
),
),
const
SizedBox
(
width:
12
),
Expanded
(
child:
ElevatedButton
(
onPressed:
_gotoPaymentScreen
,
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
BaseColor
.
primary400
,
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
)),
),
child:
const
Text
(
"Tiếp tục"
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
16
)),
),
),
],
),
);
}
return
SizedBox
(
width:
double
.
infinity
,
child:
Obx
(
()
=>
ElevatedButton
(
onPressed:
_isFormValid
.
value
?
_onSubmit
:
null
,
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
BaseColor
.
primary400
,
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
)),
),
child:
const
Text
(
"Tiếp tục"
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
16
)),
),
),
);
}
void
_gotoPaymentScreen
()
{
print
(
"_gotoPaymentScreen"
);
}
void
_onSubmit
()
{
if
(
_viewModel
.
form
.
value
?.
formConfirm
?.
checked
==
true
)
{
Get
.
toNamed
(
registerFormInputScreen
,
arguments:
{
"formConfirm"
:
_viewModel
.
form
.
value
},
preventDuplicates:
false
);
}
else
{
_gotoPaymentScreen
();
}
}
void
_validateForm
()
{
final
form
=
_viewModel
.
form
.
value
?.
formRegistration
;
final
inputs
=
form
?.
inputRequired
??
[];
inputs
.
forEach
((
input
)
{
print
(
"Input:
${input.title}
, Value:
${input.value}
"
);
});
final
isValid
=
inputs
.
every
((
input
)
{
if
(
input
.
require
==
true
)
{
return
input
.
value
.
trim
().
isNotEmpty
==
true
;
}
return
true
;
});
final
isChecked
=
_viewModel
.
isChecked
.
value
;
_isFormValid
.
value
=
isValid
&&
isChecked
;
}
}
lib/screen/register_campaign/register_form_input_viewmodel.dart
0 → 100644
View file @
8bef97c9
import
'package:get/get_rx/src/rx_types/rx_types.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api_request.dart'
;
import
'../../base/restful_api_viewmodel.dart'
;
import
'model/registration_form_package_model.dart'
;
class
RegisterFormInputViewModel
extends
RestfulApiViewModel
{
var
form
=
Rxn
<
RegistrationFormPackageModel
>();
var
isLoading
=
false
.
obs
;
var
isChecked
=
true
.
obs
;
Future
<
void
>
fetchRegisterFormInput
(
String
id
)
async
{
try
{
isLoading
.
value
=
true
;
final
response
=
await
client
.
getRegistrationForm
(
id
);
form
.
value
=
response
.
data
;
}
catch
(
error
)
{
// onShowAlertError?.call("Error fetching product detail: $error");
print
(
"Error fetching product detail:
$error
"
);
}
finally
{
isLoading
.
value
=
false
;
}
}
}
\ No newline at end of file
lib/screen/transaction/model/payment_bank_account_info_model.dart
0 → 100644
View file @
8bef97c9
import
'package:json_annotation/json_annotation.dart'
;
part
'payment_bank_account_info_model.g.dart'
;
@JsonSerializable
()
class
PaymentBankAccountInfoModel
{
final
int
?
id
;
@JsonKey
(
name:
'payment_method'
)
final
String
?
paymentMethod
;
@JsonKey
(
name:
'card_name'
)
final
String
?
cardName
;
@JsonKey
(
name:
'card_number'
)
final
String
?
cardNumber
;
@JsonKey
(
name:
'card_date'
)
final
String
?
cardDate
;
@JsonKey
(
name:
'bank_logo'
)
final
String
?
bankLogo
;
@JsonKey
(
name:
'bank_name'
)
final
String
?
bankName
;
@JsonKey
(
name:
'bank_short_name'
)
final
String
?
bankShortName
;
@JsonKey
(
name:
'bank_code'
)
final
String
?
bankCode
;
@JsonKey
(
name:
'is_default'
)
final
bool
?
isDefault
;
bool
?
isSelected
;
@JsonKey
(
name:
'form_bank_title'
)
final
String
?
formBankTitle
;
@JsonKey
(
name:
'form_bank_number_title'
)
final
String
?
formBankNumberTitle
;
@JsonKey
(
name:
'form_message_delete'
)
final
String
?
formMessageDelete
;
@JsonKey
(
name:
'form_bank_background'
)
final
String
?
formBankBackground
;
@JsonKey
(
name:
'form_bank_name'
)
final
String
?
formBankName
;
@JsonKey
(
name:
'form_bank_number'
)
final
String
?
formBankNumber
;
PaymentBankAccountInfoModel
({
this
.
id
,
this
.
paymentMethod
,
this
.
cardName
,
this
.
cardNumber
,
this
.
cardDate
,
this
.
bankLogo
,
this
.
bankName
,
this
.
bankShortName
,
this
.
bankCode
,
this
.
isDefault
,
required
this
.
isSelected
,
// initialize in constructor
this
.
formBankTitle
,
this
.
formBankNumberTitle
,
this
.
formMessageDelete
,
this
.
formBankBackground
,
this
.
formBankName
,
this
.
formBankNumber
,
});
factory
PaymentBankAccountInfoModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$PaymentBankAccountInfoModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$PaymentBankAccountInfoModelToJson
(
this
);
}
lib/screen/transaction/model/payment_bank_account_info_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'payment_bank_account_info_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PaymentBankAccountInfoModel
_$PaymentBankAccountInfoModelFromJson
(
Map
<
String
,
dynamic
>
json
,
)
=>
PaymentBankAccountInfoModel
(
id:
(
json
[
'id'
]
as
num
?)?.
toInt
(),
paymentMethod:
json
[
'payment_method'
]
as
String
?,
cardName:
json
[
'card_name'
]
as
String
?,
cardNumber:
json
[
'card_number'
]
as
String
?,
cardDate:
json
[
'card_date'
]
as
String
?,
bankLogo:
json
[
'bank_logo'
]
as
String
?,
bankName:
json
[
'bank_name'
]
as
String
?,
bankShortName:
json
[
'bank_short_name'
]
as
String
?,
bankCode:
json
[
'bank_code'
]
as
String
?,
isDefault:
json
[
'is_default'
]
as
bool
?,
isSelected:
json
[
'isSelected'
]
as
bool
?,
formBankTitle:
json
[
'form_bank_title'
]
as
String
?,
formBankNumberTitle:
json
[
'form_bank_number_title'
]
as
String
?,
formMessageDelete:
json
[
'form_message_delete'
]
as
String
?,
formBankBackground:
json
[
'form_bank_background'
]
as
String
?,
formBankName:
json
[
'form_bank_name'
]
as
String
?,
formBankNumber:
json
[
'form_bank_number'
]
as
String
?,
);
Map
<
String
,
dynamic
>
_$PaymentBankAccountInfoModelToJson
(
PaymentBankAccountInfoModel
instance
,
)
=>
<
String
,
dynamic
>{
'id'
:
instance
.
id
,
'payment_method'
:
instance
.
paymentMethod
,
'card_name'
:
instance
.
cardName
,
'card_number'
:
instance
.
cardNumber
,
'card_date'
:
instance
.
cardDate
,
'bank_logo'
:
instance
.
bankLogo
,
'bank_name'
:
instance
.
bankName
,
'bank_short_name'
:
instance
.
bankShortName
,
'bank_code'
:
instance
.
bankCode
,
'is_default'
:
instance
.
isDefault
,
'isSelected'
:
instance
.
isSelected
,
'form_bank_title'
:
instance
.
formBankTitle
,
'form_bank_number_title'
:
instance
.
formBankNumberTitle
,
'form_message_delete'
:
instance
.
formMessageDelete
,
'form_bank_background'
:
instance
.
formBankBackground
,
'form_bank_name'
:
instance
.
formBankName
,
'form_bank_number'
:
instance
.
formBankNumber
,
};
lib/screen/transaction/model/payment_method_model.dart
0 → 100644
View file @
8bef97c9
import
'package:json_annotation/json_annotation.dart'
;
import
'package:mypoint_flutter_app/screen/transaction/model/payment_method_type.dart'
;
part
'payment_method_model.g.dart'
;
@JsonSerializable
()
class
PaymentMethodModel
{
final
int
?
id
;
final
String
?
code
;
final
String
?
name
;
final
String
?
logo
;
final
bool
?
saveToken
;
final
bool
?
isSelected
;
final
bool
?
needSaveTokenWhenOrder
;
PaymentMethodType
?
get
type
{
if
(
code
==
null
)
return
null
;
try
{
return
PaymentMethodType
.
fromString
(
code
!);
}
catch
(
_
)
{
return
null
;
}
}
PaymentMethodModel
({
this
.
id
,
this
.
code
,
this
.
name
,
this
.
logo
,
this
.
saveToken
,
this
.
isSelected
,
this
.
needSaveTokenWhenOrder
,
});
factory
PaymentMethodModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$PaymentMethodModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$PaymentMethodModelToJson
(
this
);
}
lib/screen/transaction/model/payment_method_model.g.dart
0 → 100644
View file @
8bef97c9
// GENERATED CODE - DO NOT MODIFY BY HAND
part of
'payment_method_model.dart'
;
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PaymentMethodModel
_$PaymentMethodModelFromJson
(
Map
<
String
,
dynamic
>
json
)
=>
PaymentMethodModel
(
id:
(
json
[
'id'
]
as
num
?)?.
toInt
(),
code:
json
[
'code'
]
as
String
?,
name:
json
[
'name'
]
as
String
?,
logo:
json
[
'logo'
]
as
String
?,
saveToken:
json
[
'saveToken'
]
as
bool
?,
isSelected:
json
[
'isSelected'
]
as
bool
?,
needSaveTokenWhenOrder:
json
[
'needSaveTokenWhenOrder'
]
as
bool
?,
);
Map
<
String
,
dynamic
>
_$PaymentMethodModelToJson
(
PaymentMethodModel
instance
)
=>
<
String
,
dynamic
>{
'id'
:
instance
.
id
,
'code'
:
instance
.
code
,
'name'
:
instance
.
name
,
'logo'
:
instance
.
logo
,
'saveToken'
:
instance
.
saveToken
,
'isSelected'
:
instance
.
isSelected
,
'needSaveTokenWhenOrder'
:
instance
.
needSaveTokenWhenOrder
,
};
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