Feat: done features forget password

This commit is contained in:
orangdeso 2025-05-11 20:47:36 +07:00
parent e7d36fdaac
commit c2f0d75a17
6 changed files with 84 additions and 13 deletions

View File

@ -115,4 +115,26 @@ class AuthRepositoryImpl implements AuthRepository {
}
return null;
}
@override
Future<void> sendPasswordResetEmail(String email) async {
try {
await _firebaseAuth.sendPasswordResetEmail(email: email);
} on FirebaseAuthException catch (e) {
throw AuthException(e.message ?? "Gagal mengirim email reset.");
}
}
@override
Future<void> confirmPasswordReset(String code, String newPassword) async {
try {
await _firebaseAuth.verifyPasswordResetCode(code);
await _firebaseAuth.confirmPasswordReset(
code: code,
newPassword: newPassword,
);
} on FirebaseAuthException catch (e) {
throw AuthException(e.message ?? "Gagal mengganti password.");
}
}
}

View File

@ -15,6 +15,8 @@ class AuthBinding extends Bindings {
final getUserDataUseCase = GetUserDataUseCase(authRepository);
final registerUseCase = RegisterUseCase(authRepository);
final saveUserDataUseCase = SaveUserDataUseCase(authRepository);
final sendResetEmailUseCase = SendResetEmailUseCase(authRepository);
final confirmResetPasswordUseCase = ConfirmResetPasswordUseCase(authRepository);
Get.put<AuthController>(
AuthController(
@ -23,6 +25,8 @@ class AuthBinding extends Bindings {
getUserDataUseCase: getUserDataUseCase,
registerUseCase: registerUseCase,
saveUserDataUseCase: saveUserDataUseCase,
sendResetEmailUseCase: sendResetEmailUseCase,
confirmResetPasswordUseCase: confirmResetPasswordUseCase,
),
);
}

View File

@ -9,4 +9,8 @@ abstract class AuthRepository {
Future<UserEntity> registerWithEmailPassword(String email, String password);
Future<void> saveUserData(UserData userData);
Future<void> sendPasswordResetEmail(String email);
Future<void> confirmPasswordReset(String code, String newPassword);
}

View File

@ -48,3 +48,15 @@ class SaveUserDataUseCase {
return await authRepository.saveUserData(userData);
}
}
class SendResetEmailUseCase {
final AuthRepository repo;
SendResetEmailUseCase(this.repo);
Future<void> call(String email) => repo.sendPasswordResetEmail(email);
}
class ConfirmResetPasswordUseCase {
final AuthRepository repo;
ConfirmResetPasswordUseCase(this.repo);
Future<void> call(String code, String newPassword) => repo.confirmPasswordReset(code, newPassword);
}

View File

@ -16,6 +16,8 @@ class AuthController extends GetxController {
final GetUserDataUseCase getUserDataUseCase;
final RegisterUseCase registerUseCase;
final SaveUserDataUseCase saveUserDataUseCase;
final SendResetEmailUseCase sendResetEmailUseCase;
final ConfirmResetPasswordUseCase confirmResetPasswordUseCase;
final emailController = TextEditingController();
final passwordController = TextEditingController();
@ -29,6 +31,8 @@ class AuthController extends GetxController {
required this.getUserDataUseCase,
required this.registerUseCase,
required this.saveUserDataUseCase,
required this.sendResetEmailUseCase,
required this.confirmResetPasswordUseCase,
});
Future<void> login({String? roleFromOnboarding}) async {
@ -83,7 +87,7 @@ class AuthController extends GetxController {
"Login Gagal",
"Email atau password anda salah.",
);
}
}
} catch (e) {
SnackbarHelper.showError("Terjadi Kesalahan", e.toString());
} finally {
@ -200,13 +204,28 @@ class AuthController extends GetxController {
}
}
// void _showErrorSnackbar(String title, String message) {
// Get.snackbar(
// title,
// message,
// snackPosition: SnackPosition.TOP,
// backgroundColor: Colors.red,
// colorText: Colors.white,
// );
// }
Future<void> sendResetEmail(String email) async {
try {
await sendResetEmailUseCase(email.trim());
SnackbarHelper.showSuccess(
"Silahkan Cek Email",
"Link reset password telah dikirim ke $email.",
);
} on AuthException catch (e) {
SnackbarHelper.showError("Gagal", e.message);
}
}
Future<void> resetPassword(String code, String newPassword) async {
try {
await confirmResetPasswordUseCase(code, newPassword);
SnackbarHelper.showSuccess(
"Berhasil",
"Password berhasil diubah. Silakan login kembali.",
);
Get.offAllNamed(Routes.LOGIN);
} on AuthException catch (e) {
SnackbarHelper.showError("Gagal", e.message);
}
}
}

View File

@ -1,5 +1,8 @@
import 'package:e_porter/_core/component/button/button_fill.dart';
import 'package:e_porter/_core/component/button/button_no_fill.dart';
import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart';
import 'package:e_porter/_core/validators/validators.dart';
import 'package:e_porter/presentation/controllers/auth_controller.dart';
import 'package:e_porter/presentation/screens/auth/component/header_text.dart';
import 'package:e_porter/presentation/screens/routes/app_rountes.dart';
import 'package:flutter/material.dart';
@ -23,6 +26,7 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
final String? role = Get.arguments as String;
final TextEditingController emailController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final authController = Get.find<AuthController>();
@override
Widget build(BuildContext context) {
@ -57,6 +61,7 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
controller: emailController,
hintText: 'example@gmail.com',
svgIconPath: 'assets/icons/ic_email.svg',
validator: Validators.validatorEmail,
),
],
),
@ -64,8 +69,7 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
),
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
bottomNavigationBar: CustomeShadowCotainner(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -73,7 +77,13 @@ class _ForgetPasswordScreenState extends State<ForgetPasswordScreen> {
child: ButtonFill(
text: 'Atur Ulang Password',
textColor: Colors.white,
onTap: () {},
onTap: () {
if (_formKey.currentState!.validate()) {
authController.sendResetEmail(emailController.text);
Get.offAllNamed(Routes.LOGIN, arguments: role);
emailController.clear();
}
},
),
),
SizedBox(height: 10.h),