docs: atualizar README com autenticação Magic Link e remover arquivos de teste

This commit is contained in:
guisilvagomes 2025-10-29 12:22:22 -03:00
parent c5461858b0
commit 7768ebc46d
14 changed files with 75 additions and 653 deletions

View File

@ -58,17 +58,35 @@ npx wrangler pages deploy dist --project-name=mediconnect --branch=production
### Autenticação JWT com Supabase
O sistema usa **Supabase Auth** com tokens JWT. Todo login retorna:
O sistema usa **Supabase Auth** com tokens JWT e suporta **duas formas de login**:
#### 1. Login com Email e Senha (tradicional)
- `access_token` (JWT, expira em 1 hora)
- `refresh_token` (para renovação automática)
- Armazenado em `localStorage`
#### 2. Magic Link (Login sem senha)
- Usuário recebe email com link único
- Clica no link e é automaticamente autenticado
- Tokens salvos automaticamente no `localStorage`
- Redirecionamento inteligente baseado no role do usuário
```typescript
// Magic Link
await authService.sendMagicLink("email@example.com");
// Envia email com link de autenticação
// Recuperação de Senha
await authService.requestPasswordReset("email@example.com");
// Envia email com link para resetar senha
```
### Interceptors Automáticos
```typescript
// Adiciona token automaticamente em todas as requisições
axios.interceptors.request.use((config) => {
const token = localStorage.getItem("access_token");
const token = localStorage.getItem("mediconnect_access_token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
@ -80,7 +98,7 @@ axios.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
const refreshToken = localStorage.getItem("refresh_token");
const refreshToken = localStorage.getItem("mediconnect_refresh_token");
const newTokens = await authService.refreshToken(refreshToken);
// Retry request original
}
@ -150,12 +168,17 @@ src/services/
#### 🔐 Autenticação (authService)
```typescript
// Login
// Login com Email e Senha
await authService.login({ email, password });
// Retorna: { access_token, refresh_token, user }
// Magic Link (Login sem senha)
await authService.sendMagicLink("email@example.com");
// Envia email com link de autenticação
// Usuário clica no link e é automaticamente autenticado
// Recuperação de senha
await authService.requestPasswordReset(email);
await authService.requestPasswordReset("email@example.com");
// Envia email com link de reset
// Atualizar senha
@ -166,6 +189,17 @@ await authService.updatePassword(accessToken, newPassword);
await authService.refreshToken(refreshToken);
```
**Fluxo Magic Link:**
1. Usuário solicita magic link na tela de login
2. `localStorage.setItem("magic_link_redirect", "/painel-medico")` salva contexto
3. Supabase envia email com link único
4. Usuário clica no link
5. `Home.tsx` detecta hash params e redireciona para `/auth/callback`
6. `AuthCallback.tsx` processa tokens, salva no localStorage
7. `window.location.href` redireciona para painel salvo
8. Página recarrega com `AuthContext` atualizado
9. Usuário autenticado no painel correto ✅
#### 👤 Usuários (userService)
```typescript

View File

