feat : auth for new module
This commit is contained in:
@@ -5,10 +5,14 @@ class DioErrorHandler {
|
|||||||
void handle(DioException error) {
|
void handle(DioException error) {
|
||||||
switch (error.response?.statusCode) {
|
switch (error.response?.statusCode) {
|
||||||
case 401:
|
case 401:
|
||||||
_handle401();
|
_handleGeneric(error);
|
||||||
break;
|
break;
|
||||||
case 403:
|
case 403:
|
||||||
_handle403();
|
_handleGeneric(error);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 410:
|
||||||
|
_handle410();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_handleGeneric(error);
|
_handleGeneric(error);
|
||||||
@@ -16,21 +20,22 @@ class DioErrorHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//wrong password/user name => "detail": "No active account found with the given credentials" - 401
|
//wrong password/user name => "detail": "No active account found with the given credentials" - 401
|
||||||
void _handle401() {
|
void _handle410() {
|
||||||
Get.showSnackbar(
|
Get.showSnackbar(_errorSnackBar('نام کاربری یا رمز عبور اشتباه است'));
|
||||||
_errorSnackBar('نام کاربری یا رمز عبور اشتباه است'),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//wrong captcha => "detail": "Captcha code is incorrect" - 403
|
//wrong captcha => "detail": "Captcha code is incorrect" - 403
|
||||||
void _handle403() {
|
void _handle403() {}
|
||||||
Get.showSnackbar(
|
|
||||||
_errorSnackBar('کد امنیتی اشتباه است'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleGeneric(DioException error) {
|
void _handleGeneric(DioException error) {
|
||||||
// General error handling
|
Get.showSnackbar(
|
||||||
|
_errorSnackBar(
|
||||||
|
error.response?.data.keys.first == 'is_user'
|
||||||
|
? 'کاربر با این شماره تلفن وجود ندارد'
|
||||||
|
: error.response?.data[error.response?.data.keys.first] ??
|
||||||
|
'خطا در برقراری ارتباط با سرور',
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSnackBar _errorSnackBar(String message) {
|
GetSnackBar _errorSnackBar(String message) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class DioRemoteManager {
|
|||||||
ApiEnvironment env = ApiEnvironment.dam,
|
ApiEnvironment env = ApiEnvironment.dam,
|
||||||
]) async {
|
]) async {
|
||||||
if (_currentEnv != env) {
|
if (_currentEnv != env) {
|
||||||
_currentClient = DioRemote(env.baseUrl);
|
_currentClient = DioRemote(baseUrl: env.baseUrl);
|
||||||
await _currentClient?.init();
|
await _currentClient?.init();
|
||||||
_currentEnv = env;
|
_currentEnv = env;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:rasadyar_auth/data/common/constant.dart';
|
import 'package:rasadyar_auth/data/common/constant.dart';
|
||||||
import 'package:rasadyar_auth/data/common/dio_error_handler.dart';
|
import 'package:rasadyar_auth/data/common/dio_error_handler.dart';
|
||||||
import 'package:rasadyar_auth/data/repositories/auth_repository_imp.dart';
|
import 'package:rasadyar_auth/data/repositories/auth_repository_imp.dart';
|
||||||
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
|
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
import '../common/dio_manager.dart';
|
import '../common/dio_manager.dart';
|
||||||
@@ -10,12 +9,16 @@ GetIt diAuth = GetIt.instance;
|
|||||||
|
|
||||||
Future<void> setupAuthDI() async {
|
Future<void> setupAuthDI() async {
|
||||||
diAuth.registerLazySingleton(() => DioRemoteManager());
|
diAuth.registerLazySingleton(() => DioRemoteManager());
|
||||||
|
diAuth.registerLazySingleton<DioRemote>(() => DioRemote());
|
||||||
|
|
||||||
|
/* final manager = diAuth.get<DioRemoteManager>();
|
||||||
|
final dioRemote = await manager.setEnvironment(ApiEnvironment.dam);*/
|
||||||
|
|
||||||
final manager = diAuth.get<DioRemoteManager>();
|
final dioRemote = diAuth.get<DioRemote>();
|
||||||
final dioRemote = await manager.setEnvironment(ApiEnvironment.dam);
|
await dioRemote.init();
|
||||||
diAuth.registerCachedFactory<AuthRepositoryImpl>(
|
diAuth.registerCachedFactory<AuthRepositoryImpl>(
|
||||||
() => AuthRepositoryImpl(dioRemote),
|
() => AuthRepositoryImpl(dioRemote),
|
||||||
);
|
);
|
||||||
|
|
||||||
diAuth.registerLazySingleton<DioErrorHandler>(() => DioErrorHandler());
|
diAuth.registerLazySingleton<DioErrorHandler>(() => DioErrorHandler());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ class UserLocalModel extends HiveObject {
|
|||||||
@HiveField(5)
|
@HiveField(5)
|
||||||
Module? module;
|
Module? module;
|
||||||
|
|
||||||
|
@HiveField(6)
|
||||||
|
String? backend;
|
||||||
|
|
||||||
|
@HiveField(7)
|
||||||
|
String? apiKey;
|
||||||
|
|
||||||
UserLocalModel({
|
UserLocalModel({
|
||||||
this.username,
|
this.username,
|
||||||
this.password,
|
this.password,
|
||||||
@@ -26,6 +32,8 @@ class UserLocalModel extends HiveObject {
|
|||||||
this.refreshToken,
|
this.refreshToken,
|
||||||
this.name,
|
this.name,
|
||||||
this.module,
|
this.module,
|
||||||
|
this.backend,
|
||||||
|
this.apiKey,
|
||||||
});
|
});
|
||||||
|
|
||||||
UserLocalModel copyWith({
|
UserLocalModel copyWith({
|
||||||
@@ -35,6 +43,9 @@ class UserLocalModel extends HiveObject {
|
|||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String? name,
|
String? name,
|
||||||
Module? module,
|
Module? module,
|
||||||
|
String? backend,
|
||||||
|
String? apiKey,
|
||||||
|
|
||||||
}) {
|
}) {
|
||||||
return UserLocalModel(
|
return UserLocalModel(
|
||||||
username: username ?? this.username,
|
username: username ?? this.username,
|
||||||
@@ -43,6 +54,8 @@ class UserLocalModel extends HiveObject {
|
|||||||
refreshToken: refreshToken ?? this.refreshToken,
|
refreshToken: refreshToken ?? this.refreshToken,
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
module: module ?? this.module,
|
module: module ?? this.module,
|
||||||
|
backend: backend ?? this.backend,
|
||||||
|
apiKey: apiKey ?? this.apiKey,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,15 @@ class UserLocalModelAdapter extends TypeAdapter<UserLocalModel> {
|
|||||||
refreshToken: fields[3] as String?,
|
refreshToken: fields[3] as String?,
|
||||||
name: fields[4] as String?,
|
name: fields[4] as String?,
|
||||||
module: fields[5] as Module?,
|
module: fields[5] as Module?,
|
||||||
|
backend: fields[6] as String?,
|
||||||
|
apiKey: fields[7] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void write(BinaryWriter writer, UserLocalModel obj) {
|
void write(BinaryWriter writer, UserLocalModel obj) {
|
||||||
writer
|
writer
|
||||||
..writeByte(6)
|
..writeByte(8)
|
||||||
..writeByte(0)
|
..writeByte(0)
|
||||||
..write(obj.username)
|
..write(obj.username)
|
||||||
..writeByte(1)
|
..writeByte(1)
|
||||||
@@ -41,7 +43,11 @@ class UserLocalModelAdapter extends TypeAdapter<UserLocalModel> {
|
|||||||
..writeByte(4)
|
..writeByte(4)
|
||||||
..write(obj.name)
|
..write(obj.name)
|
||||||
..writeByte(5)
|
..writeByte(5)
|
||||||
..write(obj.module);
|
..write(obj.module)
|
||||||
|
..writeByte(6)
|
||||||
|
..write(obj.backend)
|
||||||
|
..writeByte(7)
|
||||||
|
..write(obj.apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
part 'user_info_model.freezed.dart';
|
||||||
|
|
||||||
|
part 'user_info_model.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class UserInfoModel with _$UserInfoModel {
|
||||||
|
const factory UserInfoModel({
|
||||||
|
bool? isUser,
|
||||||
|
String? address,
|
||||||
|
String? backend,
|
||||||
|
String? apiKey,
|
||||||
|
}) = _UserInfoModel ;
|
||||||
|
|
||||||
|
factory UserInfoModel.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$UserInfoModelFromJson(json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'user_profile_model.freezed.dart';
|
||||||
|
|
||||||
|
part 'user_profile_model.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class UserProfileModel with _$UserProfileModel {
|
||||||
|
const factory UserProfileModel({
|
||||||
|
String? accessToken,
|
||||||
|
String? expiresIn,
|
||||||
|
String? scope,
|
||||||
|
String? expireTime,
|
||||||
|
String? mobile,
|
||||||
|
String? fullname,
|
||||||
|
String? firstname,
|
||||||
|
String? lastname,
|
||||||
|
String? city,
|
||||||
|
String? province,
|
||||||
|
String? nationalCode,
|
||||||
|
String? nationalId,
|
||||||
|
String? birthday,
|
||||||
|
String? image,
|
||||||
|
int? baseOrder,
|
||||||
|
List<String>? role,
|
||||||
|
}) = _UserProfileModel;
|
||||||
|
|
||||||
|
factory UserProfileModel.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$UserProfileModelFromJson(json);
|
||||||
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
|
import 'package:rasadyar_auth/data/models/response/user_info/user_info_model.dart';
|
||||||
|
|
||||||
import '../models/response/auth/auth_response_model.dart';
|
import '../models/response/auth/auth_response_model.dart';
|
||||||
import '../models/response/captcha/captcha_response_model.dart';
|
import '../models/response/captcha/captcha_response_model.dart';
|
||||||
|
import '../models/response/user_profile_model/user_profile_model.dart';
|
||||||
|
|
||||||
abstract class AuthRepository {
|
abstract class AuthRepository {
|
||||||
Future<AuthResponseModel?> login({
|
Future<UserProfileModel?> login({required Map<String, dynamic> authRequest});
|
||||||
required Map<String, dynamic> authRequest,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<CaptchaResponseModel?> captcha();
|
Future<CaptchaResponseModel?> captcha();
|
||||||
|
|
||||||
@@ -14,10 +13,9 @@ abstract class AuthRepository {
|
|||||||
|
|
||||||
Future<bool> hasAuthenticated();
|
Future<bool> hasAuthenticated();
|
||||||
|
|
||||||
|
|
||||||
Future<AuthResponseModel?> loginWithRefreshToken({
|
Future<AuthResponseModel?> loginWithRefreshToken({
|
||||||
required Map<String, dynamic> authRequest,
|
required Map<String, dynamic> authRequest,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Future<UserInfoModel?> getUserInfo(String phoneNumber);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'package:rasadyar_auth/data/models/response/user_info/user_info_model.dart';
|
||||||
|
import 'package:rasadyar_auth/data/models/response/user_profile_model/user_profile_model.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
import '../models/response/auth/auth_response_model.dart';
|
import '../models/response/auth/auth_response_model.dart';
|
||||||
@@ -11,13 +13,13 @@ class AuthRepositoryImpl implements AuthRepository {
|
|||||||
AuthRepositoryImpl(this._httpClient);
|
AuthRepositoryImpl(this._httpClient);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<AuthResponseModel?> login({
|
Future<UserProfileModel?> login({
|
||||||
required Map<String, dynamic> authRequest,
|
required Map<String, dynamic> authRequest,
|
||||||
}) async {
|
}) async {
|
||||||
var res = await _httpClient.post<AuthResponseModel>(
|
var res = await _httpClient.post<UserProfileModel?>(
|
||||||
'$_BASE_URL/login/',
|
'/api/login/',
|
||||||
data: authRequest,
|
data: authRequest,
|
||||||
fromJson: AuthResponseModel.fromJson,
|
fromJson: UserProfileModel.fromJson,
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
);
|
);
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -59,4 +61,19 @@ class AuthRepositoryImpl implements AuthRepository {
|
|||||||
|
|
||||||
return response.data ?? false;
|
return response.data ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<UserInfoModel?> getUserInfo(String phoneNumber) async {
|
||||||
|
var res = await _httpClient.post<UserInfoModel?>(
|
||||||
|
'https://userbackend.rasadyaar.ir/api/send_otp/',
|
||||||
|
data: {
|
||||||
|
"mobile": phoneNumber,
|
||||||
|
"state": ""
|
||||||
|
},
|
||||||
|
fromJson: UserInfoModel.fromJson,
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
);
|
||||||
|
return res.data;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ class TokenStorageService extends GetxService {
|
|||||||
static const String _boxName = 'secureBox';
|
static const String _boxName = 'secureBox';
|
||||||
static const String _accessTokenKey = 'accessToken';
|
static const String _accessTokenKey = 'accessToken';
|
||||||
static const String _refreshTokenKey = 'refreshToken';
|
static const String _refreshTokenKey = 'refreshToken';
|
||||||
|
static const String _baseUrlKey = 'baseUrl';
|
||||||
|
static const String _apiKey = 'apiKey';
|
||||||
static const String _moduleKey = 'moduleSelected';
|
static const String _moduleKey = 'moduleSelected';
|
||||||
|
|
||||||
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
|
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
|
||||||
@@ -15,6 +17,7 @@ class TokenStorageService extends GetxService {
|
|||||||
|
|
||||||
RxnString accessToken = RxnString();
|
RxnString accessToken = RxnString();
|
||||||
RxnString refreshToken = RxnString();
|
RxnString refreshToken = RxnString();
|
||||||
|
RxnString baseurl= RxnString();
|
||||||
Rxn<Module> appModule = Rxn(null);
|
Rxn<Module> appModule = Rxn(null);
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
@@ -34,6 +37,7 @@ class TokenStorageService extends GetxService {
|
|||||||
accessToken.value = _localStorage.read<String?>(boxName: _boxName, key: _accessTokenKey);
|
accessToken.value = _localStorage.read<String?>(boxName: _boxName, key: _accessTokenKey);
|
||||||
refreshToken.value = _localStorage.read<String?>(boxName: _boxName, key: _refreshTokenKey);
|
refreshToken.value = _localStorage.read<String?>(boxName: _boxName, key: _refreshTokenKey);
|
||||||
appModule.value = _localStorage.read<Module?>(boxName: _boxName, key: _moduleKey);
|
appModule.value = _localStorage.read<Module?>(boxName: _boxName, key: _moduleKey);
|
||||||
|
baseurl.value = _localStorage.read<String?>(boxName: _boxName, key: _baseUrlKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveAccessToken(String token) async {
|
Future<void> saveAccessToken(String token) async {
|
||||||
@@ -59,4 +63,16 @@ class TokenStorageService extends GetxService {
|
|||||||
accessToken.value = null;
|
accessToken.value = null;
|
||||||
refreshToken.value = null;
|
refreshToken.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> saveBaseUrl(String url) async {
|
||||||
|
await _localStorage.save(boxName: _boxName, key: _baseUrlKey, value: url);
|
||||||
|
baseurl.value = url;
|
||||||
|
baseurl.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> saveApiKey(String key) async {
|
||||||
|
await _localStorage.save(boxName: _boxName, key: _apiKey, value: key);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import 'package:rasadyar_auth/auth.dart';
|
|||||||
import 'package:rasadyar_auth/data/common/dio_error_handler.dart';
|
import 'package:rasadyar_auth/data/common/dio_error_handler.dart';
|
||||||
import 'package:rasadyar_auth/data/models/request/login_request/login_request_model.dart';
|
import 'package:rasadyar_auth/data/models/request/login_request/login_request_model.dart';
|
||||||
import 'package:rasadyar_auth/data/models/response/auth/auth_response_model.dart';
|
import 'package:rasadyar_auth/data/models/response/auth/auth_response_model.dart';
|
||||||
|
import 'package:rasadyar_auth/data/models/response/user_info/user_info_model.dart';
|
||||||
|
import 'package:rasadyar_auth/data/models/response/user_profile_model/user_profile_model.dart';
|
||||||
import 'package:rasadyar_auth/data/repositories/auth_repository_imp.dart';
|
import 'package:rasadyar_auth/data/repositories/auth_repository_imp.dart';
|
||||||
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
|
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
|
||||||
import 'package:rasadyar_auth/data/utils/safe_call.dart';
|
import 'package:rasadyar_auth/data/utils/safe_call.dart';
|
||||||
@@ -34,6 +36,7 @@ class AuthLogic extends GetxController {
|
|||||||
|
|
||||||
RxnString phoneNumber = RxnString(null);
|
RxnString phoneNumber = RxnString(null);
|
||||||
RxBool isLoading = false.obs;
|
RxBool isLoading = false.obs;
|
||||||
|
RxBool isDisabled = true.obs;
|
||||||
TokenStorageService tokenStorageService = Get.find<TokenStorageService>();
|
TokenStorageService tokenStorageService = Get.find<TokenStorageService>();
|
||||||
|
|
||||||
Rx<AuthType> authType = AuthType.useAndPass.obs;
|
Rx<AuthType> authType = AuthType.useAndPass.obs;
|
||||||
@@ -108,7 +111,7 @@ class AuthLogic extends GetxController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> submitLoginForm() async {
|
/*Future<void> submitLoginForm() async {
|
||||||
if (!_isFormValid()) return;
|
if (!_isFormValid()) return;
|
||||||
iLog('module222 : ${_module.toString()}');
|
iLog('module222 : ${_module.toString()}');
|
||||||
final loginRequestModel = _buildLoginRequest();
|
final loginRequestModel = _buildLoginRequest();
|
||||||
@@ -128,5 +131,73 @@ class AuthLogic extends GetxController {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
Future<void> submitLoginForm2() async {
|
||||||
|
if (!_isFormValid()) return;
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
|
await safeCall<UserProfileModel?>(
|
||||||
|
call: () => authRepository.login(
|
||||||
|
authRequest: {
|
||||||
|
"username": phoneNumberController.value.text,
|
||||||
|
"password": passwordController.value.text,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onSuccess: (result) async {
|
||||||
|
await tokenStorageService.saveModule(_module);
|
||||||
|
await tokenStorageService.saveAccessToken(result?.accessToken ?? '');
|
||||||
|
await tokenStorageService.saveRefreshToken(result?.accessToken ?? '');
|
||||||
|
},
|
||||||
|
onError: (error, stackTrace) {
|
||||||
|
if (error is DioException) {
|
||||||
|
diAuth.get<DioErrorHandler>().handle(error);
|
||||||
|
}
|
||||||
|
captchaController.getCaptcha();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getUserInfo(String value) async {
|
||||||
|
isLoading.value = true;
|
||||||
|
await safeCall<UserInfoModel?>(
|
||||||
|
call: () async => await authRepository.getUserInfo(value),
|
||||||
|
onSuccess: (result) async {
|
||||||
|
if (result != null) {
|
||||||
|
diAuth.registerSingleton<DioRemote>(
|
||||||
|
DioRemote(baseUrl: result.backend),
|
||||||
|
instanceName: 'newDioRemote',
|
||||||
|
);
|
||||||
|
await tokenStorageService.saveApiKey(result.apiKey ?? '');
|
||||||
|
await tokenStorageService.saveBaseUrl(result.backend ?? '');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (error, stackTrace) {
|
||||||
|
if (error is DioException) {
|
||||||
|
diAuth.get<DioErrorHandler>().handle(error);
|
||||||
|
}
|
||||||
|
captchaController.getCaptcha();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSnackBar _errorSnackBar(String message) {
|
||||||
|
return GetSnackBar(
|
||||||
|
titleText: Text(
|
||||||
|
'خطا',
|
||||||
|
style: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
messageText: Text(
|
||||||
|
message,
|
||||||
|
style: AppFonts.yekan12.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
backgroundColor: AppColor.error,
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
borderRadius: 12,
|
||||||
|
duration: Duration(milliseconds: 3500),
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class AuthPage extends GetView<AuthLogic> {
|
|||||||
}
|
}
|
||||||
}, controller.authType),
|
}, controller.authType),
|
||||||
|
|
||||||
SizedBox(height: 50),
|
/* SizedBox(height: 50),
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
children: [
|
children: [
|
||||||
@@ -80,7 +80,7 @@ class AuthPage extends GetView<AuthLogic> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}, controller.authType),
|
}, controller.authType),*/
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -94,48 +94,41 @@ class AuthPage extends GetView<AuthLogic> {
|
|||||||
key: controller.formKey,
|
key: controller.formKey,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
ObxValue(
|
|
||||||
(phoneController) =>
|
|
||||||
RTextField(
|
RTextField(
|
||||||
label: 'نام کاربری',
|
label: 'نام کاربری',
|
||||||
maxLength: 11,
|
maxLength: 11,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
controller: phoneController.value,
|
controller: controller.phoneNumberController.value,
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.number,
|
||||||
initText: phoneController.value.text,
|
initText: controller.phoneNumberController.value.text,
|
||||||
onChanged: (value) {
|
onChanged: (value) async {
|
||||||
phoneController.value.text = value;
|
controller.phoneNumberController.value.text = value;
|
||||||
phoneController.refresh();
|
controller.phoneNumberController.refresh();
|
||||||
|
if (value.length == 11) {
|
||||||
|
await controller.getUserInfo(value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
|
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
|
||||||
child: Assets.vec.callSvg.svg(
|
child: Assets.vec.callSvg.svg(width: 12, height: 12),
|
||||||
width: 12,
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
suffixIcon:
|
suffixIcon:
|
||||||
phoneController.value.text
|
controller.phoneNumberController.value.text.trim().isNotEmpty
|
||||||
.trim()
|
|
||||||
.isNotEmpty
|
|
||||||
? clearButton(() {
|
? clearButton(() {
|
||||||
phoneController.value.clear();
|
controller.phoneNumberController.value.clear();
|
||||||
phoneController.refresh();
|
controller.phoneNumberController.refresh();
|
||||||
})
|
})
|
||||||
: null,
|
: null,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return '⚠️ شماره موبایل را وارد کنید';
|
return '⚠️ شماره موبایل را وارد کنید';
|
||||||
}
|
} else if (value.length < 11) {
|
||||||
/*else if (value.length < 11) {
|
|
||||||
return '⚠️ شماره موبایل باید 11 رقم باشد';
|
return '⚠️ شماره موبایل باید 11 رقم باشد';
|
||||||
}*/
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
style: AppFonts.yekan13,
|
style: AppFonts.yekan13,
|
||||||
errorStyle: AppFonts.yekan13.copyWith(
|
errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal),
|
||||||
color: AppColor.redNormal,
|
|
||||||
),
|
|
||||||
labelStyle: AppFonts.yekan13,
|
labelStyle: AppFonts.yekan13,
|
||||||
boxConstraints: const BoxConstraints(
|
boxConstraints: const BoxConstraints(
|
||||||
maxHeight: 40,
|
maxHeight: 40,
|
||||||
@@ -144,14 +137,12 @@ class AuthPage extends GetView<AuthLogic> {
|
|||||||
minWidth: 40,
|
minWidth: 40,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
controller.phoneNumberController,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 26),
|
const SizedBox(height: 26),
|
||||||
ObxValue(
|
ObxValue(
|
||||||
(passwordController) =>
|
(passwordController) => RTextField(
|
||||||
RTextField(
|
|
||||||
label: 'رمز عبور',
|
label: 'رمز عبور',
|
||||||
filled: false,
|
filled: false,
|
||||||
|
obscure: true,
|
||||||
controller: passwordController.value,
|
controller: passwordController.value,
|
||||||
variant: RTextFieldVariant.password,
|
variant: RTextFieldVariant.password,
|
||||||
initText: passwordController.value.text,
|
initText: passwordController.value.text,
|
||||||
@@ -171,10 +162,7 @@ class AuthPage extends GetView<AuthLogic> {
|
|||||||
labelStyle: AppFonts.yekan13,
|
labelStyle: AppFonts.yekan13,
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
|
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
|
||||||
child: Assets.vec.keySvg.svg(
|
child: Assets.vec.keySvg.svg(width: 12, height: 12),
|
||||||
width: 12,
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
boxConstraints: const BoxConstraints(
|
boxConstraints: const BoxConstraints(
|
||||||
maxHeight: 34,
|
maxHeight: 34,
|
||||||
@@ -188,24 +176,27 @@ class AuthPage extends GetView<AuthLogic> {
|
|||||||
SizedBox(height: 26),
|
SizedBox(height: 26),
|
||||||
CaptchaWidget(),
|
CaptchaWidget(),
|
||||||
SizedBox(height: 23),
|
SizedBox(height: 23),
|
||||||
ObxValue((data) {
|
|
||||||
|
Obx(() {
|
||||||
return RElevated(
|
return RElevated(
|
||||||
text: 'ورود',
|
text: 'ورود',
|
||||||
isLoading: data.value,
|
isLoading: controller.isLoading.value,
|
||||||
onPressed: () async {
|
onPressed: controller.isDisabled.value
|
||||||
await controller.submitLoginForm();
|
? null
|
||||||
|
: () async {
|
||||||
|
await controller.submitLoginForm2();
|
||||||
},
|
},
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
height: 48,
|
height: 48,
|
||||||
);
|
);
|
||||||
}, controller.isLoading),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Widget sendCodeForm() {
|
Widget sendCodeForm() {
|
||||||
return ObxValue((data) {
|
return ObxValue((data) {
|
||||||
return Form(
|
return Form(
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rasadyar_auth/presentation/pages/auth/logic.dart';
|
||||||
import 'package:rasadyar_auth/presentation/widget/clear_button.dart';
|
import 'package:rasadyar_auth/presentation/widget/clear_button.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
@@ -64,9 +65,19 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
|
|||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'کد امنیتی را وارد کنید';
|
return 'کد امنیتی را وارد کنید';
|
||||||
|
} else if (controller.captchaKey.value != null && controller.captchaKey.value != value) {
|
||||||
|
return 'کد امنیتی اشتباه است';
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
onChanged: (pass) {
|
||||||
|
if(pass.length== 6) {
|
||||||
|
if(controller.formKey.currentState?.validate()??false) {
|
||||||
|
Get.find<AuthLogic>().isDisabled.value = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
style: AppFonts.yekan13,
|
style: AppFonts.yekan13,
|
||||||
);
|
);
|
||||||
}, controller.textController),
|
}, controller.textController),
|
||||||
@@ -82,10 +93,10 @@ class _CaptchaLinePainter extends CustomPainter {
|
|||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
final random = Random();
|
final random = Random();
|
||||||
final paint1 = Paint()
|
final paint1 = Paint()
|
||||||
..color = Color.fromRGBO(random.nextInt(255), random.nextInt(255), random.nextInt(255), 1)
|
..color = Colors.deepOrange
|
||||||
..strokeWidth = 2;
|
..strokeWidth = 2;
|
||||||
final paint2 = Paint()
|
final paint2 = Paint()
|
||||||
..color = Color.fromRGBO(random.nextInt(255), random.nextInt(255), random.nextInt(255), 1)
|
..color =Colors.blue
|
||||||
..strokeWidth = 2;
|
..strokeWidth = 2;
|
||||||
|
|
||||||
// First line: top-left to bottom-right
|
// First line: top-left to bottom-right
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
library;
|
library;
|
||||||
|
|
||||||
|
|
||||||
//other packages
|
//other packages
|
||||||
export 'package:flutter_localizations/flutter_localizations.dart';
|
export 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
export 'package:flutter_map/flutter_map.dart';
|
export 'package:flutter_map/flutter_map.dart';
|
||||||
@@ -9,13 +8,17 @@ export 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
|||||||
export 'package:flutter_slidable/flutter_slidable.dart';
|
export 'package:flutter_slidable/flutter_slidable.dart';
|
||||||
export 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
export 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
export 'package:hive_ce_flutter/hive_flutter.dart';
|
export 'package:hive_ce_flutter/hive_flutter.dart';
|
||||||
|
|
||||||
//freezed
|
//freezed
|
||||||
export 'package:freezed_annotation/freezed_annotation.dart';
|
export 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
export 'package:geolocator/geolocator.dart';
|
export 'package:geolocator/geolocator.dart';
|
||||||
export 'package:get/get.dart';
|
export 'package:get/get.dart' hide FormData, MultipartFile, Response;
|
||||||
|
|
||||||
//di
|
//di
|
||||||
export 'package:get_it/get_it.dart';
|
export 'package:get_it/get_it.dart';
|
||||||
export 'injection/di.dart';
|
export 'injection/di.dart';
|
||||||
|
export 'package:dio/dio.dart';
|
||||||
|
export 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
||||||
|
|
||||||
//local storage
|
//local storage
|
||||||
export 'package:hive_ce_flutter/hive_flutter.dart';
|
export 'package:hive_ce_flutter/hive_flutter.dart';
|
||||||
@@ -26,13 +29,12 @@ export 'infrastructure/local/hive_local_storage.dart';
|
|||||||
//export 'package:encrypt/encrypt.dart' show Encrypted;
|
//export 'package:encrypt/encrypt.dart' show Encrypted;
|
||||||
|
|
||||||
//Map and location
|
//Map and location
|
||||||
export 'package:latlong2/latlong.dart' ;
|
export 'package:latlong2/latlong.dart';
|
||||||
export 'package:persian_datetime_picker/persian_datetime_picker.dart';
|
export 'package:persian_datetime_picker/persian_datetime_picker.dart';
|
||||||
export 'package:rasadyar_core/presentation/common/common.dart';
|
export 'package:rasadyar_core/presentation/common/common.dart';
|
||||||
export 'package:rasadyar_core/presentation/utils/utils.dart';
|
export 'package:rasadyar_core/presentation/utils/utils.dart';
|
||||||
export 'package:rasadyar_core/presentation/widget/widget.dart';
|
export 'package:rasadyar_core/presentation/widget/widget.dart';
|
||||||
|
|
||||||
|
|
||||||
//network
|
//network
|
||||||
export 'infrastructure/remote/dio_form_data.dart';
|
export 'infrastructure/remote/dio_form_data.dart';
|
||||||
export 'infrastructure/remote/dio_remote.dart';
|
export 'infrastructure/remote/dio_remote.dart';
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import 'package:rasadyar_core/infrastructure/remote/interfaces/i_form_data.dart'
|
|||||||
import 'interfaces/i_http_client.dart';
|
import 'interfaces/i_http_client.dart';
|
||||||
|
|
||||||
class DioRemote implements IHttpClient {
|
class DioRemote implements IHttpClient {
|
||||||
final String baseUrl;
|
String? baseUrl;
|
||||||
late final Dio _dio;
|
late final Dio _dio;
|
||||||
|
|
||||||
DioRemote(this.baseUrl);
|
DioRemote({this.baseUrl});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
final dio = Dio(BaseOptions(baseUrl: baseUrl));
|
final dio = Dio(BaseOptions(baseUrl: baseUrl??''));
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
dio.interceptors.add(PrettyDioLogger(
|
dio.interceptors.add(PrettyDioLogger(
|
||||||
requestHeader: true,
|
requestHeader: true,
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
dart create --template=package ../packages/livestock
|
dart create --template=package ../packages/chicken
|
||||||
Reference in New Issue
Block a user