diff --git a/android/app/build.gradle b/android/app/build.gradle index 47bcd00..5942955 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 31 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -45,7 +45,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.car_customer_app" minSdkVersion 16 - targetSdkVersion 30 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/android/build.gradle b/android/build.gradle index ed45c65..09fbd64 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.6.10' repositories { google() mavenCentral() diff --git a/assets/images/bn_map.png b/assets/images/bn_map.png new file mode 100644 index 0000000..b04b5aa Binary files /dev/null and b/assets/images/bn_map.png differ diff --git a/assets/images/ic_car.svg b/assets/images/ic_car.svg new file mode 100644 index 0000000..804f607 --- /dev/null +++ b/assets/images/ic_car.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/ic_edit.svg b/assets/images/ic_edit.svg new file mode 100644 index 0000000..c14165f --- /dev/null +++ b/assets/images/ic_edit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_lock.svg b/assets/images/ic_lock.svg new file mode 100644 index 0000000..1273157 --- /dev/null +++ b/assets/images/ic_lock.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/ic_logout.svg b/assets/images/ic_logout.svg new file mode 100644 index 0000000..2be107f --- /dev/null +++ b/assets/images/ic_logout.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/ic_mobile.svg b/assets/images/ic_mobile.svg new file mode 100644 index 0000000..068cf7a --- /dev/null +++ b/assets/images/ic_mobile.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/images/ic_notes.svg b/assets/images/ic_notes.svg new file mode 100644 index 0000000..009cf17 --- /dev/null +++ b/assets/images/ic_notes.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/images/ic_notification.svg b/assets/images/ic_notification.svg new file mode 100644 index 0000000..e45bab2 --- /dev/null +++ b/assets/images/ic_notification.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/ic_settings.svg b/assets/images/ic_settings.svg new file mode 100644 index 0000000..83b64c9 --- /dev/null +++ b/assets/images/ic_settings.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/api/client/branch_api_client.dart b/lib/api/client/branch_api_client.dart new file mode 100644 index 0000000..973e3bf --- /dev/null +++ b/lib/api/client/branch_api_client.dart @@ -0,0 +1,69 @@ +import 'dart:async'; +import 'package:car_customer_app/classes/app_state.dart'; +import 'package:car_customer_app/models/m_response.dart'; +import 'package:car_customer_app/models/profile/branch.dart'; +import 'package:car_customer_app/models/profile/categroy.dart'; +import 'package:car_customer_app/models/profile/document.dart'; +import 'package:car_customer_app/models/profile/services.dart'; +import 'package:car_customer_app/models/user/country.dart'; +import 'package:car_customer_app/models/user/role.dart'; +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 BranchApiClent { + static final BranchApiClent _instance = BranchApiClent._internal(); + + BranchApiClent._internal(); + + factory BranchApiClent() => _instance; + + Future createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async { + var postParams = { + // "id": 0, + "serviceProviderID": AppState().getUser.data?.userInfo?.providerId ?? "", + "branchName": branchName, + "branchDescription": branchDescription, + "cityID": cityId, + "address": address, + "latitude": latitude, + "longitude": longitude, + "isActive": true + }; + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createProviderBranch, postParams, token: t); + } + + Future fetchAllBranches() async { + var postParams = {"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""}; + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().getJsonForObject((json) => Branch.fromJson(json), ApiConsts.ServiceProviderBranchGet, queryParameters: postParams, token: t); + } + + Future fetchBranchCategory() async { + var postParams = {"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""}; + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().getJsonForObject((json) => Category.fromJson(json), ApiConsts.ServiceCategory_Get, queryParameters: postParams, token: t); + } + + Future fetchServices(String serviceCategoryId) async { + var postParams = {"ServiceCategoryID": serviceCategoryId}; + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().getJsonForObject((json) => Services.fromJson(json), ApiConsts.Services_Get, queryParameters: postParams, token: t); + } + + Future createService(List> map) async { + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t); + } +} diff --git a/lib/api/client/profile_api_client.dart b/lib/api/client/profile_api_client.dart new file mode 100644 index 0000000..de796b0 --- /dev/null +++ b/lib/api/client/profile_api_client.dart @@ -0,0 +1,52 @@ +import 'dart:async'; +import 'package:car_customer_app/classes/app_state.dart'; +import 'package:car_customer_app/models/m_response.dart'; +import 'package:car_customer_app/models/profile/document.dart'; +import 'package:car_customer_app/models/user/country.dart'; +import 'package:car_customer_app/models/user/role.dart'; +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 ProfileApiClent { + static final ProfileApiClent _instance = ProfileApiClent._internal(); + + ProfileApiClent._internal(); + + factory ProfileApiClent() => _instance; + + Future getServiceProviderDocument(dynamic userId) async { + var queryParameters = { + "ServiceProviderID": userId.toString(), + }; + String? token = AppState().getUser.data?.accessToken; + print(token); + return await ApiClient().getJsonForObject((json) => Document.fromJson(json), ApiConsts.GetProviderDocument, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? ""); + } + + Future serviceProviderDocumentsUpdate(List? documents) async { + List> map = []; + for (int i = 0; i < documents!.length; i++) { + if (documents[i].document != null) { + var postParams = { + "id": documents[i].id, + "serviceProviderID": documents[i].serviceProviderId, + "documentID": documents[i].documentId, + "documentExt": documents[i].fileExt, + "documentImage": documents[i].document, + "isActive": true + }; + map.add(postParams); + } + } + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderDocument_Update, map, token: t); + } +} diff --git a/lib/api/client/user_api_client.dart b/lib/api/client/user_api_client.dart new file mode 100644 index 0000000..087fbcb --- /dev/null +++ b/lib/api/client/user_api_client.dart @@ -0,0 +1,205 @@ +import 'dart:async'; +import 'package:car_customer_app/models/user/change_email.dart'; +import 'package:car_customer_app/models/user/change_mobile.dart'; +import 'package:car_customer_app/models/user/cities.dart'; +import 'package:car_customer_app/models/user/confirm_email.dart'; +import 'package:car_customer_app/models/user/confirm_mobile.dart'; +import 'package:car_customer_app/models/user/country.dart'; +import 'package:car_customer_app/models/user/image_response.dart'; +import 'package:car_customer_app/models/user/role.dart'; +import 'package:car_customer_app/models/user/confirm_password.dart'; +import 'package:car_customer_app/models/user/forget_password_otp_compare.dart'; +import 'package:car_customer_app/models/user/forget_password_otp_request.dart'; +import 'package:car_customer_app/models/user/verify_email.dart'; +import 'package:car_customer_app/models/user/verify_email_otp.dart'; +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 '../../classes/app_state.dart'; +import '../../models/m_response.dart'; +import '../api_client.dart'; + + + +class UserApiClent { + static final UserApiClent _instance = UserApiClent._internal(); + + UserApiClent._internal(); + + factory UserApiClent() => _instance; + + Future basicOtp(String phoneNo, {int otpType = 1, int roleId = 4, int countryId = 1}) async { + var postParams = {"countryID": countryId, "userMobileNo": phoneNo, "otpType": otpType, "userRole": roleId}; + return await ApiClient().postJsonForObject((json) => BasicOtp.fromJson(json), ApiConsts.BasicOTP, postParams); + } + + Future 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 basicComplete(String userId, String firstName, String lastName, String email, String password) async { + var postParams; + if(email.isEmpty){ + postParams = {"userID": userId, "firstName": firstName, "lastName": lastName, "companyName": "string", "isEmailVerified": true, "password": password}; + }else{ + 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 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 login_V2_OTP(String userToken, String loginType) async { + var postParams = { + "userToken": userToken, + "loginType": loginType, + }; + return await ApiClient().postJsonForResponse(ApiConsts.Login_V2_OTP, postParams); + } + + Future login_V2_OTPVerify(String userToken, String otp) async { + var postParams = {"userToken": userToken, "userOTP": otp}; + return await ApiClient().postJsonForResponse(ApiConsts.Login_V2_OTPVerify, postParams); + } + + Future getAllCountries() async { + var postParams = {}; + return await ApiClient().getJsonForObject((json) => Country.fromJson(json), ApiConsts.GetAllCountry); + } + + Future getAllCites(String countryId) async { + var postParams = { + "CountryID": countryId, + }; + return await ApiClient().getJsonForObject((json) => Cities.fromJson(json), ApiConsts.GetAllCities, queryParameters: postParams); + } + + Future getRoles() async { + return await ApiClient().getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles); + } + + Future ForgetPasswordOTPRequest(String userName, int otpType) async { + var postParams = { + "userName": userName, + "otpType": 1, + }; + return await ApiClient().postJsonForResponse(ApiConsts.ForgetPasswordOTPRequest, postParams); + //return await ApiClient().postJsonForObject((json) => PasswordOTPRequest.fromJson(json), ApiConsts.ForgetPasswordOTPRequest, postParams); + } + + Future ForgetPasswordOTPCompare(String userToken, String userOTP) async { + var postParams = {"userToken": userToken, "userOTP": userOTP}; + return await ApiClient().postJsonForResponse(ApiConsts.ForgetPasswordOTPCompare, postParams); + // return await ApiClient().postJsonForObject((json) => PasswordOTPCompare.fromJson(json), ApiConsts.ForgetPasswordOTPCompare, postParams); + } + + Future ForgetPassword(String userToken, String newPassword) async { + var postParams = { + "userToken": userToken, + "newPassword": newPassword, + }; + return await ApiClient().postJsonForResponse(ApiConsts.ForgetPassword, postParams); + //return await ApiClient().postJsonForObject((json) => ConfirmPassword.fromJson(json), ApiConsts.ForgetPassword, postParams); + } + + Future ChangePassword(String currentPasswor, String newPassword) async { + var postParams = { + "currentPassword": currentPasswor, + "newPassword": newPassword, + }; + // return await ApiClient().postJsonForResponse(ApiConsts.ChangePassword, postParams); + + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ChangePassword, postParams, token: t); + + } + + Future ChangeMobileNoOTPRequest( + countryID, + String mobileNo, + String password, + ) async { + var postParams = {"countryID": 1, "mobileNo": mobileNo, "password": password}; + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => ChangeMobile.fromJson(json), ApiConsts.ChangeMobileNoOTPRequest, postParams, token: t); + } + + Future ChangeMobileNo(String userToken, String userOTP) async { + var postParams = { + "userToken": userToken, + "userOTP": userOTP, + }; + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => ConfirmMobile.fromJson(json), ApiConsts.ChangeMobileNo, postParams, token: t); + } + + Future ChangeEmailOTPRequest(String email, String password) async { + var postParams = {"email": email, "password": password}; + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => ChanEmail.fromJson(json), ApiConsts.ChangeEmailOTPRequest, postParams, token: t); + } + + Future ChangeEmail(String userToken, String userOTP) async { + var postParams = {"userToken": userToken, "userOTP": userOTP}; + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => ConfirmEmail.fromJson(json), ApiConsts.ChangeEmail, postParams, token: t); + } + + Future EmailVerify(String email, String userID) async { + var postParams = { + // "email": email, + // "userID": userID, + "email": AppState().getUser.data!.userInfo!.email ?? "", + "userID": AppState().getUser.data!.userInfo!.userId ?? "", + }; + + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => VerifyEmail.fromJson(json), ApiConsts.EmailVerify, postParams, token: t); + } + + Future EmailVerifyOTPVerify(String userToken, String userOTP) async { + var postParams = + {"userToken": userToken, + "userOTP": userOTP}; + + String t = AppState().getUser.data!.accessToken ?? ""; + return await ApiClient().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.EmailVerifyOTPVerify, postParams, token: t); + } + + Future UpdateUserImage(String image) async { + var postParams = {"userID": AppState().getUser.data!.userInfo!.userId, "userImage": image}; + // return await ApiClient().postJsonForResponse(ApiConsts.ChangePassword, postParams); + + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().postJsonForObject((json) => ImageResponse.fromJson(json), ApiConsts.UpdateUserImage, postParams, token: t); + } + + Future GetUserImage(String image) async { + var postParams = {}; + // return await ApiClient().postJsonForResponse(ApiConsts.ChangePassword, postParams); + + String t = AppState().getUser.data!.accessToken ?? ""; + print("tokeen " + t); + return await ApiClient().postJsonForObject((json) => ImageResponse.fromJson(json), ApiConsts.UpdateUserImage, postParams, token: t); + } +} diff --git a/lib/api/user_api_client.dart b/lib/api/user_api_client.dart deleted file mode 100644 index 1d644ef..0000000 --- a/lib/api/user_api_client.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:async'; -import 'package:car_customer_app/models/user/country.dart'; -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(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 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 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 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 login_V2_OTP(String userToken, String loginType) async { - var postParams = { - "userToken": userToken, - "loginType": loginType, - }; - return await ApiClient().postJsonForResponse(ApiConsts.Login_V2_OTP, postParams); - } - - Future login_V2_OTPVerify(String userToken, String otp) async { - var postParams = {"userToken": userToken, "userOTP": otp}; - return await ApiClient().postJsonForResponse(ApiConsts.Login_V2_OTPVerify, postParams); - } - - Future getAllCountries() async { - var postParams = {}; - return await ApiClient().getJsonForObject((json) => Country.fromJson(json), ApiConsts.GetAllCountry); - } - - - Future ForgetPasswordOTPRequest(String userName, int otpType) async { - var postParams = { - "userName": userName, - "otpType": 1, - }; - return await ApiClient().postJsonForResponse(ApiConsts.ForgetPasswordOTPRequest, postParams); - } - - Future ForgetPasswordOTPCompare(String userToken, String otp) async { - var postParams = - {"userToken": userToken, - "userOTP": otp}; - return await ApiClient().postJsonForResponse(ApiConsts.ForgetPasswordOTPCompare, postParams); - - } - - Future ForgetPassword(String userToken, String newPassword) async { - var postParams = { - "userToken": userToken, - "newPassword": newPassword, - }; - return await ApiClient().postJsonForResponse(ApiConsts.ForgetPassword, postParams); - - } -} diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 09b8ad8..bda0cac 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,24 +1,48 @@ 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 = "https://mdlaboratories.com"; // production server static String baseUrlServices = baseUrl + "/mc/"; // production server - // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String BasicOTP = baseUrlServices + "api/Register/BasicOTP"; static String BasicVerify = baseUrlServices + "api/Register/BasicVerify"; static String BasicComplete = baseUrlServices + "api/Register/BasicComplete"; + + //User 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 GetAllCountry = baseUrlServices + "api/Master/Country_Get"; - + static String GetProviderRoles = baseUrlServices + "api/Master/RoleServiceProvider_Get"; + static String GetAllCities = baseUrlServices + "api/Master/City_Get"; static String ForgetPasswordOTPRequest = baseUrlServices + "api/Account/ForgetPasswordOTPRequest"; static String ForgetPasswordOTPCompare = baseUrlServices + "api/Account/ForgetPasswordOTPCompare"; static String ForgetPassword = baseUrlServices + "api/Account/ForgetPassword"; -} + static String Login_Email_OTP = baseUrlServices + "api/Account/EmailVerify"; + static String Login_Email_OTPVerify = baseUrlServices + "api/Account/EmailVerifyOTPVerify"; + static String ChangePassword = baseUrlServices + "api/Account/ChangePassword"; + static String ChangeMobileNoOTPRequest = baseUrlServices + "api/Account/ChangeMobileNoOTPRequest"; + static String ChangeMobileNo = baseUrlServices + "api/Account/ChangeMobileNo"; + static String ChangeEmailOTPRequest = baseUrlServices + "api/Account/ChangeEmailOTPRequest"; + static String ChangeEmail = baseUrlServices + "api/Account/ChangeEmail"; + static String EmailVerify = baseUrlServices + "api/Account/EmailVerify"; + static String EmailVerifyOTPVerify = baseUrlServices + "api/Account/EmailVerifyOTPVerify"; + static String UpdateUserImage = baseUrlServices + "api/User_UpdateProfileImage"; + static String GetUserImage = baseUrlServices + "api/ProfileImage"; + //Profile + static String GetProviderDocument = baseUrlServices + "api/ServiceProviders/ServiceProviderDocument_Get"; + static String ServiceProviderDocument_Update = baseUrlServices + "api/ServiceProviders/ServiceProviderDocument_Update"; + + //Branch + static String createProviderBranch = baseUrlServices + "api/ServiceProviders/ServiceProviderBranch_Create"; + static String ServiceProviderBranchGet = baseUrlServices + "api/ServiceProviders/ServiceProviderBranch_Get"; + static String ServiceCategory_Get = baseUrlServices + "api/Master/ServiceCategory_Get"; + static String Services_Get = baseUrlServices + "api/ServiceProviders/Services_Get"; + static String ServiceProviderService_Create = baseUrlServices + "api/ServiceProviders/ServiceProviderService_Create"; +} + class GlobalConsts { static String isRememberMe = "remember_me"; static String email = "email"; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index ab9223c..d74fc0b 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,16 +1,29 @@ 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/settings/create_services_page.dart'; +// import 'package:car_customer_app/pages/settings/dealership_page.dart'; +// import 'package:car_customer_app/pages/settings/define_branch_page.dart'; +// import 'package:car_customer_app/pages/settings/define_license_page.dart'; +import 'package:car_customer_app/pages/user/change_email_page.dart'; +import 'package:car_customer_app/pages/user/change_mobile_page.dart'; +import 'package:car_customer_app/pages/user/change_password_page.dart'; import 'package:car_customer_app/pages/user/complete_profile_page.dart'; +import 'package:car_customer_app/pages/user/confirm_new_password_page.dart'; +import 'package:car_customer_app/pages/user/edit_account_page.dart'; +import 'package:car_customer_app/pages/user/forget_password_method_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_verify_account_page.dart'; import 'package:car_customer_app/pages/user/login_with_password_page.dart'; +// import 'package:car_customer_app/pages/user/profile/profile_1_page.dart'; +// import 'package:car_customer_app/pages/user/profile/profile_2_page.dart'; +// import 'package:car_customer_app/pages/user/profile/profile_3_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/splash_page.dart'; +import 'package:car_customer_app/pages/user/vertify_password_page.dart'; import 'package:flutter/material.dart'; -import 'package:car_customer_app/pages/user/confirm_new_password.dart'; class AppRoutes { //User @@ -23,11 +36,25 @@ class AppRoutes { static final String loginWithPassword = "/loginWithPassword"; static final String loginMethodSelection = "/loginMethodSelection"; static final String completeProfile = "/completeProfile"; - + static final String profile1 = "/profile1"; + static final String profile2 = "/profile2"; + static final String profile3 = "/profile3"; + static final String vertifyPassword = "/vertifyPassword"; static final String confirmNewPasswordPage = "/confirmNewPasswordPage"; + static final String defineLicense = "/defineLicese"; + static final String changePassword = "/changePassword"; + static final String forgetPasswordMethodPage = "/forgetPasswordMethodPage"; + static final String changeMobilePage = "/changeMobilePage"; + static final String changeEmailPage = "/changeEmailPage"; + static final String editAccoundPage = "/editAccoundPage"; static final String dashboard = "/dashboard"; + //settings + static final String dealershipSetting = "/dealershipSetting"; + static final String defineBranch = "/defineBranch"; + static final String createServices = "/createServices"; + static final String initialRoute = splash; static final Map routes = { @@ -41,9 +68,23 @@ class AppRoutes { loginWithPassword: (context) => LoginWithPassword(), loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String), completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUser), + // profile1: (context) => Profile1Page(), + // profile2: (context) => Profile2Page(), + // profile3: (context) => Profile3Page(), + // defineLicense: (context) => DefineLicensePage(), + vertifyPassword: (context) => VerifyPasswordPage(), confirmNewPasswordPage: (context) => ConfirmNewPasswordPage(ModalRoute.of(context)!.settings.arguments as String), - + changePassword: (context) => ChangePasswordPage(), + forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String), + changeMobilePage: (context) => ChangeMobilePage(), + changeEmailPage : (context) => ChangeEmailPage(), + editAccoundPage : (context) => EditAccountPage(), //Home page dashboard: (context) => DashboardPage(), + + //setting + // dealershipSetting: (context) => DealershipPage(), + // defineBranch: (context) => DefineBranchPage(), + // createServices: (context) => CreateServicesPage(), }; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9b8fc19..dbcde00 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -76,6 +76,10 @@ extension EmailValidator on String { return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); } + bool isNum() { + return RegExp(r'[0-9]').hasMatch(this); + } + String toFormattedDate() { String date = this.split("T")[0]; String time = this.split("T")[1]; diff --git a/lib/models/account.dart b/lib/models/account.dart index 8657751..1cfb548 100644 --- a/lib/models/account.dart +++ b/lib/models/account.dart @@ -8,6 +8,7 @@ import 'package:car_customer_app/models/parent_list.dart'; + Account accountFromJson(String str) => Account.fromJson(json.decode(str)); String accountToJson(Account data) => json.encode(data.toJson()); diff --git a/lib/models/m_response.dart b/lib/models/m_response.dart new file mode 100644 index 0000000..bd9d3a1 --- /dev/null +++ b/lib/models/m_response.dart @@ -0,0 +1,33 @@ +// To parse this JSON data, do +// +// final mResponse = mResponseFromJson(jsonString); + +import 'dart:convert'; + +MResponse mResponseFromJson(String str) => MResponse.fromJson(json.decode(str)); + +String mResponseToJson(MResponse data) => json.encode(data.toJson()); + +class MResponse { + MResponse({ + this.totalItemsCount, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + int? messageStatus; + String? message; + + factory MResponse.fromJson(Map json) => MResponse( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} diff --git a/lib/models/profile/branch.dart b/lib/models/profile/branch.dart new file mode 100644 index 0000000..cc7d68a --- /dev/null +++ b/lib/models/profile/branch.dart @@ -0,0 +1,85 @@ +// To parse this JSON data, do +// +// final branch = branchFromJson(jsonString); + +import 'dart:convert'; + +Branch branchFromJson(String str) => Branch.fromJson(json.decode(str)); + +String branchToJson(Branch data) => json.encode(data.toJson()); + +class Branch { + Branch({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + List? data; + int? messageStatus; + String? message; + + factory Branch.fromJson(Map json) => Branch( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + data: json["data"] == null ? null : List.from(json["data"].map((x) => BranchData.fromJson(x))), + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "data": data == null ? null : List.from(data!.map((x) => x.toJson())), + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} + +class BranchData { + BranchData({ + this.id, + this.serviceProviderId, + this.branchName, + this.branchDescription, + this.cityId, + this.address, + this.latitude, + this.longitude, + this.status, + }); + + int? id; + int? serviceProviderId; + String? branchName; + String? branchDescription; + int? cityId; + String? address; + String? latitude; + String? longitude; + int? status; + + factory BranchData.fromJson(Map json) => BranchData( + id: json["id"] == null ? null : json["id"], + serviceProviderId: json["serviceProviderID"] == null ? null : json["serviceProviderID"], + branchName: json["branchName"] == null ? null : json["branchName"], + branchDescription: json["branchDescription"] == null ? null : json["branchDescription"], + cityId: json["cityID"] == null ? null : json["cityID"], + address: json["address"] == null ? null : json["address"], + latitude: json["latitude"] == null ? null : json["latitude"], + longitude: json["longitude"] == null ? null : json["longitude"], + status: json["status"] == null ? null : json["status"], + ); + + Map toJson() => { + "id": id == null ? null : id, + "serviceProviderID": serviceProviderId == null ? null : serviceProviderId, + "branchName": branchName == null ? null : branchName, + "branchDescription": branchDescription == null ? null : branchDescription, + "cityID": cityId == null ? null : cityId, + "address": address == null ? null : address, + "latitude": latitude == null ? null : latitude, + "longitude": longitude == null ? null : longitude, + "status": status == null ? null : status, + }; +} diff --git a/lib/models/profile/categroy.dart b/lib/models/profile/categroy.dart new file mode 100644 index 0000000..6f566f1 --- /dev/null +++ b/lib/models/profile/categroy.dart @@ -0,0 +1,69 @@ +// To parse this JSON data, do +// +// final category = categoryFromJson(jsonString); + +import 'dart:convert'; + +Category categoryFromJson(String str) => Category.fromJson(json.decode(str)); + +String categoryToJson(Category data) => json.encode(data.toJson()); + +class Category { + Category({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + List? data; + int? messageStatus; + String? message; + + factory Category.fromJson(Map json) => Category( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + data: json["data"] == null ? null : List.from(json["data"].map((x) => CategoryData.fromJson(x))), + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "data": data == null ? null : List.from(data!.map((x) => x.toJson())), + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} + +class CategoryData { + CategoryData({ + this.id, + this.categoryName, + this.categoryNameN, + this.serviceCategoryIconUrl, + this.serviceCategoryImageUrl, + }); + + int? id; + String? categoryName; + String? categoryNameN; + dynamic? serviceCategoryIconUrl; + dynamic? serviceCategoryImageUrl; + + factory CategoryData.fromJson(Map json) => CategoryData( + id: json["id"] == null ? null : json["id"], + categoryName: json["categoryName"] == null ? null : json["categoryName"], + categoryNameN: json["categoryNameN"] == null ? null : json["categoryNameN"], + serviceCategoryIconUrl: json["serviceCategoryIconUrl"], + serviceCategoryImageUrl: json["serviceCategoryImageUrl"], + ); + + Map toJson() => { + "id": id == null ? null : id, + "categoryName": categoryName == null ? null : categoryName, + "categoryNameN": categoryNameN == null ? null : categoryNameN, + "serviceCategoryIconUrl": serviceCategoryIconUrl, + "serviceCategoryImageUrl": serviceCategoryImageUrl, + }; +} diff --git a/lib/models/profile/document.dart b/lib/models/profile/document.dart new file mode 100644 index 0000000..da082b3 --- /dev/null +++ b/lib/models/profile/document.dart @@ -0,0 +1,83 @@ +// To parse this JSON data, do +// +// final document = documentFromJson(jsonString); + +import 'dart:convert'; + +Document documentFromJson(String str) => Document.fromJson(json.decode(str)); + +String documentToJson(Document data) => json.encode(data.toJson()); + +class Document { + Document({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + List? data; + int? messageStatus; + String? message; + + factory Document.fromJson(Map json) => Document( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + data: json["data"] == null ? null : List.from(json["data"].map((x) => DocumentData.fromJson(x))), + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "data": data == null ? null : List.from(data!.map((x) => x.toJson())), + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} + +class DocumentData { + DocumentData({ + this.id, + this.serviceProviderId, + this.documentId, + this.documentUrl, + this.status, + this.comment, + this.isActive, + this.document, + this.fileExt, + }); + + int? id; + int? serviceProviderId; + int? documentId; + dynamic? documentUrl; + int? status; + dynamic? comment; + bool? isActive; + String? document; + String? fileExt; + + factory DocumentData.fromJson(Map json) => DocumentData( + id: json["id"] == null ? null : json["id"], + serviceProviderId: json["serviceProviderID"] == null ? null : json["serviceProviderID"], + documentId: json["documentID"] == null ? null : json["documentID"], + documentUrl: json["documentURL"], + status: json["status"] == null ? null : json["status"], + comment: json["comment"], + isActive: json["isActive"] == null ? null : json["isActive"], + document: null, + fileExt: null, + ); + + Map toJson() => { + "id": id == null ? null : id, + "serviceProviderID": serviceProviderId == null ? null : serviceProviderId, + "documentID": documentId == null ? null : documentId, + "documentURL": documentUrl, + "status": status == null ? null : status, + "comment": comment, + "isActive": isActive == null ? null : isActive, + }; +} diff --git a/lib/models/profile/services.dart b/lib/models/profile/services.dart new file mode 100644 index 0000000..d296300 --- /dev/null +++ b/lib/models/profile/services.dart @@ -0,0 +1,80 @@ +// To parse this JSON data, do +// +// final services = servicesFromJson(jsonString); + +import 'dart:convert'; + +Services servicesFromJson(String str) => Services.fromJson(json.decode(str)); + +String servicesToJson(Services data) => json.encode(data.toJson()); + +class Services { + Services({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + List? data; + int? messageStatus; + String? message; + + factory Services.fromJson(Map json) => Services( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + data: json["data"] == null ? null : List.from(json["data"].map((x) => ServicesData.fromJson(x))), + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "data": data == null ? null : List.from(data!.map((x) => x.toJson())), + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} + +class ServicesData { + ServicesData({ + this.id, + this.description, + this.descriptionN, + this.serviceIconUrl, + this.serviceImageUrl, + this.serviceCategoryId, + this.categoryName, + this.isSelected, + }); + + int? id; + String? description; + String? descriptionN; + dynamic? serviceIconUrl; + dynamic? serviceImageUrl; + int? serviceCategoryId; + dynamic? categoryName; + bool? isSelected; + + factory ServicesData.fromJson(Map json) => ServicesData( + id: json["id"] == null ? null : json["id"], + description: json["description"] == null ? null : json["description"], + descriptionN: json["descriptionN"] == null ? null : json["descriptionN"], + serviceIconUrl: json["serviceIconUrl"], + serviceImageUrl: json["serviceImageUrl"], + serviceCategoryId: json["serviceCategoryID"] == null ? null : json["serviceCategoryID"], + categoryName: json["categoryName"], + isSelected: false, + ); + + Map toJson() => { + "id": id == null ? null : id, + "description": description == null ? null : description, + "descriptionN": descriptionN == null ? null : descriptionN, + "serviceIconUrl": serviceIconUrl, + "serviceImageUrl": serviceImageUrl, + "serviceCategoryID": serviceCategoryId == null ? null : serviceCategoryId, + "categoryName": categoryName, + }; +} diff --git a/lib/models/user/change_email.dart b/lib/models/user/change_email.dart new file mode 100644 index 0000000..f7f6af5 --- /dev/null +++ b/lib/models/user/change_email.dart @@ -0,0 +1,51 @@ + + +import 'dart:convert'; + +ChanEmail changeEmailFromJson(String str) => ChanEmail.fromJson(json.decode(str)); + +String changeEmailToJson(ChanEmail data) => json.encode(data.toJson()); + +class ChanEmail { + int? messageStatus; + Null? totalItemsCount; + Data? data; + String? message; + + ChanEmail( + {this.messageStatus, this.totalItemsCount, this.data, this.message}); + + ChanEmail.fromJson(Map json) { + messageStatus = json['messageStatus']; + totalItemsCount = json['totalItemsCount']; + data = json['data'] != null ? new Data.fromJson(json['data']) : null; + message = json['message']; + } + + Map toJson() { + final Map data = new Map(); + data['messageStatus'] = this.messageStatus; + data['totalItemsCount'] = this.totalItemsCount; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + data['message'] = this.message; + return data; + } +} + +class Data { + String? userToken; + + Data({this.userToken}); + + Data.fromJson(Map json) { + userToken = json['userToken']; + } + + Map toJson() { + final Map data = new Map(); + data['userToken'] = this.userToken; + return data; + } +} \ No newline at end of file diff --git a/lib/models/user/change_mobile.dart b/lib/models/user/change_mobile.dart new file mode 100644 index 0000000..fed5923 --- /dev/null +++ b/lib/models/user/change_mobile.dart @@ -0,0 +1,51 @@ + + +import 'dart:convert'; + +ChangeMobile changeMobileFromJson(String str) => ChangeMobile.fromJson(json.decode(str)); + +String changeMobileToJson(ChangeMobile data) => json.encode(data.toJson()); + +class ChangeMobile { + int? messageStatus; + Null? totalItemsCount; + Data? data; + String? message; + + ChangeMobile( + {this.messageStatus, this.totalItemsCount, this.data, this.message}); + + ChangeMobile.fromJson(Map json) { + messageStatus = json['messageStatus']; + totalItemsCount = json['totalItemsCount']; + data = json['data'] != null ? new Data.fromJson(json['data']) : null; + message = json['message']; + } + + Map toJson() { + final Map data = new Map(); + data['messageStatus'] = this.messageStatus; + data['totalItemsCount'] = this.totalItemsCount; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + data['message'] = this.message; + return data; + } +} + +class Data { + String? userToken; + + Data({this.userToken}); + + Data.fromJson(Map json) { + userToken = json['userToken']; + } + + Map toJson() { + final Map data = new Map(); + data['userToken'] = this.userToken; + return data; + } +} \ No newline at end of file diff --git a/lib/models/user/change_password.dart b/lib/models/user/change_password.dart new file mode 100644 index 0000000..fc74d4b --- /dev/null +++ b/lib/models/user/change_password.dart @@ -0,0 +1,34 @@ + + + +import 'dart:convert'; + +ChangePassword changePasswordFromJson(String str) => ChangePassword.fromJson(json.decode(str)); + +String changePasswordToJson(ChangePassword data) => json.encode(data.toJson()); + +class ChangePassword { + int? messageStatus; + Null? totalItemsCount; + bool? data; + String? message; + + ChangePassword( + {this.messageStatus, this.totalItemsCount, this.data, this.message}); + + ChangePassword.fromJson(Map json) { + messageStatus = json['messageStatus']; + totalItemsCount = json['totalItemsCount']; + data = json['data']; + message = json['message']; + } + + Map toJson() { + final Map data = new Map(); + data['messageStatus'] = this.messageStatus; + data['totalItemsCount'] = this.totalItemsCount; + data['data'] = this.data; + data['message'] = this.message; + return data; + } +} \ No newline at end of file diff --git a/lib/models/user/cities.dart b/lib/models/user/cities.dart new file mode 100644 index 0000000..5c32405 --- /dev/null +++ b/lib/models/user/cities.dart @@ -0,0 +1,65 @@ +// To parse this JSON data, do +// +// final cities = citiesFromJson(jsonString); + +import 'dart:convert'; + +Cities citiesFromJson(String str) => Cities.fromJson(json.decode(str)); + +String citiesToJson(Cities data) => json.encode(data.toJson()); + +class Cities { + Cities({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + List? data; + int? messageStatus; + String? message; + + factory Cities.fromJson(Map json) => Cities( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + data: json["data"] == null ? null : List.from(json["data"].map((x) => CityData.fromJson(x))), + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "data": data == null ? null : List.from(data!.map((x) => x.toJson())), + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} + +class CityData { + CityData({ + this.id, + this.cityName, + this.cityNameN, + this.countryId, + }); + + int? id; + String? cityName; + String? cityNameN; + int? countryId; + + factory CityData.fromJson(Map json) => CityData( + id: json["id"] == null ? null : json["id"], + cityName: json["cityName"] == null ? null : json["cityName"], + cityNameN: json["cityNameN"] == null ? null : json["cityNameN"], + countryId: json["countryID"] == null ? null : json["countryID"], + ); + + Map toJson() => { + "id": id == null ? null : id, + "cityName": cityName == null ? null : cityName, + "cityNameN": cityNameN == null ? null : cityNameN, + "countryID": countryId == null ? null : countryId, + }; +} diff --git a/lib/models/user/confirm_email.dart b/lib/models/user/confirm_email.dart new file mode 100644 index 0000000..e64dc25 --- /dev/null +++ b/lib/models/user/confirm_email.dart @@ -0,0 +1,51 @@ + + +import 'dart:convert'; + +ConfirmEmail confirmEmailFromJson(String str) => ConfirmEmail.fromJson(json.decode(str)); + +String confirmEmailToJson(ConfirmEmail data) => json.encode(data.toJson()); + +class ConfirmEmail { + int? messageStatus; + Null? totalItemsCount; + Data? data; + String? message; + + ConfirmEmail( + {this.messageStatus, this.totalItemsCount, this.data, this.message}); + + ConfirmEmail.fromJson(Map json) { + messageStatus = json['messageStatus']; + totalItemsCount = json['totalItemsCount']; + data = json['data'] != null ? new Data.fromJson(json['data']) : null; + message = json['message']; + } + + Map toJson() { + final Map data = new Map(); + data['messageStatus'] = this.messageStatus; + data['totalItemsCount'] = this.totalItemsCount; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + data['message'] = this.message; + return data; + } +} + +class Data { + String? userID; + + Data({this.userID}); + + Data.fromJson(Map json) { + userID = json['userID']; + } + + Map toJson() { + final Map data = new Map(); + data['userID'] = this.userID; + return data; + } +} \ No newline at end of file diff --git a/lib/models/user/confirm_mobile.dart b/lib/models/user/confirm_mobile.dart new file mode 100644 index 0000000..5ea817b --- /dev/null +++ b/lib/models/user/confirm_mobile.dart @@ -0,0 +1,53 @@ + + + +import 'dart:convert'; + +ConfirmMobile confirmMobileFromJson(String str) => ConfirmMobile.fromJson(json.decode(str)); + +String confirmMobileToJson(ConfirmMobile data) => json.encode(data.toJson()); + + +class ConfirmMobile { + int? messageStatus; + Null? totalItemsCount; + Data? data; + String? message; + + ConfirmMobile( + {this.messageStatus, this.totalItemsCount, this.data, this.message}); + + ConfirmMobile.fromJson(Map json) { + messageStatus = json['messageStatus']; + totalItemsCount = json['totalItemsCount']; + data = json['data'] != null ? new Data.fromJson(json['data']) : null; + message = json['message']; + } + + Map toJson() { + final Map data = new Map(); + data['messageStatus'] = this.messageStatus; + data['totalItemsCount'] = this.totalItemsCount; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + data['message'] = this.message; + return data; + } +} + +class Data { + String? userID; + + Data({this.userID}); + + Data.fromJson(Map json) { + userID = json['userID']; + } + + Map toJson() { + final Map data = new Map(); + data['userID'] = this.userID; + return data; + } +} \ No newline at end of file diff --git a/lib/models/user/confirm_password.dart b/lib/models/user/confirm_password.dart index ce87f4c..03891f9 100644 --- a/lib/models/user/confirm_password.dart +++ b/lib/models/user/confirm_password.dart @@ -1,6 +1,4 @@ - - import 'dart:convert'; ConfirmPassword confirmPasswordFromJson(String str) => ConfirmPassword.fromJson(json.decode(str)); diff --git a/lib/models/user/forget_password_otp_compare.dart b/lib/models/user/forget_password_otp_compare.dart index 9376d00..20c260b 100644 --- a/lib/models/user/forget_password_otp_compare.dart +++ b/lib/models/user/forget_password_otp_compare.dart @@ -1,5 +1,3 @@ - - import 'dart:convert'; PasswordOTPCompare otpCompareFromJson(String str) => PasswordOTPCompare.fromJson(json.decode(str)); diff --git a/lib/models/user/forget_password_otp_request.dart b/lib/models/user/forget_password_otp_request.dart index e7954bb..7ab7e5c 100644 --- a/lib/models/user/forget_password_otp_request.dart +++ b/lib/models/user/forget_password_otp_request.dart @@ -1,6 +1,4 @@ - - import 'dart:convert'; PasswordOTPRequest otpRequestFromJson(String str) => PasswordOTPRequest.fromJson(json.decode(str)); diff --git a/lib/models/user/image_response.dart b/lib/models/user/image_response.dart new file mode 100644 index 0000000..6ca0b41 --- /dev/null +++ b/lib/models/user/image_response.dart @@ -0,0 +1,37 @@ +// To parse this JSON data, do +// +// final imageResponse = imageResponseFromJson(jsonString); + +import 'dart:convert'; + +ImageResponse imageResponseFromJson(String str) => ImageResponse.fromJson(json.decode(str)); + +String imageResponseToJson(ImageResponse data) => json.encode(data.toJson()); + +class ImageResponse { + ImageResponse({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + dynamic? totalItemsCount; + String? data; + int? messageStatus; + String? message; + + factory ImageResponse.fromJson(Map json) => ImageResponse( + totalItemsCount: json["totalItemsCount"], + data: json["data"] == null ? null : json["data"], + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount, + "data": data == null ? null : data, + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} diff --git a/lib/models/user/role.dart b/lib/models/user/role.dart new file mode 100644 index 0000000..2ea0054 --- /dev/null +++ b/lib/models/user/role.dart @@ -0,0 +1,65 @@ +// To parse this JSON data, do +// +// final role = roleFromJson(jsonString); + +import 'dart:convert'; + +Role roleFromJson(String str) => Role.fromJson(json.decode(str)); + +String roleToJson(Role data) => json.encode(data.toJson()); + +class Role { + Role({ + this.totalItemsCount, + this.data, + this.messageStatus, + this.message, + }); + + int? totalItemsCount; + List? data; + int? messageStatus; + String? message; + + factory Role.fromJson(Map json) => Role( + totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], + data: json["data"] == null ? null : List.from(json["data"].map((x) => RoleData.fromJson(x))), + messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], + message: json["message"] == null ? null : json["message"], + ); + + Map toJson() => { + "totalItemsCount": totalItemsCount == null ? null : totalItemsCount, + "data": data == null ? null : List.from(data!.map((x) => x.toJson())), + "messageStatus": messageStatus == null ? null : messageStatus, + "message": message == null ? null : message, + }; +} + +class RoleData { + RoleData({ + this.id, + this.roleName, + this.roleNameN, + this.isActive, + }); + + int? id; + String? roleName; + String? roleNameN; + bool? isActive; + + factory RoleData.fromJson(Map json) => RoleData( + id: json["id"] == null ? null : json["id"], + roleName: json["roleName"] == null ? null : json["roleName"], + roleNameN: json["roleNameN"] == null ? null : json["roleNameN"], + isActive: json["isActive"] == null ? null : json["isActive"], + ); + + Map toJson() => { + "id": id == null ? null : id, + "roleName": roleName == null ? null : roleName, + "roleNameN": roleNameN == null ? null : roleNameN, + "isActive": isActive == null ? null : isActive, + }; +} diff --git a/lib/models/user/verify_email.dart b/lib/models/user/verify_email.dart new file mode 100644 index 0000000..bf0858f --- /dev/null +++ b/lib/models/user/verify_email.dart @@ -0,0 +1,53 @@ + + + +import 'dart:convert'; + +VerifyEmail verifyEmailFromJson(String str) => VerifyEmail.fromJson(json.decode(str)); + +String verifyEmailToJson(VerifyEmail data) => json.encode(data.toJson()); + + +class VerifyEmail { + Null? totalItemsCount; + Data? data; + int? messageStatus; + String? message; + + VerifyEmail( + {this.totalItemsCount, this.data, this.messageStatus, this.message}); + + VerifyEmail.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + data = json['data'] != null ? new Data.fromJson(json['data']) : null; + messageStatus = json['messageStatus']; + message = json['message']; + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + data['messageStatus'] = this.messageStatus; + data['message'] = this.message; + return data; + } +} + +class Data { + String? userToken; + + Data({this.userToken}); + + Data.fromJson(Map json) { + userToken = json['userToken']; + } + + Map toJson() { + final Map data = new Map(); + data['userToken'] = this.userToken; + return data; + } +} \ No newline at end of file diff --git a/lib/models/user/verify_email_otp.dart b/lib/models/user/verify_email_otp.dart new file mode 100644 index 0000000..aa0827c --- /dev/null +++ b/lib/models/user/verify_email_otp.dart @@ -0,0 +1,27 @@ + + + +import 'dart:convert'; + +VerifyEmailOTP verifyEmailOTPFromJson(String str) => VerifyEmailOTP.fromJson(json.decode(str)); + +String verifyEmailOTPToJson(VerifyEmailOTP data) => json.encode(data.toJson()); + +class VerifyEmailOTP { + bool? success; + Null? errors; + + VerifyEmailOTP({this.success, this.errors}); + + VerifyEmailOTP.fromJson(Map json) { + success = json['success']; + errors = json['errors']; + } + + Map toJson() { + final Map data = new Map(); + data['success'] = this.success; + data['errors'] = this.errors; + return data; + } +} \ No newline at end of file diff --git a/lib/pages/dashboard/dashboard_page.dart b/lib/pages/dashboard/dashboard_page.dart index 91caad2..fd052f2 100644 --- a/lib/pages/dashboard/dashboard_page.dart +++ b/lib/pages/dashboard/dashboard_page.dart @@ -8,6 +8,17 @@ import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:flutter/material.dart'; +import '../../api/client/user_api_client.dart'; +import '../../classes/app_state.dart'; +import '../../classes/consts.dart'; +import 'package:image_picker/image_picker.dart'; +import 'dart:io'; + +import '../../classes/utils.dart'; +import '../../config/routes.dart'; +import '../../models/user/image_response.dart'; +import '../../utils/utils.dart'; + class DashboardPage extends StatefulWidget { @override State createState() => _DashboardPageState(); @@ -16,6 +27,15 @@ class DashboardPage extends StatefulWidget { class _DashboardPageState extends State { String userName = ""; + // void _handleURLButtonPress(BuildContext context, var type) { + // Navigator.push(context, + // MaterialPageRoute(builder: (context) => ImageFromGalleryEx(type))); + // } + + File? imagePicked; + String image64 = ""; + final _picker = ImagePicker(); + @override void initState() { // TODO: implement initState @@ -48,16 +68,66 @@ class _DashboardPageState extends State { child: Container( child: Column( children: [ - Container( - width: double.infinity, - height: 200, - color: accentColor.withOpacity(0.3), - child: Icon( - Icons.person, - size: 80, + Stack(children: [ + Container( + width: double.infinity, + height: 200, color: accentColor.withOpacity(0.3), + child: Image.network(ApiConsts.baseUrlServices + AppState().getUser.data!.userInfo!.userImageUrl.toString()), ), - ), + Positioned( + top: 10, + right: 10, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + children: [ + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(30), + ), + child: Icon( + Icons.edit, + color: Colors.blue, + ).onPress(() { + _openImagePicker(); + // _handleURLButtonPress(context, ImageSourceType.camera); + }), + ), + 12.height, + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(30), + ), + child: Icon( + Icons.delete, + color: Colors.blue, + ).onPress(() async { + Utils.showLoading(context); + ImageResponse response = await UserApiClent().UpdateUserImage(""); + if (response.messageStatus == 1) { + Utils.showToast("Image is Deleted"); + setState(() { + AppState().getUser.data!.userInfo!.userImageUrl = response.data; + }); + } + Utils.hideLoading(context); + }), + ), + ], + ), + ], + ), + ) + ]), Container( width: double.infinity, color: accentColor.withOpacity(0.1), @@ -76,7 +146,9 @@ class _DashboardPageState extends State { ), ShowFillButton( title: "EDIT", - onPressed: () {}, + onPressed: () { + navigateWithName(context, AppRoutes.editAccoundPage); + }, ), ], ), @@ -106,4 +178,80 @@ class _DashboardPageState extends State { ), ); } + + void _openImagePicker() { + showDialog( + context: context, + builder: (context) => AlertDialog(content: Text("Choose image source"), actions: [ + FlatButton(child: Text("Camera"), onPressed: () => cameraImage()), + FlatButton(child: Text("Gallery"), onPressed: () => gallaryImage()), + ]), + // .then((ImageSource source) async { + // if (source != null) { + // final pickedFile = await ImagePicker().getImage(source: source); + // setState(() => imagePicked = File(pickedFile.path)); + // } + // } + ); + } + + void gallaryImage() async { + final picker = ImagePicker(); + final pickedImage = await picker.pickImage( + source: ImageSource.gallery, + ); + final pickedImageFile = File(pickedImage!.path); + int sizeInBytes = pickedImageFile.lengthSync(); + // double sizeInMb = sizeInBytes / (1024 * 1024); + if (sizeInBytes > 1000) { + Utils.showToast("File is larger then 1KB"); + } else { + image64 = convertFileToBase64(pickedImageFile); + + Utils.showLoading(context); + ImageResponse response = await UserApiClent().UpdateUserImage(image64); + Utils.hideLoading(context); + Navigator.pop(context); + if (response.messageStatus == 1) { + Utils.showToast("Image is uploaded"); + AppState().getUser.data!.userInfo!.userImageUrl = response.data; + } else { + Utils.showToast(response.message ?? ""); + } + + setState(() { + imagePicked = pickedImageFile; + }); + } + } + + void cameraImage() async { + final picker = ImagePicker(); + final pickedImage = await picker.pickImage( + source: ImageSource.camera, + ); + final pickedImageFile = File(pickedImage!.path); + int sizeInBytes = pickedImageFile.lengthSync(); + // double sizeInMb = sizeInBytes / (1024 * 1024); + if (sizeInBytes > 1000) { + Utils.showToast("File is larger then 1KB"); + } else { + image64 = convertFileToBase64(pickedImageFile); + + Utils.showLoading(context); + ImageResponse response = await UserApiClent().UpdateUserImage(image64); + Utils.hideLoading(context); + Navigator.pop(context); + if (response.messageStatus == 1) { + Utils.showToast("Image is uploaded"); + AppState().getUser.data!.userInfo!.userImageUrl = response.data; + } else { + Utils.showToast(response.message ?? ""); + } + + setState(() { + imagePicked = pickedImageFile; + }); + } + } } diff --git a/lib/pages/user/change_email_page.dart b/lib/pages/user/change_email_page.dart new file mode 100644 index 0000000..27f4db0 --- /dev/null +++ b/lib/pages/user/change_email_page.dart @@ -0,0 +1,116 @@ + +import 'package:car_customer_app/api/client/user_api_client.dart'; +import 'package:car_customer_app/classes/utils.dart'; +import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/models/user/change_email.dart'; +import 'package:car_customer_app/models/user/confirm_email.dart'; +import 'package:car_customer_app/utils/navigator.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:flutter/material.dart'; + +import 'dart:convert'; +import 'package:http/http.dart'; + +class ChangeEmailPage extends StatefulWidget { + + @override + State createState() => _ChangeEmailPageState(); +} + +class _ChangeEmailPageState extends State { + String password = ""; + String email = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Change Email"), + body: SingleChildScrollView( + child: Container( + // width: double.infinity, + // height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + "Enter Email".toText24(), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter New Email", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: false, + onChanged: (v) => email = v, + ), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter Current Password", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: true, + onChanged: (v) => password = v, + ), + 40.height, + ShowFillButton( + title: "Confirm", + width: double.infinity, + onPressed: () { + changeEmail(context); + }, + ), + ], + ), + ), + ), + ); + } + + Future changeEmail(BuildContext context) async { + Utils.showLoading(context); + ChanEmail otpRequest = await UserApiClent().ChangeEmailOTPRequest(email, password); + Utils.hideLoading(context); + if (otpRequest.messageStatus == 1) { + showMDialog(context, child: OtpDialog( + onClick: (String code) async { + pop(context); + Utils.showLoading(context); + ConfirmEmail otpCompare = await UserApiClent().ChangeEmail(otpRequest.data!.userToken ?? "", code); + Utils.hideLoading(context); + if (otpCompare.messageStatus == 1) { + showMDialog( + context, + child: MessageDialog( + title: "Email is Changed Successfully", + onClick: () { + Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.loginWithPassword, (Route route) => false); + }, + ), + ); + } else { + Utils.showToast(otpCompare.message ?? ""); + } + }, + )); + } else { + Utils.showToast(otpRequest.message ?? ""); + } + } + +} diff --git a/lib/pages/user/change_mobile_page.dart b/lib/pages/user/change_mobile_page.dart new file mode 100644 index 0000000..a2455f4 --- /dev/null +++ b/lib/pages/user/change_mobile_page.dart @@ -0,0 +1,119 @@ + +import 'package:car_customer_app/api/client/user_api_client.dart'; +import 'package:car_customer_app/classes/utils.dart'; +import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/models/user/change_mobile.dart'; +import 'package:car_customer_app/models/user/confirm_mobile.dart'; +import 'package:car_customer_app/utils/navigator.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:flutter/material.dart'; + +import 'dart:convert'; +import 'package:http/http.dart'; + +class ChangeMobilePage extends StatefulWidget { + + @override + State createState() => _ChangeMobilePageState(); +} + +class _ChangeMobilePageState extends State { + int countryID=1 ; + String mobileNo = ''; + String password = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Change Mobile Number"), + body: SingleChildScrollView( + child: Container( + // width: double.infinity, + // height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + "Enter New Phone Number".toText24(), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter New Phone Number", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: false, + onChanged: (v) => mobileNo = v, + ), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter Current Password", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: true, + onChanged: (v) => password = v, + ), + 40.height, + ShowFillButton( + title: "Confirm", + width: double.infinity, + onPressed: () { + changeMobile(context); + }, + ), + ], + ), + ), + ), + ); + } + + Future changeMobile(BuildContext context) async { + Utils.showLoading(context); + ChangeMobile otpRequest = await UserApiClent().ChangeMobileNoOTPRequest(countryID, mobileNo, password); + Utils.hideLoading(context); + if (otpRequest.messageStatus == 1) { + showMDialog(context, child: OtpDialog( + onClick: (String code) async { + pop(context); + Utils.showLoading(context); + ConfirmMobile otpCompare = await UserApiClent().ChangeMobileNo(otpRequest.data!.userToken ?? "", code); + Utils.hideLoading(context); + if (otpCompare.messageStatus == 1) { + showMDialog( + context, + child: MessageDialog( + title: "Phone Number Verified", + onClick: () { + Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.loginWithPassword, (Route route) => false); + }, + ), + ); + } else { + Utils.showToast(otpCompare.message ?? ""); + } + }, + )); + } else { + Utils.showToast(otpRequest.message ?? ""); + } + } + + + +} diff --git a/lib/pages/user/change_password_page.dart b/lib/pages/user/change_password_page.dart new file mode 100644 index 0000000..18e8214 --- /dev/null +++ b/lib/pages/user/change_password_page.dart @@ -0,0 +1,112 @@ +import 'package:car_customer_app/api/client/user_api_client.dart'; + +import 'package:car_customer_app/classes/utils.dart'; +import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/models/user/change_password.dart'; +import 'package:car_customer_app/models/user/confirm_password.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/dialog/dialogs.dart'; +import 'package:car_customer_app/widgets/dialog/message_dialog.dart'; +import 'package:car_customer_app/widgets/show_fill_button.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/widgets/txt_field.dart'; +import 'package:flutter/material.dart'; + +import 'dart:convert'; +import 'package:http/http.dart'; + +import '../../models/m_response.dart'; + +class ChangePasswordPage extends StatefulWidget { + ChangePasswordPage({Key? key}) : super(key: key); + + @override + State createState() => _ChangePasswordPageState(); +} + +class _ChangePasswordPageState extends State { + String newPassword = ""; + String currentPasswor = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Change Password"), + body: SingleChildScrollView( + child: Container( + // width: double.infinity, + // height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + "Enter New Password".toText24(), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter Old Password", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: true, + onChanged: (v) => currentPasswor = v, + ), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter New Password", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: true, + onChanged: (v) => newPassword = v, + ), + 40.height, + ShowFillButton( + title: "Confirm", + width: double.infinity, + onPressed: () { + changePassword(context); + }, + ), + ], + ), + ), + ), + ); + } + + Future changePassword(BuildContext context) async { + if (validateStructure(newPassword ?? "")) { + Utils.showLoading(context); + MResponse res = await UserApiClent().ChangePassword(currentPasswor, newPassword); + Utils.hideLoading(context); + if (res.messageStatus == 1) { + Utils.showToast("Password is Updated"); + // navigateWithName(context, AppRoutes.loginWithPassword); + Navigator.of(context) + .pushNamedAndRemoveUntil(AppRoutes.loginWithPassword, (Route route) => false); + } else { + Utils.showToast(res.message ?? ""); + } + } else { + Utils.showToast("Password Should contains Character, Number, Capital and small letters"); + } + } + + bool validateStructure(String value) { + String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{6,}$'; + RegExp regExp = new RegExp(pattern); + return regExp.hasMatch(value); + } +} diff --git a/lib/pages/user/complete_profile_page.dart b/lib/pages/user/complete_profile_page.dart index 162cf22..b5f7791 100644 --- a/lib/pages/user/complete_profile_page.dart +++ b/lib/pages/user/complete_profile_page.dart @@ -1,6 +1,7 @@ -import 'package:car_customer_app/api/user_api_client.dart'; +import 'package:car_customer_app/api/client/user_api_client.dart'; import 'package:car_customer_app/classes/utils.dart'; import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/models/m_response.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'; @@ -27,6 +28,7 @@ class CompleteProfilePage extends StatefulWidget { class _CompleteProfilePageState extends State { String? firstName = "", lastName = "", email = "", password = "", confirmPassword = ""; + bool isChecked = false; @override void initState() { @@ -43,21 +45,23 @@ class _CompleteProfilePageState extends State { height: double.infinity, child: SingleChildScrollView( child: Padding( - padding: EdgeInsets.all(40), + padding: EdgeInsets.all(20), child: Column( children: [ "Complete Profile".toText24(), 12.height, TxtField( - hint: "First Name", + hint: "First Name *", + value: firstName, onChanged: (v) { firstName = v; }, ), 12.height, TxtField( - hint: "Surname", + hint: "Surname *", + value: lastName, onChanged: (v) { lastName = v; }, @@ -65,24 +69,29 @@ class _CompleteProfilePageState extends State { 12.height, TxtField( hint: "Email", + value: email, + isButtonEnable: email!.length > 0 ? true : false, + buttonTitle: "Verify", onChanged: (v) { email = v; }, ), 12.height, TxtField( - hint: "Create Password", + hint: "Create Password *", isPasswordEnabled: true, maxLines: 1, + value: password, onChanged: (v) { password = v; }, ), 12.height, TxtField( - hint: "Confirm Password", + hint: "Confirm Password *", isPasswordEnabled: true, maxLines: 1, + value: confirmPassword, onChanged: (v) { confirmPassword = v; }, @@ -92,13 +101,18 @@ class _CompleteProfilePageState extends State { // hint: "Phone Number", // ), 50.height, - "By creating an account you agree to our Terms of Service and Privacy Policy".toText12(), + Row( + children: [ + buildCheckbox(), + "By creating an account you agree to our Terms of Service and\n Privacy Policy".toText12(), + ], + ), 16.height, ShowFillButton( title: "Continue", width: double.infinity, onPressed: () { - performCompleteProfile(); + if (validation()) performCompleteProfile(); }, ), ], @@ -109,21 +123,94 @@ class _CompleteProfilePageState extends State { ); } + Widget buildCheckbox() => Checkbox( + value: isChecked, + activeColor: Colors.blue, + onChanged: (value) { + setState(() { + isChecked = value!; + }); + }, + ); + + // Future performCompleteProfile() async { + // if(validateStructure(password??"")){ + // 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( "Successfully registered, Please login once"); + // pop(context); + // // pop(context); + // // navigateReplaceWithName(context, AppRoutes.dashboard,arguments: user); + // } else { + // Utils.showToast(user.message ?? ""); + // } + // } else { + // Utils.showToast("Please enter same password"); + // } + // }else{ + // Utils.showToast("Password Should contains character, Number, Capital and small letters"); + // } + // + // } + Future 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( "Successfully Registered, Please login once"); - pop(context); - // navigateReplaceWithName(context, AppRoutes.dashboard,arguments: user); + if (validateStructure(password ?? "")) { + 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("Successfully Registered, Please login once"); + pop(context); + // navigateReplaceWithName(context, AppRoutes.dashboard,arguments: user); + } else { + Utils.showToast(user.message ?? ""); + } } else { - Utils.showToast(user.message ?? ""); + Utils.showToast("Please enter same password"); } } else { - Utils.showToast("Please enter same password"); + Utils.showToast("Password Should contains Character, Number, Capital and small letters"); + } + } + + bool validateStructure(String value) { + String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{6,}$'; + RegExp regExp = new RegExp(pattern); + return regExp.hasMatch(value); + } + + bool isEmail(String em) { + String p = r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'; + RegExp regExp = new RegExp(p); + return regExp.hasMatch(em); + } + + bool validation() { + bool isValid = true; + if (firstName!.isEmpty) { + Utils.showToast("First name is mandatory"); + isValid = false; + } else if (lastName!.isEmpty) { + Utils.showToast("Surname is mandatory"); + isValid = false; + } else if (email!.isNotEmpty) { + if(!isEmail(email!)){ + Utils.showToast("Enter Valid Email"); + isValid = false; + } + }else if (password!.isEmpty) { + Utils.showToast("Password is mandatory"); + isValid = false; + } else if (!isChecked) { + Utils.showToast("Please accept terms"); + isValid = false; } + return isValid; } } diff --git a/lib/pages/user/confirm_new_password.dart b/lib/pages/user/confirm_new_password.dart index 851fa46..1231995 100644 --- a/lib/pages/user/confirm_new_password.dart +++ b/lib/pages/user/confirm_new_password.dart @@ -1,6 +1,6 @@ -import 'package:car_customer_app/api/user_api_client.dart'; + import 'package:car_customer_app/classes/utils.dart'; import 'package:car_customer_app/config/routes.dart'; import 'package:car_customer_app/extensions/int_extensions.dart'; @@ -15,6 +15,8 @@ import 'package:flutter/material.dart'; import 'dart:convert'; import 'package:http/http.dart'; +import '../../api/client/user_api_client.dart'; + class ConfirmNewPasswordPage extends StatelessWidget { String userToken; diff --git a/lib/pages/user/confirm_new_password_page.dart b/lib/pages/user/confirm_new_password_page.dart new file mode 100644 index 0000000..7d3cd0c --- /dev/null +++ b/lib/pages/user/confirm_new_password_page.dart @@ -0,0 +1,119 @@ +import 'package:car_customer_app/api/client/user_api_client.dart'; + +import 'package:car_customer_app/classes/utils.dart'; +import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/models/user/confirm_password.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/dialog/dialogs.dart'; +import 'package:car_customer_app/widgets/dialog/message_dialog.dart'; +import 'package:car_customer_app/widgets/show_fill_button.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/widgets/txt_field.dart'; +import 'package:flutter/material.dart'; + +import 'dart:convert'; +import 'package:http/http.dart'; + +class ConfirmNewPasswordPage extends StatefulWidget { + String userToken; + + ConfirmNewPasswordPage(this.userToken, {Key? key}) : super(key: key); + + @override + State createState() => _ConfirmNewPasswordPageState(); +} + +class _ConfirmNewPasswordPageState extends State { + String newPassword = ""; + String confirmPassword = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Forget Password"), + body: SingleChildScrollView( + child: Container( + // width: double.infinity, + // height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + "New Password".toText24(), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Enter New Password", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: true, + onChanged: (v) => newPassword = v, + ), + 12.height, + TextFormField( + decoration: InputDecoration( + hintText: "Confirm Password", + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(5.0), + ), + ), + ), + obscureText: true, + onChanged: (v) => confirmPassword = v, + ), + 40.height, + ShowFillButton( + title: "Confirm", + width: double.infinity, + onPressed: () { + if (validation()) confirmPasswordOTP(context); + }, + ), + ], + ), + ), + ), + ); + } + + Future confirmPasswordOTP(BuildContext context) async { + if(validateStructure(newPassword??"")){ + Utils.showLoading(context); + Response res = await UserApiClent().ForgetPassword(widget.userToken, newPassword); + Utils.hideLoading(context); + ConfirmPassword data = ConfirmPassword.fromJson(jsonDecode(res.body)); + if (data.messageStatus == 1) { + Utils.showToast("Password is Updated"); + navigateWithName(context, AppRoutes.loginWithPassword); + } else { + Utils.showToast(data.message ?? ""); + } + }else{ + Utils.showToast("Password Should contains Character, Number, Capital and small letters"); + } + } + + bool validation() { + bool isValid = true; + if (newPassword != confirmPassword) { + Utils.showToast("Confirmation password does not match the entered password"); + isValid = false; + } + return isValid; + } + + bool validateStructure(String value){ + String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{6,}$'; + RegExp regExp = new RegExp(pattern); + return regExp.hasMatch(value); + } +} diff --git a/lib/pages/user/edit_account_page.dart b/lib/pages/user/edit_account_page.dart new file mode 100644 index 0000000..a44de2e --- /dev/null +++ b/lib/pages/user/edit_account_page.dart @@ -0,0 +1,158 @@ +import 'dart:convert'; + +import 'package:car_customer_app/api/client/user_api_client.dart'; +import 'package:car_customer_app/classes/app_state.dart'; +import 'package:car_customer_app/classes/utils.dart'; +import 'package:car_customer_app/config/routes.dart'; +import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/models/m_response.dart'; +import 'package:car_customer_app/models/user/verify_email.dart'; +import 'package:car_customer_app/models/user/verify_email_otp.dart'; +import 'package:car_customer_app/utils/navigator.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:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class EditAccountPage extends StatefulWidget { + @override + State createState() => _EditAccountPageState(); +} + +class _EditAccountPageState extends State { + String userID = ""; + String email = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Edit Account"), + body: Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + 20.height, + ListTile( + leading: SvgPicture.asset("assets/images/ic_lock.svg"), + title: "Change Password".toText12(), + onTap: () { + navigateWithName(context, AppRoutes.changePassword); + }, + ), + 15.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + SvgPicture.asset("assets/images/ic_mobile.svg"), + "Change Mobile".toText12(), + "Verify".toText12(), + RaisedButton( + onPressed: () { + navigateWithName(context, AppRoutes.changeMobilePage); + }, + child: Text( + "Change", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + color: Colors.blue, + textColor: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8)) + ], + ), + 20.height, + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Icon( + Icons.email, + color: Colors.blue, + ), + "Change Email".toText12(), + InkWell( + child: ((AppState().getUser.data!.userInfo!.isEmailVerified ?? false) ? "Verified" : "Verify").toText12(), + onTap: (AppState().getUser.data!.userInfo!.isEmailVerified ?? false) + ? null + : () { + verifyEmail(context); + }, + ), + RaisedButton( + onPressed: () { + navigateWithName(context, AppRoutes.changeEmailPage); + }, + child: Text( + "Change", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + ), + ), + color: Colors.blue, + textColor: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8)) + ], + ) + + // ListTile( + // leading: SvgPicture.asset("assets/images/ic_mobile.svg"), + // title: "Change Mobile".toText12(), + // onTap: () { + // navigateWithName(context, AppRoutes.changeMobilePage); + // }, + // ), + // ListTile( + // leading: Icon(Icons.email_outlined, color: Colors.blue,), + // title: "Change Email".toText12(), + // onTap: () { + // navigateWithName(context, AppRoutes.changeEmailPage); + // }, + // ), + ], + ), + ), + ); + } + + Future verifyEmail(BuildContext context) async { + Utils.showLoading(context); + VerifyEmail otpRequest = await UserApiClent().EmailVerify(email, userID); + Utils.hideLoading(context); + if (otpRequest.messageStatus == 1) { + showMDialog(context, child: OtpDialog( + onClick: (String code) async { + pop(context); + Utils.showLoading(context); + MResponse otpCompare = await UserApiClent().EmailVerifyOTPVerify(otpRequest.data!.userToken ?? "", code); + Utils.hideLoading(context); + if (otpCompare.messageStatus == 1) { + AppState().getUser.data!.userInfo!.isEmailVerified = true; + setState(() {}); + Utils.showToast("Email is verified successfully"); + // Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.dashboard, (Route route) => false); + // showMDialog( + // context, + // child: MessageDialog( + // title: "Email is Verified", + // onClick: () { + // Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.dashboard, (Route route) => false); + // }, + // ), + // ); + } else { + Utils.showToast(otpCompare.message ?? ""); + } + }, + )); + } else { + Utils.showToast(otpRequest.message ?? ""); + } + } +} diff --git a/lib/pages/user/forget_password_method_page.dart b/lib/pages/user/forget_password_method_page.dart new file mode 100644 index 0000000..30e016c --- /dev/null +++ b/lib/pages/user/forget_password_method_page.dart @@ -0,0 +1,95 @@ + + + +import 'dart:convert'; +import 'package:car_customer_app/api/client/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/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/string_extensions.dart'; +import 'package:car_customer_app/models/user/forget_password_otp_compare.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/otp_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; + +class ForgetPasswordMethodPage extends StatefulWidget { + String userToken; + + ForgetPasswordMethodPage(this.userToken); + + @override + State createState() => _ForgetPasswordMethodPageState(); +} + +class _ForgetPasswordMethodPageState extends State { + int otpType = 1; + String userOTP = ""; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Forget Password"), + body: Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + "Select Method".toText24(), + 12.height, + Row( + children: [ + Expanded( + child: ShowImageButton( + onClick: () { + otpType = 1; + forgetPasswordOTPMethod(context); + }, + title: 'With SMS', + icon: icons + "ic_sms.png", + ), + ), + 20.width, + Expanded( + child: ShowImageButton( + onClick: () { + otpType = 1; + forgetPasswordOTPMethod(context); + }, + title: 'With Whatsapp', + icon: icons + "ic_whatsapp.png", + ), + ), + ], + ), + mFlex(10), + ], + ), + ), + ); + } + + Future forgetPasswordOTPMethod(BuildContext context) async { + showMDialog(context, child: OtpDialog( + onClick: (String code) async { + pop(context); + Utils.showLoading(context); + Response res = await UserApiClent().ForgetPasswordOTPCompare(widget.userToken?? "", code); + Utils.hideLoading(context); + PasswordOTPCompare otpCompare = PasswordOTPCompare.fromJson(jsonDecode(res.body)); + if (otpCompare.messageStatus == 1) { + var userToken = otpCompare.data!.userToken; + navigateWithName(context, AppRoutes.confirmNewPasswordPage, arguments: userToken); + } else { + Utils.showToast(otpCompare.message ?? ""); + } + }, + )); + } +} diff --git a/lib/pages/user/forget_password_page.dart b/lib/pages/user/forget_password_page.dart index 5469b91..71236b1 100644 --- a/lib/pages/user/forget_password_page.dart +++ b/lib/pages/user/forget_password_page.dart @@ -1,102 +1,154 @@ -import 'dart:convert'; +import 'package:car_customer_app/api/client/user_api_client.dart'; +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/forget_password_otp_compare.dart'; import 'package:car_customer_app/models/user/forget_password_otp_request.dart'; +import 'package:car_customer_app/pages/user/vertify_password_page.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/widgets/show_fill_button.dart'; import 'package:car_customer_app/extensions/string_extensions.dart'; import 'package:car_customer_app/extensions/int_extensions.dart'; +import 'package:car_customer_app/extensions/widget_extensions.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; +import 'package:car_customer_app/models/user/user.dart'; +import 'dart:convert'; import 'package:http/http.dart'; -class ForgetPasswordPage extends StatelessWidget { +import '../../models/user/country.dart'; +import '../../widgets/dropdown/dropdow_field.dart'; +import '../../widgets/tab/login_email_tab.dart'; + +class ForgetPasswordPage extends StatefulWidget { + @override + State createState() => _ForgetPasswordPageState(); +} + +class _ForgetPasswordPageState extends State { int otpType = 1; + String userName = ""; + ClassType type = ClassType.NUMBER; + Country? _country; + String countryCode = ""; + + @override + void initState() { + super.initState(); + getCountryList(); + } + + getCountryList() async { + _country = await UserApiClent().getAllCountries(); + setState(() {}); + } + @override Widget build(BuildContext context) { return Scaffold( - appBar: appBar(title: "Forget Password"), + appBar: appBar(title: "Change Password"), body: Container( width: double.infinity, height: double.infinity, padding: EdgeInsets.all(40), child: Column( children: [ + mFlex(1), + LoginEmailTab( + onSelection: (ClassType type) { + setState(() { + this.type = type; + }); + }, + ), + 50.height, "Retrieve Password".toText24(), 12.height, - TxtField( - hint: "Phone Number", + type == ClassType.NUMBER ? Column(children: [ + getCountry(), + TxtField( + hint: "5********", + value: userName, + onChanged: (v) { + userName = v; + }, + ) + ],) : TxtField( + hint: "Email Address", value: userName, onChanged: (v) { userName = v; }, ), - // TxtField( - // hint: "Email", - // ), - mFlex(2), - Row( - children: [ - Expanded( - child: ShowImageButton( - onClick: () { - otpType = 1; - forgetPasswordOTP(context); - }, - title: 'With SMS', - icon: icons + "ic_sms.png", - ), - ), - 20.width, - Expanded( - child: ShowImageButton( - onClick: () { - otpType = 1; - forgetPasswordOTP(context); - }, - title: 'With Whatsapp', - icon: icons + "ic_whatsapp.png", - ), - ), - ], + 50.height, + ShowFillButton( + title: "Continue", + width: double.infinity, + onPressed: () { + if (userName.isNum() && type==ClassType.NUMBER) { + forgetPasswordPhoneOTP(context); + } else if (!userName.isNum() && type==ClassType.EMAIL) { + forgetPasswordEmailOTP(context); + } + }, ), mFlex(10), - // 40.height, - // ShowFillButton( - // title: "Continue", - // width: double.infinity, - // onPressed: () { - // showMDialog( - // context, - // child: MessageDialog( - // title: "New Password sent used", - // ), - // ); - // }, - // ), ], ), ), ); } - Future forgetPasswordOTP(BuildContext context) async { + Widget getCountry() { + if (_country != null) { + List dropList = []; + _country!.data?.forEach((element) { + dropList.add(new DropValue(element.id ?? 0, (element.countryName ?? "") + " " + (element.countryCode ?? ""), element.countryCode ?? "")); + }); + return Padding( + padding: const EdgeInsets.all(2.0), + child: DropdownField((DropValue value) { + countryCode = value.subValue; + }, list: dropList, hint: "Chose Country"), + ); + } else { + return Center( + child: CircularProgressIndicator(), + ); + } + } + + Future forgetPasswordPhoneOTP(BuildContext context) async { + Utils.showLoading(context); + Response response = await UserApiClent().ForgetPasswordOTPRequest(countryCode+userName, otpType); + Utils.hideLoading(context); + PasswordOTPRequest otpRequest = PasswordOTPRequest.fromJson(jsonDecode(response.body)); + if (otpRequest.messageStatus == 1) { + var userToken = otpRequest.data!.userToken; + navigateReplaceWithName(context, AppRoutes.forgetPasswordMethodPage, arguments: userToken); + } else { + Utils.showToast(otpRequest.message ?? ""); + } + } + + Future forgetPasswordEmailOTP(BuildContext context) async { Utils.showLoading(context); Response response = await UserApiClent().ForgetPasswordOTPRequest(userName, otpType); Utils.hideLoading(context); PasswordOTPRequest otpRequest = PasswordOTPRequest.fromJson(jsonDecode(response.body)); if (otpRequest.messageStatus == 1) { + Utils.showToast("Code is sent to email"); showMDialog(context, child: OtpDialog( onClick: (String code) async { pop(context); @@ -106,6 +158,8 @@ class ForgetPasswordPage extends StatelessWidget { PasswordOTPCompare otpCompare = PasswordOTPCompare.fromJson(jsonDecode(res.body)); if (otpCompare.messageStatus == 1) { var userToken = otpCompare.data!.userToken; + print("token is ________"); + print(userToken); navigateWithName(context, AppRoutes.confirmNewPasswordPage, arguments: userToken); } else { Utils.showToast(otpCompare.message ?? ""); diff --git a/lib/pages/user/login_method_selection_page.dart b/lib/pages/user/login_method_selection_page.dart index 9f5d7e0..e43febf 100644 --- a/lib/pages/user/login_method_selection_page.dart +++ b/lib/pages/user/login_method_selection_page.dart @@ -1,7 +1,7 @@ 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/api/client/user_api_client.dart'; import 'package:car_customer_app/classes/app_state.dart'; import 'package:car_customer_app/classes/utils.dart'; import 'package:car_customer_app/config/constants.dart'; @@ -108,12 +108,19 @@ class LoginMethodSelectionPage extends StatelessWidget { Response response2 = await UserApiClent().login_V2_OTPVerify(user.data!.userToken??"", code); Utils.hideLoading(context); RegisterUser verifiedUser = RegisterUser.fromJson(jsonDecode(response2.body)); + if (verifiedUser.messageStatus == 1) { User user = User.fromJson(jsonDecode(response2.body)); - AppState().setUser = user; - SharedPrefManager.setUserToken(user.data!.accessToken ?? ""); - SharedPrefManager.setUserId(user.data!.userInfo!.userId ?? ""); - navigateReplaceWithName(context, AppRoutes.dashboard); + if(user.data!.userInfo!.roleId==5||user.data!.userInfo!.roleId==6){ + + AppState().setUser = user; + SharedPrefManager.setUserToken(user.data!.accessToken ?? ""); + SharedPrefManager.setUserId(user.data!.userInfo!.userId ?? ""); + navigateReplaceWithName(context, AppRoutes.dashboard); + }else{ + Utils.showToast("Sorry, Only Provider's can log in this app"); + } + } else { Utils.showToast(verifiedUser.message??""); } diff --git a/lib/pages/user/login_verification_page.dart b/lib/pages/user/login_verification_page.dart index cc95b05..0bee3ae 100644 --- a/lib/pages/user/login_verification_page.dart +++ b/lib/pages/user/login_verification_page.dart @@ -1,7 +1,7 @@ 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/api/client/user_api_client.dart'; import 'package:car_customer_app/classes/app_state.dart'; import 'package:car_customer_app/classes/utils.dart'; import 'package:car_customer_app/config/constants.dart'; @@ -48,7 +48,6 @@ class _LoginVerificationPageState extends State { LoginPassword user = LoginPassword.fromJson(jsonDecode(response.body)); if (user.messageStatus == 1) { userToken = user.data!.userToken ?? ""; - // navigateWithName(context, AppRoutes.loginMethodSelection, arguments: user.data!.userToken); } else { Utils.showToast(user.message ?? ""); @@ -72,6 +71,7 @@ class _LoginVerificationPageState extends State { if (verifiedUser.messageStatus == 1) { User user = User.fromJson(jsonDecode(response2.body)); AppState().setUser = user; + print(user.data!.userInfo!.providerId.toString()); navigateReplaceWithName(context, AppRoutes.dashboard); } else { Utils.showToast(verifiedUser.message ?? ""); diff --git a/lib/pages/user/login_verify_account_page.dart b/lib/pages/user/login_verify_account_page.dart index a2989f2..26fbf49 100644 --- a/lib/pages/user/login_verify_account_page.dart +++ b/lib/pages/user/login_verify_account_page.dart @@ -1,4 +1,4 @@ -import 'package:car_customer_app/api/user_api_client.dart'; +import 'package:car_customer_app/api/client/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'; @@ -128,7 +128,7 @@ class LoginVerifyAccountPage extends StatelessWidget { title: "Phone Number Verified", onClick: () { pop(context); - navigateWithName(context, AppRoutes.completeProfile,arguments: user); + navigateWithName(context, AppRoutes.profile1,arguments: user); }, ), ); diff --git a/lib/pages/user/login_with_password_page.dart b/lib/pages/user/login_with_password_page.dart index e5c9567..448a2ea 100644 --- a/lib/pages/user/login_with_password_page.dart +++ b/lib/pages/user/login_with_password_page.dart @@ -1,7 +1,7 @@ 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/api/client/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'; @@ -19,13 +19,38 @@ 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/tab/login_email_tab.dart'; import 'package:car_customer_app/widgets/txt_field.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; -class LoginWithPassword extends StatelessWidget { +import '../../models/user/country.dart'; +import '../../widgets/dropdown/dropdow_field.dart'; + +class LoginWithPassword extends StatefulWidget { + @override + State createState() => _LoginWithPasswordState(); +} + +class _LoginWithPasswordState extends State { int otpType = 1; + + ClassType type = ClassType.NUMBER; String phoneNum = "", password = ""; + String email = ""; + String countryCode = ""; + Country? _country; + + @override + void initState() { + super.initState(); + getCountryList(); + } + + getCountryList() async { + _country = await UserApiClent().getAllCountries(); + setState(() {}); + } @override Widget build(BuildContext context) { @@ -37,37 +62,52 @@ class LoginWithPassword extends StatelessWidget { padding: EdgeInsets.all(40), child: Column( children: [ - "Login".toText24(), - mFlex(1), - TxtField( - hint: "966501234567", - value: phoneNum, - onChanged: (v) { - phoneNum = v; + LoginEmailTab( + onSelection: (ClassType type) { + setState(() { + this.type = type; + }); }, ), - 12.height, - TxtField( - hint: "Password", - value: password, - isPasswordEnabled: true, - maxLines: 1, - onChanged: (v) { - password = v; - }, + 50.height, + (type == ClassType.NUMBER ? "Enter Phone" : "Enter Email").toText24(), + mFlex(1), + Column( + children: [ + if (type == ClassType.NUMBER) + getCountry(), + 6.height, + TxtField( + hint: type == ClassType.NUMBER ? "5********" : "Enter Email", + value: phoneNum, + onChanged: (v) { + phoneNum = v; + }, + ), + 6.height, + TxtField( + hint: "Enter Password?", + value: password, + isPasswordEnabled: true, + maxLines: 1, + onChanged: (v) { + password = v; + }, + ), + ], ), 10.height, Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - "Forget Password".toText12(color: Colors.blue).onPress(() { + "Forget Password?".toText12(color: Colors.blue).onPress(() { navigateWithName(context, AppRoutes.forgetPassword); }), ], ), 50.height, ShowFillButton( - title: "Continue", + title: "Log In", width: double.infinity, onPressed: () { performBasicOtp(context); @@ -80,17 +120,37 @@ class LoginWithPassword extends StatelessWidget { ); } + Widget getCountry() { + if (_country != null) { + List dropList = []; + _country!.data?.forEach((element) { + dropList.add(new DropValue(element.id ?? 0, (element.countryName ?? "") + " " + (element.countryCode ?? ""), element.countryCode ?? "")); + }); + return Padding( + padding: const EdgeInsets.all(2.0), + child: DropdownField((DropValue value) { + countryCode = value.subValue; + }, list: dropList, hint: "Chose Country"), + ); + } else { + return Center( + child: CircularProgressIndicator(), + ); + } + } + Future performBasicOtp(BuildContext context) async { Utils.showLoading(context); - Response response = await UserApiClent().login_V1(phoneNum, password); + Response response = await UserApiClent().login_V1(type == ClassType.NUMBER ? countryCode + phoneNum : phoneNum, password); Utils.hideLoading(context); LoginPassword user = LoginPassword.fromJson(jsonDecode(response.body)); if (user.messageStatus == 1) { - SharedPrefManager.setPhoneOrEmail(phoneNum); + SharedPrefManager.setPhoneOrEmail(type == ClassType.NUMBER ? countryCode + phoneNum : phoneNum); SharedPrefManager.setUserPassword(password); navigateReplaceWithName(context, AppRoutes.loginMethodSelection, arguments: user.data!.userToken); } else { Utils.showToast(user.message ?? ""); } } + } diff --git a/lib/pages/user/register_page.dart b/lib/pages/user/register_page.dart index 3d94e1b..fd17b8f 100644 --- a/lib/pages/user/register_page.dart +++ b/lib/pages/user/register_page.dart @@ -1,10 +1,12 @@ import 'package:car_customer_app/api/api_client.dart'; -import 'package:car_customer_app/api/user_api_client.dart'; +import 'package:car_customer_app/api/client/user_api_client.dart'; import 'package:car_customer_app/classes/utils.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/country.dart'; import 'package:car_customer_app/models/user/register_user.dart'; +import 'package:car_customer_app/models/user/role.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'; @@ -20,7 +22,8 @@ import 'package:flutter/material.dart'; class RegisterPage extends StatelessWidget { String phoneNum = "", countryCode = ""; - int role = -1, countryId = -1; + int role = 4, countryId = -1; + @override Widget build(BuildContext context) { return Scaffold( @@ -32,6 +35,23 @@ class RegisterPage extends StatelessWidget { child: Column( children: [ "Enter Phone Number".toText24(), + // 12.height, + // FutureBuilder( + // future: UserApiClent().getRoles(), + // builder: (context, snapshot) { + // if (snapshot.hasData) { + // List dropList = []; + // snapshot.data?.data?.forEach((element) { + // dropList.add(new DropValue(element.id ?? 0, element.roleName ?? "", "")); + // }); + // return DropdownField((DropValue value) { + // role = value.id; + // }, list: dropList, hint: "Chosse Role"); + // } else { + // return CircularProgressIndicator(); + // } + // }, + // ), 12.height, FutureBuilder( future: UserApiClent().getAllCountries(), @@ -44,14 +64,14 @@ class RegisterPage extends StatelessWidget { return DropdownField((DropValue value) { countryCode = value.subValue; countryId = value.id; - }, list: dropList, hint: "Chosse Country"); + }, list: dropList, hint: "Chose Country"); } else { return CircularProgressIndicator(); } }, ), TxtField( - hint: "Enter Phone number to Register", + hint: "5********", onChanged: (v) { phoneNum = v; }, @@ -61,7 +81,7 @@ class RegisterPage extends StatelessWidget { title: "Continue", width: double.infinity, onPressed: () { - performBasicOtp(context); + if (validation()) performBasicOtp(context); }, ), ], @@ -72,7 +92,7 @@ class RegisterPage extends StatelessWidget { Future performBasicOtp(BuildContext context) async { Utils.showLoading(context); - BasicOtp basicOtp = await UserApiClent().basicOtp(countryCode + phoneNum,); + BasicOtp basicOtp = await UserApiClent().basicOtp(countryCode + phoneNum, roleId: role); Utils.hideLoading(context); if (basicOtp.messageStatus == 1) { showMDialog(context, child: OtpDialog( @@ -83,25 +103,29 @@ class RegisterPage extends StatelessWidget { Utils.hideLoading(context); if (user.messageStatus == 1) { Utils.showToast(user.message ?? ""); - navigateReplaceWithName(context, AppRoutes.completeProfile,arguments: user); + navigateReplaceWithName(context, AppRoutes.completeProfile, arguments: user); } 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 ?? ""); } } + + bool validation() { + bool isValid = true; + if (role == -1) { + Utils.showToast("Please select Provider Role"); + isValid = false; + } else if (countryCode.isEmpty) { + Utils.showToast("Please select Country Code"); + isValid = false; + } else if (phoneNum.isEmpty) { + Utils.showToast("Please add Phone No"); + isValid = false; + } + return isValid; + } } diff --git a/lib/pages/user/register_selection_page.dart b/lib/pages/user/register_selection_page.dart index 189402b..523ceea 100644 --- a/lib/pages/user/register_selection_page.dart +++ b/lib/pages/user/register_selection_page.dart @@ -23,6 +23,7 @@ class RegisterSelectionPage extends StatelessWidget { mFlex(1), ShowFillButton( title: "Log In", + // title: "Log In With Password", width: double.infinity, onPressed: () { navigateWithName(context, AppRoutes.loginWithPassword); diff --git a/lib/pages/user/vertify_password_page.dart b/lib/pages/user/vertify_password_page.dart new file mode 100644 index 0000000..1c34270 --- /dev/null +++ b/lib/pages/user/vertify_password_page.dart @@ -0,0 +1,162 @@ + + +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/forget_password_otp_compare.dart'; +import 'package:car_customer_app/models/user/forget_password_otp_request.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/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/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/txt_field.dart'; +import 'package:flutter/material.dart'; + + + +class VerifyPasswordPage extends StatelessWidget { + int otpType = 1; + String phoneNum = ""; + String userName = ""; + String userToken = ""; + String otp = ""; + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: appBar(title: "Change Password"), + body: Container( + width: double.infinity, + height: double.infinity, + padding: EdgeInsets.all(40), + child: Column( + children: [ + "Verify New Password".toText24(), + mFlex(1), + TxtField( + hint: "966500000000", + value: phoneNum, + onChanged: (v) { + phoneNum = v; + }, + ), + mFlex(2), + Row( + children: [ + Expanded( + child: ShowImageButton( + onClick: () { + otpType = 1; + // sendPasswordOTP(context); + showMDialog(context, child: OtpDialog( + onClick: (String code) { + pop(context); + delay(300).then( + (value) => showMDialog( + context, + child: MessageDialog( + title: "Phone Number Verified", + onClick: () { + otpType=1; + navigateWithName(context, AppRoutes.confirmNewPasswordPage); + // ForgetPasswordOTP(context); + }, + ), + ), + ); + }, + )); + }, + title: 'With SMS', + icon: icons + "ic_sms.png", + ), + ), + 20.width, + Expanded( + child: ShowImageButton( + onClick: () { + otpType = 1; + // sendPasswordOTP(context); + showMDialog(context, child: OtpDialog( + onClick: (String code) { + pop(context); + delay(300).then( + (value) => showMDialog( + context, + child: MessageDialog( + title: "Phone Number Verified", + onClick: () { + otpType=2; + navigateWithName(context, AppRoutes.confirmNewPasswordPage); + // ForgetPasswordOTP(context); + }, + ), + ), + ); + }, + )); + }, + title: 'With Whatsapp', + icon: icons + "ic_whatsapp.png", + ), + ), + ], + ), + mFlex(10), + ], + ), + ), + ); + } + + // Future sendPasswordOTP(BuildContext context) async { + // Utils.showLoading(context); + // PasswordOTPCompare otpCompare = await UserApiClent().ForgetPasswordOTPCompare(userToken, otp); + // Utils.hideLoading(context); + // if (otpCompare.messageStatus == 1) { + // // navigateWithName(context, AppRoutes.confirmNewPasswordPage); + // showMDialog(context, child: OtpDialog( + // onClick: (String code) async { + // pop(context); + // Utils.showLoading(context); + // // PasswordOTPCompare otpCompare = await UserApiClent().ForgetPasswordOTPCompare(userToken, otp); + // Utils.hideLoading(context); + // }, + // )); + // } else { + // Utils.showToast(otpCompare.message ?? ""); + // } + // } + + +// User otpRequest = User.fromJson(jsonDecode(res.body)); +// SharedPrefManager.setUserToken(otpRequest.data!.accessToken ?? ""); +// SharedPrefManager.setUserId(otpRequest.data!.userInfo!.userId ?? ""); +// showMDialog(context, child: OtpDialog( +// onClick: (String code) { +// pop(context); +// delay(300).then( +// (value) => showMDialog( +// context, +// child: MessageDialog( +// title: "Phone Number Verified", +// onClick: () { +// otpType=1; +// navigateWithName(context, AppRoutes.confirmNewPasswordPage); +// // ForgetPasswordOTP(context); +// }, +// ), +// ), +// ); +// }, +// )); + + +} diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index fdf7639..41f75e8 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -26,6 +26,18 @@ Widget spacerVertical(double v) { width: double.infinity, ); } + +String convertFileToBase64(File file) { + List imageBytes = file.readAsBytesSync(); + return base64Encode(imageBytes); +} + +// String checkFileExt(String path) { +// String ex = p.extension(path); +// var parts = ex.split('.'); +// return parts[1] ?? "png"; // '.dart' +// } + Future delay(int millis) async { return await Future.delayed(Duration(milliseconds: millis)); } @@ -104,6 +116,7 @@ Widget mFlex(int f) { ), ); } + Widget mExp(int f) { return Expanded( flex: f, @@ -197,17 +210,19 @@ String base64String(Uint8List data) { return base64Encode(data); } -Widget overLayWidget({double? width, double? height,List? color}) { +Widget overLayWidget({double? width, double? height, List? color}) { return Container( width: width ?? double.infinity, height: height ?? 60, decoration: BoxDecoration( gradient: LinearGradient( - colors: color!=null?color:[ - Colors.black.withOpacity(0.2), - Colors.black.withOpacity(0.1), - Colors.black.withOpacity(0.004), - ], + colors: color != null + ? color + : [ + Colors.black.withOpacity(0.2), + Colors.black.withOpacity(0.1), + Colors.black.withOpacity(0.004), + ], begin: Alignment.topCenter, end: Alignment.bottomCenter, tileMode: TileMode.clamp, @@ -286,11 +301,6 @@ Decoration containerColorRadiusBorder(Color background, double radius, Color col ); } - - - - - //Decoration appGradient = BoxDecoration( // gradient: LinearGradient( // colors: [ diff --git a/lib/widgets/tab/login_email_tab.dart b/lib/widgets/tab/login_email_tab.dart new file mode 100644 index 0000000..7c29b63 --- /dev/null +++ b/lib/widgets/tab/login_email_tab.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; + +enum ClassType { EMAIL, NUMBER } + +class LoginEmailTab extends StatefulWidget { + Function(ClassType) onSelection; + + LoginEmailTab({required this.onSelection}); + + @override + State createState() => _LoginEmailTabState(); +} + +class _LoginEmailTabState extends State { + ClassType type = ClassType.NUMBER; + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + type = ClassType.NUMBER; + widget.onSelection(ClassType.NUMBER); + }, + child: Container( + width: double.infinity, + height: 45, + color: type == ClassType.NUMBER ? Colors.blue : Colors.transparent, + child: Center( + child: Text( + "Number", + style: TextStyle( + color: type == ClassType.NUMBER ? Colors.white : Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + type = ClassType.EMAIL; + widget.onSelection(ClassType.EMAIL); + }, + child: Container( + width: double.infinity, + height: 45, + color: type == ClassType.EMAIL ? Colors.blue : Colors.transparent, + child: Center( + child: Text( + "Email", + style: TextStyle( + color: type == ClassType.EMAIL ? Colors.white : Colors.black, + fontWeight: FontWeight.bold, + ), + )), + ), + ), + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 13c55cd..5ad0a2d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -50,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + cross_file: + dependency: transitive + description: + name: cross_file + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.2" crypto: dependency: transitive description: @@ -116,13 +123,20 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" flutter_svg: dependency: "direct dev" description: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "0.22.0" + version: "1.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -139,7 +153,7 @@ packages: name: fluttertoast url: "https://pub.dartlang.org" source: hosted - version: "8.0.8" + version: "8.0.9" http: dependency: "direct dev" description: @@ -154,6 +168,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + image_picker: + dependency: "direct dev" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.4+11" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.6" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" injector: dependency: "direct dev" description: @@ -189,6 +224,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -216,14 +258,14 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.5.1+1" + version: "1.0.0" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.2.1" + version: "1.0.0" path_provider: dependency: "direct dev" description: @@ -279,7 +321,21 @@ packages: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "7.1.0" + version: "9.2.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.2+1" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.4" permission_handler_platform_interface: dependency: transitive description: @@ -287,6 +343,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.7.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" petitparser: dependency: transitive description: @@ -431,7 +494,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" typed_data: dependency: transitive description: @@ -475,5 +538,5 @@ packages: source: hosted version: "5.3.1" sdks: - dart: ">=2.14.0 <3.0.0" - flutter: ">=2.5.0" + dart: ">=2.15.0 <3.0.0" + flutter: ">=2.8.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9390e9e..b48ef15 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,11 +50,12 @@ dev_dependencies: provider: ^6.0.0 easy_localization: ^3.0.0 http: ^0.13.3 - permission_handler: 7.1.0 - flutter_svg: ^0.22.0 + permission_handler: ^9.2.0 + flutter_svg: ^1.0.3 sizer: ^2.0.15 - fluttertoast: ^8.0.8 + fluttertoast: ^8.0.9 shared_preferences: ^2.0.6 + image_picker: ^0.8.4+4 # For information on the generic Dart part of this file, see the