falta so o chat

This commit is contained in:
2026-04-22 12:41:12 +01:00
parent 96d1985998
commit 2f3b03fe05
444 changed files with 22203 additions and 20079 deletions

View File

@@ -0,0 +1,40 @@
# 📄 Análise de Código: `MainActivity.java`
O `MainActivity.java` é a classe central da aplicação. Como usa o `BottomNavigationView`, ele controla três "ecrãs" virtuais que se escondem ou aparecem dependendo do botão carregado: Agenda, Pacientes e Perfil.
## 1. Importações e Declarações (Linhas 1 - 34)
A classe estende `AppCompatActivity` e implementa interfaces do `ConsultaAdapter` (`OnConsultaActionClickListener`, `OnConsultaClickListener`) para conseguir "ouvir" cliques feitos nos itens da lista de consultas.
## 2. Variáveis Globais (Linhas 36 - 57)
* **Views de Navegação:** `viewAgenda`, `viewPacientes`, `viewPerfil`, `layTop` — Estas variáveis controlam a visibilidade de cada secção da app.
* **RecyclerViews e Adapters:** `recyclerConsultas` e `adapterPacientes` (para a lista de pacientes), `recyclerAgenda` e `adapterAgenda` (para a lista de consultas).
* **Firebase:** `mAuth` (autenticação) e `db` (Firestore).
* **ID:** `currentMedicoId` guarda o UID (User ID) do médico logado.
## 3. Método `onCreate()` (Linhas 59 - 188)
* **Verificação de Login:** A primeira coisa que o `onCreate` faz é verificar se há algum utilizador logado (`mAuth.getCurrentUser() == null`). Se não houver, ele atira o utilizador para a `LoginActivity`.
* **Carregamento Instantâneo (SharedPreferences):** Usa o cache local `SessaoMedico` para exibir o nome ("Olá, [Nome]") antes mesmo da base de dados responder.
* **Configuração dos Recyclers:** Define os layouts (LinearLayoutManager) e os Adapters que vão desenhar as listas.
* **Bottom Navigation:** Há um `setOnItemSelectedListener` que, dependendo do botão tocado (Agenda, Pacientes, Perfil), faz um `setVisibility(View.GONE)` aos ecrãs indesejados e um `VISIBLE` ao ecrã selecionado.
* **Início dos Dados:** Chama `loadUtilizadores()`, `loadPerfilMedico()`, e usa a data atual (`SimpleDateFormat`) para chamar `loadConsultasAgendaForDate(today)`.
## 4. Lógica de Pacientes (`loadUtilizadores()`) (Linhas 190 - 230)
* Coloca um `SnapshotListener` (espião em tempo real) na coleção `"utilizadores"`.
* Se o `tipo` for "paciente" (ou nulo), adiciona à lista e manda o adapter desenhá-los no ecrã.
* Tenta ir buscar o nome a `"nome_completo"` e depois a `"nome"`.
## 5. Eventos de Clique nas Consultas (Linhas 232 - 260)
* **`onAceitarClick()`:** Altera o status da consulta para "aceite".
* **`onEliminarClick()`:** Elimina a consulta inteira da base de dados e informa o utilizador com um Toast.
* **`onConsultaClick()`:** Se o médico clicar na consulta (e não nos botões de aceitar/rejeitar), a app vai para a `DetalhePacienteActivity`, passando o `PACIENTE_ID` via Intent.
## 6. Lógica da Agenda (`loadConsultasAgendaForDate()`) (Linhas 262 - 342)
* Recebe uma data (ex: `12/04/2026`).
* Liga-se à coleção `"consultas"`. Filtra no cliente (através de um `if`) se o ID do médico (como string ou como parte de uma lista) está na consulta.
* Aceita três formatos de data via `getAlternativeDate` (ex: 04/05/2026 e 4/5/2026) ou formato ISO.
* Só mostra consultas se não estiverem marcadas como "cancelada".
## 7. Lógica do Perfil (`loadPerfilMedico()`) (Linhas 350 - 403)
* Acede à coleção `"utilizadores"`. Se o documento não existir, faz um *fallback* e tenta ler na coleção `"medicos"`.
* Depois de encontrar, usa o `updateProfileUI()` para meter o nome, email, especialidade e cédula nos `TextViews` respetivos.
* Atualiza a `SharedPreferences` para garantir que o "Olá, X" nunca fica vazio quando o ecrã recarrega.

View File

