Refactor: Split Auth.tsx into smaller components

Refactor src/pages/Auth.tsx into smaller, more manageable components to improve readability and maintainability.
This commit is contained in:
gpt-engineer-app[bot] 2025-05-21 19:54:31 +00:00
parent 63fd48a4a9
commit 74ec708d37
4 changed files with 309 additions and 258 deletions

View File

@ -0,0 +1,102 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useToast } from "@/components/ui/use-toast";
import { supabase } from "@/integrations/supabase/client";
interface LoginFormProps {
isLoading: boolean;
setIsLoading: (isLoading: boolean) => void;
}
const LoginForm = ({ isLoading, setIsLoading }: LoginFormProps) => {
const navigate = useNavigate();
const { toast } = useToast();
// State for login form
const [loginEmail, setLoginEmail] = useState('');
const [loginSenha, setLoginSenha] = useState('');
// Function for handling login
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Tenta autenticar o usuário através da função RPC do Supabase
const { data, error } = await supabase.rpc('autenticar_usuario', {
email_login: loginEmail,
senha_login: loginSenha
});
if (error || !data) {
throw new Error(error?.message || "Falha ao autenticar. Verifique seu email e senha.");
}
// Se encontrou um usuário válido
if (data) {
// Armazenar informações de sessão
localStorage.setItem('autenticado', 'true');
localStorage.setItem('userId', data);
localStorage.setItem('userEmail', loginEmail);
toast({
title: "Login realizado com sucesso",
description: "Bem-vindo de volta!"
});
// Redirecionamento para o dashboard após login bem-sucedido
navigate('/dashboard');
} else {
toast({
title: "Falha no login",
description: "Email ou senha incorretos",
variant: "destructive"
});
}
} catch (error) {
console.error("Erro ao fazer login:", error);
toast({
title: "Erro ao fazer login",
description: "Verifique suas credenciais e tente novamente",
variant: "destructive"
});
} finally {
setIsLoading(false);
}
};
return (
<form onSubmit={handleLogin} className="space-y-4">
<div className="space-y-2">
<Input
id="login-email"
placeholder="Email"
type="email"
value={loginEmail}
onChange={(e) => setLoginEmail(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="login-senha"
placeholder="Senha"
type="password"
value={loginSenha}
onChange={(e) => setLoginSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Entrando..." : "Entrar"}
</Button>
</form>
);
};
export default LoginForm;

View File

@ -0,0 +1,171 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useToast } from "@/components/ui/use-toast";
import { supabase } from "@/integrations/supabase/client";
import { enviarDadosParaWebhook } from '@/utils/webhookService';
interface RegisterFormProps {
isLoading: boolean;
setIsLoading: (isLoading: boolean) => void;
}
const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
const navigate = useNavigate();
const { toast } = useToast();
// Estado do formulário de cadastro
const [nome, setNome] = useState('');
const [empresa, setEmpresa] = useState('');
const [email, setEmail] = useState('');
const [senha, setSenha] = useState('');
const [confirmaSenha, setConfirmaSenha] = useState('');
// Função para cadastrar usuário
const handleCadastro = async (e: React.FormEvent) => {
e.preventDefault();
// Validações básicas
if (!nome || !email || !senha) {
toast({
title: "Campos obrigatórios",
description: "Por favor preencha todos os campos obrigatórios",
variant: "destructive"
});
return;
}
if (senha !== confirmaSenha) {
toast({
title: "Senhas não conferem",
description: "A senha e a confirmação de senha devem ser iguais",
variant: "destructive"
});
return;
}
setIsLoading(true);
try {
// Registrar o usuário usando a função RPC do Supabase
const { data, error } = await supabase.rpc('registrar_usuario', {
nome,
empresa,
email,
senha
});
if (error) throw error;
if (data) {
// Preparar os dados do usuário para enviar ao webhook
const dadosUsuario = {
nome,
empresa,
email,
data_cadastro: new Date().toISOString(),
origem: window.location.origin,
};
// Enviar dados do usuário para o webhook
await enviarDadosParaWebhook(dadosUsuario);
toast({
title: "Cadastro realizado",
description: "Sua conta foi criada com sucesso!"
});
// Fazer login automaticamente após o cadastro
const { data: loginData, error: loginError } = await supabase.rpc('autenticar_usuario', {
email_login: email,
senha_login: senha
});
if (loginError) throw loginError;
if (loginData) {
localStorage.setItem('autenticado', 'true');
localStorage.setItem('userId', loginData);
localStorage.setItem('userEmail', email);
localStorage.setItem('userName', nome);
// Redirecionamento para o dashboard após cadastro bem-sucedido
navigate('/dashboard');
}
}
} catch (error: any) {
console.error("Erro ao cadastrar:", error);
toast({
title: "Erro no cadastro",
description: error.message || "Não foi possível completar o cadastro",
variant: "destructive"
});
} finally {
setIsLoading(false);
}
};
return (
<form onSubmit={handleCadastro} className="space-y-4">
<div className="space-y-2">
<Input
id="nome"
placeholder="Nome completo"
value={nome}
onChange={(e) => setNome(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="empresa"
placeholder="Empresa (opcional)"
value={empresa}
onChange={(e) => setEmpresa(e.target.value)}
disabled={isLoading}
/>
</div>
<div className="space-y-2">
<Input
id="email"
placeholder="Email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="senha"
placeholder="Senha"
type="password"
value={senha}
onChange={(e) => setSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="confirma-senha"
placeholder="Confirme a senha"
type="password"
value={confirmaSenha}
onChange={(e) => setConfirmaSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Cadastrando..." : "Cadastrar"}
</Button>
</form>
);
};
export default RegisterForm;

View File

@ -1,184 +1,13 @@
import { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Link } from 'react-router-dom';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useToast } from "@/components/ui/use-toast";
import { supabase } from "@/integrations/supabase/client";
// URL do webhook para notificação de novo cadastro
const WEBHOOK_URL = "https://hook.us1.make.com/spgyc1wpkqmep46qzo1h1v1m246luw13";
import LoginForm from '@/components/auth/LoginForm';
import RegisterForm from '@/components/auth/RegisterForm';
const Auth = () => {
const navigate = useNavigate();
const { toast } = useToast();
const [isLoading, setIsLoading] = useState(false);
// Estado do formulário de login
const [loginEmail, setLoginEmail] = useState('');
const [loginSenha, setLoginSenha] = useState('');
// Estado do formulário de cadastro
const [nome, setNome] = useState('');
const [empresa, setEmpresa] = useState('');
const [email, setEmail] = useState('');
const [senha, setSenha] = useState('');
const [confirmaSenha, setConfirmaSenha] = useState('');
// Função para enviar dados do usuário para o webhook
const enviarDadosParaWebhook = async (dadosUsuario) => {
try {
console.log("Enviando dados do usuário para webhook:", dadosUsuario);
await fetch(WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
mode: 'no-cors', // Necessário para webhooks externos
body: JSON.stringify(dadosUsuario),
});
console.log("Dados enviados com sucesso para o webhook");
} catch (error) {
console.error("Erro ao enviar dados para o webhook:", error);
}
};
// Função para fazer login
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Tenta autenticar o usuário através da função RPC do Supabase
const { data, error } = await supabase.rpc('autenticar_usuario', {
email_login: loginEmail,
senha_login: loginSenha
});
if (error || !data) {
throw new Error(error?.message || "Falha ao autenticar. Verifique seu email e senha.");
}
// Se encontrou um usuário válido
if (data) {
// Armazenar informações de sessão
localStorage.setItem('autenticado', 'true');
localStorage.setItem('userId', data);
localStorage.setItem('userEmail', loginEmail);
toast({
title: "Login realizado com sucesso",
description: "Bem-vindo de volta!"
});
// Redirecionamento para o dashboard após login bem-sucedido
navigate('/dashboard');
} else {
toast({
title: "Falha no login",
description: "Email ou senha incorretos",
variant: "destructive"
});
}
} catch (error) {
console.error("Erro ao fazer login:", error);
toast({
title: "Erro ao fazer login",
description: "Verifique suas credenciais e tente novamente",
variant: "destructive"
});
} finally {
setIsLoading(false);
}
};
// Função para cadastrar usuário
const handleCadastro = async (e: React.FormEvent) => {
e.preventDefault();
// Validações básicas
if (!nome || !email || !senha) {
toast({
title: "Campos obrigatórios",
description: "Por favor preencha todos os campos obrigatórios",
variant: "destructive"
});
return;
}
if (senha !== confirmaSenha) {
toast({
title: "Senhas não conferem",
description: "A senha e a confirmação de senha devem ser iguais",
variant: "destructive"
});
return;
}
setIsLoading(true);
try {
// Registrar o usuário usando a função RPC do Supabase
const { data, error } = await supabase.rpc('registrar_usuario', {
nome,
empresa,
email,
senha
});
if (error) throw error;
if (data) {
// Preparar os dados do usuário para enviar ao webhook
const dadosUsuario = {
nome,
empresa,
email,
data_cadastro: new Date().toISOString(),
origem: window.location.origin,
};
// Enviar dados do usuário para o webhook
await enviarDadosParaWebhook(dadosUsuario);
toast({
title: "Cadastro realizado",
description: "Sua conta foi criada com sucesso!"
});
// Fazer login automaticamente após o cadastro
const { data: loginData, error: loginError } = await supabase.rpc('autenticar_usuario', {
email_login: email,
senha_login: senha
});
if (loginError) throw loginError;
if (loginData) {
localStorage.setItem('autenticado', 'true');
localStorage.setItem('userId', loginData);
localStorage.setItem('userEmail', email);
localStorage.setItem('userName', nome);
// Redirecionamento para o dashboard após cadastro bem-sucedido
navigate('/dashboard');
}
}
} catch (error: any) {
console.error("Erro ao cadastrar:", error);
toast({
title: "Erro no cadastro",
description: error.message || "Não foi possível completar o cadastro",
variant: "destructive"
});
} finally {
setIsLoading(false);
}
};
return (
<div className="flex items-center justify-center min-h-screen bg-gray-50 px-4">
@ -195,93 +24,11 @@ const Auth = () => {
</TabsList>
<TabsContent value="login">
<form onSubmit={handleLogin} className="space-y-4">
<div className="space-y-2">
<Input
id="login-email"
placeholder="Email"
type="email"
value={loginEmail}
onChange={(e) => setLoginEmail(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="login-senha"
placeholder="Senha"
type="password"
value={loginSenha}
onChange={(e) => setLoginSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Entrando..." : "Entrar"}
</Button>
</form>
<LoginForm isLoading={isLoading} setIsLoading={setIsLoading} />
</TabsContent>
<TabsContent value="cadastro">
<form onSubmit={handleCadastro} className="space-y-4">
<div className="space-y-2">
<Input
id="nome"
placeholder="Nome completo"
value={nome}
onChange={(e) => setNome(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="empresa"
placeholder="Empresa (opcional)"
value={empresa}
onChange={(e) => setEmpresa(e.target.value)}
disabled={isLoading}
/>
</div>
<div className="space-y-2">
<Input
id="email"
placeholder="Email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="senha"
placeholder="Senha"
type="password"
value={senha}
onChange={(e) => setSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Input
id="confirma-senha"
placeholder="Confirme a senha"
type="password"
value={confirmaSenha}
onChange={(e) => setConfirmaSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Cadastrando..." : "Cadastrar"}
</Button>
</form>
<RegisterForm isLoading={isLoading} setIsLoading={setIsLoading} />
</TabsContent>
</Tabs>
</CardContent>

View File

@ -0,0 +1,31 @@
// URL do webhook para notificação de novo cadastro
const WEBHOOK_URL = "https://hook.us1.make.com/spgyc1wpkqmep46qzo1h1v1m246luw13";
interface UserData {
nome: string;
empresa?: string;
email: string;
data_cadastro: string;
origem: string;
}
// Função para enviar dados do usuário para o webhook
export const enviarDadosParaWebhook = async (dadosUsuario: UserData) => {
try {
console.log("Enviando dados do usuário para webhook:", dadosUsuario);
await fetch(WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
mode: 'no-cors', // Necessário para webhooks externos
body: JSON.stringify(dadosUsuario),
});
console.log("Dados enviados com sucesso para o webhook");
} catch (error) {
console.error("Erro ao enviar dados para o webhook:", error);
}
};