Refactor: Split RegisterForm.tsx into smaller components

Refactor RegisterForm.tsx into smaller, reusable components to improve code organization and maintainability.
This commit is contained in:
gpt-engineer-app[bot] 2025-05-24 13:07:24 +00:00
parent bd322c9f45
commit 354c53212d
5 changed files with 270 additions and 157 deletions

View File

@ -2,12 +2,11 @@
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';
import { Label } from '@/components/ui/label';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { formatarWhatsapp } from '@/utils/whatsappFormatter';
import { validateRegisterForm } from '@/utils/registerValidation';
import { registerUser, loginAfterRegister } from '@/services/registerService';
import RegisterFormFields from './RegisterFormFields';
interface RegisterFormProps {
isLoading: boolean;
@ -26,50 +25,24 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
const [senha, setSenha] = useState('');
const [confirmaSenha, setConfirmaSenha] = useState('');
// Função para formatar o WhatsApp
const formatarWhatsapp = (valor: string) => {
// Remove todos os caracteres não numéricos
let nums = valor.replace(/\D/g, '');
// Garante que sempre começa com 55 (código do Brasil)
if (!nums.startsWith('55')) {
nums = '55' + nums;
}
// Formata com parênteses para o DDD
if (nums.length > 4) {
const codigo = nums.slice(0, 2); // 55
const ddd = nums.slice(2, 4); // DDD
const numero = nums.slice(4); // Resto do número
if (nums.length > 6) {
return `${codigo}(${ddd})${numero}`;
} else {
return `${codigo}(${ddd}${numero.length > 0 ? ')' + numero : ''}`;
}
}
return nums.length >= 2 ? `${nums.slice(0, 2)}(${nums.slice(2)}` : nums;
};
// Função para cadastrar usuário
const handleCadastro = async (e: React.FormEvent) => {
e.preventDefault();
// Validações básicas
if (!nome || !email || !senha || !whatsapp) {
const validationError = validateRegisterForm({
nome,
empresa,
email,
whatsapp,
senha,
confirmaSenha
});
if (validationError) {
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",
description: validationError,
variant: "destructive"
});
return;
@ -78,58 +51,31 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
setIsLoading(true);
try {
// Registrar o usuário usando a função RPC do Supabase
// Removemos formatação antes de enviar para o banco
const whatsappLimpo = whatsapp.replace(/\D/g, '');
// Garantir que todos os parâmetros sejam incluídos na chamada para a função registrar_usuario
const { data, error } = await supabase.rpc('registrar_usuario', {
const { userId, whatsappLimpo } = await registerUser({
nome,
empresa: empresa || null,
empresa,
email,
senha,
whatsapp: whatsappLimpo
whatsapp,
senha
});
if (error) throw error;
toast({
title: "Cadastro realizado",
description: "Sua conta foi criada com sucesso!"
});
if (data) {
// Preparar os dados do usuário para enviar ao webhook
const dadosUsuario = {
nome,
empresa,
email,
whatsapp: whatsappLimpo,
data_cadastro: new Date().toISOString(),
origem: window.location.origin,
};
// Fazer login automaticamente após o cadastro
const loginData = await loginAfterRegister(email, senha);
if (loginData) {
localStorage.setItem('autenticado', 'true');
localStorage.setItem('userId', loginData);
localStorage.setItem('userEmail', email);
localStorage.setItem('userName', nome);
localStorage.setItem('userWhatsapp', whatsappLimpo);
// 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);
localStorage.setItem('userWhatsapp', whatsappLimpo);
// Redirecionamento para a página principal após cadastro bem-sucedido
navigate('/');
}
// Redirecionamento para a página principal após cadastro bem-sucedido
navigate('/');
}
} catch (error: any) {
console.error("Erro ao cadastrar:", error);
@ -143,77 +89,27 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
}
};
const handleWhatsappChange = (value: string) => {
setWhatsapp(formatarWhatsapp(value));
};
return (
<form onSubmit={handleCadastro} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="nome">Nome completo</Label>
<Input
id="nome"
placeholder="Nome completo"
value={nome}
onChange={(e) => setNome(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="empresa">Empresa (opcional)</Label>
<Input
id="empresa"
placeholder="Empresa (opcional)"
value={empresa}
onChange={(e) => setEmpresa(e.target.value)}
disabled={isLoading}
/>
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
placeholder="Email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="whatsapp">WhatsApp (com DDD)</Label>
<Input
id="whatsapp"
placeholder="55(11)999999999"
type="tel"
value={whatsapp}
onChange={(e) => setWhatsapp(formatarWhatsapp(e.target.value))}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="senha">Senha</Label>
<Input
id="senha"
placeholder="Senha"
type="password"
value={senha}
onChange={(e) => setSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="confirma-senha">Confirme a senha</Label>
<Input
id="confirma-senha"
placeholder="Confirme a senha"
type="password"
value={confirmaSenha}
onChange={(e) => setConfirmaSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<RegisterFormFields
nome={nome}
setNome={setNome}
empresa={empresa}
setEmpresa={setEmpresa}
email={email}
setEmail={setEmail}
whatsapp={whatsapp}
setWhatsapp={handleWhatsappChange}
senha={senha}
setSenha={setSenha}
confirmaSenha={confirmaSenha}
setConfirmaSenha={setConfirmaSenha}
isLoading={isLoading}
/>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Cadastrando..." : "Cadastrar"}
</Button>

View File

@ -0,0 +1,111 @@
import { Input } from "@/components/ui/input";
import { Label } from '@/components/ui/label';
interface RegisterFormFieldsProps {
nome: string;
setNome: (value: string) => void;
empresa: string;
setEmpresa: (value: string) => void;
email: string;
setEmail: (value: string) => void;
whatsapp: string;
setWhatsapp: (value: string) => void;
senha: string;
setSenha: (value: string) => void;
confirmaSenha: string;
setConfirmaSenha: (value: string) => void;
isLoading: boolean;
}
const RegisterFormFields = ({
nome,
setNome,
empresa,
setEmpresa,
email,
setEmail,
whatsapp,
setWhatsapp,
senha,
setSenha,
confirmaSenha,
setConfirmaSenha,
isLoading
}: RegisterFormFieldsProps) => {
return (
<>
<div className="space-y-2">
<Label htmlFor="nome">Nome completo</Label>
<Input
id="nome"
placeholder="Nome completo"
value={nome}
onChange={(e) => setNome(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="empresa">Empresa (opcional)</Label>
<Input
id="empresa"
placeholder="Empresa (opcional)"
value={empresa}
onChange={(e) => setEmpresa(e.target.value)}
disabled={isLoading}
/>
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
placeholder="Email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="whatsapp">WhatsApp (com DDD)</Label>
<Input
id="whatsapp"
placeholder="55(11)999999999"
type="tel"
value={whatsapp}
onChange={(e) => setWhatsapp(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="senha">Senha</Label>
<Input
id="senha"
placeholder="Senha"
type="password"
value={senha}
onChange={(e) => setSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="confirma-senha">Confirme a senha</Label>
<Input
id="confirma-senha"
placeholder="Confirme a senha"
type="password"
value={confirmaSenha}
onChange={(e) => setConfirmaSenha(e.target.value)}
disabled={isLoading}
required
/>
</div>
</>
);
};
export default RegisterFormFields;

View File

@ -0,0 +1,58 @@
import { supabase } from "@/integrations/supabase/client";
import { enviarDadosParaWebhook } from '@/utils/webhookService';
export interface UserRegistrationData {
nome: string;
empresa: string;
email: string;
whatsapp: string;
senha: string;
}
export const registerUser = async (userData: UserRegistrationData) => {
const { nome, empresa, email, senha, whatsapp } = userData;
// Removemos formatação antes de enviar para o banco
const whatsappLimpo = whatsapp.replace(/\D/g, '');
// Registrar o usuário usando a função RPC do Supabase
const { data, error } = await supabase.rpc('registrar_usuario', {
nome,
empresa: empresa || null,
email,
senha,
whatsapp: whatsappLimpo
});
if (error) throw error;
if (data) {
// Preparar os dados do usuário para enviar ao webhook
const dadosUsuario = {
nome,
empresa,
email,
whatsapp: whatsappLimpo,
data_cadastro: new Date().toISOString(),
origem: window.location.origin,
};
// Enviar dados do usuário para o webhook
await enviarDadosParaWebhook(dadosUsuario);
return { userId: data, whatsappLimpo };
}
throw new Error("Falha no registro do usuário");
};
export const loginAfterRegister = async (email: string, senha: string) => {
const { data, error } = await supabase.rpc('autenticar_usuario', {
email_login: email,
senha_login: senha
});
if (error) throw error;
return data;
};

View File

@ -0,0 +1,23 @@
export interface RegisterFormData {
nome: string;
empresa: string;
email: string;
whatsapp: string;
senha: string;
confirmaSenha: string;
}
export const validateRegisterForm = (formData: RegisterFormData): string | null => {
const { nome, email, senha, whatsapp, confirmaSenha } = formData;
if (!nome || !email || !senha || !whatsapp) {
return "Por favor preencha todos os campos obrigatórios";
}
if (senha !== confirmaSenha) {
return "A senha e a confirmação de senha devem ser iguais";
}
return null;
};

View File

@ -0,0 +1,25 @@
export const formatarWhatsapp = (valor: string): string => {
// Remove todos os caracteres não numéricos
let nums = valor.replace(/\D/g, '');
// Garante que sempre começa com 55 (código do Brasil)
if (!nums.startsWith('55')) {
nums = '55' + nums;
}
// Formata com parênteses para o DDD
if (nums.length > 4) {
const codigo = nums.slice(0, 2); // 55
const ddd = nums.slice(2, 4); // DDD
const numero = nums.slice(4); // Resto do número
if (nums.length > 6) {
return `${codigo}(${ddd})${numero}`;
} else {
return `${codigo}(${ddd}${numero.length > 0 ? ')' + numero : ''}`;
}
}
return nums.length >= 2 ? `${nums.slice(0, 2)}(${nums.slice(2)}` : nums;
};