Feat: done implementation edit data for features change noId
This commit is contained in:
parent
b0eb48cbfe
commit
a44530f51d
|
@ -10,6 +10,14 @@ class SnackbarHelper {
|
||||||
message,
|
message,
|
||||||
backgroundColor: GreenColors.green500,
|
backgroundColor: GreenColors.green500,
|
||||||
colorText: Colors.white,
|
colorText: Colors.white,
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
duration: Duration(seconds: 3),
|
||||||
|
margin: EdgeInsets.all(10),
|
||||||
|
borderRadius: 8,
|
||||||
|
isDismissible: true,
|
||||||
|
forwardAnimationCurve: Curves.easeOutBack,
|
||||||
|
reverseAnimationCurve: Curves.easeInBack,
|
||||||
|
animationDuration: Duration(milliseconds: 800),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +27,14 @@ class SnackbarHelper {
|
||||||
message,
|
message,
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
colorText: Colors.white,
|
colorText: Colors.white,
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
duration: Duration(seconds: 3),
|
||||||
|
margin: EdgeInsets.all(10),
|
||||||
|
borderRadius: 8,
|
||||||
|
isDismissible: true,
|
||||||
|
forwardAnimationCurve: Curves.easeOutBack,
|
||||||
|
reverseAnimationCurve: Curves.easeInBack,
|
||||||
|
animationDuration: Duration(milliseconds: 800),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +42,14 @@ class SnackbarHelper {
|
||||||
Get.snackbar(
|
Get.snackbar(
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
|
snackPosition: SnackPosition.TOP,
|
||||||
|
duration: Duration(seconds: 3),
|
||||||
|
margin: EdgeInsets.all(10),
|
||||||
|
borderRadius: 8,
|
||||||
|
isDismissible: true,
|
||||||
|
forwardAnimationCurve: Curves.easeOutBack,
|
||||||
|
reverseAnimationCurve: Curves.easeInBack,
|
||||||
|
animationDuration: Duration(milliseconds: 800),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,7 @@ class ProfilRepositoryImpl implements ProfilRepository {
|
||||||
try {
|
try {
|
||||||
QuerySnapshot querySnapshot = await _firestore.collection('users').doc(userId).collection('passenger').get();
|
QuerySnapshot querySnapshot = await _firestore.collection('users').doc(userId).collection('passenger').get();
|
||||||
return querySnapshot.docs
|
return querySnapshot.docs
|
||||||
.map((doc) => PassengerModel.fromMap({
|
.map((doc) => PassengerModel.fromMap({'id': doc.id, ...doc.data() as Map<String, dynamic>}))
|
||||||
'id': doc.id,
|
|
||||||
...doc.data() as Map<String, dynamic>
|
|
||||||
}))
|
|
||||||
.toList();
|
.toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
rethrow;
|
||||||
|
@ -50,6 +47,7 @@ class ProfilRepositoryImpl implements ProfilRepository {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<UserData> getUserById(String userId) async {
|
Future<UserData> getUserById(String userId) async {
|
||||||
try {
|
try {
|
||||||
|
@ -119,6 +117,52 @@ class ProfilRepositoryImpl implements ProfilRepository {
|
||||||
await _firestore.collection('users').doc(user.uid).update({'phone': newPhone});
|
await _firestore.collection('users').doc(user.uid).update({'phone': newPhone});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> changeNoId({
|
||||||
|
required String oldPassword,
|
||||||
|
required String typeId,
|
||||||
|
required String noId,
|
||||||
|
}) async {
|
||||||
|
final user = FirebaseAuth.instance.currentUser;
|
||||||
|
if (user == null) {
|
||||||
|
throw Exception("User belum login");
|
||||||
|
}
|
||||||
|
|
||||||
|
final existingUserQuery =
|
||||||
|
await _firestore.collection('users').where('typeId', isEqualTo: typeId).where('noId', isEqualTo: noId).get();
|
||||||
|
|
||||||
|
if (existingUserQuery.docs.isNotEmpty) {
|
||||||
|
final isCurrentUser = existingUserQuery.docs.any((doc) => doc.id == user.uid);
|
||||||
|
if (!isCurrentUser) {
|
||||||
|
throw Exception("Nomor ID sudah digunakan oleh pengguna lain");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final allUsersQuery = await _firestore.collection('users').get();
|
||||||
|
for (final userDoc in allUsersQuery.docs) {
|
||||||
|
final passengerQuery = await _firestore
|
||||||
|
.collection('users')
|
||||||
|
.doc(userDoc.id)
|
||||||
|
.collection('passenger')
|
||||||
|
.where('typeId', isEqualTo: typeId)
|
||||||
|
.where('noId', isEqualTo: noId)
|
||||||
|
.get();
|
||||||
|
if (passengerQuery.docs.isNotEmpty) {
|
||||||
|
throw Exception("Nomor ID sudah digunakan oleh pengguna lain");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final cred = EmailAuthProvider.credential(
|
||||||
|
email: user.email!,
|
||||||
|
password: oldPassword,
|
||||||
|
);
|
||||||
|
await user.reauthenticateWithCredential(cred);
|
||||||
|
await _firestore.collection('users').doc(user.uid).update({
|
||||||
|
'typeId': typeId,
|
||||||
|
'noId': noId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// @override
|
// @override
|
||||||
// Future<void> changeEmail({
|
// Future<void> changeEmail({
|
||||||
// required String oldPassword,
|
// required String oldPassword,
|
||||||
|
|
|
@ -15,6 +15,7 @@ class ProfilBinding extends Bindings {
|
||||||
Get.lazyPut(() => GetUserByIdUseCase(Get.find()));
|
Get.lazyPut(() => GetUserByIdUseCase(Get.find()));
|
||||||
Get.lazyPut(() => ChangePasswordUseCase(Get.find()));
|
Get.lazyPut(() => ChangePasswordUseCase(Get.find()));
|
||||||
Get.lazyPut(() => ChangePhoneUseCase(Get.find()));
|
Get.lazyPut(() => ChangePhoneUseCase(Get.find()));
|
||||||
|
Get.lazyPut(() => ChangeNoIdUseCase(Get.find()));
|
||||||
Get.lazyPut(() => DeletePassengerUseCase(Get.find()));
|
Get.lazyPut(() => DeletePassengerUseCase(Get.find()));
|
||||||
Get.lazyPut(() => UpdatePassengerUseCase(Get.find()));
|
Get.lazyPut(() => UpdatePassengerUseCase(Get.find()));
|
||||||
// Get.lazyPut(() => ChangeEmailUseCase(Get.find()));
|
// Get.lazyPut(() => ChangeEmailUseCase(Get.find()));
|
||||||
|
@ -26,6 +27,7 @@ class ProfilBinding extends Bindings {
|
||||||
getUserByIdUseCase: Get.find(),
|
getUserByIdUseCase: Get.find(),
|
||||||
changePasswordUseCase: Get.find(),
|
changePasswordUseCase: Get.find(),
|
||||||
changePhoneUseCase: Get.find(),
|
changePhoneUseCase: Get.find(),
|
||||||
|
changeNoIdUseCase: Get.find(),
|
||||||
deletePassengerUseCase: Get.find(),
|
deletePassengerUseCase: Get.find(),
|
||||||
updatePassengerUseCase: Get.find(),
|
updatePassengerUseCase: Get.find(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -31,6 +31,12 @@ abstract class ProfilRepository {
|
||||||
required String newPhone,
|
required String newPhone,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Future<void> changeNoId({
|
||||||
|
required String oldPassword,
|
||||||
|
required String typeId,
|
||||||
|
required String noId,
|
||||||
|
});
|
||||||
|
|
||||||
// Future<void> changeEmail({
|
// Future<void> changeEmail({
|
||||||
// required String oldPassword,
|
// required String oldPassword,
|
||||||
// required String newEmail,
|
// required String newEmail,
|
||||||
|
|
|
@ -64,6 +64,23 @@ class ChangePhoneUseCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChangeNoIdUseCase {
|
||||||
|
final ProfilRepository profilRepository;
|
||||||
|
ChangeNoIdUseCase(this.profilRepository);
|
||||||
|
|
||||||
|
Future<void> call({
|
||||||
|
required String oldPassword,
|
||||||
|
required String typeId,
|
||||||
|
required String noId,
|
||||||
|
}) {
|
||||||
|
return profilRepository.changeNoId(
|
||||||
|
oldPassword: oldPassword,
|
||||||
|
typeId: typeId,
|
||||||
|
noId: noId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DeletePassengerUseCase {
|
class DeletePassengerUseCase {
|
||||||
final ProfilRepository profilRepository;
|
final ProfilRepository profilRepository;
|
||||||
DeletePassengerUseCase(this.profilRepository);
|
DeletePassengerUseCase(this.profilRepository);
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:e_porter/_core/service/preferences_service.dart';
|
||||||
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
||||||
import 'package:firebase_auth/firebase_auth.dart';
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../domain/models/user_entity.dart';
|
import '../../domain/models/user_entity.dart';
|
||||||
import '../../domain/usecases/profil_usecase.dart';
|
import '../../domain/usecases/profil_usecase.dart';
|
||||||
|
|
||||||
|
@ -13,6 +12,7 @@ class ProfilController extends GetxController {
|
||||||
final GetUserByIdUseCase getUserByIdUseCase;
|
final GetUserByIdUseCase getUserByIdUseCase;
|
||||||
final ChangePasswordUseCase changePasswordUseCase;
|
final ChangePasswordUseCase changePasswordUseCase;
|
||||||
final ChangePhoneUseCase changePhoneUseCase;
|
final ChangePhoneUseCase changePhoneUseCase;
|
||||||
|
final ChangeNoIdUseCase changeNoIdUseCase;
|
||||||
final DeletePassengerUseCase deletePassengerUseCase;
|
final DeletePassengerUseCase deletePassengerUseCase;
|
||||||
final UpdatePassengerUseCase updatePassengerUseCase;
|
final UpdatePassengerUseCase updatePassengerUseCase;
|
||||||
// final ChangeEmailUseCase changeEmailUseCase;
|
// final ChangeEmailUseCase changeEmailUseCase;
|
||||||
|
@ -22,6 +22,7 @@ class ProfilController extends GetxController {
|
||||||
var isLoading = false.obs;
|
var isLoading = false.obs;
|
||||||
var isChangingPassword = false.obs;
|
var isChangingPassword = false.obs;
|
||||||
var isChangingPhone = false.obs;
|
var isChangingPhone = false.obs;
|
||||||
|
var isChangingNoId = false.obs;
|
||||||
var isDeletingPassenger = false.obs;
|
var isDeletingPassenger = false.obs;
|
||||||
var isUpdatingPassenger = false.obs;
|
var isUpdatingPassenger = false.obs;
|
||||||
// var isChangingEmail = false.obs;
|
// var isChangingEmail = false.obs;
|
||||||
|
@ -32,6 +33,7 @@ class ProfilController extends GetxController {
|
||||||
required this.getUserByIdUseCase,
|
required this.getUserByIdUseCase,
|
||||||
required this.changePasswordUseCase,
|
required this.changePasswordUseCase,
|
||||||
required this.changePhoneUseCase,
|
required this.changePhoneUseCase,
|
||||||
|
required this.changeNoIdUseCase,
|
||||||
required this.deletePassengerUseCase,
|
required this.deletePassengerUseCase,
|
||||||
required this.updatePassengerUseCase,
|
required this.updatePassengerUseCase,
|
||||||
// required this.changeEmailUseCase,
|
// required this.changeEmailUseCase,
|
||||||
|
@ -206,6 +208,42 @@ class ProfilController extends GetxController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> changeNoId({
|
||||||
|
required String oldPassword,
|
||||||
|
required String typeId,
|
||||||
|
required String noId,
|
||||||
|
}) async {
|
||||||
|
isChangingNoId.value = true;
|
||||||
|
try {
|
||||||
|
await changeNoIdUseCase(
|
||||||
|
oldPassword: oldPassword,
|
||||||
|
typeId: typeId,
|
||||||
|
noId: noId,
|
||||||
|
);
|
||||||
|
|
||||||
|
await _loadProfile();
|
||||||
|
SnackbarHelper.showSuccess("Berhasil", "Nomor ID berhasil diperbarui.");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} on FirebaseAuthException catch (e) {
|
||||||
|
if (e.code == 'wrong-password' || e.code == 'invalid-credential') {
|
||||||
|
SnackbarHelper.showError("Gagal", "Password lama salah.");
|
||||||
|
} else {
|
||||||
|
SnackbarHelper.showError("Gagal", e.message ?? "Terjadi kesalahan.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.toString().contains("Nomor ID sudah digunakan oleh pengguna lain")) {
|
||||||
|
SnackbarHelper.showError("Gagal", "Nomor ID sudah digunakan oleh pengguna lain.");
|
||||||
|
} else {
|
||||||
|
SnackbarHelper.showError("Gagal", "Terjadi kesalahan: $e");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
isChangingNoId.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Future<bool> changeEmail({
|
// Future<bool> changeEmail({
|
||||||
// required String oldPassword,
|
// required String oldPassword,
|
||||||
// required String newEmail,
|
// required String newEmail,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
|
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
|
||||||
|
import 'package:e_porter/_core/component/button/button_fill.dart';
|
||||||
|
import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart';
|
||||||
import 'package:e_porter/_core/component/text/custom_text.dart';
|
import 'package:e_porter/_core/component/text/custom_text.dart';
|
||||||
import 'package:e_porter/_core/component/text_field/dropdown/dropdown_component.dart';
|
import 'package:e_porter/_core/component/text_field/dropdown/dropdown_component.dart';
|
||||||
import 'package:e_porter/_core/component/text_field/text_input/text_field_component.dart';
|
import 'package:e_porter/_core/component/text_field/text_input/text_field_component.dart';
|
||||||
|
@ -7,6 +9,7 @@ import 'package:e_porter/_core/constants/typography.dart';
|
||||||
import 'package:e_porter/_core/validators/validators.dart';
|
import 'package:e_porter/_core/validators/validators.dart';
|
||||||
import 'package:e_porter/presentation/screens/auth/component/Input_password.dart';
|
import 'package:e_porter/presentation/screens/auth/component/Input_password.dart';
|
||||||
import 'package:e_porter/presentation/screens/profile/component/header_information.dart';
|
import 'package:e_porter/presentation/screens/profile/component/header_information.dart';
|
||||||
|
import 'package:e_porter/presentation/controllers/profil_controller.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
@ -23,6 +26,7 @@ class _ChangeNoIdState extends State<ChangeNoId> {
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _oldPassword = TextEditingController();
|
final _oldPassword = TextEditingController();
|
||||||
final _noIdController = TextEditingController();
|
final _noIdController = TextEditingController();
|
||||||
|
final ProfilController _profilController = Get.find<ProfilController>();
|
||||||
|
|
||||||
String selectedTypeId = 'KTP';
|
String selectedTypeId = 'KTP';
|
||||||
@override
|
@override
|
||||||
|
@ -109,31 +113,38 @@ class _ChangeNoIdState extends State<ChangeNoId> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// bottomNavigationBar: Obx(
|
bottomNavigationBar: Obx(() {
|
||||||
// () {
|
return CustomeShadowCotainner(
|
||||||
// return CustomeShadowCotainner(
|
child: _profilController.isChangingNoId.value
|
||||||
// child: _authController.isChangingPhone.value
|
? Center(
|
||||||
// ? Center(
|
child: CircularProgressIndicator(color: PrimaryColors.primary800),
|
||||||
// child: CircularProgressIndicator(color: PrimaryColors.primary800),
|
)
|
||||||
// )
|
: ButtonFill(
|
||||||
// : ButtonFill(
|
text: 'Simpan',
|
||||||
// text: 'Simpan',
|
textColor: Colors.white,
|
||||||
// textColor: Colors.white,
|
onTap: () async {
|
||||||
// onTap: () async {
|
if (!_formKey.currentState!.validate()) return;
|
||||||
// if (!_formKey.currentState!.validate()) return;
|
final result = await _profilController.changeNoId(
|
||||||
// final result = await _authController.changePhone(
|
oldPassword: _oldPassword.text.trim(),
|
||||||
// oldPassword: _oldPassword.text.trim(),
|
noId: _noIdController.text.trim(),
|
||||||
// newPhone: _phoneNumber.text.trim(),
|
typeId: selectedTypeId);
|
||||||
// );
|
|
||||||
// if (result) {
|
if (result) {
|
||||||
// _oldPassword.clear();
|
_oldPassword.clear();
|
||||||
// _phoneNumber.clear();
|
_noIdController.clear();
|
||||||
// }
|
|
||||||
// },
|
await Future.delayed(Duration(milliseconds: 1500));
|
||||||
// ),
|
|
||||||
// );
|
if (Get.isSnackbarOpen) {
|
||||||
// },
|
Get.closeAllSnackbars();
|
||||||
// ),
|
await Future.delayed(Duration(milliseconds: 300));
|
||||||
|
}
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ChangeNumberScreen extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChangeNumberScreenState extends State<ChangeNumberScreen> {
|
class _ChangeNumberScreenState extends State<ChangeNumberScreen> {
|
||||||
final _authController = Get.find<ProfilController>();
|
final _profilController = Get.find<ProfilController>();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final _oldPassword = TextEditingController();
|
final _oldPassword = TextEditingController();
|
||||||
final _phoneNumber = TextEditingController();
|
final _phoneNumber = TextEditingController();
|
||||||
|
@ -78,7 +78,7 @@ class _ChangeNumberScreenState extends State<ChangeNumberScreen> {
|
||||||
bottomNavigationBar: Obx(
|
bottomNavigationBar: Obx(
|
||||||
() {
|
() {
|
||||||
return CustomeShadowCotainner(
|
return CustomeShadowCotainner(
|
||||||
child: _authController.isChangingPhone.value
|
child: _profilController.isChangingPhone.value
|
||||||
? Center(
|
? Center(
|
||||||
child: CircularProgressIndicator(color: PrimaryColors.primary800),
|
child: CircularProgressIndicator(color: PrimaryColors.primary800),
|
||||||
)
|
)
|
||||||
|
@ -87,7 +87,7 @@ class _ChangeNumberScreenState extends State<ChangeNumberScreen> {
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (!_formKey.currentState!.validate()) return;
|
if (!_formKey.currentState!.validate()) return;
|
||||||
final result = await _authController.changePhone(
|
final result = await _profilController.changePhone(
|
||||||
oldPassword: _oldPassword.text.trim(),
|
oldPassword: _oldPassword.text.trim(),
|
||||||
newPhone: _phoneNumber.text.trim(),
|
newPhone: _phoneNumber.text.trim(),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue