nao esta a funcionar o recycler view
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
|||||||
#Thu Mar 12 10:18:44 WET 2026
|
#Tue Apr 21 15:25:11 WEST 2026
|
||||||
gradle.version=9.3.1
|
gradle.version=9.4.1
|
||||||
|
|||||||
Binary file not shown.
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -1,6 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|||||||
@@ -109,9 +109,33 @@ public class DetalhePacienteActivity extends AppCompatActivity {
|
|||||||
tvNumeroUtente.setText("Nº Utente: " + (numUtente != null ? numUtente : "N/D"));
|
tvNumeroUtente.setText("Nº Utente: " + (numUtente != null ? numUtente : "N/D"));
|
||||||
tvSexo.setText("Sexo: " + (sexo != null ? sexo : "N/D"));
|
tvSexo.setText("Sexo: " + (sexo != null ? sexo : "N/D"));
|
||||||
tvEmail.setText("Email: " + (email != null ? email : "N/D"));
|
tvEmail.setText("Email: " + (email != null ? email : "N/D"));
|
||||||
tvMedicacao.setText(medicacao);
|
|
||||||
|
|
||||||
|
|
||||||
|
// Buscar medicação real na coleção 'medicamentos'
|
||||||
|
db.collection("medicamentos")
|
||||||
|
.whereEqualTo("userId", pacienteId)
|
||||||
|
.get()
|
||||||
|
.addOnSuccessListener(querySnapshot -> {
|
||||||
|
if (querySnapshot != null && !querySnapshot.isEmpty()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (com.google.firebase.firestore.DocumentSnapshot medDoc : querySnapshot.getDocuments()) {
|
||||||
|
// Tentar campos novos (PT) ou antigos (EN)
|
||||||
|
String medName = medDoc.getString("nome");
|
||||||
|
if (medName == null) medName = medDoc.getString("name");
|
||||||
|
|
||||||
|
String time = medDoc.getString("hora");
|
||||||
|
if (time == null) time = medDoc.getString("time");
|
||||||
|
|
||||||
|
if (medName != null) {
|
||||||
|
sb.append("• ").append(medName);
|
||||||
|
if (time != null) sb.append(" (").append(time).append(")");
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tvMedicacao.setText(sb.toString().trim());
|
||||||
|
} else {
|
||||||
|
tvMedicacao.setText("Nenhuma medicação ativa registada pelo paciente.");
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "No such document");
|
Log.d(TAG, "No such document");
|
||||||
Toast.makeText(DetalhePacienteActivity.this, "Paciente não encontrado", Toast.LENGTH_SHORT).show();
|
Toast.makeText(DetalhePacienteActivity.this, "Paciente não encontrado", Toast.LENGTH_SHORT).show();
|
||||||
|
|||||||
@@ -69,13 +69,13 @@ public class EditarPerfilActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void carregarDados() {
|
private void carregarDados() {
|
||||||
db.collection("medicos").document(currentUserId).get().addOnSuccessListener(doc -> {
|
db.collection("utilizadores").document(currentUserId).get().addOnSuccessListener(doc -> {
|
||||||
if (doc.exists()) {
|
if (doc.exists()) {
|
||||||
nameEditText.setText(doc.getString("nome"));
|
nameEditText.setText(doc.getString("nome_completo"));
|
||||||
specialtyEditText.setText(doc.getString("especialidade"));
|
specialtyEditText.setText(doc.getString("especialidade"));
|
||||||
emailEditText.setText(doc.getString("email"));
|
emailEditText.setText(doc.getString("email"));
|
||||||
|
|
||||||
String gender = doc.getString("gender");
|
String gender = doc.getString("sexo");
|
||||||
if (gender != null) {
|
if (gender != null) {
|
||||||
genderAutoComplete.setText(gender, false);
|
genderAutoComplete.setText(gender, false);
|
||||||
}
|
}
|
||||||
@@ -101,13 +101,17 @@ public class EditarPerfilActivity extends AppCompatActivity {
|
|||||||
btnGuardar.setEnabled(false);
|
btnGuardar.setEnabled(false);
|
||||||
|
|
||||||
Map<String, Object> updates = new HashMap<>();
|
Map<String, Object> updates = new HashMap<>();
|
||||||
updates.put("nome", name);
|
updates.put("nome_completo", name);
|
||||||
updates.put("especialidade", specialty);
|
updates.put("especialidade", specialty);
|
||||||
updates.put("gender", gender);
|
updates.put("sexo", gender);
|
||||||
|
|
||||||
db.collection("medicos").document(currentUserId)
|
// Atualizar em 'utilizadores'
|
||||||
|
db.collection("utilizadores").document(currentUserId)
|
||||||
.update(updates)
|
.update(updates)
|
||||||
.addOnSuccessListener(aVoid -> {
|
.addOnSuccessListener(aVoid -> {
|
||||||
|
// Também atualizar em 'medicos' para manter sincronizado
|
||||||
|
db.collection("medicos").document(currentUserId).update(updates);
|
||||||
|
|
||||||
Toast.makeText(EditarPerfilActivity.this, "Dados atualizados com sucesso!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(EditarPerfilActivity.this, "Dados atualizados com sucesso!", Toast.LENGTH_SHORT).show();
|
||||||
setResult(RESULT_OK);
|
setResult(RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements ConsultaAdapter.OnConsultaActionClickListener, ConsultaAdapter.OnConsultaClickListener {
|
public class MainActivity extends AppCompatActivity
|
||||||
|
implements ConsultaAdapter.OnConsultaActionClickListener, ConsultaAdapter.OnConsultaClickListener {
|
||||||
|
|
||||||
private View viewAgenda, viewPacientes, viewPerfil, layTop;
|
private View viewAgenda, viewPacientes, viewPerfil, layTop;
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
// Perfil
|
// Perfil
|
||||||
private TextView tvNome, tvEmail, tvEspecialidade, tvCedula;
|
private TextView tvNome, tvEmail, tvEspecialidade, tvCedula;
|
||||||
private MaterialButton btnLogout, btnEditarDados;
|
private MaterialButton btnLogout, btnEditarDados;
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
private TextView tvGreetingMain;
|
private TextView tvGreetingMain;
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -79,85 +80,91 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
|
|
||||||
currentMedicoId = mAuth.getCurrentUser().getUid();
|
currentMedicoId = mAuth.getCurrentUser().getUid();
|
||||||
|
|
||||||
// Bind Views
|
// Bind Views
|
||||||
viewAgenda = findViewById(R.id.view_agenda);
|
viewAgenda = findViewById(R.id.view_agenda);
|
||||||
viewPacientes = findViewById(R.id.view_pacientes);
|
viewPacientes = findViewById(R.id.view_pacientes);
|
||||||
viewPerfil = findViewById(R.id.view_perfil);
|
viewPerfil = findViewById(R.id.view_perfil);
|
||||||
layTop = findViewById(R.id.lay_top);
|
layTop = findViewById(R.id.lay_top);
|
||||||
|
|
||||||
tvGreetingMain = findViewById(R.id.tv_greeting_main);
|
|
||||||
|
|
||||||
// Bind Pacientes
|
tvGreetingMain = findViewById(R.id.tv_greeting_main);
|
||||||
recyclerConsultas = findViewById(R.id.recycler_consultas);
|
|
||||||
textEmptyState = findViewById(R.id.text_empty_state);
|
|
||||||
recyclerConsultas.setLayoutManager(new LinearLayoutManager(this));
|
|
||||||
adapterPacientes = new PacienteAdapter(paciente -> {
|
|
||||||
// Ação ao clicar no paciente (ex: abrir chat ou detalhes)
|
|
||||||
Intent intent = new Intent(MainActivity.this, DetalhePacienteActivity.class);
|
|
||||||
intent.putExtra("PACIENTE_ID", paciente.getId());
|
|
||||||
startActivity(intent);
|
|
||||||
});
|
|
||||||
recyclerConsultas.setAdapter(adapterPacientes);
|
|
||||||
|
|
||||||
// Bind Agenda
|
// Carregar nome da sessão local para exibir INSTANTANEAMENTE
|
||||||
recyclerAgenda = findViewById(R.id.recycler_agenda);
|
String cachedName = getSharedPreferences("SessaoMedico", MODE_PRIVATE).getString("nome_medico", "");
|
||||||
textAgendaVazia = findViewById(R.id.text_agenda_vazia);
|
if (!cachedName.isEmpty() && tvGreetingMain != null) {
|
||||||
CalendarView calendarView = findViewById(R.id.calendarView);
|
tvGreetingMain.setText("Olá, " + cachedName.split(" ")[0]);
|
||||||
recyclerAgenda.setLayoutManager(new LinearLayoutManager(this));
|
|
||||||
adapterAgenda = new ConsultaAdapter(this, consulta -> {
|
|
||||||
Intent intent = new Intent(MainActivity.this, DetalhePacienteActivity.class);
|
|
||||||
intent.putExtra("PACIENTE_ID", consulta.getPacienteId());
|
|
||||||
intent.putExtra("CONSULTA_ID", consulta.getId());
|
|
||||||
startActivity(intent);
|
|
||||||
});
|
|
||||||
recyclerAgenda.setAdapter(adapterAgenda);
|
|
||||||
|
|
||||||
// Bind Perfil
|
|
||||||
tvNome = findViewById(R.id.tv_nome_medico);
|
|
||||||
tvEmail = findViewById(R.id.tv_email_medico);
|
|
||||||
tvEspecialidade = findViewById(R.id.tv_especialidade);
|
|
||||||
tvCedula = findViewById(R.id.tv_cedula);
|
|
||||||
btnLogout = findViewById(R.id.btn_logout);
|
|
||||||
btnEditarDados = findViewById(R.id.btn_editar_dados);
|
|
||||||
|
|
||||||
btnEditarDados.setOnClickListener(v -> {
|
|
||||||
startActivity(new Intent(MainActivity.this, EditarPerfilActivity.class));
|
|
||||||
});
|
|
||||||
|
|
||||||
btnLogout.setOnClickListener(v -> {
|
|
||||||
mAuth.signOut();
|
|
||||||
Intent intent = new Intent(this, LoginActivity.class);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
|
||||||
startActivity(intent);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Setup BottomNavigation
|
|
||||||
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
|
||||||
bottomNav.setSelectedItemId(R.id.nav_agenda);
|
|
||||||
bottomNav.setOnItemSelectedListener(item -> {
|
|
||||||
viewAgenda.setVisibility(View.GONE);
|
|
||||||
viewPacientes.setVisibility(View.GONE);
|
|
||||||
viewPerfil.setVisibility(View.GONE);
|
|
||||||
layTop.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
if (item.getItemId() == R.id.nav_agenda) {
|
|
||||||
viewAgenda.setVisibility(View.VISIBLE);
|
|
||||||
layTop.setVisibility(View.VISIBLE);
|
|
||||||
return true;
|
|
||||||
} else if (item.getItemId() == R.id.nav_pacientes) {
|
|
||||||
viewPacientes.setVisibility(View.VISIBLE);
|
|
||||||
return true;
|
|
||||||
} else if (item.getItemId() == R.id.nav_perfil) {
|
|
||||||
viewPerfil.setVisibility(View.VISIBLE);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
});
|
// Bind Pacientes
|
||||||
|
recyclerConsultas = findViewById(R.id.recycler_consultas);
|
||||||
|
textEmptyState = findViewById(R.id.text_empty_state);
|
||||||
|
recyclerConsultas.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
adapterPacientes = new PacienteAdapter(paciente -> {
|
||||||
|
// Ação ao clicar no paciente (ex: abrir chat ou detalhes)
|
||||||
|
Intent intent = new Intent(MainActivity.this, DetalhePacienteActivity.class);
|
||||||
|
intent.putExtra("PACIENTE_ID", paciente.getId());
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
|
recyclerConsultas.setAdapter(adapterPacientes);
|
||||||
|
|
||||||
|
// Bind Agenda
|
||||||
|
recyclerAgenda = findViewById(R.id.recycler_agenda);
|
||||||
|
textAgendaVazia = findViewById(R.id.text_agenda_vazia);
|
||||||
|
CalendarView calendarView = findViewById(R.id.calendarView);
|
||||||
|
recyclerAgenda.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
adapterAgenda = new ConsultaAdapter(this, consulta -> {
|
||||||
|
Intent intent = new Intent(MainActivity.this, DetalhePacienteActivity.class);
|
||||||
|
intent.putExtra("PACIENTE_ID", consulta.getPacienteId());
|
||||||
|
intent.putExtra("CONSULTA_ID", consulta.getId());
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
|
recyclerAgenda.setAdapter(adapterAgenda);
|
||||||
|
|
||||||
|
// Bind Perfil
|
||||||
|
tvNome = findViewById(R.id.tv_nome_medico);
|
||||||
|
tvEmail = findViewById(R.id.tv_email_medico);
|
||||||
|
tvEspecialidade = findViewById(R.id.tv_especialidade);
|
||||||
|
tvCedula = findViewById(R.id.tv_cedula);
|
||||||
|
btnLogout = findViewById(R.id.btn_logout);
|
||||||
|
btnEditarDados = findViewById(R.id.btn_editar_dados);
|
||||||
|
|
||||||
|
btnEditarDados.setOnClickListener(v -> {
|
||||||
|
startActivity(new Intent(MainActivity.this, EditarPerfilActivity.class));
|
||||||
|
});
|
||||||
|
|
||||||
|
btnLogout.setOnClickListener(v -> {
|
||||||
|
mAuth.signOut();
|
||||||
|
Intent intent = new Intent(this, LoginActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup BottomNavigation
|
||||||
|
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
|
||||||
|
bottomNav.setSelectedItemId(R.id.nav_agenda);
|
||||||
|
bottomNav.setOnItemSelectedListener(item -> {
|
||||||
|
viewAgenda.setVisibility(View.GONE);
|
||||||
|
viewPacientes.setVisibility(View.GONE);
|
||||||
|
viewPerfil.setVisibility(View.GONE);
|
||||||
|
layTop.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
if (item.getItemId() == R.id.nav_agenda) {
|
||||||
|
viewAgenda.setVisibility(View.VISIBLE);
|
||||||
|
layTop.setVisibility(View.VISIBLE);
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.nav_pacientes) {
|
||||||
|
viewPacientes.setVisibility(View.VISIBLE);
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.nav_perfil) {
|
||||||
|
viewPerfil.setVisibility(View.VISIBLE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
// Load Initial Data
|
// Load Initial Data
|
||||||
loadUtilizadores();
|
loadUtilizadores();
|
||||||
loadPerfilMedico();
|
loadPerfilMedico();
|
||||||
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
|
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault());
|
||||||
String today = sdf.format(new Date());
|
String today = sdf.format(new Date());
|
||||||
TextView textAgendaInfoInit = findViewById(R.id.text_agenda_info);
|
TextView textAgendaInfoInit = findViewById(R.id.text_agenda_info);
|
||||||
@@ -174,8 +181,8 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
}
|
}
|
||||||
loadConsultasAgendaForDate(selectedDate);
|
loadConsultasAgendaForDate(selectedDate);
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
Toast.makeText(this, "Erro Init: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, "Erro Init: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +192,7 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
db.collection("utilizadores")
|
db.collection("utilizadores")
|
||||||
.addSnapshotListener((value, error) -> {
|
.addSnapshotListener((value, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
Toast.makeText(MainActivity.this, "Erro: " + error.getMessage(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(MainActivity.this, "Erro ao carregar pacientes", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Paciente> pacientesList = new ArrayList<>();
|
List<Paciente> pacientesList = new ArrayList<>();
|
||||||
@@ -194,14 +201,23 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
Paciente p = doc.toObject(Paciente.class);
|
Paciente p = doc.toObject(Paciente.class);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
p.setId(doc.getId());
|
p.setId(doc.getId());
|
||||||
// Garantir que o nome está preenchido
|
// Tenta 'nome_completo' primeiro, depois 'nome'
|
||||||
if (p.getNome() == null) p.setNome(doc.getString("nome"));
|
String nomeVal = doc.getString("nome_completo");
|
||||||
if (p.getEmail() == null) p.setEmail(doc.getString("email"));
|
if (nomeVal == null)
|
||||||
pacientesList.add(p);
|
nomeVal = doc.getString("nome");
|
||||||
|
p.setNome(nomeVal);
|
||||||
|
if (p.getEmail() == null)
|
||||||
|
p.setEmail(doc.getString("email"));
|
||||||
|
|
||||||
|
// Apenas adiciona se for realmente um paciente ou não tiver tipo definido
|
||||||
|
String tipo = doc.getString("tipo");
|
||||||
|
if (tipo == null || tipo.equalsIgnoreCase("paciente")) {
|
||||||
|
pacientesList.add(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pacientesList.isEmpty()) {
|
if (pacientesList.isEmpty()) {
|
||||||
textEmptyState.setVisibility(View.VISIBLE);
|
textEmptyState.setVisibility(View.VISIBLE);
|
||||||
recyclerConsultas.setVisibility(View.GONE);
|
recyclerConsultas.setVisibility(View.GONE);
|
||||||
@@ -225,7 +241,7 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
.addOnSuccessListener(aVoid -> Toast.makeText(this, "Consulta eliminada", Toast.LENGTH_SHORT).show())
|
.addOnSuccessListener(aVoid -> Toast.makeText(this, "Consulta eliminada", Toast.LENGTH_SHORT).show())
|
||||||
.addOnFailureListener(e -> Toast.makeText(this, "Erro ao eliminar", Toast.LENGTH_SHORT).show());
|
.addOnFailureListener(e -> Toast.makeText(this, "Erro ao eliminar", Toast.LENGTH_SHORT).show());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConsultaClick(Consulta consulta) {
|
public void onConsultaClick(Consulta consulta) {
|
||||||
Intent intent = new Intent(this, DetalhePacienteActivity.class);
|
Intent intent = new Intent(this, DetalhePacienteActivity.class);
|
||||||
@@ -237,79 +253,82 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
private void updateConsultaStatus(String consultaId, String newStatus) {
|
private void updateConsultaStatus(String consultaId, String newStatus) {
|
||||||
db.collection("consultas").document(consultaId)
|
db.collection("consultas").document(consultaId)
|
||||||
.update("status", newStatus)
|
.update("status", newStatus)
|
||||||
.addOnSuccessListener(aVoid -> Toast.makeText(this, "Consulta " + newStatus.toLowerCase(), Toast.LENGTH_SHORT).show())
|
.addOnSuccessListener(
|
||||||
.addOnFailureListener(e -> Toast.makeText(this, "Erro ao atualizar consulta", Toast.LENGTH_SHORT).show());
|
aVoid -> Toast.makeText(this, "Consulta " + newStatus.toLowerCase(), Toast.LENGTH_SHORT).show())
|
||||||
|
.addOnFailureListener(
|
||||||
|
e -> Toast.makeText(this, "Erro ao atualizar consulta", Toast.LENGTH_SHORT).show());
|
||||||
}
|
}
|
||||||
|
|
||||||
// AGENDA LOGIC
|
// AGENDA LOGIC
|
||||||
private com.google.firebase.firestore.ListenerRegistration agendaListener;
|
private com.google.firebase.firestore.ListenerRegistration agendaListener;
|
||||||
|
|
||||||
private void loadConsultasAgendaForDate(String dateStr) {
|
private void loadConsultasAgendaForDate(String dateStr) {
|
||||||
if(currentMedicoId == null) return;
|
if (currentMedicoId == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (agendaListener != null) {
|
if (agendaListener != null) {
|
||||||
agendaListener.remove();
|
agendaListener.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using a more robust query approach
|
|
||||||
agendaListener = db.collection("consultas")
|
agendaListener = db.collection("consultas")
|
||||||
.addSnapshotListener((value, error) -> {
|
.addSnapshotListener((value, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
Toast.makeText(MainActivity.this, "Erro Firebase: " + error.getMessage(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(MainActivity.this, "Erro Firebase: " + error.getMessage(), Toast.LENGTH_SHORT)
|
||||||
return;
|
.show();
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
if (value == null) return;
|
|
||||||
|
|
||||||
List<Consulta> consultasList = new ArrayList<>();
|
if (value == null)
|
||||||
String altDate = getAlternativeDate(dateStr);
|
return;
|
||||||
String isoDate = convertToISODate(dateStr);
|
|
||||||
|
|
||||||
for (QueryDocumentSnapshot doc : value) {
|
List<Consulta> consultasList = new ArrayList<>();
|
||||||
Consulta c = doc.toObject(Consulta.class);
|
String altDate = getAlternativeDate(dateStr);
|
||||||
if (c != null) {
|
String isoDate = convertToISODate(dateStr);
|
||||||
c.setId(doc.getId());
|
|
||||||
|
|
||||||
// Check if belongs to this doctor (handles both String and Array)
|
|
||||||
boolean belongsToDoctor = false;
|
|
||||||
Object med = c.getMedicos();
|
|
||||||
if (med instanceof String) {
|
|
||||||
belongsToDoctor = ((String) med).equals(currentMedicoId);
|
|
||||||
} else if (med instanceof List) {
|
|
||||||
belongsToDoctor = ((List<?>) med).contains(currentMedicoId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (belongsToDoctor) {
|
for (QueryDocumentSnapshot doc : value) {
|
||||||
String cData = c.getData() != null ? c.getData().trim() : "";
|
Consulta c = doc.toObject(Consulta.class);
|
||||||
if (cData.equals(dateStr) || cData.equals(altDate) || cData.equals(isoDate)) {
|
if (c != null) {
|
||||||
if (c.getStatus() == null || !"cancelada".equalsIgnoreCase(c.getStatus())) {
|
c.setId(doc.getId());
|
||||||
consultasList.add(c);
|
|
||||||
|
boolean belongsToDoctor = false;
|
||||||
|
Object med = c.getMedicos();
|
||||||
|
if (med instanceof String) {
|
||||||
|
belongsToDoctor = ((String) med).equals(currentMedicoId);
|
||||||
|
} else if (med instanceof List) {
|
||||||
|
belongsToDoctor = ((List<?>) med).contains(currentMedicoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (belongsToDoctor) {
|
||||||
|
String cData = c.getData() != null ? c.getData().trim() : "";
|
||||||
|
if (cData.equals(dateStr) || cData.equals(altDate) || cData.equals(isoDate)) {
|
||||||
|
if (c.getStatus() == null || !"cancelada".equalsIgnoreCase(c.getStatus())) {
|
||||||
|
consultasList.add(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
adapterAgenda.setConsultas(consultasList);
|
||||||
adapterAgenda.setConsultas(consultasList);
|
|
||||||
|
if (consultasList.isEmpty()) {
|
||||||
if (consultasList.isEmpty()) {
|
textAgendaVazia.setVisibility(View.VISIBLE);
|
||||||
textAgendaVazia.setVisibility(View.VISIBLE);
|
recyclerAgenda.setVisibility(View.GONE);
|
||||||
recyclerAgenda.setVisibility(View.GONE);
|
} else {
|
||||||
} else {
|
textAgendaVazia.setVisibility(View.GONE);
|
||||||
textAgendaVazia.setVisibility(View.GONE);
|
recyclerAgenda.setVisibility(View.VISIBLE);
|
||||||
recyclerAgenda.setVisibility(View.VISIBLE);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String convertToISODate(String ddMMyyyy) {
|
private String convertToISODate(String ddMMyyyy) {
|
||||||
try {
|
try {
|
||||||
String[] parts = ddMMyyyy.split("/");
|
String[] parts = ddMMyyyy.split("/");
|
||||||
if (parts.length == 3) {
|
if (parts.length == 3) {
|
||||||
// Return YYYY-MM-DD
|
|
||||||
return parts[2] + "-" + parts[1] + "-" + parts[0];
|
return parts[2] + "-" + parts[1] + "-" + parts[0];
|
||||||
}
|
}
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
return ddMMyyyy;
|
return ddMMyyyy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,19 +348,56 @@ public class MainActivity extends AppCompatActivity implements ConsultaAdapter.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PERFIL LOGIC
|
// PERFIL LOGIC
|
||||||
|
private com.google.firebase.firestore.ListenerRegistration perfilListener;
|
||||||
|
|
||||||
private void loadPerfilMedico() {
|
private void loadPerfilMedico() {
|
||||||
if(currentMedicoId == null) return;
|
if (currentMedicoId == null)
|
||||||
db.collection("medicos").document(currentMedicoId).get().addOnSuccessListener(doc -> {
|
return;
|
||||||
if (doc.exists()) {
|
|
||||||
String fetchedName = doc.getString("nome");
|
if (perfilListener != null)
|
||||||
tvNome.setText(fetchedName);
|
perfilListener.remove();
|
||||||
if (tvGreetingMain != null && fetchedName != null) {
|
|
||||||
tvGreetingMain.setText("Olá, " + fetchedName);
|
// Escuta em tempo real na coleção 'utilizadores'
|
||||||
}
|
perfilListener = db.collection("utilizadores").document(currentMedicoId)
|
||||||
tvEmail.setText(doc.getString("email"));
|
.addSnapshotListener((doc, error) -> {
|
||||||
tvEspecialidade.setText("Especialidade: " + doc.getString("especialidade"));
|
if (doc != null && doc.exists()) {
|
||||||
tvCedula.setText("Cédula: " + doc.getString("cedula_profissional"));
|
updateProfileUI(doc);
|
||||||
}
|
} else {
|
||||||
});
|
// Fallback para coleção 'medicos'
|
||||||
|
db.collection("medicos").document(currentMedicoId).get().addOnSuccessListener(docMed -> {
|
||||||
|
if (docMed.exists())
|
||||||
|
updateProfileUI(docMed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateProfileUI(DocumentSnapshot doc) {
|
||||||
|
String fetchedName = doc.getString("nome_completo");
|
||||||
|
if (fetchedName == null)
|
||||||
|
fetchedName = doc.getString("nome");
|
||||||
|
|
||||||
|
if (fetchedName != null) {
|
||||||
|
// Salvar na sessão local para carregamento instantâneo no futuro
|
||||||
|
getSharedPreferences("SessaoMedico", MODE_PRIVATE)
|
||||||
|
.edit()
|
||||||
|
.putString("nome_medico", fetchedName)
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
tvNome.setText(fetchedName != null ? fetchedName : "Médico");
|
||||||
|
if (tvGreetingMain != null) {
|
||||||
|
String displayName = (fetchedName != null) ? fetchedName
|
||||||
|
: getSharedPreferences("SessaoMedico", MODE_PRIVATE).getString("nome_medico", "Doutor");
|
||||||
|
tvGreetingMain.setText("Olá, " + displayName.split(" ")[0]);
|
||||||
|
}
|
||||||
|
tvEmail.setText(doc.getString("email"));
|
||||||
|
tvEspecialidade.setText(
|
||||||
|
"Especialidade: " + (doc.getString("especialidade") != null ? doc.getString("especialidade") : "--"));
|
||||||
|
|
||||||
|
String cedula = doc.getString("cedula_profissional");
|
||||||
|
if (cedula == null)
|
||||||
|
cedula = doc.getString("cedula");
|
||||||
|
tvCedula.setText("Cédula: " + (cedula != null ? cedula : "--"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,14 +74,36 @@ public class PerfilMedicoActivity extends AppCompatActivity {
|
|||||||
private void carregarPerfil() {
|
private void carregarPerfil() {
|
||||||
if (mAuth.getCurrentUser() != null) {
|
if (mAuth.getCurrentUser() != null) {
|
||||||
String uid = mAuth.getCurrentUser().getUid();
|
String uid = mAuth.getCurrentUser().getUid();
|
||||||
db.collection("medicos").document(uid).get().addOnSuccessListener(doc -> {
|
|
||||||
|
// Tentamos primeiro na coleção 'utilizadores'
|
||||||
|
db.collection("utilizadores").document(uid).get().addOnSuccessListener(doc -> {
|
||||||
if (doc.exists()) {
|
if (doc.exists()) {
|
||||||
tvNome.setText(doc.getString("nome"));
|
mostrarDados(doc);
|
||||||
tvEmail.setText(doc.getString("email"));
|
} else {
|
||||||
tvEspecialidade.setText("Especialidade: " + doc.getString("especialidade"));
|
// Se não existir em 'utilizadores', tentamos em 'medicos'
|
||||||
tvCedula.setText("Cédula: " + doc.getString("cedula_profissional"));
|
db.collection("medicos").document(uid).get().addOnSuccessListener(docMed -> {
|
||||||
|
if (docMed.exists()) {
|
||||||
|
mostrarDados(docMed);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).addOnFailureListener(e -> Toast.makeText(this, "Erro ao carregar perfil.", Toast.LENGTH_SHORT).show());
|
}).addOnFailureListener(e -> Toast.makeText(this, "Erro ao carregar perfil.", Toast.LENGTH_SHORT).show());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mostrarDados(com.google.firebase.firestore.DocumentSnapshot doc) {
|
||||||
|
// Tenta 'nome_completo' (novo) ou 'nome' (antigo)
|
||||||
|
String nome = doc.getString("nome_completo");
|
||||||
|
if (nome == null || nome.isEmpty()) nome = doc.getString("nome");
|
||||||
|
|
||||||
|
tvNome.setText(nome != null ? nome : "Utilizador sem nome");
|
||||||
|
tvEmail.setText(doc.getString("email"));
|
||||||
|
tvEspecialidade.setText("Especialidade: " + (doc.getString("especialidade") != null ? doc.getString("especialidade") : "--"));
|
||||||
|
|
||||||
|
// Tenta vários formatos de cédula que possam existir
|
||||||
|
String cedula = doc.getString("cedula_profissional");
|
||||||
|
if (cedula == null) cedula = doc.getString("cedula");
|
||||||
|
|
||||||
|
tvCedula.setText("Cédula: " + (cedula != null ? cedula : "Não configurada"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,23 +130,48 @@ public class RegisterActivity extends AppCompatActivity {
|
|||||||
saveMedicoData(user.getUid(), name, specialty, gender, email);
|
saveMedicoData(user.getUid(), name, specialty, gender, email);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "createUserWithEmail:failure", task.getException());
|
Exception e = task.getException();
|
||||||
Toast.makeText(RegisterActivity.this, "Falha no registo: " +
|
Log.w(TAG, "createUserWithEmail:failure", e);
|
||||||
(task.getException() != null ? task.getException().getMessage() : "Erro desconhecido"),
|
|
||||||
Toast.LENGTH_LONG).show();
|
if (e instanceof com.google.firebase.auth.FirebaseAuthUserCollisionException) {
|
||||||
registerButton.setEnabled(true);
|
// Se o utilizador já existe no Auth, tentamos fazer login e gravar os dados
|
||||||
|
// (caso tenham falhado da última vez)
|
||||||
|
mAuth.signInWithEmailAndPassword(email, password)
|
||||||
|
.addOnCompleteListener(loginTask -> {
|
||||||
|
if (loginTask.isSuccessful()) {
|
||||||
|
saveMedicoData(mAuth.getCurrentUser().getUid(), name, specialty, gender, email);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(RegisterActivity.this, "Este email já está registado. Tente fazer Login.", Toast.LENGTH_LONG).show();
|
||||||
|
registerButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Toast.makeText(RegisterActivity.this, "Falha no registo: " +
|
||||||
|
(e != null ? e.getMessage() : "Erro desconhecido"), Toast.LENGTH_LONG).show();
|
||||||
|
registerButton.setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveMedicoData(String uid, String name, String specialty, String gender, String email) {
|
private void saveMedicoData(String uid, String name, String specialty, String gender, String email) {
|
||||||
Medico medico = new Medico(uid, name, email, specialty, gender);
|
java.util.Map<String, Object> medicoMap = new java.util.HashMap<>();
|
||||||
|
medicoMap.put("id", uid);
|
||||||
|
medicoMap.put("nome_completo", name);
|
||||||
|
medicoMap.put("email", email);
|
||||||
|
medicoMap.put("especialidade", specialty);
|
||||||
|
medicoMap.put("sexo", gender);
|
||||||
|
medicoMap.put("tipo", "medico");
|
||||||
|
|
||||||
db.collection("medicos")
|
// Gravamos em 'utilizadores' como pedido
|
||||||
|
db.collection("utilizadores")
|
||||||
.document(uid)
|
.document(uid)
|
||||||
.set(medico)
|
.set(medicoMap)
|
||||||
.addOnCompleteListener(task -> {
|
.addOnCompleteListener(task -> {
|
||||||
if (task.isSuccessful()) {
|
if (task.isSuccessful()) {
|
||||||
|
// Também guardamos em 'medicos' para garantir que as outras partes da app funcionam
|
||||||
|
db.collection("medicos").document(uid).set(medicoMap);
|
||||||
|
|
||||||
Log.d(TAG, "saveMedicoData:success");
|
Log.d(TAG, "saveMedicoData:success");
|
||||||
Toast.makeText(RegisterActivity.this, "Registo efetuado com sucesso!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(RegisterActivity.this, "Registo efetuado com sucesso!", Toast.LENGTH_SHORT).show();
|
||||||
startActivity(new Intent(RegisterActivity.this, MainActivity.class));
|
startActivity(new Intent(RegisterActivity.this, MainActivity.class));
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
android:color="#400066CC">
|
<stroke android:width="1dp" android:color="?attr/colorPrimary" />
|
||||||
<item>
|
<corners android:radius="28dp" />
|
||||||
<shape android:shape="rectangle">
|
<solid android:color="@android:color/transparent" />
|
||||||
<solid android:color="@android:color/transparent" />
|
</shape>
|
||||||
<stroke android:width="2dp" android:color="@color/primary_color" />
|
|
||||||
<corners android:radius="8dp" />
|
|
||||||
</shape>
|
|
||||||
</item>
|
|
||||||
</ripple>
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '9.1.1' apply false
|
id 'com.android.application' version '9.2.0' apply false
|
||||||
id 'com.android.library' version '9.1.1' apply false
|
id 'com.android.library' version '9.2.0' apply false
|
||||||
id 'com.google.gms.google-services' version '4.4.4' apply false
|
id 'com.google.gms.google-services' version '4.4.4' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
Reference in New Issue
Block a user