API's implemented

fatima
devmirza121 4 years ago
parent 0c5d43c04b
commit 2d7ef46d27

@ -1,5 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.car_customer_app"> package="com.example.car_customer_app">
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:label="car_customer_app" android:label="car_customer_app"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">

@ -67,9 +67,13 @@ class ApiClient {
} }
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes); var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes);
try { try {
if (!kReleaseMode) {
print("res:"+response.body);
}
var jsonData = jsonDecode(response.body); var jsonData = jsonDecode(response.body);
return factoryConstructor(jsonData); return factoryConstructor(jsonData);
} catch (ex) { } catch (ex) {
print("exception:"+response.body);
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex); throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
} }
} }
@ -104,8 +108,13 @@ class ApiClient {
url = url + '?' + queryString; url = url + '?' + queryString;
} }
var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 15)); var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 15));
if (!kReleaseMode) {
if (response.statusCode >= 200 && response.statusCode < 300) { print("Url:$url");
print("body:$requestBody");
print("res: "+ response.body);
}
if (response.statusCode >= 200 && response.statusCode < 500) {
return response; return response;
} else { } else {
throw _throwAPIException(response); throw _throwAPIException(response);

@ -0,0 +1,34 @@
import 'dart:async';
import 'package:shared_preferences/shared_preferences.dart';
class SharedPrefManager {
static String USER_ID = "user.id";
static String USER_TOKEN = "user.token";
static Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
static setUserId(String cookie) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(USER_ID, cookie) ?? "NA";
}
static Future<String> getUserId() async {
SharedPreferences prefs = await _prefs;
return prefs.getString(USER_ID) ?? "";
}
static setUserToken(String cookie) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(USER_TOKEN, cookie) ?? "NA";
}
static Future<String> getUserToken() async {
SharedPreferences prefs = await _prefs;
return prefs.getString(USER_TOKEN) ?? "";
}
}

@ -15,19 +15,19 @@ class TangheemUserApiClient {
factory TangheemUserApiClient() => _instance; factory TangheemUserApiClient() => _instance;
Future<SurahModel> getSurahs() async { Future<SurahModel> getSurahs() async {
String url = "${ApiConsts.tangheemUsers}AlSuar_Get"; String url = "${ApiConsts.baseUrl}AlSuar_Get";
var postParams = {}; var postParams = {};
return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams); return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams);
} }
Future<MemberModel> getMembers() async { Future<MemberModel> getMembers() async {
String url = "${ApiConsts.tangheemUsers}Committee_Get"; String url = "${ApiConsts.baseUrl}Committee_Get";
var postParams = {}; var postParams = {};
return await ApiClient().postJsonForObject((json) => MemberModel.fromJson(json), url, postParams); return await ApiClient().postJsonForObject((json) => MemberModel.fromJson(json), url, postParams);
} }
Future<ContentInfoModel> getContentInfo(int contentId) async { Future<ContentInfoModel> getContentInfo(int contentId) async {
String url = "${ApiConsts.tangheemUsers}ContentInfo_Get"; String url = "${ApiConsts.baseUrl}ContentInfo_Get";
var postParams = {"contentTypeId": contentId}; var postParams = {"contentTypeId": contentId};
return await ApiClient().postJsonForObject((json) => ContentInfoModel.fromJson(json), url, postParams); return await ApiClient().postJsonForObject((json) => ContentInfoModel.fromJson(json), url, postParams);
} }

@ -0,0 +1,70 @@
import 'dart:async';
import 'package:http/http.dart';
import 'package:car_customer_app/classes/consts.dart';
import 'package:car_customer_app/models/content_info_model.dart';
import 'package:car_customer_app/models/member_model.dart';
import 'package:car_customer_app/models/surah_model.dart';
import 'package:car_customer_app/models/user/basic_otp.dart';
import 'package:car_customer_app/models/user/register_user.dart';
import 'api_client.dart';
class UserApiClent {
static final UserApiClent _instance = UserApiClent._internal();
UserApiClent._internal();
factory UserApiClent() => _instance;
Future<BasicOtp> basicOtp(String phoneNo,{int otpType=1}) async {
var postParams = {"countryID": 1, "userMobileNo": phoneNo, "otpType": otpType, "userRole": 4};
return await ApiClient().postJsonForObject((json) => BasicOtp.fromJson(json), ApiConsts.BasicOTP, postParams);
}
Future<RegisterUser> basicVerify(String phoneNo, String otp, String userToken) async {
var postParams = {
"userMobileNo": phoneNo,
"userOTP": otp,
"userToken": userToken,
};
return await ApiClient().postJsonForObject((json) => RegisterUser.fromJson(json), ApiConsts.BasicVerify, postParams);
}
Future<RegisterUser> basicComplete(String userId, String firstName, String lastName,String email,String password) async {
var postParams = {
"userID": userId,
"firstName": firstName,
"lastName": lastName,
"email": email,
"companyName": "string",
"isEmailVerified": true,
"password": password
};
return await ApiClient().postJsonForObject((json) => RegisterUser.fromJson(json), ApiConsts.BasicComplete, postParams);
}
Future<Response> login_V1(String phoneNo, String password) async {
var postParams = {
"mobileorEmail": phoneNo,
"password": password,
};
return await ApiClient().postJsonForResponse(ApiConsts.Login_V1, postParams);
//return await ApiClient().postJsonForObject((json) => BasicOtp.fromJson(json), ApiConsts.Login_V1, postParams);
}
Future<Response> login_V2_OTP(String userToken, String loginType) async {
var postParams = {
"userToken": userToken,
"loginType": loginType,
};
return await ApiClient().postJsonForResponse(ApiConsts.Login_V2_OTP, postParams);
}
Future<Response> login_V2_OTPVerify(String userToken, String otp) async {
var postParams = {
"userToken": userToken,
"userOTP": otp
};
return await ApiClient().postJsonForResponse(ApiConsts.Login_V2_OTPVerify, postParams);
}
}

