-
-
-
+const roleIcons = {
+ secretary: UserCheck,
+ patient: Stethoscope,
+ doctor: Stethoscope,
+ admin: UserCheck,
+ manager: IdCard,
+ finance: Receipt,
+};
+
+export function LoginForm({ title, description, role, themeColor, redirectPath, children }: LoginFormProps) {
+ const [form, setForm] = useState
({ email: "", password: "" });
+ const [showPassword, setShowPassword] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
+ const router = useRouter();
+ const { toast } = useToast();
+
+ const currentTheme = themeClasses[themeColor];
+ const Icon = roleIcons[role];
+
+ // ==================================================================
+ // AJUSTE PRINCIPAL NA LÓGICA DE LOGIN
+ // ==================================================================
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setIsLoading(true);
+
+ const LOGIN_URL = "https://yuanqfswhberkoevtmfr.supabase.co/auth/v1/token?grant_type=password";
+ const API_KEY = apikey;
+
+ if (!API_KEY) {
+ toast({
+ title: "Erro de Configuração",
+ description: "A chave da API não foi encontrada.",
+ });
+ setIsLoading(false);
+ return;
+ }
+
+ try {
+ const response = await fetch(LOGIN_URL, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ apikey: API_KEY,
+ },
+ body: JSON.stringify({ email: form.email, password: form.password }),
+ });
+
+ const data = await response.json();
+
+ if (!response.ok) {
+ throw new Error(data.error_description || "Credenciais inválidas. Tente novamente.");
+ }
+
+ const accessToken = data.access_token;
+ const user = data.user;
+
+ /* =================== Verificação de Role Desativada Temporariamente =================== */
+ // if (user.user_metadata.role !== role) {
+ // toast({ title: "Acesso Negado", ... });
+ // return;
+ // }
+ /* ===================================================================================== */
+
+ Cookies.set("access_token", accessToken, { expires: 1, secure: true });
+ localStorage.setItem("user_info", JSON.stringify(user));
+
+ toast({
+ title: "Login bem-sucedido!",
+ description: `Bem-vindo(a), ${user.user_metadata.full_name || "usuário"}! Redirecionando...`,
+ });
+
+ router.push(redirectPath);
+ } catch (error) {
+ toast({
+ title: "Erro no Login",
+ description: error instanceof Error ? error.message : "Ocorreu um erro inesperado.",
+ });
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ // O JSX do return permanece exatamente o mesmo, preservando seus ajustes.
+ return (
+
+
+
+
-
-
Novo por aqui?
+
+ {title}
+ {description}
-
- {children}
-
- ) : (
- <>
-
-
- ou
-
-
-
- Voltar à página inicial
-
-
- >
- )}
-
-
-
- )
-}
\ No newline at end of file
+
+
+
+ {/* Conteúdo Extra (children) */}
+
+ {children ? (
+
+ ) : (
+ <>
+
+
+ ou
+
+
+
+ Voltar à página inicial
+
+
+ >
+ )}
+
+
+
+ );
+}
diff --git a/services/api.mjs b/services/api.mjs
index 73d3721..360c744 100644
--- a/services/api.mjs
+++ b/services/api.mjs
@@ -1,90 +1,84 @@
-
const BASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co";
-const API_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
+const API_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ";
+export const apikey = API_KEY;
var tempToken;
export async function login() {
- const response = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/auth/v1/token?grant_type=password", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Prefer: "return=representation",
- "apikey": API_KEY, // valor fixo
- },
- body: JSON.stringify({ email: "riseup@popcode.com.br", password: "riseup" }),
- });
+ const response = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/auth/v1/token?grant_type=password", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Prefer: "return=representation",
+ apikey: API_KEY, // valor fixo
+ },
+ body: JSON.stringify({ email: "riseup@popcode.com.br", password: "riseup" }),
+ });
- const data = await response.json();
-
- localStorage.setItem("token", data.access_token);
-
- return data;
+ const data = await response.json();
+
+ localStorage.setItem("token", data.access_token);
+
+ return data;
}
-
let loginPromise = login();
-
-
async function request(endpoint, options = {}) {
-
- if (loginPromise) {
- try {
- await loginPromise;
- } catch (error) {
- console.error("Falha na autenticação inicial:", error);
- }
-
- loginPromise = null;
- }
-
- const token = localStorage.getItem("token");
-
- const headers = {
- "Content-Type": "application/json",
- "apikey": API_KEY,
- ...(token ? { "Authorization": `Bearer ${token}` } : {}),
- ...options.headers,
- };
-
- try {
- const response = await fetch(`${BASE_URL}${endpoint}`, {
- ...options,
- headers,
- });
-
- if (!response.ok) {
-
- let errorBody = `Status: ${response.status}`;
- try {
- const contentType = response.headers.get("content-type");
- if (contentType && contentType.includes("application/json")) {
- const jsonError = await response.json();
-
- errorBody = jsonError.message || JSON.stringify(jsonError);
- } else {
- errorBody = await response.text();
+ if (loginPromise) {
+ try {
+ await loginPromise;
+ } catch (error) {
+ console.error("Falha na autenticação inicial:", error);
}
- } catch (e) {
-
- errorBody = `Status: ${response.status} - Falha ao ler corpo do erro.`;
- }
-
- throw new Error(`Erro HTTP: ${response.status} - Detalhes: ${errorBody}`);
+
+ loginPromise = null;
}
- const contentType = response.headers.get("content-type");
- if (response.status === 204 || (contentType && !contentType.includes("application/json")) || !contentType) {
- return {};
+
+ const token = localStorage.getItem("token");
+
+ const headers = {
+ "Content-Type": "application/json",
+ apikey: API_KEY,
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
+ ...options.headers,
+ };
+
+ try {
+ const response = await fetch(`${BASE_URL}${endpoint}`, {
+ ...options,
+ headers,
+ });
+
+ if (!response.ok) {
+ let errorBody = `Status: ${response.status}`;
+ try {
+ const contentType = response.headers.get("content-type");
+ if (contentType && contentType.includes("application/json")) {
+ const jsonError = await response.json();
+
+ errorBody = jsonError.message || JSON.stringify(jsonError);
+ } else {
+ errorBody = await response.text();
+ }
+ } catch (e) {
+ errorBody = `Status: ${response.status} - Falha ao ler corpo do erro.`;
+ }
+
+ throw new Error(`Erro HTTP: ${response.status} - Detalhes: ${errorBody}`);
+ }
+ const contentType = response.headers.get("content-type");
+ if (response.status === 204 || (contentType && !contentType.includes("application/json")) || !contentType) {
+ return {};
+ }
+ return await response.json();
+ } catch (error) {
+ console.error("Erro na requisição:", error);
+ throw error;
}
- return await response.json();
- } catch (error) {
- console.error("Erro na requisição:", error);
- throw error;
- }
}
export const api = {
- get: (endpoint) => request(endpoint, { method: "GET" }),
- post: (endpoint, data) => request(endpoint, { method: "POST", body: JSON.stringify(data) }),
- patch: (endpoint, data) => request(endpoint, { method: "PATCH", body: JSON.stringify(data) }),
- delete: (endpoint) => request(endpoint, { method: "DELETE" }),
-};
\ No newline at end of file
+ get: (endpoint) => request(endpoint, { method: "GET" }),
+ post: (endpoint, data) => request(endpoint, { method: "POST", body: JSON.stringify(data) }),
+ patch: (endpoint, data) => request(endpoint, { method: "PATCH", body: JSON.stringify(data) }),
+ delete: (endpoint) => request(endpoint, { method: "DELETE" }),
+};