1111
This commit is contained in:
77
lib/data/datasources/auth_remote_data_source.dart
Normal file
77
lib/data/datasources/auth_remote_data_source.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import '../../core/error/exceptions.dart';
|
||||
import '../../core/network/api_client.dart';
|
||||
import '../dto/login_dto.dart';
|
||||
import '../dto/login_response_dto.dart';
|
||||
|
||||
abstract class AuthRemoteDataSource {
|
||||
Future<LoginResponseDto> login(LoginDto dto);
|
||||
}
|
||||
|
||||
class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
final ApiClient apiClient;
|
||||
|
||||
AuthRemoteDataSourceImpl({required this.apiClient});
|
||||
|
||||
@override
|
||||
Future<LoginResponseDto> login(LoginDto dto) async {
|
||||
try {
|
||||
final response = await apiClient.post(
|
||||
'/Auth/login',
|
||||
data: dto.toJson(),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
final responseData = response.data;
|
||||
|
||||
if (responseData is Map<String, dynamic>) {
|
||||
return LoginResponseDto.fromJson(responseData);
|
||||
} else {
|
||||
throw ServerException(
|
||||
message: 'استجابة غير صحيحة من الخادم',
|
||||
statusCode: response.statusCode,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw ServerException(
|
||||
message: 'فشل تسجيل الدخول',
|
||||
statusCode: response.statusCode,
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
if (e.type == DioExceptionType.connectionTimeout ||
|
||||
e.type == DioExceptionType.receiveTimeout) {
|
||||
throw NetworkException(message: 'انتهت مهلة الاتصال');
|
||||
} else if (e.type == DioExceptionType.connectionError) {
|
||||
throw NetworkException(message: 'لا يوجد اتصال بالانترنيت');
|
||||
} else if (e.response?.statusCode == 500) {
|
||||
throw ServerException(message: 'خطأ في الخادم يرجى المحاولة لاحقا');
|
||||
} else if (e.response != null) {
|
||||
final message = e.response?.data?['message'] ??
|
||||
e.response?.data?['error'] ??
|
||||
'فشل تسجيل الدخول';
|
||||
|
||||
// Check for invalid credentials
|
||||
final customMessage =
|
||||
message.toString().toLowerCase().contains('invalid') ||
|
||||
message.toString().toLowerCase().contains('incorrect')
|
||||
? 'رقم الهاتف أو كلمة المرور غير صحيحة'
|
||||
: message.toString().toLowerCase().contains('not found')
|
||||
? 'المستخدم غير موجود'
|
||||
: message;
|
||||
|
||||
throw ServerException(
|
||||
message: customMessage,
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
} else {
|
||||
throw NetworkException(message: 'خطأ في الانترنيت يرجى المحاولة لاحقا');
|
||||
}
|
||||
} catch (e) {
|
||||
if (e is ServerException || e is NetworkException) {
|
||||
rethrow;
|
||||
}
|
||||
throw ServerException(message: 'خطأ غير متوقع');
|
||||
}
|
||||
}
|
||||
}
|
||||
16
lib/data/dto/login_dto.dart
Normal file
16
lib/data/dto/login_dto.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
class LoginDto {
|
||||
final String phoneNumber;
|
||||
final String password;
|
||||
|
||||
LoginDto({
|
||||
required this.phoneNumber,
|
||||
required this.password,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'phoneNumber': phoneNumber,
|
||||
'password': password,
|
||||
};
|
||||
}
|
||||
}
|
||||
85
lib/data/dto/login_response_dto.dart
Normal file
85
lib/data/dto/login_response_dto.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
class LoginResponseDto {
|
||||
final int statusCode;
|
||||
final bool isSuccess;
|
||||
final String message;
|
||||
final LoginDataDto? data;
|
||||
|
||||
LoginResponseDto({
|
||||
required this.statusCode,
|
||||
required this.isSuccess,
|
||||
required this.message,
|
||||
this.data,
|
||||
});
|
||||
|
||||
factory LoginResponseDto.fromJson(Map<String, dynamic> json) {
|
||||
return LoginResponseDto(
|
||||
statusCode: json['statusCode'] ?? 0,
|
||||
isSuccess: json['isSuccess'] ?? false,
|
||||
message: json['message'] ?? '',
|
||||
data: json['data'] != null ? LoginDataDto.fromJson(json['data']) : null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'statusCode': statusCode,
|
||||
'isSuccess': isSuccess,
|
||||
'message': message,
|
||||
'data': data?.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class LoginDataDto {
|
||||
final String? token;
|
||||
final String? id;
|
||||
final String? employeeId;
|
||||
final String? username;
|
||||
final String? fullName;
|
||||
final String? role;
|
||||
final String? email;
|
||||
final String? phoneNumber;
|
||||
final List<String>? permissions;
|
||||
|
||||
LoginDataDto({
|
||||
this.token,
|
||||
this.id,
|
||||
this.employeeId,
|
||||
this.username,
|
||||
this.fullName,
|
||||
this.role,
|
||||
this.email,
|
||||
this.phoneNumber,
|
||||
this.permissions,
|
||||
});
|
||||
|
||||
factory LoginDataDto.fromJson(Map<String, dynamic> json) {
|
||||
return LoginDataDto(
|
||||
token: json['token'],
|
||||
id: json['id'],
|
||||
employeeId: json['employeeId'],
|
||||
username: json['username'],
|
||||
fullName: json['fullName'],
|
||||
role: json['role'],
|
||||
email: json['email'],
|
||||
phoneNumber: json['phoneNumber'],
|
||||
permissions: json['permissions'] != null
|
||||
? List<String>.from(json['permissions'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'token': token,
|
||||
'id': id,
|
||||
'employeeId': employeeId,
|
||||
'username': username,
|
||||
'fullName': fullName,
|
||||
'role': role,
|
||||
'email': email,
|
||||
'phoneNumber': phoneNumber,
|
||||
'permissions': permissions,
|
||||
};
|
||||
}
|
||||
}
|
||||
65
lib/data/repositories/auth_repository_impl.dart
Normal file
65
lib/data/repositories/auth_repository_impl.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import '../../core/error/exceptions.dart';
|
||||
import '../../core/error/failures.dart';
|
||||
import '../datasources/auth_remote_data_source.dart';
|
||||
import '../datasources/user_local_data_source.dart';
|
||||
import '../dto/login_dto.dart';
|
||||
import '../dto/login_response_dto.dart';
|
||||
import '../../domain/models/login_request.dart';
|
||||
import '../../domain/models/login_response_model.dart';
|
||||
import '../../domain/repositories/auth_repository.dart';
|
||||
|
||||
class AuthRepositoryImpl implements AuthRepository {
|
||||
final AuthRemoteDataSource remoteDataSource;
|
||||
final UserLocalDataSource localDataSource;
|
||||
|
||||
AuthRepositoryImpl({
|
||||
required this.remoteDataSource,
|
||||
required this.localDataSource,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, LoginResponseModel>> login(LoginRequest request) async {
|
||||
try {
|
||||
final dto = LoginDto(
|
||||
phoneNumber: request.phoneNumber,
|
||||
password: request.password,
|
||||
);
|
||||
|
||||
final responseDto = await remoteDataSource.login(dto);
|
||||
|
||||
// Cache the token locally
|
||||
if (responseDto.data?.token != null) {
|
||||
await localDataSource.cacheUserToken(responseDto.data!.token!);
|
||||
}
|
||||
|
||||
// Convert DTO to Model
|
||||
final responseModel = LoginResponseModel(
|
||||
statusCode: responseDto.statusCode,
|
||||
isSuccess: responseDto.isSuccess,
|
||||
message: responseDto.message,
|
||||
data: responseDto.data != null
|
||||
? LoginDataModel(
|
||||
token: responseDto.data!.token,
|
||||
id: responseDto.data!.id,
|
||||
employeeId: responseDto.data!.employeeId,
|
||||
username: responseDto.data!.username,
|
||||
fullName: responseDto.data!.fullName,
|
||||
role: responseDto.data!.role,
|
||||
email: responseDto.data!.email,
|
||||
phoneNumber: responseDto.data!.phoneNumber,
|
||||
permissions: responseDto.data!.permissions,
|
||||
)
|
||||
: null,
|
||||
);
|
||||
|
||||
return Right(responseModel);
|
||||
} on ServerException catch (e) {
|
||||
return Left(ServerFailure(e.message));
|
||||
} on NetworkException catch (e) {
|
||||
return Left(NetworkFailure(e.message));
|
||||
} catch (e) {
|
||||
return Left(ServerFailure('خطأ غير متوقع: $e'));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user