@ -1,14 +1,19 @@
class ApiConsts { class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server //static String baseUrl = "http://10.200.204.20:2801/"; // Local server
static String baseUrl = "http://20.203.25.82"; // production server static String baseUrl = "https://mdlaboratories.com"; // production server
static String baseUrlServices = baseUrl + "/services/"; // production server static String baseUrlServices = baseUrl + "/mc/"; // production server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String authentication = baseUrlServices + "api/Authentication/"; static String BasicOTP = baseUrlServices + "api/Register/BasicOTP";
static String tangheemUsers = baseUrlServices + "api/TangheemUsers/"; static String BasicVerify = baseUrlServices + "api/Register/BasicVerify";
static String adminConfiguration = baseUrlServices + "api/AdminConfiguration/"; static String BasicComplete = baseUrlServices + "api/Register/BasicComplete";
static String Login_V1 = baseUrlServices + "api/Account/Login_V1";
static String Login_V2_OTP = baseUrlServices + "api/Account/Login_V2_OTP";
static String Login_V2_OTPVerify = baseUrlServices + "api/Account/Login_V2_OTPVerify";
static String user = baseUrlServices + "api/User/"; static String user = baseUrlServices + "api/User/";
} }
class GlobalConsts { class GlobalConsts {
static String isRememberMe = "remember_me"; static String isRememberMe = "remember_me";
static String email = "email"; static String email = "email";

@ -1,16 +1,17 @@
import 'package:car_customer_app/widgets/loading_dialog.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// import 'package:fluttertoast/fluttertoast.dart'; // import 'package:fluttertoast/fluttertoast.dart';
import 'package:car_customer_app/exceptions/api_exception.dart'; import 'package:car_customer_app/exceptions/api_exception.dart';
import 'package:fluttertoast/fluttertoast.dart';
class Utils { class Utils {
static bool _isLoadingVisible = false; static bool _isLoadingVisible = false;
static bool get isLoading => _isLoadingVisible; static bool get isLoading => _isLoadingVisible;
static void showToast(String message) { static void showToast(String message) {
// Fluttertoast.showToast( Fluttertoast.showToast(
// msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0); msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0);
} }
static dynamic getNotNullValue(List<dynamic> list, int index) { static dynamic getNotNullValue(List<dynamic> list, int index) {
@ -32,13 +33,13 @@ class Utils {
static void showLoading(BuildContext context) { static void showLoading(BuildContext context) {
WidgetsBinding.instance?.addPostFrameCallback((_) { WidgetsBinding.instance?.addPostFrameCallback((_) {
_isLoadingVisible = true; _isLoadingVisible = true;
// showDialog( showDialog(
// context: context, context: context,
// barrierColor: ColorConsts.primaryBlack.withOpacity(0.5), barrierColor: Colors.black.withOpacity(0.5),
// builder: (BuildContext context) => LoadingDialog(), builder: (BuildContext context) => LoadingDialog(),
// ).then((value) { ).then((value) {
// _isLoadingVisible = false; _isLoadingVisible = false;
// }); });
}); });
} }

@ -1,8 +1,11 @@
import 'package:car_customer_app/models/user/register_user.dart';
import 'package:car_customer_app/pages/dashboard/dashboard_page.dart'; import 'package:car_customer_app/pages/dashboard/dashboard_page.dart';
import 'package:car_customer_app/pages/user/complete_profile_page.dart'; import 'package:car_customer_app/pages/user/complete_profile_page.dart';
import 'package:car_customer_app/pages/user/forget_password_page.dart'; import 'package:car_customer_app/pages/user/forget_password_page.dart';
import 'package:car_customer_app/pages/user/login_method_selection_page.dart';
import 'package:car_customer_app/pages/user/login_verification_page.dart'; import 'package:car_customer_app/pages/user/login_verification_page.dart';
import 'package:car_customer_app/pages/user/login_verify_account_page.dart'; import 'package:car_customer_app/pages/user/login_verify_account_page.dart';
import 'package:car_customer_app/pages/user/login_with_password_page.dart';
import 'package:car_customer_app/pages/user/register_page.dart'; import 'package:car_customer_app/pages/user/register_page.dart';
import 'package:car_customer_app/pages/user/register_selection_page.dart'; import 'package:car_customer_app/pages/user/register_selection_page.dart';
import 'package:car_customer_app/pages/user/splash_page.dart'; import 'package:car_customer_app/pages/user/splash_page.dart';
@ -16,10 +19,11 @@ class AppRoutes {
static final String register = "/register"; static final String register = "/register";
static final String forgetPassword = "/forgetPassword"; static final String forgetPassword = "/forgetPassword";
static final String loginVerification = "/loginVerification"; static final String loginVerification = "/loginVerification";
static final String dashboard = "/dashboard"; static final String loginWithPassword = "/loginWithPassword";
static final String loginMethodSelection = "/loginMethodSelection";
static final String completeProfile = "/completeProfile"; static final String completeProfile = "/completeProfile";
static final String dashboard = "/dashboard";
static final String initialRoute = splash; static final String initialRoute = splash;
@ -31,7 +35,11 @@ class AppRoutes {
register: (context) => RegisterPage(), register: (context) => RegisterPage(),
forgetPassword: (context) => ForgetPasswordPage(), forgetPassword: (context) => ForgetPasswordPage(),
loginVerification: (context) => LoginVerificationPage(), loginVerification: (context) => LoginVerificationPage(),
loginWithPassword: (context) => LoginWithPassword(),
loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String),
completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUser),
//Home page
dashboard: (context) => DashboardPage(), dashboard: (context) => DashboardPage(),
completeProfile: (context) => CompleteProfilePage(),
}; };
} }

@ -1,9 +0,0 @@
class User {
int id;
User(this.id, this.userName, this.userImage, this.createdDate);
String userName;
String userImage;
String createdDate;
}

@ -0,0 +1,61 @@
// To parse this JSON data, do
//
// final basicOtp = basicOtpFromJson(jsonString);
import 'dart:convert';
BasicOtp basicOtpFromJson(String str) => BasicOtp.fromJson(json.decode(str));
String basicOtpToJson(BasicOtp data) => json.encode(data.toJson());
class BasicOtp {
BasicOtp({
this.totalItemsCount,
this.data,
this.messageStatus,
this.message,
});
dynamic totalItemsCount;
Data? data;
int? messageStatus;
String? message;
factory BasicOtp.fromJson(Map<String, dynamic> json) => BasicOtp(
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : Data.fromJson(json["data"]),
messageStatus: json["messageStatus"] == null ? null : json["messageStatus"],
message: json["message"] == null ? null : json["message"],
);
Map<String, dynamic> toJson() => {
"totalItemsCount": totalItemsCount,
"data": data == null ? null : data!.toJson(),
"messageStatus": messageStatus == null ? null : messageStatus,
"message": message == null ? null : message,
};
}
class Data {
Data({
this.userToken,
});
String? userToken;
factory Data.fromJson(Map<String, dynamic> json) => Data(
userToken: checkValue(json),
);
static String checkValue(Map<String, dynamic> json) {
try {
return json["userToken"] == null ? null : json["userToken"];
} catch (e) {
return json["token"] == null ? null : json["token"];
}
}
Map<String, dynamic> toJson() => {
"userToken": userToken == null ? null : userToken,
};
}

@ -0,0 +1,117 @@
// To parse this JSON data, do
//
// final user = userFromMap(jsonString);
import 'dart:convert';
RegisterUser userFromMap(String str) => RegisterUser.fromJson(json.decode(str));
String userToMap(RegisterUser data) => json.encode(data.toMap());
class RegisterUser {
RegisterUser({
this.totalItemsCount,
this.data,
this.messageStatus,
this.message,
});
dynamic totalItemsCount;
Data? data;
int? messageStatus;
String? message;
factory RegisterUser.fromJson(Map<String, dynamic> json) => RegisterUser(
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : Data.fromMap(json["data"]),
messageStatus: json["messageStatus"] == null ? null : json["messageStatus"],
message: json["message"] == null ? null : json["message"],
);
Map<String, dynamic> toMap() => {
"totalItemsCount": totalItemsCount,
"data": data == null ? null : data!.toMap(),
"messageStatus": messageStatus == null ? null : messageStatus,
"message": message == null ? null : message,
};
}
class Data {
Data({
this.id,
this.userId,
this.firstName,
this.lastName,
this.mobileNo,
this.email,
this.userImageUrl,
this.roleId,
this.roleName,
this.isEmailVerified,
this.serviceProviderBranch,
this.isVerified,
this.userRoles,
this.isCustomer,
this.isProvider,
this.providerId,
this.customerId,
});
int? id;
String? userId;
dynamic? firstName;
dynamic? lastName;
String? mobileNo;
String? email;
dynamic? userImageUrl;
int? roleId;
dynamic? roleName;
bool? isEmailVerified;
List<dynamic>? serviceProviderBranch;
bool? isVerified;
List<dynamic>? userRoles;
bool? isCustomer;
bool? isProvider;
dynamic? providerId;
dynamic? customerId;
factory Data.fromMap(Map<String, dynamic> json) => Data(
id: json["id"] == null ? null : json["id"],
userId: json["userID"] == null ? null : json["userID"],
firstName: json["firstName"],
lastName: json["lastName"],
mobileNo: json["mobileNo"] == null ? null : json["mobileNo"],
email: json["email"] == null ? null : json["email"],
userImageUrl: json["userImageUrl"],
roleId: json["roleID"] == null ? null : json["roleID"],
roleName: json["roleName"],
isEmailVerified: json["isEmailVerified"] == null ? null : json["isEmailVerified"],
serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<dynamic>.from(json["serviceProviderBranch"].map((x) => x)),
isVerified: json["isVerified"] == null ? null : json["isVerified"],
userRoles: json["userRoles"] == null ? null : List<dynamic>.from(json["userRoles"].map((x) => x)),
isCustomer: json["isCustomer"] == null ? null : json["isCustomer"],
isProvider: json["isProvider"] == null ? null : json["isProvider"],
providerId: json["providerID"],
customerId: json["customerID"],
);
Map<String, dynamic> toMap() => {
"id": id == null ? null : id,
"userID": userId == null ? null : userId,
"firstName": firstName,
"lastName": lastName,
"mobileNo": mobileNo == null ? null : mobileNo,
"email": email == null ? null : email,
"userImageUrl": userImageUrl,
"roleID": roleId == null ? null : roleId,
"roleName": roleName,
"isEmailVerified": isEmailVerified == null ? null : isEmailVerified,
"serviceProviderBranch": serviceProviderBranch == null ? null : List<dynamic>.from(serviceProviderBranch!.map((x) => x)),
"isVerified": isVerified == null ? null : isVerified,
"userRoles": userRoles == null ? null : List<dynamic>.from(userRoles!.map((x) => x)),
"isCustomer": isCustomer == null ? null : isCustomer,
"isProvider": isProvider == null ? null : isProvider,
"providerID": providerId,
"customerID": customerId,
};
}

@ -0,0 +1,117 @@
// To parse this JSON data, do
//
// final user = userFromMap(jsonString);
import 'dart:convert';
User userFromMap(String str) => User.fromMap(json.decode(str));
String userToMap(User data) => json.encode(data.toMap());
class User {
User({
this.accessToken,
this.refreshToken,
this.expiryDate,
this.userInfo,
});
String? accessToken;
String? refreshToken;
DateTime? expiryDate;
UserInfo? userInfo;
factory User.fromMap(Map<String, dynamic> json) => User(
accessToken: json["accessToken"] == null ? null : json["accessToken"],
refreshToken: json["refreshToken"] == null ? null : json["refreshToken"],
expiryDate: json["expiryDate"] == null ? null : DateTime.parse(json["expiryDate"]),
userInfo: json["userInfo"] == null ? null : UserInfo.fromMap(json["userInfo"]),
);
Map<String, dynamic> toMap() => {
"accessToken": accessToken == null ? null : accessToken,
"refreshToken": refreshToken == null ? null : refreshToken,
"expiryDate": expiryDate == null ? null : expiryDate!.toIso8601String(),
"userInfo": userInfo == null ? null : userInfo!.toMap(),
};
}
class UserInfo {
UserInfo({
this.id,
this.userId,
this.firstName,
this.lastName,
this.mobileNo,
this.email,
this.userImageUrl,
this.roleId,
this.roleName,
this.isEmailVerified,
this.serviceProviderBranch,
this.isVerified,
this.userRoles,
this.isCustomer,
this.isProvider,
this.providerId,
this.customerId,
});
int? id;
String? userId;
String? firstName;
String? lastName;
String? mobileNo;
String? email;
dynamic? userImageUrl;
int? roleId;
String? roleName;
bool? isEmailVerified;
List<dynamic>? serviceProviderBranch;
bool? isVerified;
List<dynamic>? userRoles;
bool? isCustomer;
bool? isProvider;
dynamic? providerId;
int? customerId;
factory UserInfo.fromMap(Map<String, dynamic> json) => UserInfo(
id: json["id"] == null ? null : json["id"],
userId: json["userID"] == null ? null : json["userID"],
firstName: json["firstName"] == null ? null : json["firstName"],
lastName: json["lastName"] == null ? null : json["lastName"],
mobileNo: json["mobileNo"] == null ? null : json["mobileNo"],
email: json["email"] == null ? null : json["email"],
userImageUrl: json["userImageUrl"],
roleId: json["roleID"] == null ? null : json["roleID"],
roleName: json["roleName"] == null ? null : json["roleName"],
isEmailVerified: json["isEmailVerified"] == null ? null : json["isEmailVerified"],
serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<dynamic>.from(json["serviceProviderBranch"].map((x) => x)),
isVerified: json["isVerified"] == null ? null : json["isVerified"],
userRoles: json["userRoles"] == null ? null : List<dynamic>.from(json["userRoles"].map((x) => x)),
isCustomer: json["isCustomer"] == null ? null : json["isCustomer"],
isProvider: json["isProvider"] == null ? null : json["isProvider"],
providerId: json["providerID"],
customerId: json["customerID"] == null ? null : json["customerID"],
);
Map<String, dynamic> toMap() => {
"id": id == null ? null : id,
"userID": userId == null ? null : userId,
"firstName": firstName == null ? null : firstName,
"lastName": lastName == null ? null : lastName,
"mobileNo": mobileNo == null ? null : mobileNo,
"email": email == null ? null : email,
"userImageUrl": userImageUrl,
"roleID": roleId == null ? null : roleId,
"roleName": roleName == null ? null : roleName,
"isEmailVerified": isEmailVerified == null ? null : isEmailVerified,
"serviceProviderBranch": serviceProviderBranch == null ? null : List<dynamic>.from(serviceProviderBranch!.map((x) => x)),
"isVerified": isVerified == null ? null : isVerified,
"userRoles": userRoles == null ? null : List<dynamic>.from(userRoles!.map((x) => x)),
"isCustomer": isCustomer == null ? null : isCustomer,
"isProvider": isProvider == null ? null : isProvider,
"providerID": providerId,
"customerID": customerId == null ? null : customerId,
};
}

@ -1,5 +1,13 @@
import 'package:car_customer_app/api/user_api_client.dart';
import 'package:car_customer_app/classes/utils.dart';
import 'package:car_customer_app/models/user/basic_otp.dart';
import 'package:car_customer_app/models/user/register_user.dart';
import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/utils/utils.dart';
import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/app_bar.dart';
import 'package:car_customer_app/widgets/dialog/dialogs.dart';
import 'package:car_customer_app/widgets/dialog/message_dialog.dart';
import 'package:car_customer_app/widgets/dialog/otp_dialog.dart';
import 'package:car_customer_app/widgets/show_fill_button.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart';
import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/extensions/widget_extensions.dart';
import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:car_customer_app/extensions/int_extensions.dart';
@ -7,7 +15,24 @@ import 'package:car_customer_app/extensions/string_extensions.dart';
import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:car_customer_app/widgets/txt_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CompleteProfilePage extends StatelessWidget { class CompleteProfilePage extends StatefulWidget {
RegisterUser user;
CompleteProfilePage(this.user);
@override
State<CompleteProfilePage> createState() => _CompleteProfilePageState();
}
class _CompleteProfilePageState extends State<CompleteProfilePage> {
String? firstName = "", lastName = "", email = "", password = "", confirmPassword = "";
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -21,38 +46,55 @@ class CompleteProfilePage extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
"Complete Profile".toText24(), "Complete Profile".toText24(),
12.height, 12.height,
TxtField( TxtField(
hint: "First Name", hint: "First Name",
onChanged: (v) {
firstName = v;
},
), ),
12.height, 12.height,
TxtField( TxtField(
hint: "Surname", hint: "Surname",
onChanged: (v) {
lastName = v;
},
), ),
12.height, 12.height,
TxtField( TxtField(
hint: "Email", hint: "Email",
onChanged: (v) {
email = v;
},
), ),
12.height, 12.height,
TxtField( TxtField(
hint: "Create Password", hint: "Create Password",
onChanged: (v) {
password = v;
},
), ),
12.height, 12.height,
TxtField( TxtField(
hint: "Confirm Password", hint: "Confirm Password",
onChanged: (v) {
confirmPassword = v;
},
), ),
12.height, // 12.height,
TxtField( // TxtField(
hint: "Phone Number", // hint: "Phone Number",
), // ),
50.height, 50.height,
"By creating an account you agree to our Terms of Service and Privacy Policy".toText12(), "By creating an account you agree to our Terms of Service and Privacy Policy".toText12(),
16.height, 16.height,
ShowFillButton( ShowFillButton(
title: "Continue", title: "Continue",
width: double.infinity, width: double.infinity,
onPressed: () {}, onPressed: () {
performCompleteProfile();
},
), ),
], ],
), ),
@ -61,4 +103,21 @@ class CompleteProfilePage extends StatelessWidget {
), ),
); );
} }
Future<void> performCompleteProfile() async {
if (password == confirmPassword) {
print(widget.user.data!.userId??"userId");
Utils.showLoading(context);
RegisterUser user = await UserApiClent().basicComplete(widget.user.data?.userId ?? "", firstName!, lastName!, email!, password!);
Utils.hideLoading(context);
if (user.messageStatus == 1) {
Utils.showToast(user.message ?? "");
} else {
Utils.showToast(user.message ?? "");
}
} else {
Utils.showToast("Please enter same password");
}
}
} }

