feat: login api

This commit is contained in:
efrilm
2025-08-16 17:27:57 +07:00
parent 6019036cd7
commit 255b10d5a9
31 changed files with 2997 additions and 86 deletions
+9
View File
@@ -0,0 +1,9 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/auth/auth.dart';
part 'auth_dtos.freezed.dart';
part 'auth_dtos.g.dart';
part 'dto/auth_dto.dart';
part 'dto/user_dto.dart';
@@ -0,0 +1,642 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'auth_dtos.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
AuthDto _$AuthDtoFromJson(Map<String, dynamic> json) {
return _AuthDto.fromJson(json);
}
/// @nodoc
mixin _$AuthDto {
@JsonKey(name: 'token')
String? get token => throw _privateConstructorUsedError;
@JsonKey(name: 'expires_at')
String? get expiresAt => throw _privateConstructorUsedError;
@JsonKey(name: 'user')
UserDto? get user => throw _privateConstructorUsedError;
/// Serializes this AuthDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of AuthDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$AuthDtoCopyWith<AuthDto> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AuthDtoCopyWith<$Res> {
factory $AuthDtoCopyWith(AuthDto value, $Res Function(AuthDto) then) =
_$AuthDtoCopyWithImpl<$Res, AuthDto>;
@useResult
$Res call({
@JsonKey(name: 'token') String? token,
@JsonKey(name: 'expires_at') String? expiresAt,
@JsonKey(name: 'user') UserDto? user,
});
$UserDtoCopyWith<$Res>? get user;
}
/// @nodoc
class _$AuthDtoCopyWithImpl<$Res, $Val extends AuthDto>
implements $AuthDtoCopyWith<$Res> {
_$AuthDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of AuthDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? token = freezed,
Object? expiresAt = freezed,
Object? user = freezed,
}) {
return _then(
_value.copyWith(
token: freezed == token
? _value.token
: token // ignore: cast_nullable_to_non_nullable
as String?,
expiresAt: freezed == expiresAt
? _value.expiresAt
: expiresAt // ignore: cast_nullable_to_non_nullable
as String?,
user: freezed == user
? _value.user
: user // ignore: cast_nullable_to_non_nullable
as UserDto?,
)
as $Val,
);
}
/// Create a copy of AuthDto
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$UserDtoCopyWith<$Res>? get user {
if (_value.user == null) {
return null;
}
return $UserDtoCopyWith<$Res>(_value.user!, (value) {
return _then(_value.copyWith(user: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$AuthDtoImplCopyWith<$Res> implements $AuthDtoCopyWith<$Res> {
factory _$$AuthDtoImplCopyWith(
_$AuthDtoImpl value,
$Res Function(_$AuthDtoImpl) then,
) = __$$AuthDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'token') String? token,
@JsonKey(name: 'expires_at') String? expiresAt,
@JsonKey(name: 'user') UserDto? user,
});
@override
$UserDtoCopyWith<$Res>? get user;
}
/// @nodoc
class __$$AuthDtoImplCopyWithImpl<$Res>
extends _$AuthDtoCopyWithImpl<$Res, _$AuthDtoImpl>
implements _$$AuthDtoImplCopyWith<$Res> {
__$$AuthDtoImplCopyWithImpl(
_$AuthDtoImpl _value,
$Res Function(_$AuthDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of AuthDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? token = freezed,
Object? expiresAt = freezed,
Object? user = freezed,
}) {
return _then(
_$AuthDtoImpl(
token: freezed == token
? _value.token
: token // ignore: cast_nullable_to_non_nullable
as String?,
expiresAt: freezed == expiresAt
? _value.expiresAt
: expiresAt // ignore: cast_nullable_to_non_nullable
as String?,
user: freezed == user
? _value.user
: user // ignore: cast_nullable_to_non_nullable
as UserDto?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$AuthDtoImpl extends _AuthDto {
const _$AuthDtoImpl({
@JsonKey(name: 'token') this.token,
@JsonKey(name: 'expires_at') this.expiresAt,
@JsonKey(name: 'user') this.user,
}) : super._();
factory _$AuthDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$AuthDtoImplFromJson(json);
@override
@JsonKey(name: 'token')
final String? token;
@override
@JsonKey(name: 'expires_at')
final String? expiresAt;
@override
@JsonKey(name: 'user')
final UserDto? user;
@override
String toString() {
return 'AuthDto(token: $token, expiresAt: $expiresAt, user: $user)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$AuthDtoImpl &&
(identical(other.token, token) || other.token == token) &&
(identical(other.expiresAt, expiresAt) ||
other.expiresAt == expiresAt) &&
(identical(other.user, user) || other.user == user));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType, token, expiresAt, user);
/// Create a copy of AuthDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$AuthDtoImplCopyWith<_$AuthDtoImpl> get copyWith =>
__$$AuthDtoImplCopyWithImpl<_$AuthDtoImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$AuthDtoImplToJson(this);
}
}
abstract class _AuthDto extends AuthDto {
const factory _AuthDto({
@JsonKey(name: 'token') final String? token,
@JsonKey(name: 'expires_at') final String? expiresAt,
@JsonKey(name: 'user') final UserDto? user,
}) = _$AuthDtoImpl;
const _AuthDto._() : super._();
factory _AuthDto.fromJson(Map<String, dynamic> json) = _$AuthDtoImpl.fromJson;
@override
@JsonKey(name: 'token')
String? get token;
@override
@JsonKey(name: 'expires_at')
String? get expiresAt;
@override
@JsonKey(name: 'user')
UserDto? get user;
/// Create a copy of AuthDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$AuthDtoImplCopyWith<_$AuthDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
UserDto _$UserDtoFromJson(Map<String, dynamic> json) {
return _UserDto.fromJson(json);
}
/// @nodoc
mixin _$UserDto {
@JsonKey(name: 'id')
String? get id => throw _privateConstructorUsedError;
@JsonKey(name: 'organization_id')
String? get organizationId => throw _privateConstructorUsedError;
@JsonKey(name: 'outlet_id')
String? get outletId => throw _privateConstructorUsedError;
@JsonKey(name: 'name')
String? get name => throw _privateConstructorUsedError;
@JsonKey(name: 'email')
String? get email => throw _privateConstructorUsedError;
@JsonKey(name: 'role')
String? get role => throw _privateConstructorUsedError;
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions => throw _privateConstructorUsedError;
@JsonKey(name: 'is_active')
bool? get isActive => throw _privateConstructorUsedError;
@JsonKey(name: 'created_at')
String? get createdAt => throw _privateConstructorUsedError;
@JsonKey(name: 'updated_at')
String? get updatedAt => throw _privateConstructorUsedError;
/// Serializes this UserDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$UserDtoCopyWith<UserDto> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserDtoCopyWith<$Res> {
factory $UserDtoCopyWith(UserDto value, $Res Function(UserDto) then) =
_$UserDtoCopyWithImpl<$Res, UserDto>;
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class _$UserDtoCopyWithImpl<$Res, $Val extends UserDto>
implements $UserDtoCopyWith<$Res> {
_$UserDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? organizationId = freezed,
Object? outletId = freezed,
Object? name = freezed,
Object? email = freezed,
Object? role = freezed,
Object? permissions = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_value.copyWith(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String?,
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
email: freezed == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String?,
role: freezed == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String?,
permissions: freezed == permissions
? _value.permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$UserDtoImplCopyWith<$Res> implements $UserDtoCopyWith<$Res> {
factory _$$UserDtoImplCopyWith(
_$UserDtoImpl value,
$Res Function(_$UserDtoImpl) then,
) = __$$UserDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
});
}
/// @nodoc
class __$$UserDtoImplCopyWithImpl<$Res>
extends _$UserDtoCopyWithImpl<$Res, _$UserDtoImpl>
implements _$$UserDtoImplCopyWith<$Res> {
__$$UserDtoImplCopyWithImpl(
_$UserDtoImpl _value,
$Res Function(_$UserDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? organizationId = freezed,
Object? outletId = freezed,
Object? name = freezed,
Object? email = freezed,
Object? role = freezed,
Object? permissions = freezed,
Object? isActive = freezed,
Object? createdAt = freezed,
Object? updatedAt = freezed,
}) {
return _then(
_$UserDtoImpl(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String?,
organizationId: freezed == organizationId
? _value.organizationId
: organizationId // ignore: cast_nullable_to_non_nullable
as String?,
outletId: freezed == outletId
? _value.outletId
: outletId // ignore: cast_nullable_to_non_nullable
as String?,
name: freezed == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String?,
email: freezed == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String?,
role: freezed == role
? _value.role
: role // ignore: cast_nullable_to_non_nullable
as String?,
permissions: freezed == permissions
? _value._permissions
: permissions // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,
isActive: freezed == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool?,
createdAt: freezed == createdAt
? _value.createdAt
: createdAt // ignore: cast_nullable_to_non_nullable
as String?,
updatedAt: freezed == updatedAt
? _value.updatedAt
: updatedAt // ignore: cast_nullable_to_non_nullable
as String?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$UserDtoImpl extends _UserDto {
const _$UserDtoImpl({
@JsonKey(name: 'id') this.id,
@JsonKey(name: 'organization_id') this.organizationId,
@JsonKey(name: 'outlet_id') this.outletId,
@JsonKey(name: 'name') this.name,
@JsonKey(name: 'email') this.email,
@JsonKey(name: 'role') this.role,
@JsonKey(name: 'permissions') final Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') this.isActive,
@JsonKey(name: 'created_at') this.createdAt,
@JsonKey(name: 'updated_at') this.updatedAt,
}) : _permissions = permissions,
super._();
factory _$UserDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$UserDtoImplFromJson(json);
@override
@JsonKey(name: 'id')
final String? id;
@override
@JsonKey(name: 'organization_id')
final String? organizationId;
@override
@JsonKey(name: 'outlet_id')
final String? outletId;
@override
@JsonKey(name: 'name')
final String? name;
@override
@JsonKey(name: 'email')
final String? email;
@override
@JsonKey(name: 'role')
final String? role;
final Map<String, dynamic>? _permissions;
@override
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions {
final value = _permissions;
if (value == null) return null;
if (_permissions is EqualUnmodifiableMapView) return _permissions;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
@override
@JsonKey(name: 'is_active')
final bool? isActive;
@override
@JsonKey(name: 'created_at')
final String? createdAt;
@override
@JsonKey(name: 'updated_at')
final String? updatedAt;
@override
String toString() {
return 'UserDto(id: $id, organizationId: $organizationId, outletId: $outletId, name: $name, email: $email, role: $role, permissions: $permissions, isActive: $isActive, createdAt: $createdAt, updatedAt: $updatedAt)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserDtoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.organizationId, organizationId) ||
other.organizationId == organizationId) &&
(identical(other.outletId, outletId) ||
other.outletId == outletId) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.email, email) || other.email == email) &&
(identical(other.role, role) || other.role == role) &&
const DeepCollectionEquality().equals(
other._permissions,
_permissions,
) &&
(identical(other.isActive, isActive) ||
other.isActive == isActive) &&
(identical(other.createdAt, createdAt) ||
other.createdAt == createdAt) &&
(identical(other.updatedAt, updatedAt) ||
other.updatedAt == updatedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
id,
organizationId,
outletId,
name,
email,
role,
const DeepCollectionEquality().hash(_permissions),
isActive,
createdAt,
updatedAt,
);
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$UserDtoImplCopyWith<_$UserDtoImpl> get copyWith =>
__$$UserDtoImplCopyWithImpl<_$UserDtoImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$UserDtoImplToJson(this);
}
}
abstract class _UserDto extends UserDto {
const factory _UserDto({
@JsonKey(name: 'id') final String? id,
@JsonKey(name: 'organization_id') final String? organizationId,
@JsonKey(name: 'outlet_id') final String? outletId,
@JsonKey(name: 'name') final String? name,
@JsonKey(name: 'email') final String? email,
@JsonKey(name: 'role') final String? role,
@JsonKey(name: 'permissions') final Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') final bool? isActive,
@JsonKey(name: 'created_at') final String? createdAt,
@JsonKey(name: 'updated_at') final String? updatedAt,
}) = _$UserDtoImpl;
const _UserDto._() : super._();
factory _UserDto.fromJson(Map<String, dynamic> json) = _$UserDtoImpl.fromJson;
@override
@JsonKey(name: 'id')
String? get id;
@override
@JsonKey(name: 'organization_id')
String? get organizationId;
@override
@JsonKey(name: 'outlet_id')
String? get outletId;
@override
@JsonKey(name: 'name')
String? get name;
@override
@JsonKey(name: 'email')
String? get email;
@override
@JsonKey(name: 'role')
String? get role;
@override
@JsonKey(name: 'permissions')
Map<String, dynamic>? get permissions;
@override
@JsonKey(name: 'is_active')
bool? get isActive;
@override
@JsonKey(name: 'created_at')
String? get createdAt;
@override
@JsonKey(name: 'updated_at')
String? get updatedAt;
/// Create a copy of UserDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$UserDtoImplCopyWith<_$UserDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
+51
View File
@@ -0,0 +1,51 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'auth_dtos.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$AuthDtoImpl _$$AuthDtoImplFromJson(Map<String, dynamic> json) =>
_$AuthDtoImpl(
token: json['token'] as String?,
expiresAt: json['expires_at'] as String?,
user: json['user'] == null
? null
: UserDto.fromJson(json['user'] as Map<String, dynamic>),
);
Map<String, dynamic> _$$AuthDtoImplToJson(_$AuthDtoImpl instance) =>
<String, dynamic>{
'token': instance.token,
'expires_at': instance.expiresAt,
'user': instance.user,
};
_$UserDtoImpl _$$UserDtoImplFromJson(Map<String, dynamic> json) =>
_$UserDtoImpl(
id: json['id'] as String?,
organizationId: json['organization_id'] as String?,
outletId: json['outlet_id'] as String?,
name: json['name'] as String?,
email: json['email'] as String?,
role: json['role'] as String?,
permissions: json['permissions'] as Map<String, dynamic>?,
isActive: json['is_active'] as bool?,
createdAt: json['created_at'] as String?,
updatedAt: json['updated_at'] as String?,
);
Map<String, dynamic> _$$UserDtoImplToJson(_$UserDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'organization_id': instance.organizationId,
'outlet_id': instance.outletId,
'name': instance.name,
'email': instance.email,
'role': instance.role,
'permissions': instance.permissions,
'is_active': instance.isActive,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
@@ -0,0 +1,54 @@
import 'dart:convert';
import 'package:injectable/injectable.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../common/constant/local_storage_key.dart';
import '../../../domain/auth/auth.dart';
import '../auth_dtos.dart';
@injectable
class AuthLocalDataProvider {
final SharedPreferences _sharedPreferences;
AuthLocalDataProvider(this._sharedPreferences);
Future<void> saveToken(String token) async {
await _sharedPreferences.setString(LocalStorageKey.token, token);
}
Future<String?> getToken() async {
return _sharedPreferences.getString(LocalStorageKey.token);
}
Future<void> deleteToken() async {
await _sharedPreferences.remove(LocalStorageKey.token);
}
Future<bool> hasToken() async {
return _sharedPreferences.containsKey(LocalStorageKey.token);
}
Future<void> saveCurrentUser(UserDto user) async {
final userJsonString = jsonEncode(user.toJson());
await _sharedPreferences.setString(LocalStorageKey.user, userJsonString);
}
Future<User> currentUser() async {
final userString = _sharedPreferences.getString(LocalStorageKey.user);
if (userString == null) return User.empty();
final Map<String, dynamic> userMap = jsonDecode(userString);
final userDto = UserDto.fromJson(userMap);
return userDto.toDomain();
}
Future<void> deleteCurrentUser() async {
await _sharedPreferences.remove(LocalStorageKey.user);
}
Future<void> deleteAllAuth() async {
await _sharedPreferences.remove(LocalStorageKey.token);
await _sharedPreferences.remove(LocalStorageKey.user);
}
}
@@ -0,0 +1,44 @@
import 'dart:developer';
import 'package:injectable/injectable.dart';
import 'package:data_channel/data_channel.dart';
import '../../../common/api/api_client.dart';
import '../../../common/api/api_failure.dart';
import '../../../common/url/api_path.dart';
import '../../../domain/auth/auth.dart';
import '../auth_dtos.dart';
@injectable
class AuthRemoteDataProvider {
final ApiClient _apiClient;
final String _logName = "AuthRemoteDataProvider";
AuthRemoteDataProvider(this._apiClient);
Future<DC<AuthFailure, AuthDto>> login({
required String email,
required String password,
}) async {
try {
final response = await _apiClient.post(
ApiPath.login,
data: {'email': email, 'password': password},
);
if (response.data['code'] == 401) {
return DC.error(
AuthFailure.serverError(
ApiFailure.unauthorized('Incorrect email or password'),
),
);
}
final dto = AuthDto.fromJson(response.data['data']);
return DC.data(dto);
} on ApiFailure catch (e, s) {
log('login', name: _logName, error: e, stackTrace: s);
return DC.error(AuthFailure.serverError(e));
}
}
}
+23
View File
@@ -0,0 +1,23 @@
part of '../auth_dtos.dart';
@freezed
class AuthDto with _$AuthDto {
const AuthDto._();
const factory AuthDto({
@JsonKey(name: 'token') String? token,
@JsonKey(name: 'expires_at') String? expiresAt,
@JsonKey(name: 'user') UserDto? user,
}) = _AuthDto;
factory AuthDto.fromJson(Map<String, dynamic> json) =>
_$AuthDtoFromJson(json);
Auth toDomain() => Auth(
token: token ?? '',
expiresAt: expiresAt != null
? DateTime.parse(expiresAt ?? "")
: DateTime.fromMillisecondsSinceEpoch(0),
user: user?.toDomain() ?? User.empty(),
);
}
+39
View File
@@ -0,0 +1,39 @@
part of '../auth_dtos.dart';
@freezed
class UserDto with _$UserDto {
const UserDto._();
const factory UserDto({
@JsonKey(name: 'id') String? id,
@JsonKey(name: 'organization_id') String? organizationId,
@JsonKey(name: 'outlet_id') String? outletId,
@JsonKey(name: 'name') String? name,
@JsonKey(name: 'email') String? email,
@JsonKey(name: 'role') String? role,
@JsonKey(name: 'permissions') Map<String, dynamic>? permissions,
@JsonKey(name: 'is_active') bool? isActive,
@JsonKey(name: 'created_at') String? createdAt,
@JsonKey(name: 'updated_at') String? updatedAt,
}) = _UserDto;
factory UserDto.fromJson(Map<String, dynamic> json) =>
_$UserDtoFromJson(json);
User toDomain() => User(
id: id ?? '',
organizationId: organizationId ?? '',
outletId: outletId ?? '',
name: name ?? '',
email: email ?? '',
role: role ?? '',
permissions: permissions ?? {},
isActive: isActive ?? false,
createdAt: createdAt != null
? DateTime.parse(createdAt ?? "")
: DateTime.fromMillisecondsSinceEpoch(0),
updatedAt: updatedAt != null
? DateTime.parse(updatedAt ?? "")
: DateTime.fromMillisecondsSinceEpoch(0),
);
}
@@ -0,0 +1,45 @@
import 'dart:developer';
import 'package:dartz/dartz.dart';
import 'package:injectable/injectable.dart';
import '../../../domain/auth/auth.dart';
import '../datasources/local_data_provider.dart';
import '../datasources/remote_data_provider.dart';
@Injectable(as: IAuthRepository)
class AuthRepository implements IAuthRepository {
final AuthLocalDataProvider _localDataProvider;
final AuthRemoteDataProvider _remoteDataProvider;
final String _logName = 'AuthRepository';
AuthRepository(this._localDataProvider, this._remoteDataProvider);
@override
Future<Either<AuthFailure, Auth>> login({
required String email,
required String password,
}) async {
try {
final result = await _remoteDataProvider.login(
email: email,
password: password,
);
if (result.hasError) {
return left(result.error!);
}
final auth = result.data!.toDomain();
await _localDataProvider.saveToken(auth.token);
await _localDataProvider.saveCurrentUser(result.data!.user!);
return right(auth);
} catch (e, s) {
log('loginError', name: _logName, error: e, stackTrace: s);
return left(const AuthFailure.unexpectedError());
}
}
}