Delete account
This commit is contained in:
@@ -94,6 +94,11 @@ void configureAppRouter() {
|
||||
name: 'app_users',
|
||||
pageBuilder: AppUsersBuilder().buildPage,
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.deleteAccount,
|
||||
name: 'delete_account',
|
||||
pageBuilder: DeleteAccountBuilder().buildPage,
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: AppRoutes.customerService,
|
||||
|
||||
@@ -23,7 +23,7 @@ class AccountRemoteDatasourceImpl implements AccountRemoteDatasource {
|
||||
@override
|
||||
Future<List<DeviceEntity>> getLinkedDevices({required String userId}) async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>(
|
||||
/*final response = await _repository.get<Map<String, dynamic>>(
|
||||
'/$userId/devices',
|
||||
);
|
||||
final data = response.data!['items'];
|
||||
@@ -31,8 +31,8 @@ class AccountRemoteDatasourceImpl implements AccountRemoteDatasource {
|
||||
throw Exception('Empty response from /:userId/devices');
|
||||
}
|
||||
|
||||
final model = GetLinkedDevicesResponseModel.fromJson(data);
|
||||
/*final model = GetLinkedDevicesResponseModel(items: [
|
||||
final model = GetLinkedDevicesResponseModel.fromJson(data);*/
|
||||
final model = GetLinkedDevicesResponseModel(items: [
|
||||
GetLinkedDevicesItemResponseModel(
|
||||
identificator: '1111',
|
||||
carrierName: 'Carlos',
|
||||
@@ -81,7 +81,7 @@ class AccountRemoteDatasourceImpl implements AccountRemoteDatasource {
|
||||
isDisconnect: false,
|
||||
)
|
||||
),
|
||||
]);*/
|
||||
]);
|
||||
return model.toEntity();
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(
|
||||
|
||||
@@ -15,13 +15,17 @@ abstract class AccountRepository {
|
||||
required UpdateDeviceRequestEntity request
|
||||
});
|
||||
|
||||
Future<void> updateUser({required String userId, required UpdateUserRequestEntity request});
|
||||
Future<void> updateUser({
|
||||
required String userId,
|
||||
required UpdateUserRequestEntity request
|
||||
});
|
||||
|
||||
Future<List<UserEntity>> getAppUsers({required String userId});
|
||||
|
||||
Future<void> deleteAppUser({required String userId});
|
||||
|
||||
Future<void> changePassword({required String userId,
|
||||
Future<void> changePassword({
|
||||
required String userId,
|
||||
required ChangePasswordRequestEntity request
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class AccountSettingsScreen extends ConsumerWidget {
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppSectionButton(
|
||||
onPressed: (){},
|
||||
onPressed: (){navigationContract.pushTo(AppRoutes.deleteAccount);},
|
||||
icon: Icons.no_accounts,
|
||||
text: I18n.legacyDeleteAccount
|
||||
),
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:account/src/features/delete_account/presentation/delete_account_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
|
||||
class DeleteAccountBuilder {
|
||||
const DeleteAccountBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
|
||||
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: DeleteAccountScreen(navigationContract: navigationContract),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
abstract class DeleteAccountUseCase {
|
||||
Future<void> deleteAccount({
|
||||
required String userId,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:account/src/core/domain/repositories/account_repository.dart';
|
||||
import 'package:account/src/features/delete_account/domain/delete_account_use_case.dart';
|
||||
|
||||
class DeleteAccountUseCaseImpl implements DeleteAccountUseCase {
|
||||
DeleteAccountUseCaseImpl(this._repository);
|
||||
|
||||
final AccountRepository _repository;
|
||||
|
||||
@override
|
||||
Future<void> deleteAccount({required String userId}) {
|
||||
return _repository.deleteAppUser(userId: userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
import 'package:account/src/features/delete_account/presentation/state/delete_account_view_model.dart';
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class DeleteAccountScreen extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const DeleteAccountScreen({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final state = ref.watch(deleteAccountViewModelProvider);
|
||||
final viewModel = ref.read(deleteAccountViewModelProvider.notifier);
|
||||
|
||||
return PageLayout(
|
||||
title: context.translate(I18n.legacyDeleteAccount),
|
||||
body: SingleChildScrollView(child: Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
width: double.infinity,
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(vertical: 20),
|
||||
big: EdgeInsets.symmetric(vertical: 19),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF00A1C6),
|
||||
borderRadius: BorderRadius.circular(12)
|
||||
),
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.all(7),
|
||||
big: EdgeInsets.all(6),
|
||||
),
|
||||
child: Icon(Icons.power_settings_new_outlined,
|
||||
size: SizeUtils.getByScreen(small: 48, big: 46),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
Text(context.translate(I18n.legacyDeleteAccount),
|
||||
style: TextStyle(fontSize: SizeUtils.getByScreen(small: 20, big: 19)),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
Text(context.translate(I18n.legacyDeleteAccountBody1),
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 38, big: 36)),
|
||||
Text(context.translate(I18n.legacyDeleteAccountBody2),
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary)
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
)),
|
||||
footer: Container(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 14, vertical: 10),
|
||||
big: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
child: PrimaryButton(
|
||||
onPressed: (){
|
||||
if (state.loggedUser != null) {
|
||||
showDialog(context: context, builder: (context) =>
|
||||
Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
child: ConfirmDialog(navigationContract: navigationContract),
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
text: context.translate(I18n.legacyRequestCancelButton),
|
||||
color: Color(0xFF588EA5)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ConfirmDialog extends ConsumerWidget{
|
||||
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const ConfirmDialog({
|
||||
super.key,
|
||||
required this.navigationContract,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final state = ref.watch(deleteAccountViewModelProvider);
|
||||
final viewModel = ref.read(deleteAccountViewModelProvider.notifier);
|
||||
|
||||
final steps = [
|
||||
Container(
|
||||
height: 210,
|
||||
width: 500,
|
||||
color: Colors.white,
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 22, vertical: 11),
|
||||
big: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(context.translate(I18n.legacyVerifyAccount),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 16)),
|
||||
Text('${context.translate(I18n.email)}: ${state.loggedUser!.email}'),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
Row(
|
||||
children: [
|
||||
Text('${context.translate(I18n.password)}: '),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(child: TextField(
|
||||
controller: viewModel.passwordController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(hintText: context.translate(I18n.password)),
|
||||
obscureText: true,
|
||||
enableSuggestions: false,
|
||||
autocorrect: true,
|
||||
))
|
||||
],
|
||||
),
|
||||
if (state.errorMessage.isNotEmpty)
|
||||
Text(
|
||||
state.errorMessage,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: SecondaryButton(
|
||||
onPressed: (){Navigator.pop(context);},
|
||||
text: context.translate(I18n.legacyCancel),
|
||||
color: Color(0xFF588EA5),
|
||||
height: 40,
|
||||
radius: 20,
|
||||
)),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(child: PrimaryButton(
|
||||
onPressed: viewModel.nextStep,
|
||||
text: context.translate(I18n.accept),
|
||||
color: Color(0xFF588EA5),
|
||||
height: 40,
|
||||
radius: 20,
|
||||
)),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 400,
|
||||
width: 500,
|
||||
color: Colors.white,
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 22, vertical: 11),
|
||||
big: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 14, big: 12)),
|
||||
Text(context.translate(I18n.legacyRequestCancelTitle),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 14, big: 12)),
|
||||
Expanded(child: SingleChildScrollView(child: Column(
|
||||
children: [
|
||||
Text(context.translate(I18n.legacyRequestCancelBody),
|
||||
style: TextStyle(height: 1.5),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
...List<Widget>.generate(state.devices.length, (int index) =>
|
||||
CheckboxListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(context.translate(I18n.legacyDeleteDeviceData,
|
||||
args: {'name': state.devices[index].carrierName}
|
||||
),
|
||||
style: TextStyle(height: 0),
|
||||
),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
value: false,
|
||||
onChanged: (_){
|
||||
viewModel.updateDeleteDevice(index);
|
||||
}
|
||||
)
|
||||
),
|
||||
]
|
||||
))),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: SecondaryButton(
|
||||
onPressed: (){
|
||||
viewModel.resetConfirmStep();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
text: context.translate(I18n.legacyCancel),
|
||||
color: Color(0xFF588EA5),
|
||||
height: 50,
|
||||
radius: 25,
|
||||
)),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
viewModel.deleteAccount();
|
||||
if (!context.mounted) return;
|
||||
|
||||
navigationContract.goTo(AppRoutes.login);
|
||||
},
|
||||
text: context.translate(I18n.legacyConfirm),
|
||||
color: Color(0xFF588EA5),
|
||||
height: 50,
|
||||
radius: 25,
|
||||
)),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
];
|
||||
|
||||
return steps[state.confirmStep];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:account/src/core/providers/account_repository_provider.dart';
|
||||
import 'package:account/src/features/delete_account/domain/delete_account_use_case.dart';
|
||||
import 'package:account/src/features/delete_account/domain/delete_account_use_case_impl.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final deleteAccountUseCaseProvider = Provider.autoDispose<DeleteAccountUseCase>((ref) {
|
||||
final accountRepository = ref.read(accountRepositoryProvider);
|
||||
return DeleteAccountUseCaseImpl(accountRepository);
|
||||
});
|
||||
@@ -0,0 +1,128 @@
|
||||
import 'package:account/src/features/delete_account/domain/delete_account_use_case.dart';
|
||||
import 'package:account/src/features/delete_account/presentation/providers/delete_account_use_case_provider.dart';
|
||||
import 'package:account/src/features/delete_account/presentation/state/delete_account_view_state.dart';
|
||||
import 'package:account/src/features/linked_devices/domain/get_linked_devices_use_case.dart';
|
||||
import 'package:account/src/features/linked_devices/presentation/providers/get_linked_devices_use_case_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
|
||||
// import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
final deleteAccountViewModelProvider =
|
||||
NotifierProvider.autoDispose<DeleteAccountViewModel, DeleteAccountViewState>(
|
||||
DeleteAccountViewModel.new,
|
||||
);
|
||||
|
||||
class DeleteAccountViewModel extends Notifier<DeleteAccountViewState> {
|
||||
late final DeleteAccountUseCase _deleteAccountUseCase;
|
||||
late final GetLinkedDevicesUseCase _getLinkedDevicesUseCase;
|
||||
late final TextEditingController passwordController;
|
||||
|
||||
@override
|
||||
DeleteAccountViewState build() {
|
||||
_deleteAccountUseCase = ref.read(deleteAccountUseCaseProvider);
|
||||
_getLinkedDevicesUseCase = ref.read(getLinkedDevicesUseCaseProvider);
|
||||
|
||||
passwordController = TextEditingController();
|
||||
passwordController.addListener(_onPasswordChanged);
|
||||
|
||||
ref.read(loggedUserProvider.future)
|
||||
.then((user){
|
||||
setUser(user);
|
||||
return _getLinkedDevicesUseCase.getLinkedDevices(userId: user.id);
|
||||
}).then(setDevices);
|
||||
|
||||
ref.onDispose(disposeListeners);
|
||||
|
||||
return const DeleteAccountViewState();
|
||||
}
|
||||
|
||||
void setUser(UserEntity user) {
|
||||
state = state.copyWith(loggedUser: user);
|
||||
}
|
||||
|
||||
void setDevices(List<DeviceEntity> devices) {
|
||||
state = state.copyWith(
|
||||
devices: devices,
|
||||
deleteDevices: List<bool>.generate(devices.length, (_)=>false),
|
||||
);
|
||||
}
|
||||
|
||||
void updateDeleteDevice(int index) {
|
||||
List<bool> deleteDevices = state.deleteDevices;
|
||||
deleteDevices[index] = !deleteDevices[index];
|
||||
|
||||
state = state.copyWith(
|
||||
deleteDevices: deleteDevices,
|
||||
);
|
||||
}
|
||||
|
||||
void _onPasswordChanged() {
|
||||
final value = passwordController.text;
|
||||
if (value == state.password) return;
|
||||
|
||||
state = state.copyWith(
|
||||
password: value,
|
||||
errorMessage: ''
|
||||
);
|
||||
}
|
||||
|
||||
bool _validateForm() {
|
||||
if (state.password.trim().isEmpty) {
|
||||
state = state.copyWith(errorMessage: 'errorMessagePasswordIsEmpty');
|
||||
return false;
|
||||
}
|
||||
/*if (state.password.trim() != state.loggedUser.password.trim()) {
|
||||
state = state.copyWith(errorMessage: 'errorMessagePasswordsDontMatch');
|
||||
return false;
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
void nextStep() {
|
||||
final step = state.confirmStep;
|
||||
|
||||
if (step == 0 && !_validateForm()) return;
|
||||
|
||||
state = state.copyWith(confirmStep: step + 1);
|
||||
}
|
||||
|
||||
void resetConfirmStep() {
|
||||
state = state.copyWith(confirmStep: 0);
|
||||
}
|
||||
|
||||
Future<bool> deleteAccount() async {
|
||||
if (state.isLoading) return false;
|
||||
|
||||
try {
|
||||
state = state.copyWith(isLoading: true);
|
||||
|
||||
await _deleteAccountUseCase.deleteAccount(userId: state.loggedUser!.id);
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
ref.invalidate(loggedUserProvider);
|
||||
|
||||
state = state.copyWith(isLoading: false, isDeleted: true);
|
||||
return true;
|
||||
} catch (e) {
|
||||
state = state.copyWith(isLoading: false);
|
||||
if (!ref.mounted) return false;
|
||||
_finishWithError(message: e.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _finishWithError({required String message}) {
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: message,
|
||||
);
|
||||
}
|
||||
|
||||
void disposeListeners() {
|
||||
passwordController.removeListener(_onPasswordChanged);
|
||||
passwordController.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
|
||||
part 'delete_account_view_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class DeleteAccountViewState with _$DeleteAccountViewState {
|
||||
const factory DeleteAccountViewState({
|
||||
UserEntity? loggedUser,
|
||||
@Default('') String password,
|
||||
@Default(false) bool isLoading,
|
||||
@Default(false) bool isDeleted,
|
||||
@Default(0) int confirmStep,
|
||||
@Default([]) List<DeviceEntity> devices,
|
||||
@Default([]) List<bool> deleteDevices,
|
||||
@Default('') String errorMessage,
|
||||
}) = _DeleteAccountViewState;
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
// 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 'delete_account_view_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DeleteAccountViewState {
|
||||
|
||||
UserEntity? get loggedUser; String get password; bool get isLoading; bool get isDeleted; int get confirmStep; List<DeviceEntity> get devices; List<bool> get deleteDevices; String get errorMessage;
|
||||
/// Create a copy of DeleteAccountViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DeleteAccountViewStateCopyWith<DeleteAccountViewState> get copyWith => _$DeleteAccountViewStateCopyWithImpl<DeleteAccountViewState>(this as DeleteAccountViewState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeleteAccountViewState&&(identical(other.loggedUser, loggedUser) || other.loggedUser == loggedUser)&&(identical(other.password, password) || other.password == password)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isDeleted, isDeleted) || other.isDeleted == isDeleted)&&(identical(other.confirmStep, confirmStep) || other.confirmStep == confirmStep)&&const DeepCollectionEquality().equals(other.devices, devices)&&const DeepCollectionEquality().equals(other.deleteDevices, deleteDevices)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,loggedUser,password,isLoading,isDeleted,confirmStep,const DeepCollectionEquality().hash(devices),const DeepCollectionEquality().hash(deleteDevices),errorMessage);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeleteAccountViewState(loggedUser: $loggedUser, password: $password, isLoading: $isLoading, isDeleted: $isDeleted, confirmStep: $confirmStep, devices: $devices, deleteDevices: $deleteDevices, errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DeleteAccountViewStateCopyWith<$Res> {
|
||||
factory $DeleteAccountViewStateCopyWith(DeleteAccountViewState value, $Res Function(DeleteAccountViewState) _then) = _$DeleteAccountViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
UserEntity? loggedUser, String password, bool isLoading, bool isDeleted, int confirmStep, List<DeviceEntity> devices, List<bool> deleteDevices, String errorMessage
|
||||
});
|
||||
|
||||
|
||||
$UserEntityCopyWith<$Res>? get loggedUser;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DeleteAccountViewStateCopyWithImpl<$Res>
|
||||
implements $DeleteAccountViewStateCopyWith<$Res> {
|
||||
_$DeleteAccountViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DeleteAccountViewState _self;
|
||||
final $Res Function(DeleteAccountViewState) _then;
|
||||
|
||||
/// Create a copy of DeleteAccountViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? loggedUser = freezed,Object? password = null,Object? isLoading = null,Object? isDeleted = null,Object? confirmStep = null,Object? devices = null,Object? deleteDevices = null,Object? errorMessage = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
loggedUser: freezed == loggedUser ? _self.loggedUser : loggedUser // ignore: cast_nullable_to_non_nullable
|
||||
as UserEntity?,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isDeleted: null == isDeleted ? _self.isDeleted : isDeleted // ignore: cast_nullable_to_non_nullable
|
||||
as bool,confirmStep: null == confirmStep ? _self.confirmStep : confirmStep // ignore: cast_nullable_to_non_nullable
|
||||
as int,devices: null == devices ? _self.devices : devices // ignore: cast_nullable_to_non_nullable
|
||||
as List<DeviceEntity>,deleteDevices: null == deleteDevices ? _self.deleteDevices : deleteDevices // ignore: cast_nullable_to_non_nullable
|
||||
as List<bool>,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
/// Create a copy of DeleteAccountViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$UserEntityCopyWith<$Res>? get loggedUser {
|
||||
if (_self.loggedUser == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $UserEntityCopyWith<$Res>(_self.loggedUser!, (value) {
|
||||
return _then(_self.copyWith(loggedUser: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DeleteAccountViewState].
|
||||
extension DeleteAccountViewStatePatterns on DeleteAccountViewState {
|
||||
/// 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 extends Object?>(TResult Function( _DeleteAccountViewState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeleteAccountViewState() 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 extends Object?>(TResult Function( _DeleteAccountViewState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeleteAccountViewState():
|
||||
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 extends Object?>(TResult? Function( _DeleteAccountViewState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeleteAccountViewState() 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 extends Object?>(TResult Function( UserEntity? loggedUser, String password, bool isLoading, bool isDeleted, int confirmStep, List<DeviceEntity> devices, List<bool> deleteDevices, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeleteAccountViewState() when $default != null:
|
||||
return $default(_that.loggedUser,_that.password,_that.isLoading,_that.isDeleted,_that.confirmStep,_that.devices,_that.deleteDevices,_that.errorMessage);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 extends Object?>(TResult Function( UserEntity? loggedUser, String password, bool isLoading, bool isDeleted, int confirmStep, List<DeviceEntity> devices, List<bool> deleteDevices, String errorMessage) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeleteAccountViewState():
|
||||
return $default(_that.loggedUser,_that.password,_that.isLoading,_that.isDeleted,_that.confirmStep,_that.devices,_that.deleteDevices,_that.errorMessage);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 extends Object?>(TResult? Function( UserEntity? loggedUser, String password, bool isLoading, bool isDeleted, int confirmStep, List<DeviceEntity> devices, List<bool> deleteDevices, String errorMessage)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeleteAccountViewState() when $default != null:
|
||||
return $default(_that.loggedUser,_that.password,_that.isLoading,_that.isDeleted,_that.confirmStep,_that.devices,_that.deleteDevices,_that.errorMessage);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DeleteAccountViewState implements DeleteAccountViewState {
|
||||
const _DeleteAccountViewState({this.loggedUser, this.password = '', this.isLoading = false, this.isDeleted = false, this.confirmStep = 0, final List<DeviceEntity> devices = const [], final List<bool> deleteDevices = const [], this.errorMessage = ''}): _devices = devices,_deleteDevices = deleteDevices;
|
||||
|
||||
|
||||
@override final UserEntity? loggedUser;
|
||||
@override@JsonKey() final String password;
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final bool isDeleted;
|
||||
@override@JsonKey() final int confirmStep;
|
||||
final List<DeviceEntity> _devices;
|
||||
@override@JsonKey() List<DeviceEntity> get devices {
|
||||
if (_devices is EqualUnmodifiableListView) return _devices;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_devices);
|
||||
}
|
||||
|
||||
final List<bool> _deleteDevices;
|
||||
@override@JsonKey() List<bool> get deleteDevices {
|
||||
if (_deleteDevices is EqualUnmodifiableListView) return _deleteDevices;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_deleteDevices);
|
||||
}
|
||||
|
||||
@override@JsonKey() final String errorMessage;
|
||||
|
||||
/// Create a copy of DeleteAccountViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DeleteAccountViewStateCopyWith<_DeleteAccountViewState> get copyWith => __$DeleteAccountViewStateCopyWithImpl<_DeleteAccountViewState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeleteAccountViewState&&(identical(other.loggedUser, loggedUser) || other.loggedUser == loggedUser)&&(identical(other.password, password) || other.password == password)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isDeleted, isDeleted) || other.isDeleted == isDeleted)&&(identical(other.confirmStep, confirmStep) || other.confirmStep == confirmStep)&&const DeepCollectionEquality().equals(other._devices, _devices)&&const DeepCollectionEquality().equals(other._deleteDevices, _deleteDevices)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,loggedUser,password,isLoading,isDeleted,confirmStep,const DeepCollectionEquality().hash(_devices),const DeepCollectionEquality().hash(_deleteDevices),errorMessage);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeleteAccountViewState(loggedUser: $loggedUser, password: $password, isLoading: $isLoading, isDeleted: $isDeleted, confirmStep: $confirmStep, devices: $devices, deleteDevices: $deleteDevices, errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DeleteAccountViewStateCopyWith<$Res> implements $DeleteAccountViewStateCopyWith<$Res> {
|
||||
factory _$DeleteAccountViewStateCopyWith(_DeleteAccountViewState value, $Res Function(_DeleteAccountViewState) _then) = __$DeleteAccountViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
UserEntity? loggedUser, String password, bool isLoading, bool isDeleted, int confirmStep, List<DeviceEntity> devices, List<bool> deleteDevices, String errorMessage
|
||||
});
|
||||
|
||||
|
||||
@override $UserEntityCopyWith<$Res>? get loggedUser;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DeleteAccountViewStateCopyWithImpl<$Res>
|
||||
implements _$DeleteAccountViewStateCopyWith<$Res> {
|
||||
__$DeleteAccountViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DeleteAccountViewState _self;
|
||||
final $Res Function(_DeleteAccountViewState) _then;
|
||||
|
||||
/// Create a copy of DeleteAccountViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? loggedUser = freezed,Object? password = null,Object? isLoading = null,Object? isDeleted = null,Object? confirmStep = null,Object? devices = null,Object? deleteDevices = null,Object? errorMessage = null,}) {
|
||||
return _then(_DeleteAccountViewState(
|
||||
loggedUser: freezed == loggedUser ? _self.loggedUser : loggedUser // ignore: cast_nullable_to_non_nullable
|
||||
as UserEntity?,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isDeleted: null == isDeleted ? _self.isDeleted : isDeleted // ignore: cast_nullable_to_non_nullable
|
||||
as bool,confirmStep: null == confirmStep ? _self.confirmStep : confirmStep // ignore: cast_nullable_to_non_nullable
|
||||
as int,devices: null == devices ? _self._devices : devices // ignore: cast_nullable_to_non_nullable
|
||||
as List<DeviceEntity>,deleteDevices: null == deleteDevices ? _self._deleteDevices : deleteDevices // ignore: cast_nullable_to_non_nullable
|
||||
as List<bool>,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of DeleteAccountViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$UserEntityCopyWith<$Res>? get loggedUser {
|
||||
if (_self.loggedUser == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $UserEntityCopyWith<$Res>(_self.loggedUser!, (value) {
|
||||
return _then(_self.copyWith(loggedUser: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -14,7 +14,7 @@ class LegacySharedRemoteDatasourceImpl implements LegacySharedRemoteDatasource {
|
||||
@override
|
||||
Future<UserEntity> getLoggedUser({required String token}) async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>(
|
||||
/*final response = await _repository.get<Map<String, dynamic>>(
|
||||
'/users/api/auth/me',
|
||||
);
|
||||
final data = response.data!['item'];
|
||||
@@ -22,13 +22,13 @@ class LegacySharedRemoteDatasourceImpl implements LegacySharedRemoteDatasource {
|
||||
throw Exception('Empty response from /auth/me');
|
||||
}
|
||||
|
||||
final model = GetLoggedUserResponseModel.fromJson(data);
|
||||
/*final model = GetLoggedUserResponseModel(item:
|
||||
final model = GetLoggedUserResponseModel.fromJson(data);*/
|
||||
final model = GetLoggedUserResponseModel(item:
|
||||
GetLoggedUserItemResponseModel(
|
||||
id: '1111',
|
||||
firstName: 'Juan',
|
||||
email: 'juan@test.com',
|
||||
phone: '111111111'));*/
|
||||
phone: '111111111'));
|
||||
return model.toEntity();
|
||||
} on DioException catch (error) {
|
||||
throw _mapDioError(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_shared/src/data/models/entities/user_entity.dart';
|
||||
import 'package:legacy_shared/src/data/repositories/legacy_shared_repository.dart';
|
||||
|
||||
import 'legacy_shared_repository_provider.dart';
|
||||
|
||||
@@ -10,11 +11,11 @@ final loggedUserProvider = AsyncNotifierProvider<LoggedUserNotifier, UserEntity>
|
||||
);
|
||||
|
||||
class LoggedUserNotifier extends AsyncNotifier<UserEntity> {
|
||||
late final legacySharedRepository;
|
||||
late final LegacySharedRepository _legacySharedRepository;
|
||||
|
||||
@override
|
||||
Future<UserEntity> build() {
|
||||
legacySharedRepository = ref.read(legacySharedRepositoryProvider);
|
||||
return legacySharedRepository.getLoggedUser(token: '');
|
||||
_legacySharedRepository = ref.read(legacySharedRepositoryProvider);
|
||||
return _legacySharedRepository.getLoggedUser(token: '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ class AppRoutes {
|
||||
static const changePassword = '$accountSettings/change_password';
|
||||
static const linkedDevices = '$accountSettings/linked_devices';
|
||||
static const appUsers = '$accountSettings/app_users';
|
||||
static const deleteAccount = '$accountSettings/delete_account';
|
||||
|
||||
static const legacyDashboard = '$legacy/dashboard';
|
||||
|
||||
|
||||
@@ -176,5 +176,13 @@
|
||||
"userRole": "Rol: {role}",
|
||||
"copy": "copiar",
|
||||
"deviceIdLabel": "ID: {deviceId}",
|
||||
"regCodeLabel": "Código de registro: {regCode}"
|
||||
"regCodeLabel": "Código de registro: {regCode}",
|
||||
"deleteAccountBody1": "Cancelar una cuenta es una operación irreversible. Confirma que todos los servicios relacionados con la cuenta se hayan gestionado correctamente.\n\nDespués de cancelar tu cuenta, ya no podrás usar esta cuenta ni recuperar ningún contenido o información que hayas agregado o vinculado (incluso si usas la misma cuenta para registrarse y volver a usar), incluídos, entre otros:\n1. No podrás iniciar sesión y usar esta cuenta.\n2. La información personal y la información histórica de tu cuenta no se recuperarán.\n3. No se pueden recuperar todos los registros de servicios de terceros que utiliza a través de la vinculación de cuenta o la vinculación de cuenta. Ya no podrás iniciar sesión y utilizar los servicios mencionados anteriormente. El amor, las monedas de oro, los puntos de terceros, los pedidos, los boletos y otros cupones que hayas recibido se considerarán abandonados y no se utilizarán.\n\nTen en cuenta que cancelar tu cuenta no significa que el comportamiento de la cuenta y las responsabilidades relacionadas antes de la cancelación de esta cuenta estén exentas o reducidas.",
|
||||
"deleteAccountBody2": "Hacer clic en \"Solicitar la cancelación de mi cuenta\" significa que has leído y estás de acuerdo con la descripción anterior.",
|
||||
"requestCancelButton": "Solicitar la cancelación de mi cuenta",
|
||||
"verifyAccount": "Verificación de la cuenta,",
|
||||
"requestCancelTitle": "Solicitud de cancelación de la cuenta",
|
||||
"requestCancelBody": "1. La cancelación de la cuenta no es la recuperación operacional, asegúrate de que antes de operar la cuenta ya no se utiliza.\n2. Enviado correctamente una cancelación de la cuenta de la aplicación, la plataforma se eliminará toda la información relacionada con tu cuenta dentro de 1 hora.",
|
||||
"deleteDeviceData": "Borrar toda la información relacionada con el dispositivo de {name}",
|
||||
"confirm": "Confirmar"
|
||||
}
|
||||
@@ -207,4 +207,12 @@ class I18n {
|
||||
static const String legacyRegCodeLabel = 'regCodeLabel';
|
||||
static const String legacyRegCode = 'regCode';
|
||||
static const String legacyDeleteAccount = 'deleteAccount';
|
||||
static const String legacyDeleteAccountBody1 = 'deleteAccountBody1';
|
||||
static const String legacyDeleteAccountBody2 = 'deleteAccountBody2';
|
||||
static const String legacyRequestCancelButton = 'requestCancelButton';
|
||||
static const String legacyVerifyAccount = 'verifyAccount';
|
||||
static const String legacyRequestCancelTitle = 'requestCancelTitle';
|
||||
static const String legacyRequestCancelBody = 'requestCancelBody';
|
||||
static const String legacyDeleteDeviceData = 'deleteDeviceData';
|
||||
static const String legacyConfirm = 'confirm';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user