@ -0,0 +1,122 @@
import 'dart:convert';
import 'package:car_customer_app/api/shared_prefrence.dart';
import 'package:car_customer_app/api/user_api_client.dart';
import 'package:car_customer_app/classes/utils.dart';
import 'package:car_customer_app/config/constants.dart';
import 'package:car_customer_app/config/routes.dart';
import 'package:car_customer_app/models/user/user.dart';
import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart';
import 'package:car_customer_app/widgets/app_bar.dart';
import 'package:car_customer_app/widgets/button/show_image_button.dart';
import 'package:car_customer_app/widgets/dialog/dialogs.dart';
import 'package:car_customer_app/widgets/dialog/message_dialog.dart';
import 'package:car_customer_app/extensions/int_extensions.dart';
import 'package:car_customer_app/extensions/string_extensions.dart';
import 'package:car_customer_app/extensions/widget_extensions.dart';
import 'package:car_customer_app/widgets/dialog/otp_dialog.dart';
import 'package:car_customer_app/widgets/txt_field.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class LoginMethodSelectionPage extends StatelessWidget {
String userToken;
LoginMethodSelectionPage(this.userToken);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBar(title: "Log In"),
body: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40),
child: Column(
children: [
"Login Selection".toText24(),
mFlex(2),
Row(
children: [
Expanded(
child: ShowImageButton(
onClick: () {
performBasicOtp(context);
},
title: 'Finger Print',
icon: icons + "ic_fingerprint.png",
),
),
20.width,
Expanded(
child: ShowImageButton(
onClick: () {
performBasicOtp(context);
},
title: 'Face Recognition',
icon: icons + "ic_face_id.png",
),
),
],
),
40.height,
Row(
children: [
Expanded(
child: ShowImageButton(
onClick: () {
performBasicOtp(context);
},
title: 'With SMS',
icon: icons + "ic_sms.png",
),
),
20.width,
Expanded(
child: ShowImageButton(
onClick: () {
// navigateWithName(context, AppRoutes.dashboard);
performBasicOtp(context);
},
title: 'With Whatsapp',
icon: icons + "ic_whatsapp.png",
),
),
],
),
mFlex(10),
],
),
),
);
}
Future<void> performBasicOtp(BuildContext context) async {
Utils.showLoading(context);
Response response = await UserApiClent().login_V2_OTP(userToken, "1");
Utils.hideLoading(context);
if (response.statusCode == 200) {
String userToken = jsonDecode(response.body)["token"];
showMDialog(context, child: OtpDialog(
onClick: (String code) async {
pop(context);
Utils.showLoading(context);
Response response2 = await UserApiClent().login_V2_OTPVerify(userToken, code);
Utils.hideLoading(context);
if (response2.statusCode == 200) {
User user = User.fromMap(jsonDecode(response2.body));
SharedPrefManager.setUserToken(user.accessToken ?? "");
SharedPrefManager.setUserId(user.userInfo!.userId ?? "");
navigateWithName(context, AppRoutes.dashboard);
} else {
Utils.showToast("Something went wrong");
}
},
));
} else {
String res = jsonDecode(response.body)["errors"][0] ?? "";
Utils.showToast(res);
}
}
}

