mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-10 07:07:17 +00:00
add delete account UI and logic
This commit is contained in:
3
assets/icons/delete_account_icon.svg
Normal file
3
assets/icons/delete_account_icon.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 14 KiB |
@ -20,6 +20,7 @@ class SecurityBloc extends Bloc<SecurityEvent, SecurityState> {
|
||||
on<UpdateTimerEvent>(_onUpdateTimer);
|
||||
on<VerifyPassCodeEvent>(verifyCode);
|
||||
on<ChangePasswordEvent>(changePassword);
|
||||
on<DeleteAccountEvent>(onDeleteAccountEvent);
|
||||
}
|
||||
|
||||
void _onSetPassword(SetPassword event, Emitter<SecurityState> emit) {
|
||||
@ -180,7 +181,6 @@ class SecurityBloc extends Bloc<SecurityEvent, SecurityState> {
|
||||
ChangePasswordEvent event, Emitter<SecurityState> emit) async {
|
||||
emit(LoadingForgetState());
|
||||
try {
|
||||
|
||||
final response = await AuthenticationAPI.forgetPassword(
|
||||
email: HomeCubit.user!.email!,
|
||||
otpCode: event.otpCode,
|
||||
@ -195,5 +195,18 @@ class SecurityBloc extends Bloc<SecurityEvent, SecurityState> {
|
||||
emit(AuthInitialState());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Future<void> onDeleteAccountEvent(
|
||||
DeleteAccountEvent event, Emitter<SecurityState> emit) async {
|
||||
try {
|
||||
await AuthenticationAPI.deleteAccount();
|
||||
emit(ChangedPassState());
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response!.data;
|
||||
String errorMessage =
|
||||
errorData['error']['message'] ?? 'something went wrong';
|
||||
validate = errorMessage;
|
||||
emit(AuthInitialState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,3 +29,5 @@ class ChangePasswordEvent extends SecurityEvent {
|
||||
}
|
||||
|
||||
class VerifyPassCodeEvent extends SecurityEvent {}
|
||||
|
||||
class DeleteAccountEvent extends SecurityEvent {}
|
||||
|
@ -0,0 +1,88 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_bloc.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_event.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_state.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
|
||||
import '../../../../../../generated/assets.dart';
|
||||
import '../../../../../../utils/resource_manager/color_manager.dart';
|
||||
import '../../../../../shared_widgets/default_scaffold.dart';
|
||||
|
||||
class DeleteAccountPage extends StatelessWidget {
|
||||
const DeleteAccountPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocListener<SecurityBloc, SecurityState>(
|
||||
listener: (context, state) {
|
||||
if (state is ChangedPassState) {
|
||||
AuthCubit.get(context).logout();
|
||||
}
|
||||
},
|
||||
child: DefaultScaffold(
|
||||
title: 'Delete Account',
|
||||
bottomNavBar: SizedBox(
|
||||
height: 150,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
context.read<SecurityBloc>().add(DeleteAccountEvent());
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
margin: const EdgeInsets.only(right: 20, left: 20),
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.blueColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
'Delete Account',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: ColorsManager.onPrimaryColor),
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 80, bottom: 30),
|
||||
child: SvgPicture.asset(Assets.deleteAccountIcon),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: BodyMedium(
|
||||
text: 'Account Verification',
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
const BodyMedium(
|
||||
text: 'if you confirm to "delete account",',
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 16,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
const BodyMedium(
|
||||
text: 'the account will be deleted',
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -30,7 +30,10 @@ class ChangePasswordPage extends StatelessWidget {
|
||||
MaterialPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (_) => SecurityBloc(), // Provide the Bloc
|
||||
child: const VerificationCodePage(),
|
||||
child: const VerificationCodePage(
|
||||
title: 'Change Password',
|
||||
isDeleteAccountMode: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -1,10 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_bloc.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/view/change_password_page.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/view/verification_code_page.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../bloc/security_event.dart';
|
||||
|
||||
class SecurtyView extends StatelessWidget {
|
||||
const SecurtyView({super.key});
|
||||
|
||||
@ -108,33 +113,44 @@ class SecurtyView extends StatelessWidget {
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// InkWell(
|
||||
// onTap: () {},
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// const Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// BodyMedium(
|
||||
// text: 'Delete Account',
|
||||
// ),
|
||||
// Icon(
|
||||
// Icons.arrow_forward_ios,
|
||||
// color: ColorsManager.greyColor,
|
||||
// size: 15,
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// Container(
|
||||
// margin: const EdgeInsets.symmetric(vertical: 15),
|
||||
// height: 1,
|
||||
// color: ColorsManager.greyColor,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 15),
|
||||
height: 1,
|
||||
color: ColorsManager.greyColor,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => BlocProvider(
|
||||
create: (_) => SecurityBloc()..add(StartTimerEvent()),
|
||||
child: VerificationCodePage(
|
||||
title: 'Delete Account',
|
||||
isDeleteAccountMode: true,
|
||||
),
|
||||
),
|
||||
));
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyMedium(
|
||||
text: 'Delete Account',
|
||||
fontColor: ColorsManager.red,
|
||||
),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 15,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// InkWell(
|
||||
// onTap: () {},
|
||||
// child: const Row(
|
||||
|
@ -4,6 +4,7 @@ import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_bloc.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_event.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/bloc/security_state.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/delete_account/delete_account_page.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/securty/view/set_password_page.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
@ -11,7 +12,13 @@ import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
import 'package:pin_code_fields/pin_code_fields.dart';
|
||||
|
||||
class VerificationCodePage extends StatelessWidget {
|
||||
const VerificationCodePage({super.key});
|
||||
final String title;
|
||||
final bool isDeleteAccountMode;
|
||||
const VerificationCodePage({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.isDeleteAccountMode,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -20,19 +27,29 @@ class VerificationCodePage extends StatelessWidget {
|
||||
create: (context) => SecurityBloc()..add(StartTimerEvent()),
|
||||
child: BlocConsumer<SecurityBloc, SecurityState>(
|
||||
listener: (context, state) {
|
||||
final securityBloc = context.read<SecurityBloc>();
|
||||
if (state is SuccessForgetState) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => SetPasswordPage(
|
||||
otpCode: otp,
|
||||
),
|
||||
));
|
||||
if (isDeleteAccountMode) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => BlocProvider.value(
|
||||
value: securityBloc,
|
||||
child: DeleteAccountPage(),
|
||||
),
|
||||
));
|
||||
} else {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => SetPasswordPage(
|
||||
otpCode: otp,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final _bloc = BlocProvider.of<SecurityBloc>(context);
|
||||
|
||||
return DefaultScaffold(
|
||||
title: 'Change Password',
|
||||
title: title,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 55),
|
||||
@ -109,27 +126,35 @@ class VerificationCodePage extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap:
|
||||
state is TimerState && !state.isButtonEnabled && state.remainingTime != 1
|
||||
? null
|
||||
: () {
|
||||
_bloc.add(StartTimerEvent());
|
||||
},
|
||||
onTap: state is TimerState &&
|
||||
!state.isButtonEnabled &&
|
||||
state.remainingTime != 1
|
||||
? null
|
||||
: () {
|
||||
_bloc.add(StartTimerEvent());
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(right: 20, left: 20, top: 15, bottom: 15),
|
||||
padding: const EdgeInsets.only(
|
||||
right: 20, left: 20, top: 15, bottom: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: state is TimerState && !state.isButtonEnabled
|
||||
? ColorsManager.blueButton
|
||||
: ColorsManager.blueColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20))),
|
||||
child: Center(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'${state is TimerState && !state.isButtonEnabled && state.remainingTime != 1 ? "${_bloc.formattedTime(state.remainingTime)} " : "Resend"}',
|
||||
state is TimerState &&
|
||||
!state.isButtonEnabled &&
|
||||
state.remainingTime != 1
|
||||
? "${_bloc.formattedTime(state.remainingTime)} "
|
||||
: "Resend",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: state is TimerState && !state.isButtonEnabled
|
||||
color: state is TimerState &&
|
||||
!state.isButtonEnabled
|
||||
? Colors.white
|
||||
: ColorsManager.onPrimaryColor,
|
||||
),
|
||||
@ -142,18 +167,24 @@ class VerificationCodePage extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
context.read<SecurityBloc>().add(VerifyPassCodeEvent());
|
||||
context
|
||||
.read<SecurityBloc>()
|
||||
.add(VerifyPassCodeEvent());
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(right: 20, left: 20, top: 15, bottom: 15),
|
||||
padding: const EdgeInsets.only(
|
||||
right: 20, left: 20, top: 15, bottom: 15),
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.blueColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(20))),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Verify",
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: Colors.white, fontWeight: FontWeight.w700),
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w700),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1128,7 +1128,7 @@ class Assets {
|
||||
static const String editNameSetting = "assets/icons/edit_name_setting.svg";
|
||||
|
||||
static const String verificationIcon = "assets/icons/verification_icon.svg";
|
||||
|
||||
static const String deleteAccountIcon='assets/icons/delete_account_icon.svg';
|
||||
static const String passwordUnvisibility =
|
||||
"assets/icons/password_unvisibility.svg";
|
||||
static const String passwordVisibility =
|
||||
|
@ -195,6 +195,7 @@ abstract class ApiEndpoints {
|
||||
static const String sendPicture = '/user/profile-picture/{userUuid}';
|
||||
static const String getRegion = '/region';
|
||||
static const String getTimezone = '/timezone';
|
||||
static const String deleteProfile = '/user';
|
||||
|
||||
//multiple-time offline
|
||||
static const String addMultipleTimeTemporaryPassword =
|
||||
|
@ -83,4 +83,11 @@ class AuthenticationAPI {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<void> deleteAccount() async {
|
||||
await HTTPService().delete(
|
||||
path: ApiEndpoints.deleteProfile,
|
||||
expectedResponseModel: (p0) {},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user