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:
parent
bd322c9f45
commit
354c53212d
@ -2,12 +2,11 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { supabase } from "@/integrations/supabase/client";
|
import { formatarWhatsapp } from '@/utils/whatsappFormatter';
|
||||||
import { enviarDadosParaWebhook } from '@/utils/webhookService';
|
import { validateRegisterForm } from '@/utils/registerValidation';
|
||||||
import { Label } from '@/components/ui/label';
|
import { registerUser, loginAfterRegister } from '@/services/registerService';
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
import RegisterFormFields from './RegisterFormFields';
|
||||||
|
|
||||||
interface RegisterFormProps {
|
interface RegisterFormProps {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
@ -26,50 +25,24 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
|
|||||||
const [senha, setSenha] = useState('');
|
const [senha, setSenha] = useState('');
|
||||||
const [confirmaSenha, setConfirmaSenha] = 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
|
// Função para cadastrar usuário
|
||||||
const handleCadastro = async (e: React.FormEvent) => {
|
const handleCadastro = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
// Validações básicas
|
// Validações básicas
|
||||||
if (!nome || !email || !senha || !whatsapp) {
|
const validationError = validateRegisterForm({
|
||||||
|
nome,
|
||||||
|
empresa,
|
||||||
|
email,
|
||||||
|
whatsapp,
|
||||||
|
senha,
|
||||||
|
confirmaSenha
|
||||||
|
});
|
||||||
|
|
||||||
|
if (validationError) {
|
||||||
toast({
|
toast({
|
||||||
title: "Campos obrigatórios",
|
title: "Campos obrigatórios",
|
||||||
description: "Por favor preencha todos os campos obrigatórios",
|
description: validationError,
|
||||||
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"
|
variant: "destructive"
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -78,58 +51,31 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Registrar o usuário usando a função RPC do Supabase
|
const { userId, whatsappLimpo } = await registerUser({
|
||||||
// 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', {
|
|
||||||
nome,
|
nome,
|
||||||
empresa: empresa || null,
|
empresa,
|
||||||
email,
|
email,
|
||||||
senha,
|
whatsapp,
|
||||||
whatsapp: whatsappLimpo
|
senha
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error) throw error;
|
toast({
|
||||||
|
title: "Cadastro realizado",
|
||||||
|
description: "Sua conta foi criada com sucesso!"
|
||||||
|
});
|
||||||
|
|
||||||
if (data) {
|
// Fazer login automaticamente após o cadastro
|
||||||
// Preparar os dados do usuário para enviar ao webhook
|
const loginData = await loginAfterRegister(email, senha);
|
||||||
const dadosUsuario = {
|
|
||||||
nome,
|
|
||||||
empresa,
|
|
||||||
email,
|
|
||||||
whatsapp: whatsappLimpo,
|
|
||||||
data_cadastro: new Date().toISOString(),
|
|
||||||
origem: window.location.origin,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enviar dados do usuário para o webhook
|
if (loginData) {
|
||||||
await enviarDadosParaWebhook(dadosUsuario);
|
localStorage.setItem('autenticado', 'true');
|
||||||
|
localStorage.setItem('userId', loginData);
|
||||||
|
localStorage.setItem('userEmail', email);
|
||||||
|
localStorage.setItem('userName', nome);
|
||||||
|
localStorage.setItem('userWhatsapp', whatsappLimpo);
|
||||||
|
|
||||||
toast({
|
// Redirecionamento para a página principal após cadastro bem-sucedido
|
||||||
title: "Cadastro realizado",
|
navigate('/');
|
||||||
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('/');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error("Erro ao cadastrar:", error);
|
console.error("Erro ao cadastrar:", error);
|
||||||
@ -143,77 +89,27 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleWhatsappChange = (value: string) => {
|
||||||
|
setWhatsapp(formatarWhatsapp(value));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleCadastro} className="space-y-4">
|
<form onSubmit={handleCadastro} className="space-y-4">
|
||||||
<div className="space-y-2">
|
<RegisterFormFields
|
||||||
<Label htmlFor="nome">Nome completo</Label>
|
nome={nome}
|
||||||
<Input
|
setNome={setNome}
|
||||||
id="nome"
|
empresa={empresa}
|
||||||
placeholder="Nome completo"
|
setEmpresa={setEmpresa}
|
||||||
value={nome}
|
email={email}
|
||||||
onChange={(e) => setNome(e.target.value)}
|
setEmail={setEmail}
|
||||||
disabled={isLoading}
|
whatsapp={whatsapp}
|
||||||
required
|
setWhatsapp={handleWhatsappChange}
|
||||||
/>
|
senha={senha}
|
||||||
</div>
|
setSenha={setSenha}
|
||||||
<div className="space-y-2">
|
confirmaSenha={confirmaSenha}
|
||||||
<Label htmlFor="empresa">Empresa (opcional)</Label>
|
setConfirmaSenha={setConfirmaSenha}
|
||||||
<Input
|
isLoading={isLoading}
|
||||||
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>
|
|
||||||
<Button type="submit" className="w-full" disabled={isLoading}>
|
<Button type="submit" className="w-full" disabled={isLoading}>
|
||||||
{isLoading ? "Cadastrando..." : "Cadastrar"}
|
{isLoading ? "Cadastrando..." : "Cadastrar"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
111
src/components/auth/RegisterFormFields.tsx
Normal file
111
src/components/auth/RegisterFormFields.tsx
Normal 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;
|
||||||
58
src/services/registerService.ts
Normal file
58
src/services/registerService.ts
Normal 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;
|
||||||
|
};
|
||||||
23
src/utils/registerValidation.ts
Normal file
23
src/utils/registerValidation.ts
Normal 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;
|
||||||
|
};
|
||||||
25
src/utils/whatsappFormatter.ts
Normal file
25
src/utils/whatsappFormatter.ts
Normal 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;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user