@ -1,5 +1,11 @@
import 'dart:convert';
import 'package:car_customer_app/api/shared_prefrence.dart';
import 'package:car_customer_app/api/user_api_client.dart';
import 'package:car_customer_app/classes/utils.dart';
import 'package:car_customer_app/config/constants.dart'; import 'package:car_customer_app/config/constants.dart';
import 'package:car_customer_app/config/routes.dart'; import 'package:car_customer_app/config/routes.dart';
import 'package:car_customer_app/models/user/user.dart';
import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/utils/utils.dart';
import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/app_bar.dart';
@ -9,8 +15,10 @@ import 'package:car_customer_app/widgets/dialog/message_dialog.dart';
import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:car_customer_app/extensions/int_extensions.dart';
import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/extensions/string_extensions.dart';
import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/extensions/widget_extensions.dart';
import 'package:car_customer_app/widgets/dialog/otp_dialog.dart';
import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:car_customer_app/widgets/txt_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart';
class LoginVerificationPage extends StatelessWidget { class LoginVerificationPage extends StatelessWidget {
@override @override
@ -31,16 +39,7 @@ class LoginVerificationPage extends StatelessWidget {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
showMDialog( performBasicOtp(context);
context,
child: MessageDialog(
title: "Account Verified",
onClick: () {
pop(context);
navigateWithName(context, AppRoutes.dashboard);
},
),
);
}, },
title: 'Finger Print', title: 'Finger Print',
icon: icons + "ic_fingerprint.png", icon: icons + "ic_fingerprint.png",
@ -50,7 +49,7 @@ class LoginVerificationPage extends StatelessWidget {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
navigateWithName(context, AppRoutes.dashboard); performBasicOtp(context);
}, },
title: 'Face Recognition', title: 'Face Recognition',
icon: icons + "ic_face_id.png", icon: icons + "ic_face_id.png",
@ -64,7 +63,7 @@ class LoginVerificationPage extends StatelessWidget {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
navigateWithName(context, AppRoutes.dashboard); performBasicOtp(context);
}, },
title: 'With SMS', title: 'With SMS',
icon: icons + "ic_sms.png", icon: icons + "ic_sms.png",
@ -74,7 +73,7 @@ class LoginVerificationPage extends StatelessWidget {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
navigateWithName(context, AppRoutes.dashboard); performBasicOtp(context);
}, },
title: 'With Whatsapp', title: 'With Whatsapp',
icon: icons + "ic_whatsapp.png", icon: icons + "ic_whatsapp.png",
@ -88,4 +87,33 @@ class LoginVerificationPage extends StatelessWidget {
), ),
); );
} }
Future<void> performBasicOtp(BuildContext context) async {
Utils.showLoading(context);
String userToken=await SharedPrefManager.getUserToken();
Response response = await UserApiClent().login_V2_OTP(userToken, "1");
Utils.hideLoading(context);
if (response.statusCode == 200) {
String userToken = jsonDecode(response.body)["token"];
showMDialog(context, child: OtpDialog(
onClick: (String code) async {
pop(context);
Utils.showLoading(context);
Response response2 = await UserApiClent().login_V2_OTPVerify(userToken, code);
Utils.hideLoading(context);
if (response2.statusCode == 200) {
User user = User.fromMap(jsonDecode(response2.body));
SharedPrefManager.setUserToken(user.accessToken ?? "");
SharedPrefManager.setUserId(user.userInfo!.userId ?? "");
navigateWithName(context, AppRoutes.dashboard);
} else {
Utils.showToast("Something went wrong");
}
},
));
} else {
String res = jsonDecode(response.body)["errors"][0] ?? "";
Utils.showToast(res);
}
}
} }

