Files
BemPAP/app/src/main/java/com/example/bem/LoginActivity.java
2026-01-27 22:23:45 +00:00

346 lines
14 KiB
Java

package com.example.bem;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
public class LoginActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseFirestore db;
private SharedPreferences prefs;
private static final String PREF_DARK_MODE = "dark_mode";
private EditText inputEmail;
private EditText inputPassword;
private EditText inputName;
private EditText inputPhone;
private Button btnLogin;
private TextView textLoginType;
private TextView textSwitchMode;
private TextView textForgotPassword;
private TextView textSwitchToGuardian;
private ProgressBar progressBar;
private boolean isRegisterMode = false;
private boolean isGuardianMode = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
applyThemeFromPrefs();
mAuth = FirebaseAuth.getInstance();
db = FirebaseFirestore.getInstance();
if (mAuth.getCurrentUser() != null) {
mAuth.signOut();
}
setContentView(R.layout.activity_login);
inputEmail = findViewById(R.id.inputEmail);
inputPassword = findViewById(R.id.inputPassword);
inputName = findViewById(R.id.inputName);
inputPhone = findViewById(R.id.inputPhone);
btnLogin = findViewById(R.id.btnLogin);
textLoginType = findViewById(R.id.textLoginType);
textSwitchMode = findViewById(R.id.textSwitchMode);
textForgotPassword = findViewById(R.id.textForgotPassword);
textSwitchToGuardian = findViewById(R.id.textSwitchToGuardian);
btnLogin.setOnClickListener(v -> handleLogin());
textSwitchMode.setOnClickListener(v -> toggleMode());
textForgotPassword.setOnClickListener(v -> showForgotPasswordDialog());
textSwitchToGuardian.setOnClickListener(v -> switchToGuardianMode());
}
private void switchToGuardianMode() {
isGuardianMode = !isGuardianMode;
if (isGuardianMode) {
textLoginType.setText("Login de Responsável");
textSwitchToGuardian.setText("👤 Sou Utilizador");
inputPhone.setVisibility(View.VISIBLE);
inputPhone.setHint("Número de telemóvel");
} else {
textLoginType.setText("Login de Utilizador");
textSwitchToGuardian.setText("🔒 Sou Responsável");
inputPhone.setVisibility(View.GONE);
}
isRegisterMode = false;
updateUI();
}
private void toggleMode() {
isRegisterMode = !isRegisterMode;
updateUI();
}
private void updateUI() {
if (isRegisterMode) {
btnLogin.setText("Criar Conta");
textSwitchMode.setText("Já tem conta? Entrar");
inputName.setVisibility(View.VISIBLE);
if (isGuardianMode) {
inputPhone.setVisibility(View.VISIBLE);
}
} else {
btnLogin.setText("Entrar");
textSwitchMode.setText("Não tem conta? Registar");
inputName.setVisibility(View.GONE);
if (!isGuardianMode) {
inputPhone.setVisibility(View.GONE);
}
}
}
private void handleLogin() {
String email = inputEmail.getText().toString().trim();
String password = inputPassword.getText().toString().trim();
String name = inputName.getText().toString().trim();
String phone = inputPhone.getText().toString().trim();
if (TextUtils.isEmpty(email)) {
inputEmail.setError("Insira o email");
return;
}
if (!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
inputEmail.setError("Email inválido");
return;
}
if (TextUtils.isEmpty(password)) {
inputPassword.setError("Insira a palavra-passe");
return;
}
if (password.length() < 6) {
inputPassword.setError("Mínimo 6 caracteres");
return;
}
if (isRegisterMode && TextUtils.isEmpty(name)) {
inputName.setError("Insira o nome");
return;
}
btnLogin.setEnabled(false);
if (isRegisterMode) {
registerUser(email, password, name, phone);
} else {
loginUser(email, password);
}
}
private void registerUser(String email, String password, String name, String phone) {
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
saveUserData(user.getUid(), email, name, phone, true);
} else {
btnLogin.setEnabled(true);
Toast.makeText(this, "Erro ao obter utilizador. Tente entrar com o email/senha.",
Toast.LENGTH_LONG).show();
mAuth.signOut();
}
} else {
btnLogin.setEnabled(true);
String error = task.getException() != null ? task.getException().getMessage()
: "Erro desconhecido";
Toast.makeText(this, "Erro: " + error, Toast.LENGTH_LONG).show();
}
});
}
private void saveUserData(String uid, String email, String name, String phone, boolean fromRegister) {
Map<String, Object> userData = new HashMap<>();
userData.put("email", email);
userData.put("name", name);
userData.put("phone", phone != null ? phone : "");
userData.put("type", isGuardianMode ? "guardian" : "user");
userData.put("createdAt", System.currentTimeMillis());
db.collection("users").document(uid)
.set(userData)
.addOnSuccessListener(aVoid -> {
if (fromRegister) {
Toast.makeText(this, "✓ Conta criada! Faça login para continuar.", Toast.LENGTH_LONG).show();
mAuth.signOut();
btnLogin.setEnabled(true);
// Recarrega a tela limpa
Intent intent = getIntent();
finish();
startActivity(intent);
} else {
redirectToApp();
}
})
.addOnFailureListener(e -> {
btnLogin.setEnabled(true);
Toast.makeText(this, "Erro ao salvar dados: " + e.getMessage(), Toast.LENGTH_LONG).show();
});
}
private void loginUser(String email, String password) {
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
checkUserTypeAndRedirect(user.getUid());
} else {
btnLogin.setEnabled(true);
Toast.makeText(this, "Erro ao iniciar sessão. Tente novamente.", Toast.LENGTH_LONG).show();
}
} else {
btnLogin.setEnabled(true);
String error = task.getException() != null ? task.getException().getMessage()
: "Credenciais inválidas";
Toast.makeText(this, "Erro: " + error, Toast.LENGTH_LONG).show();
}
});
}
private void checkUserTypeAndRedirect(String uid) {
db.collection("users").document(uid)
.get()
.addOnSuccessListener(document -> {
if (document.exists()) {
String type = document.getString("type");
prefs.edit()
.putString("user_type", type != null ? type : "user")
.putString("user_name", document.getString("name"))
.apply();
if ("guardian".equals(type)) {
java.util.List<String> managedUsers = (java.util.List<String>) document.get("managedUsers");
if (managedUsers != null && !managedUsers.isEmpty()) {
redirectToApp();
} else {
Intent intent = new Intent(LoginActivity.this, InviteCodeActivity.class);
intent.putExtra("is_guardian", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
} else {
redirectToApp();
}
} else {
// Se o perfil não existe, cria um com base no modo de login atual.
FirebaseUser user = mAuth.getCurrentUser();
String email = user != null ? user.getEmail() : "";
String name = (email != null && email.contains("@")) ? email.substring(0, email.indexOf("@")) : "Utilizador";
String userType = isGuardianMode ? "guardian" : "user";
Map<String, Object> userData = new HashMap<>();
userData.put("email", email);
userData.put("name", name);
userData.put("phone", "");
userData.put("type", userType);
userData.put("createdAt", System.currentTimeMillis());
db.collection("users").document(uid)
.set(userData)
.addOnSuccessListener(aVoid -> {
prefs.edit()
.putString("user_type", userType)
.putString("user_name", name)
.apply();
if ("guardian".equals(userType)) {
Intent intent = new Intent(LoginActivity.this, InviteCodeActivity.class);
intent.putExtra("is_guardian", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
} else {
redirectToApp();
}
})
.addOnFailureListener(e -> {
Toast.makeText(this, "Erro ao criar perfil: " + e.getMessage(), Toast.LENGTH_SHORT).show();
btnLogin.setEnabled(true);
});
}
})
.addOnFailureListener(e -> {
Toast.makeText(this, "Erro ao carregar dados do utilizador: " + e.getMessage(), Toast.LENGTH_SHORT).show();
btnLogin.setEnabled(true);
});
}
private void redirectToApp() {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
private void showForgotPasswordDialog() {
View dialogView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null);
EditText emailInput = new EditText(this);
emailInput.setHint("Email de recuperação");
emailInput.setInputType(android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
emailInput.setPadding(50, 40, 50, 40);
new AlertDialog.Builder(this)
.setTitle("Recuperar Palavra-passe")
.setMessage("Insira o email para receber o link de recuperação:")
.setView(emailInput)
.setPositiveButton("Enviar", (dialog, which) -> {
String email = emailInput.getText().toString().trim();
if (TextUtils.isEmpty(email)) {
Toast.makeText(this, "Insira um email", Toast.LENGTH_SHORT).show();
return;
}
mAuth.sendPasswordResetEmail(email)
.addOnSuccessListener(aVoid -> {
Toast.makeText(this, "✓ Email enviado! Verifique a caixa de entrada.",
Toast.LENGTH_LONG).show();
})
.addOnFailureListener(e -> {
Toast.makeText(this, "Erro: " + e.getMessage(), Toast.LENGTH_LONG).show();
});
})
.setNegativeButton("Cancelar", null)
.show();
}
private void applyThemeFromPrefs() {
boolean dark = getSharedPreferences("app_prefs", MODE_PRIVATE).getBoolean(PREF_DARK_MODE, false);
AppCompatDelegate
.setDefaultNightMode(dark ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
}
}