@ -1,128 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
async function createAppointment() {
try {
console.log("🔐 Fazendo login como Aurora...");
// Login como Aurora
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "aurora-nascimento94@gmx.com",
password: "auroranasc94",
},
{
headers: {
apikey: SUPABASE_ANON_KEY,
"Content-Type": "application/json",
},
}
);
const auroraToken = loginResponse.data.access_token;
console.log("✅ Login realizado como Aurora");
// Buscar o patient_id da Aurora
console.log("\n👤 Buscando dados da paciente...");
const patientResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/patients?user_id=eq.${loginResponse.data.user.id}`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${auroraToken}`,
},
}
);
if (!patientResponse.data || patientResponse.data.length === 0) {
throw new Error("Paciente não encontrada");
}
const patientId = patientResponse.data[0].id;
console.log(`✅ Patient ID: ${patientId}`);
// Buscar disponibilidade do Dr. Fernando para segunda-feira
console.log("\n📅 Buscando disponibilidade do Dr. Fernando...");
const availabilityResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/doctor_availability?doctor_id=eq.6dad001d-229b-40b5-80f3-310243c4599c&weekday=eq.monday`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${auroraToken}`,
},
}
);
if (!availabilityResponse.data || availabilityResponse.data.length === 0) {
throw new Error("Disponibilidade não encontrada");
}
const availability = availabilityResponse.data[0];
console.log(
`✅ Disponibilidade encontrada: ${availability.start_time} - ${availability.end_time}`
);
// Criar consulta para próxima segunda-feira às 10:00
const today = new Date();
const daysUntilMonday = (1 - today.getDay() + 7) % 7 || 7; // Próxima segunda
const appointmentDate = new Date(today);
appointmentDate.setDate(today.getDate() + daysUntilMonday);
appointmentDate.setHours(10, 0, 0, 0);
const scheduledAt = appointmentDate.toISOString();
console.log(`\n📝 Criando consulta para ${scheduledAt}...`);
const appointmentData = {
patient_id: patientId,
doctor_id: "6dad001d-229b-40b5-80f3-310243c4599c",
scheduled_at: scheduledAt,
duration_minutes: 30,
appointment_type: "presencial",
chief_complaint: "Consulta de rotina",
};
const appointmentResponse = await axios.post(
`${SUPABASE_URL}/rest/v1/appointments`,
appointmentData,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${auroraToken}`,
"Content-Type": "application/json",
Prefer: "return=representation",
},
}
);
console.log("\n✅ Consulta criada com sucesso!");
console.log("\n📋 Detalhes da consulta:");
console.log(` - Paciente: Aurora Sabrina Clara Nascimento`);
console.log(` - Médico: Dr. Fernando Pirichowski`);
console.log(` - Data/Hora: ${scheduledAt}`);
console.log(` - Duração: 30 minutos`);
console.log(` - Tipo: presencial`);
if (appointmentResponse.data && appointmentResponse.data.length > 0) {
console.log(` - ID da consulta: ${appointmentResponse.data[0].id}`);
console.log(
` - Order Number: ${appointmentResponse.data[0].order_number}`
);
console.log(` - Status: ${appointmentResponse.data[0].status}`);
}
} catch (error) {
console.error(
"❌ Erro ao criar consulta:",
error.response?.data || error.message
);
if (error.response?.data) {
console.error("Detalhes:", JSON.stringify(error.response.data, null, 2));
}
}
}
createAppointment();

View File

@ -1,93 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
// IDs
const DOCTOR_ID = "6dad001d-229b-40b5-80f3-310243c4599c"; // Fernando (CRM 24245)
const ADMIN_ID = "c7fcd702-9a6e-4b7c-abd3-956b25af407d"; // Admin (riseup)
async function main() {
try {
console.log("🔐 Fazendo login como admin...");
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "riseup@popcode.com.br",
password: "riseup",
},
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
},
}
);
const adminToken = loginResponse.data.access_token;
console.log("✅ Login realizado\n");
console.log("📅 Criando disponibilidade para Dr. Fernando...");
console.log("⏰ Horário: 07:00 às 19:00");
console.log("📆 Dias: Segunda a Domingo\n");
const weekdays = [
{ num: "sunday", name: "Domingo" },
{ num: "monday", name: "Segunda-feira" },
{ num: "tuesday", name: "Terça-feira" },
{ num: "wednesday", name: "Quarta-feira" },
{ num: "thursday", name: "Quinta-feira" },
{ num: "friday", name: "Sexta-feira" },
{ num: "saturday", name: "Sábado" },
];
for (const day of weekdays) {
try {
const availabilityData = {
doctor_id: DOCTOR_ID,
weekday: day.num,
start_time: "07:00:00",
end_time: "19:00:00",
slot_minutes: 30,
appointment_type: "presencial",
active: true,
created_by: ADMIN_ID,
};
const response = await axios.post(
`${SUPABASE_URL}/rest/v1/doctor_availability`,
availabilityData,
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
Prefer: "return=representation",
},
}
);
console.log(`${day.name}: Disponibilidade criada`);
} catch (error) {
console.error(
`${day.name}: Erro -`,
error.response?.data?.message || error.message
);
}
}
console.log("\n🎉 Disponibilidade criada com sucesso!");
console.log("\n📋 Resumo:");
console.log("- Médico: Dr. Fernando Pirichowski");
console.log("- Dias: Todos os dias da semana (Domingo a Sábado)");
console.log("- Horário: 07:00 às 19:00");
console.log("- Duração consulta: 30 minutos");
console.log("- Tipo: Presencial");
} catch (error) {
console.error("❌ Erro geral:", error.response?.data || error.message);
}
}
main();

View File

@ -1,80 +0,0 @@
const axios = require("axios");
// Configuração
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
// Credenciais do admin
const ADMIN_EMAIL = "riseup@popcode.com.br";
const ADMIN_PASSWORD = "riseup";
// Dados do paciente (Aurora Sabrina Clara Nascimento)
const PATIENT_DATA = {
email: "aurora-nascimento94@gmx.com",
password: "auroranasc94",
full_name: "Aurora Sabrina Clara Nascimento",
phone_mobile: "(21) 99856-3014",
cpf: "66864784231", // CPF sem pontuação
create_patient_record: true,
role: "paciente",
};
async function main() {
try {
console.log("🔐 1. Fazendo login como admin...");
// 1. Login do admin
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: ADMIN_EMAIL,
password: ADMIN_PASSWORD,
},
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
},
}
);
const adminToken = loginResponse.data.access_token;
console.log("✅ Login realizado com sucesso!");
console.log("🔑 Token:", adminToken.substring(0, 30) + "...");
console.log("\n👤 2. Criando paciente...");
console.log("Dados:", JSON.stringify(PATIENT_DATA, null, 2));
// 2. Criar paciente
const createResponse = await axios.post(
`${SUPABASE_URL}/functions/v1/create-user-with-password`,
PATIENT_DATA,
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
},
}
);
console.log("\n✅ Paciente criado com sucesso!");
console.log("Resposta:", JSON.stringify(createResponse.data, null, 2));
if (createResponse.data.patient_id) {
console.log("\n📋 ID do paciente:", createResponse.data.patient_id);
console.log("✉️ Email de confirmação enviado para:", PATIENT_DATA.email);
console.log("🔐 Senha temporária:", PATIENT_DATA.password);
console.log(
"\n⚠ O usuário precisa confirmar o email antes de fazer login!"
);
}
} catch (error) {
console.error("❌ Erro:", error.response?.data || error.message);
console.error("Status:", error.response?.status);
console.error("URL:", error.config?.url);
}
}
main();

View File

@ -1,72 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
async function fixAuroraUserId() {
try {
console.log("🔐 Fazendo login como admin...");
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "riseup@popcode.com.br",
password: "riseup",
},
{
headers: {
apikey: SUPABASE_ANON_KEY,
"Content-Type": "application/json",
},
}
);
const adminToken = loginResponse.data.access_token;
console.log("✅ Login realizado");
// Fazer login como Aurora para pegar o user_id
console.log("\n👤 Fazendo login como Aurora...");
const auroraLoginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "aurora-nascimento94@gmx.com",
password: "auroranasc94",
},
{
headers: {
apikey: SUPABASE_ANON_KEY,
"Content-Type": "application/json",
},
}
);
const auroraUserId = auroraLoginResponse.data.user.id;
console.log(`✅ User ID da Aurora: ${auroraUserId}`);
// Atualizar patient com user_id
console.log("\n📝 Atualizando registro da paciente...");
const updateResponse = await axios.patch(
`${SUPABASE_URL}/rest/v1/patients?id=eq.b85486f7-9135-4b67-9aa7-b884d9603d12`,
{
user_id: auroraUserId,
},
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
"Content-Type": "application/json",
Prefer: "return=representation",
},
}
);
console.log("✅ Registro atualizado com sucesso!");
console.log(` - Patient ID: b85486f7-9135-4b67-9aa7-b884d9603d12`);
console.log(` - User ID: ${auroraUserId}`);
} catch (error) {
console.error("❌ Erro:", error.response?.data || error.message);
}
}
fixAuroraUserId();

View File

@ -1,59 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
async function main() {
try {
console.log("🔐 Fazendo login como admin...");
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "riseup@popcode.com.br",
password: "riseup",
},
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
},
}
);
const adminToken = loginResponse.data.access_token;
console.log("✅ Login realizado\n");
console.log("👤 Buscando dados de Aurora na tabela patients...");
const patientsResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/patients?email=eq.aurora-nascimento94@gmx.com`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
},
}
);
if (patientsResponse.data.length > 0) {
const patient = patientsResponse.data[0];
console.log("✅ Paciente encontrada!\n");
console.log("📋 DADOS DA AURORA:\n");
console.log("User ID (auth):", patient.id);
console.log("Patient ID:", patient.id); // Em patients, o id é o mesmo do auth
console.log("Nome:", patient.full_name);
console.log("Email:", patient.email);
console.log("CPF:", patient.cpf);
console.log("Telefone:", patient.phone_mobile);
console.log("\n📄 Dados completos:", JSON.stringify(patient, null, 2));
} else {
console.log("❌ Paciente não encontrada na tabela patients");
}
} catch (error) {
console.error("❌ Erro:", error.response?.data || error.message);
}
}
main();