@@ -0,0 +1,30 @@
# 📄 Análise de Código: `LoginActivity.java`
Esta classe (`app/src/main/java/com/example/medcuida/pro/ui/auth/LoginActivity.java`) gere toda a entrada do médico no sistema.
## 1. Importações e Declarações (Linhas 1 - 33)
Importa elementos do Firebase (`FirebaseAuth`, `FirebaseUser`, `FirebaseFirestore`) e componentes da interface (`TextInputEditText`, `MaterialButton`).
## 2. Inicialização `onCreate()` (Linhas 34 - 79)
* **Instâncias Firebase:** `mAuth` e `db` são inicializados.
* **Proteção de Sessão:** Se `mAuth.getCurrentUser() != null`, significa que o utilizador já está logado. Ele nem sequer abre o ecrã; avança logo para a `MainActivity`.
* **Ligações da Interface:** Mapeia botões (Login) e links (Registo, Recuperação de Pass) aos IDs do ficheiro XML.
* **Botão Recuperar Password:** Se carregado, verifica se o campo do email não está vazio. Se estiver cheio, chama `mAuth.sendPasswordResetEmail(email)`.
## 3. Tentativa de Login `attemptLogin()` (Linhas 81 - 98)
* Puxa o texto dos inputs `emailEditText` e `passwordEditText`.
* Valida os campos: se um deles estiver vazio, dá erro (`setError`) e foca o campo.
* Passa as credenciais para o `loginUser()`.
## 4. O Método `loginUser()` (Linhas 100 - 123)
* **Experiência de Utilizador (UX):** Bloqueia o botão e muda o texto para "A entrar..." (assim evita que o médico clique duas vezes).
* Faz a chamada ao Firebase: `mAuth.signInWithEmailAndPassword()`.
* **Se Sucesso:** Pega no UID gerado e atira-o para o `checkUserAccess()`.
* **Se Falha:** Mostra a mensagem de erro (Ex: "Password errada") e reativa o botão de login.
## 5. Validação de Papel (Role) `checkUserAccess()` (Linhas 125 - 153)
Como a base de dados tem tanto pacientes como médicos, este método é crucial para garantir que um "paciente" não entra na app dos médicos por engano.
1. Tenta ler o documento do utilizador na coleção `"medicos"`.
2. Se existir, é um médico; vai para a `MainActivity`.
3. Se não existir, tenta ler na coleção `"utilizadores"`. Isto acontece porque em versões antigas/outras ramificações da app, os médicos também podem estar aí registados.
4. Se também não estiver aí, avisa "Esta conta não tem perfil configurado" e **faz sign out** imediatamente, forçando o ecrã a ficar no Login.

View File

@@ -0,0 +1,26 @@
# 📄 Análise de Código: `AgendaActivity.java`
O ficheiro `app/src/main/java/com/example/medcuida/pro/AgendaActivity.java` é usado como o ecrã de Calendário/Agenda em "ecrã inteiro", embora a `MainActivity` também incorpore parte desta vista. O objetivo primário é ver as consultas de um dia específico.
## 1. Variáveis e `onCreate()` (Linhas 28 - 94)
* Tem um `CalendarView` e uma `RecyclerView` (que vai conter as listas das consultas).
* A lógica do **BottomNavigationView** aqui está alterada: Se clicares em "Pacientes", ele não muda uma View interna (como faz na `MainActivity`); aqui, ele lança de facto um `Intent` para voltar para a `MainActivity`. Se clicares em "Perfil", ele lança a `PerfilMedicoActivity`.
* Configura o `ConsultaAdapter`. Tem "listeners" para Aceitar, Eliminar ou Clicar (abre `DetalhePacienteActivity`).
## 2. Gestão do Calendário (Linhas 87 - 93)
* A app usa um `SimpleDateFormat` no formato `dd/MM/yyyy` para saber o dia atual.
* O `calendarView.setOnDateChangeListener` é acionado sempre que o médico toca num dia no ecrã. Ele refaz a string da data e chama `loadConsultasForDate(selectedDate)`.
## 3. Pesquisa de Consultas `loadConsultasForDate()` (Linhas 96 - 153)
* Retira a subscrição antiga (`agendaListener.remove()`) para não ficar com múltiplas consultas de dados abertas na memória.
* Lê na coleção `"consultas"`.
* Em vez de fazer uma "Query" no Firestore por data, ele lê quase toda a coleção e **filtra localmente** no telemóvel (dentro do `for(QueryDocumentSnapshot doc : value)`).
* Verifica se o id do médico logado (`doctorId`) está dentro do atributo `medicos` da consulta (que pode ser uma String solta ou uma Lista de Strings).
* Depois, tenta ver se a data coincide. Se a consulta for cancelada, é ignorada.
## 4. Lógica de Alteração da Consulta (Linhas 155 - 171)
* **`aceitarConsulta()`**: Pega no ID do documento e faz `.update("status", "aceite")`. O Firestore notifica o telemóvel de imediato graças ao `SnapshotListener`, e a consulta desaparece/muda de estado na lista sem ser necessário recarregar o ecrã.
* **`eliminarConsulta()`**: Faz um `.delete()` duro na consulta.
## 5. Tratamento de Datas Sujas (Linhas 173 - 191)
Estes dois métodos, `convertToISODate()` e `getAlternativeDate()`, existem porque a base de dados pode ter lixo (datas como `4/5/2026` em vez de `04/05/2026`, ou `2026-05-04`). Este bloco garante que, independentemente de quem guardou a consulta, o ecrã mostra o dado na mesma.