add services related to auth

merge-requests/13/head
Elham Rababah 6 years ago
parent abd02a7973
commit 4dece11a43

@ -14,6 +14,10 @@ const INSERT_DEVICE_IMEI =
const SELECT_DEVICE_IMEI =
'https://hmgwebservices.com/Services/Sentry.svc/REST/DoctorApplication_SELECTDeviceIMEIbyIMEI';
const SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE =
'https://hmgwebservices.com/Services/Sentry.svc/REST/DoctorApplication_SendActivationCodebyOTPNotificationType';
const MEMBER_CHECK_ACTIVATION_CODE_NEW ='https://hmgwebservices.com/Services/Sentry.svc/REST/MemberCheckActivationCode_New';
class AuthProvider with ChangeNotifier {
Client client =
HttpClientWithInterceptor.build(interceptors: [HttpInterceptor()]);
@ -63,4 +67,28 @@ class AuthProvider with ChangeNotifier {
throw error;
}
}
Future<Map> sendActivationCodeByOtpNotificationType(activationCodeModel) async{
const url = SEND_ACTIVATION_CODE_BY_OTP_NOTIFICATION_TYPE;
try {
final response = await client.post(url, body: json.encode(activationCodeModel));
return Future.value(json.decode(response.body));
} catch (error) {
print(error);
throw error;
}
}
Future<Map> memberCheckActivationCodeNew(activationCodeModel) async{
const url = MEMBER_CHECK_ACTIVATION_CODE_NEW;
try {
final response = await client.post(url, body: json.encode(activationCodeModel));
return Future.value(json.decode(response.body));
} catch (error) {
print(error);
throw error;
}
}
}

@ -12,7 +12,7 @@ import './screens/patients/patient_search_screen.dart';
import './screens/patients/patients_screen.dart';
import './screens/settings/settings_screen.dart';
const String INIT_ROUTE = LOGIN;
const String INIT_ROUTE = VERIFICATION_METHODS;
const String HOME = '/';
const String LOGIN = 'login';
const String CHANGE_PASSWORD = 'change-password';