View File

@ -1,80 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
async function main() {
try {
console.log("🔐 Fazendo login como admin...");
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "riseup@popcode.com.br",
password: "riseup",
},
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
},
}
);
const adminToken = loginResponse.data.access_token;
console.log("✅ Login realizado\n");
console.log("🔍 Buscando Fernando em profiles...");
const profilesResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/profiles?email=eq.fernando.pirichowski@souunit.com.br`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
},
}
);
if (profilesResponse.data.length > 0) {
console.log(
`${profilesResponse.data.length} perfil(is) encontrado(s)!\n`
);
profilesResponse.data.forEach((profile, index) => {
console.log(`📋 PERFIL ${index + 1}:\n`);
console.log("User ID:", profile.id);
console.log("Email:", profile.email);
console.log("Nome:", profile.full_name);
console.log("Telefone:", profile.phone || "Não informado");
console.log("\n" + "=".repeat(60) + "\n");
});
// Pegar roles do primeiro perfil
const userId = profilesResponse.data[0].id;
console.log("🔍 Buscando roles...");
const rolesResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/user_roles?user_id=eq.${userId}`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
},
}
);
console.log(
"📌 Roles:",
rolesResponse.data.map((r) => r.role).join(", ")
);
} else {
console.log("❌ Nenhum perfil encontrado");
}
} catch (error) {
console.error("❌ Erro:", error.response?.data || error.message);
}
}
main();