@ -1,5 +1,9 @@
import 'package:car_customer_app/api/user_api_client.dart';
import 'package:car_customer_app/classes/utils.dart';
import 'package:car_customer_app/config/constants.dart'; import 'package:car_customer_app/config/constants.dart';
import 'package:car_customer_app/config/routes.dart'; import 'package:car_customer_app/config/routes.dart';
import 'package:car_customer_app/models/user/basic_otp.dart';
import 'package:car_customer_app/models/user/register_user.dart';
import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/utils/utils.dart';
import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/app_bar.dart';
@ -14,6 +18,9 @@ import 'package:car_customer_app/widgets/txt_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class LoginVerifyAccountPage extends StatelessWidget { class LoginVerifyAccountPage extends StatelessWidget {
int otpType = 1;
String phoneNum = "";
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -28,6 +35,9 @@ class LoginVerifyAccountPage extends StatelessWidget {
mFlex(1), mFlex(1),
TxtField( TxtField(
hint: "Enter Phone number to verify", hint: "Enter Phone number to verify",
onChanged: (v) {
phoneNum = v;
},
), ),
mFlex(2), mFlex(2),
Row( Row(
@ -35,22 +45,26 @@ class LoginVerifyAccountPage extends StatelessWidget {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
showMDialog(context, child: OtpDialog( otpType = 1;
onClick: () { performBasicOtp(context);
pop(context); // showMDialog(context, child: OtpDialog(
delay(300).then( // onClick: (String code) {
(value) => showMDialog( // pop(context);
context, // delay(300).then(
child: MessageDialog( // (value) => showMDialog(
title: "Phone Number Verified", // context,
onClick: () { // child: MessageDialog(
navigateWithName(context, AppRoutes.completeProfile); // title: "Phone Number Verified",
}, // onClick: () {
), // otpType=1;
), // performBasicOtp(context);
); // // navigateWithName(context, AppRoutes.completeProfile);
}, // },
)); // ),
// ),
// );
// },
// ));
}, },
title: 'With SMS', title: 'With SMS',
icon: icons + "ic_sms.png", icon: icons + "ic_sms.png",
@ -60,22 +74,26 @@ class LoginVerifyAccountPage extends StatelessWidget {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
showMDialog(context, child: OtpDialog( otpType = 1;
onClick: () { performBasicOtp(context);
pop(context); // showMDialog(context, child: OtpDialog(
delay(300).then( // onClick: (String code) {
(value) => showMDialog( // pop(context);
context, // delay(300).then(
child: MessageDialog( // (value) => showMDialog(
title: "Phone Number Verified", // context,
onClick: () { // child: MessageDialog(
navigateWithName(context, AppRoutes.completeProfile); // title: "Phone Number Verified",
}, // onClick: () {
), // otpType=2;
), // performBasicOtp(context);
); // // navigateWithName(context, AppRoutes.completeProfile);
}, // },
)); // ),
// ),
// );
// },
// ));
}, },
title: 'With Whatsapp', title: 'With Whatsapp',
icon: icons + "ic_whatsapp.png", icon: icons + "ic_whatsapp.png",
@ -89,4 +107,36 @@ class LoginVerifyAccountPage extends StatelessWidget {
), ),
); );
} }
Future<void> performBasicOtp(BuildContext context) async {
Utils.showLoading(context);
BasicOtp basicOtp = await UserApiClent().basicOtp(phoneNum, otpType: otpType);
Utils.hideLoading(context);
if (basicOtp.messageStatus == 1) {
showMDialog(context, child: OtpDialog(
onClick: (String code) async {
pop(context);
Utils.showLoading(context);
RegisterUser user = await UserApiClent().basicVerify(phoneNum, code, basicOtp.data!.userToken ?? "");
Utils.hideLoading(context);
if (user.messageStatus == 1) {
Utils.showToast(user.message ?? "");
showMDialog(
context,
child: MessageDialog(
title: "Phone Number Verified",
onClick: () {
navigateWithName(context, AppRoutes.completeProfile,arguments: user);
},
),
);
} else {
Utils.showToast(user.message ?? "");
}
},
));
} else {
Utils.showToast(basicOtp.message ?? "");
}
}
} }

