attendence login/logout has been implemented
This commit is contained in:
58
lib/data/datasources/attendance_remote_data_source.dart
Normal file
58
lib/data/datasources/attendance_remote_data_source.dart
Normal file
@@ -0,0 +1,58 @@
|
||||
import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import '../../core/network/api_client.dart';
|
||||
import '../dto/attendance_response_dto.dart';
|
||||
|
||||
abstract class AttendanceRemoteDataSource {
|
||||
Future<AttendanceResponseDto> login({
|
||||
required String employeeId,
|
||||
required File faceImage,
|
||||
});
|
||||
|
||||
Future<AttendanceResponseDto> logout({
|
||||
required String employeeId,
|
||||
required File faceImage,
|
||||
});
|
||||
}
|
||||
|
||||
class AttendanceRemoteDataSourceImpl implements AttendanceRemoteDataSource {
|
||||
final ApiClient apiClient;
|
||||
|
||||
AttendanceRemoteDataSourceImpl({required this.apiClient});
|
||||
@override
|
||||
Future<AttendanceResponseDto> login({
|
||||
required String employeeId,
|
||||
required File faceImage,
|
||||
}) async {
|
||||
final formData = FormData.fromMap({
|
||||
'EmployeeId': employeeId,
|
||||
'FaceImage': await MultipartFile.fromFile(faceImage.path),
|
||||
});
|
||||
|
||||
final response = await apiClient.post(
|
||||
'/Attendance/login',
|
||||
data: formData,
|
||||
options: Options(contentType: 'multipart/form-data'),
|
||||
);
|
||||
return AttendanceResponseDto.fromJson(response.data);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AttendanceResponseDto> logout({
|
||||
required String employeeId,
|
||||
required File faceImage,
|
||||
}) async {
|
||||
final formData = FormData.fromMap({
|
||||
'EmployeeId': employeeId,
|
||||
'FaceImage': await MultipartFile.fromFile(faceImage.path),
|
||||
});
|
||||
|
||||
final response = await apiClient.post(
|
||||
'/Attendance/logout',
|
||||
data: formData,
|
||||
options: Options(contentType: 'multipart/form-data'),
|
||||
);
|
||||
|
||||
return AttendanceResponseDto.fromJson(response.data);
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,7 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
@override
|
||||
Future<LoginResponseDto> login(LoginDto dto) async {
|
||||
try {
|
||||
final response = await apiClient.post(
|
||||
'/Auth/login',
|
||||
data: dto.toJson(),
|
||||
);
|
||||
final response = await apiClient.post('/Auth/login', data: dto.toJson());
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
final responseData = response.data;
|
||||
@@ -47,7 +44,8 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
} else if (e.response?.statusCode == 500) {
|
||||
throw ServerException(message: 'خطأ في الخادم يرجى المحاولة لاحقا');
|
||||
} else if (e.response != null) {
|
||||
final message = e.response?.data?['message'] ??
|
||||
final message =
|
||||
e.response?.data?['message'] ??
|
||||
e.response?.data?['error'] ??
|
||||
'فشل تسجيل الدخول';
|
||||
|
||||
@@ -57,8 +55,8 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
message.toString().toLowerCase().contains('incorrect')
|
||||
? 'رقم الهاتف أو كلمة المرور غير صحيحة'
|
||||
: message.toString().toLowerCase().contains('not found')
|
||||
? 'المستخدم غير موجود'
|
||||
: message;
|
||||
? 'المستخدم غير موجود'
|
||||
: message;
|
||||
|
||||
throw ServerException(
|
||||
message: customMessage,
|
||||
|
||||
@@ -4,11 +4,14 @@ abstract class UserLocalDataSource {
|
||||
Future<void> cacheUserToken(String token);
|
||||
Future<String?> getCachedUserToken();
|
||||
Future<void> clearCache();
|
||||
Future<void> cacheEmployeeId(String id);
|
||||
Future<String?> getCachedEmployeeId();
|
||||
}
|
||||
|
||||
class UserLocalDataSourceImpl implements UserLocalDataSource {
|
||||
final SharedPreferences sharedPreferences;
|
||||
static const String _tokenKey = 'user_token';
|
||||
static const String _employeeIdKey = 'employee_id';
|
||||
|
||||
UserLocalDataSourceImpl({required this.sharedPreferences});
|
||||
|
||||
@@ -25,5 +28,16 @@ class UserLocalDataSourceImpl implements UserLocalDataSource {
|
||||
@override
|
||||
Future<void> clearCache() async {
|
||||
await sharedPreferences.remove(_tokenKey);
|
||||
await sharedPreferences.remove(_employeeIdKey);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> cacheEmployeeId(String id) async {
|
||||
await sharedPreferences.setString(_employeeIdKey, id);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String?> getCachedEmployeeId() async {
|
||||
return sharedPreferences.getString(_employeeIdKey);
|
||||
}
|
||||
}
|
||||
|
||||
24
lib/data/dto/attendance_response_dto.dart
Normal file
24
lib/data/dto/attendance_response_dto.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
class AttendanceResponseDto {
|
||||
final String id;
|
||||
final String employeeId;
|
||||
final DateTime? login;
|
||||
final DateTime? logout;
|
||||
|
||||
AttendanceResponseDto({
|
||||
required this.id,
|
||||
required this.employeeId,
|
||||
this.login,
|
||||
this.logout,
|
||||
});
|
||||
|
||||
factory AttendanceResponseDto.fromJson(Map<String, dynamic> json) {
|
||||
final data = json['data'];
|
||||
|
||||
return AttendanceResponseDto(
|
||||
id: data['id'],
|
||||
employeeId: data['employeeId'],
|
||||
login: data['login'],
|
||||
logout: data['logout'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -57,15 +57,17 @@ class LoginDataDto {
|
||||
return LoginDataDto(
|
||||
token: json['token'],
|
||||
id: json['id'],
|
||||
employeeId: json['employeeId'],
|
||||
employeeId:
|
||||
json['employeeId'] ?? json['EmployeeId'] ?? json['employee_id'],
|
||||
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,
|
||||
permissions:
|
||||
json['permissions'] != null
|
||||
? List<String>.from(json['permissions'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
41
lib/data/repositories/attendance_repository_impl.dart
Normal file
41
lib/data/repositories/attendance_repository_impl.dart
Normal file
@@ -0,0 +1,41 @@
|
||||
import '../../domain/models/attendance_login_request.dart';
|
||||
import '../../domain/models/attendance_logout_request.dart';
|
||||
import '../../domain/models/attendance_response_model.dart';
|
||||
import '../../domain/repositories/attendance_repository.dart';
|
||||
import '../datasources/attendance_remote_data_source.dart';
|
||||
|
||||
class AttendanceRepositoryImpl implements AttendanceRepository {
|
||||
final AttendanceRemoteDataSource remoteDataSource;
|
||||
|
||||
AttendanceRepositoryImpl({required this.remoteDataSource});
|
||||
|
||||
@override
|
||||
Future<AttendanceResponseModel> login(AttendanceLoginRequest request) async {
|
||||
final dto = await remoteDataSource.login(
|
||||
employeeId: request.employeeId,
|
||||
faceImage: request.faceImage,
|
||||
);
|
||||
|
||||
return AttendanceResponseModel(
|
||||
id: dto.id,
|
||||
employeeId: dto.employeeId,
|
||||
login: dto.login,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AttendanceResponseModel> logout(
|
||||
AttendanceLogoutRequest request,
|
||||
) async {
|
||||
final dto = await remoteDataSource.logout(
|
||||
employeeId: request.employeeId,
|
||||
faceImage: request.faceImage,
|
||||
);
|
||||
|
||||
return AttendanceResponseModel(
|
||||
id: dto.id,
|
||||
employeeId: dto.employeeId,
|
||||
logout: dto.logout,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ 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';
|
||||
@@ -19,7 +18,9 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, LoginResponseModel>> login(LoginRequest request) async {
|
||||
Future<Either<Failure, LoginResponseModel>> login(
|
||||
LoginRequest request,
|
||||
) async {
|
||||
try {
|
||||
final dto = LoginDto(
|
||||
phoneNumber: request.phoneNumber,
|
||||
@@ -27,30 +28,38 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
);
|
||||
|
||||
final responseDto = await remoteDataSource.login(dto);
|
||||
print("LOGIN RESPONSE DATA: ${responseDto.toJson()}"); // Debugging Log
|
||||
|
||||
// Cache the token locally
|
||||
if (responseDto.data?.token != null) {
|
||||
await localDataSource.cacheUserToken(responseDto.data!.token!);
|
||||
}
|
||||
if (responseDto.data?.employeeId != null) {
|
||||
print("AUTH_REPO: Caching EmployeeId: ${responseDto.data!.employeeId}");
|
||||
await localDataSource.cacheEmployeeId(responseDto.data!.employeeId!);
|
||||
} else {
|
||||
print("AUTH_REPO: EmployeeId is NULL in response!");
|
||||
}
|
||||
|
||||
// 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,
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user