View File

@ -1,82 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
async function main() {
try {
console.log("🔐 Fazendo login como admin...");
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "riseup@popcode.com.br",
password: "riseup",
},
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
},
}
);
const adminToken = loginResponse.data.access_token;
console.log("✅ Login realizado\n");
console.log("👨‍⚕️ Buscando dados de Fernando na tabela doctors...");
const doctorsResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/doctors?email=eq.fernando.pirichowski@souunit.com.br`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
Prefer: "return=representation",
},
}
);
if (doctorsResponse.data.length > 0) {
console.log(
`${doctorsResponse.data.length} médico(s) encontrado(s)!\n`
);
doctorsResponse.data.forEach((doctor, index) => {
console.log(`📋 MÉDICO ${index + 1}:\n`);
console.log("Doctor ID:", doctor.id);
console.log("Nome:", doctor.full_name);
console.log("Email:", doctor.email);
console.log("CRM:", doctor.crm);
console.log("Especialidade:", doctor.specialty || "Não informada");
console.log("Telefone:", doctor.phone || "Não informado");
console.log("\n" + "=".repeat(60) + "\n");
});
} else {
console.log("❌ Nenhum médico chamado Fernando encontrado");
console.log("\n🔍 Buscando todos os médicos...");
const allDoctorsResponse = await axios.get(
`${SUPABASE_URL}/rest/v1/doctors`,
{
headers: {
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${adminToken}`,
},
}
);
console.log(
`\n📊 Total de médicos cadastrados: ${allDoctorsResponse.data.length}`
);
allDoctorsResponse.data.forEach((doctor, index) => {
console.log(`${index + 1}. ${doctor.full_name} - ${doctor.email}`);
});
}
} catch (error) {
console.error("❌ Erro:", error.response?.data || error.message);
}
}
main();

View File

@ -1,38 +0,0 @@
const axios = require("axios");
const SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
const SUPABASE_ANON_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
async function main() {
try {
console.log("🔐 Fazendo login como Fernando...");
const loginResponse = await axios.post(
`${SUPABASE_URL}/auth/v1/token?grant_type=password`,
{
email: "fernando.pirichowski@souunit.com.br",
password: "fernando123",
},
{
headers: {
"Content-Type": "application/json",
apikey: SUPABASE_ANON_KEY,
},
}
);
const userData = loginResponse.data;
console.log("✅ Login realizado\n");
console.log("📋 DADOS DO FERNANDO (AUTH):\n");
console.log("User ID:", userData.user.id);
console.log("Email:", userData.user.email);
console.log("Role:", userData.user.role);
console.log("\n" + "=".repeat(60));
} catch (error) {
console.error("❌ Erro:", error.response?.data || error.message);
}
}
main();

