diff --git a/lib/core/config/dependencies.dart b/lib/core/config/dependencies.dart index 4aff56b..78d84d3 100644 --- a/lib/core/config/dependencies.dart +++ b/lib/core/config/dependencies.dart @@ -14,10 +14,13 @@ import 'package:tm_app/view_models/tenders_view_model.dart'; import 'package:tm_app/view_models/your_tenders_view_model.dart'; import '../../data/repositories/auth_repository.dart'; +import '../../data/repositories/profile_repository.dart'; import '../../data/services/auth_service.dart'; +import '../../data/services/profile_service.dart'; import '../../data/services/tenders_service.dart'; import '../../view_models/auth_view_model.dart'; import '../../view_models/home_view_model.dart'; +import '../../view_models/profile_view_model.dart'; List get providersRemote { return [...cores, ...apiClients, ...repositories, ...viewModels, ...others]; @@ -42,6 +45,9 @@ List get apiClients { Provider( create: (context) => TendersService(networkManager: context.read()), ), + Provider( + create: (context) => ProfileService(networkManager: context.read()), + ), ]; } @@ -62,6 +68,9 @@ List get repositories { Provider( create: (context) => TendersRepository(tendersService: context.read()), ), + Provider( + create: (context) => ProfileRepository(profileService: context.read()), + ), ]; } @@ -87,6 +96,13 @@ List get viewModels { (context) => YourTendersViewModel(yourTendersRepository: context.read()), ), + ChangeNotifierProvider( + create: + (context) => ProfileViewModel( + profileRepository: context.read(), + authRepository: context.read(), + ), + ), ]; } diff --git a/lib/data/repositories/auth_repository.dart b/lib/data/repositories/auth_repository.dart index 46b5e7b..1b3b8ef 100644 --- a/lib/data/repositories/auth_repository.dart +++ b/lib/data/repositories/auth_repository.dart @@ -1,4 +1,5 @@ import 'package:tm_app/data/services/model/login_response/login_response_model.dart'; +import 'package:tm_app/data/services/model/logout_response/logout_response.dart'; import '../../core/utils/result.dart'; import '../services/auth_service.dart'; @@ -15,4 +16,8 @@ class AuthRepository { }) async { return _authService.login(username: username, password: password); } + + Future> logout() async { + return _authService.logout(); + } } diff --git a/lib/data/repositories/profile_repository.dart b/lib/data/repositories/profile_repository.dart new file mode 100644 index 0000000..2540ce6 --- /dev/null +++ b/lib/data/repositories/profile_repository.dart @@ -0,0 +1,14 @@ +import 'package:tm_app/data/services/profile_service.dart'; + +import '../../core/utils/result.dart'; +import '../services/model/profile_response/profile_response.dart'; + +class ProfileRepository { + ProfileRepository({required ProfileService profileService}) + : _profileService = profileService; + final ProfileService _profileService; + + Future> getProfile() async { + return _profileService.getProfile(); + } +} diff --git a/lib/data/services/auth_service.dart b/lib/data/services/auth_service.dart index 2c008fc..d18a1fa 100644 --- a/lib/data/services/auth_service.dart +++ b/lib/data/services/auth_service.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tm_app/data/services/model/login_response/login_response_model.dart'; +import 'package:tm_app/data/services/model/logout_response/logout_response.dart'; import '../../core/network/network_manager.dart'; import '../../core/utils/result.dart'; @@ -34,4 +35,18 @@ class AuthService { } return result; } + + Future> logout() async { + final result = await _networkManager.makeRequest( + '/admin/v1/profile/logout', + method: 'DELETE', + (json) => LogoutResponse.fromJson(json), + ); + return result; + } + + Future localLogout() async { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('bearer'); + } } diff --git a/lib/data/services/model/logout_data/logout_error.dart b/lib/data/services/model/logout_data/logout_error.dart new file mode 100644 index 0000000..a4ab4fb --- /dev/null +++ b/lib/data/services/model/logout_data/logout_error.dart @@ -0,0 +1,15 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'logout_error.freezed.dart'; +part 'logout_error.g.dart'; + +@freezed +abstract class LogoutError with _$LogoutError { + const factory LogoutError({required String? message, required String? code}) = + _LogoutError; + + factory LogoutError.fromJson(Map json) => + _$LogoutErrorFromJson(json); +} diff --git a/lib/data/services/model/logout_data/logout_error.freezed.dart b/lib/data/services/model/logout_data/logout_error.freezed.dart new file mode 100644 index 0000000..3e4a504 --- /dev/null +++ b/lib/data/services/model/logout_data/logout_error.freezed.dart @@ -0,0 +1,280 @@ +// 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 'logout_error.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$LogoutError { + + String? get message; String? get code; +/// Create a copy of LogoutError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LogoutErrorCopyWith get copyWith => _$LogoutErrorCopyWithImpl(this as LogoutError, _$identity); + + /// Serializes this LogoutError to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LogoutError&&(identical(other.message, message) || other.message == message)&&(identical(other.code, code) || other.code == code)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,message,code); + +@override +String toString() { + return 'LogoutError(message: $message, code: $code)'; +} + + +} + +/// @nodoc +abstract mixin class $LogoutErrorCopyWith<$Res> { + factory $LogoutErrorCopyWith(LogoutError value, $Res Function(LogoutError) _then) = _$LogoutErrorCopyWithImpl; +@useResult +$Res call({ + String? message, String? code +}); + + + + +} +/// @nodoc +class _$LogoutErrorCopyWithImpl<$Res> + implements $LogoutErrorCopyWith<$Res> { + _$LogoutErrorCopyWithImpl(this._self, this._then); + + final LogoutError _self; + final $Res Function(LogoutError) _then; + +/// Create a copy of LogoutError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? message = freezed,Object? code = freezed,}) { + return _then(_self.copyWith( +message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,code: freezed == code ? _self.code : code // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [LogoutError]. +extension LogoutErrorPatterns on LogoutError { +/// 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( _LogoutError value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LogoutError() 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( _LogoutError value) $default,){ +final _that = this; +switch (_that) { +case _LogoutError(): +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( _LogoutError value)? $default,){ +final _that = this; +switch (_that) { +case _LogoutError() 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? message, String? code)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LogoutError() when $default != null: +return $default(_that.message,_that.code);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? message, String? code) $default,) {final _that = this; +switch (_that) { +case _LogoutError(): +return $default(_that.message,_that.code);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? message, String? code)? $default,) {final _that = this; +switch (_that) { +case _LogoutError() when $default != null: +return $default(_that.message,_that.code);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _LogoutError implements LogoutError { + const _LogoutError({required this.message, required this.code}); + factory _LogoutError.fromJson(Map json) => _$LogoutErrorFromJson(json); + +@override final String? message; +@override final String? code; + +/// Create a copy of LogoutError +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LogoutErrorCopyWith<_LogoutError> get copyWith => __$LogoutErrorCopyWithImpl<_LogoutError>(this, _$identity); + +@override +Map toJson() { + return _$LogoutErrorToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LogoutError&&(identical(other.message, message) || other.message == message)&&(identical(other.code, code) || other.code == code)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,message,code); + +@override +String toString() { + return 'LogoutError(message: $message, code: $code)'; +} + + +} + +/// @nodoc +abstract mixin class _$LogoutErrorCopyWith<$Res> implements $LogoutErrorCopyWith<$Res> { + factory _$LogoutErrorCopyWith(_LogoutError value, $Res Function(_LogoutError) _then) = __$LogoutErrorCopyWithImpl; +@override @useResult +$Res call({ + String? message, String? code +}); + + + + +} +/// @nodoc +class __$LogoutErrorCopyWithImpl<$Res> + implements _$LogoutErrorCopyWith<$Res> { + __$LogoutErrorCopyWithImpl(this._self, this._then); + + final _LogoutError _self; + final $Res Function(_LogoutError) _then; + +/// Create a copy of LogoutError +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? message = freezed,Object? code = freezed,}) { + return _then(_LogoutError( +message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,code: freezed == code ? _self.code : code // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +// dart format on diff --git a/lib/data/services/model/logout_data/logout_error.g.dart b/lib/data/services/model/logout_data/logout_error.g.dart new file mode 100644 index 0000000..cd568fc --- /dev/null +++ b/lib/data/services/model/logout_data/logout_error.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'logout_error.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_LogoutError _$LogoutErrorFromJson(Map json) => _LogoutError( + message: json['message'] as String?, + code: json['code'] as String?, +); + +Map _$LogoutErrorToJson(_LogoutError instance) => + {'message': instance.message, 'code': instance.code}; diff --git a/lib/data/services/model/logout_response/logout_response.dart b/lib/data/services/model/logout_response/logout_response.dart new file mode 100644 index 0000000..608dab1 --- /dev/null +++ b/lib/data/services/model/logout_response/logout_response.dart @@ -0,0 +1,20 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../logout_data/logout_error.dart'; + +part 'logout_response.freezed.dart'; +part 'logout_response.g.dart'; + +@freezed +abstract class LogoutResponse with _$LogoutResponse { + const factory LogoutResponse({ + required bool? success, + required String? message, + required LogoutError? error, + }) = _LogoutResponse; + + factory LogoutResponse.fromJson(Map json) => + _$LogoutResponseFromJson(json); +} diff --git a/lib/data/services/model/logout_response/logout_response.freezed.dart b/lib/data/services/model/logout_response/logout_response.freezed.dart new file mode 100644 index 0000000..90009d8 --- /dev/null +++ b/lib/data/services/model/logout_response/logout_response.freezed.dart @@ -0,0 +1,307 @@ +// 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 'logout_response.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$LogoutResponse { + + bool? get success; String? get message; LogoutError? get error; +/// Create a copy of LogoutResponse +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$LogoutResponseCopyWith get copyWith => _$LogoutResponseCopyWithImpl(this as LogoutResponse, _$identity); + + /// Serializes this LogoutResponse to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is LogoutResponse&&(identical(other.success, success) || other.success == success)&&(identical(other.message, message) || other.message == message)&&(identical(other.error, error) || other.error == error)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,success,message,error); + +@override +String toString() { + return 'LogoutResponse(success: $success, message: $message, error: $error)'; +} + + +} + +/// @nodoc +abstract mixin class $LogoutResponseCopyWith<$Res> { + factory $LogoutResponseCopyWith(LogoutResponse value, $Res Function(LogoutResponse) _then) = _$LogoutResponseCopyWithImpl; +@useResult +$Res call({ + bool? success, String? message, LogoutError? error +}); + + +$LogoutErrorCopyWith<$Res>? get error; + +} +/// @nodoc +class _$LogoutResponseCopyWithImpl<$Res> + implements $LogoutResponseCopyWith<$Res> { + _$LogoutResponseCopyWithImpl(this._self, this._then); + + final LogoutResponse _self; + final $Res Function(LogoutResponse) _then; + +/// Create a copy of LogoutResponse +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? success = freezed,Object? message = freezed,Object? error = freezed,}) { + return _then(_self.copyWith( +success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable +as LogoutError?, + )); +} +/// Create a copy of LogoutResponse +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$LogoutErrorCopyWith<$Res>? get error { + if (_self.error == null) { + return null; + } + + return $LogoutErrorCopyWith<$Res>(_self.error!, (value) { + return _then(_self.copyWith(error: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [LogoutResponse]. +extension LogoutResponsePatterns on LogoutResponse { +/// 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( _LogoutResponse value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _LogoutResponse() 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( _LogoutResponse value) $default,){ +final _that = this; +switch (_that) { +case _LogoutResponse(): +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( _LogoutResponse value)? $default,){ +final _that = this; +switch (_that) { +case _LogoutResponse() 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, LogoutError? error)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _LogoutResponse() when $default != null: +return $default(_that.success,_that.message,_that.error);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, LogoutError? error) $default,) {final _that = this; +switch (_that) { +case _LogoutResponse(): +return $default(_that.success,_that.message,_that.error);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, LogoutError? error)? $default,) {final _that = this; +switch (_that) { +case _LogoutResponse() when $default != null: +return $default(_that.success,_that.message,_that.error);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _LogoutResponse implements LogoutResponse { + const _LogoutResponse({required this.success, required this.message, required this.error}); + factory _LogoutResponse.fromJson(Map json) => _$LogoutResponseFromJson(json); + +@override final bool? success; +@override final String? message; +@override final LogoutError? error; + +/// Create a copy of LogoutResponse +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$LogoutResponseCopyWith<_LogoutResponse> get copyWith => __$LogoutResponseCopyWithImpl<_LogoutResponse>(this, _$identity); + +@override +Map toJson() { + return _$LogoutResponseToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _LogoutResponse&&(identical(other.success, success) || other.success == success)&&(identical(other.message, message) || other.message == message)&&(identical(other.error, error) || other.error == error)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,success,message,error); + +@override +String toString() { + return 'LogoutResponse(success: $success, message: $message, error: $error)'; +} + + +} + +/// @nodoc +abstract mixin class _$LogoutResponseCopyWith<$Res> implements $LogoutResponseCopyWith<$Res> { + factory _$LogoutResponseCopyWith(_LogoutResponse value, $Res Function(_LogoutResponse) _then) = __$LogoutResponseCopyWithImpl; +@override @useResult +$Res call({ + bool? success, String? message, LogoutError? error +}); + + +@override $LogoutErrorCopyWith<$Res>? get error; + +} +/// @nodoc +class __$LogoutResponseCopyWithImpl<$Res> + implements _$LogoutResponseCopyWith<$Res> { + __$LogoutResponseCopyWithImpl(this._self, this._then); + + final _LogoutResponse _self; + final $Res Function(_LogoutResponse) _then; + +/// Create a copy of LogoutResponse +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? success = freezed,Object? message = freezed,Object? error = freezed,}) { + return _then(_LogoutResponse( +success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable +as LogoutError?, + )); +} + +/// Create a copy of LogoutResponse +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$LogoutErrorCopyWith<$Res>? get error { + if (_self.error == null) { + return null; + } + + return $LogoutErrorCopyWith<$Res>(_self.error!, (value) { + return _then(_self.copyWith(error: value)); + }); +} +} + +// dart format on diff --git a/lib/data/services/model/logout_response/logout_response.g.dart b/lib/data/services/model/logout_response/logout_response.g.dart new file mode 100644 index 0000000..453edf7 --- /dev/null +++ b/lib/data/services/model/logout_response/logout_response.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'logout_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_LogoutResponse _$LogoutResponseFromJson(Map json) => + _LogoutResponse( + success: json['success'] as bool?, + message: json['message'] as String?, + error: + json['error'] == null + ? null + : LogoutError.fromJson(json['error'] as Map), + ); + +Map _$LogoutResponseToJson(_LogoutResponse instance) => + { + 'success': instance.success, + 'message': instance.message, + 'error': instance.error, + }; diff --git a/lib/data/services/model/profile_data/profile_data.dart b/lib/data/services/model/profile_data/profile_data.dart new file mode 100644 index 0000000..aa48665 --- /dev/null +++ b/lib/data/services/model/profile_data/profile_data.dart @@ -0,0 +1,29 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'profile_data.freezed.dart'; +part 'profile_data.g.dart'; + +@freezed +abstract class ProfileData with _$ProfileData { + const factory ProfileData({ + 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, + }) = _ProfileData; + + factory ProfileData.fromJson(Map json) => + _$ProfileDataFromJson(json); +} diff --git a/lib/data/services/model/profile_data/profile_data.freezed.dart b/lib/data/services/model/profile_data/profile_data.freezed.dart new file mode 100644 index 0000000..611d906 --- /dev/null +++ b/lib/data/services/model/profile_data/profile_data.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 'profile_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$ProfileData { + + 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 ProfileData +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ProfileDataCopyWith get copyWith => _$ProfileDataCopyWithImpl(this as ProfileData, _$identity); + + /// Serializes this ProfileData to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ProfileData&&(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 'ProfileData(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 $ProfileDataCopyWith<$Res> { + factory $ProfileDataCopyWith(ProfileData value, $Res Function(ProfileData) _then) = _$ProfileDataCopyWithImpl; +@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 _$ProfileDataCopyWithImpl<$Res> + implements $ProfileDataCopyWith<$Res> { + _$ProfileDataCopyWithImpl(this._self, this._then); + + final ProfileData _self; + final $Res Function(ProfileData) _then; + +/// Create a copy of ProfileData +/// 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 [ProfileData]. +extension ProfileDataPatterns on ProfileData { +/// 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( _ProfileData value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ProfileData() 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( _ProfileData value) $default,){ +final _that = this; +switch (_that) { +case _ProfileData(): +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( _ProfileData value)? $default,){ +final _that = this; +switch (_that) { +case _ProfileData() 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 _ProfileData() 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 _ProfileData(): +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 _ProfileData() 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 _ProfileData implements ProfileData { + const _ProfileData({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 _ProfileData.fromJson(Map json) => _$ProfileDataFromJson(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 ProfileData +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ProfileDataCopyWith<_ProfileData> get copyWith => __$ProfileDataCopyWithImpl<_ProfileData>(this, _$identity); + +@override +Map toJson() { + return _$ProfileDataToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProfileData&&(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 'ProfileData(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 _$ProfileDataCopyWith<$Res> implements $ProfileDataCopyWith<$Res> { + factory _$ProfileDataCopyWith(_ProfileData value, $Res Function(_ProfileData) _then) = __$ProfileDataCopyWithImpl; +@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 __$ProfileDataCopyWithImpl<$Res> + implements _$ProfileDataCopyWith<$Res> { + __$ProfileDataCopyWithImpl(this._self, this._then); + + final _ProfileData _self; + final $Res Function(_ProfileData) _then; + +/// Create a copy of ProfileData +/// 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(_ProfileData( +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/profile_data/profile_data.g.dart b/lib/data/services/model/profile_data/profile_data.g.dart new file mode 100644 index 0000000..2a69bda --- /dev/null +++ b/lib/data/services/model/profile_data/profile_data.g.dart @@ -0,0 +1,42 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'profile_data.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_ProfileData _$ProfileDataFromJson(Map json) => _ProfileData( + 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 _$ProfileDataToJson(_ProfileData 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/data/services/model/profile_response/profile_response.dart b/lib/data/services/model/profile_response/profile_response.dart new file mode 100644 index 0000000..243cbc2 --- /dev/null +++ b/lib/data/services/model/profile_response/profile_response.dart @@ -0,0 +1,20 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; + +import '../profile_data/profile_data.dart'; + +part 'profile_response.freezed.dart'; +part 'profile_response.g.dart'; + +@freezed +abstract class ProfileResponse with _$ProfileResponse { + const factory ProfileResponse({ + required String? message, + required bool? success, + required ProfileData? data, + }) = _ProfileResponse; + + factory ProfileResponse.fromJson(Map json) => + _$ProfileResponseFromJson(json); +} diff --git a/lib/data/services/model/profile_response/profile_response.freezed.dart b/lib/data/services/model/profile_response/profile_response.freezed.dart new file mode 100644 index 0000000..37f0b3f --- /dev/null +++ b/lib/data/services/model/profile_response/profile_response.freezed.dart @@ -0,0 +1,307 @@ +// 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 'profile_response.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$ProfileResponse { + + String? get message; bool? get success; ProfileData? get data; +/// Create a copy of ProfileResponse +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ProfileResponseCopyWith get copyWith => _$ProfileResponseCopyWithImpl(this as ProfileResponse, _$identity); + + /// Serializes this ProfileResponse to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ProfileResponse&&(identical(other.message, message) || other.message == message)&&(identical(other.success, success) || other.success == success)&&(identical(other.data, data) || other.data == data)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,message,success,data); + +@override +String toString() { + return 'ProfileResponse(message: $message, success: $success, data: $data)'; +} + + +} + +/// @nodoc +abstract mixin class $ProfileResponseCopyWith<$Res> { + factory $ProfileResponseCopyWith(ProfileResponse value, $Res Function(ProfileResponse) _then) = _$ProfileResponseCopyWithImpl; +@useResult +$Res call({ + String? message, bool? success, ProfileData? data +}); + + +$ProfileDataCopyWith<$Res>? get data; + +} +/// @nodoc +class _$ProfileResponseCopyWithImpl<$Res> + implements $ProfileResponseCopyWith<$Res> { + _$ProfileResponseCopyWithImpl(this._self, this._then); + + final ProfileResponse _self; + final $Res Function(ProfileResponse) _then; + +/// Create a copy of ProfileResponse +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? message = freezed,Object? success = freezed,Object? data = freezed,}) { + return _then(_self.copyWith( +message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool?,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable +as ProfileData?, + )); +} +/// Create a copy of ProfileResponse +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$ProfileDataCopyWith<$Res>? get data { + if (_self.data == null) { + return null; + } + + return $ProfileDataCopyWith<$Res>(_self.data!, (value) { + return _then(_self.copyWith(data: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [ProfileResponse]. +extension ProfileResponsePatterns on ProfileResponse { +/// 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( _ProfileResponse value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ProfileResponse() 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( _ProfileResponse value) $default,){ +final _that = this; +switch (_that) { +case _ProfileResponse(): +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( _ProfileResponse value)? $default,){ +final _that = this; +switch (_that) { +case _ProfileResponse() 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? message, bool? success, ProfileData? data)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ProfileResponse() when $default != null: +return $default(_that.message,_that.success,_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( String? message, bool? success, ProfileData? data) $default,) {final _that = this; +switch (_that) { +case _ProfileResponse(): +return $default(_that.message,_that.success,_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( String? message, bool? success, ProfileData? data)? $default,) {final _that = this; +switch (_that) { +case _ProfileResponse() when $default != null: +return $default(_that.message,_that.success,_that.data);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _ProfileResponse implements ProfileResponse { + const _ProfileResponse({required this.message, required this.success, required this.data}); + factory _ProfileResponse.fromJson(Map json) => _$ProfileResponseFromJson(json); + +@override final String? message; +@override final bool? success; +@override final ProfileData? data; + +/// Create a copy of ProfileResponse +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ProfileResponseCopyWith<_ProfileResponse> get copyWith => __$ProfileResponseCopyWithImpl<_ProfileResponse>(this, _$identity); + +@override +Map toJson() { + return _$ProfileResponseToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProfileResponse&&(identical(other.message, message) || other.message == message)&&(identical(other.success, success) || other.success == success)&&(identical(other.data, data) || other.data == data)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,message,success,data); + +@override +String toString() { + return 'ProfileResponse(message: $message, success: $success, data: $data)'; +} + + +} + +/// @nodoc +abstract mixin class _$ProfileResponseCopyWith<$Res> implements $ProfileResponseCopyWith<$Res> { + factory _$ProfileResponseCopyWith(_ProfileResponse value, $Res Function(_ProfileResponse) _then) = __$ProfileResponseCopyWithImpl; +@override @useResult +$Res call({ + String? message, bool? success, ProfileData? data +}); + + +@override $ProfileDataCopyWith<$Res>? get data; + +} +/// @nodoc +class __$ProfileResponseCopyWithImpl<$Res> + implements _$ProfileResponseCopyWith<$Res> { + __$ProfileResponseCopyWithImpl(this._self, this._then); + + final _ProfileResponse _self; + final $Res Function(_ProfileResponse) _then; + +/// Create a copy of ProfileResponse +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? message = freezed,Object? success = freezed,Object? data = freezed,}) { + return _then(_ProfileResponse( +message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool?,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable +as ProfileData?, + )); +} + +/// Create a copy of ProfileResponse +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$ProfileDataCopyWith<$Res>? get data { + if (_self.data == null) { + return null; + } + + return $ProfileDataCopyWith<$Res>(_self.data!, (value) { + return _then(_self.copyWith(data: value)); + }); +} +} + +// dart format on diff --git a/lib/data/services/model/profile_response/profile_response.g.dart b/lib/data/services/model/profile_response/profile_response.g.dart new file mode 100644 index 0000000..c12bab5 --- /dev/null +++ b/lib/data/services/model/profile_response/profile_response.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'profile_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_ProfileResponse _$ProfileResponseFromJson(Map json) => + _ProfileResponse( + message: json['message'] as String?, + success: json['success'] as bool?, + data: + json['data'] == null + ? null + : ProfileData.fromJson(json['data'] as Map), + ); + +Map _$ProfileResponseToJson(_ProfileResponse instance) => + { + 'message': instance.message, + 'success': instance.success, + 'data': instance.data, + }; diff --git a/lib/data/services/profile_service.dart b/lib/data/services/profile_service.dart new file mode 100644 index 0000000..770720a --- /dev/null +++ b/lib/data/services/profile_service.dart @@ -0,0 +1,20 @@ +import 'package:tm_app/data/services/model/profile_response/profile_response.dart'; + +import '../../core/network/network_manager.dart'; +import '../../core/utils/result.dart'; + +class ProfileService { + ProfileService({required NetworkManager networkManager}) + : _networkManager = networkManager; + + final NetworkManager _networkManager; + + Future> getProfile() async { + final result = await _networkManager.makeRequest( + '/admin/v1/profile', + method: 'GET', + (json) => ProfileResponse.fromJson(json), + ); + return result; + } +} diff --git a/lib/view_models/auth_view_model.dart b/lib/view_models/auth_view_model.dart index 543c415..4390a4e 100644 --- a/lib/view_models/auth_view_model.dart +++ b/lib/view_models/auth_view_model.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import '../core/utils/result.dart'; import '../data/repositories/auth_repository.dart'; import '../data/services/model/login_response/login_response_model.dart'; +import '../data/services/model/logout_response/logout_response.dart'; import '../data/services/model/user/user.dart'; class AuthViewModel with ChangeNotifier { @@ -70,6 +71,26 @@ class AuthViewModel with ChangeNotifier { notifyListeners(); } + Future logout() async { + _errorMessage = null; + notifyListeners(); + + final result = await _authRepository.logout(); + + switch (result) { + case Ok(): + _loggedInUser = null; + break; + case Error(): + _errorMessage = result.error.toString(); + break; + } + + notifyListeners(); + _errorMessage = null; + notifyListeners(); + } + @override void dispose() { usernameController.dispose(); diff --git a/lib/view_models/profile_view_model.dart b/lib/view_models/profile_view_model.dart new file mode 100644 index 0000000..5da48c6 --- /dev/null +++ b/lib/view_models/profile_view_model.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:tm_app/data/repositories/auth_repository.dart'; +import 'package:tm_app/data/services/model/profile_data/profile_data.dart'; + +import '../core/utils/result.dart'; +import '../data/repositories/profile_repository.dart'; +import '../data/services/model/profile_response/profile_response.dart'; + +class ProfileViewModel with ChangeNotifier { + final ProfileRepository _profileRepository; + final AuthRepository _authRepository; + + ProfileViewModel({ + required ProfileRepository profileRepository, + required AuthRepository authRepository, + }) : _profileRepository = profileRepository, + _authRepository = authRepository { + getProfile(); + } + + bool _isLoading = false; + String? _errorMessage; + ProfileData? _profileData; + + bool get isLoading => _isLoading; + String? get errorMessage => _errorMessage; + ProfileData? get profileData => _profileData; + + Future getProfile() async { + _isLoading = true; + _errorMessage = null; + notifyListeners(); + + final result = await _profileRepository.getProfile(); + + switch (result) { + case Ok(): + _profileData = result.value.data; + break; + case Error(): + _errorMessage = result.error.toString(); + break; + } + _isLoading = false; + notifyListeners(); + _errorMessage = null; + notifyListeners(); + } +} diff --git a/lib/views/profile/pages/m_profile_page.dart b/lib/views/profile/pages/m_profile_page.dart index 516ee41..bdf8dfa 100644 --- a/lib/views/profile/pages/m_profile_page.dart +++ b/lib/views/profile/pages/m_profile_page.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:tm_app/view_models/auth_view_model.dart'; +import 'package:tm_app/view_models/profile_view_model.dart'; import 'package:tm_app/views/shared/tender_app_bar.dart'; import '../../../core/constants/strings.dart'; @@ -15,41 +18,67 @@ class MobileProfilePage extends StatelessWidget { return Scaffold( backgroundColor: AppColors.backgroundColor, appBar: tenderMobileAppBar(title: AppStrings.profile), - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 24.0.w(), vertical: 16.0.h()), - child: Column( - children: [ - SizedBox(height: 36.0.h()), - TitleDescription( - title: 'Company Name', - description: 'Telecom Solutions GmbH', + body: Consumer( + builder: (context, viewModel, child) { + if (viewModel.isLoading) { + return Center( + child: CircularProgressIndicator(color: AppColors.secondary50), + ); + } + + if (viewModel.errorMessage != null) { + return Center(child: Text(viewModel.errorMessage!)); + } + + return Padding( + padding: EdgeInsets.symmetric( + horizontal: 24.0.w(), + vertical: 16.0.h(), ), - TitleDescription(title: 'National ID', description: '12345678901'), - TitleDescription( - title: 'Registration No.', - description: 'DE-55667788', + child: Column( + children: [ + SizedBox(height: 36.0.h()), + TitleDescription( + title: 'Company Name', + description: 'Telecom Solutions GmbH', + ), + TitleDescription( + title: 'National ID', + description: '12345678901', + ), + TitleDescription( + title: 'Registration No.', + description: 'DE-55667788', + ), + TitleDescription( + title: 'Business Type', + description: 'Telecommunications', + ), + TitleDescription(title: 'Founded', description: '2010'), + SizedBox(height: 24.0.h()), + // Theme Toggle + Container( + padding: EdgeInsets.symmetric( + horizontal: 16.0.w(), + vertical: 12.0.h(), + ), + decoration: BoxDecoration( + color: AppColors.surfaceColor, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColors.borderColor), + ), + child: const ThemeToggle(), + ), + ElevatedButton( + onPressed: () { + context.read().logout(); + }, + child: const Text('Logout'), + ), + ], ), - TitleDescription( - title: 'Business Type', - description: 'Telecommunications', - ), - TitleDescription(title: 'Founded', description: '2010'), - SizedBox(height: 24.0.h()), - // Theme Toggle - Container( - padding: EdgeInsets.symmetric( - horizontal: 16.0.w(), - vertical: 12.0.h(), - ), - decoration: BoxDecoration( - color: AppColors.surfaceColor, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: AppColors.borderColor), - ), - child: const ThemeToggle(), - ), - ], - ), + ); + }, ), ); }