import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class AuthController extends GetxController { final FirebaseAuth _auth = FirebaseAuth.instance; var isLoading = false.obs; var user = Rxn(); @override void onInit() { super.onInit(); user.bindStream(_auth.authStateChanges()); // listen login/logout } // LOGIN Future login(String email, String password) async { try { isLoading.value = true; await _auth.signInWithEmailAndPassword( email: email.trim(), password: password.trim(), ); Get.snackbar( "Berhasil", "Login berhasil", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); Get.offAllNamed('/home'); } on FirebaseAuthException catch (e) { String message; switch (e.code) { case 'channel-error': message = 'Email dan password wajib diisi.'; break; case 'invalid-credential': message = 'Email atau password salah.'; break; default: message = 'Login gagal. Silakan coba lagi.'; } Get.snackbar( "Login Gagal", message, snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); } catch (e) { Get.snackbar( "Error", "Terjadi kesalahan sistem.", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); } finally { isLoading.value = false; } } // REGISTER Future register(String name, String email, String password) async { try { isLoading.value = true; await _auth.createUserWithEmailAndPassword( email: email.trim(), password: password.trim(), ).then((userCredential) async { await FirebaseFirestore.instance .collection('users') .doc(userCredential.user!.uid) .set({ "name": name.trim(), "email": email.trim(), "createdAt": DateTime.now(), }); }); Get.snackbar( "Berhasil", "Registrasi berhasil", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); Get.offAllNamed('/home'); } on FirebaseAuthException catch (e) { String message; switch (e.code) { case 'channel-error': message = 'Semua field wajib diisi.'; break; case 'invalid-email': message = 'Format email tidak valid.'; break; case 'email-already-in-use': message = 'Email sudah terdaftar.'; break; case 'weak-password': message = 'Password minimal 6 karakter.'; break; case 'network-request-failed': message = 'Tidak ada koneksi internet.'; break; default: message = 'Registrasi gagal. Silakan coba lagi.'; } Get.snackbar( "Registrasi Gagal", message, snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); } catch (e) { Get.snackbar( "Error", "Terjadi kesalahan sistem.", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); } finally { isLoading.value = false; } } // RESET PASSWORD Future resetPassword(String email) async { try { // ========================== // VALIDASI LOCAL // ========================== if (email.trim().isEmpty) { Get.snackbar( "Reset Password Gagal", "Email wajib diisi.", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); return; } if (!GetUtils.isEmail(email.trim())) { Get.snackbar( "Reset Password Gagal", "Format email tidak valid.", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); return; } // ========================== // KIRIM RESET EMAIL // ========================== await _auth.sendPasswordResetEmail(email: email.trim()); Get.snackbar( "Berhasil", "Jika email terdaftar, link reset password telah dikirim.", snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); } on FirebaseAuthException catch (e) { String message; switch (e.code) { case 'user-not-found': // Demi keamanan, sebaiknya jangan terlalu detail message = "Jika email terdaftar, link reset password telah dikirim."; break; case 'invalid-email': message = "Format email tidak valid."; break; case 'network-request-failed': message = "Tidak ada koneksi internet."; break; default: message = "Gagal mengirim email reset."; } Get.snackbar( "Reset Password", message, snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, ); } } // LOGOUT Future logout() async { await _auth.signOut(); Get.offAllNamed('/login'); } }