View File

@ -73,9 +73,12 @@ export default function AuthCallback() {
// Magic link ou qualquer callback com sessão válida:
// Salvar tokens diretamente no localStorage
console.log("[AuthCallback] Salvando tokens e user no localStorage");
localStorage.setItem("mediconnect_access_token", session.access_token);
localStorage.setItem("mediconnect_refresh_token", session.refresh_token);
localStorage.setItem(
"mediconnect_refresh_token",
session.refresh_token
);
localStorage.setItem(
"mediconnect_user",
JSON.stringify({
@ -94,16 +97,19 @@ export default function AuthCallback() {
// Verificar se há redirecionamento salvo do magic link
const savedRedirect = localStorage.getItem("magic_link_redirect");
console.log("[AuthCallback] Verificando redirecionamento:");
console.log(" - magic_link_redirect:", savedRedirect);
console.log(" - user role:", session.user.user_metadata?.role);
console.log(" - localStorage keys:", Object.keys(localStorage));
if (savedRedirect) {
console.log("[AuthCallback] ✅ Redirecionando para (saved):", savedRedirect);
console.log(
"[AuthCallback] ✅ Redirecionando para (saved):",
savedRedirect
);
localStorage.removeItem("magic_link_redirect"); // Limpar após uso
// Usar window.location.href para forçar reload completo e atualizar AuthContext
window.location.href = savedRedirect;
return;
@ -111,10 +117,13 @@ export default function AuthCallback() {
// Fallback: redirecionar baseado no role
const userRole = session.user.user_metadata?.role || "paciente";
console.log("[AuthCallback] ⚠️ Nenhum redirect salvo, usando role:", userRole);
console.log(
"[AuthCallback] ⚠️ Nenhum redirect salvo, usando role:",
userRole
);
let redirectUrl = "/acompanhamento"; // default paciente
switch (userRole) {
case "medico":
console.log("[AuthCallback] Navegando para /painel-medico");
@ -130,7 +139,7 @@ export default function AuthCallback() {
redirectUrl = "/acompanhamento";
break;
}
// Usar window.location.href para forçar reload completo
window.location.href = redirectUrl;
} catch (err: any) {

View File

@ -24,8 +24,13 @@ const Home: React.FC = () => {
// Verificar se há parâmetros de magic link e redirecionar para AuthCallback
useEffect(() => {
const hash = window.location.hash;
if (hash && (hash.includes('access_token') || hash.includes('type=magiclink'))) {
console.log("[Home] Detectado magic link, redirecionando para /auth/callback");
if (
hash &&
(hash.includes("access_token") || hash.includes("type=magiclink"))
) {
console.log(
"[Home] Detectado magic link, redirecionando para /auth/callback"
);
navigate(`/auth/callback${hash}`, { replace: true });
return;
}

View File

@ -204,7 +204,7 @@ const LoginMedico: React.FC = () => {
try {
// Salvar contexto para redirecionamento correto após magic link
localStorage.setItem("magic_link_redirect", "/painel-medico");
await authService.sendMagicLink(formData.email);
toast.success(
"Link de acesso enviado para seu email! Verifique sua caixa de entrada.",

View File

@ -313,8 +313,11 @@ const LoginPaciente: React.FC = () => {
setLoading(true);
try {
// Salvar contexto para redirecionamento correto após magic link
localStorage.setItem("magic_link_redirect", "/acompanhamento");
localStorage.setItem(
"magic_link_redirect",
"/acompanhamento"
);
await authService.sendMagicLink(formData.email);
toast.success(
"Link de acesso enviado para seu email! Verifique sua caixa de entrada.",

View File

@ -213,8 +213,11 @@ const LoginSecretaria: React.FC = () => {
setLoading(true);
try {
// Salvar contexto para redirecionamento correto após magic link
localStorage.setItem("magic_link_redirect", "/painel-secretaria");
localStorage.setItem(
"magic_link_redirect",
"/painel-secretaria"
);
await authService.sendMagicLink(formData.email);
toast.success(
"Link de acesso enviado para seu email! Verifique sua caixa de entrada.",