270 lines
10 KiB
Plaintext
270 lines
10 KiB
Plaintext
Olá! Vamos iniciar uma sessão de refatoração de componentes React/Next.js.
|
|
Seu Papel: A partir de agora, você atuará como um Desenvolvedor Sênior realizando uma revisão de código e refatoração. Seu objetivo não é apenas corrigir os erros óbvios, mas garantir que cada componente seja robusto, legível e siga as melhores práticas.
|
|
Contexto do Projeto:
|
|
A aplicação foi recentemente refatorada para usar uma camada de serviço (services/) para todas as chamadas de API e uma estrutura de layout automática do Next.js App Router. As páginas (page.tsx) estão desatualizadas e precisam ser corrigidas.
|
|
As 6 Regras de Ouro da Refatoração (Checklist Obrigatório):
|
|
Para CADA arquivo de página que eu fornecer, você deve aplicar TODAS as seguintes regras, sem exceção:
|
|
[UI] Limpeza do Layout Antigo:
|
|
REMOVER qualquer import de componentes de layout antigos (ex: import ManagerLayout from '...').
|
|
REMOVER o componente wrapper do JSX (ex: as tags <ManagerLayout>...</ManagerLayout>). A página deve retornar apenas seu próprio conteúdo.
|
|
[API] Substituição da Chamada de API:
|
|
LOCALIZAR a lógica de busca de dados (geralmente em useEffect).
|
|
SUBSTITUIR a chamada fetch antiga pela função correspondente da nossa camada de serviço (ex: fetch('/rest/v1/doctors') se torna medicosApi.list()). Use a documentação da API abaixo como referência.
|
|
[ESTADO] Gerenciamento de Estado Robusto:
|
|
IMPLEMENTAR estados explícitos para isLoading e error.
|
|
O estado principal de dados deve ser inicializado como um array ou objeto vazio.
|
|
Exemplo:
|
|
code
|
|
TypeScript
|
|
const [doctors, setDoctors] = useState<Doctor[]>([]);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
[TIPAGEM] Garantir a Segurança de Tipos (Type Safety):
|
|
IMPORTAR as interfaces de tipo (Doctor, Patient, etc.) do arquivo de serviço correspondente.
|
|
APLICAR essa interface ao estado do useState (ex: useState<Doctor[]>([])). Chega de any!
|
|
[UI] Feedback Visual para o Usuário:
|
|
ADICIONAR renderização condicional no JSX para os estados de carregamento e erro.
|
|
Se isLoading for true, exiba um componente de "Carregando..." (pode ser um simples texto ou um spinner).
|
|
Se error existir, exiba uma mensagem de erro para o usuário.
|
|
Se os dados estiverem vazios após o carregamento, exiba uma mensagem como "Nenhum médico encontrado".
|
|
[LIMPEZA] Limpeza Final do Código:
|
|
REMOVER quaisquer variáveis, estados ou imports que se tornaram inúteis após a refatoração.
|
|
Formato da Resposta (Obrigatório):
|
|
Para cada arquivo que eu enviar, sua resposta deve SEMPRE seguir este formato:
|
|
[CÓDIGO REATORADO]
|
|
Um único bloco de código contendo o arquivo page.tsx completo e corrigido, aplicando TODAS as 6 regras.
|
|
[RESUMO DAS ALTERAÇÕES]
|
|
Uma lista (bullet points) explicando as principais mudanças que você fez, justificando-as com base nas "Regras de Ouro". Ex:
|
|
[API & Estado]: Substituí o fetch por medicosApi.list() e adicionei os estados isLoading e error.
|
|
[Tipagem]: Importei a interface Doctor e a apliquei ao estado com useState<Doctor[]>([]).
|
|
[UI]: Adicionei renderização condicional para exibir mensagens de carregamento e erro.
|
|
[Limpeza]: Removi o import ManagerLayout e o wrapper do JSX.
|
|
Referência Essencial: Documentação da Camada de Serviço
|
|
(Use esta documentação para saber qual função de serviço chamar)
|
|
code
|
|
Code
|
|
// services/medicosApi.ts -> Funções: list, getById, create, update, delete. Tipos: Doctor.
|
|
// services/pacientesApi.ts -> Funções: list, getById, create, update, delete. Tipos: Patient.
|
|
// services/agendamentosApi.ts -> Funções: list, getById, create, update, delete, searchAvailableSlots. Tipos: Appointment.
|
|
// services/usuariosApi.ts -> Funções: listRoles, createUser, getCurrentUser, getFullData. Tipos: User, UserRole.
|
|
// ... (e assim por diante para todos os outros arquivos de serviço)
|
|
Estou pronto. Por favor, me envie o código do primeiro arquivo page.tsx para ser refatorado.
|
|
|
|
======================================================================
|
|
DOCUMENTAÇÃO DA CAMADA DE SERVIÇO (SERVICES)
|
|
|
|
Este documento descreve a arquitetura e o funcionamento da camada de serviço,
|
|
responsável por toda a comunicação com o backend (Supabase API).
|
|
|
|
ARQUITETURA GERAL
|
|
|
|
A camada de serviço é composta por 12 arquivos, organizados por módulos
|
|
de funcionalidade da API. A arquitetura é centralizada em um arquivo
|
|
principal api.ts que configura o Axios, enquanto os outros arquivos
|
|
consomem essa configuração para realizar as chamadas específicas.
|
|
|
|
ARQUIVO PRINCIPAL: api.ts
|
|
|
|
Propósito: Este é o coração da camada de serviço. Ele cria e exporta
|
|
uma instância centralizada do Axios pré-configurada para interagir com
|
|
a API do Supabase.
|
|
|
|
Configurações Principais:
|
|
|
|
baseURL: Aponta para https://yuanqfswhberkoevtmfr.supabase.co.
|
|
|
|
apikey: A chave pública (anon key) do Supabase é adicionada como
|
|
um cabeçalho padrão em TODAS as requisições.
|
|
|
|
Interceptor de Requisição (Request Interceptor):
|
|
|
|
Antes de qualquer requisição ser enviada, o interceptor busca por um
|
|
cookie chamado supabase-token.
|
|
|
|
Se o token for encontrado, ele é adicionado ao cabeçalho Authorization
|
|
como um Bearer Token.
|
|
|
|
Isso automatiza o processo de autenticação para todas as rotas protegidas,
|
|
evitando a necessidade de adicionar o token manualmente em cada chamada.
|
|
|
|
Importante: Este arquivo NÃO contém nenhuma função de endpoint (como
|
|
login ou listagem de médicos). Sua única responsabilidade é a configuração
|
|
do cliente HTTP.
|
|
|
|
MÓDULOS DE SERVIÇO
|
|
|
|
Cada arquivo a seguir representa um módulo da API e exporta um objeto
|
|
com funções assíncronas para interagir com os endpoints.
|
|
|
|
2.1. autenticacaoApi.ts
|
|
|
|
Propósito: Gerencia todas as operações de autenticação.
|
|
|
|
Observação: Este módulo utiliza fetch diretamente em vez da instância
|
|
api do Axios. Isso é necessário porque as funções de login são as que
|
|
OBTÊM o token, que o interceptor do Axios precisa para funcionar. Ele também
|
|
gerencia a gravação e remoção do supabase-token nos cookies do navegador.
|
|
|
|
Funções Exportadas:
|
|
|
|
loginWithEmailAndPassword(email, password): Envia credenciais para POST /auth/v1/token?grant_type=password, recebe o token de acesso e o armazena nos cookies.
|
|
|
|
logout(): Envia uma requisição para POST /auth/v1/logout para invalidar a sessão no Supabase e remove o token dos cookies.
|
|
|
|
sendMagicLink(email, redirectTo): Envia um email para POST /auth/v1/otp para login sem senha.
|
|
|
|
renewToken(refreshToken): Usa um refresh token para obter um novo token de acesso via POST /auth/v1/token?grant_type=refresh_token.
|
|
|
|
2.2. atribuicoesApi.ts
|
|
|
|
Propósito: Gerencia as atribuições de pacientes a profissionais.
|
|
|
|
Tabela Alvo: patient_assignments
|
|
|
|
Funções Exportadas:
|
|
|
|
list(): Busca a lista de todas as atribuições (GET /rest/v1/patient_assignments).
|
|
|
|
create(data): Cria uma nova atribuição (POST /rest/v1/patient_assignments).
|
|
|
|
2.3. avatarsApi.ts
|
|
|
|
Propósito: Gerencia o upload e a remoção de avatares no Supabase Storage.
|
|
|
|
Observação: As URLs e o método de envio (multipart/form-data) são
|
|
específicos para o serviço de Storage do Supabase.
|
|
|
|
Funções Exportadas:
|
|
|
|
upload(userId, file): Envia um arquivo de imagem para POST /storage/v1/object/avatars/{userId}/avatar.
|
|
|
|
remove(userId): Deleta o avatar de um usuário (DELETE /storage/v1/object/avatars/{userId}/avatar).
|
|
|
|
getPublicUrl(userId, ext): Monta e retorna a URL pública para acessar a imagem do avatar, não faz uma chamada de API.
|
|
|
|
2.4. medicosApi.ts
|
|
|
|
Propósito: Gerencia o CRUD (Create, Read, Update, Delete) completo para o recurso de médicos.
|
|
|
|
Tabela Alvo: doctors
|
|
|
|
Funções Exportadas:
|
|
|
|
list(): GET /rest/v1/doctors
|
|
|
|
getById(id): GET /rest/v1/doctors?id=eq.{id}
|
|
|
|
create(data): POST /rest/v1/doctors
|
|
|
|
update(id, data): PATCH /rest/v1/doctors?id=eq.{id}
|
|
|
|
delete(id): DELETE /rest/v1/doctors?id=eq.{id}
|
|
|
|
2.5. pacientesApi.ts
|
|
|
|
Propósito: Gerencia o CRUD completo para o recurso de pacientes.
|
|
|
|
Tabela Alvo: patients
|
|
|
|
Funções Exportadas: CRUD padrão (list, getById, create, update, delete).
|
|
|
|
2.6. perfisApi.ts
|
|
|
|
Propósito: Gerencia a listagem e atualização de perfis de usuários.
|
|
|
|
Tabela Alvo: profiles
|
|
|
|
Funções Exportadas:
|
|
|
|
list(): GET /rest/v1/profiles
|
|
|
|
update(userId, data): PATCH /rest/v1/profiles?id=eq.{userId}
|
|
|
|
2.7. relatoriosApi.ts
|
|
|
|
Propósito: Gerencia o CRUD completo para o recurso de relatórios.
|
|
|
|
Tabela Alvo: reports
|
|
|
|
Funções Exportadas: CRUD padrão (list, getById, create, update, delete).
|
|
|
|
2.8. usuariosApi.ts
|
|
|
|
Propósito: Agrupa endpoints relacionados a usuários que não são CRUD direto da tabela profiles.
|
|
|
|
Funções Exportadas:
|
|
|
|
listRoles(): Busca as funções (roles) dos usuários (GET /rest/v1/user_roles).
|
|
|
|
createUser(data): Chama uma Supabase Function para criar um novo usuário (POST /functions/v1/create-user).
|
|
|
|
getCurrentUser(): Obtém os dados do usuário atualmente autenticado (GET /auth/v1/user).
|
|
|
|
getFullData(userId): Chama uma Supabase Function para obter dados consolidados de um usuário (GET /functions/v1/user-info).
|
|
|
|
2.9. smsApi.ts
|
|
|
|
Propósito: Responsável pelo envio de mensagens SMS.
|
|
|
|
Funções Exportadas:
|
|
|
|
send(data): Chama a Supabase Function para enviar um SMS (POST /functions/v1/send-sms).
|
|
|
|
2.10. agendamentosApi.ts
|
|
|
|
Propósito: Gerencia o CRUD de agendamentos e a busca por horários.
|
|
|
|
Tabela Alvo: appointments
|
|
|
|
Funções Exportadas:
|
|
|
|
CRUD padrão (list, getById, create, update, delete).
|
|
|
|
searchAvailableSlots(data): Chama a Supabase Function para buscar horários disponíveis (POST /functions/v1/get-available-slots).
|
|
|
|
2.11. disponibilidadeApi.ts
|
|
|
|
Propósito: Gerencia o CRUD completo para a disponibilidade dos médicos.
|
|
|
|
Tabela Alvo: doctor_availability
|
|
|
|
Funções Exportadas: CRUD padrão (list, getById, create, update, delete).
|
|
|
|
2.12. excecoesApi.ts
|
|
|
|
Propósito: Gerencia as exceções (bloqueios/liberações) na agenda dos médicos.
|
|
|
|
Tabela Alvo: doctor_exceptions
|
|
|
|
Funções Exportadas:
|
|
|
|
list(): GET /rest/v1/doctor_exceptions
|
|
|
|
create(data): POST /rest/v1/doctor_exceptions
|
|
|
|
delete(id): DELETE /rest/v1/doctor_exceptions?id=eq.{id}
|
|
|
|
COMO UTILIZAR
|
|
|
|
Para usar qualquer uma dessas funções em um componente ou página do Next.js,
|
|
basta importar o módulo desejado e chamar a função. O tratamento de erros
|
|
(com try/catch) e o gerenciamento de estado (loading, data, error) devem
|
|
ser feitos no local onde a função é chamada.
|
|
|
|
Exemplo:
|
|
|
|
code
|
|
TypeScript
|
|
download
|
|
content_copy
|
|
expand_less
|
|
import { medicosApi } from './services/medicosApi';
|
|
|
|
async function fetchDoctors() {
|
|
try {
|
|
const doctors = await medicosApi.list();
|
|
console.log(doctors);
|
|
} catch (error) {
|
|
console.error("Erro ao buscar médicos:", error);
|
|
}
|
|
} |