@ -0,0 +1,80 @@
import 'dart:convert';
import 'package:car_customer_app/api/user_api_client.dart';
import 'package:car_customer_app/classes/utils.dart';
import 'package:car_customer_app/config/constants.dart';
import 'package:car_customer_app/config/routes.dart';
import 'package:car_customer_app/models/user/basic_otp.dart';
import 'package:car_customer_app/models/user/register_user.dart';
import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart';
import 'package:car_customer_app/widgets/app_bar.dart';
import 'package:car_customer_app/widgets/button/show_image_button.dart';
import 'package:car_customer_app/widgets/dialog/dialogs.dart';
import 'package:car_customer_app/widgets/dialog/message_dialog.dart';
import 'package:car_customer_app/widgets/dialog/otp_dialog.dart';
import 'package:car_customer_app/extensions/int_extensions.dart';
import 'package:car_customer_app/extensions/string_extensions.dart';
import 'package:car_customer_app/extensions/widget_extensions.dart';
import 'package:car_customer_app/widgets/show_fill_button.dart';
import 'package:car_customer_app/widgets/txt_field.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class LoginWithPassword extends StatelessWidget {
int otpType = 1;
String phoneNum = "", password = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBar(title: "Log In"),
body: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40),
child: Column(
children: [
"Login".toText24(),
mFlex(1),
TxtField(
hint: "Enter Phone number to verify",
onChanged: (v) {
phoneNum = v;
},
),
12.height,
TxtField(
hint: "Password",
onChanged: (v) {
password = v;
},
),
50.height,
ShowFillButton(
title: "Continue",
width: double.infinity,
onPressed: () {
performBasicOtp(context);
},
),
mFlex(10),
],
),
),
);
}
Future<void> performBasicOtp(BuildContext context) async {
Utils.showLoading(context);
Response response = await UserApiClent().login_V1(phoneNum, password);
Utils.hideLoading(context);
if (response.statusCode == 200) {
String userToken = jsonDecode(response.body)["userToken"];
navigateWithName(context, AppRoutes.loginMethodSelection, arguments: userToken);
} else {
String res = jsonDecode(response.body)["errors"][0] ?? "";
Utils.showToast(res);
}
}
}

@ -1,5 +1,13 @@
import 'package:car_customer_app/api/api_client.dart';
import 'package:car_customer_app/api/user_api_client.dart';
import 'package:car_customer_app/classes/utils.dart';
import 'package:car_customer_app/models/user/basic_otp.dart';
import 'package:car_customer_app/models/user/register_user.dart';
import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/utils/utils.dart';
import 'package:car_customer_app/widgets/app_bar.dart'; import 'package:car_customer_app/widgets/app_bar.dart';
import 'package:car_customer_app/widgets/dialog/dialogs.dart';
import 'package:car_customer_app/widgets/dialog/otp_dialog.dart';
import 'package:car_customer_app/widgets/show_fill_button.dart'; import 'package:car_customer_app/widgets/show_fill_button.dart';
import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:car_customer_app/extensions/int_extensions.dart';
import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/extensions/string_extensions.dart';
@ -8,6 +16,8 @@ import 'package:car_customer_app/widgets/txt_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class RegisterPage extends StatelessWidget { class RegisterPage extends StatelessWidget {
String phoneNum = "";
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -19,30 +29,58 @@ class RegisterPage extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
"Enter Phone Number".toText24(), "Enter Phone Number".toText24(),
12.height, 12.height,
TxtField( TxtField(
hint: "Enter Phone number to Register", hint: "Enter Phone number to Register",
), onChanged: (v) {
TxtField( phoneNum = v;
hint: "Enter Phone number to Register", },
),
40.height,
"Or Enter Email".toText24(),
12.height,
TxtField(
hint: "Enter Email to Register",
), ),
50.height, 50.height,
ShowFillButton( ShowFillButton(
title: "Continue", title: "Continue",
width: double.infinity, width: double.infinity,
onPressed: () {}, onPressed: () {
performBasicOtp(context);
},
), ),
], ],
), ),
), ),
); );
} }
Future<void> performBasicOtp(BuildContext context) async {
Utils.showLoading(context);
BasicOtp basicOtp = await UserApiClent().basicOtp(phoneNum);
Utils.hideLoading(context);
if (basicOtp.messageStatus == 1) {
showMDialog(context, child: OtpDialog(
onClick: (String code) async {
pop(context);
Utils.showLoading(context);
RegisterUser user = await UserApiClent().basicVerify(phoneNum, code, basicOtp.data!.userToken ?? "");
Utils.hideLoading(context);
if (user.messageStatus == 1) {
Utils.showToast(user.message ?? "");
} else {
Utils.showToast(user.message ?? "");
}
// delay(300).then(
// (value) => showMDialog(
// context,
// child: MessageDialog(
// title: "Phone Number Verified",
// onClick: () {
// navigateWithName(context, AppRoutes.completeProfile);
// },
// ),
// ),
// );
},
));
} else {
Utils.showToast(basicOtp.message ?? "");
}
}
} }

