diff --git a/lib/core/config/app_config.dart b/lib/core/config/app_config.dart index b73dd76..3439e47 100644 --- a/lib/core/config/app_config.dart +++ b/lib/core/config/app_config.dart @@ -8,11 +8,26 @@ class AppConfig { // این متد بر اساس محیط فعال، URL مناسب را برمی‌گرداند. static String get apiBaseUrl { - if (isDevelopment) { - return 'https://api.dev.your-app.com'; - } else { - return 'https://api.prod.your-app.com'; - } + return 'http://10.0.2.2:8081'; + // if (isDevelopment) { + // // Handle different platforms for local development + // if (kIsWeb) { + // // For web, use localhost + // return 'http://localhost:8081'; + // } else if (Platform.isAndroid) { + // // For Android emulator, use 10.0.2.2 (special IP for host machine) + // return 'http://10.0.2.2:8081'; + // } else if (Platform.isIOS) { + // // For iOS simulator, use localhost + // return 'http://localhost:8081'; + // } else { + // // For other platforms (desktop), use localhost + // return 'http://localhost:8081'; + // } + // } else { + // // Production URL - replace with your actual production server + // return 'https://your-production-server.com'; + // } } // کلیدهای حساس را به این شکل مدیریت کنید diff --git a/lib/core/network/network_manager.dart b/lib/core/network/network_manager.dart index 755dd89..1a60fb7 100644 --- a/lib/core/network/network_manager.dart +++ b/lib/core/network/network_manager.dart @@ -1,24 +1,17 @@ -import 'dart:io'; - import 'package:dio/dio.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import '../utils/logger.dart'; -import '../utils/result.dart'; -import 'app_exceptions.dart'; -import 'network_connectivity.dart'; +import '../config/app_config.dart'; class NetworkManager { final Dio mainDio; - final NetworkConnectivity _connectivity = NetworkConnectivity(); NetworkManager() : mainDio = Dio( BaseOptions( - // baseUrl: 'https://stage.cura-bau.de', + // baseUrl: AppConfig.apiBaseUrl, connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 10), - sendTimeout: const Duration(seconds: 10), contentType: 'application/json', headers: {'Accept': 'application/json'}, ), @@ -31,270 +24,108 @@ class NetworkManager { Future addInterceptors() async { final requestInterceptor = InterceptorsWrapper( onRequest: (options, handler) { - appLogger.info('🌐 Request: ${options.method} ${options.path}'); - appLogger.info('🌐 Headers: ${options.headers}'); + // TODO: add more return handler.next(options); }, - onResponse: (response, handler) { - appLogger.info( - '✅ Response: ${response.statusCode} ${response.requestOptions.path}', - ); - appLogger.info('✅ Response data: ${response.data}'); - return handler.next(response); - }, - onError: (error, handler) { - appLogger.error( - '❌ Error: ${error.message} - ${error.requestOptions.path}', - ); - appLogger.error('❌ Error type: ${error.type}'); - return handler.next(error); - }, ); mainDio.interceptors.add(requestInterceptor); } - /// Enhanced makeRequest method with comprehensive error handling - Future> makeRequest( + Future makeRequest( String endpoint, T Function(Map) fromJson, { String method = 'GET', FormData? data, - Map? queryParameters, }) async { - appLogger.info('🚀 network request: $method $endpoint'); + SharedPreferences prefs = await SharedPreferences.getInstance(); + + Dio dioInstance = mainDio; + + await addInterceptors(); + + Future makeApiCall(String token, String url) async { + final headers = + token.isEmpty + ? {} + : {'Authorization': 'Bearer $token'}; + switch (method.toUpperCase()) { + case 'POST': + return await dioInstance.post( + url + endpoint, + data: data, + options: Options(headers: headers), + ); + case 'PUT': + return await dioInstance.put( + url + endpoint, + data: data, + options: Options(headers: headers), + ); + case 'PATCH': + return await dioInstance.patch( + url + endpoint, + data: data, + options: Options(headers: headers), + ); + case 'DELETE': + return await dioInstance.delete( + url + endpoint, + data: data, + options: Options(headers: headers), + ); + case 'GET': + return await dioInstance.get( + url + endpoint, + data: data, + options: Options(headers: headers), + ); + default: + return await dioInstance.get( + url + endpoint, + options: Options(headers: headers), + ); + } + } try { - // Check network connectivity first - if (!await _connectivity.hasInternetConnection()) { - appLogger.error('❌ No internet connection available'); - return Result.error( - NetworkConnectionException('No internet connection available'), - ); - } - - SharedPreferences prefs = await SharedPreferences.getInstance(); - Dio dioInstance = mainDio; - - await addInterceptors(); - - Future makeApiCall(String token, String url) async { - final headers = - token.isEmpty - ? {} - : {'Authorization': 'Bearer $token'}; - - final options = Options( - headers: headers, - validateStatus: (status) => status != null && status < 500, - ); - - switch (method.toUpperCase()) { - case 'POST': - return await dioInstance.post( - url + endpoint, - data: data, - queryParameters: queryParameters, - options: options, - ); - case 'PUT': - return await dioInstance.put( - url + endpoint, - data: data, - queryParameters: queryParameters, - options: options, - ); - case 'PATCH': - return await dioInstance.patch( - url + endpoint, - data: data, - queryParameters: queryParameters, - options: options, - ); - case 'DELETE': - return await dioInstance.delete( - url + endpoint, - data: data, - queryParameters: queryParameters, - options: options, - ); - case 'GET': - return await dioInstance.get( - url + endpoint, - queryParameters: queryParameters, - options: options, - ); - default: - return await dioInstance.get( - url + endpoint, - queryParameters: queryParameters, - options: options, - ); - } - } - String? bearerToken = prefs.getString('bearer'); - String? url = prefs.getString('url'); - - appLogger.info('🔗 Base URL: ${url ?? 'NOT SET'}'); - appLogger.info( - '🔑 Bearer token: ${bearerToken != null ? 'PRESENT' : 'NOT SET'}', - ); - - if (url == null || url.isEmpty) { - appLogger.error('❌ Base URL not configured'); - return Result.error(BadRequestException('Base URL not configured')); + // String? url = prefs.getString('url'); + Response res = await makeApiCall(bearerToken ?? '', AppConfig.apiBaseUrl); + switch (res.statusCode) { + case 200: + case 201: + return fromJson(res.data); + case 401: + break; + case 403: + throw Exception('Forbidden: ${res.data['message']}'); + case 404: + throw Exception('Not found: ${res.data['message']}'); + case 423: + throw Exception('Locked: ${res.data['message']}'); + case 500: + throw Exception('Internal server error: ${res.data['message']}'); + default: + throw Exception('Error: ${res.data['message']}'); } - - Response res = await makeApiCall(bearerToken ?? '', url); - - // Handle successful responses - if (res.statusCode == 200 || res.statusCode == 201) { - appLogger.info('✅ Request successful: ${res.statusCode}'); - try { - final result = fromJson(res.data); - appLogger.info('✅ Response parsed successfully'); - return Result.ok(result); - } on Exception catch (e) { - appLogger.error('❌ Failed to parse response: $e'); - return Result.error( - FetchDataException( - 'Failed to parse response data', - res.statusCode, - e, - ), - ); - } - } - - // Handle specific HTTP error codes - return _handleHttpError(res); } on DioException catch (e) { - return _handleDioException(e); - } on Exception catch (e) { - appLogger.error('Unexpected error in makeRequest: $e'); - return Result.error( - FetchDataException('Unexpected error occurred', null, e), - ); - } - } + if (e.response?.statusCode == 401) { + // await api.refreshToken(); + String? bearerToken = prefs.getString('bearer'); + String? url = prefs.getString('url'); + Response res = await makeApiCall(bearerToken ?? '', url ?? ''); - /// Handle HTTP error responses - Result _handleHttpError(Response response) { - final statusCode = response.statusCode; - final message = _extractErrorMessage(response.data); - - switch (statusCode) { - case 400: - return Result.error( - BadRequestException(message, statusCode, response.data), - ); - case 401: - return Result.error( - AuthenticationException(message, statusCode, response.data), - ); - case 403: - return Result.error( - ForbiddenException(message, statusCode, response.data), - ); - case 404: - return Result.error( - NotFoundException(message, statusCode, response.data), - ); - case 423: - return Result.error( - ForbiddenException( - 'Resource is locked: $message', - statusCode, - response.data, - ), - ); - case 429: - return Result.error( - RateLimitException(message, statusCode, response.data), - ); - case 500: - case 502: - case 503: - case 504: - return Result.error( - ServerException(message, statusCode, response.data), - ); - default: - return Result.error( - FetchDataException(message, statusCode, response.data), - ); - } - } - - /// Handle Dio exceptions - Result _handleDioException(DioException e) { - switch (e.type) { - case DioExceptionType.connectionTimeout: - case DioExceptionType.sendTimeout: - case DioExceptionType.receiveTimeout: - return Result.error(TimeoutException('Request timed out', e)); - - case DioExceptionType.connectionError: - return Result.error( - NetworkConnectionException('Connection error occurred', e), - ); - - case DioExceptionType.badResponse: - if (e.response?.statusCode == 401) { - // Handle token refresh logic here if needed - // For now, return authentication error - return Result.error( - AuthenticationException( - 'Authentication failed', - e.response?.statusCode, - e, - ), - ); + if (res.statusCode == 200 || res.statusCode == 201) { + return fromJson(res.data); } - return Result.error( - FetchDataException( - 'Bad response from server', - e.response?.statusCode, - e, - ), - ); - case DioExceptionType.cancel: - return Result.error( - FetchDataException('Request was cancelled', null, e), - ); - - case DioExceptionType.unknown: - default: - if (e.error is SocketException) { - return Result.error( - NetworkConnectionException('No internet connection', e), - ); - } - return Result.error( - FetchDataException('Network error occurred', null, e), - ); - } - } - - /// Extract error message from response data - String _extractErrorMessage(data) { - if (data == null) { - return 'Unknown error'; + throw Exception(e.message ?? 'Error occurred'); + } + } catch (e) { + throw Exception(e.toString()); } - if (data is Map) { - return data['message'] ?? - data['error'] ?? - data['detail'] ?? - 'Unknown error'; - } - - if (data is String) { - return data; - } - - return 'Unknown error'; + throw Exception('Unhandled error occurred'); } } diff --git a/lib/data/repositories/auth_repository.dart b/lib/data/repositories/auth_repository.dart index 506f269..46b5e7b 100644 --- a/lib/data/repositories/auth_repository.dart +++ b/lib/data/repositories/auth_repository.dart @@ -1,6 +1,6 @@ -import '../../core/network/app_exceptions.dart'; +import 'package:tm_app/data/services/model/login_response/login_response_model.dart'; + import '../../core/utils/result.dart'; -import '../models/user_model.dart'; import '../services/auth_service.dart'; class AuthRepository { @@ -9,15 +9,10 @@ class AuthRepository { AuthRepository({required AuthService authService}) : _authService = authService; - Future> login(String email, String password) async { - try { - final response = await _authService.login(email, password); - final user = UserModel(token: response['token'], name: response['name']); - return Result.ok(user); - } on Exception { - return Result.error( - AuthenticationException('Email or password is not correct.'), - ); - } + Future> login({ + required String username, + required String password, + }) async { + return _authService.login(username: username, password: password); } } diff --git a/lib/data/services/auth_service.dart b/lib/data/services/auth_service.dart index d8257a9..038d99d 100644 --- a/lib/data/services/auth_service.dart +++ b/lib/data/services/auth_service.dart @@ -1,4 +1,13 @@ +// ignore_for_file: prefer_single_quotes + +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:tm_app/data/services/model/login_response/login_response_model.dart'; + import '../../core/network/network_manager.dart'; +import '../../core/utils/result.dart'; class AuthService { AuthService({required NetworkManager networkManager}) @@ -6,31 +15,35 @@ class AuthService { final NetworkManager _networkManager; - Future> login(String email, String password) async { - // شبیه‌سازی API Call - await Future.delayed(const Duration(seconds: 2)); + Future> login({ + required String username, + required String password, + }) async { + var headers = { + 'accept': 'application/json', + 'Content-Type': 'application/json', + }; + var data = jsonEncode({"password": "Nima.1998", "username": "nakhostin"}); + var dio = Dio( + BaseOptions(baseUrl: 'http://10.0.2.2:8081', headers: headers), + ); + var response = await dio.request( + '/admin/v1/profile/login', + options: Options(method: 'POST'), + data: data, + ); - if (email == 'a' && password == 'a') { - return {'token': 'xyz123', 'name': 'John Doe'}; + if (response.statusCode == 200) { + final prefs = await SharedPreferences.getInstance(); + final token = response.data['data']?['access_token']; + prefs.setString('token', token); + if (token != null) { + await prefs.setString('bearer', token); + } + print(json.encode(response.data)); } else { - throw Exception('Invalid credentials'); + print(response.statusMessage); } + return Result.ok(LoginResponseModel.fromJson(response.data)); } } - -// Future> getImages(String projectId) async { -// try { -// final result = await networkManager.makeRequest( -// '/api/v1/projects/$projectId/files', -// (json) { -// Logger().i(json); -// return OnlineGalleryResponse.fromJson(json); -// }, -// method: 'GET', -// ); - -// return Result.ok(result); -// } on DioException catch (e) { -// return Result.error(e); -// } -// } diff --git a/lib/data/services/model/login_data/login_data.dart b/lib/data/services/model/login_data/login_data.dart new file mode 100644 index 0000000..9e02f96 --- /dev/null +++ b/lib/data/services/model/login_data/login_data.dart @@ -0,0 +1,20 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:tm_app/data/services/model/user/user.dart'; + +part 'login_data.freezed.dart'; +part 'login_data.g.dart'; + +@freezed +abstract class LoginData with _$LoginData { + const factory LoginData({ + required User user, + @JsonKey(name: 'access_token') required String accessToken, + @JsonKey(name: 'refresh_token') required String refreshToken, + @JsonKey(name: 'expires_at') required int expiresAt, + }) = _LoginData; + + factory LoginData.fromJson(Map json) => + _$LoginDataFromJson(json); +} diff --git a/lib/data/services/model/login_data/login_data.freezed.dart b/lib/data/services/model/login_data/login_data.freezed.dart new file mode 100644 index 0000000..f5e6234 --- /dev/null +++ b/lib/data/services/model/login_data/login_data.freezed.dart @@ -0,0 +1,304 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// 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 'login_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$LoginData { + + User get user;@JsonKey(name: 'access_token') String get accessToken;@JsonKey(name: 'refresh_token') String get refreshToken;@JsonKey(name: 'expires_at') int get expiresAt; +/// Create a copy of LoginData +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LoginDataCopyWith get copyWith => _$LoginDataCopyWithImpl(this as LoginData, _$identity); + + /// Serializes this LoginData to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginData&&(identical(other.user, user) || other.user == user)&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken)&&(identical(other.expiresAt, expiresAt) || other.expiresAt == expiresAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,user,accessToken,refreshToken,expiresAt); + +@override +String toString() { + return 'LoginData(user: $user, accessToken: $accessToken, refreshToken: $refreshToken, expiresAt: $expiresAt)'; +} + + +} + +/// @nodoc +abstract mixin class $LoginDataCopyWith<$Res> { + factory $LoginDataCopyWith(LoginData value, $Res Function(LoginData) _then) = _$LoginDataCopyWithImpl; +@useResult +$Res call({ + User user,@JsonKey(name: 'access_token') String accessToken,@JsonKey(name: 'refresh_token') String refreshToken,@JsonKey(name: 'expires_at') int expiresAt +}); + + +$UserCopyWith<$Res> get user; + +} +/// @nodoc +class _$LoginDataCopyWithImpl<$Res> + implements $LoginDataCopyWith<$Res> { + _$LoginDataCopyWithImpl(this._self, this._then); + + final LoginData _self; + final $Res Function(LoginData) _then; + +/// Create a copy of LoginData +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? user = null,Object? accessToken = null,Object? refreshToken = null,Object? expiresAt = null,}) { + return _then(_self.copyWith( +user: null == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as User,accessToken: null == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable +as String,refreshToken: null == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable +as String,expiresAt: null == expiresAt ? _self.expiresAt : expiresAt // ignore: cast_nullable_to_non_nullable +as int, + )); +} +/// Create a copy of LoginData +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserCopyWith<$Res> get user { + + return $UserCopyWith<$Res>(_self.user, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [LoginData]. +extension LoginDataPatterns on LoginData { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _LoginData value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LoginData() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _LoginData value) $default,){ +final _that = this; +switch (_that) { +case _LoginData(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _LoginData value)? $default,){ +final _that = this; +switch (_that) { +case _LoginData() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( User user, @JsonKey(name: 'access_token') String accessToken, @JsonKey(name: 'refresh_token') String refreshToken, @JsonKey(name: 'expires_at') int expiresAt)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LoginData() when $default != null: +return $default(_that.user,_that.accessToken,_that.refreshToken,_that.expiresAt);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( User user, @JsonKey(name: 'access_token') String accessToken, @JsonKey(name: 'refresh_token') String refreshToken, @JsonKey(name: 'expires_at') int expiresAt) $default,) {final _that = this; +switch (_that) { +case _LoginData(): +return $default(_that.user,_that.accessToken,_that.refreshToken,_that.expiresAt);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( User user, @JsonKey(name: 'access_token') String accessToken, @JsonKey(name: 'refresh_token') String refreshToken, @JsonKey(name: 'expires_at') int expiresAt)? $default,) {final _that = this; +switch (_that) { +case _LoginData() when $default != null: +return $default(_that.user,_that.accessToken,_that.refreshToken,_that.expiresAt);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _LoginData implements LoginData { + const _LoginData({required this.user, @JsonKey(name: 'access_token') required this.accessToken, @JsonKey(name: 'refresh_token') required this.refreshToken, @JsonKey(name: 'expires_at') required this.expiresAt}); + factory _LoginData.fromJson(Map json) => _$LoginDataFromJson(json); + +@override final User user; +@override@JsonKey(name: 'access_token') final String accessToken; +@override@JsonKey(name: 'refresh_token') final String refreshToken; +@override@JsonKey(name: 'expires_at') final int expiresAt; + +/// Create a copy of LoginData +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoginDataCopyWith<_LoginData> get copyWith => __$LoginDataCopyWithImpl<_LoginData>(this, _$identity); + +@override +Map toJson() { + return _$LoginDataToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoginData&&(identical(other.user, user) || other.user == user)&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken)&&(identical(other.expiresAt, expiresAt) || other.expiresAt == expiresAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,user,accessToken,refreshToken,expiresAt); + +@override +String toString() { + return 'LoginData(user: $user, accessToken: $accessToken, refreshToken: $refreshToken, expiresAt: $expiresAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoginDataCopyWith<$Res> implements $LoginDataCopyWith<$Res> { + factory _$LoginDataCopyWith(_LoginData value, $Res Function(_LoginData) _then) = __$LoginDataCopyWithImpl; +@override @useResult +$Res call({ + User user,@JsonKey(name: 'access_token') String accessToken,@JsonKey(name: 'refresh_token') String refreshToken,@JsonKey(name: 'expires_at') int expiresAt +}); + + +@override $UserCopyWith<$Res> get user; + +} +/// @nodoc +class __$LoginDataCopyWithImpl<$Res> + implements _$LoginDataCopyWith<$Res> { + __$LoginDataCopyWithImpl(this._self, this._then); + + final _LoginData _self; + final $Res Function(_LoginData) _then; + +/// Create a copy of LoginData +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? user = null,Object? accessToken = null,Object? refreshToken = null,Object? expiresAt = null,}) { + return _then(_LoginData( +user: null == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as User,accessToken: null == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable +as String,refreshToken: null == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable +as String,expiresAt: null == expiresAt ? _self.expiresAt : expiresAt // ignore: cast_nullable_to_non_nullable +as int, + )); +} + +/// Create a copy of LoginData +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserCopyWith<$Res> get user { + + return $UserCopyWith<$Res>(_self.user, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + +// dart format on diff --git a/lib/data/services/model/login_data/login_data.g.dart b/lib/data/services/model/login_data/login_data.g.dart new file mode 100644 index 0000000..7fea684 --- /dev/null +++ b/lib/data/services/model/login_data/login_data.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_data.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_LoginData _$LoginDataFromJson(Map json) => _LoginData( + user: User.fromJson(json['user'] as Map), + accessToken: json['access_token'] as String, + refreshToken: json['refresh_token'] as String, + expiresAt: (json['expires_at'] as num).toInt(), +); + +Map _$LoginDataToJson(_LoginData instance) => + { + 'user': instance.user, + 'access_token': instance.accessToken, + 'refresh_token': instance.refreshToken, + 'expires_at': instance.expiresAt, + }; diff --git a/lib/data/services/model/login_response/login_response_model.dart b/lib/data/services/model/login_response/login_response_model.dart new file mode 100644 index 0000000..00346e0 --- /dev/null +++ b/lib/data/services/model/login_response/login_response_model.dart @@ -0,0 +1,18 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../login_data/login_data.dart'; + +part 'login_response_model.freezed.dart'; +part 'login_response_model.g.dart'; + +@freezed +abstract class LoginResponseModel with _$LoginResponseModel { + const factory LoginResponseModel({ + required bool success, + required String message, + required LoginData data, + }) = _LoginResponseModel; + + factory LoginResponseModel.fromJson(Map json) => + _$LoginResponseModelFromJson(json); +} diff --git a/lib/data/services/model/login_response/login_response_model.freezed.dart b/lib/data/services/model/login_response/login_response_model.freezed.dart new file mode 100644 index 0000000..f8f1e2c --- /dev/null +++ b/lib/data/services/model/login_response/login_response_model.freezed.dart @@ -0,0 +1,301 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// 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 'login_response_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$LoginResponseModel { + + bool get success; String get message; LoginData get data; +/// Create a copy of LoginResponseModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LoginResponseModelCopyWith get copyWith => _$LoginResponseModelCopyWithImpl(this as LoginResponseModel, _$identity); + + /// Serializes this LoginResponseModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginResponseModel&&(identical(other.success, success) || other.success == success)&&(identical(other.message, message) || other.message == message)&&(identical(other.data, data) || other.data == data)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,success,message,data); + +@override +String toString() { + return 'LoginResponseModel(success: $success, message: $message, data: $data)'; +} + + +} + +/// @nodoc +abstract mixin class $LoginResponseModelCopyWith<$Res> { + factory $LoginResponseModelCopyWith(LoginResponseModel value, $Res Function(LoginResponseModel) _then) = _$LoginResponseModelCopyWithImpl; +@useResult +$Res call({ + bool success, String message, LoginData data +}); + + +$LoginDataCopyWith<$Res> get data; + +} +/// @nodoc +class _$LoginResponseModelCopyWithImpl<$Res> + implements $LoginResponseModelCopyWith<$Res> { + _$LoginResponseModelCopyWithImpl(this._self, this._then); + + final LoginResponseModel _self; + final $Res Function(LoginResponseModel) _then; + +/// Create a copy of LoginResponseModel +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? success = null,Object? message = null,Object? data = null,}) { + return _then(_self.copyWith( +success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String,data: null == data ? _self.data : data // ignore: cast_nullable_to_non_nullable +as LoginData, + )); +} +/// Create a copy of LoginResponseModel +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$LoginDataCopyWith<$Res> get data { + + return $LoginDataCopyWith<$Res>(_self.data, (value) { + return _then(_self.copyWith(data: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [LoginResponseModel]. +extension LoginResponseModelPatterns on LoginResponseModel { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _LoginResponseModel value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LoginResponseModel() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _LoginResponseModel value) $default,){ +final _that = this; +switch (_that) { +case _LoginResponseModel(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _LoginResponseModel value)? $default,){ +final _that = this; +switch (_that) { +case _LoginResponseModel() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( bool success, String message, LoginData data)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LoginResponseModel() when $default != null: +return $default(_that.success,_that.message,_that.data);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( bool success, String message, LoginData data) $default,) {final _that = this; +switch (_that) { +case _LoginResponseModel(): +return $default(_that.success,_that.message,_that.data);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool success, String message, LoginData data)? $default,) {final _that = this; +switch (_that) { +case _LoginResponseModel() when $default != null: +return $default(_that.success,_that.message,_that.data);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _LoginResponseModel implements LoginResponseModel { + const _LoginResponseModel({required this.success, required this.message, required this.data}); + factory _LoginResponseModel.fromJson(Map json) => _$LoginResponseModelFromJson(json); + +@override final bool success; +@override final String message; +@override final LoginData data; + +/// Create a copy of LoginResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LoginResponseModelCopyWith<_LoginResponseModel> get copyWith => __$LoginResponseModelCopyWithImpl<_LoginResponseModel>(this, _$identity); + +@override +Map toJson() { + return _$LoginResponseModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoginResponseModel&&(identical(other.success, success) || other.success == success)&&(identical(other.message, message) || other.message == message)&&(identical(other.data, data) || other.data == data)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,success,message,data); + +@override +String toString() { + return 'LoginResponseModel(success: $success, message: $message, data: $data)'; +} + + +} + +/// @nodoc +abstract mixin class _$LoginResponseModelCopyWith<$Res> implements $LoginResponseModelCopyWith<$Res> { + factory _$LoginResponseModelCopyWith(_LoginResponseModel value, $Res Function(_LoginResponseModel) _then) = __$LoginResponseModelCopyWithImpl; +@override @useResult +$Res call({ + bool success, String message, LoginData data +}); + + +@override $LoginDataCopyWith<$Res> get data; + +} +/// @nodoc +class __$LoginResponseModelCopyWithImpl<$Res> + implements _$LoginResponseModelCopyWith<$Res> { + __$LoginResponseModelCopyWithImpl(this._self, this._then); + + final _LoginResponseModel _self; + final $Res Function(_LoginResponseModel) _then; + +/// Create a copy of LoginResponseModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? success = null,Object? message = null,Object? data = null,}) { + return _then(_LoginResponseModel( +success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String,data: null == data ? _self.data : data // ignore: cast_nullable_to_non_nullable +as LoginData, + )); +} + +/// Create a copy of LoginResponseModel +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$LoginDataCopyWith<$Res> get data { + + return $LoginDataCopyWith<$Res>(_self.data, (value) { + return _then(_self.copyWith(data: value)); + }); +} +} + +// dart format on diff --git a/lib/data/services/model/login_response/login_response_model.g.dart b/lib/data/services/model/login_response/login_response_model.g.dart new file mode 100644 index 0000000..b268e47 --- /dev/null +++ b/lib/data/services/model/login_response/login_response_model.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_response_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_LoginResponseModel _$LoginResponseModelFromJson(Map json) => + _LoginResponseModel( + success: json['success'] as bool, + message: json['message'] as String, + data: LoginData.fromJson(json['data'] as Map), + ); + +Map _$LoginResponseModelToJson(_LoginResponseModel instance) => + { + 'success': instance.success, + 'message': instance.message, + 'data': instance.data, + }; diff --git a/lib/data/services/model/user/user.dart b/lib/data/services/model/user/user.dart new file mode 100644 index 0000000..9105c09 --- /dev/null +++ b/lib/data/services/model/user/user.dart @@ -0,0 +1,28 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'user.freezed.dart'; +part 'user.g.dart'; + +@freezed +abstract class User with _$User { + const factory User({ + required String? id, + @JsonKey(name: 'full_name') required String? fullName, + required String? username, + required String? email, + required String? role, + required String? status, + required String? department, + required String? position, + required String? phone, + @JsonKey(name: 'profile_image') required String? profileImage, + @JsonKey(name: 'is_verified') required bool? isVerified, + @JsonKey(name: 'last_login_at') required int? lastLoginAt, + @JsonKey(name: 'created_at') required int? createdAt, + @JsonKey(name: 'updated_at') required int? updatedAt, + }) = _User; + + factory User.fromJson(Map json) => _$UserFromJson(json); +} diff --git a/lib/data/services/model/user/user.freezed.dart b/lib/data/services/model/user/user.freezed.dart new file mode 100644 index 0000000..011a4e5 --- /dev/null +++ b/lib/data/services/model/user/user.freezed.dart @@ -0,0 +1,316 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// 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 'user.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$User { + + String? get id;@JsonKey(name: 'full_name') String? get fullName; String? get username; String? get email; String? get role; String? get status; String? get department; String? get position; String? get phone;@JsonKey(name: 'profile_image') String? get profileImage;@JsonKey(name: 'is_verified') bool? get isVerified;@JsonKey(name: 'last_login_at') int? get lastLoginAt;@JsonKey(name: 'created_at') int? get createdAt;@JsonKey(name: 'updated_at') int? get updatedAt; +/// Create a copy of User +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$UserCopyWith get copyWith => _$UserCopyWithImpl(this as User, _$identity); + + /// Serializes this User to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is User&&(identical(other.id, id) || other.id == id)&&(identical(other.fullName, fullName) || other.fullName == fullName)&&(identical(other.username, username) || other.username == username)&&(identical(other.email, email) || other.email == email)&&(identical(other.role, role) || other.role == role)&&(identical(other.status, status) || other.status == status)&&(identical(other.department, department) || other.department == department)&&(identical(other.position, position) || other.position == position)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.profileImage, profileImage) || other.profileImage == profileImage)&&(identical(other.isVerified, isVerified) || other.isVerified == isVerified)&&(identical(other.lastLoginAt, lastLoginAt) || other.lastLoginAt == lastLoginAt)&&(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,fullName,username,email,role,status,department,position,phone,profileImage,isVerified,lastLoginAt,createdAt,updatedAt); + +@override +String toString() { + return 'User(id: $id, fullName: $fullName, username: $username, email: $email, role: $role, status: $status, department: $department, position: $position, phone: $phone, profileImage: $profileImage, isVerified: $isVerified, lastLoginAt: $lastLoginAt, createdAt: $createdAt, updatedAt: $updatedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $UserCopyWith<$Res> { + factory $UserCopyWith(User value, $Res Function(User) _then) = _$UserCopyWithImpl; +@useResult +$Res call({ + String? id,@JsonKey(name: 'full_name') String? fullName, String? username, String? email, String? role, String? status, String? department, String? position, String? phone,@JsonKey(name: 'profile_image') String? profileImage,@JsonKey(name: 'is_verified') bool? isVerified,@JsonKey(name: 'last_login_at') int? lastLoginAt,@JsonKey(name: 'created_at') int? createdAt,@JsonKey(name: 'updated_at') int? updatedAt +}); + + + + +} +/// @nodoc +class _$UserCopyWithImpl<$Res> + implements $UserCopyWith<$Res> { + _$UserCopyWithImpl(this._self, this._then); + + final User _self; + final $Res Function(User) _then; + +/// Create a copy of User +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? fullName = freezed,Object? username = freezed,Object? email = freezed,Object? role = freezed,Object? status = freezed,Object? department = freezed,Object? position = freezed,Object? phone = freezed,Object? profileImage = freezed,Object? isVerified = freezed,Object? lastLoginAt = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,}) { + return _then(_self.copyWith( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String?,fullName: freezed == fullName ? _self.fullName : fullName // ignore: cast_nullable_to_non_nullable +as String?,username: freezed == username ? _self.username : username // ignore: cast_nullable_to_non_nullable +as String?,email: freezed == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String?,role: freezed == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as String?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as String?,department: freezed == department ? _self.department : department // ignore: cast_nullable_to_non_nullable +as String?,position: freezed == position ? _self.position : position // ignore: cast_nullable_to_non_nullable +as String?,phone: freezed == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String?,profileImage: freezed == profileImage ? _self.profileImage : profileImage // ignore: cast_nullable_to_non_nullable +as String?,isVerified: freezed == isVerified ? _self.isVerified : isVerified // ignore: cast_nullable_to_non_nullable +as bool?,lastLoginAt: freezed == lastLoginAt ? _self.lastLoginAt : lastLoginAt // ignore: cast_nullable_to_non_nullable +as int?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as int?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [User]. +extension UserPatterns on User { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _User value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _User() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _User value) $default,){ +final _that = this; +switch (_that) { +case _User(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _User value)? $default,){ +final _that = this; +switch (_that) { +case _User() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String? id, @JsonKey(name: 'full_name') String? fullName, String? username, String? email, String? role, String? status, String? department, String? position, String? phone, @JsonKey(name: 'profile_image') String? profileImage, @JsonKey(name: 'is_verified') bool? isVerified, @JsonKey(name: 'last_login_at') int? lastLoginAt, @JsonKey(name: 'created_at') int? createdAt, @JsonKey(name: 'updated_at') int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _User() when $default != null: +return $default(_that.id,_that.fullName,_that.username,_that.email,_that.role,_that.status,_that.department,_that.position,_that.phone,_that.profileImage,_that.isVerified,_that.lastLoginAt,_that.createdAt,_that.updatedAt);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String? id, @JsonKey(name: 'full_name') String? fullName, String? username, String? email, String? role, String? status, String? department, String? position, String? phone, @JsonKey(name: 'profile_image') String? profileImage, @JsonKey(name: 'is_verified') bool? isVerified, @JsonKey(name: 'last_login_at') int? lastLoginAt, @JsonKey(name: 'created_at') int? createdAt, @JsonKey(name: 'updated_at') int? updatedAt) $default,) {final _that = this; +switch (_that) { +case _User(): +return $default(_that.id,_that.fullName,_that.username,_that.email,_that.role,_that.status,_that.department,_that.position,_that.phone,_that.profileImage,_that.isVerified,_that.lastLoginAt,_that.createdAt,_that.updatedAt);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? id, @JsonKey(name: 'full_name') String? fullName, String? username, String? email, String? role, String? status, String? department, String? position, String? phone, @JsonKey(name: 'profile_image') String? profileImage, @JsonKey(name: 'is_verified') bool? isVerified, @JsonKey(name: 'last_login_at') int? lastLoginAt, @JsonKey(name: 'created_at') int? createdAt, @JsonKey(name: 'updated_at') int? updatedAt)? $default,) {final _that = this; +switch (_that) { +case _User() when $default != null: +return $default(_that.id,_that.fullName,_that.username,_that.email,_that.role,_that.status,_that.department,_that.position,_that.phone,_that.profileImage,_that.isVerified,_that.lastLoginAt,_that.createdAt,_that.updatedAt);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _User implements User { + const _User({required this.id, @JsonKey(name: 'full_name') required this.fullName, required this.username, required this.email, required this.role, required this.status, required this.department, required this.position, required this.phone, @JsonKey(name: 'profile_image') required this.profileImage, @JsonKey(name: 'is_verified') required this.isVerified, @JsonKey(name: 'last_login_at') required this.lastLoginAt, @JsonKey(name: 'created_at') required this.createdAt, @JsonKey(name: 'updated_at') required this.updatedAt}); + factory _User.fromJson(Map json) => _$UserFromJson(json); + +@override final String? id; +@override@JsonKey(name: 'full_name') final String? fullName; +@override final String? username; +@override final String? email; +@override final String? role; +@override final String? status; +@override final String? department; +@override final String? position; +@override final String? phone; +@override@JsonKey(name: 'profile_image') final String? profileImage; +@override@JsonKey(name: 'is_verified') final bool? isVerified; +@override@JsonKey(name: 'last_login_at') final int? lastLoginAt; +@override@JsonKey(name: 'created_at') final int? createdAt; +@override@JsonKey(name: 'updated_at') final int? updatedAt; + +/// Create a copy of User +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UserCopyWith<_User> get copyWith => __$UserCopyWithImpl<_User>(this, _$identity); + +@override +Map toJson() { + return _$UserToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _User&&(identical(other.id, id) || other.id == id)&&(identical(other.fullName, fullName) || other.fullName == fullName)&&(identical(other.username, username) || other.username == username)&&(identical(other.email, email) || other.email == email)&&(identical(other.role, role) || other.role == role)&&(identical(other.status, status) || other.status == status)&&(identical(other.department, department) || other.department == department)&&(identical(other.position, position) || other.position == position)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.profileImage, profileImage) || other.profileImage == profileImage)&&(identical(other.isVerified, isVerified) || other.isVerified == isVerified)&&(identical(other.lastLoginAt, lastLoginAt) || other.lastLoginAt == lastLoginAt)&&(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,fullName,username,email,role,status,department,position,phone,profileImage,isVerified,lastLoginAt,createdAt,updatedAt); + +@override +String toString() { + return 'User(id: $id, fullName: $fullName, username: $username, email: $email, role: $role, status: $status, department: $department, position: $position, phone: $phone, profileImage: $profileImage, isVerified: $isVerified, lastLoginAt: $lastLoginAt, createdAt: $createdAt, updatedAt: $updatedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$UserCopyWith<$Res> implements $UserCopyWith<$Res> { + factory _$UserCopyWith(_User value, $Res Function(_User) _then) = __$UserCopyWithImpl; +@override @useResult +$Res call({ + String? id,@JsonKey(name: 'full_name') String? fullName, String? username, String? email, String? role, String? status, String? department, String? position, String? phone,@JsonKey(name: 'profile_image') String? profileImage,@JsonKey(name: 'is_verified') bool? isVerified,@JsonKey(name: 'last_login_at') int? lastLoginAt,@JsonKey(name: 'created_at') int? createdAt,@JsonKey(name: 'updated_at') int? updatedAt +}); + + + + +} +/// @nodoc +class __$UserCopyWithImpl<$Res> + implements _$UserCopyWith<$Res> { + __$UserCopyWithImpl(this._self, this._then); + + final _User _self; + final $Res Function(_User) _then; + +/// Create a copy of User +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? fullName = freezed,Object? username = freezed,Object? email = freezed,Object? role = freezed,Object? status = freezed,Object? department = freezed,Object? position = freezed,Object? phone = freezed,Object? profileImage = freezed,Object? isVerified = freezed,Object? lastLoginAt = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,}) { + return _then(_User( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String?,fullName: freezed == fullName ? _self.fullName : fullName // ignore: cast_nullable_to_non_nullable +as String?,username: freezed == username ? _self.username : username // ignore: cast_nullable_to_non_nullable +as String?,email: freezed == email ? _self.email : email // ignore: cast_nullable_to_non_nullable +as String?,role: freezed == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as String?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable +as String?,department: freezed == department ? _self.department : department // ignore: cast_nullable_to_non_nullable +as String?,position: freezed == position ? _self.position : position // ignore: cast_nullable_to_non_nullable +as String?,phone: freezed == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable +as String?,profileImage: freezed == profileImage ? _self.profileImage : profileImage // ignore: cast_nullable_to_non_nullable +as String?,isVerified: freezed == isVerified ? _self.isVerified : isVerified // ignore: cast_nullable_to_non_nullable +as bool?,lastLoginAt: freezed == lastLoginAt ? _self.lastLoginAt : lastLoginAt // ignore: cast_nullable_to_non_nullable +as int?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as int?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + + +} + +// dart format on diff --git a/lib/data/services/model/user/user.g.dart b/lib/data/services/model/user/user.g.dart new file mode 100644 index 0000000..d0b7610 --- /dev/null +++ b/lib/data/services/model/user/user.g.dart @@ -0,0 +1,41 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_User _$UserFromJson(Map json) => _User( + id: json['id'] as String?, + fullName: json['full_name'] as String?, + username: json['username'] as String?, + email: json['email'] as String?, + role: json['role'] as String?, + status: json['status'] as String?, + department: json['department'] as String?, + position: json['position'] as String?, + phone: json['phone'] as String?, + profileImage: json['profile_image'] as String?, + isVerified: json['is_verified'] as bool?, + lastLoginAt: (json['last_login_at'] as num?)?.toInt(), + createdAt: (json['created_at'] as num?)?.toInt(), + updatedAt: (json['updated_at'] as num?)?.toInt(), +); + +Map _$UserToJson(_User instance) => { + 'id': instance.id, + 'full_name': instance.fullName, + 'username': instance.username, + 'email': instance.email, + 'role': instance.role, + 'status': instance.status, + 'department': instance.department, + 'position': instance.position, + 'phone': instance.phone, + 'profile_image': instance.profileImage, + 'is_verified': instance.isVerified, + 'last_login_at': instance.lastLoginAt, + 'created_at': instance.createdAt, + 'updated_at': instance.updatedAt, +}; diff --git a/lib/view_models/auth_view_model.dart b/lib/view_models/auth_view_model.dart index 47e08af..543c415 100644 --- a/lib/view_models/auth_view_model.dart +++ b/lib/view_models/auth_view_model.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import '../core/utils/result.dart'; -import '../data/models/user_model.dart'; import '../data/repositories/auth_repository.dart'; +import '../data/services/model/login_response/login_response_model.dart'; +import '../data/services/model/user/user.dart'; class AuthViewModel with ChangeNotifier { final AuthRepository _authRepository; @@ -28,11 +29,11 @@ class AuthViewModel with ChangeNotifier { // Auth state bool _isLoading = false; String? _errorMessage; - UserModel? _loggedInUser; + User? _loggedInUser; bool get isLoading => _isLoading; String? get errorMessage => _errorMessage; - UserModel? get loggedInUser => _loggedInUser; + User? get loggedInUser => _loggedInUser; void togglePasswordVisibility() { _obscurePassword = !_obscurePassword; @@ -49,15 +50,16 @@ class AuthViewModel with ChangeNotifier { notifyListeners(); final result = await _authRepository.login( - usernameController.text.trim(), - passwordController.text.trim(), + username: usernameController.text.trim(), + password: passwordController.text.trim(), ); switch (result) { - case Ok(): - _loggedInUser = result.value; + case Ok(): + _loggedInUser = result.value.data.user; + break; - case Error(): + case Error(): _errorMessage = result.error.toString(); break; } diff --git a/pubspec.lock b/pubspec.lock index 24b3493..c9d7851 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.0" boolean_selector: dependency: transitive description: @@ -221,10 +221,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" ffi: dependency: transitive description: @@ -361,7 +361,7 @@ packages: source: hosted version: "2.0.0" http: - dependency: transitive + dependency: "direct main" description: name: http sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 @@ -436,10 +436,10 @@ packages: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: @@ -841,10 +841,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "15.0.0" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index cc02d09..42b28db 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ dependencies: dio: ^5.8.0+1 shared_preferences: ^2.5.3 json_annotation: ^4.8.1 + http: ^1.5.0 dev_dependencies: flutter_test: