v1.1.27 deactivate customer

This commit is contained in:
Tibor Bossanyi (Freelancer) 2022-11-26 16:46:06 +01:00
parent dbdcf2f239
commit 98901f2770
10 changed files with 116 additions and 9 deletions

View File

@ -6,6 +6,8 @@ import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import '../../service/customer_service.dart';
part 'account_event.dart';
part 'account_state.dart';
@ -21,6 +23,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
on<AccountLogout>(_onLogout);
on<AccountGetTrainees>(_onGetTrainees);
on<AccountSelectTrainee>(_onSelectTrainees);
on<DeleteAccount>(_onDeleteAccount);
}
void _load() {
@ -56,6 +59,24 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
emit(AccountReady());
}
void _onDeleteAccount(DeleteAccount event, Emitter<AccountState> emit) async {
emit(AccountLoading());
await Cache().logout();
customerRepository.customer = event.customer;
customerRepository.emptyTrainees();
loggedIn = false;
//delete local store
int customerId = customerRepository.customer!.customerId!;
await Cache().deleteCustomerId(customerId);
customerRepository.customer = null;
// deactivate user
await CustomerApi().deactivateCustomer(customerId);
emit(AccountReady());
}
void _onGetTrainees(AccountGetTrainees event, Emitter<AccountState> emit) async {
emit(AccountLoading());
await customerRepository.getTrainees();

View File

@ -20,6 +20,14 @@ class AccountLogin extends AccountEvent {
const AccountLogin();
}
class DeleteAccount extends AccountEvent {
final Customer customer;
const DeleteAccount ({required this.customer});
@override
List<Object> get props => [customer];
}
class AccountLogInFinished extends AccountEvent {
final Customer customer;

View File

@ -95,6 +95,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
Cache().setLoginType(LoginType.email);
emit(LoginSuccess());
} on Exception catch (e) {
print("Login error: $e" );
emit(LoginError(message: e.toString()));
}
}

View File

@ -212,6 +212,12 @@ class Cache with Logging {
return this.authToken;
}
Future<void> deleteCustomerId(int customerId) async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs;
sharedPreferences.remove(Cache.customerIdKey);
}
Future<void> saveActiveExercisePlan(ExercisePlan exercisePlan, List<ExercisePlanDetail> exercisePlanDetails) async {
this.activeExercisePlan = exercisePlan;
this.activeExercisePlanDetails = exercisePlanDetails;

View File

@ -204,12 +204,15 @@ class UserRepository with Logging {
Future<void> getUser() async {
final User modelUser = this.user;
String rc = await FirebaseApi().signInEmail(modelUser.email, modelUser.password);
if (rc == FirebaseApi.SIGN_IN_OK) {
await CustomerApi().getUserByEmail(modelUser.email!);
await Cache().afterFirebaseLogin();
} else {
log("Exception: user not found or password is wrong");
try {
if (rc == FirebaseApi.SIGN_IN_OK) {
await CustomerApi().getUserByEmail(modelUser.email!);
await Cache().afterFirebaseLogin();
} else {
log("Exception: user not found or password is wrong");
throw Exception("Customer does not exist or the password is wrong");
}
} on NotFoundException catch (_) {
throw Exception("Customer does not exist or the password is wrong");
}
}

View File

@ -92,6 +92,8 @@ class APIClient with Common, Logging {
} else {
throw Exception("Network Error, please try again later");
}
} on NotFoundException catch(e) {
throw NotFoundException(message: "Not Found");
} on Exception catch (e) {
print("Post Exception: $e");
await Sentry.captureException(e);
@ -128,6 +130,8 @@ class APIClient with Common, Logging {
} else {
throw Exception("Network Error, please try again later");
}
} on NotFoundException catch(e) {
throw NotFoundException(message: "Not Found");
} on Exception catch (e) {
print("Post Exception: $e");
await Sentry.captureException(e);

View File

@ -32,6 +32,11 @@ class CustomerApi with Logging {
await _client.post("customers/update_firebase_uid/" + customerId.toString(), uid);
}
Future<void> deactivateCustomer(int customerId) async {
log(" ===== deactivate : $customerId");
await _client.post("customers/deactivate/$customerId", "");
}
Future<void> addCustomer(Customer customer) async {
customer.dateAdd = DateTime.now();
customer.dateChange = DateTime.now();
@ -80,7 +85,7 @@ class CustomerApi with Logging {
final String responseBody = await _client.get("customers/find_by_email/" + email, "");
Customer customer;
try {
customer = Customer.fromJson(jsonDecode(responseBody));
customer = Customer.fromJson(jsonDecode(responseBody));
if (customer.firebaseUid == null) {
await this.updateFirebaseUid(customer.customerId!, Cache().firebaseUid!);
}

View File

@ -53,6 +53,7 @@ enum TrackingEvent {
tutorial_activate,
terms_of_use,
data_privacy,
delete_account,
faq,
training_plan_open,
training_plan_start,
@ -60,7 +61,7 @@ enum TrackingEvent {
training_plan_finished,
training_plan_custom,
trial,
feedback_email
feedback_email,
}
T enumFromString<T>(Iterable<T> values, String value) {

View File

@ -14,6 +14,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
import '../util/enums.dart';
import '../util/track.dart';
// ignore: must_be_immutable
class AccountPage extends StatelessWidget with Trans {
// ignore: close_sinks
@ -152,6 +155,9 @@ class AccountPage extends StatelessWidget with Trans {
),
devices(context, accountBloc),
loginOut(context, accountBloc),
Divider(),
Divider(),
deleteAccount(accountBloc),
//messaging(),
//getMyTrainees(context, accountBloc),
]);
@ -241,6 +247,29 @@ class AccountPage extends StatelessWidget with Trans {
return element;
}
ListTile deleteAccount(AccountBloc accountBloc) {
return ListTile(
leading: Icon(Icons.delete_forever),
title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(t("Delete Account"), style: TextStyle(color: Color.fromARGB(255, 202, 10, 10))),
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white70,
disabledForegroundColor: Colors.grey,
),
onPressed: () => {
if (accountBloc.loggedIn)
{
deleteAccountConfirmationDialog(accountBloc),
}
},
),
);
}
Widget getMyTrainees(BuildContext context, AccountBloc accountBloc) {
if (accountBloc.customerRepository.customer == null || accountBloc.customerRepository.customer!.trainer == 0) {
return ListTile(
@ -303,6 +332,35 @@ class AccountPage extends StatelessWidget with Trans {
));
}
void deleteAccountConfirmationDialog(AccountBloc accountBloc) {
showCupertinoDialog(
useRootNavigator: true,
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text(t("Are you sure to delete your account?")),
content: Column(children: [
Divider(),
Text(t("Your training data, historical data, goals, 1RMs will be completly lost!")),
]),
actions: [
TextButton(
child: Text(t("No")),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text(t("Yes")),
onPressed: () => {
if (accountBloc.customerRepository.customer != null && accountBloc.customerRepository.customer!.customerId != null) {
Track().track(TrackingEvent.delete_account),
accountBloc.add(DeleteAccount(customer: accountBloc.customerRepository.customer!)),
},
Navigator.pop(context),
},
)
],
));
}
void confirmationDialog(AccountBloc accountBloc) {
showCupertinoDialog(
useRootNavigator: true,

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.27+115
version: 1.1.27+116
environment:
sdk: ">=2.18.4 <3.0.0"