@ -21,6 +21,14 @@ class RegisterSelectionPage extends StatelessWidget {
children: [ children: [
"Welcome Message".toText24(), "Welcome Message".toText24(),
mFlex(1), mFlex(1),
ShowFillButton(
title: "Log In With Password",
width: double.infinity,
onPressed: () {
navigateWithName(context, AppRoutes.loginWithPassword);
},
),
20.height,
ShowFillButton( ShowFillButton(
title: "Log In", title: "Log In",
width: double.infinity, width: double.infinity,

@ -1,3 +1,4 @@
import 'package:car_customer_app/classes/colors.dart';
import 'package:car_customer_app/theme/colors.dart'; import 'package:car_customer_app/theme/colors.dart';
import 'package:car_customer_app/utils/navigator.dart'; import 'package:car_customer_app/utils/navigator.dart';
import 'package:car_customer_app/utils/utils.dart'; import 'package:car_customer_app/utils/utils.dart';
@ -6,67 +7,96 @@ import 'package:car_customer_app/extensions/string_extensions.dart';
import 'package:car_customer_app/extensions/int_extensions.dart'; import 'package:car_customer_app/extensions/int_extensions.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../otp_widget.dart';
class OtpDialog extends StatelessWidget { class OtpDialog extends StatelessWidget {
VoidCallback onClick; Function(String) onClick;
OtpDialog({required this.onClick}); OtpDialog({required this.onClick});
String code="";
final TextEditingController _pinPutController = TextEditingController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Colors.white, color: Colors.white,
padding: EdgeInsets.all(30), padding: EdgeInsets.all(24),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Please insert OTP Code".toText24(), "Please insert OTP Code".toText24(),
20.height, 20.height,
Row( OTPWidget(
children: [ autoFocus: true,
Expanded( controller: _pinPutController,
child: Container( defaultBorderColor: const Color(0xffD8D8D8),
width: double.infinity, maxLength: 4,
height: 60, onTextChanged: (text) {},
color: accentColor.withOpacity(0.3), pinBoxColor: Colors.white,
), onDone: (code) => _onOtpCallBack(code, null),
), textBorderColor: const Color(0xffD8D8D8),
12.width, pinBoxWidth: 60,
Expanded( pinBoxHeight: 60,
child: Container( pinTextStyle: const TextStyle(fontSize: 24.0, color: MyColors.darkTextColor),
width: double.infinity, pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition,
height: 60, pinTextAnimatedSwitcherDuration: const Duration(milliseconds: 300),
color: accentColor.withOpacity(0.3), pinBoxRadius: 10,
), keyboardType: TextInputType.number,
),
12.width,
Expanded(
child: Container(
width: double.infinity,
height: 60,
color: accentColor.withOpacity(0.3),
),
),
12.width,
Expanded(
child: Container(
width: double.infinity,
height: 60,
color: accentColor.withOpacity(0.3),
),
),
],
), ),
// Row(
// children: [
// Expanded(
// child: Container(
// width: double.infinity,
// height: 60,
// color: accentColor.withOpacity(0.3),
// ),
// ),
// 12.width,
// Expanded(
// child: Container(
// width: double.infinity,
// height: 60,
// color: accentColor.withOpacity(0.3),
// ),
// ),
// 12.width,
// Expanded(
// child: Container(
// width: double.infinity,
// height: 60,
// color: accentColor.withOpacity(0.3),
// ),
// ),
// 12.width,
// Expanded(
// child: Container(
// width: double.infinity,
// height: 60,
// color: accentColor.withOpacity(0.3),
// ),
// ),
// ],
// ),
40.height, 40.height,
ShowFillButton( ShowFillButton(
title: "Check Code", title: "Check Code",
width: double.infinity, width: double.infinity,
onPressed: () { onPressed: () {
onClick(); onClick(code);
}, },
) )
], ],
), ),
); );
} }
_onOtpCallBack(String otpCode, bool? isAutofill) {
if (otpCode.length == 4) {
// onSuccess(otpCode);
code=otpCode;
}
}
} }

@ -0,0 +1,43 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class LoadingDialog extends StatefulWidget {
LoadingDialog({Key? key}) : super(key: key);
@override
_LoadingDialogState createState() {
return _LoadingDialogState();
}
}
class _LoadingDialogState extends State<LoadingDialog> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Dialog(
insetPadding: const EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Directionality(
textDirection: TextDirection.rtl,
child: Center(
child: CircularProgressIndicator(),
),
),
);
}
}