@ -14,7 +14,7 @@ class VerifyAccountScreen extends StatelessWidget {
body: SafeArea(
child: ListView(children: <Widget>[
Container(
margin: EdgeInsetsDirectional.fromSTEB(30, 0, 0, 0),
margin: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[

@ -24,10 +24,12 @@ import 'package:flutter_flexible_toast/flutter_flexible_toast.dart';
FlutterFlexibleToast.showToast(
message: msg,
toastLength: Toast.LENGTH_SHORT,
toastGravity: ToastGravity.TOP,
backgroundColor: Colors.red,
icon: ICON.CLOSE,
fontSize: 16,
imageSize: 35,
timeInSeconds: 110,
textColor: Colors.white);
}

@ -1,7 +1,10 @@
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../config/size_config.dart';
import '../util/dr_app_toast_msg.dart';
DrAppToastMsg toastMsg = DrAppToastMsg();
/*
*@author: Elham Rababah
*@Date:12/4/2020
@ -56,4 +59,14 @@ class Helpers {
),
);
}
showErrorToast([msg = null]) {
String localMsg = 'Something wrong happened, please contact the admin';
if (msg != null) {
localMsg = msg.toString();
}
toastMsg.showErrorToast(localMsg);
}
}

@ -80,12 +80,14 @@ class _KnownUserLoginState extends State<KnownUserLogin> {
2; //res['SELECTDeviceIMEIbyIMEI_List'][0]['LogInType'];
}).catchError((err) {
print('${err}');
toastMsg.showErrorToast(err);
});
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return DrAppCircularProgressIndeicator();
default:
if (snapshot.hasError) {
toastMsg.showErrorToast('Error: ${snapshot.error}');
return Text('Error: ${snapshot.error}');
} else {
return Column(

@ -1,4 +1,3 @@
import 'package:doctor_app_flutter/util/helpers.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
@ -14,10 +13,12 @@ import '../../providers/projects_provider.dart';
import '../../routes.dart';
import '../../util/dr_app_shared_pref.dart';
import '../../util/dr_app_toast_msg.dart';
import '../../util/helpers.dart';
DrAppSharedPreferances sharedPref = DrAppSharedPreferances();
DrAppToastMsg toastMsg = DrAppToastMsg();
Helpers helpers = Helpers();
class LoginForm extends StatefulWidget with DrAppToastMsg {
LoginForm({
Key key,
@ -126,7 +127,7 @@ class _LoginFormState extends State<LoginForm> {
controller: projectIdController,
onTap: () {
helpers.showCupertinoPicker(
context,projectsList, 'Desciption', onSelectProject);
context, projectsList, 'Desciption', onSelectProject);
},
showCursor: false,
readOnly: true,
@ -151,9 +152,6 @@ class _LoginFormState extends State<LoginForm> {
return 'Please enter your porject';
}
return null;
},
onSaved: (value) {
userInfo.Password = value;
}),
buildSizedBox(),
Row(
@ -175,9 +173,9 @@ class _LoginFormState extends State<LoginForm> {
),
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed(VERIFICATION_METHODS);
// Navigator.of(context).pushNamed(VERIFICATION_METHODS);
// login(context, authProv);
login(context, authProv);
},
textColor: Colors.white,
elevation: 0.0,
@ -221,16 +219,18 @@ class _LoginFormState extends State<LoginForm> {
loginFormKey.currentState.save();
authProv.login(userInfo).then((res) {
if (res['MessageStatus'] == 1) {
insertDeviceImei(res, authProv);
// insertDeviceImei(res, authProv);
saveObjToString('loggedUser', res);
Navigator.of(context).pushNamed(VERIFICATION_METHODS);
} else {
// handel error
// widget.showCenterShortLoadingToast("watting");
showLoginError(res['ErrorEndUserMessage']);
helpers.showErrorToast(res['ErrorEndUserMessage']);
}
// Navigator.of(context).pushNamed(HOME);
}).catchError((err) {
print('$err');
showLoginError();
helpers.showErrorToast();
});
}
}
@ -260,11 +260,11 @@ class _LoginFormState extends State<LoginForm> {
// save imei on shared preferance
} else {
// handel error
showLoginError(res['ErrorEndUserMessage']);
helpers.showErrorToast(res['ErrorEndUserMessage']);
}
}).catchError((err) {
print(err);
showLoginError();
helpers.showErrorToast();
});
}
}
@ -315,15 +315,7 @@ class _LoginFormState extends State<LoginForm> {
});
}
showLoginError([msg = null]) {
String localMsg = 'Something wrong happened, please contact the admin';
if (msg != null) {
localMsg = msg.toString();
}
toastMsg.showErrorToast(localMsg);
}
saveObjToString(String key, value) async {
sharedPref.setObj(key, value);
@ -335,5 +327,4 @@ class _LoginFormState extends State<LoginForm> {
projectIdController.text = projectsList[index]['Desciption'];
});
}
}

@ -1,149 +1,186 @@
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:provider/provider.dart';
import '../../config/size_config.dart';
import '../../providers/auth_provider.dart';
import '../../routes.dart';
import '../../util/dr_app_shared_pref.dart';
import '../../util/dr_app_toast_msg.dart';
import '../../util/helpers.dart';
import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart';
class VerifyAccount extends StatelessWidget {
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
DrAppToastMsg toastMsg = DrAppToastMsg();
Helpers helpers = Helpers();
class VerifyAccount extends StatefulWidget {
@override
_VerifyAccountState createState() => _VerifyAccountState();
}
class _VerifyAccountState extends State<VerifyAccount> {
final verifyAccountForm = GlobalKey<FormState>();
Map verifyAccountFormValue = {
'digit1': null,
'digit2': null,
'digit3': null,
'digit4': null,
};
Future _loggedUserFuture;
var _loggedUser;
@override
void initState() {
super.initState();
_loggedUserFuture = getSharedPref();
}
Future<void> getSharedPref() async {
sharedPref.getObj('loggedUser').then((userInfo) {
_loggedUser = userInfo;
});
}
@override
Widget build(BuildContext context) {
return Form(
key: verifyAccountForm,
child: Container(
width: SizeConfig.realScreenWidth * 0.90,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
buildSizedBox(30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width:SizeConfig.realScreenWidth*0.20,
child: TextFormField(
decoration: InputDecoration(
// ts/images/password_icon.png
contentPadding:
EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(
color: Theme.of(context).primaryColor),
)),
onChanged: (_) {},
)),
Container(
width:SizeConfig.realScreenWidth*0.20,
child: TextFormField(
decoration: InputDecoration(
// ts/images/password_icon.png
contentPadding:
EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(
color: Theme.of(context).primaryColor),
)),
onChanged: (_) {},
)),
Container(
width:SizeConfig.realScreenWidth*0.20,
child: TextFormField(
decoration: InputDecoration(
// ts/images/password_icon.png
contentPadding:
EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
AuthProvider authProv = Provider.of<AuthProvider>(context);
return FutureBuilder(
future: Future.wait([_loggedUserFuture]),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return DrAppCircularProgressIndeicator();
default:
if (snapshot.hasError) {
toastMsg.showErrorToast('Error: ${snapshot.error}');
return Text('Error: ${snapshot.error}');
} else {
return Form(
key: verifyAccountForm,
child: Container(
width: SizeConfig.realScreenWidth * 0.90,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
buildSizedBox(30),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
width: SizeConfig.realScreenWidth * 0.20,
child: TextFormField(
decoration:
buildInputDecoration(context),
onSaved: (val) {
verifyAccountFormValue['digit1'] =
val;
},
validator: validateCodeDigit,
)),
Container(
width: SizeConfig.realScreenWidth * 0.20,
child: TextFormField(
decoration:
buildInputDecoration(context),
onSaved: (val) {
verifyAccountFormValue['digit2'] =
val;
},
validator: validateCodeDigit)),
Container(
width: SizeConfig.realScreenWidth * 0.20,
child: TextFormField(
decoration:
buildInputDecoration(context),
onSaved: (val) {
verifyAccountFormValue['digit3'] =
val;
},
validator: validateCodeDigit)),
Container(
width: SizeConfig.realScreenWidth * 0.20,
child: TextFormField(
decoration:
buildInputDecoration(context),
onSaved: (val) {
verifyAccountFormValue['digit4'] =
val;
},
validator: validateCodeDigit))
],
),
// buildSizedBox(40),
buildSizedBox(20),
buildText(),
// buildSizedBox(10.0),
// Text()
buildSizedBox(40),
// buildSizedBox(),
RaisedButton(
onPressed: () {
verifyAccount(authProv);
// Navigator.of(context).pushNamed(HOME);
},
elevation: 0.0,
child: Container(
width: double.infinity,
height: 50,
child: Center(
child: Text(
'Verfiy'.toUpperCase(),
// textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize:
3 * SizeConfig.textMultiplier),
),
),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(
color: Theme.of(context).primaryColor),
)),
onChanged: (_) {},
)),
Container(
width:SizeConfig.realScreenWidth*0.20,
child: TextFormField(
decoration: InputDecoration(
// ts/images/password_icon.png
contentPadding:
EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side: BorderSide(
width: 0.5,
color: Hexcolor('#CCCCCC'))),
),
buildSizedBox(20),
Center(
child: Text(
"Resend in 4.20",
style: TextStyle(
fontSize: 3.0 * SizeConfig.textMultiplier,
),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(
color: Theme.of(context).primaryColor),
)),
onChanged: (_) {},
))
],
),
// buildSizedBox(40),
buildSizedBox(20),
buildText(),
// buildSizedBox(10.0),
// Text()
buildSizedBox(40),
// buildSizedBox(),
RaisedButton(
onPressed: () {
Navigator.of(context).pushNamed(HOME);
},
elevation: 0.0,
child: Container(
width: double.infinity,
height: 50,
child: Center(
child: Text(
'Verfiy'.toUpperCase(),
// textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 3 * SizeConfig.textMultiplier),
),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
side:
BorderSide(width: 0.5, color: Hexcolor('#CCCCCC'))),
),
buildSizedBox(20),
Center(
child: Text(
"Resend in 4.20",
style: TextStyle(
fontSize: 3.0 * SizeConfig.textMultiplier,
),
),
),
buildSizedBox(10),
])));
),
buildSizedBox(10),
])));
}
}
});
}
String validateCodeDigit(value) {
if (value.isEmpty) {
return 'Please enter your Password';
}
return null;
}
InputDecoration buildInputDecoration(BuildContext context) {
return InputDecoration(
// ts/images/password_icon.png
contentPadding: EdgeInsets.only(top: 30, bottom: 30),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
borderSide: BorderSide(color: Colors.black),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Theme.of(context).primaryColor),
));
}
RichText buildText() {
@ -158,7 +195,7 @@ class VerifyAccount extends StatelessWidget {
style: TextStyle(fontWeight: FontWeight.w700)),
new TextSpan(text: 'By SMS, Please enter the code')
]));
return text;
return text;
}
SizedBox buildSizedBox([double height = 20]) {
@ -166,4 +203,51 @@ class VerifyAccount extends StatelessWidget {
height: height,
);
}
/*
*@author: Elham Rababah
*@Date:15/4/2020
*@param: authProv
*@return:
*@desc: verify Account func call sendActivationCodeByOtpNotificationType service
*/
verifyAccount(AuthProvider authProv) {
if (verifyAccountForm.currentState.validate()) {
verifyAccountForm.currentState.save();
final activationCode = verifyAccountFormValue['digit1'] +
verifyAccountFormValue['digit2'] +
verifyAccountFormValue['digit3'] +
verifyAccountFormValue['digit4'];
print(activationCode);
Map model = {
"activationCode": activationCode,
"DoctorID": _loggedUser['List_MemberInformation'][0]['MemberID'],
"LogInTokenID": _loggedUser['LogInTokenID'],
"ProjectID": 15,
"LanguageID": 2,
"stamp": "2020-02-26T14:48:27.221Z",
"IPAdress": "11.11.11.11",
"VersionID": 1.2,
"Channel": 9,
"TokenID": "",
"SessionID": "i1UJwCTSqt",
"IsLoginForDoctorApp": true,
"IsSilentLogIN": false
};
authProv.sendActivationCodeByOtpNotificationType(model).then((res) {
// Navigator.of(context).pushNamed(VERIFY_ACCOUNT);
if (res['MessageStatus'] == 1) {
Navigator.of(context).pushNamed(VERIFY_ACCOUNT);
} else {
helpers.showErrorToast(res['ErrorEndUserMessage']);
}
}).catchError((err) {
print('$err');
helpers.showErrorToast();
});
}
}
}

@ -1,7 +1,16 @@
import 'package:doctor_app_flutter/config/size_config.dart';
import 'package:doctor_app_flutter/routes.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:provider/provider.dart';
import '../../config/size_config.dart';
import '../../providers/auth_provider.dart';
import '../../routes.dart';
import '../../util/dr_app_shared_pref.dart';
import '../../util/helpers.dart';
import '../../widgets/shared/dr_app_circular_progress_Indeicator.dart';
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();
Helpers helpers = Helpers();
/*
*@author: Elham Rababah
@ -10,86 +19,114 @@ import 'package:hexcolor/hexcolor.dart';
*@return:
*@desc: Verification Methods widget
*/
class VerificationMethods extends StatelessWidget {
MainAxisAlignment spaceBetweenMethods =MainAxisAlignment.spaceBetween;
class VerificationMethods extends StatefulWidget {
@override
_VerificationMethodsState createState() => _VerificationMethodsState();
}
class _VerificationMethodsState extends State<VerificationMethods> {
MainAxisAlignment spaceBetweenMethods = MainAxisAlignment.spaceBetween;
Future _loggedUserFuture;
var _loggedUser;
@override
void initState() {
super.initState();
_loggedUserFuture = getSharedPref();
}
Future<void> getSharedPref() async {
sharedPref.getObj('loggedUser').then((userInfo) {
_loggedUser = userInfo;
});
}
@override
Widget build(BuildContext context) {
// if(!SizeConfig.isMobile) {
// spaceBetweenMethods = MainAxisAlignment.spaceAround;
// }
return Container(
width: SizeConfig.realScreenWidth * 0.90,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Please choose one of the Following option to verify",
style: TextStyle(
fontSize: 3.5 * SizeConfig.textMultiplier,
),
),
SizedBox(
height: 40,
),
Container(
width: SizeConfig.realScreenWidth * 80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: spaceBetweenMethods,
children: <Widget>[
buildVerificationMethod(context,
'assets/images/verification_fingerprint_icon.png',
'Fingerprint',
() {}),
buildVerificationMethod(context,
'assets/images/verification_faceid_icon.png',
'Face ID',
() {}),
],
),
SizedBox(
height: 40,
),
Row(
mainAxisAlignment: spaceBetweenMethods,
children: <Widget>[
buildVerificationMethod(context,
'assets/images/verification_whatsapp_icon.png',
'WhatsApp',
() {}),
buildVerificationMethod(context,
'assets/images/verification_sms_icon.png',
'SMS',
() {}),
],
)
],
),
),
SizedBox(
height: SizeConfig.heightMultiplier * 2,
)
],
),
);
AuthProvider authProv = Provider.of<AuthProvider>(context);
return FutureBuilder(
future: Future.wait([_loggedUserFuture]),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return DrAppCircularProgressIndeicator();
default:
if (snapshot.hasError) {
helpers.showErrorToast('Error: ${snapshot.error}');
return Text('Error: ${snapshot.error}');
} else {
return Container(
width: SizeConfig.realScreenWidth * 0.90,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Please choose one of the Following option to verify",
style: TextStyle(
fontSize: 3.5 * SizeConfig.textMultiplier,
),
),
SizedBox(
height: 40,
),
Container(
width: SizeConfig.realScreenWidth * 80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: spaceBetweenMethods,
children: <Widget>[
buildVerificationMethod(
context,
'assets/images/verification_fingerprint_icon.png',
'Fingerprint',
() {}),
buildVerificationMethod(
context,
'assets/images/verification_faceid_icon.png',
'Face ID',
() {}),
],
),
SizedBox(
height: 40,
),
Row(
mainAxisAlignment: spaceBetweenMethods,
children: <Widget>[
buildVerificationMethod(
context,
'assets/images/verification_whatsapp_icon.png',
'WhatsApp', () {
sendActivationCodeByOtpNotificationType(
2, authProv);
}),
buildVerificationMethod(
context,
'assets/images/verification_sms_icon.png',
'SMS', () {
sendActivationCodeByOtpNotificationType(
1, authProv);
}),
],
)
],
),
),
SizedBox(
height: SizeConfig.heightMultiplier * 2,
)
],
),
);
}
}
});
}
/*
*@author: Elham Rababah
*@Date:07/4/2020
*@param: url , dec, fun
*@return: InkWell widget
*@desc: Build Verification Method
*/
InkWell buildVerificationMethod(context,url, dec, fun) {
InkWell buildVerificationMethod(context, url, dec, Function fun) {
return InkWell(
onTap: (){
Navigator.of(context).pushNamed(VERIFY_ACCOUNT);
},
onTap: fun,
child: Container(
// height: SizeConfig.heightMultiplier *2,
height: SizeConfig.heightMultiplier * 19,
@ -117,10 +154,54 @@ class VerificationMethods extends StatelessWidget {
SizedBox(
height: 10,
),
Text(dec, style: TextStyle(fontSize:SizeConfig.textMultiplier*2 ),)
Text(
dec,
style: TextStyle(fontSize: SizeConfig.textMultiplier * 2),
)
],
),
),
);
}
/*
*@author: Elham Rababah
*@Date:15/4/2020
*@param: oTPSendType
*@return:
*@desc: send Activation Code By Otp Notification Type
*/
sendActivationCodeByOtpNotificationType(oTPSendType, AuthProvider authProv) {
// TODO : build enum for verfication method
if (oTPSendType == 1 || oTPSendType == 2) {
Map model = {
"LogInTokenID": _loggedUser['LogInTokenID'],
"Channel": 9,
"MobileNumber": _loggedUser['MobileNumber'],
"IPAdress": "11.11.11.11",
"LanguageID": 2,
"ProjectID": 15, //TODO : this should become daynamci
"ZipCode": _loggedUser['ZipCode'],
"UserName": _loggedUser['List_MemberInformation'][0]['MemberID'],
"OTP_SendType": oTPSendType
};
print('$_loggedUser');
print(oTPSendType);
authProv.sendActivationCodeByOtpNotificationType(model).then((res) {
Navigator.of(context).pushNamed(VERIFY_ACCOUNT);
if (res['MessageStatus'] == 1) {
Navigator.of(context).pushNamed(VERIFY_ACCOUNT);
} else {
helpers.showErrorToast(res['ErrorEndUserMessage']);
}
// Navigator.of(context).pushNamed(HOME);
}).catchError((err) {
print('$err');
helpers.showErrorToast();
});
} else {
// TODO route to this page with parameters to inicate we should present 2 option
}
}
}

Loading…
Cancel
Save