feat(auth): Implements user API and fixes login flows.

- Adds new API functions for user management (createUser, etc.).    - Fixes multiple bugs that prevented administrator login and broke the project build.
This commit is contained in:
M-Gabrielly 2025-09-30 01:14:41 -03:00
parent 576c0d53b4
commit ba89bc17f2
5 changed files with 116 additions and 52 deletions

View File

@ -76,7 +76,7 @@ export default function DoutoresPage() {
}
return (
<ProtectedRoute requiredUserType={['administrador']}> // <-- REGRA APLICADA
<>
{showForm ? (
<div className="space-y-6 p-6">
<div className="flex items-center gap-4">
@ -233,6 +233,6 @@ export default function DoutoresPage() {
</div>
</div>
)}
</ProtectedRoute>
</>
);
}

View File

@ -16,31 +16,36 @@ export default function LoginAdminPage() {
const router = useRouter()
const { login } = useAuth()
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault()
setLoading(true)
setError('')
const handleLogin = async (e: React.MouseEvent) => {
e.preventDefault();
console.log('[LOGIN-DEBUG] 1. handleLogin iniciado.');
setLoading(true);
setError('');
try {
// Tentar fazer login usando o contexto com tipo administrador
const success = await login(credentials.email, credentials.password, 'administrador')
console.log('[LOGIN-DEBUG] 2. Chamando a função de login do useAuth...');
const success = await login(credentials.email, credentials.password, 'administrador');
console.log('[LOGIN-DEBUG] 3. A função de login retornou:', success);
if (success) {
console.log('[LOGIN-ADMIN] Login bem-sucedido, redirecionando...')
// Redirecionamento direto - solução que funcionou
window.location.href = '/dashboard'
console.log('[LOGIN-DEBUG] 4. Sucesso! Redirecionando para /dashboard...');
window.location.href = '/dashboard';
} else {
console.log('[LOGIN-DEBUG] 4b. A função de login retornou um valor falso, mas não lançou erro.');
setError('Ocorreu uma falha inesperada no login.');
}
} catch (err) {
console.error('[LOGIN-ADMIN] Erro no login:', err)
console.log('[LOGIN-DEBUG] 5. Ocorreu um erro (catch).');
console.error('[LOGIN-ADMIN] Erro no login:', err);
if (err instanceof AuthenticationError) {
setError(err.message)
setError(err.message);
} else {
setError('Erro inesperado. Tente novamente.')
setError('Erro inesperado. Tente novamente.');
}
} finally {
setLoading(false)
console.log('[LOGIN-DEBUG] 6. Bloco finally executado.');
setLoading(false);
}
}
@ -61,7 +66,7 @@ export default function LoginAdminPage() {
<CardTitle className="text-center">Acesso Administrativo</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleLogin} className="space-y-6">
<form onSubmit={(e) => e.preventDefault()} className="space-y-6">
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email
@ -101,7 +106,8 @@ export default function LoginAdminPage() {
)}
<Button
type="submit"
type="button"
onClick={handleLogin}
className="w-full cursor-pointer"
disabled={loading}
>

View File

@ -26,6 +26,7 @@ import {
listarAnexos,
removerAnexo,
buscarPacientePorId,
listarPerfis,
} from "@/lib/api";
type Mode = "create" | "edit";
@ -230,11 +231,28 @@ export function PatientRegistrationForm({
let saved: Paciente;
if (mode === "create") {
saved = await criarPaciente(payload);
console.log("--- INÍCIO DO TESTE DE API ---");
console.log("Paciente recém-criado:", saved);
try {
console.log("Buscando lista de perfis para verificar a criação...");
const perfis = await listarPerfis();
console.log("Lista de Perfis encontrada:", perfis);
const perfilCorrespondente = perfis.find(p => p.email === saved.email);
if (perfilCorrespondente) {
console.log("SUCESSO: Perfil correspondente foi encontrado!", perfilCorrespondente);
} else {
console.log("FALHA: Nenhum perfil correspondente ao email do paciente foi encontrado na lista de perfis.");
}
} catch (error) {
console.error("ERRO AO BUSCAR PERFIS:", error);
}
console.log("--- FIM DO TESTE DE API ---");
} else {
if (patientId == null) throw new Error("Paciente inexistente para edição");
saved = await atualizarPaciente(String(patientId), payload);
}
if (form.photo && saved?.id) {
try {
await uploadFotoPaciente(saved.id, form.photo);

View File

@ -402,6 +402,78 @@ export async function atualizarPerfil(id: string | number, input: UserProfileInp
}
//
// User Management APIs
//
export type UserRole = {
id: string;
user_id: string;
role: 'admin' | 'medico' | 'paciente';
created_at: string;
};
export type CreateUserInput = {
email: string;
password?: string;
full_name: string;
phone?: string;
role: 'admin' | 'medico' | 'paciente';
};
export type CreatedUser = {
id: string;
email: string;
full_name: string;
phone?: string;
role: string;
};
export type CompleteUserInfo = {
user: {
id: string;
email: string;
email_confirmed_at: string;
created_at: string;
last_sign_in_at: string;
};
profile: UserProfile;
roles: string[];
permissions: {
isAdmin: boolean;
isManager: boolean;
isDoctor: boolean;
isSecretary: boolean;
isAdminOrManager: boolean;
};
};
export async function criarUsuario(input: CreateUserInput): Promise<{ success: boolean; user: CreatedUser }> {
const url = `${API_BASE}/functions/v1/create-user`;
const res = await fetch(url, { method: "POST", headers: headers("json"), body: JSON.stringify(input) });
const data = await parse<any>(res);
logAPI("criarUsuario", { url, payload: input, result: data });
return data;
}
export async function listarUserRoles(): Promise<UserRole[]> {
const url = `${API_BASE}/rest/v1/user_roles`;
const res = await fetch(url, { method: "GET", headers: headers("json") });
const data = await parse<UserRole[]>(res);
logAPI("listarUserRoles", { url, result: data });
return data ?? [];
}
export async function getCompleteUserInfo(userId: string): Promise<CompleteUserInfo> {
const url = `${API_BASE}/functions/v1/user-info`;
// Assuming the function takes the user ID in the body of a POST request
const res = await fetch(url, { method: "POST", headers: headers("json"), body: JSON.stringify({ id: userId }) });
const data = await parse<CompleteUserInfo>(res);
logAPI("getCompleteUserInfo", { url, payload: { id: userId }, result: data });
return data;
}
//
// MÉDICOS (CRUD)
//

View File

@ -119,39 +119,7 @@ export async function loginUser(
body: JSON.stringify(payload),
});
// Se login falhar com 400, tentar criar usuário automaticamente
if (!response.ok && response.status === 400) {
console.log('[AUTH-API] Login falhou (400), tentando criar usuário...');
const signupUrl = `${ENV_CONFIG.SUPABASE_URL}/auth/v1/signup`;
const signupPayload = {
email,
password,
data: {
userType: userType,
name: email.split('@')[0],
}
};
debugRequest('POST', signupUrl, getLoginHeaders(), signupPayload);
const signupResponse = await fetch(signupUrl, {
method: 'POST',
headers: getLoginHeaders(),
body: JSON.stringify(signupPayload),
});
if (signupResponse.ok) {
console.log('[AUTH-API] Usuário criado, tentando login novamente...');
await new Promise(resolve => setTimeout(resolve, 100));
response = await fetch(url, {
method: 'POST',
headers: getLoginHeaders(),
body: JSON.stringify(payload),
});
}
}
console.log(`[AUTH-API] Login response: ${response.status} ${response.statusText}`, {
url: response.url,