@ -0,0 +1,373 @@
import 'dart:async';
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
typedef OnDone = void Function(String text);
class ProvidedPinBoxTextAnimation {
static AnimatedSwitcherTransitionBuilder scalingTransition = (child, animation) {
return ScaleTransition(
child: child,
scale: animation,
);
};
static AnimatedSwitcherTransitionBuilder defaultNoTransition = (Widget child, Animation<double> animation) {
return child;
};
}
class OTPWidget extends StatefulWidget {
final int maxLength;
final TextEditingController? controller;
final Color defaultBorderColor;
final Color pinBoxColor;
final double pinBoxBorderWidth;
final double pinBoxRadius;
final bool hideDefaultKeyboard;
final TextStyle? pinTextStyle;
final double pinBoxHeight;
final double pinBoxWidth;
final OnDone? onDone;
final bool hasError;
final Color errorBorderColor;
final Color textBorderColor;
final Function(String)? onTextChanged;
final bool autoFocus;
final FocusNode? focusNode;
final AnimatedSwitcherTransitionBuilder? pinTextAnimatedSwitcherTransition;
final Duration pinTextAnimatedSwitcherDuration;
final TextDirection textDirection;
final TextInputType keyboardType;
final EdgeInsets pinBoxOuterPadding;
const OTPWidget({
Key? key,
this.maxLength: 4,
this.controller,
this.pinBoxWidth: 70.0,
this.pinBoxHeight: 70.0,
this.pinTextStyle,
this.onDone,
this.defaultBorderColor: Colors.black,
this.textBorderColor: Colors.black,
this.pinTextAnimatedSwitcherTransition,
this.pinTextAnimatedSwitcherDuration: const Duration(),
this.hasError: false,
this.errorBorderColor: Colors.red,
this.onTextChanged,
this.autoFocus: false,
this.focusNode,
this.textDirection: TextDirection.ltr,
this.keyboardType: TextInputType.number,
this.pinBoxOuterPadding = const EdgeInsets.symmetric(horizontal: 4.0),
this.pinBoxColor = Colors.white,
this.pinBoxBorderWidth = 2.0,
this.pinBoxRadius = 0,
this.hideDefaultKeyboard = false,
}) : super(key: key);
@override
State<StatefulWidget> createState() {
return OTPWidgetState();
}
}
class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixin {
AnimationController? _highlightAnimationController;
FocusNode? focusNode;
String text = "";
int currentIndex = 0;
List<String> strList = [];
bool hasFocus = false;
@override
void didUpdateWidget(OTPWidget oldWidget) {
super.didUpdateWidget(oldWidget);
focusNode = widget.focusNode ?? focusNode;
if (oldWidget.maxLength < widget.maxLength) {
setState(() {
currentIndex = text.length;
});
widget.controller?.text = text;
widget.controller?.selection = TextSelection.collapsed(offset: text.length);
} else if (oldWidget.maxLength > widget.maxLength && widget.maxLength > 0 && text.length > 0 && text.length > widget.maxLength) {
setState(() {
text = text.substring(0, widget.maxLength);
currentIndex = text.length;
});
widget.controller?.text = text;
widget.controller?.selection = TextSelection.collapsed(offset: text.length);
}
}
_calculateStrList() {
if (strList.length > widget.maxLength) {
strList.length = widget.maxLength;
}
while (strList.length < widget.maxLength) {
strList.add("");
}
}
@override
void initState() {
super.initState();
focusNode = widget.focusNode ?? FocusNode();
_initTextController();
_calculateStrList();
widget.controller?.addListener(_controllerListener);
focusNode?.addListener(_focusListener);
}
void _controllerListener() {
if (mounted == true) {
setState(() {
_initTextController();
});
var onTextChanged = widget.onTextChanged;
if (onTextChanged != null) {
onTextChanged(widget.controller?.text ?? "");
}
}
}
void _focusListener() {
if (mounted == true) {
setState(() {
hasFocus = focusNode?.hasFocus ?? false;
});
}
}
void _initTextController() {
if (widget.controller == null) {
return;
}
strList.clear();
var text = widget.controller?.text ?? "";
if (text.isNotEmpty) {
if (text.length > widget.maxLength) {
throw Exception("TextEditingController length exceeded maxLength!");
}
}
for (var i = 0; i < text.length; i++) {
strList.add(text[i]);
}
}
double get _width {
var width = 0.0;
for (var i = 0; i < widget.maxLength; i++) {
width += widget.pinBoxWidth;
if (i == 0) {
width += widget.pinBoxOuterPadding.left;
} else if (i + 1 == widget.maxLength) {
width += widget.pinBoxOuterPadding.right;
} else {
width += widget.pinBoxOuterPadding.left;
}
}
return width;
}
@override
void dispose() {
if (widget.focusNode == null) {
focusNode?.dispose();
} else {
focusNode?.removeListener(_focusListener);
}
_highlightAnimationController?.dispose();
widget.controller?.removeListener(_controllerListener);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
_otpTextInput(),
_touchPinBoxRow(),
],
);
}
Widget _touchPinBoxRow() {
return widget.hideDefaultKeyboard
? _pinBoxRow(context)
: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (hasFocus) {
FocusScope.of(context).requestFocus(FocusNode());
Future.delayed(Duration(milliseconds: 100), () {
FocusScope.of(context).requestFocus(focusNode);
});
} else {
FocusScope.of(context).requestFocus(focusNode);
}
},
child: _pinBoxRow(context),
);
}
Widget _otpTextInput() {
var transparentBorder = OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
width: 0.0,
),
);
return Container(
width: _width,
height: widget.pinBoxHeight,
child: TextField(
autofocus: !kIsWeb ? widget.autoFocus : false,
enableInteractiveSelection: false,
focusNode: focusNode,
controller: widget.controller,
keyboardType: widget.keyboardType,
inputFormatters: widget.keyboardType == TextInputType.number ? <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly] : null,
style: TextStyle(
height: 0.1,
color: Colors.transparent,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0),
focusedErrorBorder: transparentBorder,
errorBorder: transparentBorder,
disabledBorder: transparentBorder,
enabledBorder: transparentBorder,
focusedBorder: transparentBorder,
counterText: null,
counterStyle: null,
helperStyle: TextStyle(
height: 0.0,
color: Colors.transparent,
),
labelStyle: TextStyle(height: 0.1),
fillColor: Colors.transparent,
border: InputBorder.none,
),
cursorColor: Colors.transparent,
showCursor: false,
maxLength: widget.maxLength,
onChanged: _onTextChanged,
),
);
}
void _onTextChanged(text) {
var onTextChanged = widget.onTextChanged;
if (onTextChanged != null) {
onTextChanged(text);
}
setState(() {
this.text = text;
if (text.length >= currentIndex) {
for (int i = currentIndex; i < text.length; i++) {
strList[i] = text[i];
}
}
currentIndex = text.length;
});
if (text.length == widget.maxLength) {
FocusScope.of(context).requestFocus(FocusNode());
var onDone = widget.onDone;
if (onDone != null) {
onDone(text);
}
}
}
Widget _pinBoxRow(BuildContext context) {
_calculateStrList();
List<Widget> pinCodes = List.generate(widget.maxLength, (int i) {
return _buildPinCode(i, context);
});
return Row(children: pinCodes, mainAxisSize: MainAxisSize.min);
}
Widget _buildPinCode(int i, BuildContext context) {
Color borderColor;
Color pinBoxColor = widget.pinBoxColor;
if (widget.hasError) {
borderColor = widget.errorBorderColor;
} else if (i < text.length) {
borderColor = widget.textBorderColor;
} else {
borderColor = widget.defaultBorderColor;
pinBoxColor = widget.pinBoxColor;
}
EdgeInsets insets;
if (i == 0) {
insets = EdgeInsets.only(
left: 0,
top: widget.pinBoxOuterPadding.top,
right: widget.pinBoxOuterPadding.right,
bottom: widget.pinBoxOuterPadding.bottom,
);
} else if (i == strList.length - 1) {
insets = EdgeInsets.only(
left: widget.pinBoxOuterPadding.left,
top: widget.pinBoxOuterPadding.top,
right: 0,
bottom: widget.pinBoxOuterPadding.bottom,
);
} else {
insets = widget.pinBoxOuterPadding;
}
return Container(
key: ValueKey<String>("container$i"),
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 1.0),
margin: insets,
child: _animatedTextBox(strList[i], i),
decoration: BoxDecoration(
border: Border.all(
color: borderColor,
width: widget.pinBoxBorderWidth,
),
color: pinBoxColor,
borderRadius: BorderRadius.circular(widget.pinBoxRadius),
),
width: widget.pinBoxWidth,
height: widget.pinBoxHeight,
);
}
Widget _animatedTextBox(String text, int i) {
if (widget.pinTextAnimatedSwitcherTransition != null) {
return AnimatedSwitcher(
duration: widget.pinTextAnimatedSwitcherDuration,
transitionBuilder: widget.pinTextAnimatedSwitcherTransition ??
(Widget child, Animation<double> animation) {
return child;
},
child: Text(
text,
key: ValueKey<String>("$text$i"),
style: widget.pinTextStyle,
),
);
} else {
return Text(
text,
key: ValueKey<String>("${strList[i]}$i"),
style: widget.pinTextStyle,
);
}
}
}

@ -21,6 +21,7 @@ class TxtField extends StatelessWidget {
int? maxLines; int? maxLines;
bool isSidePaddingZero; bool isSidePaddingZero;
bool isNeedBorder; bool isNeedBorder;
Function(String)? onChanged;
TxtField({ TxtField({
this.title, this.title,
@ -37,6 +38,7 @@ class TxtField extends StatelessWidget {
this.maxLines, this.maxLines,
this.isSidePaddingZero=false, this.isSidePaddingZero=false,
this.isNeedBorder=true, this.isNeedBorder=true,
this.onChanged,
}); });
@override @override
@ -61,6 +63,7 @@ class TxtField extends StatelessWidget {
enabled: isNeedClickAll == true ? false : true, enabled: isNeedClickAll == true ? false : true,
maxLines: maxLines, maxLines: maxLines,
onTap: () {}, onTap: () {},
onChanged: onChanged,
decoration: InputDecoration( decoration: InputDecoration(
labelText: lable, labelText: lable,
alignLabelWithHint: true, alignLabelWithHint: true,

@ -133,6 +133,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
fluttertoast:
dependency: "direct dev"
description:
name: fluttertoast
url: "https://pub.dartlang.org"
source: hosted
version: "8.0.8"
http: http:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -316,7 +323,7 @@ packages:
source: hosted source: hosted
version: "6.0.1" version: "6.0.1"
shared_preferences: shared_preferences:
dependency: transitive dependency: "direct dev"
description: description:
name: shared_preferences name: shared_preferences
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"

@ -53,6 +53,8 @@ dev_dependencies:
permission_handler: 7.1.0 permission_handler: 7.1.0
flutter_svg: ^0.22.0 flutter_svg: ^0.22.0
sizer: ^2.0.15 sizer: ^2.0.15
fluttertoast: ^8.0.8
shared_preferences: ^2.0.6
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the

Loading…
Cancel
Save