Files
cuidamais_med/docs/01_MainActivity.md
2026-04-22 12:41:12 +01:00

166 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🏠 MainActivity.java — Ecrã Principal
> **Ficheiro:** `app/src/main/java/com/example/medcuida/pro/MainActivity.java`
> **Layout:** `activity_main.xml`
> **Linhas de código:** 404
---
## Descrição Geral
A `MainActivity` é o **ecrã central da aplicação**. Funciona como um painel de controlo do médico, com **3 secções** controladas por uma `BottomNavigationView`:
| Tab | Conteúdo |
|---|---|
| 📅 **Agenda** | Calendário + lista de consultas do dia selecionado |
| 👥 **Pacientes** | Lista de todos os pacientes registados |
| 👤 **Perfil** | Dados do médico (nome, email, especialidade, cédula) |
---
## Inicialização (`onCreate`) — Linhas 59188
### 1. Configuração do Layout (Linhas 6369)
```java
setContentView(R.layout.activity_main);
```
- Carrega o layout XML
- Envolto em `try-catch` para capturar erros de inflação da view
### 2. Verificação de Autenticação (Linhas 7179)
```java
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(this, LoginActivity.class));
finish();
return;
}
```
- Se o utilizador **não está autenticado**, redireciona para o `LoginActivity`
- Obtém o `uid` do médico atual para filtrar dados
### 3. Carregamento do Nome em Cache (Linhas 9195)
```java
String cachedName = getSharedPreferences("SessaoMedico", MODE_PRIVATE).getString("nome_medico", "");
```
- Lê o nome do médico das `SharedPreferences` para **exibição instantânea** (sem esperar pelo Firestore)
- Mostra "Olá, [Primeiro Nome]" no topo
### 4. Configuração dos Pacientes (Linhas 97107)
- Cria um `RecyclerView` com `PacienteAdapter`
- Ao clicar num paciente → abre `DetalhePacienteActivity`
### 5. Configuração da Agenda (Linhas 109120)
- Cria um `RecyclerView` com `ConsultaAdapter`
- Ao clicar numa consulta → abre `DetalhePacienteActivity` com ID da consulta
### 6. Configuração do Perfil (Linhas 122139)
- Associa os `TextView` do perfil (nome, email, especialidade, cédula)
- **Botão "Editar Dados"** → abre `EditarPerfilActivity`
- **Botão "Logout"** → faz sign out e redireciona para login
### 7. Bottom Navigation (Linhas 141162)
```java
bottomNav.setOnItemSelectedListener(item -> {
// Esconde todas as views
// Mostra apenas a view selecionada
});
```
- Controla a visibilidade das 3 secções (Agenda, Pacientes, Perfil)
- A tab **Agenda** é a selecionada por defeito
### 8. Carregamento de Dados (Linhas 164183)
- Chama `loadUtilizadores()` para carregar pacientes
- Chama `loadPerfilMedico()` para carregar o perfil
- Configura o `CalendarView` para filtrar consultas por data
---
## Lógica dos Pacientes — Linhas 190230
### `loadUtilizadores()`
```java
db.collection("utilizadores").addSnapshotListener(...)
```
**O que faz:**
1. Escuta **em tempo real** a coleção `utilizadores` no Firestore
2. Para cada documento:
- Converte para objeto `Paciente`
- Tenta o campo `nome_completo`, depois `nome` como fallback
- Filtra: apenas inclui se `tipo` for `"paciente"` ou não estiver definido
3. Atualiza o `RecyclerView` ou mostra mensagem "vazio"
---
## Ações nas Consultas — Linhas 232260
### `onAceitarClick(Consulta)` — Linha 233
- Atualiza o campo `status` da consulta para `"aceite"` no Firestore
### `onEliminarClick(Consulta)` — Linha 238
- **Elimina** o documento da consulta do Firestore
### `onConsultaClick(Consulta)` — Linha 246
- Abre o `DetalhePacienteActivity` com os IDs do paciente e da consulta
### `updateConsultaStatus()` — Linha 253
- Método auxiliar que atualiza o campo `status` de uma consulta
---
## Lógica da Agenda — Linhas 262342
### `loadConsultasAgendaForDate(String dateStr)`
**O que faz:**
1. Remove qualquer listener anterior (para evitar duplicados)
2. Escuta **todas** as consultas em tempo real
3. Para cada consulta:
- Verifica se **pertence ao médico atual** (campo `medicos` pode ser `String` ou `List`)
- Verifica se a **data corresponde** à data selecionada (suporta 3 formatos: `dd/MM/yyyy`, `d/M/yyyy`, `yyyy-MM-dd`)
- Exclui consultas com status `"cancelada"`
4. Atualiza a lista na UI
### `convertToISODate()` — Linha 324
- Converte `"22/04/2026"``"2026-04-22"`
### `getAlternativeDate()` — Linha 335
- Converte `"01/04/2026"``"1/4/2026"` (sem zeros à esquerda)
---
## Lógica do Perfil — Linhas 350402
### `loadPerfilMedico()`
1. Escuta em tempo real na coleção `utilizadores`
2. Se o documento **não existe**, faz fallback para a coleção `medicos`
3. Chama `updateProfileUI()` com os dados encontrados
### `updateProfileUI(DocumentSnapshot doc)`
1.`nome_completo` (ou `nome` como fallback)
2. Guarda o nome nas `SharedPreferences` para cache
3. Atualiza todos os campos da UI:
- Nome, Email, Especialidade, Cédula profissional
- Saudação "Olá, [Nome]" no topo
---
## Diagrama de Fluxo
```mermaid
graph TD
A[onCreate] --> B{Utilizador autenticado?}
B -->|Não| C[Ir para Login]
B -->|Sim| D[Carregar UI]
D --> E[Carregar nome em cache]
D --> F[Configurar RecyclerViews]
D --> G[Configurar BottomNav]
D --> H[loadUtilizadores]
D --> I[loadPerfilMedico]
D --> J[loadConsultasAgendaForDate - hoje]
G -->|Tab Agenda| K[Mostrar Agenda]
G -->|Tab Pacientes| L[Mostrar Pacientes]
G -->|Tab Perfil| M[Mostrar Perfil]
```